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"
41 /** Given an array of name, value string pairs creates a new hash
42 containing all of the pairs.
45 populateStringHash(const char **pin)
51 shash_add (&pret, pin[0], pin[1]);
58 /** Prints elements of the set to the file, each element on new line
61 fputStrSet(FILE *fp, set *list)
65 for (s = setFirstItem(list); s != NULL; s = setNextItem(list)) {
71 /** Prepend / append given strings to each item of string set. The result is in a
75 appendStrSet(set *list, const char *pre, const char *post)
81 for (item = setFirstItem(list); item != NULL; item = setNextItem(list)) {
82 dbuf_init(&dbuf, PATH_MAX);
84 dbuf_append(&dbuf, pre, strlen(pre));
85 dbuf_append(&dbuf, item, strlen(item));
87 dbuf_append(&dbuf, post, strlen(post));
88 addSet(&new_list, (void *)dbuf_c_str(&dbuf));
95 /** Given a set returns a string containing all of the strings seperated
96 by spaces. The returned string is on the heap.
104 dbuf_init(&dbuf, PATH_MAX);
106 for (s = setFirstItem(list); s != NULL; s = setNextItem(list))
108 dbuf_append(&dbuf, s, strlen(s));
109 dbuf_append(&dbuf, " ", 1);
112 s = dbuf_c_str(&dbuf);
117 /** Given a file with path information in the binary files directory,
118 returns the directory component. Used for discovery of bin
119 directory of SDCC installation. Returns NULL if the path is
124 getBinPath(const char *prel)
128 static char path[PATH_MAX];
130 /* try DOS and *nix dir separator on WIN32 */
131 if (NULL != (p = strrchr(prel, DIR_SEPARATOR_CHAR)) ||
132 NULL != (p = strrchr(prel, UNIX_DIR_SEPARATOR_CHAR))) {
133 len = min((sizeof path) - 1, p - prel);
134 strncpy(path, prel, len);
138 /* not enough info in prel; do it with module name */
139 else if (0 != GetModuleFileName(NULL, path, sizeof path) != 0 &&
140 NULL != (p = strrchr(path, DIR_SEPARATOR_CHAR))) {
149 getBinPath(const char *prel)
151 static char path[PATH_MAX];
152 const char *ret_path;
154 if (NULL != (ret_path = findProgramPath(prel))) {
158 if (NULL != (p = strrchr(ret_path, DIR_SEPARATOR_CHAR)) &&
159 PATH_MAX > (len = p - ret_path)) {
160 memcpy(path, ret_path, len);
162 free((void *)ret_path);
167 free((void *)ret_path);
177 /** Returns true if the given path exists.
180 pathExists (const char *ppath)
184 return stat (ppath, &s) == 0;
187 static hTab *_mainValues;
190 setMainValue (const char *pname, const char *pvalue)
194 shash_add (&_mainValues, pname, pvalue);
198 buildCmdLine2 (char *pbuffer, size_t len, const char *pcmd, ...)
203 assert(pbuffer && pcmd);
208 poutcmd = mvsprintf(_mainValues, pcmd, ap);
212 strncpyz(pbuffer, poutcmd, len);
217 populateMainValues (const char **ppin)
219 _mainValues = populateStringHash(ppin);
222 /** Returns true if sz starts with the string given in key.
225 startsWith (const char *sz, const char *key)
227 return !strncmp (sz, key, strlen (key));
230 /** Removes any newline characters from the string. Not strictly the
231 same as perl's chomp.
237 while ((nl = strrchr (sz, '\n')))
242 getRuntimeVariables(void)
248 /* strncpy() with guaranteed NULL termination. */
249 char *strncpyz(char *dest, const char *src, size_t n)
257 fprintf(stderr, "strncpyz prevented buffer overrun!\n");
260 strncpy(dest, src, n);
265 /* like strncat() with guaranteed NULL termination
266 * The passed size should be the size of the dest buffer, not the number of
269 char *strncatz(char *dest, const char *src, size_t n)
272 size_t destLen = strlen(dest);
277 maxToCopy = n - destLen - 1;
280 if (strlen(src) + destLen >= n)
282 fprintf(stderr, "strncatz prevented buffer overrun!\n");
285 strncat(dest, src, maxToCopy);
291 /*-----------------------------------------------------------------*/
292 /* getBuildNumber - return build number */
293 /*-----------------------------------------------------------------*/
294 const char *getBuildNumber(void)
296 return (SDCC_BUILD_NUMBER);
301 #if defined(HAVE_VSNPRINTF) || defined(HAVE_VSPRINTF)
302 size_t SDCCsnprintf(char *dst, size_t n, const char *fmt, ...)
309 # if defined(HAVE_VSNPRINTF)
310 len = vsnprintf(dst, n, fmt, args);
312 vsprintf(dst, fmt, args);
313 len = strlen(dst) + 1;
318 /* on some gnu systems, vsnprintf returns -1 if output is truncated.
319 * In the C99 spec, vsnprintf returns the number of characters that
320 * would have been written, were space available.
322 if ((len < 0) || (size_t) len >= n) {
323 fprintf(stderr, "internal error: sprintf truncated.\n");