2 * Manipulation routines for BREGEXP list
4 * Eric Bollengier, Mars 2007
10 Bacula® - The Network Backup Solution
12 Copyright (C) 2006-2006 Free Software Foundation Europe e.V.
14 The main author of Bacula is Kern Sibbald, with contributions from
15 many others, a complete list can be found in the file AUTHORS.
16 This program is Free Software; you can redistribute it and/or
17 modify it under the terms of version two of the GNU General Public
18 License as published by the Free Software Foundation plus additions
19 that are listed in the file LICENSE.
21 This program is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 Bacula® is a registered trademark of John Walker.
32 The licensor of Bacula is the Free Software Foundation Europe
33 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34 Switzerland, email:ftf@fsfeurope.org.
43 BREGEXP *new_bregexp(const char *motif)
45 Dmsg0(500, "bregexp: creating new bregexp object\n");
46 BREGEXP *self = (BREGEXP *)malloc(sizeof(BREGEXP));
47 memset(self, 0, sizeof(BREGEXP));
51 if (!self->extract_regexp(motif)) {
52 // Dmsg0(100, "bregexp: extract_regexp error\n");
53 printf("bregexp: extract_regexp error\n");
58 self->result = get_pool_memory(PM_FNAME);
63 bool BREGEXP::extract_regexp(const char *motif)
70 char *search = (char *) motif + 1;
72 int options = REG_EXTENDED;
74 bool found_motif = false;
76 /* extract 1st part */
77 char *dest = expr = bstrdup(motif);
79 while (*search && !ok) {
80 if (*search == '\\' && *dest == sep) {
81 *dest++ = *++search; /* we skip separator */
82 } else if (*search == sep) {
85 if (subst) { /* already have found motif */
88 *dest++ = *++search; /* we skip separator */
89 subst = dest; /* get replaced string */
95 *dest = '\0'; /* in case of */
104 if (*search == 'i') {
105 options |= REG_ICASE;
110 int rc = regcomp(&preg, expr, options);
113 regerror(rc, &preg, prbuf, sizeof(prbuf));
114 printf("bregexp: compile error: %s\n", prbuf);
115 // Dmsg1(100, "bregexp: compile error: %s\n", prbuf);
123 void free_bregexp(BREGEXP *self)
125 Dmsg0(500, "bregexp: freeing BREGEXP object\n");
131 free_pool_memory(self->result);
133 regfree(&self->preg);
137 void free_bregexps(alist *bregexps)
139 Dmsg0(500, "bregexp: freeing all BREGEXP object\n");
142 foreach_alist(elt, bregexps) {
147 /* return regexp->result */
148 char *BREGEXP::replace(const char *fname)
150 struct re_registers regs;
151 int flen = strlen(fname);
152 int rc = re_search(&preg, fname, flen, 0, flen, ®s);
155 printf("E: regex mismatch\n");
156 return return_fname(fname, flen);
159 int len = compute_dest_len(fname, ®s);
162 result = check_pool_memory_size(result, len);
163 edit_subst(fname, ®s);
165 } else { /* error in substitution */
166 printf("E: error in substitution\n");
167 return return_fname(fname, flen);
173 char *BREGEXP::return_fname(const char *fname, int len)
175 result = check_pool_memory_size(result, len+1);
176 strcpy(result,fname);
180 int BREGEXP::compute_dest_len(const char *fname, struct re_registers *regs)
184 char *psubst = subst;
187 if (!fname || !regs) {
192 if (regs->start[0] < 0) {
196 for (p = psubst++; *p ; p = psubst++) {
197 /* match $1 \1 back references */
198 if ((*p == '$' || *p == '\\') && ('0' <= *psubst && *psubst <= '9')) {
199 no = *psubst++ - '0';
201 /* we check if the back reference exists */
202 if (regs->start[no] >= 0 && regs->end[no] >= 0) {
203 len += regs->end[no] - regs->start[no];
205 return 0; /* back reference missing */
212 /* $0 is replaced by subst */
213 len -= regs->end[0] - regs->start[0];
214 len += strlen(fname) + 1;
219 char *BREGEXP::edit_subst(const char *fname, struct re_registers *regs)
223 char *psubst = subst;
227 /* il faut recopier fname dans dest
228 * on recopie le debut fname -> regs->start[0]
231 for (i = 0; i < regs->start[0] ; i++) {
232 result[i] = fname[i];
235 /* on recopie le motif de remplacement (avec tous les $x) */
237 for (p = psubst++; *p ; p = psubst++) {
238 /* match $1 \1 back references */
239 if ((*p == '$' || *p == '\\') && ('0' <= *psubst && *psubst <= '9')) {
240 no = *psubst++ - '0';
242 len = regs->end[no] - regs->start[no];
243 bstrncpy(result + i, fname + regs->start[no], len + 1);
251 strcpy(result + i, fname + regs->end[0]);
256 void BREGEXP::debug()
258 printf("expr=[%s]\n", expr);
259 printf("subst=[%s]\n", subst);
260 printf("result=%s\n", result?result:"(null)");
263 int main(int argc, char **argv)
267 reg = new_bregexp(argv[1]);
270 reg->replace(argv[2]);
272 printf("%s => %s\n", argv[1], reg->result);