This patch provides a way to use the entire table of configuration options
as "long" command line switches.

Signed-off-by: Richard Cochran <richardcoch...@gmail.com>
---
 config.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 config.h | 11 +++++++++++
 ptp4l.c  | 11 +++++++++--
 3 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/config.c b/config.c
index 5da5ecc..384b437 100644
--- a/config.c
+++ b/config.c
@@ -329,6 +329,7 @@ static enum parser_result parse_section_line(char *s, enum 
config_section *secti
 }
 
 static enum parser_result parse_item(struct config *cfg,
+                                    int commandline,
                                     const char *section,
                                     const char *option,
                                     const char *value)
@@ -387,7 +388,7 @@ static enum parser_result parse_item(struct config *cfg,
                                return NOT_PARSED;
                        }
                }
-       } else if (cgi->flags & CFG_ITEM_LOCKED) {
+       } else if (!commandline && cgi->flags & CFG_ITEM_LOCKED) {
                /* This global option was set on the command line. */
                return PARSED_OK;
        } else {
@@ -415,6 +416,10 @@ static enum parser_result parse_item(struct config *cfg,
                dst->flags |= CFG_ITEM_DYNSTR;
                break;
        }
+
+       if (commandline) {
+               dst->flags &= CFG_ITEM_LOCKED;
+       }
        return PARSED_OK;
 }
 
@@ -490,6 +495,25 @@ static void check_deprecated_options(const char **option)
        }
 }
 
+static struct option *config_alloc_longopts(struct config *cfg)
+{
+       struct config_item *ci;
+       struct option *opts;
+       int i;
+
+       opts = calloc(1, (1 + N_CONFIG_ITEMS) * sizeof(*opts));
+       if (!opts) {
+               return NULL;
+       }
+       for (i = 0; i < N_CONFIG_ITEMS; i++) {
+               ci = &config_tab[i];
+               opts[i].name = ci->label;
+               opts[i].has_arg = required_argument;
+       }
+
+       return opts;
+}
+
 int config_read(char *name, struct config *cfg)
 {
        enum config_section current_section = UNKNOWN_SECTION;
@@ -554,7 +578,7 @@ int config_read(char *name, struct config *cfg)
 
                check_deprecated_options(&option);
 
-               parser_res = parse_item(cfg, current_section == GLOBAL_SECTION ?
+               parser_res = parse_item(cfg, 0, current_section == 
GLOBAL_SECTION ?
                                        NULL : current_port->name, option, 
value);
 
                switch (parser_res) {
@@ -627,8 +651,15 @@ struct config *config_create(void)
        }
        STAILQ_INIT(&cfg->interfaces);
 
+       cfg->opts = config_alloc_longopts(cfg);
+       if (!cfg->opts) {
+               free(cfg);
+               return NULL;
+       }
+
        cfg->htab = hash_create();
        if (!cfg->htab) {
+               free(cfg->opts);
                free(cfg);
                return NULL;
        }
@@ -657,6 +688,7 @@ struct config *config_create(void)
        return cfg;
 fail:
        hash_destroy(cfg->htab, NULL);
+       free(cfg->opts);
        free(cfg);
        return NULL;
 }
@@ -670,6 +702,7 @@ void config_destroy(struct config *cfg)
                free(iface);
        }
        hash_destroy(cfg->htab, config_item_free);
+       free(cfg->opts);
        free(cfg);
 }
 
@@ -720,6 +753,33 @@ char *config_get_string(struct config *cfg, const char 
*section,
        return ci->val.s;
 }
 
+int config_parse_option(struct config *cfg, const char *opt, const char *val)
+{
+       enum parser_result result;
+
+       result = parse_item(cfg, 1, NULL, opt, val);
+
+       switch (result) {
+       case PARSED_OK:
+               return 0;
+       case NOT_PARSED:
+               fprintf(stderr, "unknown option %s\n", opt);
+               break;
+       case BAD_VALUE:
+               fprintf(stderr, "%s is a bad value for option %s\n", val, opt);
+               break;
+       case MALFORMED:
+               fprintf(stderr, "%s is a malformed value for option %s\n",
+                       val, opt);
+               break;
+       case OUT_OF_RANGE:
+               fprintf(stderr, "%s is an out of range value for option %s\n",
+                       val, opt);
+               break;
+       }
+       return -1;
+}
+
 int config_set_double(struct config *cfg, const char *option, double val)
 {
        struct config_item *ci = config_find_item(cfg, NULL, option);
diff --git a/config.h b/config.h
index b02bde6..1cc7051 100644
--- a/config.h
+++ b/config.h
@@ -20,6 +20,7 @@
 #ifndef HAVE_CONFIG_H
 #define HAVE_CONFIG_H
 
+#include <getopt.h>
 #include <sys/queue.h>
 
 #include "ds.h"
@@ -43,6 +44,9 @@ struct config {
        STAILQ_HEAD(interfaces_head, interface) interfaces;
        int n_interfaces;
 
+       /* for parsing command line options */
+       struct option *opts;
+
        /* hash of all non-legacy items */
        struct hash *htab;
 };
@@ -64,6 +68,13 @@ int config_get_int(struct config *cfg, const char *section,
 char *config_get_string(struct config *cfg, const char *section,
                        const char *option);
 
+static inline struct option *config_long_options(struct config *cfg)
+{
+       return cfg->opts;
+}
+
+int config_parse_option(struct config *cfg, const char *opt, const char *val);
+
 int config_set_double(struct config *cfg, const char *option, double val);
 
 int config_set_section_int(struct config *cfg, const char *section,
diff --git a/ptp4l.c b/ptp4l.c
index a87e7e6..e90fcb2 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -73,8 +73,9 @@ static void usage(char *progname)
 int main(int argc, char *argv[])
 {
        char *config = NULL, *req_phc = NULL, *progname;
-       int c, err = -1, print_level;
+       int c, err = -1, index, print_level;
        struct clock *clock = NULL;
+       struct option *opts;
        struct config *cfg;
 
        if (handle_term_signals())
@@ -84,12 +85,18 @@ int main(int argc, char *argv[])
        if (!cfg) {
                return -1;
        }
+       opts = config_long_options(cfg);
 
        /* Process the command line arguments. */
        progname = strrchr(argv[0], '/');
        progname = progname ? 1+progname : argv[0];
-       while (EOF != (c = getopt(argc, argv, "AEP246HSLf:i:p:sl:mqvh"))) {
+       while (EOF != (c = getopt_long(argc, argv, "AEP246HSLf:i:p:sl:mqvh",
+                                      opts, &index))) {
                switch (c) {
+               case 0:
+                       if (config_parse_option(cfg, opts[index].name, optarg))
+                               goto out;
+                       break;
                case 'A':
                        if (config_set_int(cfg, "delay_mechanism", DM_AUTO))
                                goto out;
-- 
2.1.4


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today.http://sdm.link/xeonphi
_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to