1 /*
2  * This file is part of the Yices SMT Solver.
3  * Copyright (C) 2017 SRI International.
4  *
5  * Yices is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Yices is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Yices.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /*
20  * Test of the command line parser
21  */
22 
23 #include <stdio.h>
24 #include <stdbool.h>
25 #include <inttypes.h>
26 #include <assert.h>
27 
28 #include "utils/command_line.h"
29 
30 enum option_keys {
31   TEST1,
32   TEST2,
33   TEST3,
34   TEST4,
35   TEST5,
36   TEST6,
37 };
38 
39 static option_desc_t options[6] = {
40   { "flag", 't', FLAG_OPTION, TEST1 },
41   { "flag-trick", 'u', FLAG_OPTION, TEST2 },
42   { "int-required", 'i', MANDATORY_INT, TEST3 },
43   { "int-optional", 'j', OPTIONAL_INT, TEST4 },
44   { "string-required", 's', MANDATORY_STRING, TEST5 },
45   { "string-optional", 'w', OPTIONAL_STRING, TEST6 },
46 };
47 
48 
show_cmdline_details(cmdline_elem_t * e)49 static void show_cmdline_details(cmdline_elem_t *e) {
50   printf("  option given as %s\n", e->arg);
51   switch (e->format) {
52   case cmdline_short:
53     printf("  short name\n");
54     break;
55   case cmdline_long:
56     printf("  long name\n");
57     break;
58   case cmdline_long_val:
59     printf("  long name + value\n");
60     break;
61   default:
62     printf("   unknown format\n");
63     break;
64   }
65   if (e->s_value == NULL) {
66     printf("  no parameter\n");
67   } else {
68     printf("  parameter %s (i_value = %"PRId32")\n", e->s_value, e->i_value);
69   }
70 }
71 
show_cmdline_error(cmdline_elem_t * e)72 static void show_cmdline_error(cmdline_elem_t *e) {
73   switch (e->e_code) {
74   case cmdline_unknown_option:
75     printf("  unrecognized option %s\n", e->arg);
76     break;
77   case cmdline_noval_expected:
78     printf("  option %s requires no argument\n", e->arg);
79     break;
80   case cmdline_val_missing:
81     printf("  option %s requires an argument\n", e->arg);
82     break;
83   case cmdline_format:
84     printf("  invalid option %s\n", e->arg);
85     break;
86   case cmdline_int_format:
87     printf("  value %s is not an integer\n", e->s_value);
88     break;
89   case cmdline_int_overflow:
90     printf("  cannot deal with value %s: overflow\n", e->s_value);
91     break;
92   case cmdline_arg_missing:
93     printf("  -- must be followed by a parameter\n");
94     break;
95   default:
96     printf("  unknown error code\n");
97     break;
98   }
99 }
100 
show_cmdline_element(cmdline_elem_t * e,uint32_t i)101 static void show_cmdline_element(cmdline_elem_t *e, uint32_t i) {
102   int32_t k;
103 
104   printf("option[%"PRId32"]: ", i);
105   switch (e->status) {
106   case cmdline_done:
107     printf("end\n");
108     break;
109 
110   case cmdline_argument:
111     printf("string argument: %s\n", e->arg);
112     break;
113 
114   case cmdline_option:
115     k = e->key;
116     printf("option %s\n", options[k].name);
117     show_cmdline_details(e);
118     break;
119 
120   case cmdline_error:
121     printf("parse error\n");
122     show_cmdline_details(e);
123     show_cmdline_error(e);
124     break;
125 
126   default:
127     printf("invalid status\n");
128     break;
129   }
130 }
131 
132 
main(int argc,char * argv[])133 int main(int argc, char *argv[]) {
134   cmdline_parser_t parser;
135   cmdline_elem_t elem;
136   uint32_t i;
137 
138   init_cmdline_parser(&parser, options, 6, argv, argc);
139 
140   i = 0;
141   for (;;) {
142     elem.s_value = NULL;
143     cmdline_parse_element(&parser, &elem);
144     show_cmdline_element(&elem, i);
145     if (elem.status == cmdline_done) break;
146     if (elem.status == cmdline_error) {
147       cmdline_print_error(&parser, &elem);
148       break;
149     }
150     i ++;
151   }
152 
153   return 0;
154 }
155