| 50 |
* Find number for named string * |
* Find number for named string * |
| 51 |
*************************************************/ |
*************************************************/ |
| 52 |
|
|
| 53 |
/* 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 |
| 54 |
as being generally available. |
as being generally available. It assumes that names are unique. |
| 55 |
|
|
| 56 |
Arguments: |
Arguments: |
| 57 |
code the compiled regex |
code the compiled regex |
| 94 |
|
|
| 95 |
|
|
| 96 |
/************************************************* |
/************************************************* |
| 97 |
|
* Find (multiple) entries for named string * |
| 98 |
|
*************************************************/ |
| 99 |
|
|
| 100 |
|
/* This is used by the get_first_set() function below, as well as being |
| 101 |
|
generally available. It is used when duplicated names are permitted. |
| 102 |
|
|
| 103 |
|
Arguments: |
| 104 |
|
code the compiled regex |
| 105 |
|
stringname the name whose entries required |
| 106 |
|
firstptr where to put the pointer to the first entry |
| 107 |
|
lastptr where to put the pointer to the last entry |
| 108 |
|
|
| 109 |
|
Returns: the length of each entry, or a negative number |
| 110 |
|
(PCRE_ERROR_NOSUBSTRING) if not found |
| 111 |
|
*/ |
| 112 |
|
|
| 113 |
|
int |
| 114 |
|
pcre_get_stringtable_entries(const pcre *code, const char *stringname, |
| 115 |
|
char **firstptr, char **lastptr) |
| 116 |
|
{ |
| 117 |
|
int rc; |
| 118 |
|
int entrysize; |
| 119 |
|
int top, bot; |
| 120 |
|
uschar *nametable, *lastentry; |
| 121 |
|
|
| 122 |
|
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) |
| 123 |
|
return rc; |
| 124 |
|
if (top <= 0) return PCRE_ERROR_NOSUBSTRING; |
| 125 |
|
|
| 126 |
|
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) |
| 127 |
|
return rc; |
| 128 |
|
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) |
| 129 |
|
return rc; |
| 130 |
|
|
| 131 |
|
lastentry = nametable + entrysize * (top - 1); |
| 132 |
|
bot = 0; |
| 133 |
|
while (top > bot) |
| 134 |
|
{ |
| 135 |
|
int mid = (top + bot) / 2; |
| 136 |
|
uschar *entry = nametable + entrysize*mid; |
| 137 |
|
int c = strcmp(stringname, (char *)(entry + 2)); |
| 138 |
|
if (c == 0) |
| 139 |
|
{ |
| 140 |
|
uschar *first = entry; |
| 141 |
|
uschar *last = entry; |
| 142 |
|
while (first > nametable) |
| 143 |
|
{ |
| 144 |
|
if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break; |
| 145 |
|
first -= entrysize; |
| 146 |
|
} |
| 147 |
|
while (last < lastentry) |
| 148 |
|
{ |
| 149 |
|
if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break; |
| 150 |
|
last += entrysize; |
| 151 |
|
} |
| 152 |
|
*firstptr = (char *)first; |
| 153 |
|
*lastptr = (char *)last; |
| 154 |
|
return entrysize; |
| 155 |
|
} |
| 156 |
|
if (c > 0) bot = mid + 1; else top = mid; |
| 157 |
|
} |
| 158 |
|
|
| 159 |
|
return PCRE_ERROR_NOSUBSTRING; |
| 160 |
|
} |
| 161 |
|
|
| 162 |
|
|
| 163 |
|
|
| 164 |
|
/************************************************* |
| 165 |
|
* Find first set of multiple named strings * |
| 166 |
|
*************************************************/ |
| 167 |
|
|
| 168 |
|
/* This function allows for duplicate names in the table of named substrings. |
| 169 |
|
It returns the number of the first one that was set in a pattern match. |
| 170 |
|
|
| 171 |
|
Arguments: |
| 172 |
|
code the compiled regex |
| 173 |
|
stringname the name of the capturing substring |
| 174 |
|
ovector the vector of matched substrings |
| 175 |
|
|
| 176 |
|
Returns: the number of the first that is set, |
| 177 |
|
or the number of the last one if none are set, |
| 178 |
|
or a negative number on error |
| 179 |
|
*/ |
| 180 |
|
|
| 181 |
|
static int |
| 182 |
|
get_first_set(const pcre *code, const char *stringname, int *ovector) |
| 183 |
|
{ |
| 184 |
|
const real_pcre *re = (const real_pcre *)code; |
| 185 |
|
int entrysize; |
| 186 |
|
char *first, *last; |
| 187 |
|
uschar *entry; |
| 188 |
|
if ((re->options & (PCRE_DUPNAMES | PCRE_JCHANGED)) == 0) |
| 189 |
|
return pcre_get_stringnumber(code, stringname); |
| 190 |
|
entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last); |
| 191 |
|
if (entrysize <= 0) return entrysize; |
| 192 |
|
for (entry = (uschar *)first; entry <= (uschar *)last; entry += entrysize) |
| 193 |
|
{ |
| 194 |
|
int n = (entry[0] << 8) + entry[1]; |
| 195 |
|
if (ovector[n*2] >= 0) return n; |
| 196 |
|
} |
| 197 |
|
return (first[0] << 8) + first[1]; |
| 198 |
|
} |
| 199 |
|
|
| 200 |
|
|
| 201 |
|
|
| 202 |
|
|
| 203 |
|
/************************************************* |
| 204 |
* Copy captured string to given buffer * |
* Copy captured string to given buffer * |
| 205 |
*************************************************/ |
*************************************************/ |
| 206 |
|
|
| 249 |
*************************************************/ |
*************************************************/ |
| 250 |
|
|
| 251 |
/* This function copies a single captured substring into a given buffer, |
/* This function copies a single captured substring into a given buffer, |
| 252 |
identifying it by name. |
identifying it by name. If the regex permits duplicate names, the first |
| 253 |
|
substring that is set is chosen. |
| 254 |
|
|
| 255 |
Arguments: |
Arguments: |
| 256 |
code the compiled regex |
code the compiled regex |
| 276 |
pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, |
pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, |
| 277 |
int stringcount, const char *stringname, char *buffer, int size) |
int stringcount, const char *stringname, char *buffer, int size) |
| 278 |
{ |
{ |
| 279 |
int n = pcre_get_stringnumber(code, stringname); |
int n = get_first_set(code, stringname, ovector); |
| 280 |
if (n <= 0) return n; |
if (n <= 0) return n; |
| 281 |
return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); |
return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); |
| 282 |
} |
} |
| 407 |
*************************************************/ |
*************************************************/ |
| 408 |
|
|
| 409 |
/* This function copies a single captured substring, identified by name, into |
/* This function copies a single captured substring, identified by name, into |
| 410 |
new store. |
new store. If the regex permits duplicate names, the first substring that is |
| 411 |
|
set is chosen. |
| 412 |
|
|
| 413 |
Arguments: |
Arguments: |
| 414 |
code the compiled regex |
code the compiled regex |
| 433 |
pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, |
pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, |
| 434 |
int stringcount, const char *stringname, const char **stringptr) |
int stringcount, const char *stringname, const char **stringptr) |
| 435 |
{ |
{ |
| 436 |
int n = pcre_get_stringnumber(code, stringname); |
int n = get_first_set(code, stringname, ovector); |
| 437 |
if (n <= 0) return n; |
if (n <= 0) return n; |
| 438 |
return pcre_get_substring(subject, ovector, stringcount, n, stringptr); |
return pcre_get_substring(subject, ovector, stringcount, n, stringptr); |
| 439 |
|
|
| 440 |
} |
} |
| 441 |
|
|
| 442 |
|
|