/[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 41 by nigel, Sat Feb 24 21:39:17 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-1999 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 };
50    
51  static int eint[] = {  static int eint[] = {
52    REG_EESCAPE, /* "\\ at end of pattern" */    REG_EESCAPE, /* "\\ at end of pattern" */
# Line 67  static int eint[] = { Line 71  static int eint[] = {
71    REG_ESIZE,   /* "regular expression too large" */    REG_ESIZE,   /* "regular expression too large" */
72    REG_ESPACE,  /* "failed to get memory" */    REG_ESPACE,  /* "failed to get memory" */
73    REG_EPAREN,  /* "unmatched brackets" */    REG_EPAREN,  /* "unmatched brackets" */
74    REG_ASSERT   /* "internal error: code overflow" */    REG_ASSERT,  /* "internal error: code overflow" */
75      REG_BADPAT,  /* "unrecognized character after (?<" */
76      REG_BADPAT,  /* "lookbehind assertion is not fixed length" */
77      REG_BADPAT,  /* "malformed number after (?(" */
78      REG_BADPAT,  /* "conditional group containe more than two branches" */
79      REG_BADPAT   /* "assertion expected after (?(" */
80  };  };
81    
82  /* Table of texts corresponding to POSIX error codes */  /* Table of texts corresponding to POSIX error codes */
83    
84  static char *pstring[] = {  static const char *pstring[] = {
85    "",                                /* Dummy for value 0 */    "",                                /* Dummy for value 0 */
86    "internal error",                  /* REG_ASSERT */    "internal error",                  /* REG_ASSERT */
87    "invalid repeat counts in {}",     /* BADBR      */    "invalid repeat counts in {}",     /* BADBR      */
# Line 106  look them up in a table to turn them int Line 115  look them up in a table to turn them int
115  static int  static int
116  pcre_posix_error_code(const char *s)  pcre_posix_error_code(const char *s)
117  {  {
118  int i;  size_t i;
119  for (i = 0; i < sizeof(estring)/sizeof(char *); i++)  for (i = 0; i < sizeof(estring)/sizeof(char *); i++)
120    if (strcmp(s, estring[i]) == 0) return eint[i];    if (strcmp(s, estring[i]) == 0) return eint[i];
121  return REG_ASSERT;  return REG_ASSERT;
# Line 121  return REG_ASSERT; Line 130  return REG_ASSERT;
130  size_t  size_t
131  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)
132  {  {
133  char *message, *addmessage;  const char *message, *addmessage;
134  int length, adlength;  size_t length, addlength;
135    
136  message = (errcode >= sizeof(pstring)/sizeof(char *))?  message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))?
137    "unknown error code" : pstring[errcode];    "unknown error code" : pstring[errcode];
138    length = strlen(message) + 1;
139    
140  length = (int)strlen(message) + 1;  addmessage = " at offset ";
141    addlength = (preg != NULL && (int)preg->re_erroffset != -1)?
142  if (preg != NULL && (int)preg->re_erroffset != -1)    strlen(addmessage) + 6 : 0;
   {  
   addmessage = " at offset ";  
   adlength = (int)strlen(addmessage) + 6;  
   }  
 else adlength = 0;  
143    
144  if (errbuf_size > 0)  if (errbuf_size > 0)
145    {    {
146    if (adlength > 0 && errbuf_size >= length + adlength)    if (addlength > 0 && errbuf_size >= length + addlength)
147      sprintf(errbuf, "%s%s%-6d", message, addmessage, preg->re_erroffset);      sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset);
148    else    else
149      {      {
150      strncpy(errbuf, message, errbuf_size - 1);      strncpy(errbuf, message, errbuf_size - 1);
# Line 147  if (errbuf_size > 0) Line 152  if (errbuf_size > 0)
152      }      }
153    }    }
154    
155  return length + adlength;  return length + addlength;
156  }  }
157    
158    
# Line 183  Returns:      0 on success Line 188  Returns:      0 on success
188  int  int
189  regcomp(regex_t *preg, const char *pattern, int cflags)  regcomp(regex_t *preg, const char *pattern, int cflags)
190  {  {
191  char *errorptr;  const char *errorptr;
192  int erroffset;  int erroffset;
193  int options = 0;  int options = 0;
194    
195  if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS;  if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS;
196  if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE;  if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE;
197    
198  preg->re_pcre = pcre_compile(pattern, options, &errorptr, &erroffset);  preg->re_pcre = pcre_compile(pattern, options, &errorptr, &erroffset, NULL);
199  preg->re_erroffset = erroffset;  preg->re_erroffset = erroffset;
200    
201  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 211  return 0;
211  *              Match a regular expression        *  *              Match a regular expression        *
212  *************************************************/  *************************************************/
213    
214    /* Unfortunately, PCRE requires 3 ints of working space for each captured
215    substring, so we have to get and release working store instead of just using
216    the POSIX structures as was done in earlier releases when PCRE needed only 2
217    ints. */
218    
219  int  int
220  regexec(regex_t *preg, const char *string, size_t nmatch,  regexec(regex_t *preg, const char *string, size_t nmatch,
221    regmatch_t pmatch[], int eflags)    regmatch_t pmatch[], int eflags)
222  {  {
223  int rc;  int rc;
224  int options = 0;  int options = 0;
225    int *ovector = NULL;
226    
227  if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;  if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
228  if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;  if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
229    
230  preg->re_erroffset = -1;   /* Only has meaning after compile */  preg->re_erroffset = (size_t)(-1);   /* Only has meaning after compile */
231    
232    if (nmatch > 0)
233      {
234      ovector = malloc(sizeof(int) * nmatch * 3);
235      if (ovector == NULL) return REG_ESPACE;
236      }
237    
238  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,
239    (int *)pmatch, nmatch * 2);    ovector, nmatch * 3);
240    
241  if (rc == 0) return 0;    /* All pmatch were filled in */  if (rc == 0) rc = nmatch;    /* All captured slots were filled in */
242    
243  if (rc > 0)  if (rc >= 0)
244    {    {
245    int i;    size_t i;
246    for (i = rc; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;    for (i = 0; i < rc; i++)
247        {
248        pmatch[i].rm_so = ovector[i*2];
249        pmatch[i].rm_eo = ovector[i*2+1];
250        }
251      if (ovector != NULL) free(ovector);
252      for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
253    return 0;    return 0;
254    }    }
255    
256  else switch(rc)  else
257    {    {
258    case PCRE_ERROR_NOMATCH: return REG_NOMATCH;    if (ovector != NULL) free(ovector);
259    case PCRE_ERROR_BADREF: return REG_ESUBREG;    switch(rc)
260    case PCRE_ERROR_NULL: return REG_INVARG;      {
261    case PCRE_ERROR_BADOPTION: return REG_INVARG;      case PCRE_ERROR_NOMATCH: return REG_NOMATCH;
262    case PCRE_ERROR_BADMAGIC: return REG_INVARG;      case PCRE_ERROR_NULL: return REG_INVARG;
263    case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT;      case PCRE_ERROR_BADOPTION: return REG_INVARG;
264    case PCRE_ERROR_NOMEMORY: return REG_ESPACE;      case PCRE_ERROR_BADMAGIC: return REG_INVARG;
265    default: return REG_ASSERT;      case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT;
266        case PCRE_ERROR_NOMEMORY: return REG_ESPACE;
267        default: return REG_ASSERT;
268        }
269    }    }
270  }  }
271    

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

  ViewVC Help
Powered by ViewVC 1.1.5