head 1.23; access; symbols STR_0_9_12:1.22 LMTP2NNTP_1_4_1:1.21 LMTP2NNTP_1_4_0:1.21 STR_0_9_11:1.21 STR_0_9_10:1.21 LMTP2NNTP_1_3_0:1.20 LMTP2NNTP_1_3b2:1.20 LMTP2NNTP_1_3b1:1.20 LMTP2NNTP_1_3a3:1.20 LMTP2NNTP_1_3a2:1.20 STR_0_9_9:1.20 LMTP2NNTP_1_3a1:1.20 STR_0_9_8:1.20 LMTP2NNTP_1_2_0:1.20 LMTP2NNTP_1_2b4:1.20 LMTP2NNTP_1_2b3:1.20 LMTP2NNTP_1_2b2:1.20 LMTP2NNTP_1_2b1:1.20 LMTP2NNTP_1_2a8:1.20 LMTP2NNTP_1_2a7:1.20 LMTP2NNTP_1_2a6:1.19 LMTP2NNTP_1_2a5:1.19 STR_0_9_7:1.19 LMTP2NNTP_1_2a4:1.18 LMTP2NNTP_1_2a3:1.18 OSSP_RC_SPEC:1.18 LMTP2NNTP_1_2a1:1.17 LMTP2NNTP_1_1_1:1.17 LMTP2NNTP_1_1_0:1.17 LMTP2NNTP_1_1b4:1.17 LMTP2NNTP_1_1b3:1.17 LMTP2NNTP_1_1b2:1.17 LMTP2NNTP_1_1b1:1.17 STR_0_9_6:1.17 STR_0_9_5:1.14 STR_0_9_4:1.13 STR_0_9_3:1.13 STR_0_9_2:1.13 STR_0_9_1:1.11 STR_0_9_0:1.10; locks; strict; comment @ * @; 1.23 date 2008.06.06.12.28.54; author rse; state Exp; branches; next 1.22; commitid AXPIzNjsx3yzYS5t; 1.22 date 2005.10.12.08.24.30; author rse; state Exp; branches; next 1.21; 1.21 date 2005.01.24.15.22.19; author rse; state Exp; branches; next 1.20; 1.20 date 2003.01.06.19.13.47; author rse; state Exp; branches; next 1.19; 1.19 date 2002.04.01.08.32.54; author rse; state Exp; branches; next 1.18; 1.18 date 2002.01.02.17.09.13; author rse; state Exp; branches; next 1.17; 1.17 date 2001.09.11.13.20.27; author rse; state Exp; branches; next 1.16; 1.16 date 2001.09.11.11.39.28; author rse; state Exp; branches; next 1.15; 1.15 date 2001.08.28.10.38.44; author rse; state Exp; branches; next 1.14; 1.14 date 2001.08.16.13.21.23; author rse; state Exp; branches; next 1.13; 1.13 date 2000.01.20.20.42.11; author rse; state Exp; branches; next 1.12; 1.12 date 2000.01.10.11.55.58; author rse; state Exp; branches; next 1.11; 1.11 date 2000.01.09.19.11.43; author rse; state Exp; branches; next 1.10; 1.10 date 2000.01.01.13.05.18; author rse; state Exp; branches; next 1.9; 1.9 date 99.12.28.10.19.00; author rse; state Exp; branches; next 1.8; 1.8 date 99.12.27.15.53.31; author rse; state Exp; branches; next 1.7; 1.7 date 99.12.26.15.37.34; author rse; state Exp; branches; next 1.6; 1.6 date 99.12.25.18.33.25; author rse; state Exp; branches; next 1.5; 1.5 date 99.12.25.18.23.02; author rse; state Exp; branches; next 1.4; 1.4 date 99.11.26.16.48.27; author rse; state Exp; branches; next 1.3; 1.3 date 99.11.23.16.08.11; author rse; state Exp; branches; next 1.2; 1.2 date 99.11.23.08.58.42; author rse; state Exp; branches; next 1.1; 1.1 date 99.11.23.08.57.35; author rse; state Exp; branches; next ; desc @@ 1.23 log @fix pattern lookup algorihtm @ text @/* ** OSSP str - String Handling ** Copyright (c) 1999-2005 Ralf S. Engelschall ** Copyright (c) 1999-2005 The OSSP Project ** ** This file is part of OSSP str, a string handling and manipulation ** library which can be found at http://www.ossp.org/pkg/lib/str/. ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** str_parse.c: parsing functions */ #include "str_p.h" /* compile a regular expression pattern from string into internal format */ static int pattern_compile( const char *ptr, int len, int opt, pcre **p_pcre, pcre_extra **p_pcre_extra) { const char *err_str; char buf[128]; int err_pos; char *cp; if (ptr[len] == NUL) { /* plain string, so we can speed up processing... */ *p_pcre = pcre_compile(ptr, opt, &err_str, &err_pos, NULL); } else { /* ...else we have to create a temporary NUL-terminated string */ if (len < sizeof(buf)) { /* either we use a local buffer to avoid malloc/free ping-pong... */ memcpy(buf, ptr, len); buf[len] = NUL; *p_pcre = pcre_compile(buf, opt, &err_str, &err_pos, NULL); } else { /* ...or we have to actually allocate a memory chunk :-( */ if ((cp = malloc(len+1)) == NULL) return FALSE; memcpy(cp, ptr, len); cp[len] = NUL; *p_pcre = pcre_compile(cp, opt, &err_str, &err_pos, NULL); free(cp); } } if (*p_pcre == NULL) return FALSE; /* optionally study pattern */ if (p_pcre_extra != NULL) { *p_pcre_extra = pcre_study(*p_pcre, 0, &err_str); if (err_str != NULL) { free(p_pcre); return FALSE; } } return TRUE; } /* the hash table entry in the pattern cache */ struct hash_entry { struct hash_entry *next; char *key; int keylen; pcre *p_pcre; pcre_extra *p_pcre_extra; }; /* size of the cache hash table; is prime */ #define HASH_SIZE 101 /* the pattern cache hash table */ static struct hash_entry *pattern_hash[HASH_SIZE]; /* initialization flag for hash table */ static int hash_initialized = FALSE; /* initialize cache hash table */ static void hash_init(void) { int i; for (i = 0; i < HASH_SIZE; i++) pattern_hash[i] = NULL; return; } /* destroy cache hash table */ static void hash_destroy(void) { int i; struct hash_entry *he, *ohe; for (i = 0; i < HASH_SIZE; i++) { he = pattern_hash[i]; pattern_hash[i] = NULL; while (he != NULL) { ohe = he; he = he->next; if (ohe->key != NULL) free(ohe->key); free(ohe); } } return; } /* the hashing function: a popular `times 33' hash */ static unsigned int hash_func( const char *key, int keylen) { unsigned int h; int i; h = 0xDEAD; for (i = 0; key[i] != NUL; i++) h = ((((h<<5)+h)+key[i]) % HASH_SIZE); return h; } /* cache a pattern */ static void pattern_cache( const char *key, int keylen, pcre *p_pcre, pcre_extra *p_pcre_extra) { int h; struct hash_entry *he, *che; if ((he = (struct hash_entry *)malloc(sizeof(struct hash_entry))) == NULL) return; if ((he->key = malloc(keylen)) == NULL) { free(he); return; } he->next = NULL; memcpy(he->key, key, keylen); he->keylen = keylen; he->p_pcre = p_pcre; he->p_pcre_extra = p_pcre_extra; h = hash_func(key, keylen); if (pattern_hash[h] == NULL) pattern_hash[h] = he; else { che = pattern_hash[h]; while (che->next != NULL) che = che->next; che->next = he; } return; } /* lookup a pattern */ static void pattern_lookup( const char *key, int keylen, pcre **p_pcre, pcre_extra **p_pcre_extra) { int h; struct hash_entry *he; *p_pcre = NULL; *p_pcre_extra = NULL; h = hash_func(key, keylen); he = pattern_hash[h]; while (he != NULL) { if (he->keylen == keylen) if (memcmp(he->key, key, keylen)) break; he = he->next; } if (he == NULL) return; *p_pcre = he->p_pcre; *p_pcre_extra = he->p_pcre_extra; return; } static int str_parse_flush_nop( str_vformat_t *sf) { sf->data[2].i = sf->data[2].i + sf->data[1].i; sf->curpos = (char *)sf->data[0].p; return 0; } static int str_parse_flush_str( str_vformat_t *sf) { return -1; } static char * str_parse_format( str_vformat_t *sf, char *cpPrefix, char *cpPad, int *ipStrLen, char *cpBuf, int nBufLen, char *cpExtinfo, int cFmt, va_list ap) { char *pStr; int n; int *cap_vec; int cap_num; char *string; pStr = NULL; if (cFmt == 'R') { if (cpExtinfo != NULL && str_isdigit(cpExtinfo[0]) && cpExtinfo[1] == NUL) { n = cpExtinfo[0] - '0'; string = (char *)sf->data[3].p; cap_vec = (int *)sf->data[4].p; cap_num = sf->data[5].i; if (n <= cap_num) { if (cap_vec[(n*2)] != -1 && cap_vec[(n*2)+1] != -1) { pStr = (char *)(string+cap_vec[(n*2)]); *ipStrLen = (cap_vec[(n*2)+1] - cap_vec[(n*2)]); } } } } return pStr; } /* the API parsing function */ int str_parse(const char *string, const char *pattern, ...) { va_list ap; int rv; va_start(ap, pattern); rv = str_parse_va(string, pattern, ap); va_end(ap); return rv; } int str_parse_va(const char *string, const char *pattern, va_list ap) { pcre *p_pcre = NULL; pcre_extra *p_pcre_extra = NULL; const char *match_ptr; int match_len; int match_opt; int match_once; int match_1resbuf; const char *subst_ptr; int subst_len; int *cap_vec; int cap_num; int cap_len; char *cp; char *cp2; char **cpp; char cb[2]; int n; int i; int k; int l; int ismop; int issop; char buf[128]; char buf2[128]; char *buf_ptr; str_vformat_t sf; va_list ap_temp; /* * Caching support */ /* hash table initialization */ if (!hash_initialized) { hash_init(); atexit(hash_destroy); hash_initialized = TRUE; } /* hash table destruction */ if (string == NULL && pattern == NULL) { hash_destroy(); return 0; } /* * Check input parameters */ if (string == NULL || pattern == NULL) return -1; /* * Parse pattern */ match_ptr = NULL; match_len = 0; match_opt = 0; match_once = FALSE; match_1resbuf = FALSE; subst_ptr = NULL; subst_len = 0; ismop = FALSE; issop = FALSE; cp = NULL; /* compiler happyness only */ cp2 = NULL; /* compiler happyness only */ /* determine type of pattern and remember important positions */ if (*pattern == 'm' && str_len(pattern) >= 3) if ((cp = str_span(pattern, 0, "imsxob", STR_RIGHT)) > pattern+1) if (*(pattern+1) == *cp) ismop = TRUE; if (!ismop) if (*pattern == 's' && str_len(pattern) >= 4) if ((cp = str_span(pattern, 0, "imsxo", STR_RIGHT)) > pattern+1) if ((cb[0] = *cp, cb[1] = NUL, cp2 = str_span(pattern, cp-pattern, cb, STR_RIGHT|STR_COMPLEMENT)) > pattern+1) if (*(pattern+1) == *cp && *(pattern+1) == *cp2) issop = TRUE; /* finish parsing */ if (ismop) { /* pattern is a match operation */ match_ptr = pattern + 2; match_len = cp - match_ptr; cp++; for (i = 0; cp[i] != NUL; i++) { switch (cp[i]) { case 'i': match_opt |= PCRE_CASELESS; break; case 'm': match_opt |= PCRE_MULTILINE; break; case 's': match_opt |= PCRE_DOTALL; break; case 'x': match_opt |= PCRE_EXTENDED; break; case 'o': match_once = TRUE; break; case 'b': match_1resbuf = TRUE; break; default: return -1; } } } else if (issop) { /* pattern is a substitute operation */ match_ptr = pattern + 2; match_len = cp2 - match_ptr; subst_ptr = cp2 + 1; subst_len = cp - subst_ptr; cp++; for (i = 0; cp[i] != NUL; i++) { switch (cp[i]) { case 'i': match_opt |= PCRE_CASELESS; break; case 'm': match_opt |= PCRE_MULTILINE; break; case 's': match_opt |= PCRE_DOTALL; break; case 'x': match_opt |= PCRE_EXTENDED; break; case 'o': match_once = TRUE; break; default: return -1; } } } else { /* fallback: treat pattern as a match operation */ match_ptr = pattern; match_len = str_len(pattern); ismop = TRUE; } /* * Compile pattern into internal PCRE structure */ if (match_once) { /* optimized processing: up to factor 15(!) for complex regular expressions */ pattern_lookup(match_ptr, match_len, &p_pcre, &p_pcre_extra); if (p_pcre == NULL) { if (!pattern_compile(match_ptr, match_len, match_opt, &p_pcre, &p_pcre_extra)) return -1; pattern_cache(match_ptr, match_len, p_pcre, p_pcre_extra); } } else { /* unoptimized processing */ p_pcre_extra = NULL; if (!pattern_compile(match_ptr, match_len, match_opt, &p_pcre, NULL)) return -1; } /* * Allocate storage for offset table of captured substrings */ cap_vec = NULL; cap_len = 0; cap_num = pcre_info(p_pcre, NULL, NULL); if (cap_num > 0) { cap_len = (cap_num+1)*3; if ((cap_vec = (int *)malloc(cap_len*sizeof(int))) == NULL) { if (p_pcre != NULL) free(p_pcre); if (p_pcre_extra != NULL) free(p_pcre_extra); return -1; } } /* * Perform the matching operation */ n = pcre_exec(p_pcre, p_pcre_extra, string, str_len(string), 0, 0, cap_vec, cap_len); if (n < 0) { if (cap_vec != NULL) free(cap_vec); if (p_pcre != NULL) free(p_pcre); if (p_pcre_extra != NULL) free(p_pcre_extra); if (n == PCRE_ERROR_NOMATCH) return 0; return -1; } /* * Create either matching or substitution result */ if (ismop && cap_num > 0) { /* * extract captured substrings into caller provided pointer variables */ if (match_1resbuf) { /* use a single result buffer */ l = 0; for (i = 1; i <= cap_num && i <= (n-1); i++) { if (cap_vec[(i*2)] != -1 && cap_vec[(i*2)+1] != -1) { k = (cap_vec[(i*2)+1] - cap_vec[(i*2)]); if (k > 0) l += k+1; } } cpp = va_arg(ap, char **); if (cpp == NULL) cpp = &cp; if ((*cpp = malloc(l)) != NULL) { cp = *cpp; for (i = 1; i <= cap_num; i++) { cpp = va_arg(ap, char **); if (cpp != NULL) { if (i <= (n-1)) { if (cap_vec[(i*2)] != -1 && cap_vec[(i*2)+1] != -1) { k = (cap_vec[(i*2)+1] - cap_vec[(i*2)]); if (k > 0) { memcpy(cp, (char *)(string+cap_vec[(i*2)]), k); cp += k; *cp++ = NUL; continue; } } } *cpp = cp; *cp++ = NUL; } } } } else { /* use multiple result buffers */ for (i = 1; i <= cap_num; i++) { cpp = va_arg(ap, char **); if (cpp != NULL) { if (i <= (n-1)) { if (cap_vec[(i*2)] != -1 && cap_vec[(i*2)+1] != -1) { k = (cap_vec[(i*2)+1] - cap_vec[(i*2)]); if (k > 0) { if ((*cpp = malloc(k+1)) != NULL) { memcpy(*cpp, (char *)(string+cap_vec[(i*2)]), k); (*cpp)[k] = NUL; continue; } } } } *cpp = strdup(""); } } } } else if (issop) { /* * create a substitutional string with optional expansions */ /* determine required buffer len */ l = 0; for (cp = (char *)subst_ptr; cp < (subst_ptr+subst_len); cp++, l++) { if (*cp == '$') { if (!(cp > subst_ptr && *(cp-1) == '\\')) { if (cp < (subst_ptr+subst_len-1) && str_isdigit(*(cp+1))) { cp += 1; l += 4; } } } } l++; /* NUL char */ /* allocate temp buffer */ if (l <= sizeof(buf)) buf_ptr = buf; else buf_ptr = (char *)malloc(l); /* copy subst string into temp buffer and replace $N with %{N}R */ for (cp = (char *)subst_ptr, cp2 = buf_ptr; cp < (subst_ptr+subst_len); ) { if (*cp == '$') { if (!(cp > subst_ptr && *(cp-1) == '\\')) { if (cp < (subst_ptr+subst_len-1) && str_isdigit(*(cp+1))) { *cp2++ = '%'; *cp2++ = '{'; *cp2++ = *(cp+1); *cp2++ = '}'; *cp2++ = 'R'; cp += 2; continue; } } } *cp2++ = *cp++; } *cp2 = NUL; /* remove output argument from varargs */ cpp = va_arg(ap, char **); /* calculate output buffer requirement */ sf.curpos = buf2; sf.endpos = buf2 + sizeof(buf2) - 1; sf.flush = str_parse_flush_nop; sf.format = str_parse_format; sf.data[0].p = buf2; sf.data[1].i = sizeof(buf2); sf.data[2].i = 0; sf.data[3].p = (char *)string; sf.data[4].p = cap_vec; sf.data[5].i = cap_num; va_copy(ap_temp, ap); l = str_vformat(&sf, buf_ptr, ap_temp); /* allocate output buffer */ if ((*cpp = (char *)malloc(l+1)) == NULL) { if (cap_vec != NULL) free(cap_vec); if (p_pcre != NULL) free(p_pcre); if (p_pcre_extra != NULL) free(p_pcre_extra); return -1; /* XXX */ } /* finally expand the substitutions string into output buffer */ sf.curpos = *cpp; sf.endpos = *cpp + l; sf.flush = str_parse_flush_str; sf.format = str_parse_format; sf.data[3].p = (char *)string; sf.data[4].p = cap_vec; sf.data[5].i = cap_num; str_vformat(&sf, buf_ptr, ap); *((*cpp)+l) = NUL; /* free temp buffer */ if (buf_ptr != buf) free(buf_ptr); } /* cleanup */ if (cap_vec != NULL) free(cap_vec); if (p_pcre != NULL) free(p_pcre); if (p_pcre_extra != NULL) free(p_pcre_extra); /* return success */ return 1; } @ 1.22 log @Fixed str_parse(3): the va_list argument was incorrectly used twice for processing the arguments and hence lead to a segmentation faults. It is triggered by calls like str_parse(var, "s/^(.+?):(.+)$/$1-%s-$2/", &new, subst); Submitted by: Vasil Dimov @ text @d196 2 a197 3 if ((he = pattern_hash[h]) == NULL) return; while (he->next != NULL) { d203 2 @ 1.21 log @Adjusted copyright messages for new year 2004/2005. @ text @d300 1 d568 2 a569 1 l = str_vformat(&sf, buf_ptr, ap); @ 1.20 log @- adjust copyright messages for new year 2003 - strip trailing whitespaces - consistently use OSSP ASCII-art - add standard devtool.conf stuff from OSSP sa @ text @d3 2 a4 2 ** Copyright (c) 1999-2003 Ralf S. Engelschall ** Copyright (c) 1999-2003 The OSSP Project @ 1.19 log @finally switch to full OSSP branding @ text @d3 2 a4 2 ** Copyright (c) 1999-2002 Ralf S. Engelschall ** Copyright (c) 1999-2002 The OSSP Project d6 1 a6 1 ** This file is part of OSSP str, a string handling and manipulation d27 1 a27 1 ** str_parse.c: parsing functions d33 1 a33 1 static int d35 4 a38 4 const char *ptr, int len, int opt, pcre **p_pcre, d102 1 a102 1 static void d112 1 a112 1 static void d133 1 a133 1 static unsigned int d135 1 a135 1 const char *key, d148 1 a148 1 static void d150 3 a152 3 const char *key, int keylen, pcre *p_pcre, d182 1 a182 1 static void d184 3 a186 3 const char *key, int keylen, pcre **p_pcre, d209 1 a209 1 static int d212 1 a212 1 { d216 1 a216 1 } d218 1 a218 1 static int d221 1 a221 1 { d223 1 a223 1 } d229 1 a229 1 char *cpPad, d231 4 a234 4 char *cpBuf, int nBufLen, char *cpExtinfo, int cFmt, d242 1 a242 1 d276 1 a276 1 const char *match_ptr; d316 2 a317 2 /* * Check input parameters d322 1 a322 1 /* d344 1 a344 1 if ((cb[0] = *cp, cb[1] = NUL, d393 1 a393 1 /* d412 2 a413 2 /* * Allocate storage for offset table of captured substrings d429 1 a429 1 /* d449 2 a450 2 /* * extract captured substrings into caller provided pointer variables d510 1 a510 1 /* d556 1 a556 1 /* calculate output buffer requirement */ @ 1.18 log @bump copyright year @ text @d2 1 a2 1 ** Str - String Library d4 1 d6 2 a7 2 ** This file is part of Str, a string handling and manipulation ** library which can be found at http://www.engelschall.com/sw/str/. @ 1.17 log @fix one more memory leak @ text @d3 1 a3 1 ** Copyright (c) 1999-2001 Ralf S. Engelschall @ 1.16 log @try to fix memory leak @ text @d570 2 @ 1.15 log @Fix a memory leak in Str @ text @d273 2 a274 2 pcre *p_pcre; pcre_extra *p_pcre_extra; d420 1 a420 1 if (!match_once) { d422 1 a423 1 } d435 1 a435 1 if (!match_once) { d437 1 a438 1 } d569 5 a573 1 if ((*cpp = (char *)malloc(l+1)) == NULL) d575 1 d596 1 a596 1 if (!match_once) { d598 1 a599 1 } @ 1.14 log @Adjust copyright for year 2001. @ text @d123 2 @ 1.13 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999-2000 Ralf S. Engelschall @ 1.12 log @*** empty log message *** @ text @d261 10 a290 1 va_list ap; a444 1 va_start(ap, pattern); a584 1 va_end(ap); @ 1.11 log @*** empty log message *** @ text @d571 1 @ 1.10 log @*** empty log message *** @ text @d155 1 a155 1 if ((he = malloc(sizeof(struct hash_entry))) == NULL) d408 1 a408 1 if ((cap_vec = malloc(cap_len*sizeof(int))) == NULL) { @ 1.9 log @*** empty log message *** @ text @d3 1 a3 1 ** Copyright (c) 1999 Ralf S. Engelschall @ 1.8 log @*** empty log message *** @ text @a30 6 #ifdef STR_PCRE #include #endif #ifdef STR_PCRE a257 2 #endif /* STR_PCRE */ a260 3 #ifndef STR_PCRE return (-1); #else a586 1 #endif /* STR_PCRE */ @ 1.7 log @*** empty log message *** @ text @d214 1 a214 1 str_format_t *sf) d223 1 a223 1 str_format_t *sf) d230 1 a230 1 struct str_format_st *sf, d298 1 a298 1 str_format_t sf; @ 1.6 log @*** empty log message *** @ text @d337 1 a337 1 if ((cp = str_span(pattern, STR_FULL, "imsxob", STR_RIGHT)) > pattern+1) d342 1 a342 1 if ((cp = str_span(pattern, STR_FULL, "imsxo", STR_RIGHT)) > pattern+1) @ 1.5 log @*** empty log message *** @ text @a34 2 #include @ 1.4 log @*** empty log message *** @ text @d1 3 a3 2 /* ** str_match.c -- String Matching d5 2 a6 2 ** ==================================================================== ** Copyright (c) 1999 Ralf S. Engelschall. All rights reserved. d8 4 a11 3 ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions ** are met: d13 12 a24 2 ** 1. Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. d26 1 a26 18 ** 2. Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** ** THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY ** EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR ** ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ** STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ** OF THE POSSIBILITY OF SUCH DAMAGE. ** ==================================================================== @ 1.3 log @*** empty log message *** @ text @d224 1 a224 1 sf->curpos = (char *)sf->data[0].p; d303 1 a519 1 fprintf(stderr, "subst=<%s>\n", str_dup(subst_ptr, subst_len)); a559 2 fprintf(stderr, "buf_ptr=<%s>\n", buf_ptr); d564 2 a565 2 sf.curpos = buf; sf.endpos = buf + sizeof(buf) - 1; d568 2 a569 2 sf.data[0].p = buf; sf.data[1].i = sizeof(buf); @ 1.2 log @*** empty log message *** @ text @d34 1 a34 2 #include "str.h" #include "str_config.h" d219 52 d302 3 d306 3 a314 1 d321 3 a323 1 /* check input parameters */ d327 3 a329 1 /* parse pattern */ d337 5 a341 4 ismop = FALSE; issop = FALSE; cp = NULL; cp2 = NULL; d353 1 d355 1 d373 1 d392 1 d395 1 a396 2 fprintf(stderr, "match=<%s>\n", str_dup(match_ptr, match_len)); fprintf(stderr, "subst=<%s>\n", str_dup(subst_ptr, subst_len)); d398 3 a400 1 /* compile pattern into internal PCRE structure */ d417 3 a419 1 /* allocate storage for offset table of captured substrings */ d434 3 a436 1 /* perform the matching */ a437 2 /* error cases */ d450 8 a457 3 /* extract captured substrings into caller provided pointer variables */ if (cap_num > 0) { va_start(ap, pattern); a513 1 va_end(ap); d515 82 @ 1.1 log @*** empty log message *** @ text @d222 2 a223 2 /* the API matching function */ int str_match(const char *string, const char *pattern, ...) @