]> git.sur5r.net Git - bacula/bacula/commitdiff
First cut selection list
authorKern Sibbald <kern@sibbald.com>
Sun, 1 Jan 2012 16:07:50 +0000 (17:07 +0100)
committerKern Sibbald <kern@sibbald.com>
Sun, 1 Jan 2012 16:07:50 +0000 (17:07 +0100)
bacula/src/lib/Makefile.in
bacula/src/lib/lib.h
bacula/src/lib/sellist.c [new file with mode: 0644]
bacula/src/lib/sellist.h [new file with mode: 0644]

index 312e328ddbc4e0ba923251a53a4360ca527f711a..88f416abed730c817bdf2b7d1190bbaba2d67b57 100644 (file)
@@ -39,7 +39,7 @@ INCLUDE_FILES = ../baconfig.h ../bacula.h ../bc_types.h \
                fnmatch.h guid_to_name.h htable.h lex.h \
                lib.h md5.h mem_pool.h message.h mntent_cache.h \
                openssl.h plugins.h protos.h queue.h rblist.h \
-               runscript.h rwlock.h serial.h sha1.h \
+               runscript.h rwlock.h serial.h sellist.h sha1.h \
                smartall.h status.h tls.h tree.h var.h \
                waitq.h watchdog.h workq.h \
                parse_conf.h \
@@ -55,7 +55,7 @@ LIBBAC_SRCS = attr.c base64.c berrno.c bsys.c binflate.c bget_msg.c \
              guid_to_name.c hmac.c jcr.c lex.c alist.c dlist.c \
              md5.c message.c mem_pool.c mntent_cache.c openssl.c \
              plugins.c priv.c queue.c bregex.c \
-             rwlock.c scan.c serial.c sha1.c \
+             rwlock.c scan.c sellist.c serial.c sha1.c \
              signal.c smartall.c rblist.c tls.c tree.c \
              util.c var.c watchdog.c workq.c btimers.c \
              address_conf.c breg.c htable.c lockmgr.c devlock.c
@@ -167,7 +167,7 @@ devlock_test: Makefile
 
 htable_test: Makefile
        rm -f htable.o
-       $(CXX) -DTEST_SMALL_HTABLE -DTEST_NON_CHAR -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE)  $(CFLAGS) htable.c
+       $(CXX) -DTEST_SMALL_HTABLE -DTEST_NON_CHAR -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE)  $(CFLAGS) htable.c
        $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ htable.o $(DLIB) -lbac -lm $(LIBS) $(OPENSSL_LIBS)
        rm -f htable.o
        $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) htable.c
index b2339a894561343290c781f7a690c216a251ecf0..b81f89f747d6e37261fe5de28b829f9eac278080 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -32,7 +32,6 @@
  *   that we use within Bacula. bacula.h includes this
  *   file and thus picks up everything we need in lib.
  *
- *   Version $Id$
  */
 
 #include "smartall.h"
@@ -70,4 +69,5 @@
 #include "var.h"
 #include "guid_to_name.h"
 #include "htable.h"
+#include "sellist.h"
 #include "protos.h"
diff --git a/bacula/src/lib/sellist.c b/bacula/src/lib/sellist.c
new file mode 100644 (file)
index 0000000..eeb37ce
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2011-2011 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version three of the GNU Affero General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ *  Kern Sibbald, January  MMXII
+ *
+ *  Selection list. A string of integers separated by commas
+ *   representing items selected. Ranges of the form nn-mm
+ *   are also permitted.
+ */
+
+#include "bacula.h"
+#include "sellist.h"
+
+/*
+ * Returns next item
+ *   error if returns -1 and errmsg set
+ *   end of items if returns -1 and errmsg NULL
+ */
+int64_t sellist::next()
+{
+   if (e == NULL) {
+      goto bail_out;
+   }
+   errmsg = NULL;
+   if (beg <= end) {
+      return beg++;
+   }
+   /*
+    * As we walk the list, we set EOF in
+    *   the end of the next item to ease scanning,
+    *   but save and then restore the character.
+    */
+   for (p=e; p && *p; p=e) {
+      /* Check for list */
+      e = strchr(p, ',');
+      if (e) {
+         esave = *e;
+         *e++ = 0;
+      } else {
+         esave = 0;
+      }
+      /* Check for range */
+      h = strchr(p, '-');             /* range? */
+      if (h == p) {
+         errmsg = _("Negative numbers not permitted.\n");
+         goto bail_out;
+      }
+      if (h) {
+         hsave = *h;
+         *h++ = 0;
+         if (!is_an_integer(h)) {
+            errmsg = _("Range end is not integer.\n");
+            goto bail_out;
+         }
+         skip_spaces(&p);
+         if (!is_an_integer(p)) {
+            errmsg = _("Range start is not an integer.\n");
+            goto bail_out;
+         }
+         beg = str_to_int64(p);
+         end = str_to_int64(h);
+         if (end < beg) {
+            errmsg = _("Range end not bigger than start.\n");
+            goto bail_out;
+         }
+      } else {
+         hsave = 0;
+         skip_spaces(&p);
+         if (!is_an_integer(p)) {
+            errmsg = _("Input value is not an integer.\n");
+            goto bail_out;
+         }
+         beg = end = str_to_int64(p);
+      }
+      if (esave) {
+         *(e-1) = esave;
+      }
+      if (hsave) {
+         *(h-1) = hsave;
+      }
+      if (beg <= 0 || end <= 0) {
+         errmsg = _("Selection items must be be greater than zero.\n");
+         goto bail_out;
+      }
+      if (end > max) {
+         errmsg = _("Selection item too large.\n");
+         goto bail_out;
+      }
+      if (beg <= end) {
+         return beg++;
+      }
+   }
+   /* End of items */
+   errmsg = NULL;      /* No error */
+   return -1;
+
+bail_out:
+   return -1;          /* Error, errmsg set */
+}
+
+
+/*
+ * Set selection string and optionally scan it
+ *   returns false on error in string
+ *   returns true if OK
+ */
+bool sellist::set_string(char *string, bool scan=true)
+{
+   /*
+    * Copy string, because we write into it,
+    *  then scan through it once to find any
+    *  errors.
+    */
+   if (str) {
+      free(str);
+   }
+   e = str = bstrdup(string);
+   end = 0;
+   beg = 1;
+   num_items = 0;
+   if (scan) {
+      while (next() >= 0) {
+         num_items++;
+      }
+      if (get_errmsg()) {
+         return false;
+      }
+      e = str;
+      end = 0;
+      beg = 1;
+   }
+   return true;
+}
+
+#ifdef TEST_PROGRAM
+int main(int argc, char **argv, char **env)
+{
+   char *msg;
+   sellist sl;
+   int i;
+
+   if (!argv[1]) {
+      msg = _("No input string given.\n");
+      goto bail_out;
+   }
+   Dmsg1(000, "argv[1]=%s\n", argv[1]);
+
+   strip_trailing_junk(argv[1]);
+   sl.set_string(argv[1]);
+   if ((msg = sl.get_errmsg())) {
+      goto bail_out;
+   }
+   while ((i=sl.next()) >= 0) {
+      Dmsg1(000, "%d\n", i);
+   }
+   if ((msg = sl.get_errmsg())) {
+      goto bail_out;
+   }
+   printf("\nPass 2\n");
+   sl.set_string(argv[1]);
+   while ((i=sl.next()) >= 0) {
+      Dmsg1(000, "%d\n", i);
+   }
+   if ((msg = sl.get_errmsg())) {
+      goto bail_out;
+   }
+   return 0;
+
+bail_out:
+   Dmsg1(000, "Error: %s\n", msg);
+   return 1;
+
+}
+#endif /* TEST_PROGRAM */
diff --git a/bacula/src/lib/sellist.h b/bacula/src/lib/sellist.h
new file mode 100644 (file)
index 0000000..99365bd
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2011-2011 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version three of the GNU Affero General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ *  Kern Sibbald, January  MMXII
+ *
+ *  Selection list. A string of integers separated by commas
+ *   representing items selected. Ranges of the form nn-mm
+ *   are also permitted.
+ */
+
+/*
+ * Loop var through each member of list
+ */
+#define foreach_sellist(var, list) \
+        for((var)=(list)->first(); (var)>=0; (var)=(list)->next() )
+
+
+class sellist : public SMARTALLOC {
+   char *errmsg;
+   char *p, *e, *h;
+   char esave, hsave;
+   int64_t beg, end;
+   int64_t max;
+   int num_items;
+   char *str;
+public:
+   sellist();
+   ~sellist();
+   bool set_string(char *string, bool scan);
+   int64_t first();
+   int64_t next();
+   int size() const;
+   char *get_errmsg();
+};
+
+/*
+ * Initialize the list structure
+ */
+inline sellist::sellist()
+{
+   num_items = 0;
+   max = 99999;
+   str = NULL;
+   e = errmsg = NULL;
+}   
+
+/*
+ * Destroy the list
+ */
+inline sellist::~sellist() 
+{
+   if (str) {
+      free(str);
+      str = NULL;
+   }
+}
+
+/*
+ * Return list size, but only if scan enabled on string
+ */
+inline int sellist::size() const
+{
+   return num_items;
+}
+
+/*
+ * Return error message or NULL if none
+ */
+inline char *sellist::get_errmsg()
+{
+   return errmsg;
+}
+
+/*
+ * Returns first item
+ *   error if returns -1 and errmsg set
+ *   end of items if returns -1 and errmsg NULL
+ */
+inline int64_t sellist::first()
+{
+   e = str;
+   end = 0;
+   beg = 1;
+   errmsg = NULL;
+   return next();
+}