#include "bacula.h"
#include "bregex.h"
/* s/toto(.)/titi$1/
* toto est beau => titi est beau
*
*/
/* re_match()
* compute_dest_len()
* check_pool_size()
* edit()
*/
typedef struct {
char *subst;
char *motif;
int nmatch;
regex_t preg;
} breg_t ;
breg_t *breg_new(char *regexp)
{
Dmsg0(500, "breg: creating new breg_t object\n");
RUNSCRIPT *cmd = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
memset(cmd, 0, sizeof(RUNSCRIPT));
cmd->reset_default();
return cmd;
}
int compute_dest_len(char *fname, char *subst,
regmatch_t *pmatch, int nmatch)
{
int len=0;
char *p;
int no;
if (!fname || !subst || !pmatch || !nmatch) {
return 0;
}
/* match failed ? */
if (pmatch[0].rm_so < 0) {
return 0;
}
for (p = subst++; *p ; p = subst++) {
/* match $1 \1 back references */
if ((*p == '$' || *p == '\\') && ('0' <= *subst && *subst <= '9')) {
no = *subst++ - '0';
/* we check if the back reference exists */
if (no < nmatch && pmatch[no].rm_so >= 0 && pmatch[no].rm_eo >= 0) {
len += pmatch[no].rm_eo - pmatch[no].rm_so;
} else {
return 0; /* back reference missing or reference number > nmatch */
}
} else {
len++;
}
}
/* $0 is replaced by subst */
len -= pmatch[0].rm_eo - pmatch[0].rm_so;
len += strlen(fname) + 1;
return len;
}
/* /toto/titi/
* preg
* subst
*/
bool extract_regexp(char *motif, regex_t *preg, POOLMEM **subst)
{
if (!motif || !preg || !subst) {
return false;
}
/* extract 1st part */
POOLMEM *dest = bstrdup(motif);
char sep = motif[0];
char *search = motif + 1;
char *replace;
bool ok = false;
bool found_motif = false;
while (*search && !ok) {
if (*search == sep && *dest == '\\') {
*dest++ = *++search; /* we skip separator */
} else if (*search == sep) {
*dest++ = '\0';
if (found_motif) { /* already have found motif */
ok = true;
} else {
replace = dest; /* get replaced string */
found_motif = true;
}
} else {
*dest++ = *search++;
}
}
*dest = '\0'; /* in case of */
if (!ok || !found_motif) {
/* bad regexp */
free(dest);
return false;
}
/* rechercher le 1er car sans \ devant */
/* compiler la re dans preg */
/* extraire le subst */
/* verifier le nombre de reference */
}
/* dest is long enough */
char *edit_subst(char *fname, char *subst, regmatch_t *pmatch, char *dest)
{
int i;
char *p;
int no;
int len;
/* il faut recopier fname dans dest
* on recopie le debut fname -> pmatch[0].rm_so
*/
for (i = 0; i < pmatch[0].rm_so ; i++) {
dest[i] = fname[i];
}
/* on recopie le motif de remplacement (avec tous les $x) */
for (p = subst++; *p ; p = subst++) {
/* match $1 \1 back references */
if ((*p == '$' || *p == '\\') && ('0' <= *subst && *subst <= '9')) {
no = *subst++ - '0';
len = pmatch[no].rm_eo - pmatch[no].rm_so;
bstrncpy(dest + i, fname + pmatch[no].rm_so, len);
i += len;
} else {
dest[i++] = *p;
}
}
strcpy(dest + i, fname + pmatch[0].rm_eo);
return dest;
}
/* return jcr->subst_fname or fname */
char *fname_subst(JCR *jcr, char *fname)
{
/* in JCR */
regex_t preg;
char *pat="$";
char *subst=".old";
char *dest=NULL;
int rc = regcomp(&preg, pat, REG_EXTENDED);
if (rc != 0) {
char prbuf[500];
regerror(rc, &preg, prbuf, sizeof(prbuf));
printf("Regex compile error: %s\n", prbuf);
return fname;
}
const int nmatch = 30;
regmatch_t pmatch[nmatch];
rc = regexec(&preg, fname, nmatch, pmatch, 0);
if (!rc) {
char prbuf[500];
regerror(rc, &preg, prbuf, sizeof(prbuf));
printf("Regex error: %s\n", prbuf);
return fname;
}
int len = compute_dest_len(fname, subst,
pmatch, nmatch);
if (len) {
dest = (char *)malloc(len);
edit_subst(fname, subst, pmatch, dest);
}
return dest;
}
syntax highlighted by Code2HTML, v. 0.9.1