Allow preprocess-only and setting of preproc. Update main() and related

functions to be a bit more clean.

svn path=/trunk/yasm/; revision=479
0.3
Peter Johnson 23 years ago
parent 4ee8ccc660
commit 5d2e9ea0f0
  1. 1
      frontends/yasm/Makefile.inc
  2. 230
      frontends/yasm/yasm.c
  3. 1
      libyasm/Makefile.inc
  4. 9
      libyasm/preproc.h
  5. 1
      modules/Makefile.inc
  6. 1
      src/Makefile.inc
  7. 230
      src/main.c
  8. 66
      src/preproc.c
  9. 9
      src/preproc.h

@ -21,6 +21,7 @@ YASMBASEFILES = \
src/arch.h \ src/arch.h \
src/objfmt.c \ src/objfmt.c \
src/objfmt.h \ src/objfmt.h \
src/preproc.c \
src/preproc.h \ src/preproc.h \
src/parser.c \ src/parser.c \
src/parser.h \ src/parser.h \

@ -46,22 +46,25 @@
#define countof(x,y) (sizeof(x)/sizeof(y)) #define countof(x,y) (sizeof(x)/sizeof(y))
#endif #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@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL;
/*@null@*/ static FILE *in = NULL, *obj = NULL;
static int special_options = 0; 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); static void cleanup(sectionhead *sections);
/* Forward declarations: cmd line parser handlers */ /* Forward declarations: cmd line parser handlers */
static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra); 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_objfile_handler(char *cmd, /*@null@*/ char *param, int extra);
static int opt_warning_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 preproc_only_handler(char *cmd, /*@null@*/ char *param, int extra);
static int boo_boo_handler(char *cmd, /*@null@*/ char *param, int extra);
static int b_handler(char *cmd, /*@null@*/ char *param, int extra);
/* values for special_options */ /* values for special_options */
#define SPECIAL_SHOW_HELP 0x01 #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 }, { 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 }, { '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_("<format>") }, { 'p', "parser", 1, opt_parser_handler, 0, N_("select parser"), N_("parser") },
{ 'o', "objfile", 1, opt_objfile_handler, 0, N_("name of object-file output"), N_("<filename>") }, { '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, 1, N_("inhibits warning messages"), NULL },
{ 'W', NULL, 0, opt_warning_handler, 0, N_("enables/disables warning"), NULL }, { 'W', NULL, 0, opt_warning_handler, 0, N_("enables/disables warning"), NULL },
/* Fake handlers: remove them */ { 'e', "preproc-only", 0, preproc_only_handler, 0, N_("preprocess only (writes output to stdout by default)"), NULL },
{ 'b', NULL, 0, b_handler, 0, "says boom!", NULL },
{ 0, "boo-boo", 0, boo_boo_handler, 0, "says boo-boo!", NULL },
}; };
/* version message */ /* version message */
@ -95,7 +98,7 @@ static const char version_msg[] = N_(
/* help messages */ /* help messages */
static const char help_head[] = N_( static const char help_head[] = N_(
"usage: yasm [options|files]+\n" "usage: yasm [option]* file\n"
"Options:\n"); "Options:\n");
static const char help_tail[] = N_( static const char help_tail[] = N_(
"\n" "\n"
@ -111,6 +114,7 @@ static const char help_tail[] = N_(
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
/*@null@*/ FILE *in = NULL, *obj = NULL;
sectionhead *sections; sectionhead *sections;
#if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES) #if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES)
@ -141,14 +145,21 @@ main(int argc, char *argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* if no files were specified, fallback to reading stdin */ if (in_filename && strcmp(in_filename, "-") != 0) {
if (!in || !in_filename) { /* 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; in = stdin;
if (in_filename) if (!in_filename)
xfree(in_filename); in_filename = xstrdup("-");
in_filename = xstrdup("<STDIN>"); /* Default to stdout if no obj filename specified */
if (!obj) if (!obj_filename)
obj = stdout; obj_filename = xstrdup("-");
} }
/* Initialize line info */ /* Initialize line info */
@ -162,22 +173,59 @@ main(int argc, char *argv[])
cur_objfmt = find_objfmt("dbg"); cur_objfmt = find_objfmt("dbg");
assert(cur_objfmt != NULL); assert(cur_objfmt != NULL);
/* open the object file if not specified */ /* handle preproc-only case here */
if (!obj) { if (preproc_only) {
/* build the object filename */ char *preproc_buf = xmalloc(PREPROC_BUF_SIZE);
if (obj_filename) size_t got;
xfree(obj_filename);
assert(in_filename != NULL); /* 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 */ /* replace (or add) extension */
obj_filename = replace_extension(in_filename, cur_objfmt->extension, obj_filename = replace_extension(in_filename, cur_objfmt->extension,
"yasm.out"); "yasm.out");
}
/* Pre-open the object file as debug_file if we're using a debug-type /* 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). * format. (This is so the format can output ALL function call info).
*/ */
if (strcmp(cur_objfmt->keyword, "dbg") == 0) { if (strcmp(cur_objfmt->keyword, "dbg") == 0) {
if (!open_obj()) obj = open_obj();
if (!obj)
return EXIT_FAILURE; return EXIT_FAILURE;
debug_file = obj; debug_file = obj;
} }
@ -192,15 +240,26 @@ main(int argc, char *argv[])
return EXIT_FAILURE; 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 */ /* Get initial BITS setting from object format */
x86_mode_bits = cur_objfmt->default_mode_bits; x86_mode_bits = cur_objfmt->default_mode_bits;
/* Parse! */
sections = cur_parser->do_parse(cur_parser, in); sections = cur_parser->do_parse(cur_parser, in);
/* Close input file */
if (in != stdin) if (in != stdin)
fclose(in); fclose(in);
if (in_filename) xfree(in_filename);
xfree(in_filename);
if (OutputAllErrorWarning() > 0) { if (OutputAllErrorWarning() > 0) {
cleanup(sections); cleanup(sections);
@ -216,17 +275,18 @@ main(int argc, char *argv[])
} }
/* open the object file for output (if not already opened above) */ /* open the object file for output (if not already opened above) */
if (!debug_file) { if (!obj) {
if (!open_obj()) obj = open_obj();
if (!obj) {
cleanup(sections);
return EXIT_FAILURE; return EXIT_FAILURE;
}
} }
/* Write the object file */ /* Write the object file */
cur_objfmt->output(obj, sections); cur_objfmt->output(obj, sections);
/* Finalize the object output */ /* Close object file */
cur_objfmt->cleanup();
if (obj != stdout) if (obj != stdout)
fclose(obj); fclose(obj);
@ -240,8 +300,7 @@ main(int argc, char *argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (obj_filename) xfree(obj_filename);
xfree(obj_filename);
cleanup(sections); cleanup(sections);
return EXIT_SUCCESS; return EXIT_SUCCESS;
@ -249,17 +308,21 @@ main(int argc, char *argv[])
/*@=globstate =unrecog@*/ /*@=globstate =unrecog@*/
/* Open the object file. Returns 0 on failure. */ /* Open the object file. Returns 0 on failure. */
static int static FILE *
open_obj(void) 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"); obj = fopen(obj_filename, "wb");
if (!obj) { if (!obj)
ErrorNow(_("could not open file `%s'"), obj_filename); ErrorNow(_("could not open file `%s'"), obj_filename);
return 0;
}
} }
return 1; return obj;
} }
/* Cleans up all allocated structures. */ /* Cleans up all allocated structures. */
@ -268,6 +331,8 @@ cleanup(sectionhead *sections)
{ {
sections_delete(sections); sections_delete(sections);
symrec_delete_all(); symrec_delete_all();
if (cur_objfmt)
cur_objfmt->cleanup();
line_shutdown(); line_shutdown();
floatnum_shutdown(); floatnum_shutdown();
@ -282,22 +347,13 @@ cleanup(sectionhead *sections)
int int
not_an_option_handler(char *param) not_an_option_handler(char *param)
{ {
if (in) { if (in_filename) {
WarningNow("can open only one input file, only latest file will be processed"); WarningNow("can open only one input file, only the last file will be processed");
if (fclose(in)) xfree(in_filename);
ErrorNow("could not close old input file");
} }
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); in_filename = xstrdup(param);
files_open++;
return 0; return 0;
} }
@ -310,7 +366,31 @@ opt_special_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
} }
static int 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); assert(param != NULL);
cur_objfmt = find_objfmt(param); cur_objfmt = find_objfmt(param);
@ -325,27 +405,12 @@ static int
opt_objfile_handler(/*@unused@*/ char *cmd, char *param, opt_objfile_handler(/*@unused@*/ char *cmd, char *param,
/*@unused@*/ int extra) /*@unused@*/ int extra)
{ {
assert(param != NULL); if (obj_filename) {
if (strcmp(param, "-") == 0) WarningNow(_("can output to only one object file, last specified used"));
obj = stdout; xfree(obj_filename);
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) assert(param != NULL);
xfree(obj_filename);
obj_filename = xstrdup(param); obj_filename = xstrdup(param);
return 0; return 0;
@ -384,19 +449,10 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra)
return 0; 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 static int
b_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, preproc_only_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param,
/*@unused@*/ int extra) /*@unused@*/ int extra)
{ {
fprintf(stdout, "boom!\n"); preproc_only = 1;
return 0; return 0;
} }

@ -21,6 +21,7 @@ YASMBASEFILES = \
src/arch.h \ src/arch.h \
src/objfmt.c \ src/objfmt.c \
src/objfmt.h \ src/objfmt.h \
src/preproc.c \
src/preproc.h \ src/preproc.h \
src/parser.c \ src/parser.c \
src/parser.h \ src/parser.h \

@ -49,4 +49,13 @@ struct preproc {
/* Available preprocessors */ /* Available preprocessors */
extern preproc raw_preproc; 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 #endif

@ -21,6 +21,7 @@ YASMBASEFILES = \
src/arch.h \ src/arch.h \
src/objfmt.c \ src/objfmt.c \
src/objfmt.h \ src/objfmt.h \
src/preproc.c \
src/preproc.h \ src/preproc.h \
src/parser.c \ src/parser.c \
src/parser.h \ src/parser.h \

@ -21,6 +21,7 @@ YASMBASEFILES = \
src/arch.h \ src/arch.h \
src/objfmt.c \ src/objfmt.c \
src/objfmt.h \ src/objfmt.h \
src/preproc.c \
src/preproc.h \ src/preproc.h \
src/parser.c \ src/parser.c \
src/parser.h \ src/parser.h \

@ -46,22 +46,25 @@
#define countof(x,y) (sizeof(x)/sizeof(y)) #define countof(x,y) (sizeof(x)/sizeof(y))
#endif #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@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL;
/*@null@*/ static FILE *in = NULL, *obj = NULL;
static int special_options = 0; 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); static void cleanup(sectionhead *sections);
/* Forward declarations: cmd line parser handlers */ /* Forward declarations: cmd line parser handlers */
static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra); 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_objfile_handler(char *cmd, /*@null@*/ char *param, int extra);
static int opt_warning_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 preproc_only_handler(char *cmd, /*@null@*/ char *param, int extra);
static int boo_boo_handler(char *cmd, /*@null@*/ char *param, int extra);
static int b_handler(char *cmd, /*@null@*/ char *param, int extra);
/* values for special_options */ /* values for special_options */
#define SPECIAL_SHOW_HELP 0x01 #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 }, { 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 }, { '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_("<format>") }, { 'p', "parser", 1, opt_parser_handler, 0, N_("select parser"), N_("parser") },
{ 'o', "objfile", 1, opt_objfile_handler, 0, N_("name of object-file output"), N_("<filename>") }, { '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, 1, N_("inhibits warning messages"), NULL },
{ 'W', NULL, 0, opt_warning_handler, 0, N_("enables/disables warning"), NULL }, { 'W', NULL, 0, opt_warning_handler, 0, N_("enables/disables warning"), NULL },
/* Fake handlers: remove them */ { 'e', "preproc-only", 0, preproc_only_handler, 0, N_("preprocess only (writes output to stdout by default)"), NULL },
{ 'b', NULL, 0, b_handler, 0, "says boom!", NULL },
{ 0, "boo-boo", 0, boo_boo_handler, 0, "says boo-boo!", NULL },
}; };
/* version message */ /* version message */
@ -95,7 +98,7 @@ static const char version_msg[] = N_(
/* help messages */ /* help messages */
static const char help_head[] = N_( static const char help_head[] = N_(
"usage: yasm [options|files]+\n" "usage: yasm [option]* file\n"
"Options:\n"); "Options:\n");
static const char help_tail[] = N_( static const char help_tail[] = N_(
"\n" "\n"
@ -111,6 +114,7 @@ static const char help_tail[] = N_(
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
/*@null@*/ FILE *in = NULL, *obj = NULL;
sectionhead *sections; sectionhead *sections;
#if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES) #if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES)
@ -141,14 +145,21 @@ main(int argc, char *argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* if no files were specified, fallback to reading stdin */ if (in_filename && strcmp(in_filename, "-") != 0) {
if (!in || !in_filename) { /* 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; in = stdin;
if (in_filename) if (!in_filename)
xfree(in_filename); in_filename = xstrdup("-");
in_filename = xstrdup("<STDIN>"); /* Default to stdout if no obj filename specified */
if (!obj) if (!obj_filename)
obj = stdout; obj_filename = xstrdup("-");
} }
/* Initialize line info */ /* Initialize line info */
@ -162,22 +173,59 @@ main(int argc, char *argv[])
cur_objfmt = find_objfmt("dbg"); cur_objfmt = find_objfmt("dbg");
assert(cur_objfmt != NULL); assert(cur_objfmt != NULL);
/* open the object file if not specified */ /* handle preproc-only case here */
if (!obj) { if (preproc_only) {
/* build the object filename */ char *preproc_buf = xmalloc(PREPROC_BUF_SIZE);
if (obj_filename) size_t got;
xfree(obj_filename);
assert(in_filename != NULL); /* 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 */ /* replace (or add) extension */
obj_filename = replace_extension(in_filename, cur_objfmt->extension, obj_filename = replace_extension(in_filename, cur_objfmt->extension,
"yasm.out"); "yasm.out");
}
/* Pre-open the object file as debug_file if we're using a debug-type /* 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). * format. (This is so the format can output ALL function call info).
*/ */
if (strcmp(cur_objfmt->keyword, "dbg") == 0) { if (strcmp(cur_objfmt->keyword, "dbg") == 0) {
if (!open_obj()) obj = open_obj();
if (!obj)
return EXIT_FAILURE; return EXIT_FAILURE;
debug_file = obj; debug_file = obj;
} }
@ -192,15 +240,26 @@ main(int argc, char *argv[])
return EXIT_FAILURE; 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 */ /* Get initial BITS setting from object format */
x86_mode_bits = cur_objfmt->default_mode_bits; x86_mode_bits = cur_objfmt->default_mode_bits;
/* Parse! */
sections = cur_parser->do_parse(cur_parser, in); sections = cur_parser->do_parse(cur_parser, in);
/* Close input file */
if (in != stdin) if (in != stdin)
fclose(in); fclose(in);
if (in_filename) xfree(in_filename);
xfree(in_filename);
if (OutputAllErrorWarning() > 0) { if (OutputAllErrorWarning() > 0) {
cleanup(sections); cleanup(sections);
@ -216,17 +275,18 @@ main(int argc, char *argv[])
} }
/* open the object file for output (if not already opened above) */ /* open the object file for output (if not already opened above) */
if (!debug_file) { if (!obj) {
if (!open_obj()) obj = open_obj();
if (!obj) {
cleanup(sections);
return EXIT_FAILURE; return EXIT_FAILURE;
}
} }
/* Write the object file */ /* Write the object file */
cur_objfmt->output(obj, sections); cur_objfmt->output(obj, sections);
/* Finalize the object output */ /* Close object file */
cur_objfmt->cleanup();
if (obj != stdout) if (obj != stdout)
fclose(obj); fclose(obj);
@ -240,8 +300,7 @@ main(int argc, char *argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (obj_filename) xfree(obj_filename);
xfree(obj_filename);
cleanup(sections); cleanup(sections);
return EXIT_SUCCESS; return EXIT_SUCCESS;
@ -249,17 +308,21 @@ main(int argc, char *argv[])
/*@=globstate =unrecog@*/ /*@=globstate =unrecog@*/
/* Open the object file. Returns 0 on failure. */ /* Open the object file. Returns 0 on failure. */
static int static FILE *
open_obj(void) 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"); obj = fopen(obj_filename, "wb");
if (!obj) { if (!obj)
ErrorNow(_("could not open file `%s'"), obj_filename); ErrorNow(_("could not open file `%s'"), obj_filename);
return 0;
}
} }
return 1; return obj;
} }
/* Cleans up all allocated structures. */ /* Cleans up all allocated structures. */
@ -268,6 +331,8 @@ cleanup(sectionhead *sections)
{ {
sections_delete(sections); sections_delete(sections);
symrec_delete_all(); symrec_delete_all();
if (cur_objfmt)
cur_objfmt->cleanup();
line_shutdown(); line_shutdown();
floatnum_shutdown(); floatnum_shutdown();
@ -282,22 +347,13 @@ cleanup(sectionhead *sections)
int int
not_an_option_handler(char *param) not_an_option_handler(char *param)
{ {
if (in) { if (in_filename) {
WarningNow("can open only one input file, only latest file will be processed"); WarningNow("can open only one input file, only the last file will be processed");
if (fclose(in)) xfree(in_filename);
ErrorNow("could not close old input file");
} }
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); in_filename = xstrdup(param);
files_open++;
return 0; return 0;
} }
@ -310,7 +366,31 @@ opt_special_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
} }
static int 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); assert(param != NULL);
cur_objfmt = find_objfmt(param); cur_objfmt = find_objfmt(param);
@ -325,27 +405,12 @@ static int
opt_objfile_handler(/*@unused@*/ char *cmd, char *param, opt_objfile_handler(/*@unused@*/ char *cmd, char *param,
/*@unused@*/ int extra) /*@unused@*/ int extra)
{ {
assert(param != NULL); if (obj_filename) {
if (strcmp(param, "-") == 0) WarningNow(_("can output to only one object file, last specified used"));
obj = stdout; xfree(obj_filename);
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) assert(param != NULL);
xfree(obj_filename);
obj_filename = xstrdup(param); obj_filename = xstrdup(param);
return 0; return 0;
@ -384,19 +449,10 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra)
return 0; 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 static int
b_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, preproc_only_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param,
/*@unused@*/ int extra) /*@unused@*/ int extra)
{ {
fprintf(stdout, "boom!\n"); preproc_only = 1;
return 0; return 0;
} }

@ -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);
}
}

@ -49,4 +49,13 @@ struct preproc {
/* Available preprocessors */ /* Available preprocessors */
extern preproc raw_preproc; 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 #endif

Loading…
Cancel
Save