diff options
-rw-r--r-- | assemble.c | 52 | ||||
-rw-r--r-- | nasmlib.c | 2 | ||||
-rw-r--r-- | pptok.dat | 2 | ||||
-rw-r--r-- | preproc.c | 186 | ||||
-rw-r--r-- | preproc.h | 1 | ||||
-rw-r--r-- | standard.mac | 8 |
6 files changed, 140 insertions, 111 deletions
@@ -119,7 +119,6 @@ #include "nasmlib.h" #include "assemble.h" #include "insns.h" -#include "preproc.h" #include "tables.h" /* Initialized to zero by the C standard */ @@ -369,8 +368,6 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp, static char fname[FILENAME_MAX]; FILE *fp; int32_t len; - char *prefix = "", *combine; - char **pPrevPath = NULL; len = FILENAME_MAX - 1; if (len > instruction->eops->stringlen) @@ -378,30 +375,14 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp, strncpy(fname, instruction->eops->stringval, len); fname[len] = '\0'; - while (1) { /* added by alexfru: 'incbin' uses include paths */ - combine = nasm_malloc(strlen(prefix) + len + 1); - strcpy(combine, prefix); - strcat(combine, fname); - - if ((fp = fopen(combine, "rb")) != NULL) { - nasm_free(combine); - break; - } - - nasm_free(combine); - pPrevPath = pp_get_include_path_ptr(pPrevPath); - if (pPrevPath == NULL) - break; - prefix = *pPrevPath; - } - - if (fp == NULL) + fp = fopen(fname, "rb"); + if (!fp) { error(ERR_NONFATAL, "`incbin': unable to open file `%s'", fname); - else if (fseek(fp, 0L, SEEK_END) < 0) + } else if (fseek(fp, 0L, SEEK_END) < 0) { error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'", fname); - else { + } else { static char buf[2048]; int32_t t = instruction->times; int32_t base = 0; @@ -694,34 +675,15 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp, char fname[FILENAME_MAX]; FILE *fp; int32_t len; - char *prefix = "", *combine; - char **pPrevPath = NULL; len = FILENAME_MAX - 1; if (len > instruction->eops->stringlen) len = instruction->eops->stringlen; strncpy(fname, instruction->eops->stringval, len); fname[len] = '\0'; - - /* added by alexfru: 'incbin' uses include paths */ - while (1) { - combine = nasm_malloc(strlen(prefix) + len + 1); - strcpy(combine, prefix); - strcat(combine, fname); - - if ((fp = fopen(combine, "rb")) != NULL) { - nasm_free(combine); - break; - } - - nasm_free(combine); - pPrevPath = pp_get_include_path_ptr(pPrevPath); - if (pPrevPath == NULL) - break; - prefix = *pPrevPath; - } - - if (fp == NULL) + + fp = fopen(fname, "rb"); + if (!fp) error(ERR_NONFATAL, "`incbin': unable to open file `%s'", fname); else if (fseek(fp, 0L, SEEK_END) < 0) @@ -930,6 +930,8 @@ int src_get(int32_t *xline, char **xname) return 0; } +/* XXX: This is broken for strings which contain multiple quotes... + NASM doesn't have a sane syntax for dealing with those currently. */ void nasm_quote(char **str) { int ln = strlen(*str); @@ -17,6 +17,7 @@ %assign %clear %define +%depend %elif* %else %endif @@ -34,6 +35,7 @@ %line %local %macro +%pathsearch %pop %push %rep @@ -1276,7 +1276,8 @@ static bool in_list(const StrList *list, const char *str) * the include path one by one until it finds the file or reaches * the end of the path. */ -static FILE *inc_fopen(const char *file) +static FILE *inc_fopen(const char *file, StrList **dhead, StrList **dtail, + bool missing_ok) { FILE *fp; char *prefix = ""; @@ -1290,29 +1291,33 @@ static FILE *inc_fopen(const char *file) memcpy(sl->str, prefix, prefix_len); memcpy(sl->str+prefix_len, file, len+1); fp = fopen(sl->str, "r"); - if (fp && dephead && !in_list(*dephead, sl->str)) { + if (fp && dhead && !in_list(*dhead, sl->str)) { sl->next = NULL; - *deptail = sl; - deptail = &sl->next; + *dtail = sl; + dtail = &sl->next; } else { nasm_free(sl); } if (fp) return fp; - if (!ip) - break; - prefix = ip->path; - ip = ip->next; + if (!ip) { + if (!missing_ok) + break; + prefix = NULL; + } else { + prefix = ip->path; + ip = ip->next; + } if (prefix) { prefix_len = strlen(prefix); } else { /* -MG given and file not found */ - if (dephead && !in_list(*dephead, file)) { + if (dhead && !in_list(*dhead, file)) { sl = nasm_malloc(len+1+sizeof sl->next); sl->next = NULL; strcpy(sl->str, file); - *deptail = sl; - deptail = &sl->next; + *dtail = sl; + dtail = &sl->next; } return NULL; } @@ -1681,7 +1686,9 @@ fail: } /* - * Expand macros in a string. Used in %error and %include directives. + * Expand macros in a string. Used in %error directives (and it should + * almost certainly be removed from there, too.) + * * First tokenize the string, apply "expand_smacro" and then de-tokenize back. * The returned variable should ALWAYS be freed after usage. */ @@ -2060,9 +2067,37 @@ static int do_directive(Token * tline) free_tlist(origline); return DIRECTIVE_FOUND; + case PP_DEPEND: + tline = expand_smacro(tline->next); + skip_white_(tline); + if (!tline || (tline->type != TOK_STRING && + tline->type != TOK_INTERNAL_STRING)) { + error(ERR_NONFATAL, "`%%depend' expects a file name"); + free_tlist(origline); + return DIRECTIVE_FOUND; /* but we did _something_ */ + } + if (tline->next) + error(ERR_WARNING, + "trailing garbage after `%%depend' ignored"); + if (tline->type != TOK_INTERNAL_STRING) { + p = tline->text + 1; /* point past the quote to the name */ + p[strlen(p) - 1] = '\0'; /* remove the trailing quote */ + } else + p = tline->text; /* internal_string is easier */ + if (dephead && !in_list(*dephead, p)) { + StrList *sl = nasm_malloc(strlen(p)+1+sizeof sl->next); + sl->next = NULL; + strcpy(sl->str, p); + *deptail = sl; + deptail = &sl->next; + } + free_tlist(origline); + return DIRECTIVE_FOUND; + case PP_INCLUDE: - tline = expand_smacros(tline->next); + tline = expand_smacro(tline->next); skip_white_(tline); + if (!tline || (tline->type != TOK_STRING && tline->type != TOK_INTERNAL_STRING)) { error(ERR_NONFATAL, "`%%include' expects a file name"); @@ -2080,8 +2115,8 @@ static int do_directive(Token * tline) inc = nasm_malloc(sizeof(Include)); inc->next = istk; inc->conds = NULL; - inc->fp = inc_fopen(p); - if (!inc->fp && pass == 0) { + inc->fp = inc_fopen(p, dephead, deptail, pass == 0); + if (!inc->fp) { /* -MG given but file not found */ nasm_free(inc); } else { @@ -2153,7 +2188,7 @@ static int do_directive(Token * tline) if (tok_type_(tline, TOK_STRING)) { p = tline->text + 1; /* point past the quote to the name */ p[strlen(p) - 1] = '\0'; /* remove the trailing quote */ - expand_macros_in_string(&p); + expand_macros_in_string(&p); error(ERR_NONFATAL, "%s", p); nasm_free(p); } else { @@ -2596,6 +2631,76 @@ static int do_directive(Token * tline) free_tlist(origline); return DIRECTIVE_FOUND; + case PP_PATHSEARCH: + { + FILE *fp; + StrList *xsl = NULL; + + casesense = true; + + tline = tline->next; + skip_white_(tline); + tline = expand_id(tline); + if (!tline || (tline->type != TOK_ID && + (tline->type != TOK_PREPROC_ID || + tline->text[1] != '$'))) { + error(ERR_NONFATAL, + "`%%pathsearch' expects a macro identifier as first parameter"); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + ctx = get_ctx(tline->text, false); + + mname = tline->text; + last = tline; + tline = expand_smacro(tline->next); + last->next = NULL; + + t = tline; + while (tok_type_(t, TOK_WHITESPACE)) + t = t->next; + + if (!t || (t->type != TOK_STRING && + t->type != TOK_INTERNAL_STRING)) { + error(ERR_NONFATAL, "`%%pathsearch' expects a file name"); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; /* but we did _something_ */ + } + if (t->next) + error(ERR_WARNING, + "trailing garbage after `%%pathsearch' ignored"); + if (t->type != TOK_INTERNAL_STRING) { + p = t->text + 1; /* point past the quote to the name */ + p[strlen(p) - 1] = '\0'; /* remove the trailing quote */ + } else + p = t->text; /* internal_string is easier */ + + fp = inc_fopen(p, &xsl, &xsl, true); + if (fp) { + p = xsl->str; + fclose(fp); /* Don't actually care about the file */ + } + macro_start = nasm_malloc(sizeof(*macro_start)); + macro_start->next = NULL; + macro_start->text = nasm_strdup(p); + nasm_quote(¯o_start->text); + macro_start->type = TOK_STRING; + macro_start->mac = NULL; + if (xsl) + nasm_free(xsl); + + /* + * We now have a macro name, an implicit parameter count of + * zero, and a string token to use as an expansion. Create + * and store an SMacro. + */ + define_smacro(ctx, mname, casesense, 0, macro_start); + free_tlist(tline); + free_tlist(origline); + return DIRECTIVE_FOUND; + } + case PP_STRLEN: casesense = true; @@ -4032,55 +4137,6 @@ void pp_include_path(char *path) } } -/* - * added by alexfru: - * - * This function is used to "export" the include paths, e.g. - * the paths specified in the '-I' command switch. - * The need for such exporting is due to the 'incbin' directive, - * which includes raw binary files (unlike '%include', which - * includes text source files). It would be real nice to be - * able to specify paths to search for incbin'ned files also. - * So, this is a simple workaround. - * - * The function use is simple: - * - * The 1st call (with NULL argument) returns a pointer to the 1st path - * (char** type) or NULL if none include paths available. - * - * All subsequent calls take as argument the value returned by this - * function last. The return value is either the next path - * (char** type) or NULL if the end of the paths list is reached. - * - * It is maybe not the best way to do things, but I didn't want - * to export too much, just one or two functions and no types or - * variables exported. - * - * Can't say I like the current situation with e.g. this path list either, - * it seems to be never deallocated after creation... - */ -char **pp_get_include_path_ptr(char **pPrevPath) -{ -/* This macro returns offset of a member of a structure */ -#define GetMemberOffset(StructType,MemberName)\ - ((size_t)&((StructType*)0)->MemberName) - IncPath *i; - - if (pPrevPath == NULL) { - if (ipath != NULL) - return &ipath->path; - else - return NULL; - } - i = (IncPath *) ((char *)pPrevPath - GetMemberOffset(IncPath, path)); - i = i->next; - if (i != NULL) - return &i->path; - else - return NULL; -#undef GetMemberOffset -} - void pp_pre_include(char *fname) { Token *inc, *space, *name; @@ -15,7 +15,6 @@ extern const char * const pp_directives[]; enum preproc_token pp_token_hash(const char *token); void pp_include_path(char *); -char **pp_get_include_path_ptr(char **pPrevPath); void pp_pre_include(char *); void pp_pre_define(char *); void pp_pre_undefine(char *); diff --git a/standard.mac b/standard.mac index 52f1c579..23dcb543 100644 --- a/standard.mac +++ b/standard.mac @@ -141,3 +141,11 @@ __SECT__ %imacro default 1+.nolist [default %1] %endmacro + +%imacro incbin 1-2+.nolist 0 +%push _incbin +%pathsearch %$dep %1 +%depend %$dep + incbin %$dep,%2 +%pop +%endmacro |