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

Diff of /code/trunk/pcre_get.c

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

revision 77 by nigel, Sat Feb 24 21:40:45 2007 UTC revision 199 by ph10, Tue Jul 31 14:39:09 2007 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2005 University of Cambridge             Copyright (c) 1997-2007 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 43  from the subject string after a regex ma Line 43  from the subject string after a regex ma
43  for these functions came from Scott Wimer. */  for these functions came from Scott Wimer. */
44    
45    
46    #ifdef HAVE_CONFIG_H
47    #include <config.h>
48    #endif
49    
50  #include "pcre_internal.h"  #include "pcre_internal.h"
51    
52    
# Line 50  for these functions came from Scott Wime Line 54  for these functions came from Scott Wime
54  *           Find number for named string         *  *           Find number for named string         *
55  *************************************************/  *************************************************/
56    
57  /* This function is used by the two extraction functions below, as well  /* This function is used by the get_first_set() function below, as well
58  as being generally available.  as being generally available. It assumes that names are unique.
59    
60  Arguments:  Arguments:
61    code        the compiled regex    code        the compiled regex
# Line 94  return PCRE_ERROR_NOSUBSTRING; Line 98  return PCRE_ERROR_NOSUBSTRING;
98    
99    
100  /*************************************************  /*************************************************
101    *     Find (multiple) entries for named string   *
102    *************************************************/
103    
104    /* This is used by the get_first_set() function below, as well as being
105    generally available. It is used when duplicated names are permitted.
106    
107    Arguments:
108      code        the compiled regex
109      stringname  the name whose entries required
110      firstptr    where to put the pointer to the first entry
111      lastptr     where to put the pointer to the last entry
112    
113    Returns:      the length of each entry, or a negative number
114                    (PCRE_ERROR_NOSUBSTRING) if not found
115    */
116    
117    int
118    pcre_get_stringtable_entries(const pcre *code, const char *stringname,
119      char **firstptr, char **lastptr)
120    {
121    int rc;
122    int entrysize;
123    int top, bot;
124    uschar *nametable, *lastentry;
125    
126    if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
127      return rc;
128    if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
129    
130    if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
131      return rc;
132    if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
133      return rc;
134    
135    lastentry = nametable + entrysize * (top - 1);
136    bot = 0;
137    while (top > bot)
138      {
139      int mid = (top + bot) / 2;
140      uschar *entry = nametable + entrysize*mid;
141      int c = strcmp(stringname, (char *)(entry + 2));
142      if (c == 0)
143        {
144        uschar *first = entry;
145        uschar *last = entry;
146        while (first > nametable)
147          {
148          if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break;
149          first -= entrysize;
150          }
151        while (last < lastentry)
152          {
153          if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break;
154          last += entrysize;
155          }
156        *firstptr = (char *)first;
157        *lastptr = (char *)last;
158        return entrysize;
159        }
160      if (c > 0) bot = mid + 1; else top = mid;
161      }
162    
163    return PCRE_ERROR_NOSUBSTRING;
164    }
165    
166    
167    
168    /*************************************************
169    *    Find first set of multiple named strings    *
170    *************************************************/
171    
172    /* This function allows for duplicate names in the table of named substrings.
173    It returns the number of the first one that was set in a pattern match.
174    
175    Arguments:
176      code         the compiled regex
177      stringname   the name of the capturing substring
178      ovector      the vector of matched substrings
179    
180    Returns:       the number of the first that is set,
181                   or the number of the last one if none are set,
182                   or a negative number on error
183    */
184    
185    static int
186    get_first_set(const pcre *code, const char *stringname, int *ovector)
187    {
188    const real_pcre *re = (const real_pcre *)code;
189    int entrysize;
190    char *first, *last;
191    uschar *entry;
192    if ((re->options & (PCRE_DUPNAMES | PCRE_JCHANGED)) == 0)
193      return pcre_get_stringnumber(code, stringname);
194    entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
195    if (entrysize <= 0) return entrysize;
196    for (entry = (uschar *)first; entry <= (uschar *)last; entry += entrysize)
197      {
198      int n = (entry[0] << 8) + entry[1];
199      if (ovector[n*2] >= 0) return n;
200      }
201    return (first[0] << 8) + first[1];
202    }
203    
204    
205    
206    
207    /*************************************************
208  *      Copy captured string to given buffer      *  *      Copy captured string to given buffer      *
209  *************************************************/  *************************************************/
210    
# Line 142  return yield; Line 253  return yield;
253  *************************************************/  *************************************************/
254    
255  /* This function copies a single captured substring into a given buffer,  /* This function copies a single captured substring into a given buffer,
256  identifying it by name.  identifying it by name. If the regex permits duplicate names, the first
257    substring that is set is chosen.
258    
259  Arguments:  Arguments:
260    code           the compiled regex    code           the compiled regex
# Line 168  int Line 280  int
280  pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,  pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,
281    int stringcount, const char *stringname, char *buffer, int size)    int stringcount, const char *stringname, char *buffer, int size)
282  {  {
283  int n = pcre_get_stringnumber(code, stringname);  int n = get_first_set(code, stringname, ovector);
284  if (n <= 0) return n;  if (n <= 0) return n;
285  return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);  return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
286  }  }
# Line 299  return yield; Line 411  return yield;
411  *************************************************/  *************************************************/
412    
413  /* This function copies a single captured substring, identified by name, into  /* This function copies a single captured substring, identified by name, into
414  new store.  new store. If the regex permits duplicate names, the first substring that is
415    set is chosen.
416    
417  Arguments:  Arguments:
418    code           the compiled regex    code           the compiled regex
# Line 324  int Line 437  int
437  pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,  pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,
438    int stringcount, const char *stringname, const char **stringptr)    int stringcount, const char *stringname, const char **stringptr)
439  {  {
440  int n = pcre_get_stringnumber(code, stringname);  int n = get_first_set(code, stringname, ovector);
441  if (n <= 0) return n;  if (n <= 0) return n;
442  return pcre_get_substring(subject, ovector, stringcount, n, stringptr);  return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
443  }  }

Legend:
Removed from v.77  
changed lines
  Added in v.199

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12