source: benchmark/io/http/parseargs.cfa @ 463cb33

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 463cb33 was 7f389a5c, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Added support for argument parsing.
Removed unnecessary headers.
Fixed magic number in splice.

  • Property mode set to 100644
File size: 3.1 KB
Line 
1#include "parseargs.hfa"
2
3// #include <stdio.h>
4// #include <stdlib.h>
5#include <string.h>
6extern "C" {
7        #include <getopt.h>
8
9        struct FILE;
10        extern FILE * stderr;
11        extern FILE * stdout;
12
13        extern int fprintf ( FILE * stream, const char * format, ... );
14        extern long long int strtoll (const char* str, char** endptr, int base);
15}
16
17void parse_args(
18        int argc,
19        char * argv[],
20        cfa_option options[],
21        size_t opt_count,
22        const char * usage,
23        char ** & left
24) {
25        struct option optarr[opt_count + 2];
26        int width = 0;
27        {
28                int idx = 0;
29                for(i; opt_count) {
30                        if(options[i].long_name) {
31                                optarr[idx].name = options[i].long_name;
32                                optarr[idx].flag = 0p;
33                                optarr[idx].val  = options[i].short_name;
34                                if(    ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue)
35                                    || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) {
36                                        optarr[idx].has_arg = no_argument;
37                                } else {
38                                        optarr[idx].has_arg = required_argument;
39                                }
40                                idx++;
41
42                                int w = strlen(options[i].long_name);
43                                if(w > width) width = w;
44                        }
45                }
46                optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0p, 'h'];
47                optarr[idx+1].[name, has_arg, flag, val] = [0p, no_argument, 0p, 0];
48        }
49
50        char optstring[opt_count * 3] = { '\0' };
51        {
52                int idx = 0;
53                for(i; opt_count) {
54                        optstring[idx] = options[i].short_name;
55                        idx++;
56                        if(    ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue)
57                            && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
58                                optstring[idx] = ':';
59                                idx++;
60                        }
61                }
62                optstring[idx+0] = 'h';
63                optstring[idx+1] = '\0';
64        }
65
66        FILE * out = stderr;
67        NEXT_ARG:
68        for() {
69                int idx = 0;
70                int opt = getopt_long(argc, argv, optstring, optarr, &idx);
71                switch(opt) {
72                        case -1:
73                                if(&left != 0p) left = argv + optind;
74                                return;
75                        case 'h':
76                                out = stdout;
77                        case '?':
78                                goto USAGE;
79                        default:
80                                for(i; opt_count) {
81                                        if(opt == options[i].short_name) {
82                                                const char * arg = optarg ? optarg : "";
83                                                bool success = options[i].parse( arg, options[i].variable );
84                                                if(success) continue NEXT_ARG;
85
86                                                fprintf(out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt);
87                                                goto USAGE;
88                                        }
89                                }
90                                abort("Internal parse arg error\n");
91                }
92
93        }
94
95        USAGE:
96        fprintf(out, "%s\n", usage);
97
98        for(i; opt_count) {
99                fprintf(out, "  -%c, --%-*s   %s\n", options[i].short_name, width, options[i].long_name, options[i].help);
100        }
101        fprintf(out, "  -%c, --%-*s   %s\n", 'h', width, "help", "print this help message");
102        exit(out == stdout ? 0 : 1);
103}
104
105bool parse_yesno(const char * arg, bool & value ) {
106        if(strcmp(arg, "yes") == 0) {
107                value = true;
108                return true;
109        }
110
111        if(strcmp(arg, "no") == 0) {
112                value = false;
113                return true;
114        }
115
116        return false;
117}
118
119bool parse_settrue (const char *, bool & value ) {
120        value = true;
121        return true;
122}
123
124bool parse_setfalse(const char *, bool & value )  {
125        value = false;
126        return true;
127}
128
129bool parse(const char * arg, const char * & value ) {
130        value = arg;
131        return true;
132}
133
134bool parse(const char * arg, int & value) {
135        char * end;
136        int r = strtoll(arg, &end, 10);
137        if(*end != '\0') return false;
138
139        value = r;
140        return true;
141}
Note: See TracBrowser for help on using the repository browser.