-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.c
191 lines (167 loc) · 6.65 KB
/
main.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
/*
CSP-LINT - THE CSPYDR PROGRAMMING LANGUAGE LINTER
This is the main file and entry point to the linter.
This linter, the compiler and all components of CSpydr, except external dependencies (acutest, json-c), are licensed under the MIT license.
Creator:
https://github.com/spydr06
Official git repository:
https://github.com/spydr06/cspydr.git
*/
// std includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// compiler includes
#include <io/log.h>
#include <io/io.h>
#include <version.h>
#include <platform/platform_bindings.h>
// linter includes
#include "config.h"
#include "context.h"
#include "error/panic.h"
#include "linter.h"
#include "error.h"
#include "live.h"
#include "panic.h"
#define streq(a, b) (strcmp(a, b) == 0)
// default texts, which get shown if you enter help, info or version flags
#define CSPL_HELP_COMMAND "csp-lint --help"
const char usage_text[] = COLOR_BOLD_WHITE "Usage:" COLOR_RESET " csp-lint <input file> <flags>\n";
// this text gets shown if -i or --info is used
const char info_text[] = COLOR_BOLD_MAGENTA "** csp-lint - The CSpydr Programming Language Linter **\n" COLOR_RESET
COLOR_BOLD_WHITE "Version:" COLOR_RESET " %s\n"
COLOR_BOLD_WHITE "Build:" COLOR_RESET " %s\n"
"\n"
"Copyright (c) 2022 Spydr06\n"
"CSpydr is distributed under the MIT license.\n"
"This is free software; see the source for copying conditions;\n"
"you may redistribute it under the terms of the MIT license.\n"
"This program has absolutely no warranty.\n"
"\n"
#ifdef CSPYDR_SHOW_GIT_REPOSITORY
COLOR_BOLD_WHITE " repository: " COLOR_RESET CSPYDR_GIT_REPOSITORY "\n"
#endif
#ifdef CSPYDR_SHOW_GIT_DEVELOPER
COLOR_BOLD_WHITE " developer: " COLOR_RESET CSPYDR_GIT_DEVELOPER "\n"
#endif
#ifdef CSPYDR_SHOW_SUBREDDIT
COLOR_BOLD_WHITE " support & help: " COLOR_RESET CSPYDR_SUBREDDIT "\n"
#endif
"\n"
"Type -h or --help for the help page.\n";
const char help_text[] = "%s"
COLOR_BOLD_WHITE "Options:\n" COLOR_RESET
" -h, --help | Displays this help text and quits.\n"
" -i, --info | Displays information text and quits.\n"
" --version | Displays the version of CSpydr and quits.\n"
" -v, --verbose | Sets verbose error messages, used for programs.\n"
" | communicating with the linter.\n"
" -o, --output | Sets an output file for the error log.\n"
" -l, --live | Start a live session of the linter.\n"
" -p, --std-path <string> | Set the path of the standard library (default: " DEFAULT_STD_PATH ")"
" -y, --yes | Answer prompts with `yes` on default.\n";
// this text gets shown if -v or --version is used
const char version_text[] = COLOR_BOLD_MAGENTA "** csp-lint - The CSpydr Programming Language Linter **\n" COLOR_RESET
COLOR_BOLD_WHITE "Version:" COLOR_RESET " %s\n"
COLOR_BOLD_WHITE "Build:" COLOR_RESET " %s\n"
"\n"
"For more information type -i; for help type -h.\n";
i32 main(i32 argc, char* argv[])
{
if(argc == 1)
{
LOG_ERROR_F("[Error] Too few arguments given.\n" COLOR_RESET "%s", usage_text);
exit(1);
}
set_error_output_file(stderr);
Context_T context;
init_context(&context);
context.paths.exec_name = argv[0]; // save the execution name for later use
char* src_path = NULL;
char* std_path = DEFAULT_STD_PATH;
bool is_live = false,
default_yes = false;
for(i32 i = 1; i < argc; i++)
{
char* arg = argv[i];
if(streq(arg, "-h") || streq(arg, "--help"))
{
printf(help_text, usage_text);
exit(0);
}
else if(streq(arg, "--version"))
{
char buf[BUFSIZ] = {};
get_cspydr_build(buf);
printf(version_text, get_cspydr_version(), buf);
exit(0);
}
else if(streq(arg, "-i") || streq(arg, "--info"))
{
char buf[BUFSIZ] = {};
get_cspydr_build(buf);
printf(info_text, get_cspydr_version(), buf);
exit(0);
}
else if(streq(arg, "-v") || streq(arg, "--verbose"))
set_error_handler(linter_error_handler);
else if(streq(arg, "-o") || streq(arg, "--output"))
{
char* path = argv[++i];
if(!path)
{
LOG_ERROR_F("expect file name after `%s`\n", arg);
exit(1);
}
FILE* output_file = open_file(path);
set_error_output_file(output_file);
atexit(close_output_file);
set_error_handler(linter_error_handler); // switch to the linter error handler since text files don't support color
}
else if(streq(arg, "-l") || streq(arg, "--live"))
is_live = true;
else if(streq(arg, "-y") || streq(arg, "--yes"))
default_yes = true;
else if(streq(arg, "-p") || streq(arg, "--std-path"))
{
if(!argv[++i])
{
LOG_ERROR_F(COLOR_BOLD_RED "[Error]" COLOR_RESET COLOR_RED " expect STD path after %s.", arg);
exit(1);
}
std_path = get_absolute_path(argv[i]);
}
else if(arg[0] == '-')
{
LOG_ERROR_F("[Error] Invalid option `%s`\n", arg);
exit(1);
}
else
{
if(src_path)
{
LOG_ERROR("[Error] More than one file path given\n");
exit(1);
}
src_path = arg;
}
}
if(!src_path)
{
LOG_ERROR("[Error] No file path given\n");
exit(1);
}
set_panic_handler(linter_panic_handler);
if(is_live)
{
live_session(&context, src_path, std_path, !default_yes);
summary(&context);
}
else
{
i32 exit_code = lint(&context, src_path, std_path);
summary(&context);
return exit_code;
}
}