/[pcre]/code/trunk/pcreposix.c
ViewVC logotype

Diff of /code/trunk/pcreposix.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3 by nigel, Sat Feb 24 21:38:01 2007 UTC revision 53 by nigel, Sat Feb 24 21:39:42 2007 UTC
# Line 12  functions. Line 12  functions.
12    
13  Written by: Philip Hazel <ph10@cam.ac.uk>  Written by: Philip Hazel <ph10@cam.ac.uk>
14    
15             Copyright (c) 1997 University of Cambridge             Copyright (c) 1997-2001 University of Cambridge
16    
17  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
18  Permission is granted to anyone to use this software for any purpose on any  Permission is granted to anyone to use this software for any purpose on any
# Line 28  restrictions: Line 28  restrictions:
28    
29  3. Altered versions must be plainly marked as such, and must not be  3. Altered versions must be plainly marked as such, and must not be
30     misrepresented as being the original software.     misrepresented as being the original software.
31    
32    4. If PCRE is embedded in any software that is released under the GNU
33       General Purpose Licence (GPL), then the terms of that licence shall
34       supersede any condition above with which it is incompatible.
35  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
36  */  */
37    
# Line 39  restrictions: Line 43  restrictions:
43    
44  /* Corresponding tables of PCRE error messages and POSIX error codes. */  /* Corresponding tables of PCRE error messages and POSIX error codes. */
45    
46  static char *estring[] = {  static const char *estring[] = {
47    ERR1,  ERR2,  ERR3,  ERR4,  ERR5,  ERR6,  ERR7,  ERR8,  ERR9,  ERR10,    ERR1,  ERR2,  ERR3,  ERR4,  ERR5,  ERR6,  ERR7,  ERR8,  ERR9,  ERR10,
48    ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20,    ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20,
49    ERR21, ERR22, ERR23 };    ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR29, ERR29, ERR30,
50      ERR31 };
51    
52  static int eint[] = {  static int eint[] = {
53    REG_EESCAPE, /* "\\ at end of pattern" */    REG_EESCAPE, /* "\\ at end of pattern" */
# Line 57  static int eint[] = { Line 62  static int eint[] = {
62    REG_BADRPT,  /* "operand of unlimited repeat could match the empty string" */    REG_BADRPT,  /* "operand of unlimited repeat could match the empty string" */
63    REG_ASSERT,  /* "internal error: unexpected repeat" */    REG_ASSERT,  /* "internal error: unexpected repeat" */
64    REG_BADPAT,  /* "unrecognized character after (?" */    REG_BADPAT,  /* "unrecognized character after (?" */
65    REG_ESIZE,   /* "too many capturing parenthesized sub-patterns" */    REG_ASSERT,  /* "unused error" */
66    REG_EPAREN,  /* "missing )" */    REG_EPAREN,  /* "missing )" */
67    REG_ESUBREG, /* "back reference to non-existent subpattern" */    REG_ESUBREG, /* "back reference to non-existent subpattern" */
68    REG_INVARG,  /* "erroffset passed as NULL" */    REG_INVARG,  /* "erroffset passed as NULL" */
69    REG_INVARG,  /* "unknown option bit(s) set" */    REG_INVARG,  /* "unknown option bit(s) set" */
70    REG_EPAREN,  /* "missing ) after comment" */    REG_EPAREN,  /* "missing ) after comment" */
71    REG_ESIZE,   /* "too many sets of parentheses" */    REG_ESIZE,   /* "parentheses nested too deeply" */
72    REG_ESIZE,   /* "regular expression too large" */    REG_ESIZE,   /* "regular expression too large" */
73    REG_ESPACE,  /* "failed to get memory" */    REG_ESPACE,  /* "failed to get memory" */
74    REG_EPAREN,  /* "unmatched brackets" */    REG_EPAREN,  /* "unmatched brackets" */
75    REG_ASSERT   /* "internal error: code overflow" */    REG_ASSERT,  /* "internal error: code overflow" */
76      REG_BADPAT,  /* "unrecognized character after (?<" */
77      REG_BADPAT,  /* "lookbehind assertion is not fixed length" */
78      REG_BADPAT,  /* "malformed number after (?(" */
79      REG_BADPAT,  /* "conditional group containe more than two branches" */
80      REG_BADPAT,  /* "assertion expected after (?(" */
81      REG_BADPAT,  /* "(?p must be followed by )" */
82      REG_ECTYPE,  /* "unknown POSIX class name" */
83      REG_BADPAT,  /* "POSIX collating elements are not supported" */
84      REG_INVARG,  /* "this version of PCRE is not compiled with PCRE_UTF8 support" */
85      REG_BADPAT,  /* "characters with values > 255 are not yet supported in classes" */
86      REG_BADPAT,  /* "character value in \x{...} sequence is too large" */
87      REG_BADPAT   /* "invalid condition (?(0)" */
88  };  };
89    
90  /* Table of texts corresponding to POSIX error codes */  /* Table of texts corresponding to POSIX error codes */
91    
92  static char *pstring[] = {  static const char *pstring[] = {
93    "",                                /* Dummy for value 0 */    "",                                /* Dummy for value 0 */
94    "internal error",                  /* REG_ASSERT */    "internal error",                  /* REG_ASSERT */
95    "invalid repeat counts in {}",     /* BADBR      */    "invalid repeat counts in {}",     /* BADBR      */
# Line 106  look them up in a table to turn them int Line 123  look them up in a table to turn them int
123  static int  static int
124  pcre_posix_error_code(const char *s)  pcre_posix_error_code(const char *s)
125  {  {
126  int i;  size_t i;
127  for (i = 0; i < sizeof(estring)/sizeof(char *); i++)  for (i = 0; i < sizeof(estring)/sizeof(char *); i++)
128    if (strcmp(s, estring[i]) == 0) return eint[i];    if (strcmp(s, estring[i]) == 0) return eint[i];
129  return REG_ASSERT;  return REG_ASSERT;
# Line 121  return REG_ASSERT; Line 138  return REG_ASSERT;
138  size_t  size_t
139  regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)  regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
140  {  {
141  char *message, *addmessage;  const char *message, *addmessage;
142  int length, adlength;  size_t length, addlength;
143    
144  message = (errcode >= sizeof(pstring)/sizeof(char *))?  message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))?
145    "unknown error code" : pstring[errcode];    "unknown error code" : pstring[errcode];
146    length = strlen(message) + 1;
147    
148  length = (int)strlen(message) + 1;  addmessage = " at offset ";
149    addlength = (preg != NULL && (int)preg->re_erroffset != -1)?
150  if (preg != NULL && (int)preg->re_erroffset != -1)    strlen(addmessage) + 6 : 0;
   {  
   addmessage = " at offset ";  
   adlength = (int)strlen(addmessage) + 6;  
   }  
 else adlength = 0;  
151    
152  if (errbuf_size > 0)  if (errbuf_size > 0)
153    {    {
154    if (adlength > 0 && errbuf_size >= length + adlength)    if (addlength > 0 && errbuf_size >= length + addlength)
155      sprintf(errbuf, "%s%s%-6d", message, addmessage, preg->re_erroffset);      sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset);
156    else    else
157      {      {
158      strncpy(errbuf, message, errbuf_size - 1);      strncpy(errbuf, message, errbuf_size - 1);
# Line 147  if (errbuf_size > 0) Line 160  if (errbuf_size > 0)
160      }      }
161    }    }
162    
163  return length + adlength;  return length + addlength;
164  }  }
165    
166    
# Line 183  Returns:      0 on success Line 196  Returns:      0 on success
196  int  int
197  regcomp(regex_t *preg, const char *pattern, int cflags)  regcomp(regex_t *preg, const char *pattern, int cflags)
198  {  {
199  char *errorptr;  const char *errorptr;
200  int erroffset;  int erroffset;
201  int options = 0;  int options = 0;
202    
203  if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS;  if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS;
204  if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE;  if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE;
205    
206  preg->re_pcre = pcre_compile(pattern, options, &errorptr, &erroffset);  preg->re_pcre = pcre_compile(pattern, options, &errorptr, &erroffset, NULL);
207  preg->re_erroffset = erroffset;  preg->re_erroffset = erroffset;
208    
209  if (preg->re_pcre == NULL) return pcre_posix_error_code(errorptr);  if (preg->re_pcre == NULL) return pcre_posix_error_code(errorptr);
# Line 206  return 0; Line 219  return 0;
219  *              Match a regular expression        *  *              Match a regular expression        *
220  *************************************************/  *************************************************/
221    
222    /* Unfortunately, PCRE requires 3 ints of working space for each captured
223    substring, so we have to get and release working store instead of just using
224    the POSIX structures as was done in earlier releases when PCRE needed only 2
225    ints. */
226    
227  int  int
228  regexec(regex_t *preg, const char *string, size_t nmatch,  regexec(regex_t *preg, const char *string, size_t nmatch,
229    regmatch_t pmatch[], int eflags)    regmatch_t pmatch[], int eflags)
230  {  {
231  int rc;  int rc;
232  int options = 0;  int options = 0;
233    int *ovector = NULL;
234    
235  if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;  if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
236  if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;  if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
237    
238  preg->re_erroffset = -1;   /* Only has meaning after compile */  preg->re_erroffset = (size_t)(-1);   /* Only has meaning after compile */
239    
240    if (nmatch > 0)
241      {
242      ovector = (int *)malloc(sizeof(int) * nmatch * 3);
243      if (ovector == NULL) return REG_ESPACE;
244      }
245    
246  rc = pcre_exec(preg->re_pcre, NULL, string, (int)strlen(string), options,  rc = pcre_exec(preg->re_pcre, NULL, string, (int)strlen(string), 0, options,
247    (int *)pmatch, nmatch * 2);    ovector, nmatch * 3);
248    
249  if (rc == 0) return 0;    /* All pmatch were filled in */  if (rc == 0) rc = nmatch;    /* All captured slots were filled in */
250    
251  if (rc > 0)  if (rc >= 0)
252    {    {
253    int i;    size_t i;
254    for (i = rc; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;    for (i = 0; i < rc; i++)
255        {
256        pmatch[i].rm_so = ovector[i*2];
257        pmatch[i].rm_eo = ovector[i*2+1];
258        }
259      if (ovector != NULL) free(ovector);
260      for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
261    return 0;    return 0;
262    }    }
263    
264  else switch(rc)  else
265    {    {
266    case PCRE_ERROR_NOMATCH: return REG_NOMATCH;    if (ovector != NULL) free(ovector);
267    case PCRE_ERROR_BADREF: return REG_ESUBREG;    switch(rc)
268    case PCRE_ERROR_NULL: return REG_INVARG;      {
269    case PCRE_ERROR_BADOPTION: return REG_INVARG;      case PCRE_ERROR_NOMATCH: return REG_NOMATCH;
270    case PCRE_ERROR_BADMAGIC: return REG_INVARG;      case PCRE_ERROR_NULL: return REG_INVARG;
271    case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT;      case PCRE_ERROR_BADOPTION: return REG_INVARG;
272    case PCRE_ERROR_NOMEMORY: return REG_ESPACE;      case PCRE_ERROR_BADMAGIC: return REG_INVARG;
273    default: return REG_ASSERT;      case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT;
274        case PCRE_ERROR_NOMEMORY: return REG_ESPACE;
275        default: return REG_ASSERT;
276        }
277    }    }
278  }  }
279    

Legend:
Removed from v.3  
changed lines
  Added in v.53

  ViewVC Help
Powered by ViewVC 1.1.5