]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/testing/resubst.c
Update
[bacula/bacula] / bacula / patches / testing / resubst.c
1 #include "bacula.h"
2 #include "bregex.h"
3
4 /* s/toto(.)/titi$1/ 
5  * toto est beau => titi est beau
6  *
7  */
8
9 /* re_match()
10  * compute_dest_len()
11  * check_pool_size()
12  * edit()
13  */
14
15 typedef struct {
16    char *subst;
17    char *motif;
18    int nmatch;
19    regex_t preg;
20 } breg_t ;
21
22 breg_t *breg_new(char *regexp)
23 {
24    Dmsg0(500, "breg: creating new breg_t object\n");
25    RUNSCRIPT *cmd = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
26    memset(cmd, 0, sizeof(RUNSCRIPT));
27    cmd->reset_default();
28    
29    return cmd;
30
31 }
32
33
34 int compute_dest_len(char *fname, char *subst, 
35                      regmatch_t *pmatch, int nmatch)
36 {
37    int len=0;
38    char *p;
39    int no;
40
41    if (!fname || !subst || !pmatch || !nmatch) {
42       return 0;
43    }
44
45    /* match failed ? */
46    if (pmatch[0].rm_so < 0) {
47       return 0;
48    }
49
50    for (p = subst++; *p ; p = subst++) {
51       /* match $1 \1 back references */
52       if ((*p == '$' || *p == '\\') && ('0' <= *subst && *subst <= '9')) {
53          no = *subst++ - '0';
54
55          /* we check if the back reference exists */
56          if (no < nmatch && pmatch[no].rm_so >= 0 && pmatch[no].rm_eo >= 0) { 
57             len += pmatch[no].rm_eo - pmatch[no].rm_so;
58          } else {
59             return 0; /* back reference missing or reference number > nmatch */
60          }
61       } else {
62          len++;
63       }
64    }
65
66    /* $0 is replaced by subst */
67    len -= pmatch[0].rm_eo - pmatch[0].rm_so;
68    len += strlen(fname) + 1;
69
70    return len;
71 }
72
73 /* /toto/titi/ 
74  * preg
75  * subst
76  */
77 bool extract_regexp(char *motif, regex_t *preg, POOLMEM **subst)
78 {
79    if (!motif || !preg || !subst) {
80       return false;
81    }
82    /* extract 1st part */
83    POOLMEM *dest = bstrdup(motif);
84    char sep = motif[0];
85    char *search = motif + 1;
86    char *replace;
87    bool ok = false;
88    bool found_motif = false;
89
90    while (*search && !ok) {
91       if (*search == sep && *dest == '\\') {
92          *dest++ = *++search;       /* we skip separator */ 
93
94       } else if (*search == sep) {
95          *dest++ = '\0';
96          if (found_motif) {     /* already have found motif */
97             ok = true;
98          } else {
99             replace = dest;     /* get replaced string */
100             found_motif = true;
101          }
102       } else {
103          *dest++ = *search++;
104       }
105    }
106    *dest = '\0';                /* in case of */
107    
108    if (!ok || !found_motif) {
109       /* bad regexp */
110       free(dest);
111       return false;
112    }
113
114    
115   
116
117    /* rechercher le 1er car sans \ devant */
118    /* compiler la re dans preg */
119    /* extraire le subst */
120    /* verifier le nombre de reference */
121 }
122
123 /* dest is long enough */
124 char *edit_subst(char *fname, char *subst, regmatch_t *pmatch, char *dest)
125 {
126    int i;
127    char *p;
128    int no;
129    int len;
130
131    /* il faut recopier fname dans dest
132     *  on recopie le debut fname -> pmatch[0].rm_so
133     */
134    
135    for (i = 0; i < pmatch[0].rm_so ; i++) {
136       dest[i] = fname[i];
137    }
138
139    /* on recopie le motif de remplacement (avec tous les $x) */
140
141    for (p = subst++; *p ; p = subst++) {
142       /* match $1 \1 back references */
143       if ((*p == '$' || *p == '\\') && ('0' <= *subst && *subst <= '9')) {
144          no = *subst++ - '0';
145
146          len = pmatch[no].rm_eo - pmatch[no].rm_so;
147          bstrncpy(dest + i, fname + pmatch[no].rm_so, len);
148          i += len;
149
150       } else {
151          dest[i++] = *p;
152       }
153    }
154
155    strcpy(dest + i, fname + pmatch[0].rm_eo);
156
157    return dest;
158 }
159
160 /* return jcr->subst_fname or fname */
161 char *fname_subst(JCR *jcr, char *fname)
162 {
163    /* in JCR */
164    regex_t preg;
165    char *pat="$";
166    char *subst=".old";
167    char *dest=NULL;
168
169    int rc = regcomp(&preg, pat, REG_EXTENDED);
170    if (rc != 0) {
171       char prbuf[500];
172       regerror(rc, &preg, prbuf, sizeof(prbuf));
173       printf("Regex compile error: %s\n", prbuf);
174       return fname;
175    }
176
177    const int nmatch = 30;
178    regmatch_t pmatch[nmatch];
179    rc = regexec(&preg, fname, nmatch, pmatch,  0);
180
181    if (!rc) {
182       char prbuf[500];
183       regerror(rc, &preg, prbuf, sizeof(prbuf));
184       printf("Regex error: %s\n", prbuf);
185       return fname;
186    }
187
188    int len = compute_dest_len(fname, subst, 
189                               pmatch, nmatch);
190
191    if (len) {
192       dest = (char *)malloc(len);
193       edit_subst(fname, subst, pmatch, dest);
194    }
195
196    return dest;
197