1 /*-------------------------------------------------------------------------
2 SDCCutil.c - Small utility functions.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
31 #include "SDCCglobl.h"
32 #include "SDCCmacro.h"
36 /** Given an array of name, value string pairs creates a new hash
37 containing all of the pairs.
40 populateStringHash(const char **pin)
46 shash_add (&pret, pin[0], pin[1]);
53 /** Prints elements of the set to the file, each element on new line
56 fputStrSet(FILE *fp, set *list)
60 for (s = setFirstItem(list); s != NULL; s = setNextItem(list)) {
66 /** Prepend / append given strings to each item of string set. The result is in a
70 appendStrSet(set *list, const char *pre, const char *post)
76 for (item = setFirstItem(list); item != NULL; item = setNextItem(list)) {
77 dbuf_init(&dbuf, PATH_MAX);
79 dbuf_append(&dbuf, pre, strlen(pre));
80 dbuf_append(&dbuf, item, strlen(item));
82 dbuf_append(&dbuf, post, strlen(post));
83 addSet(&new_list, (void *)dbuf_c_str(&dbuf));
90 /** Given a set returns a string containing all of the strings seperated
91 by spaces. The returned string is on the heap.
99 dbuf_init(&dbuf, PATH_MAX);
101 for (s = setFirstItem(list); s != NULL; s = setNextItem(list))
103 dbuf_append(&dbuf, s, strlen(s));
104 dbuf_append(&dbuf, " ", 1);
107 s = dbuf_c_str(&dbuf);
112 /** Given a file with path information in the binary files directory,
113 returns the directory component. Used for discovery of bin
114 directory of SDCC installation. Returns NULL if the path is
119 getBinPath(const char *prel)
123 static char path[PATH_MAX];
125 /* try DOS and *nix dir separator on WIN32 */
126 if (NULL != (p = strrchr(prel, DIR_SEPARATOR_CHAR)) ||
127 NULL != (p = strrchr(prel, UNIX_DIR_SEPARATOR_CHAR))) {
128 len = min((sizeof path) - 1, p - prel);
129 strncpy(path, prel, len);
133 /* not enough info in prel; do it with module name */
134 else if (0 != GetModuleFileName(NULL, path, sizeof path) != 0 &&
135 NULL != (p = strrchr(path, DIR_SEPARATOR_CHAR))) {
144 getBinPath(const char *prel)
148 static char path[PATH_MAX];
150 if ((p = strrchr(prel, DIR_SEPARATOR_CHAR)) == NULL)
153 len = min((sizeof path) - 1, p - prel);
154 strncpy(path, prel, len);
161 /** Returns true if the given path exists.
164 pathExists (const char *ppath)
168 return stat (ppath, &s) == 0;
171 static hTab *_mainValues;
174 setMainValue (const char *pname, const char *pvalue)
178 shash_add (&_mainValues, pname, pvalue);
182 buildCmdLine2 (char *pbuffer, size_t len, const char *pcmd, ...)
187 assert(pbuffer && pcmd);
192 poutcmd = mvsprintf(_mainValues, pcmd, ap);
196 strncpyz(pbuffer, poutcmd, len);
201 populateMainValues (const char **ppin)
203 _mainValues = populateStringHash(ppin);
206 /** Returns true if sz starts with the string given in key.
209 startsWith (const char *sz, const char *key)
211 return !strncmp (sz, key, strlen (key));
214 /** Removes any newline characters from the string. Not strictly the
215 same as perl's chomp.
221 while ((nl = strrchr (sz, '\n')))
226 getRuntimeVariables(void)
232 /* strncpy() with guaranteed NULL termination. */
233 char *strncpyz(char *dest, const char *src, size_t n)
241 fprintf(stderr, "strncpyz prevented buffer overrun!\n");
244 strncpy(dest, src, n);
249 /* like strncat() with guaranteed NULL termination
250 * The passed size should be the size of the dest buffer, not the number of
253 char *strncatz(char *dest, const char *src, size_t n)
256 size_t destLen = strlen(dest);
261 maxToCopy = n - destLen - 1;
264 if (strlen(src) + destLen >= n)
266 fprintf(stderr, "strncatz prevented buffer overrun!\n");
269 strncat(dest, src, maxToCopy);
275 #if defined(HAVE_VSNPRINTF) || defined(HAVE_VSPRINTF)
276 size_t SDCCsnprintf(char *dst, size_t n, const char *fmt, ...)
283 # if defined(HAVE_VSNPRINTF)
284 len = vsnprintf(dst, n, fmt, args);
286 vsprintf(dst, fmt, args);
287 len = strlen(dst) + 1;
292 /* on some gnu systems, vsnprintf returns -1 if output is truncated.
293 * In the C99 spec, vsnprintf returns the number of characters that
294 * would have been written, were space available.
296 if ((len < 0) || (size_t) len >= n) {
297 fprintf(stderr, "internal error: sprintf truncated.\n");