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"
39 /** Given an array of name, value string pairs creates a new hash
40 containing all of the pairs.
43 populateStringHash(const char **pin)
49 shash_add (&pret, pin[0], pin[1]);
56 /** Prints elements of the set to the file, each element on new line
59 fputStrSet(FILE *fp, set *list)
63 for (s = setFirstItem(list); s != NULL; s = setNextItem(list)) {
69 /** Prepend / append given strings to each item of string set. The result is in a
73 appendStrSet(set *list, const char *pre, const char *post)
79 for (item = setFirstItem(list); item != NULL; item = setNextItem(list)) {
80 dbuf_init(&dbuf, PATH_MAX);
82 dbuf_append(&dbuf, pre, strlen(pre));
83 dbuf_append(&dbuf, item, strlen(item));
85 dbuf_append(&dbuf, post, strlen(post));
86 addSet(&new_list, (void *)dbuf_c_str(&dbuf));
93 /** Given a set returns a string containing all of the strings seperated
94 by spaces. The returned string is on the heap.
102 dbuf_init(&dbuf, PATH_MAX);
104 for (s = setFirstItem(list); s != NULL; s = setNextItem(list))
106 dbuf_append(&dbuf, s, strlen(s));
107 dbuf_append(&dbuf, " ", 1);
110 s = dbuf_c_str(&dbuf);
115 /** Given a file with path information in the binary files directory,
116 returns the directory component. Used for discovery of bin
117 directory of SDCC installation. Returns NULL if the path is
122 getBinPath(const char *prel)
126 static char path[PATH_MAX];
128 /* try DOS and *nix dir separator on WIN32 */
129 if (NULL != (p = strrchr(prel, DIR_SEPARATOR_CHAR)) ||
130 NULL != (p = strrchr(prel, UNIX_DIR_SEPARATOR_CHAR))) {
131 len = min((sizeof path) - 1, p - prel);
132 strncpy(path, prel, len);
136 /* not enough info in prel; do it with module name */
137 else if (0 != GetModuleFileName(NULL, path, sizeof path) != 0 &&
138 NULL != (p = strrchr(path, DIR_SEPARATOR_CHAR))) {
147 getBinPath(const char *prel)
149 static char path[PATH_MAX];
150 const char *ret_path;
152 if (NULL != (ret_path = findProgramPath(prel))) {
156 if (NULL != (p = strrchr(ret_path, DIR_SEPARATOR_CHAR)) &&
157 PATH_MAX > (len = p - ret_path)) {
158 memcpy(path, ret_path, len);
160 free((void *)ret_path);
165 free((void *)ret_path);
175 /** Returns true if the given path exists.
178 pathExists (const char *ppath)
182 return stat (ppath, &s) == 0;
185 static hTab *_mainValues;
188 setMainValue (const char *pname, const char *pvalue)
192 shash_add (&_mainValues, pname, pvalue);
196 buildCmdLine2 (char *pbuffer, size_t len, const char *pcmd, ...)
201 assert(pbuffer && pcmd);
206 poutcmd = mvsprintf(_mainValues, pcmd, ap);
210 strncpyz(pbuffer, poutcmd, len);
215 populateMainValues (const char **ppin)
217 _mainValues = populateStringHash(ppin);
220 /** Returns true if sz starts with the string given in key.
223 startsWith (const char *sz, const char *key)
225 return !strncmp (sz, key, strlen (key));
228 /** Removes any newline characters from the string. Not strictly the
229 same as perl's chomp.
235 while ((nl = strrchr (sz, '\n')))
240 getRuntimeVariables(void)
246 /* strncpy() with guaranteed NULL termination. */
247 char *strncpyz(char *dest, const char *src, size_t n)
255 fprintf(stderr, "strncpyz prevented buffer overrun!\n");
258 strncpy(dest, src, n);
263 /* like strncat() with guaranteed NULL termination
264 * The passed size should be the size of the dest buffer, not the number of
267 char *strncatz(char *dest, const char *src, size_t n)
270 size_t destLen = strlen(dest);
275 maxToCopy = n - destLen - 1;
278 if (strlen(src) + destLen >= n)
280 fprintf(stderr, "strncatz prevented buffer overrun!\n");
283 strncat(dest, src, maxToCopy);
289 #if defined(HAVE_VSNPRINTF) || defined(HAVE_VSPRINTF)
290 size_t SDCCsnprintf(char *dst, size_t n, const char *fmt, ...)
297 # if defined(HAVE_VSNPRINTF)
298 len = vsnprintf(dst, n, fmt, args);
300 vsprintf(dst, fmt, args);
301 len = strlen(dst) + 1;
306 /* on some gnu systems, vsnprintf returns -1 if output is truncated.
307 * In the C99 spec, vsnprintf returns the number of characters that
308 * would have been written, were space available.
310 if ((len < 0) || (size_t) len >= n) {
311 fprintf(stderr, "internal error: sprintf truncated.\n");