diff --git a/Makefile b/Makefile index b90d0875..bc4d0225 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,9 @@ rgbasm_obj := \ src/asm/output.o \ src/asm/rpn.o \ src/asm/symbol.o \ - src/asm/gameboy/locallex.o + src/asm/gameboy/locallex.o \ + src/extern/strlcpy.o \ + src/extern/strlcat.o rgblib_obj := \ src/lib/library.o \ diff --git a/include/asm/fstack.h b/include/asm/fstack.h index 9978a3e2..c3ca1ef0 100644 --- a/include/asm/fstack.h +++ b/include/asm/fstack.h @@ -9,6 +9,8 @@ #ifndef ASMOTOR_ASM_FSTACK_H #define ASMOTOR_ASM_FSTACK_H +#include + #include "asm/asm.h" #include "asm/types.h" #include "asm/lexer.h" @@ -27,14 +29,17 @@ struct sContext { ULONG nREPTBlockSize; }; -extern ULONG fstk_RunInclude(char *s); +void +fstk_RunInclude(char *); extern void fstk_RunMacroArg(SLONG s); -extern ULONG fstk_Init(char *s); +void +fstk_Init(char *); extern void fstk_Dump(void); extern void fstk_AddIncludePath(char *s); extern ULONG fstk_RunMacro(char *s); extern void fstk_RunRept(ULONG count); -extern void fstk_FindFile(char *s); +FILE * +fstk_FindFile(char *); extern int yywrap(void); diff --git a/src/asm/fstack.c b/src/asm/fstack.c index b7c3d489..8fe3b1ee 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -5,10 +5,19 @@ * */ +#include +#include #include #include #include +#ifndef STRL_IN_LIBC +#define strlcpy rgbds_strlcpy +#define strlcat rgbds_strlcat +size_t strlcpy(char *, const char *, size_t); +size_t strlcat(char *, const char *, size_t); +#endif + #include "asm/symbol.h" #include "asm/fstack.h" #include "asm/types.h" @@ -195,28 +204,33 @@ fstk_AddIncludePath(char *s) strcpy(IncludePaths[NextIncPath++], s); } -void -fstk_FindFile(char *s) +FILE * +fstk_FindFile(char *fname) { - char t[_MAX_PATH + 1]; - SLONG i = -1; + char path[PATH_MAX]; + int i; + FILE *f; - strcpy(t, s); + if ((f = fopen(fname, "rb")) != NULL || errno != ENOENT) { + return f; + } - while (i < NextIncPath) { - FILE *f; - - if ((f = fopen(t, "rb")) != NULL) { - fclose(f); - strcpy(s, t); - return; + for (i = 0; i < NextIncPath; ++i) { + if (strlcpy(path, IncludePaths[i], sizeof path) >= + sizeof path) { + continue; } - i += 1; - if (i < NextIncPath) { - strcpy(t, IncludePaths[i]); - strcat(t, s); + if (strlcat(path, fname, sizeof path) >= sizeof path) { + continue; + } + + if ((f = fopen(path, "rb")) != NULL || errno != ENOENT) { + return f; } } + + errno = ENOENT; + return NULL; } /* * RGBAsm - FSTACK.C (FileStack routines) @@ -225,33 +239,32 @@ fstk_FindFile(char *s) * */ -ULONG +void fstk_RunInclude(char *tzFileName) { FILE *f; - //printf("INCLUDE: %s\n", s); + f = fstk_FindFile(tzFileName); - fstk_FindFile(tzFileName); - //printf("INCLUDING: %s\n", tzFileName); + if (f == NULL) { + fprintf(stderr, "Unable to open included file '%s': ", + tzFileName); + perror(NULL); + exit(1); + } - if ((f = fopen(tzFileName, "r")) != NULL) { - pushcontext(); - nLineNo = 1; - nCurrentStatus = STAT_isInclude; - strcpy(tzCurrentFileName, tzFileName); - pCurrentFile = f; - CurrentFlexHandle = yy_create_buffer(pCurrentFile); - yy_switch_to_buffer(CurrentFlexHandle); + pushcontext(); + nLineNo = 1; + nCurrentStatus = STAT_isInclude; + strcpy(tzCurrentFileName, tzFileName); + pCurrentFile = f; + CurrentFlexHandle = yy_create_buffer(pCurrentFile); + yy_switch_to_buffer(CurrentFlexHandle); - //Dirty hack to give the INCLUDE directive a linefeed + //Dirty hack to give the INCLUDE directive a linefeed - yyunput('\n'); - nLineNo -= 1; - - return (1); - } else - return (0); + yyunput('\n'); + nLineNo -= 1; } /* * RGBAsm - FSTACK.C (FileStack routines) @@ -360,7 +373,7 @@ fstk_RunRept(ULONG count) * */ -ULONG +void fstk_Init(char *s) { char tzFileName[_MAX_PATH + 1]; @@ -368,17 +381,19 @@ fstk_Init(char *s) sym_AddString("__FILE__", s); strcpy(tzFileName, s); - fstk_FindFile(tzFileName); - pFileStack = NULL; - if ((pCurrentFile = fopen(tzFileName, "r")) != NULL) { - nMacroCount = 0; - nCurrentStatus = STAT_isInclude; - strcpy(tzCurrentFileName, tzFileName); - CurrentFlexHandle = yy_create_buffer(pCurrentFile); - yy_switch_to_buffer(CurrentFlexHandle); - nLineNo = 1; - return (1); - } else - return (0); + pCurrentFile = fopen(tzFileName, "rb"); + if (pCurrentFile == NULL) { + fprintf(stderr, "Unable to open file '%s': ", + tzFileName); + perror(NULL); + exit(1); + } + + nMacroCount = 0; + nCurrentStatus = STAT_isInclude; + strcpy(tzCurrentFileName, tzFileName); + CurrentFlexHandle = yy_create_buffer(pCurrentFile); + yy_switch_to_buffer(CurrentFlexHandle); + nLineNo = 1; } diff --git a/src/asm/main.c b/src/asm/main.c index 46194cfd..f5d14439 100644 --- a/src/asm/main.c +++ b/src/asm/main.c @@ -348,7 +348,6 @@ main(int argc, char *argv[]) DefaultOptions = CurrentOptions; - /* tzMainfile=argv[argn++]; argc-=1; */ tzMainfile = argv[argc - 1]; setuplex(); @@ -366,75 +365,71 @@ main(int argc, char *argv[]) nPass = 1; nErrors = 0; sym_PrepPass1(); - if (fstk_Init(tzMainfile)) { - if (CurrentOptions.verbose) { - printf("Pass 1...\n"); - } + fstk_Init(tzMainfile); + if (CurrentOptions.verbose) { + printf("Pass 1...\n"); + } - yy_set_state(LEX_STATE_NORMAL); - opt_SetCurrentOptions(&DefaultOptions); + yy_set_state(LEX_STATE_NORMAL); + opt_SetCurrentOptions(&DefaultOptions); - if (yyparse() == 0 && nErrors == 0) { - if (nIFDepth == 0) { - nTotalLines = 0; - nLineNo = 1; - nIFDepth = 0; - nPC = 0; - nPass = 2; - nErrors = 0; - sym_PrepPass2(); - out_PrepPass2(); - fstk_Init(tzMainfile); - yy_set_state(LEX_STATE_NORMAL); - opt_SetCurrentOptions(&DefaultOptions); + if (yyparse() == 0 && nErrors == 0) { + if (nIFDepth == 0) { + nTotalLines = 0; + nLineNo = 1; + nIFDepth = 0; + nPC = 0; + nPass = 2; + nErrors = 0; + sym_PrepPass2(); + out_PrepPass2(); + fstk_Init(tzMainfile); + yy_set_state(LEX_STATE_NORMAL); + opt_SetCurrentOptions(&DefaultOptions); + if (CurrentOptions.verbose) { + printf("Pass 2...\n"); + } + + if (yyparse() == 0 && nErrors == 0) { + double timespent; + + nEndClock = clock(); + timespent = + ((double) (nEndClock - nStartClock)) + / (double) CLOCKS_PER_SEC; if (CurrentOptions.verbose) { - printf("Pass 2...\n"); - } - - if (yyparse() == 0 && nErrors == 0) { - double timespent; - - nEndClock = clock(); - timespent = - ((double) (nEndClock - nStartClock)) - / (double) CLOCKS_PER_SEC; - if (CurrentOptions.verbose) { - printf - ("Success! %ld lines in %d.%02d seconds ", - nTotalLines, (int) timespent, - ((int) (timespent * 100.0)) % 100); - if (timespent == 0) - printf - ("(INFINITY lines/minute)\n"); - else - printf("(%d lines/minute)\n", - (int) (60 / timespent * - nTotalLines)); - } - out_WriteObject(); - } else { printf - ("Assembly aborted in pass 2 (%ld errors)!\n", - nErrors); - //sym_PrintSymbolTable(); - exit(5); + ("Success! %ld lines in %d.%02d seconds ", + nTotalLines, (int) timespent, + ((int) (timespent * 100.0)) % 100); + if (timespent == 0) + printf + ("(INFINITY lines/minute)\n"); + else + printf("(%d lines/minute)\n", + (int) (60 / timespent * + nTotalLines)); } + out_WriteObject(); } else { - fprintf(stderr, - "Unterminated IF construct (%ld levels)!\n", - nIFDepth); - exit(1); + printf + ("Assembly aborted in pass 2 (%ld errors)!\n", + nErrors); + //sym_PrintSymbolTable(); + exit(5); } } else { fprintf(stderr, - "Assembly aborted in pass 1 (%ld errors)!\n", - nErrors); + "Unterminated IF construct (%ld levels)!\n", + nIFDepth); exit(1); } } else { - printf("File '%s' not found\n", tzMainfile); - exit(5); + fprintf(stderr, + "Assembly aborted in pass 1 (%ld errors)!\n", + nErrors); + exit(1); } - return (0); + return 0; } diff --git a/src/asm/output.c b/src/asm/output.c index fe075cee..c60919d4 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -907,30 +907,33 @@ out_BinaryFile(char *s) { FILE *f; - fstk_FindFile(s); + f = fstk_FindFile(s); + if (f == NULL) { + fprintf(stderr, "Unable to open incbin file '%s': ", + s); + perror(NULL); + exit(1); + } - if ((f = fopen(s, "rb")) != NULL) { - SLONG fsize; + SLONG fsize; - fseek(f, 0, SEEK_END); - fsize = ftell(f); - fseek(f, 0, SEEK_SET); + fseek(f, 0, SEEK_END); + fsize = ftell(f); + fseek(f, 0, SEEK_SET); - checkcodesection(fsize); + checkcodesection(fsize); - if (nPass == 2) { - SLONG dest = nPC; - SLONG todo = fsize; + if (nPass == 2) { + SLONG dest = nPC; + SLONG todo = fsize; - while (todo--) - pCurrentSection->tData[dest++] = fgetc(f); - } - pCurrentSection->nPC += fsize; - nPC += fsize; - pPCSymbol->nValue += fsize; - fclose(f); - } else - fatalerror("Could not open file '%s': %s", s, strerror(errno)); + while (todo--) + pCurrentSection->tData[dest++] = fgetc(f); + } + pCurrentSection->nPC += fsize; + nPC += fsize; + pPCSymbol->nValue += fsize; + fclose(f); } void @@ -944,36 +947,39 @@ out_BinaryFileSlice(char *s, SLONG start_pos, SLONG length) if (length < 0) fatalerror("Number of bytes to read must be greater than zero"); - fstk_FindFile(s); + f = fstk_FindFile(s); + if (f == NULL) { + fprintf(stderr, "Unable to open included file '%s': ", + s); + perror(NULL); + exit(1); + } - if ((f = fopen(s, "rb")) != NULL) { - SLONG fsize; + SLONG fsize; - fseek(f, 0, SEEK_END); - fsize = ftell(f); + fseek(f, 0, SEEK_END); + fsize = ftell(f); - if (start_pos >= fsize) - fatalerror("Specified start position is greater than length of file"); + if (start_pos >= fsize) + fatalerror("Specified start position is greater than length of file"); - if ((start_pos + length) > fsize) - fatalerror("Specified range in INCBIN is out of bounds"); + if ((start_pos + length) > fsize) + fatalerror("Specified range in INCBIN is out of bounds"); - fseek(f, start_pos, SEEK_SET); + fseek(f, start_pos, SEEK_SET); - checkcodesection(length); + checkcodesection(length); - if (nPass == 2) { - SLONG dest = nPC; - SLONG todo = length; + if (nPass == 2) { + SLONG dest = nPC; + SLONG todo = length; - while (todo--) - pCurrentSection->tData[dest++] = fgetc(f); - } - pCurrentSection->nPC += length; - nPC += length; - pPCSymbol->nValue += length; + while (todo--) + pCurrentSection->tData[dest++] = fgetc(f); + } + pCurrentSection->nPC += length; + nPC += length; + pPCSymbol->nValue += length; - fclose(f); - } else - fatalerror("Could not open file '%s': %s", s, strerror(errno)); + fclose(f); } diff --git a/src/asm/yaccprt3.y b/src/asm/yaccprt3.y index f0a50a90..48c3c996 100644 --- a/src/asm/yaccprt3.y +++ b/src/asm/yaccprt3.y @@ -265,10 +265,7 @@ set : T_LABEL T_POP_SET const include : T_POP_INCLUDE string { - if( !fstk_RunInclude($2) ) - { - yyerror("Could not open file '%s' : %s\n", $2, strerror(errno)); - } + fstk_RunInclude($2); } ; diff --git a/src/extern/strlcat.c b/src/extern/strlcat.c new file mode 100644 index 00000000..ca202404 --- /dev/null +++ b/src/extern/strlcat.c @@ -0,0 +1,55 @@ +/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +rgbds_strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff --git a/src/extern/strlcpy.c b/src/extern/strlcpy.c new file mode 100644 index 00000000..f20c00c2 --- /dev/null +++ b/src/extern/strlcpy.c @@ -0,0 +1,51 @@ +/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +rgbds_strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +}