OSDN Git Service

73a674f5a2d198dfb93dd07f83866e5164c47a68
[modchxj/mod_chxj.git] / src / chxj_preg_replace.c
1 /*
2  * Copyright (C) 2005-2008 Atsushi Konno All rights reserved.
3  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include <apr.h>
18 #include <ap_config.h>
19 #include <ap_regex.h>
20 #include <apr_strings.h>
21 #include <httpd.h>
22
23 #include "chxj_preg_replace.h"
24
25 static inline char *
26 s_init_pattern(apr_pool_t *p, const char *old)
27 {
28   return apr_psprintf(p, "^(.*)(%s)(.*)$", old);
29 }
30
31
32 static inline ap_regex_t *
33 s_compile_regex(apr_pool_t *p, const char *pattern)
34 {
35   char *new_pat;
36   new_pat = s_init_pattern(p, pattern);
37   return ap_pregcomp(p, new_pat, AP_REG_EXTENDED|AP_REG_ICASE);
38 }
39
40 ap_regex_t *
41 chxj_compile_for_preg_replace(apr_pool_t *p, const char *pattern)
42 {
43   return s_compile_regex(p, pattern);
44 }
45
46
47 static inline char *
48 s_one_time_replace(apr_pool_t *p, ap_regex_t *regexp, const char *replacement, const char *str)
49 {
50   ap_regmatch_t match[10];
51
52   if (ap_regexec(regexp, str, regexp->re_nsub + 1, match, 0) == 0) {
53     /* Match */
54     char *one = ap_pregsub(p, "$1", str, regexp->re_nsub + 1, match);
55     char *three = ap_pregsub(p, "$3", str, regexp->re_nsub + 1, match);
56     if (strlen(replacement)) {
57       return apr_pstrcat(p, one, replacement, three, NULL);
58     }
59     return apr_pstrcat(p, one, three, NULL);
60   }
61   /* Not Match */
62   return NULL;
63 }
64
65
66 char *
67 chxj_preg_str_replace(apr_pool_t *p, const char *pattern, const char *replacement, const char *str)
68 {
69   return chxj_preg_replace(p, s_compile_regex(p, pattern), replacement, str);
70 }
71
72
73 char *
74 chxj_preg_str_replace_all(apr_pool_t *p, const char *pattern, const char *replacement, const char *str)
75 {
76   return chxj_preg_replace_all(p, s_compile_regex(p, pattern), replacement, str);
77 }
78
79
80 char *
81 chxj_preg_replace(apr_pool_t *p, ap_regex_t *regexp, const char *replacement, const char *str)
82 {
83   char *result;
84
85   result = s_one_time_replace(p, regexp, replacement, str);
86   if (result == NULL)
87     return apr_pstrdup(p, str);
88
89   return result;
90 }
91
92
93 char *
94 chxj_preg_replace_all(apr_pool_t *p, ap_regex_t *regexp, const char *replacement, const char *str)
95 {
96   char *result;
97   char *pre_result;
98
99   result = apr_pstrdup(p, str);
100   for (;;) {
101     pre_result = s_one_time_replace(p, regexp, replacement, result);
102     if (pre_result == NULL)
103       break;
104     result = pre_result;
105   }
106
107   return result;
108 }
109
110