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 -------------------------------------------------------------------------*/
33 #include "SDCCglobl.h"
34 #include "SDCCmacro.h"
43 /** Given an array of name, value string pairs creates a new hash
44 containing all of the pairs.
47 populateStringHash(const char **pin)
53 shash_add (&pret, pin[0], pin[1]);
60 /** Prints elements of the set to the file, each element on new line
63 fputStrSet(FILE *fp, set *list)
67 for (s = setFirstItem(list); s != NULL; s = setNextItem(list)) {
73 /** Prepend / append given strings to each item of string set. The result is in a
77 appendStrSet(set *list, const char *pre, const char *post)
83 for (item = setFirstItem(list); item != NULL; item = setNextItem(list)) {
84 dbuf_init(&dbuf, PATH_MAX);
86 dbuf_append(&dbuf, pre, strlen(pre));
87 dbuf_append(&dbuf, item, strlen(item));
89 dbuf_append(&dbuf, post, strlen(post));
90 addSet(&new_list, (void *)dbuf_c_str(&dbuf));
97 /** Given a set returns a string containing all of the strings seperated
98 by spaces. The returned string is on the heap.
101 joinStrSet(set *list)
106 dbuf_init(&dbuf, PATH_MAX);
108 for (s = setFirstItem(list); s != NULL; s = setNextItem(list))
110 dbuf_append(&dbuf, s, strlen(s));
111 dbuf_append(&dbuf, " ", 1);
114 s = dbuf_c_str(&dbuf);
119 /** Given a file with path information in the binary files directory,
120 returns the directory component. Used for discovery of bin
121 directory of SDCC installation. Returns NULL if the path is
126 getBinPath(const char *prel)
130 static char path[PATH_MAX];
132 /* try DOS and *nix dir separator on WIN32 */
133 if (NULL != (p = strrchr(prel, DIR_SEPARATOR_CHAR)) ||
134 NULL != (p = strrchr(prel, UNIX_DIR_SEPARATOR_CHAR))) {
135 len = min((sizeof path) - 1, p - prel);
136 strncpy(path, prel, len);
140 /* not enough info in prel; do it with module name */
141 else if (0 != GetModuleFileName(NULL, path, sizeof path) &&
142 NULL != (p = strrchr(path, DIR_SEPARATOR_CHAR))) {
151 getBinPath(const char *prel)
153 static char path[PATH_MAX];
154 const char *ret_path;
156 if (NULL != (ret_path = findProgramPath(prel))) {
160 if (NULL != (p = strrchr(ret_path, DIR_SEPARATOR_CHAR)) &&
161 PATH_MAX > (len = p - ret_path)) {
162 memcpy(path, ret_path, len);
164 free((void *)ret_path);
169 free((void *)ret_path);
179 /** Returns true if the given path exists.
182 pathExists (const char *ppath)
186 return stat (ppath, &s) == 0;
189 static hTab *_mainValues;
192 setMainValue (const char *pname, const char *pvalue)
196 shash_add (&_mainValues, pname, pvalue);
200 buildCmdLine2 (char *pbuffer, size_t len, const char *pcmd, ...)
205 assert(pbuffer && pcmd);
210 poutcmd = mvsprintf(_mainValues, pcmd, ap);
214 strncpyz(pbuffer, poutcmd, len);
219 populateMainValues (const char **ppin)
221 _mainValues = populateStringHash(ppin);
224 /** Returns true if sz starts with the string given in key.
227 startsWith (const char *sz, const char *key)
229 return !strncmp (sz, key, strlen (key));
232 /** Removes any newline characters from the string. Not strictly the
233 same as perl's chomp.
239 while ((nl = strrchr (sz, '\n')))
244 getRuntimeVariables(void)
250 /* strncpy() with guaranteed NULL termination. */
251 char *strncpyz(char *dest, const char *src, size_t n)
259 fprintf(stderr, "strncpyz prevented buffer overrun!\n");
262 strncpy(dest, src, n);
267 /* like strncat() with guaranteed NULL termination
268 * The passed size should be the size of the dest buffer, not the number of
271 char *strncatz(char *dest, const char *src, size_t n)
274 size_t destLen = strlen(dest);
279 maxToCopy = n - destLen - 1;
282 if (strlen(src) + destLen >= n)
284 fprintf(stderr, "strncatz prevented buffer overrun!\n");
287 strncat(dest, src, maxToCopy);
293 /*-----------------------------------------------------------------*/
294 /* getBuildNumber - return build number */
295 /*-----------------------------------------------------------------*/
296 const char *getBuildNumber(void)
298 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");
333 init_pragma_token(struct pragma_token_s *token)
335 dbuf_init(&token->dbuf, 16);
336 token->type = TOKEN_UNKNOWN;
340 get_pragma_token(const char *s, struct pragma_token_s *token)
342 dbuf_set_size(&token->dbuf, 0);
344 /* skip leading spaces */
345 while ('\n' != *s && isspace(*s))
348 if ('\0' == *s || '\n' == *s)
350 token->type = TOKEN_EOL;
356 long val = strtol(s, &end, 0);
358 if (end != s && ('\0' == *end || isspace(*end)))
360 token->val.int_val = val;
361 token->type = TOKEN_INT;
362 dbuf_append(&token->dbuf, s, end - s);
367 while ('\0' != *s && !isspace(*s))
369 dbuf_append(&token->dbuf, s, 1);
373 token->type = TOKEN_STR;
381 get_pragma_string(struct pragma_token_s *token)
383 return dbuf_c_str(&token->dbuf);
387 free_pragma_token(struct pragma_token_s *token)
389 dbuf_destroy(&token->dbuf);