1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2007 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Authors: Rasmus Lerdorf <rasmus@php.net> |
16 : | Jim Winstead <jimw@php.net> |
17 : | Jaakko Hyvätti <jaakko@hyvatti.iki.fi> |
18 : +----------------------------------------------------------------------+
19 : */
20 : /* $Id: reg.c,v 1.82.2.3.2.2 2007/01/01 09:36:08 sebastian Exp $ */
21 :
22 : #include <stdio.h>
23 : #include <ctype.h>
24 : #include "php.h"
25 : #include "php_string.h"
26 : #include "reg.h"
27 : #include "ext/standard/info.h"
28 :
29 : ZEND_DECLARE_MODULE_GLOBALS(reg)
30 :
31 : typedef struct {
32 : regex_t preg;
33 : int cflags;
34 : } reg_cache;
35 :
36 : static int reg_magic = 0;
37 :
38 : /* {{{ _php_regcomp
39 : */
40 : static int _php_regcomp(regex_t *preg, const char *pattern, int cflags)
41 0 : {
42 0 : int r = 0;
43 0 : int patlen = strlen(pattern);
44 0 : reg_cache *rc = NULL;
45 : TSRMLS_FETCH();
46 :
47 0 : if(zend_hash_find(®(ht_rc), (char *) pattern, patlen+1, (void **) &rc) == SUCCESS
48 : && rc->cflags == cflags) {
49 : #ifdef HAVE_REGEX_T_RE_MAGIC
50 : /*
51 : * We use a saved magic number to see whether cache is corrupted, and if it
52 : * is, we flush it and compile the pattern from scratch.
53 : */
54 0 : if (rc->preg.re_magic != reg_magic) {
55 0 : zend_hash_clean(®(ht_rc));
56 : } else {
57 0 : memcpy(preg, &rc->preg, sizeof(*preg));
58 0 : return r;
59 : }
60 : }
61 :
62 0 : r = regcomp(preg, pattern, cflags);
63 0 : if(!r) {
64 : reg_cache rcp;
65 :
66 0 : rcp.cflags = cflags;
67 0 : memcpy(&rcp.preg, preg, sizeof(*preg));
68 : /*
69 : * Since we don't have access to the actual MAGIC1 definition in the private
70 : * header file, we save the magic value immediately after compilation. Hopefully,
71 : * it's good.
72 : */
73 0 : if (!reg_magic) reg_magic = preg->re_magic;
74 0 : zend_hash_update(®(ht_rc), (char *) pattern, patlen+1,
75 : (void *) &rcp, sizeof(rcp), NULL);
76 : }
77 : #else
78 : memcpy(preg, &rc->preg, sizeof(*preg));
79 : } else {
80 : r = regcomp(preg, pattern, cflags);
81 : if(!r) {
82 : reg_cache rcp;
83 :
84 : rcp.cflags = cflags;
85 : memcpy(&rcp.preg, preg, sizeof(*preg));
86 : zend_hash_update(®(ht_rc), (char *) pattern, patlen+1,
87 : (void *) &rcp, sizeof(rcp), NULL);
88 : }
89 : }
90 : #endif
91 0 : return r;
92 : }
93 : /* }}} */
94 :
95 : static void _free_reg_cache(reg_cache *rc)
96 0 : {
97 0 : regfree(&rc->preg);
98 0 : }
99 :
100 : #undef regfree
101 : #define regfree(a);
102 : #undef regcomp
103 : #define regcomp(a, b, c) _php_regcomp(a, b, c)
104 :
105 : static void php_reg_init_globals(zend_reg_globals *reg_globals TSRMLS_DC)
106 220 : {
107 220 : zend_hash_init(®_globals->ht_rc, 0, NULL, (void (*)(void *)) _free_reg_cache, 1);
108 220 : }
109 :
110 : static void php_reg_destroy_globals(zend_reg_globals *reg_globals TSRMLS_DC)
111 219 : {
112 219 : zend_hash_destroy(®_globals->ht_rc);
113 219 : }
114 :
115 : PHP_MINIT_FUNCTION(regex)
116 220 : {
117 220 : ZEND_INIT_MODULE_GLOBALS(reg, php_reg_init_globals, php_reg_destroy_globals);
118 220 : return SUCCESS;
119 : }
120 :
121 : PHP_MSHUTDOWN_FUNCTION(regex)
122 219 : {
123 : #ifndef ZTS
124 219 : php_reg_destroy_globals(®_globals TSRMLS_CC);
125 : #endif
126 :
127 219 : return SUCCESS;
128 : }
129 :
130 : PHP_MINFO_FUNCTION(regex)
131 0 : {
132 : #if HSREGEX
133 0 : php_info_print_table_row(2, "Regex Library", "Bundled library enabled");
134 : #else
135 : php_info_print_table_row(2, "Regex Library", "System library enabled");
136 : #endif
137 0 : }
138 :
139 :
140 : /* {{{ php_reg_eprint
141 : * php_reg_eprint - convert error number to name
142 : */
143 0 : static void php_reg_eprint(int err, regex_t *re) {
144 0 : char *buf = NULL, *message = NULL;
145 : size_t len;
146 : size_t buf_len;
147 :
148 : #ifdef REG_ITOA
149 : /* get the length of the message */
150 0 : buf_len = regerror(REG_ITOA | err, re, NULL, 0);
151 0 : if (buf_len) {
152 0 : buf = (char *)safe_emalloc(buf_len, sizeof(char), 0);
153 0 : if (!buf) return; /* fail silently */
154 : /* finally, get the error message */
155 0 : regerror(REG_ITOA | err, re, buf, buf_len);
156 : }
157 : #else
158 : buf_len = 0;
159 : #endif
160 0 : len = regerror(err, re, NULL, 0);
161 0 : if (len) {
162 : TSRMLS_FETCH();
163 :
164 0 : message = (char *)safe_emalloc((buf_len + len + 2), sizeof(char), 0);
165 0 : if (!message) {
166 0 : return; /* fail silently */
167 : }
168 0 : if (buf_len) {
169 0 : snprintf(message, buf_len, "%s: ", buf);
170 0 : buf_len += 1; /* so pointer math below works */
171 : }
172 : /* drop the message into place */
173 0 : regerror(err, re, message + buf_len, len);
174 :
175 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message);
176 : }
177 :
178 0 : STR_FREE(buf);
179 0 : STR_FREE(message);
180 : }
181 : /* }}} */
182 :
183 : /* {{{ php_ereg
184 : */
185 : static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase)
186 0 : {
187 : zval **regex, /* Regular expression */
188 : **findin, /* String to apply expression to */
189 0 : **array = NULL; /* Optional register array */
190 : regex_t re;
191 : regmatch_t *subs;
192 : int err, match_len, string_len;
193 : uint i;
194 0 : int copts = 0;
195 : off_t start, end;
196 0 : char *buf = NULL;
197 0 : char *string = NULL;
198 0 : int argc = ZEND_NUM_ARGS();
199 :
200 0 : if (argc < 2 || argc > 3 ||
201 : zend_get_parameters_ex(argc, ®ex, &findin, &array) == FAILURE) {
202 0 : WRONG_PARAM_COUNT;
203 : }
204 :
205 0 : if (icase)
206 0 : copts |= REG_ICASE;
207 :
208 0 : if (argc == 2)
209 0 : copts |= REG_NOSUB;
210 :
211 : /* compile the regular expression from the supplied regex */
212 0 : if (Z_TYPE_PP(regex) == IS_STRING) {
213 0 : err = regcomp(&re, Z_STRVAL_PP(regex), REG_EXTENDED | copts);
214 : } else {
215 : /* we convert numbers to integers and treat them as a string */
216 0 : if (Z_TYPE_PP(regex) == IS_DOUBLE)
217 0 : convert_to_long_ex(regex); /* get rid of decimal places */
218 0 : convert_to_string_ex(regex);
219 : /* don't bother doing an extended regex with just a number */
220 0 : err = regcomp(&re, Z_STRVAL_PP(regex), copts);
221 : }
222 :
223 0 : if (err) {
224 0 : php_reg_eprint(err, &re);
225 0 : RETURN_FALSE;
226 : }
227 :
228 : /* make a copy of the string we're looking in */
229 0 : convert_to_string_ex(findin);
230 0 : string = estrndup(Z_STRVAL_PP(findin), Z_STRLEN_PP(findin));
231 :
232 : /* allocate storage for (sub-)expression-matches */
233 0 : subs = (regmatch_t *)ecalloc(sizeof(regmatch_t),re.re_nsub+1);
234 :
235 : /* actually execute the regular expression */
236 0 : err = regexec(&re, string, re.re_nsub+1, subs, 0);
237 0 : if (err && err != REG_NOMATCH) {
238 0 : php_reg_eprint(err, &re);
239 : regfree(&re);
240 0 : efree(subs);
241 0 : RETURN_FALSE;
242 : }
243 0 : match_len = 1;
244 :
245 0 : if (array && err != REG_NOMATCH) {
246 0 : match_len = (int) (subs[0].rm_eo - subs[0].rm_so);
247 0 : string_len = Z_STRLEN_PP(findin) + 1;
248 :
249 0 : buf = emalloc(string_len);
250 :
251 0 : zval_dtor(*array); /* start with clean array */
252 0 : array_init(*array);
253 :
254 0 : for (i = 0; i <= re.re_nsub; i++) {
255 0 : start = subs[i].rm_so;
256 0 : end = subs[i].rm_eo;
257 0 : if (start != -1 && end > 0 && start < string_len && end < string_len && start < end) {
258 0 : add_index_stringl(*array, i, string+start, end-start, 1);
259 : } else {
260 0 : add_index_bool(*array, i, 0);
261 : }
262 : }
263 0 : efree(buf);
264 : }
265 :
266 0 : efree(subs);
267 0 : efree(string);
268 0 : if (err == REG_NOMATCH) {
269 0 : RETVAL_FALSE;
270 : } else {
271 0 : if (match_len == 0)
272 0 : match_len = 1;
273 0 : RETVAL_LONG(match_len);
274 : }
275 : regfree(&re);
276 : }
277 : /* }}} */
278 :
279 : /* {{{ proto int ereg(string pattern, string string [, array registers])
280 : Regular expression match */
281 : PHP_FUNCTION(ereg)
282 0 : {
283 0 : php_ereg(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
284 0 : }
285 : /* }}} */
286 :
287 : /* {{{ proto int eregi(string pattern, string string [, array registers])
288 : Case-insensitive regular expression match */
289 : PHP_FUNCTION(eregi)
290 0 : {
291 0 : php_ereg(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
292 0 : }
293 : /* }}} */
294 :
295 : /* {{{ php_reg_replace
296 : * this is the meat and potatoes of regex replacement! */
297 : PHPAPI char *php_reg_replace(const char *pattern, const char *replace, const char *string, int icase, int extended)
298 0 : {
299 : regex_t re;
300 : regmatch_t *subs;
301 :
302 : char *buf, /* buf is where we build the replaced string */
303 : *nbuf, /* nbuf is used when we grow the buffer */
304 : *walkbuf; /* used to walk buf when replacing backrefs */
305 : const char *walk; /* used to walk replacement string for backrefs */
306 : int buf_len;
307 : int pos, tmp, string_len, new_l;
308 0 : int err, copts = 0;
309 :
310 0 : string_len = strlen(string);
311 :
312 0 : if (icase) {
313 0 : copts = REG_ICASE;
314 : }
315 0 : if (extended) {
316 0 : copts |= REG_EXTENDED;
317 : }
318 :
319 0 : err = regcomp(&re, pattern, copts);
320 0 : if (err) {
321 0 : php_reg_eprint(err, &re);
322 0 : return ((char *) -1);
323 : }
324 :
325 :
326 : /* allocate storage for (sub-)expression-matches */
327 0 : subs = (regmatch_t *)ecalloc(sizeof(regmatch_t),re.re_nsub+1);
328 :
329 : /* start with a buffer that is twice the size of the stringo
330 : we're doing replacements in */
331 0 : buf_len = 2 * string_len + 1;
332 0 : buf = safe_emalloc(buf_len, sizeof(char), 0);
333 :
334 0 : err = pos = 0;
335 0 : buf[0] = '\0';
336 0 : while (!err) {
337 0 : err = regexec(&re, &string[pos], re.re_nsub+1, subs, (pos ? REG_NOTBOL : 0));
338 :
339 0 : if (err && err != REG_NOMATCH) {
340 0 : php_reg_eprint(err, &re);
341 0 : efree(subs);
342 0 : efree(buf);
343 : regfree(&re);
344 0 : return ((char *) -1);
345 : }
346 :
347 0 : if (!err) {
348 : /* backref replacement is done in two passes:
349 : 1) find out how long the string will be, and allocate buf
350 : 2) copy the part before match, replacement and backrefs to buf
351 :
352 : Jaakko Hyvätti <Jaakko.Hyvatti@iki.fi>
353 : */
354 :
355 0 : new_l = strlen(buf) + subs[0].rm_so; /* part before the match */
356 0 : walk = replace;
357 0 : while (*walk) {
358 0 : if ('\\' == *walk && isdigit((unsigned char)walk[1]) && ((unsigned char)walk[1]) - '0' <= (int)re.re_nsub) {
359 0 : if (subs[walk[1] - '0'].rm_so > -1 && subs[walk[1] - '0'].rm_eo > -1) {
360 0 : new_l += subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so;
361 : }
362 0 : walk += 2;
363 : } else {
364 0 : new_l++;
365 0 : walk++;
366 : }
367 : }
368 0 : if (new_l + 1 > buf_len) {
369 0 : buf_len = 1 + buf_len + 2 * new_l;
370 0 : nbuf = emalloc(buf_len);
371 0 : strcpy(nbuf, buf);
372 0 : efree(buf);
373 0 : buf = nbuf;
374 : }
375 0 : tmp = strlen(buf);
376 : /* copy the part of the string before the match */
377 0 : strncat(buf, &string[pos], subs[0].rm_so);
378 :
379 : /* copy replacement and backrefs */
380 0 : walkbuf = &buf[tmp + subs[0].rm_so];
381 0 : walk = replace;
382 0 : while (*walk) {
383 0 : if ('\\' == *walk && isdigit(walk[1]) && walk[1] - '0' <= (int)re.re_nsub) {
384 0 : if (subs[walk[1] - '0'].rm_so > -1 && subs[walk[1] - '0'].rm_eo > -1
385 : /* this next case shouldn't happen. it does. */
386 : && subs[walk[1] - '0'].rm_so <= subs[walk[1] - '0'].rm_eo) {
387 :
388 0 : tmp = subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so;
389 0 : memcpy (walkbuf, &string[pos + subs[walk[1] - '0'].rm_so], tmp);
390 0 : walkbuf += tmp;
391 : }
392 0 : walk += 2;
393 : } else {
394 0 : *walkbuf++ = *walk++;
395 : }
396 : }
397 0 : *walkbuf = '\0';
398 :
399 : /* and get ready to keep looking for replacements */
400 0 : if (subs[0].rm_so == subs[0].rm_eo) {
401 0 : if (subs[0].rm_so + pos >= string_len) {
402 0 : break;
403 : }
404 0 : new_l = strlen (buf) + 1;
405 0 : if (new_l + 1 > buf_len) {
406 0 : buf_len = 1 + buf_len + 2 * new_l;
407 0 : nbuf = safe_emalloc(buf_len, sizeof(char), 0);
408 0 : strcpy(nbuf, buf);
409 0 : efree(buf);
410 0 : buf = nbuf;
411 : }
412 0 : pos += subs[0].rm_eo + 1;
413 0 : buf [new_l-1] = string [pos-1];
414 0 : buf [new_l] = '\0';
415 : } else {
416 0 : pos += subs[0].rm_eo;
417 : }
418 : } else { /* REG_NOMATCH */
419 0 : new_l = strlen(buf) + strlen(&string[pos]);
420 0 : if (new_l + 1 > buf_len) {
421 0 : buf_len = new_l + 1; /* now we know exactly how long it is */
422 0 : nbuf = safe_emalloc(buf_len, sizeof(char), 0);
423 0 : strcpy(nbuf, buf);
424 0 : efree(buf);
425 0 : buf = nbuf;
426 : }
427 : /* stick that last bit of string on our output */
428 0 : strlcat(buf, &string[pos], buf_len);
429 : }
430 : }
431 :
432 : /* don't want to leak memory .. */
433 0 : efree(subs);
434 : regfree(&re);
435 :
436 : /* whew. */
437 0 : return (buf);
438 : }
439 : /* }}} */
440 :
441 : /* {{{ php_ereg_replace
442 : */
443 : static void php_ereg_replace(INTERNAL_FUNCTION_PARAMETERS, int icase)
444 0 : {
445 : zval **arg_pattern,
446 : **arg_replace,
447 : **arg_string;
448 : char *pattern;
449 : char *string;
450 : char *replace;
451 : char *ret;
452 :
453 0 : if (ZEND_NUM_ARGS() != 3 ||
454 : zend_get_parameters_ex(3, &arg_pattern, &arg_replace, &arg_string) == FAILURE) {
455 0 : WRONG_PARAM_COUNT;
456 : }
457 :
458 0 : if (Z_TYPE_PP(arg_pattern) == IS_STRING) {
459 0 : if (Z_STRVAL_PP(arg_pattern) && Z_STRLEN_PP(arg_pattern))
460 0 : pattern = estrndup(Z_STRVAL_PP(arg_pattern), Z_STRLEN_PP(arg_pattern));
461 : else
462 0 : pattern = STR_EMPTY_ALLOC();
463 : } else {
464 0 : convert_to_long_ex(arg_pattern);
465 0 : pattern = emalloc(2);
466 0 : pattern[0] = (char) Z_LVAL_PP(arg_pattern);
467 0 : pattern[1] = '\0';
468 : }
469 :
470 0 : if (Z_TYPE_PP(arg_replace) == IS_STRING) {
471 0 : if (Z_STRVAL_PP(arg_replace) && Z_STRLEN_PP(arg_replace))
472 0 : replace = estrndup(Z_STRVAL_PP(arg_replace), Z_STRLEN_PP(arg_replace));
473 : else
474 0 : replace = STR_EMPTY_ALLOC();
475 : } else {
476 0 : convert_to_long_ex(arg_replace);
477 0 : replace = emalloc(2);
478 0 : replace[0] = (char) Z_LVAL_PP(arg_replace);
479 0 : replace[1] = '\0';
480 : }
481 :
482 0 : convert_to_string_ex(arg_string);
483 0 : if (Z_STRVAL_PP(arg_string) && Z_STRLEN_PP(arg_string))
484 0 : string = estrndup(Z_STRVAL_PP(arg_string), Z_STRLEN_PP(arg_string));
485 : else
486 0 : string = STR_EMPTY_ALLOC();
487 :
488 : /* do the actual work */
489 0 : ret = php_reg_replace(pattern, replace, string, icase, 1);
490 0 : if (ret == (char *) -1) {
491 0 : RETVAL_FALSE;
492 : } else {
493 0 : RETVAL_STRING(ret, 1);
494 0 : STR_FREE(ret);
495 : }
496 :
497 0 : STR_FREE(string);
498 0 : STR_FREE(replace);
499 0 : STR_FREE(pattern);
500 : }
501 : /* }}} */
502 :
503 : /* {{{ proto string ereg_replace(string pattern, string replacement, string string)
504 : Replace regular expression */
505 : PHP_FUNCTION(ereg_replace)
506 0 : {
507 0 : php_ereg_replace(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
508 0 : }
509 : /* }}} */
510 :
511 : /* {{{ proto string eregi_replace(string pattern, string replacement, string string)
512 : Case insensitive replace regular expression */
513 : PHP_FUNCTION(eregi_replace)
514 0 : {
515 0 : php_ereg_replace(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
516 0 : }
517 : /* }}} */
518 :
519 : /* {{{ php_split
520 : */
521 : static void php_split(INTERNAL_FUNCTION_PARAMETERS, int icase)
522 0 : {
523 0 : zval **spliton, **str, **arg_count = NULL;
524 : regex_t re;
525 : regmatch_t subs[1];
526 : char *strp, *endp;
527 0 : int err, size, count = -1, copts = 0;
528 0 : int argc = ZEND_NUM_ARGS();
529 :
530 0 : if (argc < 2 || argc > 3 ||
531 : zend_get_parameters_ex(argc, &spliton, &str, &arg_count) == FAILURE) {
532 0 : WRONG_PARAM_COUNT;
533 : }
534 :
535 0 : if (argc > 2) {
536 0 : convert_to_long_ex(arg_count);
537 0 : count = Z_LVAL_PP(arg_count);
538 : }
539 :
540 0 : if (icase)
541 0 : copts = REG_ICASE;
542 :
543 0 : convert_to_string_ex(spliton);
544 0 : convert_to_string_ex(str);
545 :
546 0 : strp = Z_STRVAL_PP(str);
547 0 : endp = strp + Z_STRLEN_PP(str);
548 :
549 0 : err = regcomp(&re, Z_STRVAL_PP(spliton), REG_EXTENDED | copts);
550 0 : if (err) {
551 0 : php_reg_eprint(err, &re);
552 0 : RETURN_FALSE;
553 : }
554 :
555 0 : array_init(return_value);
556 :
557 : /* churn through str, generating array entries as we go */
558 0 : while ((count == -1 || count > 1) && !(err = regexec(&re, strp, 1, subs, 0))) {
559 0 : if (subs[0].rm_so == 0 && subs[0].rm_eo) {
560 : /* match is at start of string, return empty string */
561 0 : add_next_index_stringl(return_value, "", 0, 1);
562 : /* skip ahead the length of the regex match */
563 0 : strp += subs[0].rm_eo;
564 0 : } else if (subs[0].rm_so == 0 && subs[0].rm_eo == 0) {
565 : /* No more matches */
566 : regfree(&re);
567 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Regular Expression to split()");
568 0 : zend_hash_destroy(Z_ARRVAL_P(return_value));
569 0 : efree(Z_ARRVAL_P(return_value));
570 0 : RETURN_FALSE;
571 : } else {
572 : /* On a real match */
573 :
574 : /* make a copy of the substring */
575 0 : size = subs[0].rm_so;
576 :
577 : /* add it to the array */
578 0 : add_next_index_stringl(return_value, strp, size, 1);
579 :
580 : /* point at our new starting point */
581 0 : strp = strp + subs[0].rm_eo;
582 : }
583 :
584 : /* if we're only looking for a certain number of points,
585 : stop looking once we hit it */
586 0 : if (count != -1) {
587 0 : count--;
588 : }
589 : }
590 :
591 : /* see if we encountered an error */
592 0 : if (err && err != REG_NOMATCH) {
593 0 : php_reg_eprint(err, &re);
594 : regfree(&re);
595 0 : zend_hash_destroy(Z_ARRVAL_P(return_value));
596 0 : efree(Z_ARRVAL_P(return_value));
597 0 : RETURN_FALSE;
598 : }
599 :
600 : /* otherwise we just have one last element to add to the array */
601 0 : size = endp - strp;
602 :
603 0 : add_next_index_stringl(return_value, strp, size, 1);
604 :
605 : regfree(&re);
606 : }
607 : /* }}} */
608 :
609 : /* {{{ proto array split(string pattern, string string [, int limit])
610 : Split string into array by regular expression */
611 : PHP_FUNCTION(split)
612 0 : {
613 0 : php_split(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
614 0 : }
615 : /* }}} */
616 :
617 : /* {{{ proto array spliti(string pattern, string string [, int limit])
618 : Split string into array by regular expression case-insensitive */
619 :
620 : PHP_FUNCTION(spliti)
621 0 : {
622 0 : php_split(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
623 0 : }
624 :
625 : /* }}} */
626 :
627 : /* {{{ proto string sql_regcase(string string)
628 : Make regular expression for case insensitive match */
629 : PHPAPI PHP_FUNCTION(sql_regcase)
630 0 : {
631 : zval **string;
632 : char *tmp;
633 : unsigned char c;
634 : register int i, j;
635 :
636 0 : if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &string)==FAILURE) {
637 0 : WRONG_PARAM_COUNT;
638 : }
639 0 : convert_to_string_ex(string);
640 :
641 0 : tmp = safe_emalloc(Z_STRLEN_PP(string), 4, 1);
642 :
643 0 : for (i = j = 0; i < Z_STRLEN_PP(string); i++) {
644 0 : c = (unsigned char) Z_STRVAL_PP(string)[i];
645 0 : if(isalpha(c)) {
646 0 : tmp[j++] = '[';
647 0 : tmp[j++] = toupper(c);
648 0 : tmp[j++] = tolower(c);
649 0 : tmp[j++] = ']';
650 : } else {
651 0 : tmp[j++] = c;
652 : }
653 : }
654 0 : tmp[j] = 0;
655 :
656 0 : RETVAL_STRINGL(tmp, j, 1);
657 0 : efree(tmp);
658 : }
659 : /* }}} */
660 :
661 : /*
662 : * Local variables:
663 : * tab-width: 4
664 : * c-basic-offset: 4
665 : * End:
666 : * vim600: noet sw=4 ts=4 fdm=marker
667 : * vim<600: noet sw=4 ts=4
668 : */
|