Ignore:
Timestamp:
Oct 28, 2022, 3:12:16 PM (3 years ago)
Author:
JiadaL <j82liang@…>
Branches:
ADT, ast-experimental, master
Children:
fa2e183
Parents:
e874605 (diff), 22a0e87 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/parseargs.cfa

    re874605 r93d2219  
    5050extern char ** cfa_args_envp __attribute__((weak));
    5151
    52 static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * usage, FILE * out)  __attribute__ ((noreturn));
     52forall([N])
     53static void usage(char * cmd, const array( cfa_option, N ) & options, const char * usage, FILE * out)  __attribute__ ((noreturn));
    5354//-----------------------------------------------------------------------------
    5455// checking
    55 static void check_args(cfa_option options[], size_t opt_count) {
    56         for(i; opt_count) {
    57                 for(j; opt_count) {
     56forall([N])
     57static void check_args( const array( cfa_option, N ) & options ) {
     58        for(i; N) {
     59                for(j; N) {
    5860                        if(i == j) continue;
    5961
     
    7072//-----------------------------------------------------------------------------
    7173// Parsing args
    72 void parse_args( cfa_option options[], size_t opt_count, const char * usage, char ** & left ) {
    73         if( 0p != &cfa_args_argc ) {
    74                 parse_args(cfa_args_argc, cfa_args_argv, options, opt_count, usage, left );
    75         }
    76         else {
    77                 char * temp = "";
    78                 parse_args(0, &temp, options, opt_count, usage, left );
    79         }
    80 }
    81 
    82 void parse_args(
    83         int argc,
    84         char * argv[],
    85         cfa_option options[],
    86         size_t opt_count,
    87         const char * usage,
    88         char ** & left
    89 ) {
    90         check_args(options, opt_count);
    91 
    92         int maxv = 'h';
    93         char optstring[(opt_count * 3) + 2] = { '\0' };
    94         {
    95                 int idx = 0;
    96                 for(i; opt_count) {
    97                         if (options[i].short_name) {
    98                                 maxv = max(options[i].short_name, maxv);
    99                                 optstring[idx] = options[i].short_name;
    100                                 idx++;
    101                                 if(    ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue)
    102                                 && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
    103                                         optstring[idx] = ':';
     74forall([opt_count]) {
     75        void parse_args( const array( cfa_option, opt_count ) & options, const char * usage, char ** & left ) {
     76                if( 0p != &cfa_args_argc ) {
     77                        parse_args(cfa_args_argc, cfa_args_argv, options, usage, left );
     78                }
     79                else {
     80                        char * temp = "";
     81                        parse_args(0, &temp, options, usage, left );
     82                }
     83        }
     84
     85        void parse_args(
     86                int argc,
     87                char * argv[],
     88                const array( cfa_option, opt_count ) & options,
     89                const char * usage,
     90                char ** & left
     91        ) {
     92                check_args(options);
     93
     94                int maxv = 'h';
     95                char optstring[(opt_count * 3) + 2] = { '\0' };
     96                {
     97                        int idx = 0;
     98                        for(i; opt_count) {
     99                                if (options[i].short_name) {
     100                                        maxv = max(options[i].short_name, maxv);
     101                                        optstring[idx] = options[i].short_name;
     102                                        idx++;
     103                                        if(    ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue)
     104                                        && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
     105                                                optstring[idx] = ':';
     106                                                idx++;
     107                                        }
     108                                }
     109                        }
     110                        optstring[idx+0] = 'h';
     111                        optstring[idx+1] = '\0';
     112                }
     113
     114                struct option optarr[opt_count + 2];
     115                {
     116                        int idx = 0;
     117                        for(i; opt_count) {
     118                                if(options[i].long_name) {
     119                                        // we don't have the mutable keyword here, which is really what we would want
     120                                        int & val_ref = (int &)(const int &)options[i].val;
     121                                        val_ref = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv;
     122
     123                                        optarr[idx].name = options[i].long_name;
     124                                        optarr[idx].flag = 0p;
     125                                        optarr[idx].val  = options[i].val;
     126                                        if(    ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue)
     127                                        || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) {
     128                                                optarr[idx].has_arg = no_argument;
     129                                        } else {
     130                                                optarr[idx].has_arg = required_argument;
     131                                        }
    104132                                        idx++;
    105133                                }
    106134                        }
    107                 }
    108                 optstring[idx+0] = 'h';
    109                 optstring[idx+1] = '\0';
    110         }
    111 
    112         struct option optarr[opt_count + 2];
    113         {
    114                 int idx = 0;
    115                 for(i; opt_count) {
    116                         if(options[i].long_name) {
    117                                 options[i].val = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv;
    118                                 optarr[idx].name = options[i].long_name;
    119                                 optarr[idx].flag = 0p;
    120                                 optarr[idx].val  = options[i].val;
    121                                 if(    ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue)
    122                                     || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) {
    123                                         optarr[idx].has_arg = no_argument;
    124                                 } else {
    125                                         optarr[idx].has_arg = required_argument;
    126                                 }
    127                                 idx++;
     135                        optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h'];
     136                        optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0];
     137                }
     138
     139                FILE * out = stderr;
     140                NEXT_ARG:
     141                for() {
     142                        int idx = 0;
     143                        int opt = getopt_long(argc, argv, optstring, optarr, &idx);
     144                        switch(opt) {
     145                                case -1:
     146                                        if(&left != 0p) left = argv + optind;
     147                                        return;
     148                                case 'h':
     149                                        out = stdout;
     150                                case '?':
     151                                        usage(argv[0], options, usage, out);
     152                                default:
     153                                        for(i; opt_count) {
     154                                                if(opt == options[i].val) {
     155                                                        const char * arg = optarg ? optarg : "";
     156                                                        if( arg[0] == '=' ) { arg++; }
     157                                                        // work around for some weird bug
     158                                                        void * variable = options[i].variable;
     159                                                        bool (*parse_func)(const char *, void * ) = options[i].parse;
     160                                                        bool success = parse_func( arg, variable );
     161                                                        if(success) continue NEXT_ARG;
     162
     163                                                        fprintf(out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt);
     164                                                        usage(argv[0], options, usage, out);
     165                                                }
     166                                        }
     167                                        abort("Internal parse arg error\n");
    128168                        }
    129                 }
    130                 optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h'];
    131                 optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0];
    132         }
    133 
    134         FILE * out = stderr;
    135         NEXT_ARG:
    136         for() {
    137                 int idx = 0;
    138                 int opt = getopt_long(argc, argv, optstring, optarr, &idx);
    139                 switch(opt) {
    140                         case -1:
    141                                 if(&left != 0p) left = argv + optind;
    142                                 return;
    143                         case 'h':
    144                                 out = stdout;
    145                         case '?':
    146                                 usage(argv[0], options, opt_count, usage, out);
    147                         default:
    148                                 for(i; opt_count) {
    149                                         if(opt == options[i].val) {
    150                                                 const char * arg = optarg ? optarg : "";
    151                                                 if( arg[0] == '=' ) { arg++; }
    152                                                 bool success = options[i].parse( arg, options[i].variable );
    153                                                 if(success) continue NEXT_ARG;
    154 
    155                                                 fprintf(out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt);
    156                                                 usage(argv[0], options, opt_count, usage, out);
    157                                         }
    158                                 }
    159                                 abort("Internal parse arg error\n");
    160                 }
    161 
     169
     170                }
    162171        }
    163172}
     
    222231
    223232void print_args_usage(cfa_option options[], size_t opt_count, const char * usage, bool error)  __attribute__ ((noreturn)) {
    224         usage(cfa_args_argv[0], options, opt_count, usage, error ? stderr : stdout);
     233        const array( cfa_option, opt_count ) & arr = (const array( cfa_option, opt_count ) &) *options;
     234        usage(cfa_args_argv[0], arr, usage, error ? stderr : stdout);
    225235}
    226236
    227237void print_args_usage(int , char * argv[], cfa_option options[], size_t opt_count, const char * usage, bool error)  __attribute__ ((noreturn)) {
    228         usage(argv[0], options, opt_count, usage, error ? stderr : stdout);
    229 }
    230 
    231 static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * help, FILE * out) __attribute__((noreturn)) {
     238        const array( cfa_option, opt_count ) & arr = (const array( cfa_option, opt_count ) &) *options;
     239        usage(argv[0], arr, usage, error ? stderr : stdout);
     240}
     241
     242forall( [N] ) {
     243        void print_args_usage( const array(cfa_option, N ) & options, const char * usage, bool error) {
     244                usage(cfa_args_argv[0], options, usage, error ? stderr : stdout);
     245        }
     246
     247        void print_args_usage(int argc, char * argv[], const array( cfa_option, N ) & options, const char * usage, bool error) {
     248                usage(argv[0], options, usage, error ? stderr : stdout);
     249        }
     250}
     251
     252forall([N])
     253static void usage(char * cmd, const array( cfa_option, N ) & options, const char * help, FILE * out) __attribute__((noreturn)) {
    232254        int width = 0;
    233255        {
    234                 for(i; opt_count) {
     256                for(i; N) {
    235257                        if(options[i].long_name) {
    236258                                int w = strlen(options[i].long_name);
     
    251273        fprintf(out, "Usage:\n  %s %s\n", cmd, help);
    252274
    253         for(i; opt_count) {
     275        for(i; N) {
    254276                printopt(out, width, max_width, options[i].short_name, options[i].long_name, options[i].help);
    255277        }
Note: See TracChangeset for help on using the changeset viewer.