From: borutr Date: Sun, 30 Mar 2003 19:47:28 +0000 (+0000) Subject: handling macros with empty or NULL values in _evalMacros() X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=0ce8efe26f679dbe937404c4023993fc9a0e044e;p=fw%2Fsdcc handling macros with empty or NULL values in _evalMacros() git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2443 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/src/SDCCmacro.c b/src/SDCCmacro.c index 2502b04e..9e0d87c0 100644 --- a/src/SDCCmacro.c +++ b/src/SDCCmacro.c @@ -26,7 +26,7 @@ enum { - MAX_STRING_LENGTH = 2048, + MAX_STRING_LENGTH = 2048, MAX_MACRO_NAME_LENGTH = 128 }; @@ -36,77 +36,104 @@ _evalMacros(char *apinto, hTab *pvals, const char *pfrom, size_t alen) bool fdidsomething = FALSE; char *pinto = apinto; size_t plen = alen; + char quote = '\0'; assert(pinto); assert(pvals); assert(pfrom); - while (plen && *pfrom) - { - if (*pfrom == '{') - { - const char *pend = ++pfrom; - char name[MAX_MACRO_NAME_LENGTH]; - const char *pval; + while (plen && *pfrom) { + switch (*pfrom) { + case '"': + case '\'': + quote = *pfrom; + ++pfrom; + break; + + case '{': + { + const char *pend = ++pfrom; + char name[MAX_MACRO_NAME_LENGTH]; + const char *pval; + + /* Find the end of macro */ + while (*pend && *pend != '}') { + pend++; + } + if (*pend != '}') { + wassertl(0, "Unterminated macro expansion"); + } - while (*pend && *pend != '}') - { - pend++; - } - if (*pend != '}') - { - wassertl(0, "Unterminated macro expansion"); + /* Pull out the macro name */ + if (pend - pfrom >= MAX_MACRO_NAME_LENGTH) { + wassertl(0, "macro name too long"); + } + + strncpy(name, pfrom, pend-pfrom); + name[pend-pfrom] = '\0'; + + /* Look up the value in the hash table */ + pval = shash_find (pvals, name); + + if (pval == NULL) { + /* Empty macro value */ + if (quote != '\0') { + /* It was a quote */ + if (pend[1] == quote) { + /* Start quote equals end quote: skip both */ + ++pend; } - /* Pull out the macro name */ - if (pend - pfrom >= MAX_MACRO_NAME_LENGTH) - { - wassertl(0, "macro name too long"); - } - - strncpy(name, pfrom, pend-pfrom); - name[pend-pfrom] = '\0'; - - /* Look up the value in the hash table */ - pval = shash_find (pvals, name); - - if (pval == NULL) - { - fprintf (stderr, "Cant find macro \"%s\"\n", name); - wassertl (0, "Invalid macro name"); + else { + /* Start quote not equals end quote: add both */ + *pinto++ = quote; + --plen; } - else - { - /* Replace */ - strncpy(pinto, pval, plen); - pinto += strlen(pval); - plen -= plen > strlen(pval) ? strlen(pval) : plen; - fdidsomething = TRUE; - } - - pfrom = pend+1; + } } - else - { - /* Pass through */ - *pinto++ = *pfrom++; - plen--; + else { + if (quote != '\0') { + /* It was a quote, add it */ + *pinto++ = quote; + } + if (--plen > 0) { + /* Replace macro*/ + strncpy(pinto, pval, plen); + pinto += strlen(pval); + plen -= plen > strlen(pval) ? strlen(pval) : plen; + fdidsomething = TRUE; + } } + + pfrom = pend + 1; + } + break; + + default: + if (quote != '\0') { + *pinto++ = quote; + quote = '\0'; + } + + if (--plen > 0) { + /* Pass through */ + *pinto++ = *pfrom++; + --plen; + } } + } - if (!plen) - { - wassertl(0, "macro expansion too long"); + if (!plen) { + wassertl(0, "macro expansion too long"); } *pinto = '\0'; /* If we did something then recursivly expand any expanded macros */ - if (fdidsomething) - { - char ainto[MAX_STRING_LENGTH]; - _evalMacros(ainto, pvals, apinto, MAX_STRING_LENGTH); - strncpyz(apinto, ainto, alen); - } + if (fdidsomething) { + char ainto[MAX_STRING_LENGTH]; + _evalMacros(ainto, pvals, apinto, MAX_STRING_LENGTH); + strncpyz(apinto, ainto, alen); + } } char * @@ -121,18 +148,18 @@ mvsprintf(hTab *pvals, const char *pformat, va_list ap) #if defined(HAVE_VSNPRINTF) if (vsnprintf(atmp, MAX_STRING_LENGTH, ainto, ap) >= MAX_STRING_LENGTH) { - fprintf(stderr, "Internal error: mvsprintf output truncated.\n"); + fprintf(stderr, "Internal error: mvsprintf output truncated.\n"); } #else - { - int wlen; - - wlen = vsprintf(atmp, ainto, ap); - - if (wlen < 0 || wlen >= MAX_STRING_LENGTH) - { - wassertl(0, "mvsprintf overflowed."); - } + { + int wlen; + + wlen = vsprintf(atmp, ainto, ap); + + if (wlen < 0 || wlen >= MAX_STRING_LENGTH) + { + wassertl(0, "mvsprintf overflowed."); + } } #endif