Changeset d1abc63c


Ignore:
Timestamp:
Oct 19, 2022, 4:33:34 PM (22 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master
Children:
135143b
Parents:
72b5805e
Message:

Change parse args to use new arrays instead of C arrays.
Also added const ?? to arrays.

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/containers/array.hfa

    r72b5805e rd1abc63c  
    2727    // -  Given bug of Trac #247, CFA gives sizeof expressions type unsigned long int, when it
    2828    //    should give them type size_t.
    29     //   
     29    //
    3030    //                          gcc -m32         cfa -m32 given bug         gcc -m64
    3131    // ptrdiff_t                int              int                        long int
     
    3939    }
    4040
     41    static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, int i ) {
     42        assert( i < N );
     43        return (Timmed &) a.strides[i];
     44    }
     45
    4146    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, unsigned int i ) {
     47        assert( i < N );
     48        return (Timmed &) a.strides[i];
     49    }
     50
     51    static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, unsigned int i ) {
    4252        assert( i < N );
    4353        return (Timmed &) a.strides[i];
     
    4959    }
    5060
     61    static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, long int i ) {
     62        assert( i < N );
     63        return (Timmed &) a.strides[i];
     64    }
     65
    5166    static inline Timmed & ?[?]( arpk(N, S, Timmed, Tbase) & a, unsigned long int i ) {
     67        assert( i < N );
     68        return (Timmed &) a.strides[i];
     69    }
     70
     71    static inline const Timmed & ?[?]( const arpk(N, S, Timmed, Tbase) & a, unsigned long int i ) {
    5272        assert( i < N );
    5373        return (Timmed &) a.strides[i];
     
    83103    // Make a FOREACH macro
    84104    #define FE_0(WHAT)
    85     #define FE_1(WHAT, X) WHAT(X) 
     105    #define FE_1(WHAT, X) WHAT(X)
    86106    #define FE_2(WHAT, X, ...) WHAT(X)FE_1(WHAT, __VA_ARGS__)
    87107    #define FE_3(WHAT, X, ...) WHAT(X)FE_2(WHAT, __VA_ARGS__)
     
    90110    //... repeat as needed
    91111
    92     #define GET_MACRO(_0,_1,_2,_3,_4,_5,NAME,...) NAME 
     112    #define GET_MACRO(_0,_1,_2,_3,_4,_5,NAME,...) NAME
    93113    #define FOR_EACH(action,...) \
    94114    GET_MACRO(_0,__VA_ARGS__,FE_5,FE_4,FE_3,FE_2,FE_1,FE_0)(action,__VA_ARGS__)
     
    115135}
    116136
    117 #else 
     137#else
    118138
    119139// Workaround form.  Listing all possibilities up to 4 dims.
  • libcfa/src/parseargs.cfa

    r72b5805e rd1abc63c  
    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        }
  • libcfa/src/parseargs.hfa

    r72b5805e rd1abc63c  
    1616#pragma once
    1717
     18#include <array.hfa>
     19
    1820struct cfa_option {
    19       int val; // reserved
    20       char short_name;
    21       const char * long_name;
    22       const char * help;
    23       void * variable;
    24       bool (*parse)(const char *, void * );
     21        int val; // reserved
     22        char short_name;
     23        const char * long_name;
     24        const char * help;
     25        void * variable;
     26        bool (*parse)(const char *, void * );
    2527};
    2628
     
    3133forall(T & | { bool parse(const char *, T & ); })
    3234static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable ) {
    33       this.val        = 0;
    34       this.short_name = short_name;
    35       this.long_name  = long_name;
    36       this.help       = help;
    37       this.variable   = (void*)&variable;
    38       this.parse      = (bool (*)(const char *, void * ))parse;
     35        this.val        = 0;
     36        this.short_name = short_name;
     37        this.long_name  = long_name;
     38        this.help       = help;
     39        this.variable   = (void*)&variable;
     40        this.parse      = (bool (*)(const char *, void * ))parse;
    3941}
    4042
    4143forall(T &)
    4244static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable, bool (*parse)(const char *, T & )) {
    43       this.val        = 0;
    44       this.short_name = short_name;
    45       this.long_name  = long_name;
    46       this.help       = help;
    47       this.variable   = (void*)&variable;
    48       this.parse      = (bool (*)(const char *, void * ))parse;
     45        this.val        = 0;
     46        this.short_name = short_name;
     47        this.long_name  = long_name;
     48        this.help       = help;
     49        this.variable   = (void*)&variable;
     50        this.parse      = (bool (*)(const char *, void * ))parse;
    4951}
    5052
     
    5254void parse_args( int argc, char * argv[], cfa_option options[], size_t opt_count, const char * usage, char ** & left );
    5355
     56forall( [N] ) {
     57        void parse_args( const array( cfa_option, N ) & options, const char * usage, char ** & left );
     58        void parse_args( int argc, char * argv[], const array( cfa_option, N ) & options, const char * usage, char ** & left );
     59}
     60
    5461void print_args_usage(cfa_option options[], size_t opt_count, const char * usage, bool error)  __attribute__ ((noreturn));
    5562void print_args_usage(int argc, char * argv[], cfa_option options[], size_t opt_count, const char * usage, bool error)  __attribute__ ((noreturn));
     63
     64forall( [N] ) {
     65        void print_args_usage( const array(cfa_option, N ) & options, const char * usage, bool error)  __attribute__ ((noreturn));
     66        void print_args_usage(int argc, char * argv[], const array( cfa_option, N ) & options, const char * usage, bool error)  __attribute__ ((noreturn));
     67}
    5668
    5769bool parse_yesno    (const char *, bool & );
  • tests/configs/parsebools.cfa

    r72b5805e rd1abc63c  
    1515//
    1616
     17#include <fstream.hfa>
    1718#include <parseargs.hfa>
    18 #include <fstream.hfa>
    1919
    2020#include "../meta/fork+exec.hfa"
     
    3030        bool sf = true;
    3131
    32         cfa_option options[] = {
    33                 {'e', "yesno",     "test yes/no",     YN, parse_yesno},
    34                 {'y', "YN",        "test yes/no",     Yn, parse_yesno},
    35                 {'n', "yn",        "test yes/no",     yn, parse_yesno},
    36                 {'t', "truefalse", "test true/false", tf, parse_truefalse},
    37                 {'s', "settrue",   "test set true",   st, parse_settrue},
    38                 {'u', "setfalse",  "test set false",  sf, parse_setfalse},
    39         };
    40         int options_cnt = sizeof(options) / sizeof(cfa_option);
     32        array( cfa_option, 6 ) options;
     33        options[0] = (cfa_option){'e', "yesno",     "test yes/no",     YN, parse_yesno};
     34        options[1] = (cfa_option){'y', "YN",        "test yes/no",     Yn, parse_yesno};
     35        options[2] = (cfa_option){'n', "yn",        "test yes/no",     yn, parse_yesno};
     36        options[3] = (cfa_option){'t', "truefalse", "test true/false", tf, parse_truefalse};
     37        options[4] = (cfa_option){'s', "settrue",   "test set true",   st, parse_settrue};
     38        options[5] = (cfa_option){'u', "setfalse",  "test set false",  sf, parse_setfalse};
    4139
    4240        char **left;
    43         parse_args( options, options_cnt, "[OPTIONS]...\ntesting bool parameters", left);
     41        parse_args( options, "[OPTIONS]...\ntesting bool parameters", left);
    4442
    4543        sout | "yes/no     :" | YN;
  • tests/configs/parsenums.cfa

    r72b5805e rd1abc63c  
    1515//
    1616
     17#include <fstream.hfa>
    1718#include <parseargs.hfa>
    18 #include <fstream.hfa>
    1919
    2020#include "../meta/fork+exec.hfa"
     
    4242
    4343
    44         cfa_option options[] = {
    45                 { 'i', "int",              "test int",                i   },
    46                 { 'u', "unsigned",         "test unsigned",           u   },
    47                 { 'l', "unsignedlong",     "test unsigned long",      ul  },
    48                 { 'L', "unsignedlonglong", "test unsigned long long", ull },
    49                 { 'd', "double",           "test double",             d   },
    50         };
    51         int options_cnt = sizeof(options) / sizeof(cfa_option);
     44        array( cfa_option, 5 ) options;
     45        options[0] = (cfa_option){ 'i', "int",              "test int",                i   };
     46        options[1] = (cfa_option){ 'u', "unsigned",         "test unsigned",           u   };
     47        options[2] = (cfa_option){ 'l', "unsignedlong",     "test unsigned long",      ul  };
     48        options[3] = (cfa_option){ 'L', "unsignedlonglong", "test unsigned long long", ull };
     49        options[4] = (cfa_option){ 'd', "double",           "test double",             d   };
    5250
    5351        char **left;
    54         parse_args( options, options_cnt, "[OPTIONS]...\ntesting bool parameters", left);
     52        parse_args( options, "[OPTIONS]...\ntesting bool parameters", left);
    5553
    5654        sout | "int                :" | i;
  • tests/configs/usage.cfa

    r72b5805e rd1abc63c  
    1515//
    1616
     17#include <fstream.hfa>
    1718#include <parseargs.hfa>
    18 #include <fstream.hfa>
    1919
    2020#include "../meta/fork+exec.hfa"
     
    2525        sout | "No args, no errors";
    2626        if(pid_t child = strict_fork(); child == 0) {
    27                 cfa_option opts[0];
    28                 print_args_usage(1, fake_argv, opts, 0, "Test usage", false);
     27                array( cfa_option, 0 ) opts;
     28                print_args_usage(1, fake_argv, opts, "Test usage", false);
    2929        }
    3030        else {
     
    3535        sout | "No args, with errors";
    3636        if(pid_t child = strict_fork(); child == 0) {
    37                 cfa_option opts[0];
    38                 print_args_usage(1, fake_argv, opts, 0, "Test usage", true);
     37                array( cfa_option, 0 ) opts;
     38                print_args_usage(1, fake_argv, opts, "Test usage", true);
    3939        }
    4040        else {
     
    4646        if(pid_t child = strict_fork(); child == 0) {
    4747                int a, b, c;
    48                 cfa_option opts[] = {
    49                         {'a', "", "First arg", a },
    50                         {'b', "", "Second arg", b },
    51                         {'c', "", "Third arg", c },
    52                 };
    53                 print_args_usage(1, fake_argv, opts, 3, "Test usage", false);
     48                array( cfa_option, 3 ) opts;
     49                opts[0] = (cfa_option){'a', "", "First arg", a };
     50                opts[1] = (cfa_option){'b', "", "Second arg", b };
     51                opts[2] = (cfa_option){'c', "", "Third arg", c };
     52                print_args_usage(1, fake_argv, opts, "Test usage", false);
    5453        }
    5554        else {
     
    6160        if(pid_t child = strict_fork(); child == 0) {
    6261                int a, b, c;
    63                 cfa_option opts[] = {
    64                         {'\0', "AA", "First arg", a },
    65                         {'\0', "BB", "Second arg", b },
    66                         {'\0', "CC", "Third arg", c },
    67                 };
    68                 print_args_usage(1, fake_argv, opts, 3, "Test usage", false);
     62                array( cfa_option, 3 ) opts;
     63                opts[0] = (cfa_option){'\0', "AA", "First arg", a };
     64                opts[1] = (cfa_option){'\0', "BB", "Second arg", b };
     65                opts[2] = (cfa_option){'\0', "CC", "Third arg", c };
     66                print_args_usage(1, fake_argv, opts, "Test usage", false);
    6967        }
    7068        else {
     
    7674        if(pid_t child = strict_fork(); child == 0) {
    7775                int a, b, c;
    78                 cfa_option opts[] = {
    79                         {'a', "", "First arg", a },
    80                         {'b', "BBBB", "Second arg", b },
    81                         {'\0', "CC", "Third arg", c },
    82                 };
    83                 print_args_usage(1, fake_argv, opts, 3, "Test usage", false);
     76                array( cfa_option, 3 ) opts;
     77                opts[0] = (cfa_option){'a', "", "First arg", a };
     78                opts[1] = (cfa_option){'b', "BBBB", "Second arg", b };
     79                opts[2] = (cfa_option){'\0', "CC", "Third arg", c };
     80                print_args_usage(1, fake_argv, opts, "Test usage", false);
    8481        }
    8582        else {
     
    9188        if(pid_t child = strict_fork(); child == 0) {
    9289                int a, b, c;
    93                 cfa_option opts[] = {
    94                         {'a', "", "First arg", a },
    95                         {'b', "BBBB", "", b },
    96                         {'\0', "CC", "Third arg", c },
    97                 };
    98                 print_args_usage(1, fake_argv, opts, 3, "Test usage", false);
     90                array( cfa_option, 3 ) opts;
     91                opts[0] = (cfa_option){'a', "", "First arg", a };
     92                opts[1] = (cfa_option){'b', "BBBB", "", b };
     93                opts[2] = (cfa_option){'\0', "CC", "Third arg", c };
     94                print_args_usage(1, fake_argv, opts, "Test usage", false);
    9995        }
    10096        else {
     
    106102        if(pid_t child = strict_fork(); child == 0) {
    107103                int a, b, c;
    108                 cfa_option opts[] = {
    109                         {'a', "", "First arg\nThe description has multiple lines,\n...for some reason", a },
    110                         {'b', "BBBB", "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", b },
    111                         {'\0', "CC", "Third arg", c },
    112                 };
    113                 print_args_usage(1, fake_argv, opts, 3, "Test usage", false);
     104                array( cfa_option, 3 ) opts;
     105                opts[0] = (cfa_option){'a', "", "First arg\nThe description has multiple lines,\n...for some reason", a };
     106                opts[1] = (cfa_option){'b', "BBBB", "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", b };
     107                opts[2] = (cfa_option){'\0', "CC", "Third arg", c };
     108                print_args_usage(1, fake_argv, opts, "Test usage", false);
    114109        }
    115110        else {
Note: See TracChangeset for help on using the changeset viewer.