source: libcfa/src/parseargs.cfa @ cd02108

arm-ehenumforall-pointer-decayjacob/cs343-translationnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since cd02108 was cd02108, checked in by Thierry Delisle <tdelisle@…>, 2 years ago

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

  • Property mode set to 100644
File size: 5.0 KB
Line 
1#include "parseargs.hfa"
2
3#include <stdint.h>
4#include <string.h>
5#include <errno.h>
6#include <unistd.h>
7extern "C" {
8        #include <getopt.h>
9        #include <sys/ioctl.h>
10
11        struct FILE;
12        extern FILE * stderr;
13        extern FILE * stdout;
14
15        extern int fileno(FILE *stream);
16
17        extern int fprintf ( FILE * stream, const char * format, ... );
18
19        extern          long long int strtoll (const char* str, char** endptr, int base);
20        extern unsigned long long int strtoull(const char* str, char** endptr, int base);
21        extern                 double strtod  (const char* str, char** endptr);
22}
23
24#include "common.hfa"
25#include "limits.hfa"
26
27extern int cfa_args_argc;
28extern char ** cfa_args_argv;
29extern char ** cfa_args_envp;
30
31void printopt(FILE * out, int width, int max, char sn, const char * ln, const char * help) {
32        int hwidth = max - (11 + width);
33        if(hwidth <= 0) hwidth = max;
34
35        fprintf(out, "  -%c, --%-*s   %.*s\n", sn, width, ln, hwidth, help);
36        for() {
37                help += min(strlen(help), hwidth);
38                if('\0' == *help) break;
39                fprintf(out, "%*s%.*s\n", width + 11, "", hwidth, help);
40        }
41}
42
43void parse_args( cfa_option options[], size_t opt_count, const char * usage, char ** & left ) {
44        parse_args(cfa_args_argc, cfa_args_argv, options, opt_count, usage, left );
45}
46
47void parse_args(
48        int argc,
49        char * argv[],
50        cfa_option options[],
51        size_t opt_count,
52        const char * usage,
53        char ** & left
54) {
55        struct option optarr[opt_count + 2];
56        int width = 0;
57        int max_width = 1_000_000;
58        {
59                int idx = 0;
60                for(i; opt_count) {
61                        if(options[i].long_name) {
62                                optarr[idx].name = options[i].long_name;
63                                optarr[idx].flag = 0p;
64                                optarr[idx].val  = options[i].short_name;
65                                if(    ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue)
66                                    || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) {
67                                        optarr[idx].has_arg = no_argument;
68                                } else {
69                                        optarr[idx].has_arg = required_argument;
70                                }
71                                idx++;
72
73                                int w = strlen(options[i].long_name);
74                                if(w > width) width = w;
75                        }
76                }
77                optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h'];
78                optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0];
79        }
80
81        char optstring[opt_count * 3] = { '\0' };
82        {
83                int idx = 0;
84                for(i; opt_count) {
85                        optstring[idx] = options[i].short_name;
86                        idx++;
87                        if(    ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue)
88                            && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
89                                optstring[idx] = ':';
90                                idx++;
91                        }
92                }
93                optstring[idx+0] = 'h';
94                optstring[idx+1] = '\0';
95        }
96
97        FILE * out = stderr;
98        NEXT_ARG:
99        for() {
100                int idx = 0;
101                int opt = getopt_long(argc, argv, optstring, optarr, &idx);
102                switch(opt) {
103                        case -1:
104                                if(&left != 0p) left = argv + optind;
105                                return;
106                        case 'h':
107                                out = stdout;
108                        case '?':
109                                goto USAGE;
110                        default:
111                                for(i; opt_count) {
112                                        if(opt == options[i].short_name) {
113                                                const char * arg = optarg ? optarg : "";
114                                                bool success = options[i].parse( arg, options[i].variable );
115                                                if(success) continue NEXT_ARG;
116
117                                                fprintf(out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt);
118                                                goto USAGE;
119                                        }
120                                }
121                                abort("Internal parse arg error\n");
122                }
123
124        }
125
126        USAGE:;
127        int outfd = fileno(out);
128        if(isatty(outfd)) {
129                struct winsize size;
130                int ret = ioctl(outfd, TIOCGWINSZ, &size);
131                if(ret < 0) abort( "ioctl error: (%d) %s\n", (int)errno, strerror(errno) );
132                max_width = size.ws_col;
133        }
134
135        fprintf(out, "Usage:\n  %s %s\n", argv[0], usage);
136
137        for(i; opt_count) {
138                printopt(out, width, max_width, options[i].short_name, options[i].long_name, options[i].help);
139        }
140        fprintf(out, "  -%c, --%-*s   %s\n", 'h', width, "help", "print this help message");
141        exit(out == stdout ? 0 : 1);
142}
143
144bool parse_yesno(const char * arg, bool & value ) {
145        if(strcmp(arg, "yes") == 0) {
146                value = true;
147                return true;
148        }
149
150        if(strcmp(arg, "no") == 0) {
151                value = false;
152                return true;
153        }
154
155        return false;
156}
157
158bool parse_settrue (const char *, bool & value ) {
159        value = true;
160        return true;
161}
162
163bool parse_setfalse(const char *, bool & value )  {
164        value = false;
165        return true;
166}
167
168bool parse(const char * arg, const char * & value ) {
169        value = arg;
170        return true;
171}
172
173bool parse(const char * arg, int & value) {
174        char * end;
175        int r = strtoll(arg, &end, 10);
176        if(*end != '\0') return false;
177
178        value = r;
179        return true;
180}
181
182bool parse(const char * arg, unsigned & value) {
183        char * end;
184        unsigned long long int r = strtoull(arg, &end, 10);
185        if(*end != '\0') return false;
186        if(r > (unsigned)MAX) return false;
187
188        value = r;
189        return true;
190}
191
192bool parse(const char * arg, unsigned long & value) {
193        char * end;
194        unsigned long long int r = strtoull(arg, &end, 10);
195        if(*end != '\0') return false;
196        if(r > (unsigned long)MAX) return false;
197
198        value = r;
199        return true;
200}
201
202bool parse(const char * arg, unsigned long long & value) {
203        char * end;
204        unsigned long long int r = strtoull(arg, &end, 10);
205        if(*end != '\0') return false;
206        if(r > (unsigned long long)MAX) return false;
207
208        value = r;
209        return true;
210}
211
212bool parse(const char * arg, double & value) {
213        char * end;
214        double r = strtod(arg, &end);
215        if(*end != '\0') return false;
216
217        value = r;
218        return true;
219}
Note: See TracBrowser for help on using the repository browser.