]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/patches/testing/breg.c
ebl fix compilation
[bacula/bacula] / bacula / patches / testing / breg.c
index 261424fd4c94262b307849b2d824e8294e637686..7468c6572d0a17f04ace7d84e6113604ea4ea8ea 100644 (file)
@@ -7,7 +7,7 @@
  *
  */
 /*
-   Bacula® - The Network Backup Solution
+   Bacula\81Â\81® - The Network Backup Solution
 
    Copyright (C) 2006-2006 Free Software Foundation Europe e.V.
 
@@ -28,9 +28,9 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Bacula® is a registered trademark of John Walker.
+   Bacula\81Â\81® is a registered trademark of John Walker.
    The licensor of Bacula is the Free Software Foundation Europe
-   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Z\81Ã\81¼rich,
    Switzerland, email:ftf@fsfeurope.org.
 */
 
 BREGEXP *new_bregexp(const char *motif)
 {
    Dmsg0(500, "bregexp: creating new bregexp object\n");
-   BREGEXP *self = (BREGEXP *)malloc(sizeof(BREGEXP));
+   BREGEXP *self = (BREGEXP *)bmalloc(sizeof(BREGEXP));
    memset(self, 0, sizeof(BREGEXP));
    
    if (!self->extract_regexp(motif)) {
-//      Dmsg0(100, "bregexp: extract_regexp error\n");
-      printf("bregexp: extract_regexp error\n");
+      Dmsg0(100, "bregexp: extract_regexp error\n");
       free_bregexp(self);
       return NULL;
    }
 
-   static int _start[RE_NREGS];
-   static int _end[RE_NREGS];
-
    self->result = get_pool_memory(PM_FNAME);
    self->result[0] = '\0';
 
 #ifdef HAVE_REGEX_H
    /* TODO: que devient cette memoire... */
-   self->_regs_match = (int *) malloc (2*RE_NREGS * sizeof(int));
+   self->_regs_match = (int *) bmalloc (2*RE_NREGS * sizeof(int));
 
    self->regs.num_regs = RE_NREGS;
    self->regs.start = self->_regs_match;
@@ -75,20 +71,26 @@ void free_bregexp(BREGEXP *self)
 {
    Dmsg0(500, "bregexp: freeing BREGEXP object\n");
 
+   if (!self) {
+      return;
+   }
+
    if (self->expr) {
-      free(self->expr);
+      bfree(self->expr);
    }
    if (self->result) {
       free_pool_memory(self->result);
    }
    if (self->_regs_match) {
-      free(self->_regs_match);
+      bfree(self->_regs_match);
    }
 
    regfree(&self->preg);
-   free(self);
+   bfree(self);
 }
 
+/* Free a bregexps alist
+ */
 void free_bregexps(alist *bregexps)
 {
    Dmsg0(500, "bregexp: freeing all BREGEXP object\n");
@@ -99,34 +101,96 @@ void free_bregexps(alist *bregexps)
    }
 }
 
+/* Apply all regexps to fname
+ */
+bool apply_bregexps(const char *fname, alist *bregexps, char **result)
+{
+   BREGEXP *elt;
+   bool ok=false;
+
+   char *ret = (char *) fname;
+   foreach_alist(elt, bregexps) {
+      ret = elt->replace(ret);
+      ok = ok || elt->success;
+   }
+   Dmsg2(500, "bregexp: fname=%s ret=%s\n", fname, ret);
+
+   *result = ret;
+   return ok;
+}
+
+/* return an alist of BREGEXP or return NULL if it's not a 
+ * where=!tmp!opt!ig,!temp!opt!i
+ */
+alist *get_bregexps(const char *where)
+{
+   char *p = (char *)where;
+   alist *list = New(alist(10, not_owned_by_alist));
+   BREGEXP *reg;
+
+   reg = new_bregexp(p);
+
+   while(reg) {
+      p = reg->eor;
+      list->append(reg);
+      reg = new_bregexp(p);
+   }
+
+   if (list->size()) {
+      return list;      
+   } else {
+      delete list;
+      return NULL;
+   }
+}
+
 bool BREGEXP::extract_regexp(const char *motif)
 {
-   
-   if (!motif) {
+   if ( !motif ) {
       return false;
    }
+   
    char sep = motif[0];
+
+   if (!(sep == '!' || 
+        sep == ':' || 
+        sep == ';' || 
+        sep == '|' || 
+        sep == ',' || 
+        sep == '&' || 
+        sep == '%' || 
+        sep == '=' || 
+        sep == '~' ||
+        sep == '#'   )) 
+   {
+      return false;
+   }
+
    char *search = (char *) motif + 1;
-   char *replace;
    int options = REG_EXTENDED | REG_NEWLINE;
    bool ok = false;
-   bool found_motif = false;
 
    /* extract 1st part */
    char *dest = expr = bstrdup(motif);
 
    while (*search && !ok) {
-      if (*search == '\\' && *dest == sep) {
+      if (search[0] == '\\' && search[1] == sep) {
         *dest++ = *++search;       /* we skip separator */ 
-      } else if (*search == sep) {
+
+      } else if (search[0] == '\\' && search[1] == '\\') {
+        *dest++ = *++search;       /* we skip the second \ */
+
+      } else if (*search == sep) {  /* we found end of expression */
         *dest++ = '\0';
 
-        if (subst) {   /* already have found motif */
+        if (subst) {           /* already have found motif */
            ok = true;
+
         } else {
            *dest++ = *++search; /* we skip separator */ 
            subst = dest;        /* get replaced string */
         }
+
       } else {
         *dest++ = *search++;
       }
@@ -138,13 +202,20 @@ bool BREGEXP::extract_regexp(const char *motif)
       return false;
    }
 
+   ok = false;
    /* find options */
-   while (*search) {
+   while (*search && !ok) {
       if (*search == 'i') {
         options |= REG_ICASE;
-      }
-      if (*search == 'g') {
+
+      } else if (*search == 'g') {
              /* recherche multiple*/
+
+      } else if (*search == sep) {
+        /* skip separator */
+
+      } else {                 /* end of options */
+        ok = true;
       }
       search++;
    }
@@ -153,11 +224,12 @@ bool BREGEXP::extract_regexp(const char *motif)
    if (rc != 0) {
       char prbuf[500];
       regerror(rc, &preg, prbuf, sizeof(prbuf));
-      printf("bregexp: compile error: %s\n", prbuf);
-//      Dmsg1(100, "bregexp: compile error: %s\n", prbuf);
+      Dmsg1(100, "bregexp: compile error: %s\n", prbuf);
       return false;
    }
 
+   eor = search;               /* useful to find the next regexp in where */
+
    return true;
 }
 
@@ -170,11 +242,12 @@ bool BREGEXP::extract_regexp(const char *motif)
 /* return regexp->result */
 char *BREGEXP::replace(const char *fname)
 {
+   success = false;            /* use this.success to known if it's ok */
    int flen = strlen(fname);
    int rc = re_search(&preg, (BREGEX_CAST char*) fname, flen, 0, flen, &regs);
 
    if (rc < 0) {
-      printf("E: regex mismatch\n");
+      Dmsg0(500, "bregexp: regex mismatch\n");
       return return_fname(fname, flen);
    }
 
@@ -183,9 +256,11 @@ char *BREGEXP::replace(const char *fname)
    if (len) {
       result = check_pool_memory_size(result, len);
       edit_subst(fname, &regs);
+      success = true;
+      Dmsg2(500, "bregexp: len = %i, result_len = %i\n", len, strlen(result));
 
    } else {                    /* error in substitution */
-      printf("E: error in substitution\n");
+      Dmsg0(100, "bregexp: error in substitution\n");
       return return_fname(fname, flen);
    }
 
@@ -221,11 +296,12 @@ int BREGEXP::compute_dest_len(const char *fname, struct re_registers *regs)
         no = *psubst++ - '0';
 
         /* we check if the back reference exists */
+        /* references can not match if we are using (..)? */
+
         if (regs->start[no] >= 0 && regs->end[no] >= 0) { 
            len += regs->end[no] - regs->start[no];
-        } else {
-           return 0; /* back reference missing */
         }
+        
       } else {
         len++;
       }
@@ -261,9 +337,12 @@ char *BREGEXP::edit_subst(const char *fname, struct re_registers *regs)
       if ((*p == '$' || *p == '\\') && ('0' <= *psubst && *psubst <= '9')) {
         no = *psubst++ - '0';
 
-        len = regs->end[no] - regs->start[no];
-        bstrncpy(result + i, fname + regs->start[no], len + 1);
-        i += len ;
+        /* have a back reference ? */
+        if (regs->start[no] >= 0 && regs->end[no] >= 0) {
+           len = regs->end[no] - regs->start[no];
+           bstrncpy(result + i, fname + regs->start[no], len + 1);
+           i += len ;
+        }
 
       } else {
         result[i++] = *p;
@@ -276,27 +355,91 @@ char *BREGEXP::edit_subst(const char *fname, struct re_registers *regs)
    return result;
 }
 
-void BREGEXP::debug()
+/* escape sep char and \
+ * dest must be long enough (src*2+1)
+ * return end of the string */
+char *bregexp_escape_string(char *dest, char *src, char sep)
 {
-   printf("expr=[%s]\n", expr);
-   printf("subst=[%s]\n", subst);
-   printf("result=%s\n", result?result:"(null)");
+   char *ret = dest;
+   while (*src)
+   {
+      if (*src == sep) {
+        *dest++ = '\\';
+      } else if (*src == '\\') {
+        *dest++ = '\\';
+      }
+      *dest++ = *src++;
+   }
+   *dest = '\0';
+
+   return ret; 
 }
 
-#ifdef TEST
+int bregexp_get_build_where_size(char *strip_prefix, 
+                                char *add_prefix, 
+                                char *add_suffix)
+{
+   /* strip_prefix = !strip_prefix!!i        4 bytes
+    * add_prefix   = !^!add_prefix!          5 bytes
+    * add_suffix   = !([^/])$!$1add_suffix! 13 bytes
+    */
+   int str_size = ((strip_prefix?strlen(strip_prefix)+4:0) +
+                  (add_prefix?strlen(add_prefix)+5    :0) + /* escape + 3*, + \0 */ 
+                  (add_suffix?strlen(add_suffix)+14   :0) )   * 2     + 3   + 1;
+
+   Dmsg1(1, "bregexp_get_build_where_size = %i\n", str_size);
+   return str_size;
+}
 
-int main(int argc, char **argv)
+/* build a regexp string with user arguments
+ * Usage :
+ * 
+ * int len = bregexp_get_build_where_size(a,b,c) ;
+ * char *dest = (char *) bmalloc (len * sizeof(char));
+ * bregexp_build_where(dest, len, a, b, c);
+ * free(dest);
+ * 
+ */
+char *bregexp_build_where(char *dest, int str_size,
+                         char *strip_prefix, 
+                          char *add_prefix, 
+                          char *add_suffix)
 {
-   BREGEXP *reg;
+   int len=0;
+   char sep = '!';
+
+   POOLMEM *str_tmp = get_memory(str_size);
+
+   *str_tmp = *dest = '\0';
    
-   reg = new_bregexp(argv[1]);
+   if (strip_prefix) {
+      len += bsnprintf(dest, str_size - len, "!%s!!i",
+                      bregexp_escape_string(str_tmp, strip_prefix, sep));
+   }
 
-   if (reg) {
-      reg->replace(argv[2]);
-      reg->debug();
-      printf("%s => %s\n", argv[1], reg->result);
+   if (add_suffix) {
+      if (len) dest[len++] = ',';
+
+      len += bsnprintf(dest + len,  str_size - len, "!([^/])$!$1%s!",
+                      bregexp_escape_string(str_tmp, add_suffix, sep));
    }
-   exit(0);
+
+   if (add_prefix) {
+      if (len) dest[len++] = ',';
+
+      len += bsnprintf(dest + len, str_size - len, "!^!%s!", 
+                      bregexp_escape_string(str_tmp, add_prefix, sep));
+   }
+
+   free_pool_memory(str_tmp);
+
+   return dest;
 }
 
-#endif
+
+void BREGEXP::debug()
+{
+   printf("expr=[%s]\n", expr);
+   printf("subst=[%s]\n", subst);
+   printf("result=%s\n", result?result:"(null)");
+}