mirror of
https://github.com/yasm/yasm
synced 2026-08-26 22:26:05 -04:00
Allow preprocess-only and setting of preproc. Update main() and related
functions to be a bit more clean. svn path=/trunk/yasm/; revision=479
This commit is contained in:
parent
4ee8ccc660
commit
5d2e9ea0f0
9 changed files with 380 additions and 180 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -46,22 +46,25 @@
|
|||
#define countof(x,y) (sizeof(x)/sizeof(y))
|
||||
#endif
|
||||
|
||||
static int files_open = 0;
|
||||
/*@null@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL;
|
||||
/*@null@*/ static FILE *in = NULL, *obj = NULL;
|
||||
static int special_options = 0;
|
||||
/* Preprocess-only buffer size */
|
||||
#define PREPROC_BUF_SIZE 16384
|
||||
|
||||
static int open_obj(void);
|
||||
/*@null@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL;
|
||||
static int special_options = 0;
|
||||
static preproc *cur_preproc = NULL;
|
||||
static int preproc_only = 0;
|
||||
|
||||
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_("<format>") },
|
||||
{ 'o', "objfile", 1, opt_objfile_handler, 0, N_("name of object-file output"), N_("<filename>") },
|
||||
{ '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("<STDIN>");
|
||||
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)
|
||||
if (obj_filename) {
|
||||
WarningNow(_("can output to only one object file, last specified used"));
|
||||
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)
|
||||
preproc_only_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)
|
||||
{
|
||||
fprintf(stdout, "boom!\n");
|
||||
preproc_only = 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
236
src/main.c
236
src/main.c
|
|
@ -46,22 +46,25 @@
|
|||
#define countof(x,y) (sizeof(x)/sizeof(y))
|
||||
#endif
|
||||
|
||||
static int files_open = 0;
|
||||
/*@null@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL;
|
||||
/*@null@*/ static FILE *in = NULL, *obj = NULL;
|
||||
static int special_options = 0;
|
||||
/* Preprocess-only buffer size */
|
||||
#define PREPROC_BUF_SIZE 16384
|
||||
|
||||
static int open_obj(void);
|
||||
/*@null@*/ /*@only@*/ static char *obj_filename = NULL, *in_filename = NULL;
|
||||
static int special_options = 0;
|
||||
static preproc *cur_preproc = NULL;
|
||||
static int preproc_only = 0;
|
||||
|
||||
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_("<format>") },
|
||||
{ 'o', "objfile", 1, opt_objfile_handler, 0, N_("name of object-file output"), N_("<filename>") },
|
||||
{ '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("<STDIN>");
|
||||
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)
|
||||
if (obj_filename) {
|
||||
WarningNow(_("can output to only one object file, last specified used"));
|
||||
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)
|
||||
preproc_only_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)
|
||||
{
|
||||
fprintf(stdout, "boom!\n");
|
||||
preproc_only = 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
66
src/preproc.c
Normal file
66
src/preproc.c
Normal file
|
|
@ -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 */
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue