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"
37 #include "dbuf_string.h"
44 /** Given an array of name, value string pairs creates a new hash
45 containing all of the pairs.
48 populateStringHash(const char **pin)
54 shash_add (&pret, pin[0], pin[1]);
61 /** Prints elements of the set to the file, each element on new line
64 fputStrSet(FILE *fp, set *list)
68 for (s = setFirstItem(list); s != NULL; s = setNextItem(list)) {
74 /** Prepend / append given strings to each item of string set. The result is in a
78 appendStrSet(set *list, const char *pre, const char *post)
84 for (item = setFirstItem(list); item != NULL; item = setNextItem(list)) {
85 dbuf_init(&dbuf, PATH_MAX);
88 dbuf_append_str(&dbuf, pre);
89 dbuf_append_str(&dbuf, item);
91 dbuf_append_str(&dbuf, post);
93 /* null terminate the buffer */
95 addSet(&new_list, dbuf_detach(&dbuf));
101 /** Given a set returns a string containing all of the strings seperated
102 by spaces. The returned string is on the heap.
105 joinStrSet(set *list)
110 dbuf_init(&dbuf, PATH_MAX);
112 for (s = setFirstItem(list); s != NULL; s = setNextItem(list))
114 dbuf_append_str(&dbuf, s);
115 dbuf_append_char(&dbuf, ' ');
118 s = dbuf_c_str(&dbuf);
123 /** Split the path string to the directory and file name (including extension) components.
124 The directory component doesn't contain trailing directory separator.
125 Returns true if the path contains the directory separator. */
127 dbuf_splitPath(const char *path, struct dbuf_s *dir, struct dbuf_s *file)
131 const char *end = &path[strlen(path)];
133 for (p = end - 1; p >= path && !IS_DIR_SEPARATOR(*p); --p)
143 dbuf_append(dir, path, len);
154 dbuf_append(file, p, len);
160 /** Split the path string to the file name (including directory) and file extension components.
161 The file name component doesn't contain trailing extension separator.
162 Returns true if the path contains the extension separator. */
164 dbuf_splitFile(const char *path, struct dbuf_s *file, struct dbuf_s *ext)
167 const char *end = &path[strlen(path)];
169 for (p = end - 1; p >= path && !IS_DIR_SEPARATOR(*p) && '.' != *p; --p)
172 if (p < path || '.' != *p)
174 dbuf_append_str(file, path);
185 dbuf_append(file, path, len);
196 dbuf_append(ext, p, len);
203 /** Combile directory and the file name to a path string using the DIR_SEPARATOR_CHAR.
206 dbuf_makePath(struct dbuf_s *path,const char *dir, const char *file)
209 dbuf_append_str(path, dir);
211 dbuf_append_char(path, DIR_SEPARATOR_CHAR);
214 dbuf_append_str(path, file);
217 /** Given a file with path information in the binary files directory,
218 returns the directory component. Used for discovery of bin
219 directory of SDCC installation. Returns NULL if the path is
224 getBinPath(const char *prel)
229 dbuf_init(&path, 128);
230 dbuf_splitPath(prel, &path, NULL);
232 p = dbuf_c_str(&path);
237 char module[PATH_MAX];
241 /* not enough info in prel; do it with module name */
242 if (0 != GetModuleFileName(NULL, module, sizeof (module)))
244 dbuf_init(&path, 128);
246 dbuf_splitPath(module, &path, NULL);
248 return dbuf_detach(&path);
256 getBinPath(const char *prel)
258 const char *ret_path;
260 if (NULL != (ret_path = findProgramPath(prel)))
264 dbuf_init(&path, 128);
266 dbuf_splitPath(ret_path, &path, NULL);
267 free((void *)ret_path);
269 return dbuf_detach(&path);
276 /** Returns true if the given path exists.
279 pathExists (const char *ppath)
283 return stat (ppath, &s) == 0;
286 static hTab *_mainValues;
289 setMainValue (const char *pname, const char *pvalue)
293 shash_add (&_mainValues, pname, pvalue);
297 buildCmdLine2 (char *pbuffer, size_t len, const char *pcmd, ...)
302 assert(pbuffer && pcmd);
307 poutcmd = mvsprintf(_mainValues, pcmd, ap);
311 strncpyz(pbuffer, poutcmd, len);
316 populateMainValues (const char **ppin)
318 _mainValues = populateStringHash(ppin);
321 /** Returns true if sz starts with the string given in key.
324 startsWith (const char *sz, const char *key)
326 return !strncmp (sz, key, strlen (key));
329 /** Removes any newline characters from the string. Not strictly the
330 same as perl's chomp.
336 while ((nl = strrchr (sz, '\n')))
341 getRuntimeVariables(void)
347 /* strncpy() with guaranteed NULL termination. */
348 char *strncpyz(char *dest, const char *src, size_t n)
356 fprintf(stderr, "strncpyz prevented buffer overrun!\n");
359 strncpy(dest, src, n);
364 /* like strncat() with guaranteed NULL termination
365 * The passed size should be the size of the dest buffer, not the number of
368 char *strncatz(char *dest, const char *src, size_t n)
371 size_t destLen = strlen(dest);
376 maxToCopy = n - destLen - 1;
379 if (strlen(src) + destLen >= n)
381 fprintf(stderr, "strncatz prevented buffer overrun!\n");
384 strncat(dest, src, maxToCopy);
390 /*-----------------------------------------------------------------*/
391 /* getBuildNumber - return build number */
392 /*-----------------------------------------------------------------*/
393 const char *getBuildNumber(void)
395 return (SDCC_BUILD_NUMBER);
398 #if defined(HAVE_VSNPRINTF) || defined(HAVE_VSPRINTF)
399 size_t SDCCsnprintf(char *dst, size_t n, const char *fmt, ...)
406 # if defined(HAVE_VSNPRINTF)
407 len = vsnprintf(dst, n, fmt, args);
409 vsprintf(dst, fmt, args);
410 len = strlen(dst) + 1;
415 /* on some gnu systems, vsnprintf returns -1 if output is truncated.
416 * In the C99 spec, vsnprintf returns the number of characters that
417 * would have been written, were space available.
419 if ((len < 0) || (size_t) len >= n) {
420 fprintf(stderr, "internal error: sprintf truncated.\n");
430 init_pragma_token(struct pragma_token_s *token)
432 dbuf_init(&token->dbuf, 16);
433 token->type = TOKEN_UNKNOWN;
437 get_pragma_token(const char *s, struct pragma_token_s *token)
439 dbuf_set_length(&token->dbuf, 0);
441 /* skip leading spaces */
442 while ('\n' != *s && isspace(*s))
445 if ('\0' == *s || '\n' == *s)
447 token->type = TOKEN_EOL;
453 long val = strtol(s, &end, 0);
455 if (end != s && ('\0' == *end || isspace(*end)))
457 token->val.int_val = val;
458 token->type = TOKEN_INT;
459 dbuf_append(&token->dbuf, s, end - s);
464 while ('\0' != *s && !isspace(*s))
466 dbuf_append_char(&token->dbuf, *s);
470 token->type = TOKEN_STR;
478 get_pragma_string(struct pragma_token_s *token)
480 return dbuf_c_str(&token->dbuf);
484 free_pragma_token(struct pragma_token_s *token)
486 dbuf_destroy(&token->dbuf);