/[pcre]/code/tags/pcre-4.5/pcreposix.c
ViewVC logotype

Diff of /code/tags/pcre-4.5/pcreposix.c

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

revision 29 by nigel, Sat Feb 24 21:38:53 2007 UTC revision 73 by nigel, Sat Feb 24 21:40:30 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-1999 University of Cambridge             Copyright (c) 1997-2003 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 43  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 const char *estring[] = {  static const char *const 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, ERR24, ERR25 };    ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR29, ERR29, ERR30,
50      ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40,
51      ERR41, ERR42, ERR43, ERR44 };
52    
53  static int eint[] = {  static const int eint[] = {
54    REG_EESCAPE, /* "\\ at end of pattern" */    REG_EESCAPE, /* "\\ at end of pattern" */
55    REG_EESCAPE, /* "\\c at end of pattern" */    REG_EESCAPE, /* "\\c at end of pattern" */
56    REG_EESCAPE, /* "unrecognized character follows \\" */    REG_EESCAPE, /* "unrecognized character follows \\" */
# Line 61  static int eint[] = { Line 63  static int eint[] = {
63    REG_BADRPT,  /* "operand of unlimited repeat could match the empty string" */    REG_BADRPT,  /* "operand of unlimited repeat could match the empty string" */
64    REG_ASSERT,  /* "internal error: unexpected repeat" */    REG_ASSERT,  /* "internal error: unexpected repeat" */
65    REG_BADPAT,  /* "unrecognized character after (?" */    REG_BADPAT,  /* "unrecognized character after (?" */
66    REG_ESIZE,   /* "too many capturing parenthesized sub-patterns" */    REG_BADPAT,  /* "POSIX named classes are supported only within a class" */
67    REG_EPAREN,  /* "missing )" */    REG_EPAREN,  /* "missing )" */
68    REG_ESUBREG, /* "back reference to non-existent subpattern" */    REG_ESUBREG, /* "reference to non-existent subpattern" */
69    REG_INVARG,  /* "erroffset passed as NULL" */    REG_INVARG,  /* "erroffset passed as NULL" */
70    REG_INVARG,  /* "unknown option bit(s) set" */    REG_INVARG,  /* "unknown option bit(s) set" */
71    REG_EPAREN,  /* "missing ) after comment" */    REG_EPAREN,  /* "missing ) after comment" */
72    REG_ESIZE,   /* "too many sets of parentheses" */    REG_ESIZE,   /* "parentheses nested too deeply" */
73    REG_ESIZE,   /* "regular expression too large" */    REG_ESIZE,   /* "regular expression too large" */
74    REG_ESPACE,  /* "failed to get memory" */    REG_ESPACE,  /* "failed to get memory" */
75    REG_EPAREN,  /* "unmatched brackets" */    REG_EPAREN,  /* "unmatched brackets" */
# Line 76  static int eint[] = { Line 78  static int eint[] = {
78    REG_BADPAT,  /* "lookbehind assertion is not fixed length" */    REG_BADPAT,  /* "lookbehind assertion is not fixed length" */
79    REG_BADPAT,  /* "malformed number after (?(" */    REG_BADPAT,  /* "malformed number after (?(" */
80    REG_BADPAT,  /* "conditional group containe more than two branches" */    REG_BADPAT,  /* "conditional group containe more than two branches" */
81    REG_BADPAT   /* "assertion expected after (?(" */    REG_BADPAT,  /* "assertion expected after (?(" */
82      REG_BADPAT,  /* "(?R or (?digits must be followed by )" */
83      REG_ECTYPE,  /* "unknown POSIX class name" */
84      REG_BADPAT,  /* "POSIX collating elements are not supported" */
85      REG_INVARG,  /* "this version of PCRE is not compiled with PCRE_UTF8 support" */
86      REG_BADPAT,  /* "spare error" */
87      REG_BADPAT,  /* "character value in \x{...} sequence is too large" */
88      REG_BADPAT,  /* "invalid condition (?(0)" */
89      REG_BADPAT,  /* "\\C not allowed in lookbehind assertion" */
90      REG_EESCAPE, /* "PCRE does not support \\L, \\l, \\N, \\P, \\p, \\U, \\u, or \\X" */
91      REG_BADPAT,  /* "number after (?C is > 255" */
92      REG_BADPAT,  /* "closing ) for (?C expected" */
93      REG_BADPAT,  /* "recursive call could loop indefinitely" */
94      REG_BADPAT,  /* "unrecognized character after (?P" */
95      REG_BADPAT,  /* "syntax error after (?P" */
96      REG_BADPAT,  /* "two named groups have the same name" */
97      REG_BADPAT   /* "invalid UTF-8 string" */
98  };  };
99    
100  /* Table of texts corresponding to POSIX error codes */  /* Table of texts corresponding to POSIX error codes */
101    
102  static const char *pstring[] = {  static const char *const pstring[] = {
103    "",                                /* Dummy for value 0 */    "",                                /* Dummy for value 0 */
104    "internal error",                  /* REG_ASSERT */    "internal error",                  /* REG_ASSERT */
105    "invalid repeat counts in {}",     /* BADBR      */    "invalid repeat counts in {}",     /* BADBR      */
# Line 127  return REG_ASSERT; Line 145  return REG_ASSERT;
145  *          Translate error code to string        *  *          Translate error code to string        *
146  *************************************************/  *************************************************/
147    
148  size_t  EXPORT size_t
149  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)
150  {  {
151  const char *message, *addmessage;  const char *message, *addmessage;
# Line 162  return length + addlength; Line 180  return length + addlength;
180  *           Free store held by a regex           *  *           Free store held by a regex           *
181  *************************************************/  *************************************************/
182    
183  void  EXPORT void
184  regfree(regex_t *preg)  regfree(regex_t *preg)
185  {  {
186  (pcre_free)(preg->re_pcre);  (pcre_free)(preg->re_pcre);
# Line 185  Returns:      0 on success Line 203  Returns:      0 on success
203                various non-zero codes on failure                various non-zero codes on failure
204  */  */
205    
206  int  EXPORT int
207  regcomp(regex_t *preg, const char *pattern, int cflags)  regcomp(regex_t *preg, const char *pattern, int cflags)
208  {  {
209  const char *errorptr;  const char *errorptr;
# Line 200  preg->re_erroffset = erroffset; Line 218  preg->re_erroffset = erroffset;
218    
219  if (preg->re_pcre == NULL) return pcre_posix_error_code(errorptr);  if (preg->re_pcre == NULL) return pcre_posix_error_code(errorptr);
220    
221  preg->re_nsub = pcre_info(preg->re_pcre, NULL, NULL);  preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL);
222  return 0;  return 0;
223  }  }
224    
# Line 211  return 0; Line 229  return 0;
229  *              Match a regular expression        *  *              Match a regular expression        *
230  *************************************************/  *************************************************/
231    
232  int  /* Unfortunately, PCRE requires 3 ints of working space for each captured
233  regexec(regex_t *preg, const char *string, size_t nmatch,  substring, so we have to get and release working store instead of just using
234    the POSIX structures as was done in earlier releases when PCRE needed only 2
235    ints. However, if the number of possible capturing brackets is small, use a
236    block of store on the stack, to reduce the use of malloc/free. The threshold is
237    in a macro that can be changed at configure time. */
238    
239    EXPORT int
240    regexec(const regex_t *preg, const char *string, size_t nmatch,
241    regmatch_t pmatch[], int eflags)    regmatch_t pmatch[], int eflags)
242  {  {
243  int rc;  int rc;
244  int options = 0;  int options = 0;
245    int *ovector = NULL;
246    int small_ovector[POSIX_MALLOC_THRESHOLD * 3];
247    BOOL allocated_ovector = FALSE;
248    
249  if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;  if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
250  if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;  if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
251    
252  preg->re_erroffset = (size_t)(-1);   /* Only has meaning after compile */  ((regex_t *)preg)->re_erroffset = (size_t)(-1);  /* Only has meaning after compile */
253    
254  rc = pcre_exec(preg->re_pcre, NULL, string, (int)strlen(string), options,  if (nmatch > 0)
255    (int *)pmatch, nmatch * 2);    {
256      if (nmatch <= POSIX_MALLOC_THRESHOLD)
257        {
258        ovector = &(small_ovector[0]);
259        }
260      else
261        {
262        ovector = (int *)malloc(sizeof(int) * nmatch * 3);
263        if (ovector == NULL) return REG_ESPACE;
264        allocated_ovector = TRUE;
265        }
266      }
267    
268    rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string, (int)strlen(string),
269      0, options, ovector, nmatch * 3);
270    
271  if (rc == 0) return 0;    /* All pmatch were filled in */  if (rc == 0) rc = nmatch;    /* All captured slots were filled in */
272    
273  if (rc > 0)  if (rc >= 0)
274    {    {
275    size_t i;    size_t i;
276    for (i = rc; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;    for (i = 0; i < (size_t)rc; i++)
277        {
278        pmatch[i].rm_so = ovector[i*2];
279        pmatch[i].rm_eo = ovector[i*2+1];
280        }
281      if (allocated_ovector) free(ovector);
282      for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
283    return 0;    return 0;
284    }    }
285    
286  else switch(rc)  else
287    {    {
288    case PCRE_ERROR_NOMATCH: return REG_NOMATCH;    if (allocated_ovector) free(ovector);
289    case PCRE_ERROR_NULL: return REG_INVARG;    switch(rc)
290    case PCRE_ERROR_BADOPTION: return REG_INVARG;      {
291    case PCRE_ERROR_BADMAGIC: return REG_INVARG;      case PCRE_ERROR_NOMATCH: return REG_NOMATCH;
292    case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT;      case PCRE_ERROR_NULL: return REG_INVARG;
293    case PCRE_ERROR_NOMEMORY: return REG_ESPACE;      case PCRE_ERROR_BADOPTION: return REG_INVARG;
294    default: return REG_ASSERT;      case PCRE_ERROR_BADMAGIC: return REG_INVARG;
295        case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT;
296        case PCRE_ERROR_NOMEMORY: return REG_ESPACE;
297        case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE;
298        case PCRE_ERROR_BADUTF8: return REG_INVARG;
299        case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG;
300        default: return REG_ASSERT;
301        }
302    }    }
303  }  }
304    

Legend:
Removed from v.29  
changed lines
  Added in v.73

  ViewVC Help
Powered by ViewVC 1.1.5