Changeset 80d3b1b


Ignore:
Timestamp:
Jan 15, 2021, 12:23:18 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
bdbc24d
Parents:
325e6ea
Message:

Libcfa parseargs now supports arguments that don't have short options

Location:
libcfa/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/parseargs.cfa

    r325e6ea r80d3b1b  
    3030
    3131static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * usage, FILE * out)  __attribute__ ((noreturn));
    32 
     32//-----------------------------------------------------------------------------
     33// checking
     34static void check_args(cfa_option options[], size_t opt_count) {
     35        for(i; opt_count) {
     36                for(j; opt_count) {
     37                        if(i == j) continue;
     38
     39                        if( options[i].short_name != '\0'
     40                        && options[i].short_name == options[j].short_name)
     41                                abort("Parse Args error: two options have short name '%c' (%d & %d)", options[i].short_name, i, j);
     42
     43                        if(0 == strcmp(options[i].long_name, options[j].long_name)) abort("Parse Args error: two options have long name '%s' (%d & %d)", options[i].long_name, i, j);
     44                }
     45        }
     46}
     47
     48
     49//-----------------------------------------------------------------------------
     50// Parsing args
    3351void parse_args( cfa_option options[], size_t opt_count, const char * usage, char ** & left ) {
    3452        if( 0p != &cfa_args_argc ) {
     
    4159}
    4260
    43 //-----------------------------------------------------------------------------
    44 // getopt_long wrapping
    4561void parse_args(
    4662        int argc,
     
    5167        char ** & left
    5268) {
     69        check_args(options, opt_count);
     70
     71        int maxv = 'h';
     72        char optstring[opt_count * 3] = { '\0' };
     73        {
     74                int idx = 0;
     75                for(i; opt_count) {
     76                        if (options[i].short_name) {
     77                                maxv = max(options[i].short_name, maxv);
     78                                optstring[idx] = options[i].short_name;
     79                                idx++;
     80                                if(    ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue)
     81                                && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
     82                                        optstring[idx] = ':';
     83                                        idx++;
     84                                }
     85                        }
     86                }
     87                optstring[idx+0] = 'h';
     88                optstring[idx+1] = '\0';
     89        }
     90
    5391        struct option optarr[opt_count + 2];
    5492        {
     
    5694                for(i; opt_count) {
    5795                        if(options[i].long_name) {
     96                                options[i].val = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv;
    5897                                optarr[idx].name = options[i].long_name;
    5998                                optarr[idx].flag = 0p;
    60                                 optarr[idx].val  = options[i].short_name;
     99                                optarr[idx].val  = options[i].val;
    61100                                if(    ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue)
    62101                                    || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) {
     
    70109                optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h'];
    71110                optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0];
    72         }
    73 
    74         char optstring[opt_count * 3] = { '\0' };
    75         {
    76                 int idx = 0;
    77                 for(i; opt_count) {
    78                         optstring[idx] = options[i].short_name;
    79                         idx++;
    80                         if(    ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue)
    81                             && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
    82                                 optstring[idx] = ':';
    83                                 idx++;
    84                         }
    85                 }
    86                 optstring[idx+0] = 'h';
    87                 optstring[idx+1] = '\0';
    88111        }
    89112
     
    103126                        default:
    104127                                for(i; opt_count) {
    105                                         if(opt == options[i].short_name) {
     128                                        if(opt == options[i].val) {
    106129                                                const char * arg = optarg ? optarg : "";
    107130                                                if( arg[0] == '=' ) { arg++; }
  • libcfa/src/parseargs.hfa

    r325e6ea r80d3b1b  
    22
    33struct cfa_option {
     4      int val; // reserved
    45      char short_name;
    56      const char * long_name;
     
    1516forall(dtype T | { bool parse(const char *, T & ); })
    1617static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable ) {
     18      this.val        = 0;
    1719      this.short_name = short_name;
    1820      this.long_name  = long_name;
     
    2426forall(dtype T)
    2527static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable, bool (*parse)(const char *, T & )) {
     28      this.val        = 0;
    2629      this.short_name = short_name;
    2730      this.long_name  = long_name;
Note: See TracChangeset for help on using the changeset viewer.