pub_core_redir.h \
pub_core_replacemalloc.h\
pub_core_scheduler.h \
+ pub_core_seqmatch.h \
pub_core_sigframe.h \
pub_core_signals.h \
pub_core_sparsewa.h \
m_options.c \
m_oset.c \
m_redir.c \
+ m_seqmatch.c \
m_signals.c \
m_sparsewa.c \
m_stacks.c \
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
#include "pub_core_libcfile.h"
+#include "pub_core_seqmatch.h"
#include "pub_core_options.h"
#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo)
#include "pub_core_aspacemgr.h"
#include "pub_core_libcfile.h"
#include "pub_core_libcprint.h"
#include "pub_core_libcproc.h" // For VG_(getpid)()
+#include "pub_core_seqmatch.h"
#include "pub_core_mallocfree.h"
#include "pub_core_options.h"
#include "pub_core_stacktrace.h"
/*------------------------------------------------------------*/
-/*--- Standard suppressions ---*/
+/*--- Suppression parsing ---*/
/*------------------------------------------------------------*/
/* Get the next char from fd into *out_buf. Returns 1 if success,
/* Look for "tool" in a string like "tool1,tool2,tool3" */
-static __inline__
-Bool tool_name_present(Char *name, Char *names)
+static Bool tool_name_present(Char *name, Char *names)
{
Bool found;
Char *s = NULL; /* Shut gcc up */
}
if (VG_(needs).tool_errors &&
- !VG_TDICT_CALL(tool_read_extra_suppression_info, fd, buf, N_BUF, supp))
+ !VG_TDICT_CALL(tool_read_extra_suppression_info,
+ fd, buf, N_BUF, supp))
{
BOMB("bad or missing extra suppression info");
}
}
}
+
+/*------------------------------------------------------------*/
+/*--- Matching errors to suppressions ---*/
+/*------------------------------------------------------------*/
+
+/* Parameterising functions for the use of VG_(generic_match) in
+ suppression-vs-error matching. The suppression frames (SuppLoc)
+ play the role of 'pattern'-element, and the error frames (IPs,
+ hence simply Addrs) play the role of 'input'. In short then, we're
+ matching a sequence of Addrs against a pattern composed of a
+ sequence of SuppLocs.
+*/
+static Bool supploc_IsStar ( void* supplocV )
+{
+ SuppLoc* supploc = (SuppLoc*)supplocV;
+ return supploc->ty == DotDotDot;
+}
+
+static Bool supploc_IsQuery ( void* supplocV )
+{
+ return False; /* there's no '?' equivalent in the supp syntax */
+}
+
+static Bool supp_pattEQinp ( void* supplocV, void* addrV )
+{
+ SuppLoc* supploc = (SuppLoc*)supplocV; /* PATTERN */
+ Addr ip = *(Addr*)addrV; /* INPUT */
+
+ Char caller_name[ERRTXT_LEN];
+ caller_name[0] = 0;
+
+ /* So, does this IP address match this suppression-line? */
+ switch (supploc->ty) {
+ case DotDotDot:
+ /* supp_pattEQinp is a callback from VG_(generic_match). As
+ per the spec thereof (see include/pub_tool_seqmatch.h), we
+ should never get called with a pattern value for which the
+ _IsStar or _IsQuery function would return True. Hence
+ this can't happen. */
+ vg_assert(0);
+ case ObjName:
+ /* Get the object name into 'caller_name', or "???"
+ if unknown. */
+ if (!VG_(get_objname)(ip, caller_name, ERRTXT_LEN))
+ VG_(strcpy)(caller_name, "???");
+ break;
+ case FunName:
+ /* Get the function name into 'caller_name', or "???"
+ if unknown. */
+ // Nb: mangled names used in suppressions. Do, though,
+ // Z-demangle them, since otherwise it's possible to wind
+ // up comparing "malloc" in the suppression against
+ // "_vgrZU_libcZdsoZa_malloc" in the backtrace, and the
+ // two of them need to be made to match.
+ if (!VG_(get_fnname_Z_demangle_only)(ip, caller_name, ERRTXT_LEN))
+ VG_(strcpy)(caller_name, "???");
+ break;
+ default:
+ vg_assert(0);
+ }
+
+ /* So now we have the function or object name in caller_name, and
+ the pattern (at the character level) to match against is in
+ supploc->name. Hence (and leading to a re-entrant call of
+ VG_(generic_match)): */
+ return VG_(string_match)(supploc->name, caller_name);
+}
+
+/////////////////////////////////////////////////////
+
+static Bool supp_matches_callers(Error* err, Supp* su)
+{
+ /* Unwrap the args and set up the correct parameterisation of
+ VG_(generic_match), using supploc_IsStar, supploc_IsQuery and
+ supp_pattEQinp. */
+ /* note, StackTrace === Addr* */
+ StackTrace ips = VG_(get_ExeContext_StackTrace)(err->where);
+ UWord n_ips = VG_(get_ExeContext_n_ips)(err->where);
+ SuppLoc* supps = su->callers;
+ UWord n_supps = su->n_callers;
+ UWord szbPatt = sizeof(SuppLoc);
+ UWord szbInput = sizeof(Addr);
+ Bool matchAll = False; /* we just want to match a prefix */
+ return
+ VG_(generic_match)(
+ matchAll,
+ /*PATT*/supps, szbPatt, n_supps, 0/*initial Ix*/,
+ /*INPUT*/ips, szbInput, n_ips, 0/*initial Ix*/,
+ supploc_IsStar, supploc_IsQuery, supp_pattEQinp
+ );
+}
+
+/////////////////////////////////////////////////////
+
static
Bool supp_matches_error(Supp* su, Error* err)
{
}
}
-
-/* This function is recursive, in order to handle frame-level
- wildcards. */
-static
-Bool supp_matches_callers_WRK ( StackTrace trace, Int n_ips,
- SuppLoc *callers, Int n_callers )
-{
- Int i, j;
- static Char caller_name[ERRTXT_LEN]; /* NOT IN FRAME */
-
- vg_assert(n_ips > 0 && n_callers > 0);
- i = j = 0;
- while (i < n_callers) {
- Addr a = trace[j];
-
- switch (callers[i].ty) {
- case ObjName:
- if (!VG_(get_objname)(a, caller_name, ERRTXT_LEN))
- VG_(strcpy)(caller_name, "???");
- break;
- case FunName:
- // Nb: mangled names used in suppressions. Do, though,
- // Z-demangle them, since otherwise it's possible to wind
- // up comparing "malloc" in the suppression against
- // "_vgrZU_libcZdsoZa_malloc" in the backtrace, and the
- // two of them need to be made to match.
- if (!VG_(get_fnname_Z_demangle_only)(a, caller_name, ERRTXT_LEN))
- VG_(strcpy)(caller_name, "???");
- break;
- case DotDotDot:
- caller_name[0] = 0; /* precautionary */
- break;
- default:
- VG_(tool_panic)("supp_wildmatch_callers");
- }
- // If "..." is given in a suppression (either obj, or fun), then
- // use it as wildcard, and match as many callers as possible.
- if (callers[i].ty == DotDotDot) {
- /* Handle frame-level wildcard case */
- Char *lookahead;
-
- // collapse subsequent wildcards
- while (i < n_callers && callers[i].ty == DotDotDot)
- ++i;
- --i;
-
- if (i == n_callers-1)
- // wildcard at the top, doesn't matter
- return True;
-
- vg_assert(i >= 0 && i+1 < n_callers);
- lookahead = callers[i+1].name;
- while (j < n_ips) {
- static Char tmp[ERRTXT_LEN]; /* NOT IN FRAME */
-
- if (!VG_(get_fnname_Z_demangle_only)(trace[j], tmp, ERRTXT_LEN))
- VG_(strcpy)(tmp, "???");
- if (VG_(string_match)(lookahead, tmp)) {
- // found a possible continuation, try from there
- return supp_matches_callers_WRK(
- &trace[j], n_ips - j,
- &callers[i+1], n_callers - i - 1
- );
- }
- j++;
- }
- } else {
- /* Handle normal (obj: or fun:) case */
- if (!VG_(string_match)(callers[i].name, caller_name)) {
- return False;
- }
- }
- j++;
- i++;
- }
-
- /* If we reach here, it's a match */
- return True;
-}
-
-static
-Bool supp_matches_callers(Error* err, Supp* su)
-{
- /* Unwrap the args and pass them to the worker function. */
- StackTrace ips = VG_(get_ExeContext_StackTrace)(err->where);
- UInt n_ips = VG_(get_ExeContext_n_ips)(err->where);
- return supp_matches_callers_WRK(ips, n_ips, su->callers, su->n_callers);
-}
-
+/////////////////////////////////////////////////////
/* Does an error context match a suppression? ie is this a suppressible
error? If so, return a pointer to the Supp record, otherwise NULL.
}
-/* ---------------------------------------------------------------------
- A simple string matching routine, purloined from Hugs98.
- '*' matches any sequence of zero or more characters
- '?' matches any single character exactly
- '\c' matches the character c only (ignoring special chars)
- c matches the character c only
- ------------------------------------------------------------------ */
-
-/* Keep track of recursion depth. */
-static Int recDepth;
-
-// Nb: vg_assert disabled because we can't use it from this module...
-static Bool string_match_wrk ( const Char* pat, const Char* str )
-{
- //vg_assert(recDepth >= 0 && recDepth < 500);
- recDepth++;
- for (;;) {
- switch (*pat) {
- case '\0':recDepth--;
- return (*str=='\0');
- case '*': do {
- if (string_match_wrk(pat+1,str)) {
- recDepth--;
- return True;
- }
- } while (*str++);
- recDepth--;
- return False;
- case '?': if (*str++=='\0') {
- recDepth--;
- return False;
- }
- pat++;
- break;
- case '\\':if (*++pat == '\0') {
- recDepth--;
- return False; /* spurious trailing \ in pattern */
- }
- /* falls through to ... */
- default : if (*pat++ != *str++) {
- recDepth--;
- return False;
- }
- break;
- }
- }
-}
-
-Bool VG_(string_match) ( const Char* pat, const Char* str )
-{
- Bool b;
- recDepth = 0;
- b = string_match_wrk ( pat, str );
- //vg_assert(recDepth == 0);
- /*
- VG_(printf)("%s %s %s\n",
- b?"TRUE ":"FALSE", pat, str);
- */
- return b;
-}
-
-
/* ---------------------------------------------------------------------
mem* functions
------------------------------------------------------------------ */
#include "pub_core_libcprint.h"
#include "pub_core_libcproc.h"
#include "pub_core_libcsignal.h"
+#include "pub_core_seqmatch.h"
#include "pub_core_mallocfree.h"
#include "pub_core_syscall.h"
#include "pub_core_xarray.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
+#include "pub_core_seqmatch.h"
#include "pub_core_mallocfree.h"
#include "pub_core_options.h"
#include "pub_core_oset.h"
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- A simple sequence matching facility. ---*/
+/*--- m_seqmatch.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2008-2008 OpenWorks Ltd
+ info@open-works.co.uk
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcbase.h" // VG_(strlen)
+#include "pub_core_seqmatch.h" // self
+
+/* ---------------------------------------------------------------------
+ A simple sequence matching facility
+ ------------------------------------------------------------------ */
+
+/* See detailed comment in include/pub_tool_seqmatch.h about this. */
+Bool VG_(generic_match) (
+ Bool matchAll,
+ void* patt, SizeT szbPatt, UWord nPatt, UWord ixPatt,
+ void* input, SizeT szbInput, UWord nInput, UWord ixInput,
+ Bool (*pIsStar)(void*),
+ Bool (*pIsQuery)(void*),
+ Bool (*pattEQinp)(void*,void*)
+ )
+{
+ /* This is the spec, written in my favourite formal specification
+ language. It specifies non-greedy matching of '*'s.
+
+ ma ('*':ps) (i:is) = ma ps (i:is) || ma ('*':ps) is
+ ma ('*':ps) [] = ma ps []
+
+ ma ('?':ps) (i:is) = ma ps is
+ ma ('?':ps) [] = False
+
+ ma (p:ps) (i:is) = p == i && ma ps is
+
+ ma (p:ps) [] = False
+ ma [] (i:is) = False -- m-all, True for m-prefix
+ ma [] [] = True
+ */
+ Bool havePatt, haveInput;
+ void *currPatt, *currInput;
+ tailcall:
+ vg_assert(nPatt >= 0 && nPatt < 1000000); /* arbitrary */
+ vg_assert(nInput >= 0 && nInput < 1000000); /* arbitrary */
+ vg_assert(ixPatt >= 0 && ixPatt <= nPatt);
+ vg_assert(ixInput >= 0 && ixInput <= nInput);
+
+ havePatt = ixPatt < nPatt;
+ haveInput = ixInput < nInput;
+
+ /* No specific need to set NULL when !have{Patt,Input}, but guards
+ against inadvertantly dereferencing an out of range pointer to
+ the pattern or input arrays. */
+ currPatt = havePatt ? ((Char*)patt) + szbPatt * ixPatt : NULL;
+ currInput = haveInput ? ((Char*)input) + szbInput * ixInput : NULL;
+
+ // Deal with the complex case first: wildcards. Do frugal
+ // matching. When encountering a '*', first skip no characters
+ // at all, and see if the rest of the match still works. Only if
+ // that fails do we then skip a character, and retry at the next
+ // position.
+ //
+ // ma ('*':ps) (i:is) = ma ps (i:is) || ma ('*':ps) is
+ //
+ // If we're out of input, check the rest of the pattern matches
+ // the empty input. This really means can only be be empty or
+ // composed entirely of '*'s.
+ //
+ // ma ('*':ps) [] = ma ps []
+ //
+ if (havePatt && pIsStar(currPatt)) {
+ if (haveInput) {
+ // ma ('*':ps) (i:is) = ma ps (i:is) || ma ('*':ps) is
+ // we unavoidably have to make a real recursive call for the
+ // first half of the OR, since this isn't straight tail-recursion.
+ if (VG_(generic_match)( matchAll,
+ patt, szbPatt, nPatt, ixPatt+1,
+ input,szbInput,nInput, ixInput+0,
+ pIsStar,pIsQuery,pattEQinp) ) {
+ return True;
+ }
+ // but we can tail-recurse for the second call
+ ixInput++; goto tailcall;
+ } else {
+ // ma ('*':ps) [] = ma ps []
+ ixPatt++; goto tailcall;
+ }
+ }
+
+ // simpler cases now. Deal with '?' wildcards.
+ //
+ // ma ('?':ps) (i:is) = ma ps is
+ // ma ('?':ps) [] = False
+ if (havePatt && pIsQuery(currPatt)) {
+ if (haveInput) {
+ ixPatt++; ixInput++; goto tailcall;
+ } else {
+ return False;
+ }
+ }
+
+ // obvious case with literal chars in the pattern
+ //
+ // ma (p:ps) (i:is) = p == i && ma ps is
+ if (havePatt && haveInput) {
+ if (!pattEQinp(currPatt,currInput)) return False;
+ ixPatt++; ixInput++; goto tailcall;
+ }
+
+ // if we run out of input before we run out of pattern, we must fail
+ // ma (p:ps) [] = False
+ if (havePatt && !haveInput) return False;
+
+ // if we run out of pattern before we run out of input, the
+ // verdict depends on the matching mode. If we are trying to
+ // match exactly (the pattern must consume the entire input)
+ // then the outcome is failure. However, if we're merely attempting
+ // to match some prefix of the input, then we have been successful.
+ //
+ // ma [] (i:is) = False -- m-all, True for m-prefix
+ if (!havePatt && haveInput) {
+ return matchAll ? False // match-all
+ : True; // match-prefix
+ }
+
+ // finally, if both sequence and input are both completely
+ // consumed, then we were successful, regardless of matching mode.
+ if (!havePatt && !haveInput) return True;
+
+ // end of cases
+ vg_assert(0);
+}
+
+
+/* And a parameterization of the above, to make it do
+ string matching.
+*/
+static Bool charIsStar ( void* pV ) { return *(Char*)pV == '*'; }
+static Bool charIsQuery ( void* pV ) { return *(Char*)pV == '?'; }
+static Bool char_p_EQ_i ( void* pV, void* cV ) {
+ Char p = *(Char*)pV;
+ Char c = *(Char*)cV;
+ vg_assert(p != '*' && p != '?');
+ return p == c;
+}
+Bool VG_(string_match) ( const Char* patt, const Char* input )
+{
+ return VG_(generic_match)(
+ True/* match-all */,
+ (void*)patt, sizeof(UChar), VG_(strlen)(patt), 0,
+ (void*)input, sizeof(UChar), VG_(strlen)(input), 0,
+ charIsStar, charIsQuery, char_p_EQ_i
+ );
+}
+
+
+// test cases for the matcher (in match-all mode)
+// typedef struct { char* patt; char* input; Bool xres; } Test;
+//
+//static Test tests[] =
+// {
+// { "" ,"" , True },
+// { "a" ,"" , False },
+// { "a" ,"b" , False },
+// { "a" ,"a" , True },
+// { "a" ,"aa" , False },
+// { "*" ,"" , True },
+// { "**" ,"" , True },
+// { "*" ,"abc", True },
+// { "*a" ,"abc", False },
+// { "*b" ,"abc", False },
+// { "*bc" ,"abc", True },
+// { "a*b" ,"abc", False },
+// { "a*c" ,"abc", True },
+// { "*c" ,"abc", True },
+// { "c*c" ,"abc", False },
+// { "abc*" ,"abc", True },
+// { "abc**" ,"abc", True },
+// { "**abc" ,"abc", True },
+// { "**a*b*c**" ,"abc", True },
+// { "**a*b*d**" ,"abc", False },
+// { "a?b" ,"abc", False },
+// { "a?c" ,"abc", True },
+// { "?" ,"" , False },
+// { "?" ,"a" , True },
+// { "?" ,"ab" , False },
+// { "abcd" ,"abc", False },
+// { "ab" ,"abc", False },
+// { NULL ,NULL , False }
+// };
+//
+//int main ( void )
+//{
+// Test* t;
+// for (t = tests; t->patt; t++) {
+// printf("%10s %6s %s\n",
+// t->patt, t->input,
+// match_string_all((UChar*)t->patt,(UChar*)t->input,True)
+// == t->xres
+// ? "pass" : "FAIL" );
+// }
+// return 0;
+//}
+
+/*--------------------------------------------------------------------*/
+/*--- end m_seqmatch.c ---*/
+/*--------------------------------------------------------------------*/
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- A simple sequence matching facility. ---*/
+/*--- pub_core_seqmatch.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2008-2008 OpenWorks Ltd
+ info@open-works.co.uk
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PUB_CORE_SEQMATCH_H
+#define __PUB_CORE_SEQMATCH_H
+
+//--------------------------------------------------------------------
+// PURPOSE: Provides a simple generic sequence matching facility, with
+// '*' and '?' style wildcards. Also provides a parameterisation
+// thereof suitable for matching strings. See pub_tool_seqmatch.h
+// for details.
+//--------------------------------------------------------------------
+
+// No core-only exports; everything in this module is visible to both
+// the core and tools.
+
+#include "pub_tool_seqmatch.h"
+
+#endif // __PUB_CORE_SEQMATCH_H
+
+/*--------------------------------------------------------------------*/
+/*--- end pub_core_seqmatch.h ---*/
+/*--------------------------------------------------------------------*/
pub_tool_oset.h \
pub_tool_redir.h \
pub_tool_replacemalloc.h \
+ pub_tool_seqmatch.h \
pub_tool_signals.h \
pub_tool_sparsewa.h \
pub_tool_stacktrace.h \
last character. */
extern void VG_(strncpy_safely) ( Char* dest, const Char* src, SizeT ndest );
-/* Mini-regexp function. Searches for 'pat' in 'str'. Supports
- * meta-symbols '*' and '?'. '\' escapes meta-symbols. */
-extern Bool VG_(string_match) ( const Char* pat, const Char* str );
-
/* ---------------------------------------------------------------------
mem* functions
------------------------------------------------------------------ */
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- A simple sequence matching facility. ---*/
+/*--- pub_tool_seqmatch.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2008-2008 OpenWorks Ltd
+ info@open-works.co.uk
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PUB_TOOL_SEQMATCH_H
+#define __PUB_TOOL_SEQMATCH_H
+
+/* Perform totally abstractified sequence matching, of an input
+ sequence against a pattern sequence. The pattern sequence may
+ include '*' elements (matches any number of anything) and '?'
+ elements (matches exactly one element). '*' patterns are matched
+ frugally, meaning that they are "assigned" the minimum amount of
+ input needed to make the match work.
+
+ This routine is recursive. The recursion depth is equal to the
+ number of '*' elements in the pattern. There is no guard against
+ excessive recursion. This function has no global state and so is
+ thread-safe and re-entrant. (It needs to be, since m_errormgr will
+ effectively construct two simultaneous calls to it, once to match
+ at the frame level, and whilst that is happening, once at the
+ function/object-name level.)
+
+ When matchAll is True, the entire input sequence must match the
+ pattern, else the match fails. When False, it's ok for some tail
+ of the input sequence to be unused -- so we're only matching a
+ prefix.
+
+ The pattern array is starts at 'patt' and consists of 'nPatt'
+ elements each of size 'szbPatt'. For the initial call, pass a
+ value of zero to 'ixPatt'.
+
+ Ditto for input/nInput/szbInput/ixInput.
+
+ pIsStar should return True iff the pointed-to pattern element is
+ conceptually a '*'.
+
+ pIsQuery should return True iff the pointed-to-pattern element is
+ conceptually a '?'.
+
+ pattEQinp takes a pointer to a pattern element and a pointer to an
+ input element. It should return True iff they are considered
+ equal. Note that the pattern element is guaranteed to be neither
+ (conceptually) '*' nor '?', so it must be a literal (in the sense
+ that all the input sequence elements are literal).
+*/
+Bool VG_(generic_match) (
+ Bool matchAll,
+ void* patt, SizeT szbPatt, UWord nPatt, UWord ixPatt,
+ void* input, SizeT szbInput, UWord nInput, UWord ixInput,
+ Bool (*pIsStar)(void*),
+ Bool (*pIsQuery)(void*),
+ Bool (*pattEQinp)(void*,void*)
+ );
+
+/* Mini-regexp function. Searches for 'pat' in 'str'. Supports
+ meta-symbols '*' and '?'. There is no way to escape meta-symbols
+ in the pattern. */
+Bool VG_(string_match) ( const Char* pat, const Char* str );
+
+#endif // __PUB_TOOL_SEQMATCH_H
+
+/*--------------------------------------------------------------------*/
+/*--- end pub_tool_seqmatch.h ---*/
+/*--------------------------------------------------------------------*/