# HG changeset patch # User David A. Holland # Date 1292799179 18000 # Node ID ee9a66b87c7055bfe1adc23e110cd748d7c5710a # Parent bfa97d43197e23801b5818a5f1b25e94405eda27 Initial version of toplevel and options handling. diff -r bfa97d43197e -r ee9a66b87c70 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Sun Dec 19 17:52:59 2010 -0500 @@ -0,0 +1,7 @@ +# $NetBSD$ + +PROG= tradcpp +SRCS= main.c array.c utils.c +WARNS= 5 + +.include diff -r bfa97d43197e -r ee9a66b87c70 config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config.h Sun Dec 19 17:52:59 2010 -0500 @@ -0,0 +1,14 @@ +#define CONFIG_LOCALINCLUDE "/usr/local/include" +#define CONFIG_SYSTEMINCLUDE "/usr/include" + +#define CONFIG_OS "__NetBSD__" +#define CONFIG_OS_2 "__unix__" + +#define CONFIG_CPU "__x86_64__" +#define CONFIG_CPU_2 "__amd64__" + +#define CONFIG_SIZE "__LP64__" +#define CONFIG_BINFMT "__ELF__" + +#define CONFIG_COMPILER "__NBCC__" +#define CONFIG_COMPILER_MINOR "__NBCC_MINOR__" diff -r bfa97d43197e -r ee9a66b87c70 files.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files.h Sun Dec 19 17:52:59 2010 -0500 @@ -0,0 +1,6 @@ +struct place; + +void files_addquotepath(const char *dir, bool issystem); +void files_addbracketpath(const char *dir, bool issystem); + +void files_read(struct place *, const char *name); diff -r bfa97d43197e -r ee9a66b87c70 macro.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/macro.h Sun Dec 19 17:52:59 2010 -0500 @@ -0,0 +1,4 @@ +struct place; + +void macro_define(struct place *, const char *macro, const char *expansion); +void macro_undef(const char *macro); diff -r bfa97d43197e -r ee9a66b87c70 main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.c Sun Dec 19 17:52:59 2010 -0500 @@ -0,0 +1,914 @@ +#include +#include +#include +#include +#include +#include + +#include "inlinedefs.h" // XXX +#include "version.h" +#include "config.h" +#include "utils.h" +#include "array.h" +#include "mode.h" +#include "files.h" +#include "macro.h" + +struct mode mode = { + .werror = false, + + .input_allow_dollars = false, + .input_tabstop = 8, + + .do_stdinc = true, + .do_stddef = true, + + .do_output = true, + .output_linenumbers = true, + .output_retain_comments = false, + .output_file = NULL, + + .do_depend = false, + .depend_report_system = false, + .depend_assume_generated = false, + .depend_issue_fakerules = false, + .depend_quote_target = true, + .depend_target = NULL, + .depend_file = NULL, + + .do_macrolist = false, + .macrolist_include_stddef = false, + .macrolist_include_expansions = false, + + .do_trace = false, + .trace_namesonly = false, + .trace_indented = false, +}; + +struct warns warns = { + .endiflabels = true, + .nestcomment = false, + .undef = false, + .unused = false, +}; + +//////////////////////////////////////////////////////////// +// commandline macros + +struct commandline_macro { + const char *macro; + const char *expansion; +}; + +static struct array commandline_macros; + +static +void +commandline_macros_init(void) +{ + array_init(&commandline_macros); +} + +static +void +commandline_macros_cleanup(void) +{ + array_cleanup(&commandline_macros); +} + +static +void +commandline_macro_add(const char *macro, const char *expansion) +{ + struct commandline_macro *cm; + + cm = domalloc(sizeof(*cm)); + cm->macro = macro; + cm->expansion = expansion; +} + +static +void +commandline_def(char *str) +{ + char *val; + + val = strchr(str, '='); + if (val != NULL) { + *val = '\0'; + val++; + } + commandline_macro_add(str, val ? val : "1"); +} + +static +void +commandline_undef(char *str) +{ + commandline_macro_add(str, NULL); +} + +static +void +apply_commandline_macros(void) +{ + struct commandline_macro *cm; + unsigned i, num; + + num = array_num(&commandline_macros); + for (i=0; iexpansion != NULL) { + macro_define(NULL, cm->macro, cm->expansion); + } else { + macro_undef(cm->macro); + } + free(cm); + } + array_setsize(&commandline_macros, 0); +} + +static +void +apply_builtin_macro(const char *name, const char *val) +{ + /* XXX distinguish builtin-place and commandline-place and nowhere */ + macro_define(NULL, name, val); +} + +static +void +apply_builtin_macros(void) +{ +#ifdef CONFIG_OS + apply_builtin_macro(CONFIG_OS, "1"); +#endif +#ifdef CONFIG_OS_2 + apply_builtin_macro(CONFIG_OS_2, "1"); +#endif + +#ifdef CONFIG_CPU + apply_builtin_macro(CONFIG_CPU, "1"); +#endif +#ifdef CONFIG_CPU_2 + apply_builtin_macro(CONFIG_CPU_2, "1"); +#endif + +#ifdef CONFIG_SIZE + apply_builtin_macro(CONFIG_SIZE, "1"); +#endif +#ifdef CONFIG_BINFMT + apply_builtin_macro(CONFIG_BINFMT, "1"); +#endif + +#ifdef CONFIG_COMPILER + apply_builtin_macro(CONFIG_COMPILER, VERSION_MAJOR); + apply_builtin_macro(CONFIG_COMPILER_MINOR, VERSION_MINOR); + apply_builtin_macro("__VERSION__", VERSION_LONG); +#endif +} + +//////////////////////////////////////////////////////////// +// extra included files + +struct commandline_file { + char *name; + bool suppress_output; +}; + +static struct array commandline_files; + +static +void +commandline_files_init(void) +{ + array_init(&commandline_files); +} + +static +void +commandline_files_cleanup(void) +{ + array_cleanup(&commandline_files); +} + +static +void +commandline_addfile(char *name, bool suppress_output) +{ + struct commandline_file *cf; + + cf = domalloc(sizeof(*cf)); + cf->name = name; + cf->suppress_output = suppress_output; + array_add(&commandline_files, cf, NULL); +} + +static +void +commandline_addfile_output(char *name) +{ + commandline_addfile(name, false); +} + +static +void +commandline_addfile_nooutput(char *name) +{ + commandline_addfile(name, true); +} + +static +void +read_commandline_files(void) +{ + struct commandline_file *cf; + unsigned i, num; + bool save = false; + + num = array_num(&commandline_files); + for (i=0; isuppress_output) { + save = mode.do_output; + mode.do_output = false; + files_read(NULL, cf->name); + mode.do_output = save; + } else { + files_read(NULL, cf->name); + } + } +} + +//////////////////////////////////////////////////////////// +// include path accumulation + +static struct stringarray incpath_quote; +static struct stringarray incpath_user; +static struct stringarray incpath_system; +static struct stringarray incpath_late; +static const char *sysroot; + +static +void +incpath_init(void) +{ + stringarray_init(&incpath_quote); + stringarray_init(&incpath_user); + stringarray_init(&incpath_system); + stringarray_init(&incpath_late); +} + +static +void +incpath_cleanup(void) +{ + stringarray_cleanup(&incpath_quote); + stringarray_cleanup(&incpath_user); + stringarray_cleanup(&incpath_system); + stringarray_cleanup(&incpath_late); +} + +static +void +commandline_isysroot(char *dir) +{ + sysroot = dir; +} + +static +void +commandline_addincpath(struct stringarray *arr, char *s) +{ + stringarray_add(arr, s, NULL); +} + +static +void +commandline_addincpath_quote(char *dir) +{ + commandline_addincpath(&incpath_quote, dir); +} + +static +void +commandline_addincpath_user(char *dir) +{ + commandline_addincpath(&incpath_user, dir); +} + +static +void +commandline_addincpath_system(char *dir) +{ + commandline_addincpath(&incpath_system, dir); +} + +static +void +commandline_addincpath_late(char *dir) +{ + commandline_addincpath(&incpath_late, dir); +} + +static +void +loadincludepath(void) +{ + unsigned i, num; + const char *dir; + char *t; + + num = stringarray_num(&incpath_quote); + for (i=0; i 64) { + warnx("Preposterously large tabstop"); + die(); + } + mode.input_tabstop = val; +} + +/* + * macrolist + */ + +static +void +commandline_dD(void) +{ + mode.do_macrolist = true; + mode.macrolist_include_stddef = false; + mode.macrolist_include_expansions = true; +} + +static +void +commandline_dM(void) +{ + mode.do_macrolist = true; + mode.macrolist_include_stddef = true; + mode.macrolist_include_expansions = true; + mode.do_output = false; +} + +static +void +commandline_dN(void) +{ + mode.do_macrolist = true; + mode.macrolist_include_stddef = false; + mode.macrolist_include_expansions = false; +} + +/* + * include trace + */ + +static +void +commandline_dI(void) +{ + mode.do_trace = true; + mode.trace_namesonly = false; + mode.trace_indented = false; +} + +static +void +commandline_H(void) +{ + mode.do_trace = true; + mode.trace_namesonly = true; + mode.trace_indented = true; +} + +/* + * depend + */ + +static +void +commandline_setdependtarget(char *str) +{ + mode.depend_target = str; + mode.depend_quote_target = false; +} + +static +void +commandline_setdependtarget_quoted(char *str) +{ + mode.depend_target = str; + mode.depend_quote_target = true; +} + +static +void +commandline_setdependoutput(char *str) +{ + mode.depend_file = str; +} + +static +void +commandline_M(void) +{ + mode.do_depend = true; + mode.depend_report_system = true; + mode.do_output = false; +} + +static +void +commandline_MM(void) +{ + mode.do_depend = true; + mode.depend_report_system = false; + mode.do_output = false; +} + +static +void +commandline_MD(void) +{ + mode.do_depend = true; + mode.depend_report_system = true; +} + +static +void +commandline_MMD(void) +{ + mode.do_depend = true; + mode.depend_report_system = false; +} + +static +void +commandline_wall(void) +{ + warns.nestcomment = true; + warns.undef = true; + warns.unused = true; +} + +static +void +commandline_wnoall(void) +{ + warns.nestcomment = false; + warns.undef = false; + warns.unused = false; +} + +static +void +commandline_wnone(void) +{ + warns.nestcomment = false; + warns.endiflabels = false; + warns.undef = false; + warns.unused = false; +} + +//////////////////////////////////////////////////////////// +// options + +struct flag_option { + const char *string; + bool *flag; + bool setto; +}; + +struct act_option { + const char *string; + void (*func)(void); +}; + +struct prefix_option { + const char *string; + void (*func)(char *); +}; + +struct arg_option { + const char *string; + void (*func)(char *); +}; + +static const struct flag_option flag_options[] = { + { "C", &mode.output_retain_comments, true }, + { "CC", &mode.output_retain_comments, true }, + { "fdollars-in-identifiers", &mode.input_allow_dollars, true }, + { "fno-dollars-in-identifiers", &mode.input_allow_dollars, false }, + { "MG", &mode.depend_assume_generated, true }, + { "MP", &mode.depend_issue_fakerules, true }, + { "nostdinc", &mode.do_stdinc, false }, + { "P", &mode.output_linenumbers, false }, + { "undef", &mode.do_stddef, false }, + { "Wcomment", &warns.nestcomment, true }, + { "Wendif-labels", &warns.endiflabels, true }, + { "Werror", &mode.werror, true }, + { "Wno-comment", &warns.nestcomment, false }, + { "Wno-endif-labels", &warns.endiflabels, false }, + { "Wno-error", &mode.werror, false }, + { "Wno-undef", &warns.undef, false }, + { "Wno-unused-macros", &warns.unused, false }, + { "Wundef", &warns.undef, true }, + { "Wunused-macros", &warns.unused, true }, +}; +static const unsigned num_flag_options = HOWMANY(flag_options); + +static const struct act_option act_options[] = { + { "dD", commandline_dD }, + { "dI", commandline_dI }, + { "dM", commandline_dM }, + { "dN", commandline_dN }, + { "H", commandline_H }, + { "M", commandline_M }, + { "MD", commandline_MD }, + { "MM", commandline_MM }, + { "MMD", commandline_MMD }, + { "Wall", commandline_wall }, + { "Wno-all", commandline_wnoall }, + { "w", commandline_wnone }, +}; +static const unsigned num_act_options = HOWMANY(act_options); + +static const struct prefix_option prefix_options[] = { + { "D", commandline_def }, + { "ftabstop=", commandline_tabstop }, + { "I", commandline_addincpath_user }, + { "std=", commandline_setstd }, + { "U", commandline_undef }, +}; +static const unsigned num_prefix_options = HOWMANY(prefix_options); + +static const struct arg_option arg_options[] = { + { "idirafter", commandline_addincpath_late }, + { "imacros", commandline_addfile_nooutput }, + { "include", commandline_addfile_output }, + { "iprefix", commandline_setprefix }, + { "iquote", commandline_addincpath_quote }, + { "iremap", commandline_iremap }, + { "isysroot", commandline_isysroot }, + { "isystem", commandline_addincpath_system }, + { "iwithprefix", commandline_addincpath_late_withprefix }, + { "iwithprefixbefore", commandline_addincpath_user_withprefix }, + { "MF", commandline_setdependoutput }, + { "MT", commandline_setdependtarget }, + { "MQ", commandline_setdependtarget_quoted }, + { "x", commandline_setlang }, +}; +static const unsigned num_arg_options = HOWMANY(arg_options); + +static +bool +check_flag_option(const char *opt) +{ + unsigned i; + int r; + + for (i=0; i