1d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 2d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*--------------------------------------------------------------------*/ 3d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*--- A simple sequence matching facility. ---*/ 4d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*--- m_seqmatch.c ---*/ 5d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*--------------------------------------------------------------------*/ 6d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 7d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/* 8d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj This file is part of Valgrind, a dynamic binary instrumentation 9d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj framework. 10d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 11b3a1e4bffbdbbf38304f216af405009868f43628sewardj Copyright (C) 2008-2015 OpenWorks Ltd 12d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj info@open-works.co.uk 13d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 14d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj This program is free software; you can redistribute it and/or 15d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj modify it under the terms of the GNU General Public License as 16d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj published by the Free Software Foundation; either version 2 of the 17d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj License, or (at your option) any later version. 18d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 19d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj This program is distributed in the hope that it will be useful, but 20d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 21d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj General Public License for more details. 23d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 24d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj You should have received a copy of the GNU General Public License 25d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj along with this program; if not, write to the Free Software 26d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 02111-1307, USA. 28d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 29d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj The GNU General Public License is contained in the file COPYING. 30d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj*/ 31d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 32d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj#include "pub_core_basics.h" 33d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj#include "pub_core_libcassert.h" 34d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj#include "pub_core_libcbase.h" // VG_(strlen) 35d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj#include "pub_core_seqmatch.h" // self 36d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 37d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/* --------------------------------------------------------------------- 38d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj A simple sequence matching facility 39d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ------------------------------------------------------------------ */ 40d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 41d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/* See detailed comment in include/pub_tool_seqmatch.h about this. */ 42d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardjBool VG_(generic_match) ( 43d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj Bool matchAll, 443e7986312a0ffc7646b0552d4c4ea3744a870e73florian const void* patt, SizeT szbPatt, UWord nPatt, UWord ixPatt, 453e7986312a0ffc7646b0552d4c4ea3744a870e73florian const void* input, SizeT szbInput, UWord nInput, UWord ixInput, 463e7986312a0ffc7646b0552d4c4ea3744a870e73florian Bool (*pIsStar)(const void*), 473e7986312a0ffc7646b0552d4c4ea3744a870e73florian Bool (*pIsQuery)(const void*), 483e7986312a0ffc7646b0552d4c4ea3744a870e73florian Bool (*pattEQinp)(const void*,const void*,void*,UWord), 49a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe void* inputCompleter, Bool (*haveInputInpC)(void*,UWord) 50d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ) 51d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj{ 52d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj /* This is the spec, written in my favourite formal specification 53d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj language. It specifies non-greedy matching of '*'s. 54d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 55d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ma ('*':ps) (i:is) = ma ps (i:is) || ma ('*':ps) is 56d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ma ('*':ps) [] = ma ps [] 57d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 58d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ma ('?':ps) (i:is) = ma ps is 59d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ma ('?':ps) [] = False 60d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 61d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ma (p:ps) (i:is) = p == i && ma ps is 62d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 63d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ma (p:ps) [] = False 64d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ma [] (i:is) = False -- m-all, True for m-prefix 65d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ma [] [] = True 66d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj */ 67d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj Bool havePatt, haveInput; 683e7986312a0ffc7646b0552d4c4ea3744a870e73florian const HChar *currPatt, *currInput; 69d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj tailcall: 70a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert(nPatt >= 0 && nPatt < 1000000); /* arbitrary */ 71a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert(inputCompleter 72a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe || (nInput >= 0 && nInput < 1000000)); /* arbitrary */ 73d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj vg_assert(ixPatt >= 0 && ixPatt <= nPatt); 74a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert(ixInput >= 0 && (inputCompleter || ixInput <= nInput)); 75d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 76d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj havePatt = ixPatt < nPatt; 77a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe haveInput = inputCompleter ? 78a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (*haveInputInpC)(inputCompleter, ixInput) 79a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : ixInput < nInput; 80d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 81d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj /* No specific need to set NULL when !have{Patt,Input}, but guards 82d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj against inadvertantly dereferencing an out of range pointer to 83d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj the pattern or input arrays. */ 843e7986312a0ffc7646b0552d4c4ea3744a870e73florian currPatt = havePatt ? ((const HChar*)patt) + szbPatt * ixPatt : NULL; 85a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe currInput = haveInput && !inputCompleter ? 86a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ((const HChar*)input) + szbInput * ixInput : NULL; 87d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 88d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // Deal with the complex case first: wildcards. Do frugal 89d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // matching. When encountering a '*', first skip no characters 90d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // at all, and see if the rest of the match still works. Only if 91d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // that fails do we then skip a character, and retry at the next 92d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // position. 93d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // 94d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // ma ('*':ps) (i:is) = ma ps (i:is) || ma ('*':ps) is 95d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // 96d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // If we're out of input, check the rest of the pattern matches 97d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // the empty input. This really means can only be be empty or 98d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // composed entirely of '*'s. 99d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // 100d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // ma ('*':ps) [] = ma ps [] 101d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // 102d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj if (havePatt && pIsStar(currPatt)) { 103d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj if (haveInput) { 104d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // ma ('*':ps) (i:is) = ma ps (i:is) || ma ('*':ps) is 105d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // we unavoidably have to make a real recursive call for the 106d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // first half of the OR, since this isn't straight tail-recursion. 107d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj if (VG_(generic_match)( matchAll, 108d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj patt, szbPatt, nPatt, ixPatt+1, 109d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj input,szbInput,nInput, ixInput+0, 11013a59524748a7af0f403e4aba435144fa9a6af4cphilippe pIsStar,pIsQuery,pattEQinp, 111a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe inputCompleter,haveInputInpC) ) { 112d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj return True; 113d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj } 114d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // but we can tail-recurse for the second call 115d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ixInput++; goto tailcall; 116d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj } else { 117d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // ma ('*':ps) [] = ma ps [] 118d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ixPatt++; goto tailcall; 119d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj } 120d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj } 121d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 122d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // simpler cases now. Deal with '?' wildcards. 123d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // 124d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // ma ('?':ps) (i:is) = ma ps is 125d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // ma ('?':ps) [] = False 126d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj if (havePatt && pIsQuery(currPatt)) { 127d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj if (haveInput) { 128d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ixPatt++; ixInput++; goto tailcall; 129d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj } else { 130d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj return False; 131d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj } 132d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj } 133d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 134d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // obvious case with literal chars in the pattern 135d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // 136d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // ma (p:ps) (i:is) = p == i && ma ps is 137d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj if (havePatt && haveInput) { 13813a59524748a7af0f403e4aba435144fa9a6af4cphilippe if (!pattEQinp(currPatt,currInput,inputCompleter,ixInput)) return False; 139d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ixPatt++; ixInput++; goto tailcall; 140d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj } 141d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 142d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // if we run out of input before we run out of pattern, we must fail 143d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // ma (p:ps) [] = False 144d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj if (havePatt && !haveInput) return False; 145d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 146d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // if we run out of pattern before we run out of input, the 147d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // verdict depends on the matching mode. If we are trying to 148d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // match exactly (the pattern must consume the entire input) 149d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // then the outcome is failure. However, if we're merely attempting 150d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // to match some prefix of the input, then we have been successful. 151d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // 152d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // ma [] (i:is) = False -- m-all, True for m-prefix 153d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj if (!havePatt && haveInput) { 154d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj return matchAll ? False // match-all 155d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj : True; // match-prefix 156d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj } 157d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 158d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // finally, if both sequence and input are both completely 159d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // consumed, then we were successful, regardless of matching mode. 160d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj if (!havePatt && !haveInput) return True; 161d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 162d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj // end of cases 163d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj vg_assert(0); 164d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj} 165d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 166d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 167d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/* And a parameterization of the above, to make it do 168d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj string matching. 169d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj*/ 1703e7986312a0ffc7646b0552d4c4ea3744a870e73florianstatic Bool charIsStar ( const void* pV ) { return *(const HChar*)pV == '*'; } 1713e7986312a0ffc7646b0552d4c4ea3744a870e73florianstatic Bool charIsQuery ( const void* pV ) { return *(const HChar*)pV == '?'; } 1723e7986312a0ffc7646b0552d4c4ea3744a870e73florianstatic Bool char_p_EQ_i ( const void* pV, const void* cV, 17313a59524748a7af0f403e4aba435144fa9a6af4cphilippe void* null_completer, UWord ixcV ) { 1743e7986312a0ffc7646b0552d4c4ea3744a870e73florian HChar p = *(const HChar*)pV; 1753e7986312a0ffc7646b0552d4c4ea3744a870e73florian HChar c = *(const HChar*)cV; 176d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj vg_assert(p != '*' && p != '?'); 177d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj return p == c; 178d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj} 17919f91bbaedb4caef8a60ce94b0f507193cc0bc10florianBool VG_(string_match) ( const HChar* patt, const HChar* input ) 180d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj{ 181d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj return VG_(generic_match)( 182d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj True/* match-all */, 1833e7986312a0ffc7646b0552d4c4ea3744a870e73florian patt, sizeof(HChar), VG_(strlen)(patt), 0, 1843e7986312a0ffc7646b0552d4c4ea3744a870e73florian input, sizeof(HChar), VG_(strlen)(input), 0, 18513a59524748a7af0f403e4aba435144fa9a6af4cphilippe charIsStar, charIsQuery, char_p_EQ_i, 186a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe NULL, NULL 187d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj ); 188d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj} 189d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 190d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 191d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// test cases for the matcher (in match-all mode) 192d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// typedef struct { char* patt; char* input; Bool xres; } Test; 193d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// 194d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj//static Test tests[] = 195d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { 196d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "" ,"" , True }, 197d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "a" ,"" , False }, 198d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "a" ,"b" , False }, 199d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "a" ,"a" , True }, 200d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "a" ,"aa" , False }, 201d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "*" ,"" , True }, 202d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "**" ,"" , True }, 203d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "*" ,"abc", True }, 204d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "*a" ,"abc", False }, 205d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "*b" ,"abc", False }, 206d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "*bc" ,"abc", True }, 207d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "a*b" ,"abc", False }, 208d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "a*c" ,"abc", True }, 209d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "*c" ,"abc", True }, 210d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "c*c" ,"abc", False }, 211d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "abc*" ,"abc", True }, 212d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "abc**" ,"abc", True }, 213d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "**abc" ,"abc", True }, 214d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "**a*b*c**" ,"abc", True }, 215d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "**a*b*d**" ,"abc", False }, 216d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "a?b" ,"abc", False }, 217d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "a?c" ,"abc", True }, 218d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "?" ,"" , False }, 219d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "?" ,"a" , True }, 220d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "?" ,"ab" , False }, 221d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "abcd" ,"abc", False }, 222d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { "ab" ,"abc", False }, 223d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// { NULL ,NULL , False } 224d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// }; 225d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// 226d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj//int main ( void ) 227d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj//{ 228d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// Test* t; 229d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// for (t = tests; t->patt; t++) { 230866862a87a06a70e2e0c0d7e5c773e252db8ecddflorian// printf("%-10s %-6s %s\n", 231d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// t->patt, t->input, 232d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// match_string_all((UChar*)t->patt,(UChar*)t->input,True) 233d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// == t->xres 234d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// ? "pass" : "FAIL" ); 235d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// } 236d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj// return 0; 237d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj//} 238d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj 239d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*--------------------------------------------------------------------*/ 240d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*--- end m_seqmatch.c ---*/ 241d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*--------------------------------------------------------------------*/ 242