add support for long options

Incorporating existing tests (like pthread_cond_many) may require support
for long options if the existing arguments are to remain supported.  This
patch adds support for long options, while keeping the default of only
short options in place.  long opts MUST have an equivalent short opt so
as to not require changing (and complicating) the parse_arg signature.
This patch tests for this in the rt_init routine.

Signed-off-by: Darren Hart <[email protected]>
Acked-by: Vernon Mauery <[email protected]>

---
 include/librttest.h |   12 ++++++++++--
 lib/librttest.c     |   49 +++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 55 insertions(+), 6 deletions(-)

Index: realtime/include/librttest.h
===================================================================
--- realtime.orig/include/librttest.h
+++ realtime/include/librttest.h
@@ -235,10 +235,12 @@ static volatile int _debug_count = 0;
 /* rt_help: print help for standard args */
 void rt_help();
 
-/* rt_init: initialize librttest
+/* rt_init_long: initialize librttest
  * options: pass in an getopt style string of options -- e.g. "ab:cd::e:"
  *          if this or parse_arg is null, no option parsing will be done
  *          on behalf of the calling program (only internal args will be 
parsed)
+ * longopts: a pointer to the first element of an array of struct option, the
+ *           last entry must be set to all zeros.
  * parse_arg: a function that will get called when one of the above
  *            options is encountered on the command line.  It will be passed
  *            the option -- e.g. 'b' -- and the value.  Something like:
@@ -267,7 +269,13 @@ void rt_help();
  * argc: passed from main
  * argv: passed from main
  */
-int rt_init(const char *options, int (*parse_arg)(int option, char *value), 
int argc, char *argv[]);
+int rt_init_long(const char *options, const struct option *longopts,
+                int (*parse_arg)(int option, char *value),
+                int argc, char *argv[]);
+
+/* rt_init: same as rt_init_long with no long options */
+int rt_init(const char *options, int (*parse_arg)(int option, char *value),
+           int argc, char *argv[]);
 
 int create_thread(void*(*func)(void*), void *arg, int prio, int policy);
 
Index: realtime/lib/librttest.c
===================================================================
--- realtime.orig/lib/librttest.c
+++ realtime/lib/librttest.c
@@ -99,9 +99,13 @@ void calibrate_busyloop(void)
        iters_per_us = (CALIBRATE_LOOPS * NS_PER_US) / (end-start);
 }
 
-int rt_init(const char *options, int (*parse_arg)(int option, char *value), 
int argc, char *argv[])
+int rt_init_long(const char *options, const struct option *longopts,
+                int (*parse_arg)(int option, char *value), int argc,
+                char *argv[])
 {
+       const struct option *cur_opt;
        int use_buffer = 1;
+       char *longopt_vals;
        size_t i;
        int c;
        opterr = 0;
@@ -126,8 +130,33 @@ int rt_init(const char *options, int (*p
                        exit(1);
                }
        }
+
+       /* Ensure each long options has a known unique short option in val. */
+       longopt_vals = "";
+       cur_opt = longopts;
+       while (cur_opt && cur_opt->name) {
+               if (cur_opt->flag) {
+                       fprintf(stderr, "Programmer error -- argument --%s flag"
+                               " is non-null\n", cur_opt->name);
+                       exit(1);
+               }
+               if (!strchr(all_options, cur_opt->val)) {
+                       fprintf(stderr, "Progreammer error -- argument --%s "
+                               "shortopt -%c wasn't listed in options (%s)\n",
+                               cur_opt->name, cur_opt->val, all_options);
+                       exit(1);
+               }
+               if (strchr(longopt_vals, cur_opt->val)) {
+                       fprintf(stderr, "Programmer error -- argument --%s "
+                               "shortopt -%c is used more than once\n",
+                               cur_opt->name, cur_opt->val);
+                       exit(1);
+               }
+               asprintf(&longopt_vals, "%s%c", longopt_vals, cur_opt->val);
+               cur_opt++;
+       }
        
-       while ((c = getopt(argc, argv, all_options)) != -1) {
+       while ((c = getopt_long(argc, argv, all_options, longopts, NULL)) != 
-1) {
                switch (c) {
                case 'c':
                        pass_criteria = atof(optarg);
@@ -148,11 +177,17 @@ int rt_init(const char *options, int (*p
                        save_stats = 1;
                        break;
                case ':':
-                       fprintf(stderr, "option -%c: missing arg\n", optopt);
+                       if (optopt == '-')
+                               fprintf(stderr, "long option missing arg\n");
+                       else
+                               fprintf(stderr, "option -%c: missing arg\n", 
optopt);
                        parse_arg('h', optarg); /* Just to display usage */
                        exit (1); /* Just in case. (should normally be done by 
usage()) */
                case '?':
-                       fprintf(stderr, "option -%c not recognized\n", optopt);
+                       if (optopt == '-')
+                               fprintf(stderr, "unrecognized long option\n");
+                       else
+                               fprintf(stderr, "option -%c not recognized\n", 
optopt);
                        parse_arg('h', optarg); /* Just to display usage */
                        exit (1); /* Just in case. (should normally be done by 
usage()) */
                default:
@@ -185,6 +220,12 @@ int rt_init(const char *options, int (*p
        return 0;
 }
 
+int rt_init(const char *options, int (*parse_arg)(int option, char *value),
+           int argc, char *argv[])
+{
+       return rt_init_long(options, NULL, parse_arg, argc, argv);
+}
+
 void buffer_init(void)
 {
        _print_buffer = (char *)malloc(PRINT_BUFFER_SIZE);
-- 
Darren Hart
IBM Linux Technology Center
Real-Time Linux Team

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to