X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fasm.c;h=1ab5c5275e169fb8296d0fb85216eadc8dd70684;hb=db452f31f22e0f21c1da062d228355aefdb5dede;hp=325b28a9f60c7c434e27f0d912e71249645cc10b;hpb=b1f9b010e519cb7319310c975755d3014534254f;p=fw%2Fsdcc diff --git a/src/asm.c b/src/asm.c index 325b28a9..1ab5c527 100644 --- a/src/asm.c +++ b/src/asm.c @@ -9,6 +9,15 @@ #include "common.h" #include "asm.h" +#ifdef _WIN32 + // for O_BINARY in _pipe() +# include +# include +#else + // for pipe and close +# include +#endif + /* A 'token' is like !blah or %24f and is under the programmers control. */ #define MAX_TOKEN_LEN 64 @@ -45,15 +54,16 @@ _findMapping (const char *szKey) // Append a string onto another, and update the pointer to the end of // the new string. static char * -_appendAt (char *at, char *onto, const char *sz) +_appendAt (char *at, char *onto, const char *sz, size_t *max) { wassert (at && onto && sz); - strcpy (at, sz); - return at + strlen (sz); + strncpyz (at, sz, *max); + *max -= strlen (at); + return at + strlen (at); } void -tvsprintf (char *buffer, const char *format, va_list ap) +tvsprintf (char *buffer, size_t len, const char *format, va_list ap) { // Under Linux PPC va_list is a structure instead of a primitive type, // and doesnt like being passed around. This version turns everything @@ -66,19 +76,20 @@ tvsprintf (char *buffer, const char *format, va_list ap) // This is acheived by expanding the tokens and zero arg formats into // one big format string, which is passed to the native printf. - static int count; - char noTokens[INITIAL_INLINEASM]; - char newFormat[INITIAL_INLINEASM]; - char *pInto = noTokens; - char *p; - char token[MAX_TOKEN_LEN]; - const char *sz = format; + static int count; + char noTokens[INITIAL_INLINEASM]; + char newFormat[INITIAL_INLINEASM]; + char *pInto = noTokens; + size_t pIntoLen = sizeof(noTokens); + char *p; + char token[MAX_TOKEN_LEN]; + const char *sz = format; // NULL terminate it to let strlen work. *pInto = '\0'; /* First pass: expand all of the macros */ - while (*sz) + while (pIntoLen && *sz) { if (*sz == '!') { @@ -95,7 +106,7 @@ tvsprintf (char *buffer, const char *format, va_list ap) /* Now find the token in the token list */ if ((t = _findMapping (token))) { - pInto = _appendAt (pInto, noTokens, t); + pInto = _appendAt (pInto, noTokens, t, &pIntoLen); } else { @@ -106,16 +117,25 @@ tvsprintf (char *buffer, const char *format, va_list ap) else { *pInto++ = *sz++; + pIntoLen--; } } + if (!pIntoLen) + { + fprintf(stderr, + "Internal error: tvsprintf overflowed on pass one.\n"); + // Might as well go on... + } + *pInto = '\0'; /* Second pass: Expand any macros that we own */ sz = noTokens; pInto = newFormat; + pIntoLen = sizeof(newFormat); - while (*sz) + while (pIntoLen && *sz) { if (*sz == '%') { @@ -125,48 +145,79 @@ tvsprintf (char *buffer, const char *format, va_list ap) { case 'C': // Code segment name. - pInto = _appendAt (pInto, newFormat, CODE_NAME); + pInto = _appendAt (pInto, newFormat, CODE_NAME, &pIntoLen); sz++; break; case 'F': // Source file name. - pInto = _appendAt (pInto, newFormat, srcFileName); + pInto = _appendAt (pInto, newFormat, fullSrcFileName, &pIntoLen); sz++; break; case 'N': // Current function name. - pInto = _appendAt (pInto, newFormat, currFunc->rname); + pInto = _appendAt (pInto, newFormat, currFunc->rname, &pIntoLen); sz++; break; case 'I': { // Unique ID. char id[20]; - sprintf (id, "%u", ++count); - pInto = _appendAt (pInto, newFormat, id); + SNPRINTF (id, sizeof(id), "%u", ++count); + pInto = _appendAt (pInto, newFormat, id, &pIntoLen); sz++; break; } default: // Not one of ours. Copy until the end. *pInto++ = '%'; - while (!isalpha (*sz)) + pIntoLen--; + while (pIntoLen && !isalpha (*sz)) { *pInto++ = *sz++; + pIntoLen--; + } + if (pIntoLen) + { + *pInto++ = *sz++; + pIntoLen--; } - *pInto++ = *sz++; } } else { *pInto++ = *sz++; + pIntoLen--; } } + if (!pIntoLen) + { + fprintf(stderr, + "Internal error: tvsprintf overflowed on pass two.\n"); + // Might as well go on... + } + *pInto = '\0'; // Now do the actual printing - vsprintf (buffer, newFormat, ap); +#if defined(HAVE_VSNPRINTF) + { + int wrlen; + wrlen = vsnprintf (buffer, len, newFormat, ap); + + if (wrlen < 0 || wrlen >= len) + { + fprintf(stderr, "Internal error: tvsprintf truncated.\n"); + } + } + +#else + vsprintf (buffer, newFormat, ap); + if (strlen(buffer) >= len) + { + fprintf(stderr, "Internal error: tvsprintf overflowed.\n"); + } +#endif } void @@ -176,16 +227,18 @@ tfprintf (FILE * fp, const char *szFormat,...) char buffer[INITIAL_INLINEASM]; va_start (ap, szFormat); - tvsprintf (buffer, szFormat, ap); + tvsprintf (buffer, INITIAL_INLINEASM, szFormat, ap); + va_end(ap); fputs (buffer, fp); } void -tsprintf (char *buffer, const char *szFormat,...) +tsprintf (char *buffer, size_t len, const char *szFormat,...) { va_list ap; va_start (ap, szFormat); - tvsprintf (buffer, szFormat, ap); + tvsprintf (buffer, len, szFormat, ap); + va_end(ap); } void @@ -204,21 +257,70 @@ asm_addTree (const ASM_MAPPINGS * pMappings) } /*-----------------------------------------------------------------*/ -/* printCLine - try to find the c-code for this lineno */ +/* printILine - return the readable i-code for this ic */ +/* */ +/* iCodePrint wants a file stream so we need a pipe to fool it */ +/*-----------------------------------------------------------------*/ +static char verbalICode[1024]; + +char *printILine (iCode *ic) { + int filedes[2]; + FILE *pipeStream; + iCodeTable *icTab=getTableEntry(ic->op); + int res; + +#ifdef _WIN32 + res = _pipe(filedes, 256, O_BINARY); +#else + res = pipe(filedes); +#endif + assert(res != -1); // forget it + if (res == -1) + return ""; // return empty line if pipe creation failed + + // stuff the pipe with the readable icode + pipeStream=fdopen(filedes[1],"w"); + icTab->iCodePrint(pipeStream, ic, icTab->printName); + // it really needs an extra push + fflush(pipeStream); + // now swallow it + pipeStream=fdopen(filedes[0],"r"); + fgets(verbalICode, sizeof(verbalICode), pipeStream); + // clean up the mess, we'll return here for all icodes!! + assert(!close (filedes[0])); + assert(!close (filedes[1])); + // kill the trailing NL + verbalICode[strlen(verbalICode)-1]='\0'; + // and throw it up + return verbalICode; +} + +/*-----------------------------------------------------------------*/ +/* printCLine - return the c-code for this lineno */ /*-----------------------------------------------------------------*/ static FILE *inFile=NULL; static char inLineString[1024]; static int inLineNo=0; +static char lastSrcFile[PATH_MAX]; int rewinds=0; char *printCLine (char *srcFile, int lineno) { char *ilsP=inLineString; + + if (inFile) { + if (strcmp (lastSrcFile, srcFile) != 0) { + fclose (inFile); + inFile = NULL; + inLineNo = 0; + } + } if (!inFile) { inFile=fopen(srcFile, "r"); if (!inFile) { perror ("printCLine"); exit (1); } + strncpyz (lastSrcFile, srcFile, PATH_MAX); } if (lineno%s"},