| 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 |
| 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 |
|
|
| 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 |
| 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 |
|
|
| 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 |
| 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 |
} |
} |
| 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 |
| 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 |
} |
} |