/[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 87 by nigel, Sat Feb 24 21:41:21 2007 UTC revision 359 by ph10, Wed Jul 9 16:20:19 2008 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-2006 University of Cambridge             Copyright (c) 1997-2008 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 61  Returns: the number of the named pa Line 65  Returns: the number of the named pa
65                  (PCRE_ERROR_NOSUBSTRING) if not found                  (PCRE_ERROR_NOSUBSTRING) if not found
66  */  */
67    
68  int  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
69  pcre_get_stringnumber(const pcre *code, const char *stringname)  pcre_get_stringnumber(const pcre *code, const char *stringname)
70  {  {
71  int rc;  int rc;
# 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    PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
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) == 0 && (re->flags & 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 120  Returns: if successful: Line 231  Returns: if successful:
231                     PCRE_ERROR_NOSUBSTRING (-7) no such captured substring                     PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
232  */  */
233    
234  int  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
235  pcre_copy_substring(const char *subject, int *ovector, int stringcount,  pcre_copy_substring(const char *subject, int *ovector, int stringcount,
236    int stringnumber, char *buffer, int size)    int stringnumber, char *buffer, int size)
237  {  {
# 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 164  Returns: if successful: Line 276  Returns: if successful:
276                     PCRE_ERROR_NOSUBSTRING (-7) no such captured substring                     PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
277  */  */
278    
279  int  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
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 196  Returns: if successful: 0 Line 308  Returns: if successful: 0
308                     PCRE_ERROR_NOMEMORY (-6) failed to get store                     PCRE_ERROR_NOMEMORY (-6) failed to get store
309  */  */
310    
311  int  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
312  pcre_get_substring_list(const char *subject, int *ovector, int stringcount,  pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
313    const char ***listptr)    const char ***listptr)
314  {  {
# Line 241  Argument: the result of a previous pcr Line 353  Argument: the result of a previous pcr
353  Returns:    nothing  Returns:    nothing
354  */  */
355    
356  void  PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
357  pcre_free_substring_list(const char **pointer)  pcre_free_substring_list(const char **pointer)
358  {  {
359  (pcre_free)((void *)pointer);  (pcre_free)((void *)pointer);
# Line 274  Returns: if successful: Line 386  Returns: if successful:
386                     PCRE_ERROR_NOSUBSTRING (-7) substring not present                     PCRE_ERROR_NOSUBSTRING (-7) substring not present
387  */  */
388    
389  int  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
390  pcre_get_substring(const char *subject, int *ovector, int stringcount,  pcre_get_substring(const char *subject, int *ovector, int stringcount,
391    int stringnumber, const char **stringptr)    int stringnumber, const char **stringptr)
392  {  {
# 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 320  Returns: if successful: Line 433  Returns: if successful:
433                     PCRE_ERROR_NOSUBSTRING (-7) no such captured substring                     PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
434  */  */
435    
436  int  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
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  }  }
# Line 343  Argument: the result of a previous pcr Line 456  Argument: the result of a previous pcr
456  Returns:    nothing  Returns:    nothing
457  */  */
458    
459  void  PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
460  pcre_free_substring(const char *pointer)  pcre_free_substring(const char *pointer)
461  {  {
462  (pcre_free)((void *)pointer);  (pcre_free)((void *)pointer);

Legend:
Removed from v.87  
changed lines
  Added in v.359

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12