]> mj.ucw.cz Git - libucw.git/blobdiff - lib/conf.c
Another thing about the C standard I didn't know: passing a va_list to
[libucw.git] / lib / conf.c
index c2e5f1b4fa14dd3599b5c405d2cdeded05a95049..2293cdae84a836ab7b22e0d6504e2003c80d228f 100644 (file)
@@ -1,8 +1,8 @@
 /*
- *     Sherlock Library -- Reading of configuration files
+ *     UCW Library -- Reading of configuration files
  *
  *     (c) 2001 Robert Spalek <robert@ucw.cz>
- *     (c) 2003 Martin Mares <mj@ucw.cz>
+ *     (c) 2003--2005 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
@@ -11,7 +11,7 @@
 #include "lib/lib.h"
 #include "lib/chartype.h"
 #include "lib/fastbuf.h"
-#include "lib/pools.h"
+#include "lib/mempool.h"
 
 #include "lib/conf.h"
 
 static struct cfitem *cfsection;
 struct mempool *cfpool;
 
+#ifndef DEFAULT_CONFIG
+#define DEFAULT_CONFIG NULL
+#endif
+
 byte *cfdeffile = DEFAULT_CONFIG;
 
 static void CONSTRUCTOR
@@ -42,13 +46,16 @@ cfg_malloc(uns size)
        return mp_alloc(cfpool, size);
 }
 
+void *
+cfg_malloc_zero(uns size)
+{
+       return mp_alloc_zero(cfpool, size);
+}
+
 byte *
-cfg_stralloc(byte *s)
+cfg_strdup(byte *s)
 {
-       uns l = strlen(s);
-       byte *k = cfg_malloc(l + 1);
-       strcpy(k, s);
-       return k;
+       return mp_strdup(cfpool, s);
 }
 
 void cf_register(struct cfitem *items)
@@ -94,7 +101,7 @@ struct unit {
 
 static const struct unit units[] = {
        { 'd', 86400, 1 },
-       { 'h', 1440, 1 },
+       { 'h', 3600, 1 },
        { 'k', 1000, 1 },
        { 'm', 1000000, 1 },
        { 'g', 1000000000, 1 },
@@ -217,10 +224,10 @@ byte *cf_set_item(byte *sect, byte *name, byte *value)
                        msg = cf_parse_int(value, (uns *) item->var);
                        break;
                case CT_STRING:
-                       *((byte **) item->var) = cfg_stralloc(value);
+                       *((byte **) item->var) = cfg_strdup(value);
                        break;
                case CT_FUNCTION:
-                       msg = ((ci_func) item->var)(item, cfg_stralloc(value));
+                       msg = ((ci_func) item->var)(item, cfg_strdup(value));
                        break;
                case CT_DOUBLE:
                        msg = cf_parse_double(value, (double *) item->var);
@@ -334,50 +341,63 @@ void cf_read(byte *filename)
        cfdeffile = NULL;
 }
 
+static void cf_opt_S(void)
+{
+       byte *sect,*name,*value;
+       byte *c;
+       byte *msg=NULL;
+       byte arg[strlen(optarg)+1];
+
+       strcpy(arg, optarg);
+       name = arg;
+       c=strchr(name,'=');
+       if(!c){
+               msg="Missing argument";
+               sect=value="";
+       }else{
+               *c++=0;
+               value=c;
+
+               c=strchr(name,'.');
+               if(!c)
+                       sect="";
+               else{
+                       sect=name;
+                       *c++=0;
+                       name=c;
+               }
+
+               if (cfdeffile)
+                       cf_read(cfdeffile);
+               msg=cf_set_item(sect,name,value);
+       }
+       if(msg)
+               die("Invalid command line argument -S%s.%s=%s: %s",sect,name,value,msg);
+
+}
+
 int cf_getopt(int argc,char * const argv[],
                const char *shortopts,const struct option *longopts,
                int *longindex)
 {
        int res;
+       static int other_options;
 
        do{
                res=getopt_long(argc,argv,shortopts,longopts,longindex);
+               if(res == 'S' || res == 'C') {
+                       if(other_options)
+                               die("The -S and -C options must precede all other arguments");
+               }
                if(res=='S'){
-                       byte *sect,*name,*value;
-                       byte *c;
-                       byte *msg=NULL;
-
-                       name=optarg;
-                       c=strchr(name,'=');
-                       if(!c){
-                               msg="Missing argument";
-                               sect=value="";
-                       }else{
-                               *c++=0;
-                               value=c;
-
-                               c=strchr(name,'.');
-                               if(!c)
-                                       sect="";
-                               else{
-                                       sect=name;
-                                       *c++=0;
-                                       name=c;
-                               }
-
-                               if (cfdeffile)
-                                       cf_read(cfdeffile);
-                               msg=cf_set_item(sect,name,value);
-                       }
-                       if(msg)
-                               die("Invalid command line argument %s.%s=%s: %s",sect,name,value,msg);
-
+                       cf_opt_S();
                }else if(res=='C'){
                        cf_read(optarg);
                }else{
                        /* unhandled option or end of options */
                        if(cfdeffile)
                                cf_read(cfdeffile);
+                       other_options++;
                        return res;
                }
        }while(1);