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 /** Given a file with path information in the binary files directory,
124 returns the directory component. Used for discovery of bin
125 directory of SDCC installation. Returns NULL if the path is
130 getBinPath(const char *prel)
134 static char path[PATH_MAX];
136 /* try DOS and *nix dir separator on WIN32 */
137 if (NULL != (p = strrchr(prel, DIR_SEPARATOR_CHAR)) ||
138 NULL != (p = strrchr(prel, UNIX_DIR_SEPARATOR_CHAR))) {
139 len = min((sizeof path) - 1, p - prel);
140 strncpy(path, prel, len);
144 /* not enough info in prel; do it with module name */
145 else if (0 != GetModuleFileName(NULL, path, sizeof path) &&
146 NULL != (p = strrchr(path, DIR_SEPARATOR_CHAR))) {
155 getBinPath(const char *prel)
157 static char path[PATH_MAX];
158 const char *ret_path;
160 if (NULL != (ret_path = findProgramPath(prel))) {
164 if (NULL != (p = strrchr(ret_path, DIR_SEPARATOR_CHAR)) &&
165 PATH_MAX > (len = p - ret_path)) {
166 memcpy(path, ret_path, len);
168 free((void *)ret_path);
173 free((void *)ret_path);
183 /** Returns true if the given path exists.
186 pathExists (const char *ppath)
190 return stat (ppath, &s) == 0;
193 static hTab *_mainValues;
196 setMainValue (const char *pname, const char *pvalue)
200 shash_add (&_mainValues, pname, pvalue);
204 buildCmdLine2 (char *pbuffer, size_t len, const char *pcmd, ...)
209 assert(pbuffer && pcmd);
214 poutcmd = mvsprintf(_mainValues, pcmd, ap);
218 strncpyz(pbuffer, poutcmd, len);
223 populateMainValues (const char **ppin)
225 _mainValues = populateStringHash(ppin);
228 /** Returns true if sz starts with the string given in key.
231 startsWith (const char *sz, const char *key)
233 return !strncmp (sz, key, strlen (key));
236 /** Removes any newline characters from the string. Not strictly the
237 same as perl's chomp.
243 while ((nl = strrchr (sz, '\n')))
248 getRuntimeVariables(void)
254 /* strncpy() with guaranteed NULL termination. */
255 char *strncpyz(char *dest, const char *src, size_t n)
263 fprintf(stderr, "strncpyz prevented buffer overrun!\n");
266 strncpy(dest, src, n);
271 /* like strncat() with guaranteed NULL termination
272 * The passed size should be the size of the dest buffer, not the number of
275 char *strncatz(char *dest, const char *src, size_t n)
278 size_t destLen = strlen(dest);
283 maxToCopy = n - destLen - 1;
286 if (strlen(src) + destLen >= n)
288 fprintf(stderr, "strncatz prevented buffer overrun!\n");
291 strncat(dest, src, maxToCopy);
297 /*-----------------------------------------------------------------*/
298 /* getBuildNumber - return build number */
299 /*-----------------------------------------------------------------*/
300 const char *getBuildNumber(void)
302 return (SDCC_BUILD_NUMBER);
305 #if defined(HAVE_VSNPRINTF) || defined(HAVE_VSPRINTF)
306 size_t SDCCsnprintf(char *dst, size_t n, const char *fmt, ...)
313 # if defined(HAVE_VSNPRINTF)
314 len = vsnprintf(dst, n, fmt, args);
316 vsprintf(dst, fmt, args);
317 len = strlen(dst) + 1;
322 /* on some gnu systems, vsnprintf returns -1 if output is truncated.
323 * In the C99 spec, vsnprintf returns the number of characters that
324 * would have been written, were space available.
326 if ((len < 0) || (size_t) len >= n) {
327 fprintf(stderr, "internal error: sprintf truncated.\n");
337 init_pragma_token(struct pragma_token_s *token)
339 dbuf_init(&token->dbuf, 16);
340 token->type = TOKEN_UNKNOWN;
344 get_pragma_token(const char *s, struct pragma_token_s *token)
346 dbuf_set_length(&token->dbuf, 0);
348 /* skip leading spaces */
349 while ('\n' != *s && isspace(*s))
352 if ('\0' == *s || '\n' == *s)
354 token->type = TOKEN_EOL;
360 long val = strtol(s, &end, 0);
362 if (end != s && ('\0' == *end || isspace(*end)))
364 token->val.int_val = val;
365 token->type = TOKEN_INT;
366 dbuf_append(&token->dbuf, s, end - s);
371 while ('\0' != *s && !isspace(*s))
373 dbuf_append_char(&token->dbuf, *s);
377 token->type = TOKEN_STR;
385 get_pragma_string(struct pragma_token_s *token)
387 return dbuf_c_str(&token->dbuf);
391 free_pragma_token(struct pragma_token_s *token)
393 dbuf_destroy(&token->dbuf);