-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathio.c
218 lines (186 loc) · 6.61 KB
/
io.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdnoreturn.h>
#include <string.h>
#include "io.h"
#include "lib.h"
static noreturn void display_help(const char *restrict fmt, ...) {
const int status = fmt == NULL ? EXIT_SUCCESS : EXIT_FAILURE;
const char *restrict help =
"SoS2MIPS - A Subscript of Shell to MIPS32 Assembly Compiler\n"
"version " __VERSION__ " by " __AUTHORS__ "\n"
"usage: sos2mips [options] -i <filename>\n"
"options:\n"
" -h, --help\t\tDisplay this help message and exit\n"
" -v, --version\t\tDisplay the version of this program and exit\n"
" -l, --license\t\tDisplay the license of this program and exit\n"
" -i, --in\t\tSpecify the input file\n"
" -o, --out\t\tSpecify the output file\n"
" .., --tos\t\tDisplay the Symbol Table on runtime\n"
" .., --verbose\t\tDisplay verbose information on runtime\n"
" .., --no-exe\t\tDo not execute output file\n"
" -O, --optlvl\t\tSet the optimization level\n"
"the input and output files can be non-option arguments\n"
"but are taken in order of appearance\n";
if (fmt != NULL) {
fprintf(stderr, FG_YEL " alert: " RST);
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n\n");
}
printf("%s", help);
exit(status);
}
static noreturn void display_version(void) {
printf("SoS2MIPS - A Subscript of Shell to MIPS32 Assembly Compiler\n"
"version " __VERSION__ " by " __AUTHORS__ "\n");
exit(EXIT_SUCCESS);
}
static noreturn void display_license(void) {
const char *restrict l =
"This project is licensed under the [GPL-3.0](LICENSE) license. "
"Please see the [license](LICENSE) file for more "
"details.\n\nRedistribution and use in source and binary forms, with "
"or without\nmodification, are permitted provided that the following "
"conditions are met:\n\n- Redistributions of source code must retain "
"the above copyright notice,\n this list of conditions and the "
"following disclaimer.\n\n- Redistributions in binary form must "
"reproduce the above copyright notice,\n this list of conditions "
"and the following disclaimer in the documentation\n and/or other "
"materials provided with the distribution.\n\n- Neither the name of "
"the SoS2MIPS authors nor the names of its\n contributors may be "
"used to endorse or promote products derived from\n this software "
"without specific prior written permission.\n\nTHIS SOFTWARE IS "
"PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""
"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED "
"TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A "
"PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT "
"HOLDER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, "
"INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES "
"(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR "
"SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) "
"HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER "
"IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR "
"OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, "
"EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n";
printf("%s", l);
exit(EXIT_SUCCESS);
}
void cmd_args_init(struct cmd_args *args) {
// struct _io *args = (struct _io *)malloc(sizeof(struct _io));
args->filename = NULL;
args->output = "a.s";
args->dispose_on_exit = true;
args->stdisplay = false;
args->verbose = false;
args->no_exe = false;
args->opt_lvl = 0;
// return args;
}
void parse_args(int argc, char *argv[], struct cmd_args *args) {
#define TOS_OPT 1000
#define VERB_OPT 2000
#define NOEXE_OPT 3000
static const struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
{"license", no_argument, NULL, 'l'},
{"in", required_argument, NULL, 'i'},
{"out", required_argument, NULL, 'o'},
{"tos", no_argument, NULL, TOS_OPT},
{"verbose", no_argument, NULL, VERB_OPT},
{"no-exe", no_argument, NULL, NOEXE_OPT},
{"optlvl", required_argument, NULL, 'O'},
{NULL, 0, NULL, 0},
};
static const char short_options[] = ":i:o:O:hvl";
extern int opterr;
opterr = 0;
int opt;
while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) !=
-1) {
switch (opt) {
case 'h':
display_help(NULL);
unreachable();
break;
case 'v':
display_version();
unreachable();
break;
case 'l':
display_license();
unreachable();
break;
case 'i':
args->filename = optarg;
break;
case 'o':
args->output = optarg;
args->dispose_on_exit = false;
break;
case TOS_OPT:
args->stdisplay = true;
break;
case VERB_OPT:
args->verbose = true;
break;
case NOEXE_OPT:
args->no_exe = true;
break;
case 'O':
args->opt_lvl = strtoi(optarg);
break;
case '?':
display_help("unrecognized option '%s'", argv[optind - 1]);
unreachable();
break;
case ':':
display_help("option '%s' requires an argument", argv[optind - 1]);
unreachable();
break;
default:
unreachable();
}
}
if (optind < argc) /* non-option arguments remain */ {
if (args->filename == NULL) {
args->filename = argv[optind];
optind++;
}
if (optind < argc) {
args->output = argv[optind];
args->dispose_on_exit = false;
optind++;
}
// check if there are more arguments
for (int i = optind; i < argc; i++) {
alert("ignoring extra argument: %s", argv[i]);
}
}
optind = 0;
}
void check_args(const struct cmd_args *args) {
if (args->filename == NULL) {
display_help("no input file specified");
}
if (args->opt_lvl < 0 || args->opt_lvl > 1) {
display_help("invalid optimization level");
}
if (args->no_exe && args->dispose_on_exit) {
display_help("can't run in no-exe mode without output file");
}
}
void print_args(const struct cmd_args *args) {
debug("filename: %s", args->filename);
debug("output: %s", args->output);
debug("dispose_on_exit: %s", args->dispose_on_exit ? "true" : "false");
debug("stdisplay: %s", args->stdisplay ? "true" : "false");
debug("verbose: %s", args->verbose ? "true" : "false");
debug("no_exe: %s", args->no_exe ? "true" : "false");
debug("opt_lvl: %d", args->opt_lvl);
}