source: benchmark/io/http/parseargs.cfa@ cf48a14

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since cf48a14 was 7f389a5c, checked in by Thierry Delisle <tdelisle@…>, 5 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.