]> mj.ucw.cz Git - libucw.git/blobdiff - lib/conf.c
Added STRINGIFY macro.
[libucw.git] / lib / conf.c
index b27745faeea8f90a0c0bab6e3d2cf809adbe42d0..35f0502b743b007e0591527aabef8a534a24bf08 100644 (file)
@@ -93,6 +93,8 @@ struct unit {
 };
 
 static const struct unit units[] = {
+       { 'd', 86400, 1 },
+       { 'h', 3600, 1 },
        { 'k', 1000, 1 },
        { 'm', 1000000, 1 },
        { 'g', 1000000000, 1 },
@@ -149,6 +151,35 @@ byte *cf_parse_int(byte *value, uns *varp)
        return msg;
 }
 
+byte *cf_parse_u64(byte *value, u64 *varp)
+{
+       char *msg = NULL;
+       const struct unit *u;
+
+       if (!*value)
+               msg = "Missing number";
+       else {
+               errno = 0;
+               char *end;
+               u64 x = strtoull(value, &end, 0);
+               if (errno == ERANGE)
+                       msg = cf_rngerr;
+               else if (u = cf_lookup_unit(value, end, &msg)) {
+                       if (x > ~(u64)0 / u->num)
+                               msg = "Number out of range";
+                       else {
+                               x *= u->num;
+                               if (x % u->den)
+                                       msg = "Number is not an integer";
+                               else
+                                       *varp = x / u->den;
+                       }
+               } else
+                       *varp = x;
+       }
+       return msg;
+}
+
 byte *cf_parse_double(byte *value, double *varp)
 {
        char *msg = NULL;
@@ -194,6 +225,9 @@ byte *cf_set_item(byte *sect, byte *name, byte *value)
                case CT_DOUBLE:
                        msg = cf_parse_double(value, (double *) item->var);
                        break;
+               case CT_U64:
+                       msg = cf_parse_u64(value, (u64 *) item->var);
+                       break;
                default:
                        msg = "Unknown keyword";
        }
@@ -305,9 +339,14 @@ int cf_getopt(int argc,char * const argv[],
                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;
@@ -336,7 +375,7 @@ int cf_getopt(int argc,char * const argv[],
                                msg=cf_set_item(sect,name,value);
                        }
                        if(msg)
-                               die("Invalid command line argument %s.%s=%s: %s",sect,name,value,msg);
+                               die("Invalid command line argument -S%s.%s=%s: %s",sect,name,value,msg);
 
                }else if(res=='C'){
                        cf_read(optarg);
@@ -344,6 +383,7 @@ int cf_getopt(int argc,char * const argv[],
                        /* unhandled option or end of options */
                        if(cfdeffile)
                                cf_read(cfdeffile);
+                       other_options++;
                        return res;
                }
        }while(1);