X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCutil.c;h=a08cd115abe74ce9aea81c81de8c9e013cd6d361;hb=bb939d05cb3f6e3e8f8d5cb10a63b8d48e07a085;hp=3cd6a0c8b8c7b9c515444c6f23b1ad794bd33f92;hpb=72cf40557bdf2e62a452a851d2ba115149b57ba3;p=fw%2Fsdcc diff --git a/src/SDCCutil.c b/src/SDCCutil.c index 3cd6a0c8..a08cd115 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,169 +57,71 @@ 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) -{ - /* 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; -} - -/** 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; -} - -/** 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. -*/ -char * -joinn(char **pplist, int n) -{ - buffer[0] = 0; - - while (n--) - { - strncatz(buffer, *pplist, PATH_MAX); - strncatz(buffer, " ", PATH_MAX); - pplist++; - } - - return buffer; -} - -/** Returns TRUE if for the host the two path characters are - equivalent. -*/ -static bool -pathCharsEquivalent(char c1, char c2) +fputStrSet(FILE *fp, 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 -} + const char *s; -static char -pathCharTransform(char c) -{ -#if NATIVE_WIN32 - if (c == '/') - { - return DIR_SEPARATOR_CHAR; - } - else - { - return c; - } -#else - return c; -#endif + for (s = setFirstItem(list); s != NULL; s = setNextItem(list)) { + fputs(s, fp); + fputc('\n', fp); + } } -/** Fixes up a potentially mixed path to the proper representation for - the host. Fixes up in place. +/** Prepend / append given strings to each item of string set. The result is in a + new string set. */ -static char * -fixupPath(char *pin) +set * +appendStrSet(set *list, const char *pre, const char *post) { - char *p = pin; - - while (*p) - { - *p = pathCharTransform(*p); - p++; - } - *p = '\0'; + 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 pin; + return new_list; } -/** Returns the characters in p2 past the last matching characters in - p1. +/** Given a set returns a string containing all of the strings seperated + by spaces. The returned string is on the heap. */ -char * -getPathDifference (char *pinto, const char *p1, const char *p2) +const char * +joinStrSet(set *list) { - char *p = pinto; + const char *s; + struct dbuf_s dbuf; -#if NATIVE_WIN32 - /* win32 can have a path at the start. */ - if (strchr(p2, ':')) - { - p2 = strchr(p2, ':')+1; - } -#endif + dbuf_init(&dbuf, PATH_MAX); - while (*p1 != '\0' && *p2 != '\0') - { - if (pathCharsEquivalent(*p1, *p2) == FALSE) - { - break; - } - p1++; - p2++; - } - while (*p2) + for (s = setFirstItem(list); s != NULL; s = setNextItem(list)) { - *p++ = *p2++; + dbuf_append(&dbuf, s, strlen(s)); + dbuf_append(&dbuf, " ", 1); } - *p = '\0'; - return fixupPath(pinto); + s = dbuf_c_str(&dbuf); + dbuf_detach(&dbuf); + return s; } - /** 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. */ +#ifdef _WIN32 char * getBinPath(const char *prel) { @@ -215,20 +129,52 @@ getBinPath(const char *prel) size_t len; static char path[PATH_MAX]; - if ((p = strrchr(prel, DIR_SEPARATOR_CHAR)) == NULL) -#ifdef _WIN32 - /* try *nix dir separator on WIN32 */ - if ((p = strrchr(prel, UNIX_DIR_SEPARATOR_CHAR)) == NULL) -#endif - return NULL; + /* 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; +} +#else +char * +getBinPath(const char *prel) +{ + static char path[PATH_MAX]; + const char *ret_path; - len = min((sizeof path) - 1, p - prel); - strncpy(path, prel, len); - path[len] = '\0'; + if (NULL != (ret_path = findProgramPath(prel))) { + char *p; + size_t len; - return path; -} + 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); + + return path; + } + else { + free((void *)ret_path); + return NULL; + } + } + else + return NULL; +} +#endif /** Returns true if the given path exists. */ @@ -251,14 +197,22 @@ setMainValue (const char *pname, const char *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 @@ -299,7 +253,7 @@ char *strncpyz(char *dest, const char *src, size_t n) assert(n > 0); --n; - // paranoia... + /* paranoia... */ if (strlen(src) > n) { fprintf(stderr, "strncpyz prevented buffer overrun!\n"); @@ -324,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"); @@ -336,6 +290,65 @@ char *strncatz(char *dest, const char *src, size_t n) } +/*-----------------------------------------------------------------*/ +/* getBuildNumber - return build number */ +/*-----------------------------------------------------------------*/ +const char *getBuildNumber(void) +{ + return (SDCC_BUILD_NUMBER); +} + +/*-----------------------------------------------------------------*/ +/* doubleFromFixed16x16 - convert a fixed16x16 to double */ +/*-----------------------------------------------------------------*/ +double doubleFromFixed16x16(TYPE_UDWORD value) +{ +#if 0 + /* This version is incorrect negative values. */ + double tmp=0, exp=2; + + tmp = (value & 0xffff0000) >> 16; + + while(value) { + value &= 0xffff; + if(value & 0x8000)tmp += 1/exp; + exp *= 2; + value <<= 1; + } + + return (tmp); +#else + return ((double)(value * 1.0) / (double)(1UL << 16)); +#endif +} + +TYPE_UDWORD fixed16x16FromDouble(double value) +{ +#if 0 + /* This version is incorrect negative values. */ + unsigned int tmp=0, pos=16; + TYPE_UDWORD res; + + tmp = floor( value ); + res = tmp << 16; + value -= tmp; + + tmp = 0; + while(pos--) { + value *= 2; + if(value >= 1.0)tmp |= (1 << pos); + value -= floor( value ); + } + + res |= tmp; + + return (res); +#else + return (TYPE_UDWORD)(value * (double)(1UL << 16)); +#endif +} + + #if defined(HAVE_VSNPRINTF) || defined(HAVE_VSPRINTF) size_t SDCCsnprintf(char *dst, size_t n, const char *fmt, ...) {