X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCutil.c;h=da0223f6f6b67c36715ac3f119ed2a4fefffd4d0;hb=90bdb43b342189fcb94a398855d43f3f47f96738;hp=065d2834c2693d0fcc01c3f4fad25e201454744c;hpb=df203a96d87ea3322e836e3dd980f64b80b234e7;p=fw%2Fsdcc diff --git a/src/SDCCutil.c b/src/SDCCutil.c index 065d2834..da0223f6 100644 --- a/src/SDCCutil.c +++ b/src/SDCCutil.c @@ -22,11 +22,23 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#include "common.h" +#include + +#ifdef _WIN32 +#include +#include +#endif +#include +#include "dbuf.h" +#include "SDCCglobl.h" #include "SDCCmacro.h" #include "SDCCutil.h" #include "newalloc.h" -#include +#ifndef _WIN32 +#include "findme.h" +#endif + +#include "version.h" /** Given an array of name, value string pairs creates a new hash containing all of the pairs. @@ -45,211 +57,124 @@ populateStringHash(const char **pin) return pret; } -/** Given an array of string pointers and another string, adds the - string to the end of the list. The end of the list is assumed to - be the first NULL pointer. +/** Prints elements of the set to the file, each element on new line */ void -addToList (const char **list, const char *str) +fputStrSet(FILE *fp, set *list) { - /* This is the bad way to do things :) */ - while (*list) - list++; - *list = Safe_strdup (str); - if (!*list) - { - werror (E_OUT_OF_MEM, __FILE__, 0); - exit (1); - } - *(++list) = NULL; -} + const char *s; -/** Given an array of string pointers returns a string containing all - of the strings seperated by spaces. The returned string is on the - heap. The join stops when a NULL pointer is hit. -*/ -char * -join(const char **pplist) -{ - buffer[0] = 0; - - while (*pplist) - { - strncatz(buffer, *pplist, PATH_MAX); - strncatz(buffer, " ", PATH_MAX); - pplist++; - } - - return buffer; + for (s = setFirstItem(list); s != NULL; s = setNextItem(list)) { + fputs(s, fp); + fputc('\n', fp); + } } -/** Given an array of string pointers, returns a string containing all - of the strings seperated by spaces. The returned string is on the - heap. n is the number of strings in the list. +/** Prepend / append given strings to each item of string set. The result is in a + new string set. */ -char * -joinn(char **pplist, int n) +set * +appendStrSet(set *list, const char *pre, const char *post) { - buffer[0] = 0; - - while (n--) - { - strncatz(buffer, *pplist, PATH_MAX); - strncatz(buffer, " ", PATH_MAX); - pplist++; - } - - return buffer; + set *new_list = NULL; + const char *item; + struct dbuf_s dbuf; + + for (item = setFirstItem(list); item != NULL; item = setNextItem(list)) { + dbuf_init(&dbuf, PATH_MAX); + if (pre != NULL) + dbuf_append(&dbuf, pre, strlen(pre)); + dbuf_append(&dbuf, item, strlen(item)); + if (post != NULL) + dbuf_append(&dbuf, post, strlen(post)); + addSet(&new_list, (void *)dbuf_c_str(&dbuf)); + dbuf_detach(&dbuf); + } + + return new_list; } -/** Returns TRUE if for the host the two path characters are - equivalent. +/** Given a set returns a string containing all of the strings seperated + by spaces. The returned string is on the heap. */ -static bool -pathCharsEquivalent(char c1, char c2) +const char * +joinStrSet(set *list) { -#if NATIVE_WIN32 - /* win32 is case insensitive */ - if (tolower(c1) == tolower(c2)) - { - return TRUE; - } - /* And / is equivalent to \ */ - else if (c1 == '/' && c2 == '\\') - { - return TRUE; - } - else if (c1 == '\\' && c2 == '/') - { - return TRUE; - } - else - { - return FALSE; - } -#else - /* Assume a Unix host where they must match exactly. */ - return c1 == c2; -#endif -} - -static bool -pathEquivalent(const char *p1, const char *p2) -{ - while (*p1 != '\0' && *p2 != '\0') - { - if (pathCharsEquivalent (*p1, *p2) == FALSE) - { - break; - } - p1++; - p2++; - } + const char *s; + struct dbuf_s dbuf; - return *p1 == *p2; -} + dbuf_init(&dbuf, PATH_MAX); -static char -pathCharTransform(char c) -{ -#if NATIVE_WIN32 - if (c == '/') - { - return DIR_SEPARATOR_CHAR; - } - else + for (s = setFirstItem(list); s != NULL; s = setNextItem(list)) { - return c; + dbuf_append(&dbuf, s, strlen(s)); + dbuf_append(&dbuf, " ", 1); } -#else - return c; -#endif + + s = dbuf_c_str(&dbuf); + dbuf_detach(&dbuf); + return s; } -/** Fixes up a potentially mixed path to the proper representation for - the host. Fixes up in place. +/** Given a file with path information in the binary files directory, + returns the directory component. Used for discovery of bin + directory of SDCC installation. Returns NULL if the path is + impossible. */ -static char * -fixupPath(char *pin) +#ifdef _WIN32 +char * +getBinPath(const char *prel) { - char *p = pin; - - while (*p) - { - *p = pathCharTransform(*p); - p++; - } - *p = '\0'; - - return pin; + char *p; + size_t len; + static char path[PATH_MAX]; + + /* try DOS and *nix dir separator on WIN32 */ + if (NULL != (p = strrchr(prel, DIR_SEPARATOR_CHAR)) || + NULL != (p = strrchr(prel, UNIX_DIR_SEPARATOR_CHAR))) { + len = min((sizeof path) - 1, p - prel); + strncpy(path, prel, len); + path[len] = '\0'; + return path; + } + /* not enough info in prel; do it with module name */ + else if (0 != GetModuleFileName(NULL, path, sizeof path) && + NULL != (p = strrchr(path, DIR_SEPARATOR_CHAR))) { + *p = '\0'; + return path; + } + else + return NULL; } - -/** Returns the characters in p2 past the last matching characters in - p1. -*/ +#else char * -getPathDifference (char *pinto, const char *p1, const char *p2) +getBinPath(const char *prel) { - char *p = pinto; + static char path[PATH_MAX]; + const char *ret_path; -#if NATIVE_WIN32 - /* win32 can have a path at the start. */ - if (strchr(p2, ':')) - { - p2 = strchr(p2, ':')+1; - } -#endif + if (NULL != (ret_path = findProgramPath(prel))) { + char *p; + size_t len; - while (*p1 != '\0' && *p2 != '\0') - { - if (pathCharsEquivalent(*p1, *p2) == FALSE) - { - break; - } - p1++; - p2++; - } - while (*p2) - { - *p++ = *p2++; - } - *p = '\0'; - - return fixupPath(pinto); -} + if (NULL != (p = strrchr(ret_path, DIR_SEPARATOR_CHAR)) && + PATH_MAX > (len = p - ret_path)) { + memcpy(path, ret_path, len); + path[len] = '\0'; + free((void *)ret_path); -/** Given a file with path information in the binary files directory, - returns what PREFIX must be to get this path. Used for discovery - of where SDCC is installed. Returns NULL if the path is - impossible. -*/ -char * -getPrefixFromBinPath (const char *prel) -{ - strncpyz(scratchFileName, prel, PATH_MAX); - /* Strip off the /sdcc at the end */ - *strrchr(scratchFileName, DIR_SEPARATOR_CHAR) = '\0'; - /* Compute what the difference between the prefix and the bin dir - should be. */ - getPathDifference (buffer, PREFIX, BINDIR); - - /* Verify that the path in has the expected suffix */ - if (strlen(buffer) > strlen(scratchFileName)) - { - /* Not long enough */ - return NULL; + return path; } + else { + free((void *)ret_path); - if (pathEquivalent (buffer, scratchFileName + strlen(scratchFileName) - strlen(buffer)) == FALSE) - { - /* Doesn't match */ return NULL; } - - scratchFileName[strlen(scratchFileName) - strlen(buffer)] = '\0'; - - return Safe_strdup (scratchFileName); + } + else + return NULL; } +#endif /** Returns true if the given path exists. */ @@ -267,20 +192,27 @@ void setMainValue (const char *pname, const char *pvalue) { assert(pname); - assert(pvalue); shash_add (&_mainValues, pname, pvalue); } void -buildCmdLine2 (char *pbuffer, const char *pcmd, size_t len) +buildCmdLine2 (char *pbuffer, size_t len, const char *pcmd, ...) { + va_list ap; char *poutcmd; + assert(pbuffer && pcmd); assert(_mainValues); - poutcmd = msprintf(_mainValues, pcmd); + va_start(ap, pcmd); + + poutcmd = mvsprintf(_mainValues, pcmd, ap); + + va_end(ap); + strncpyz(pbuffer, poutcmd, len); + Safe_free(poutcmd); } void @@ -319,15 +251,16 @@ getRuntimeVariables(void) char *strncpyz(char *dest, const char *src, size_t n) { assert(n > 0); - - // paranoia... - if (strlen(src) >= n) + + --n; + /* paranoia... */ + if (strlen(src) > n) { fprintf(stderr, "strncpyz prevented buffer overrun!\n"); } strncpy(dest, src, n); - dest[n - 1] = 0; + dest[n] = 0; return dest; } @@ -345,7 +278,7 @@ char *strncatz(char *dest, const char *src, size_t n) maxToCopy = n - destLen - 1; - // paranoia... + /* paranoia... */ if (strlen(src) + destLen >= n) { fprintf(stderr, "strncatz prevented buffer overrun!\n"); @@ -357,32 +290,40 @@ char *strncatz(char *dest, const char *src, size_t n) } -#if defined(HAVE_VSNPRINTF) || defined(have_VSPRINTF) +/*-----------------------------------------------------------------*/ +/* getBuildNumber - return build number */ +/*-----------------------------------------------------------------*/ +const char *getBuildNumber(void) +{ + return (SDCC_BUILD_NUMBER); +} + +#if defined(HAVE_VSNPRINTF) || defined(HAVE_VSPRINTF) size_t SDCCsnprintf(char *dst, size_t n, const char *fmt, ...) { - va_list args; - int len; - - va_start(args, fmt); - -# if defined(HAVE_VSNPRINTF) - len = vsnprintf(dst, n, fmt, args); + va_list args; + int len; + + va_start(args, fmt); + +# if defined(HAVE_VSNPRINTF) + len = vsnprintf(dst, n, fmt, args); # else - vsprintf(dst, fmt, args); - len = strlen(dst) + 1; -# endif - - va_end(args); - - /* on some gnu systems, vsnprintf returns -1 if output is truncated. - * In the C99 spec, vsnprintf returns the number of characters that - * would have been written, were space available. - */ - if ((len < 0) || len >= n) - { - fprintf(stderr, "internal error: sprintf truncated.\n"); - } - return len; + vsprintf(dst, fmt, args); + len = strlen(dst) + 1; +# endif + + va_end(args); + + /* on some gnu systems, vsnprintf returns -1 if output is truncated. + * In the C99 spec, vsnprintf returns the number of characters that + * would have been written, were space available. + */ + if ((len < 0) || (size_t) len >= n) { + fprintf(stderr, "internal error: sprintf truncated.\n"); + } + + return len; } #endif