* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "gmqcc.h"
#include "lexer.h"
-#include <time.h>
/* TODO: cleanup this whole file .. it's a fuckign mess */
static const char *app_name;
-static void version() {
- con_out("GMQCC %d.%d.%d Built %s %s\n",
+static void version(void) {
+ con_out("GMQCC %d.%d.%d Built %s %s\n" GMQCC_DEV_VERSION_STRING,
GMQCC_VERSION_MAJOR,
GMQCC_VERSION_MINOR,
GMQCC_VERSION_PATCH,
__DATE__,
__TIME__
);
-#ifdef GMQCC_GITINFO
- con_out("git build: %s\n", GMQCC_GITINFO);
-#elif defined(GMQCC_VERION_TYPE_DEVEL)
- con_out("development build\n");
-#endif
}
-static int usage() {
+static int usage(void) {
con_out("usage: %s [options] [files...]", app_name);
con_out("options:\n"
" -h, --help show this help message\n"
bool argend = false;
size_t itr;
char buffer[1024];
- char *redirout = NULL;
- char *redirerr = NULL;
- char *config = NULL;
+ char *redirout = NULL;
+ char *redirerr = NULL;
+ char *config = NULL;
+ char *memdumpcols = NULL;
while (!argend && argc > 1) {
char *argarg;
opts_set(opts.flags, ADJUST_VECTOR_FIELDS, true);
opts_set(opts.flags, CORRECT_LOGIC, true);
+ opts_set(opts.flags, SHORT_LOGIC, true);
+ opts_set(opts.flags, UNTYPED_NIL, true);
+ opts_set(opts.flags, VARIADIC_ARGS, true);
opts_set(opts.flags, FALSE_EMPTY_STRINGS, false);
opts_set(opts.flags, TRUE_EMPTY_STRINGS, true);
opts_set(opts.flags, LOOP_LABELS, true);
opts_set(opts.flags, INITIALIZED_NONCONSTANTS, true);
opts_set(opts.werror, WARN_INVALID_PARAMETER_COUNT, true);
opts_set(opts.werror, WARN_MISSING_RETURN_VALUES, true);
+ opts_set(opts.flags, EXPRESSIONS_FOR_BUILTINS, true);
+ opts_set(opts.warn, WARN_BREAKDEF, true);
+
OPTS_OPTION_U32(OPTION_STANDARD) = COMPILER_GMQCC;
opts_set(opts.flags, ASSIGN_FUNCTION_TYPES, true);
opts_set(opts.flags, CORRECT_TERNARY, false);
opts_set(opts.warn, WARN_TERNARY_PRECEDENCE, true);
+ opts_set(opts.warn, WARN_BREAKDEF, true);
OPTS_OPTION_U32(OPTION_STANDARD) = COMPILER_FTEQCC;
config = argarg;
continue;
}
+ if (options_long_gcc("memdumpcols", &argc, &argv, &memdumpcols)) {
+ OPTS_OPTION_U16(OPTION_MEMDUMPCOLS) = (uint16_t)strtol(memdumpcols, NULL, 10);
+ continue;
+ }
+ if (options_long_gcc("progsrc", &argc, &argv, &argarg)) {
+ OPTS_OPTION_STR(OPTION_PROGSRC) = argarg;
+ continue;
+ }
/* show defaults (like pathscale) */
if (!strcmp(argv[0]+1, "show-defaults")) {
else if (!strcmp(argv[0]+2, "NO_ERROR") ||
!strcmp(argv[0]+2, "NO_ERROR_ALL"))
{
- for (itr = 0; itr < sizeof(opts.werror)/sizeof(opts.werror[0]); ++itr)
+ for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.werror); ++itr)
opts.werror[itr] = 0;
break;
}
!strcmp(argv[0]+2, "ERROR_ALL"))
{
opts_backup_non_Werror_all();
- for (itr = 0; itr < sizeof(opts.werror)/sizeof(opts.werror[0]); ++itr)
+ for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.werror); ++itr)
opts.werror[itr] = 0xFFFFFFFFL;
opts_restore_non_Werror_all();
break;
}
else if (!strcmp(argv[0]+2, "NONE")) {
- for (itr = 0; itr < sizeof(opts.warn)/sizeof(opts.warn[0]); ++itr)
+ for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.warn); ++itr)
opts.warn[itr] = 0;
break;
}
else if (!strcmp(argv[0]+2, "ALL")) {
opts_backup_non_Wall();
- for (itr = 0; itr < sizeof(opts.warn)/sizeof(opts.warn[0]); ++itr)
+ for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.warn); ++itr)
opts.warn[itr] = 0xFFFFFFFFL;
opts_restore_non_Wall();
break;
con_out("option -O requires a numerical argument, or optimization name with an optional 'no-' prefix\n");
return false;
}
- if (isdigit(argarg[0])) {
+ if (util_isdigit(argarg[0])) {
uint32_t val = (uint32_t)strtol(argarg, NULL, 10);
OPTS_OPTION_U32(OPTION_O) = val;
opts_setoptimlevel(val);
else if (!strcmp(argarg, "ALL"))
opts_setoptimlevel(OPTS_OPTION_U32(OPTION_O) = 9999);
else if (!strncmp(argarg, "NO_", 3)) {
- if (!opts_setoptim(argarg+3, false)) {
+ /* constant folding cannot be turned off for obvious reasons */
+ if (!strcmp(argarg, "NO_CONST_FOLD") || !opts_setoptim(argarg+3, false)) {
con_out("unknown optimization: %s\n", argarg+3);
return false;
}
return false;
/* start at first non-blank */
- for (start = line; isspace(*start); ++start) {}
+ for (start = line; util_isspace(*start); ++start) {}
/* end at the first non-blank */
- for (end = start; *end && !isspace(*end); ++end) {}
+ for (end = start; *end && !util_isspace(*end); ++end) {}
*out = line;
/* move the actual filename to the beginning */
}
int main(int argc, char **argv) {
- size_t itr;
- int retval = 0;
- bool opts_output_free = false;
- bool operators_free = false;
- bool progs_src = false;
- FILE *outfile = NULL;
+ size_t itr;
+ int retval = 0;
+ bool opts_output_free = false;
+ bool operators_free = false;
+ bool progs_src = false;
+ FILE *outfile = NULL;
+ struct parser_s *parser = NULL;
+ struct ftepp_s *ftepp = NULL;
app_name = argv[0];
con_init ();
- opts_init("progs.dat", COMPILER_GMQCC, (1024 << 3));
+ opts_init("progs.dat", COMPILER_QCC, (1024 << 3));
util_seed(time(0));
/* the standard decides which set of operators to use */
if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_GMQCC) {
operators = c_operators;
- operator_count = c_operator_count;
+ operator_count = GMQCC_ARRAY_COUNT(c_operators);
} else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_FTEQCC) {
operators = fte_operators;
- operator_count = fte_operator_count;
+ operator_count = GMQCC_ARRAY_COUNT(fte_operators);
} else {
operators = qcc_operators;
- operator_count = qcc_operator_count;
+ operator_count = GMQCC_ARRAY_COUNT(qcc_operators);
}
if (operators == fte_operators) {
}
if (!OPTS_OPTION_BOOL(OPTION_PP_ONLY)) {
- if (!parser_init()) {
+ if (!(parser = parser_create())) {
con_err("failed to initialize parser\n");
retval = 1;
goto cleanup;
}
if (OPTS_OPTION_BOOL(OPTION_PP_ONLY) || OPTS_FLAG(FTEPP)) {
- if (!ftepp_init()) {
+ if (!(ftepp = ftepp_create())) {
con_err("failed to initialize parser\n");
retval = 1;
goto cleanup;
}
}
- if (OPTS_FLAG(TRUE_EMPTY_STRINGS))
- type_not_instr[TYPE_STRING] = INSTR_NOT_F;
-
- util_debug("COM", "starting ...\n");
-
/* add macros */
if (OPTS_OPTION_BOOL(OPTION_PP_ONLY) || OPTS_FLAG(FTEPP)) {
for (itr = 0; itr < vec_size(ppems); itr++) {
- ftepp_add_macro(ppems[itr].name, ppems[itr].value);
+ ftepp_add_macro(ftepp, ppems[itr].name, ppems[itr].value);
mem_d(ppems[itr].name);
/* can be null */
}
if (!vec_size(items)) {
- FILE *src;
- char *line;
+ FILE *src;
+ char *line = NULL;
size_t linelen = 0;
+ bool hasline = false;
progs_src = true;
- src = fs_file_open("progs.src", "rb");
+ src = fs_file_open(OPTS_OPTION_STR(OPTION_PROGSRC), "rb");
if (!src) {
- con_err("failed to open `progs.src` for reading\n");
+ con_err("failed to open `%s` for reading\n", OPTS_OPTION_STR(OPTION_PROGSRC));
retval = 1;
goto cleanup;
}
- line = NULL;
- if (!progs_nextline(&line, &linelen, src) || !line[0]) {
- con_err("illformatted progs.src file: expected output filename in first line\n");
- retval = 1;
- goto srcdone;
- }
-
- if (!opts_output_wasset) {
- OPTS_OPTION_STR(OPTION_OUTPUT) = util_strdup(line);
- opts_output_free = true;
- }
-
while (progs_nextline(&line, &linelen, src)) {
argitem item;
+
if (!line[0] || (line[0] == '/' && line[1] == '/'))
continue;
- item.filename = util_strdup(line);
- item.type = TYPE_QC;
- vec_push(items, item);
+
+ if (hasline) {
+ item.filename = util_strdup(line);
+ item.type = TYPE_QC;
+ vec_push(items, item);
+ } else if (!opts_output_wasset) {
+ OPTS_OPTION_STR(OPTION_OUTPUT) = util_strdup(line);
+ opts_output_free = true;
+ hasline = true;
+ }
}
-srcdone:
fs_file_close(src);
mem_d(line);
}
- if (retval)
- goto cleanup;
-
if (vec_size(items)) {
if (!OPTS_OPTION_BOOL(OPTION_QUIET) &&
!OPTS_OPTION_BOOL(OPTION_PP_ONLY))
con_out("Mode: %s\n", (progs_src ? "progs.src" : "manual"));
con_out("There are %lu items to compile:\n", (unsigned long)vec_size(items));
}
+
for (itr = 0; itr < vec_size(items); ++itr) {
if (!OPTS_OPTION_BOOL(OPTION_QUIET) &&
!OPTS_OPTION_BOOL(OPTION_PP_ONLY))
if (OPTS_OPTION_BOOL(OPTION_PP_ONLY)) {
const char *out;
- if (!ftepp_preprocess_file(items[itr].filename)) {
+ if (!ftepp_preprocess_file(ftepp, items[itr].filename)) {
retval = 1;
goto cleanup;
}
- out = ftepp_get();
+ out = ftepp_get(ftepp);
if (out)
fs_file_printf(outfile, "%s", out);
- ftepp_flush();
+ ftepp_flush(ftepp);
}
else {
if (OPTS_FLAG(FTEPP)) {
const char *data;
- if (!ftepp_preprocess_file(items[itr].filename)) {
+ if (!ftepp_preprocess_file(ftepp, items[itr].filename)) {
retval = 1;
goto cleanup;
}
- data = ftepp_get();
+ data = ftepp_get(ftepp);
if (vec_size(data)) {
- if (!parser_compile_string(items[itr].filename, data, vec_size(data))) {
+ if (!parser_compile_string(parser, items[itr].filename, data, vec_size(data))) {
retval = 1;
goto cleanup;
}
}
- ftepp_flush();
+ ftepp_flush(ftepp);
}
else {
- if (!parser_compile_file(items[itr].filename)) {
+ if (!parser_compile_file(parser, items[itr].filename)) {
retval = 1;
goto cleanup;
}
}
}
- ftepp_finish();
+ ftepp_finish(ftepp);
+ ftepp = NULL;
if (!OPTS_OPTION_BOOL(OPTION_PP_ONLY)) {
- if (!parser_finish(OPTS_OPTION_STR(OPTION_OUTPUT))) {
+ if (!parser_finish(parser, OPTS_OPTION_STR(OPTION_OUTPUT))) {
retval = 1;
goto cleanup;
}
}
}
- /* stuff */
- if (!OPTS_OPTION_BOOL(OPTION_QUIET) &&
- !OPTS_OPTION_BOOL(OPTION_PP_ONLY))
- {
- for (itr = 0; itr < COUNT_OPTIMIZATIONS; ++itr) {
- if (opts_optimizationcount[itr]) {
- con_out("%s: %u\n", opts_opt_list[itr].name, (unsigned int)opts_optimizationcount[itr]);
- }
- }
- }
-
cleanup:
- util_debug("COM", "cleaning ...\n");
- ftepp_finish();
+ if (ftepp)
+ ftepp_finish(ftepp);
con_close();
vec_free(items);
vec_free(ppems);
if (!OPTS_OPTION_BOOL(OPTION_PP_ONLY))
- parser_cleanup();
+ if(parser) parser_cleanup(parser);
if (opts_output_free)
mem_d(OPTS_OPTION_STR(OPTION_OUTPUT));
if (operators_free)
mem_d((void*)operators);
lex_cleanup();
- util_meminfo();
+ stat_info();
+
return retval;
}