From 5d2e9ea0f0e70e66d2012e80751f1deebd79d861 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Wed, 6 Mar 2002 06:02:21 +0000 Subject: [PATCH] Allow preprocess-only and setting of preproc. Update main() and related functions to be a bit more clean. svn path=/trunk/yasm/; revision=479 --- frontends/yasm/Makefile.inc | 1 + frontends/yasm/yasm.c | 230 ++++++++++++++++++++++-------------- libyasm/Makefile.inc | 1 + libyasm/preproc.h | 9 ++ modules/Makefile.inc | 1 + src/Makefile.inc | 1 + src/main.c | 230 ++++++++++++++++++++++-------------- src/preproc.c | 66 +++++++++++ src/preproc.h | 9 ++ 9 files changed, 374 insertions(+), 174 deletions(-) create mode 100644 src/preproc.c diff --git a/frontends/yasm/Makefile.inc b/frontends/yasm/Makefile.inc index 0ff46e7c..62b3e572 100644 --- a/frontends/yasm/Makefile.inc +++ b/frontends/yasm/Makefile.inc @@ -21,6 +21,7 @@ YASMBASEFILES = \ src/arch.h \ src/objfmt.c \ src/objfmt.h \ + src/preproc.c \ src/preproc.h \ src/parser.c \ src/parser.h \ diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index 87f1fea5..d4eb2def 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -46,22 +46,25 @@ #define countof(x,y) (sizeof(x)/sizeof(y)) #endif -static int files_open = 0; +/* Preprocess-only buffer size */ +#define PREPROC_BUF_SIZE 16384 + /*@null@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL; -/*@null@*/ static FILE *in = NULL, *obj = NULL; static int special_options = 0; +static preproc *cur_preproc = NULL; +static int preproc_only = 0; -static int open_obj(void); +static FILE *open_obj(void); static void cleanup(sectionhead *sections); /* Forward declarations: cmd line parser handlers */ static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra); -static int opt_format_handler(char *cmd, /*@null@*/ char *param, int extra); +static int opt_parser_handler(char *cmd, /*@null@*/ char *param, int extra); +static int opt_preproc_handler(char *cmd, /*@null@*/ char *param, int extra); +static int opt_objfmt_handler(char *cmd, /*@null@*/ char *param, int extra); static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra); static int opt_warning_handler(char *cmd, /*@null@*/ char *param, int extra); -/* Fake handlers: remove them */ -static int boo_boo_handler(char *cmd, /*@null@*/ char *param, int extra); -static int b_handler(char *cmd, /*@null@*/ char *param, int extra); +static int preproc_only_handler(char *cmd, /*@null@*/ char *param, int extra); /* values for special_options */ #define SPECIAL_SHOW_HELP 0x01 @@ -72,13 +75,13 @@ static opt_option options[] = { { 0, "version", 0, opt_special_handler, SPECIAL_SHOW_VERSION, N_("show version text"), NULL }, { 'h', "help", 0, opt_special_handler, SPECIAL_SHOW_HELP, N_("show help text"), NULL }, - { 'f', "oformat", 1, opt_format_handler, 0, N_("select output format"), N_("") }, - { 'o', "objfile", 1, opt_objfile_handler, 0, N_("name of object-file output"), N_("") }, + { 'p', "parser", 1, opt_parser_handler, 0, N_("select parser"), N_("parser") }, + { 'r', "preproc", 1, opt_preproc_handler, 0, N_("select preprocessor"), N_("preproc") }, + { 'f', "oformat", 1, opt_objfmt_handler, 0, N_("select object format"), N_("format") }, + { 'o', "objfile", 1, opt_objfile_handler, 0, N_("name of object-file output"), N_("filename") }, { 'w', NULL, 0, opt_warning_handler, 1, N_("inhibits warning messages"), NULL }, { 'W', NULL, 0, opt_warning_handler, 0, N_("enables/disables warning"), NULL }, - /* Fake handlers: remove them */ - { 'b', NULL, 0, b_handler, 0, "says boom!", NULL }, - { 0, "boo-boo", 0, boo_boo_handler, 0, "says boo-boo!", NULL }, + { 'e', "preproc-only", 0, preproc_only_handler, 0, N_("preprocess only (writes output to stdout by default)"), NULL }, }; /* version message */ @@ -95,7 +98,7 @@ static const char version_msg[] = N_( /* help messages */ static const char help_head[] = N_( - "usage: yasm [options|files]+\n" + "usage: yasm [option]* file\n" "Options:\n"); static const char help_tail[] = N_( "\n" @@ -111,6 +114,7 @@ static const char help_tail[] = N_( int main(int argc, char *argv[]) { + /*@null@*/ FILE *in = NULL, *obj = NULL; sectionhead *sections; #if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES) @@ -141,14 +145,21 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } - /* if no files were specified, fallback to reading stdin */ - if (!in || !in_filename) { + if (in_filename && strcmp(in_filename, "-") != 0) { + /* Open the input file (if not standard input) */ + in = fopen(in_filename, "rt"); + if (!in) { + ErrorNow(_("could not open file `%s'"), in_filename); + return EXIT_FAILURE; + } + } else { + /* If no files were specified, fallback to reading stdin */ in = stdin; - if (in_filename) - xfree(in_filename); - in_filename = xstrdup(""); - if (!obj) - obj = stdout; + if (!in_filename) + in_filename = xstrdup("-"); + /* Default to stdout if no obj filename specified */ + if (!obj_filename) + obj_filename = xstrdup("-"); } /* Initialize line info */ @@ -162,22 +173,59 @@ main(int argc, char *argv[]) cur_objfmt = find_objfmt("dbg"); assert(cur_objfmt != NULL); - /* open the object file if not specified */ - if (!obj) { - /* build the object filename */ - if (obj_filename) - xfree(obj_filename); - assert(in_filename != NULL); + /* handle preproc-only case here */ + if (preproc_only) { + char *preproc_buf = xmalloc(PREPROC_BUF_SIZE); + size_t got; + + /* Default output to stdout if not specified */ + if (!obj_filename) + obj_filename = xstrdup("-"); + + /* Open output (object) file */ + obj = open_obj(); + if (!obj) + return EXIT_FAILURE; + + /* If not already specified, default to raw preproc. */ + if (!cur_preproc) + cur_preproc = find_preproc("raw"); + assert(cur_preproc != NULL); + + /* Pre-process until done */ + cur_preproc->initialize(in); + while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0) + fwrite(preproc_buf, got, 1, obj); + + if (in != stdin) + fclose(in); + xfree(in_filename); + + if (obj != stdout) + fclose(obj); + + if (OutputAllErrorWarning() > 0) { + if (obj != stdout) + remove(obj_filename); + return EXIT_FAILURE; + } + xfree(obj_filename); + + return EXIT_SUCCESS; + } + + /* determine the object filename if not specified or stdout defaulted */ + if (!obj_filename) /* replace (or add) extension */ obj_filename = replace_extension(in_filename, cur_objfmt->extension, "yasm.out"); - } /* Pre-open the object file as debug_file if we're using a debug-type * format. (This is so the format can output ALL function call info). */ if (strcmp(cur_objfmt->keyword, "dbg") == 0) { - if (!open_obj()) + obj = open_obj(); + if (!obj) return EXIT_FAILURE; debug_file = obj; } @@ -192,15 +240,26 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } + /* (Try to) set a preprocessor, if requested */ + if (cur_preproc) { + if (parser_setpp(cur_parser, cur_preproc->keyword)) { + if (in != stdin) + fclose(in); + xfree(in_filename); + return EXIT_FAILURE; + } + } + /* Get initial BITS setting from object format */ x86_mode_bits = cur_objfmt->default_mode_bits; + /* Parse! */ sections = cur_parser->do_parse(cur_parser, in); + /* Close input file */ if (in != stdin) fclose(in); - if (in_filename) - xfree(in_filename); + xfree(in_filename); if (OutputAllErrorWarning() > 0) { cleanup(sections); @@ -216,17 +275,18 @@ main(int argc, char *argv[]) } /* open the object file for output (if not already opened above) */ - if (!debug_file) { - if (!open_obj()) + if (!obj) { + obj = open_obj(); + if (!obj) { + cleanup(sections); return EXIT_FAILURE; + } } /* Write the object file */ cur_objfmt->output(obj, sections); - /* Finalize the object output */ - cur_objfmt->cleanup(); - + /* Close object file */ if (obj != stdout) fclose(obj); @@ -240,8 +300,7 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } - if (obj_filename) - xfree(obj_filename); + xfree(obj_filename); cleanup(sections); return EXIT_SUCCESS; @@ -249,17 +308,21 @@ main(int argc, char *argv[]) /*@=globstate =unrecog@*/ /* Open the object file. Returns 0 on failure. */ -static int +static FILE * open_obj(void) { - if (obj != stdout) { + FILE *obj; + + assert(obj_filename != NULL); + + if (strcmp(obj_filename, "-") == 0) + obj = stdout; + else { obj = fopen(obj_filename, "wb"); - if (!obj) { + if (!obj) ErrorNow(_("could not open file `%s'"), obj_filename); - return 0; - } } - return 1; + return obj; } /* Cleans up all allocated structures. */ @@ -268,6 +331,8 @@ cleanup(sectionhead *sections) { sections_delete(sections); symrec_delete_all(); + if (cur_objfmt) + cur_objfmt->cleanup(); line_shutdown(); floatnum_shutdown(); @@ -282,22 +347,13 @@ cleanup(sectionhead *sections) int not_an_option_handler(char *param) { - if (in) { - WarningNow("can open only one input file, only latest file will be processed"); - if (fclose(in)) - ErrorNow("could not close old input file"); + if (in_filename) { + WarningNow("can open only one input file, only the last file will be processed"); + xfree(in_filename); } - in = fopen(param, "rt"); - if (!in) { - ErrorNow(_("could not open file `%s'"), param); - return 1; - } - if (in_filename) - xfree(in_filename); in_filename = xstrdup(param); - files_open++; return 0; } @@ -310,7 +366,31 @@ opt_special_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra) } static int -opt_format_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) +opt_parser_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) +{ + assert(param != NULL); + cur_parser = find_parser(param); + if (!cur_parser) { + ErrorNow(_("unrecognized parser `%s'"), param); + return 1; + } + return 0; +} + +static int +opt_preproc_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) +{ + assert(param != NULL); + cur_preproc = find_preproc(param); + if (!cur_preproc) { + ErrorNow(_("unrecognized preprocessor `%s'"), param); + return 1; + } + return 0; +} + +static int +opt_objfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) { assert(param != NULL); cur_objfmt = find_objfmt(param); @@ -325,27 +405,12 @@ static int opt_objfile_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) { - assert(param != NULL); - if (strcmp(param, "-") == 0) - obj = stdout; - else { - if (obj) { - WarningNow("can open only one output file, last specified used"); - if (obj != stdout && fclose(obj)) - ErrorNow("could not close old output file"); - } - } - - if (obj != stdout) { - obj = fopen(param, "wb"); - if (!obj) { - ErrorNow(_("could not open file `%s'"), param); - return 1; - } + if (obj_filename) { + WarningNow(_("can output to only one object file, last specified used")); + xfree(obj_filename); } - if (obj_filename) - xfree(obj_filename); + assert(param != NULL); obj_filename = xstrdup(param); return 0; @@ -384,19 +449,10 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra) return 0; } -/* Fake handlers: remove them */ -static int -boo_boo_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, - /*@unused@*/ int extra) -{ - printf("boo-boo!\n"); - return 0; -} - static int -b_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, - /*@unused@*/ int extra) +preproc_only_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, + /*@unused@*/ int extra) { - fprintf(stdout, "boom!\n"); + preproc_only = 1; return 0; } diff --git a/libyasm/Makefile.inc b/libyasm/Makefile.inc index 0ff46e7c..62b3e572 100644 --- a/libyasm/Makefile.inc +++ b/libyasm/Makefile.inc @@ -21,6 +21,7 @@ YASMBASEFILES = \ src/arch.h \ src/objfmt.c \ src/objfmt.h \ + src/preproc.c \ src/preproc.h \ src/parser.c \ src/parser.h \ diff --git a/libyasm/preproc.h b/libyasm/preproc.h index 68d4b2d4..8164e1f7 100644 --- a/libyasm/preproc.h +++ b/libyasm/preproc.h @@ -49,4 +49,13 @@ struct preproc { /* Available preprocessors */ extern preproc raw_preproc; +/* Finds a preproc based on its keyword. Returns NULL if no match was found. + */ +/*@null@*/ preproc *find_preproc(const char *keyword); + +/* Lists all available preprocs. Calls printfunc with the name and keyword + * of each available preprocessor. + */ +void list_preprocs(void (*printfunc) (const char *name, const char *keyword)); + #endif diff --git a/modules/Makefile.inc b/modules/Makefile.inc index 0ff46e7c..62b3e572 100644 --- a/modules/Makefile.inc +++ b/modules/Makefile.inc @@ -21,6 +21,7 @@ YASMBASEFILES = \ src/arch.h \ src/objfmt.c \ src/objfmt.h \ + src/preproc.c \ src/preproc.h \ src/parser.c \ src/parser.h \ diff --git a/src/Makefile.inc b/src/Makefile.inc index 0ff46e7c..62b3e572 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -21,6 +21,7 @@ YASMBASEFILES = \ src/arch.h \ src/objfmt.c \ src/objfmt.h \ + src/preproc.c \ src/preproc.h \ src/parser.c \ src/parser.h \ diff --git a/src/main.c b/src/main.c index 87f1fea5..d4eb2def 100644 --- a/src/main.c +++ b/src/main.c @@ -46,22 +46,25 @@ #define countof(x,y) (sizeof(x)/sizeof(y)) #endif -static int files_open = 0; +/* Preprocess-only buffer size */ +#define PREPROC_BUF_SIZE 16384 + /*@null@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL; -/*@null@*/ static FILE *in = NULL, *obj = NULL; static int special_options = 0; +static preproc *cur_preproc = NULL; +static int preproc_only = 0; -static int open_obj(void); +static FILE *open_obj(void); static void cleanup(sectionhead *sections); /* Forward declarations: cmd line parser handlers */ static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra); -static int opt_format_handler(char *cmd, /*@null@*/ char *param, int extra); +static int opt_parser_handler(char *cmd, /*@null@*/ char *param, int extra); +static int opt_preproc_handler(char *cmd, /*@null@*/ char *param, int extra); +static int opt_objfmt_handler(char *cmd, /*@null@*/ char *param, int extra); static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra); static int opt_warning_handler(char *cmd, /*@null@*/ char *param, int extra); -/* Fake handlers: remove them */ -static int boo_boo_handler(char *cmd, /*@null@*/ char *param, int extra); -static int b_handler(char *cmd, /*@null@*/ char *param, int extra); +static int preproc_only_handler(char *cmd, /*@null@*/ char *param, int extra); /* values for special_options */ #define SPECIAL_SHOW_HELP 0x01 @@ -72,13 +75,13 @@ static opt_option options[] = { { 0, "version", 0, opt_special_handler, SPECIAL_SHOW_VERSION, N_("show version text"), NULL }, { 'h', "help", 0, opt_special_handler, SPECIAL_SHOW_HELP, N_("show help text"), NULL }, - { 'f', "oformat", 1, opt_format_handler, 0, N_("select output format"), N_("") }, - { 'o', "objfile", 1, opt_objfile_handler, 0, N_("name of object-file output"), N_("") }, + { 'p', "parser", 1, opt_parser_handler, 0, N_("select parser"), N_("parser") }, + { 'r', "preproc", 1, opt_preproc_handler, 0, N_("select preprocessor"), N_("preproc") }, + { 'f', "oformat", 1, opt_objfmt_handler, 0, N_("select object format"), N_("format") }, + { 'o', "objfile", 1, opt_objfile_handler, 0, N_("name of object-file output"), N_("filename") }, { 'w', NULL, 0, opt_warning_handler, 1, N_("inhibits warning messages"), NULL }, { 'W', NULL, 0, opt_warning_handler, 0, N_("enables/disables warning"), NULL }, - /* Fake handlers: remove them */ - { 'b', NULL, 0, b_handler, 0, "says boom!", NULL }, - { 0, "boo-boo", 0, boo_boo_handler, 0, "says boo-boo!", NULL }, + { 'e', "preproc-only", 0, preproc_only_handler, 0, N_("preprocess only (writes output to stdout by default)"), NULL }, }; /* version message */ @@ -95,7 +98,7 @@ static const char version_msg[] = N_( /* help messages */ static const char help_head[] = N_( - "usage: yasm [options|files]+\n" + "usage: yasm [option]* file\n" "Options:\n"); static const char help_tail[] = N_( "\n" @@ -111,6 +114,7 @@ static const char help_tail[] = N_( int main(int argc, char *argv[]) { + /*@null@*/ FILE *in = NULL, *obj = NULL; sectionhead *sections; #if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES) @@ -141,14 +145,21 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } - /* if no files were specified, fallback to reading stdin */ - if (!in || !in_filename) { + if (in_filename && strcmp(in_filename, "-") != 0) { + /* Open the input file (if not standard input) */ + in = fopen(in_filename, "rt"); + if (!in) { + ErrorNow(_("could not open file `%s'"), in_filename); + return EXIT_FAILURE; + } + } else { + /* If no files were specified, fallback to reading stdin */ in = stdin; - if (in_filename) - xfree(in_filename); - in_filename = xstrdup(""); - if (!obj) - obj = stdout; + if (!in_filename) + in_filename = xstrdup("-"); + /* Default to stdout if no obj filename specified */ + if (!obj_filename) + obj_filename = xstrdup("-"); } /* Initialize line info */ @@ -162,22 +173,59 @@ main(int argc, char *argv[]) cur_objfmt = find_objfmt("dbg"); assert(cur_objfmt != NULL); - /* open the object file if not specified */ - if (!obj) { - /* build the object filename */ - if (obj_filename) - xfree(obj_filename); - assert(in_filename != NULL); + /* handle preproc-only case here */ + if (preproc_only) { + char *preproc_buf = xmalloc(PREPROC_BUF_SIZE); + size_t got; + + /* Default output to stdout if not specified */ + if (!obj_filename) + obj_filename = xstrdup("-"); + + /* Open output (object) file */ + obj = open_obj(); + if (!obj) + return EXIT_FAILURE; + + /* If not already specified, default to raw preproc. */ + if (!cur_preproc) + cur_preproc = find_preproc("raw"); + assert(cur_preproc != NULL); + + /* Pre-process until done */ + cur_preproc->initialize(in); + while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0) + fwrite(preproc_buf, got, 1, obj); + + if (in != stdin) + fclose(in); + xfree(in_filename); + + if (obj != stdout) + fclose(obj); + + if (OutputAllErrorWarning() > 0) { + if (obj != stdout) + remove(obj_filename); + return EXIT_FAILURE; + } + xfree(obj_filename); + + return EXIT_SUCCESS; + } + + /* determine the object filename if not specified or stdout defaulted */ + if (!obj_filename) /* replace (or add) extension */ obj_filename = replace_extension(in_filename, cur_objfmt->extension, "yasm.out"); - } /* Pre-open the object file as debug_file if we're using a debug-type * format. (This is so the format can output ALL function call info). */ if (strcmp(cur_objfmt->keyword, "dbg") == 0) { - if (!open_obj()) + obj = open_obj(); + if (!obj) return EXIT_FAILURE; debug_file = obj; } @@ -192,15 +240,26 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } + /* (Try to) set a preprocessor, if requested */ + if (cur_preproc) { + if (parser_setpp(cur_parser, cur_preproc->keyword)) { + if (in != stdin) + fclose(in); + xfree(in_filename); + return EXIT_FAILURE; + } + } + /* Get initial BITS setting from object format */ x86_mode_bits = cur_objfmt->default_mode_bits; + /* Parse! */ sections = cur_parser->do_parse(cur_parser, in); + /* Close input file */ if (in != stdin) fclose(in); - if (in_filename) - xfree(in_filename); + xfree(in_filename); if (OutputAllErrorWarning() > 0) { cleanup(sections); @@ -216,17 +275,18 @@ main(int argc, char *argv[]) } /* open the object file for output (if not already opened above) */ - if (!debug_file) { - if (!open_obj()) + if (!obj) { + obj = open_obj(); + if (!obj) { + cleanup(sections); return EXIT_FAILURE; + } } /* Write the object file */ cur_objfmt->output(obj, sections); - /* Finalize the object output */ - cur_objfmt->cleanup(); - + /* Close object file */ if (obj != stdout) fclose(obj); @@ -240,8 +300,7 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } - if (obj_filename) - xfree(obj_filename); + xfree(obj_filename); cleanup(sections); return EXIT_SUCCESS; @@ -249,17 +308,21 @@ main(int argc, char *argv[]) /*@=globstate =unrecog@*/ /* Open the object file. Returns 0 on failure. */ -static int +static FILE * open_obj(void) { - if (obj != stdout) { + FILE *obj; + + assert(obj_filename != NULL); + + if (strcmp(obj_filename, "-") == 0) + obj = stdout; + else { obj = fopen(obj_filename, "wb"); - if (!obj) { + if (!obj) ErrorNow(_("could not open file `%s'"), obj_filename); - return 0; - } } - return 1; + return obj; } /* Cleans up all allocated structures. */ @@ -268,6 +331,8 @@ cleanup(sectionhead *sections) { sections_delete(sections); symrec_delete_all(); + if (cur_objfmt) + cur_objfmt->cleanup(); line_shutdown(); floatnum_shutdown(); @@ -282,22 +347,13 @@ cleanup(sectionhead *sections) int not_an_option_handler(char *param) { - if (in) { - WarningNow("can open only one input file, only latest file will be processed"); - if (fclose(in)) - ErrorNow("could not close old input file"); + if (in_filename) { + WarningNow("can open only one input file, only the last file will be processed"); + xfree(in_filename); } - in = fopen(param, "rt"); - if (!in) { - ErrorNow(_("could not open file `%s'"), param); - return 1; - } - if (in_filename) - xfree(in_filename); in_filename = xstrdup(param); - files_open++; return 0; } @@ -310,7 +366,31 @@ opt_special_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra) } static int -opt_format_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) +opt_parser_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) +{ + assert(param != NULL); + cur_parser = find_parser(param); + if (!cur_parser) { + ErrorNow(_("unrecognized parser `%s'"), param); + return 1; + } + return 0; +} + +static int +opt_preproc_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) +{ + assert(param != NULL); + cur_preproc = find_preproc(param); + if (!cur_preproc) { + ErrorNow(_("unrecognized preprocessor `%s'"), param); + return 1; + } + return 0; +} + +static int +opt_objfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) { assert(param != NULL); cur_objfmt = find_objfmt(param); @@ -325,27 +405,12 @@ static int opt_objfile_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) { - assert(param != NULL); - if (strcmp(param, "-") == 0) - obj = stdout; - else { - if (obj) { - WarningNow("can open only one output file, last specified used"); - if (obj != stdout && fclose(obj)) - ErrorNow("could not close old output file"); - } - } - - if (obj != stdout) { - obj = fopen(param, "wb"); - if (!obj) { - ErrorNow(_("could not open file `%s'"), param); - return 1; - } + if (obj_filename) { + WarningNow(_("can output to only one object file, last specified used")); + xfree(obj_filename); } - if (obj_filename) - xfree(obj_filename); + assert(param != NULL); obj_filename = xstrdup(param); return 0; @@ -384,19 +449,10 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra) return 0; } -/* Fake handlers: remove them */ -static int -boo_boo_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, - /*@unused@*/ int extra) -{ - printf("boo-boo!\n"); - return 0; -} - static int -b_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, - /*@unused@*/ int extra) +preproc_only_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, + /*@unused@*/ int extra) { - fprintf(stdout, "boom!\n"); + preproc_only = 1; return 0; } diff --git a/src/preproc.c b/src/preproc.c new file mode 100644 index 00000000..1c7a802f --- /dev/null +++ b/src/preproc.c @@ -0,0 +1,66 @@ +/* + * Generic functions for all preprocessors + * + * Copyright (C) 2002 Peter Johnson + * + * This file is part of YASM. + * + * YASM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * YASM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "util.h" +/*@unused@*/ RCSID("$IdPath$"); + +#include "globals.h" + +#include "preproc.h" + + +/* NULL-terminated list of all available preprocessors. + * Someday change this if we dynamically load preprocessors at runtime. + * Could improve this a little by generating automatically at build-time. + */ +/*@-nullassign@*/ +static preproc *preprocs[] = { + &raw_preproc, + NULL +}; +/*@=nullassign@*/ + +preproc * +find_preproc(const char *keyword) +{ + int i; + + /* We're just doing a linear search, as there aren't many preprocs */ + for (i = 0; preprocs[i]; i++) { + if (strcasecmp(preprocs[i]->keyword, keyword) == 0) + /*@-unqualifiedtrans@*/ + return preprocs[i]; + /*@=unqualifiedtrans@*/ + } + + /* no match found */ + return NULL; +} + +void +list_preprocs(void (*printfunc) (const char *name, const char *keyword)) +{ + int i; + + for (i = 0; preprocs[i]; i++) { + printfunc(preprocs[i]->name, preprocs[i]->keyword); + } +} diff --git a/src/preproc.h b/src/preproc.h index 68d4b2d4..8164e1f7 100644 --- a/src/preproc.h +++ b/src/preproc.h @@ -49,4 +49,13 @@ struct preproc { /* Available preprocessors */ extern preproc raw_preproc; +/* Finds a preproc based on its keyword. Returns NULL if no match was found. + */ +/*@null@*/ preproc *find_preproc(const char *keyword); + +/* Lists all available preprocs. Calls printfunc with the name and keyword + * of each available preprocessor. + */ +void list_preprocs(void (*printfunc) (const char *name, const char *keyword)); + #endif -- 2.40.0