PageRenderTime 35ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/sdcc-240/sdcc/src/SDCCutil.c

#
C | 303 lines | 194 code | 50 blank | 59 comment | 30 complexity | a8f143e000347155bdd93f784962d493 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, GPL-3.0
  1. /*-------------------------------------------------------------------------
  2. SDCCutil.c - Small utility functions.
  3. Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
  4. This program is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. In other words, you are welcome to use, share and improve this program.
  16. You are forbidden to forbid anyone else to use, share and improve
  17. what you give them. Help stamp out software-hoarding!
  18. -------------------------------------------------------------------------*/
  19. #ifdef _WIN32
  20. #include <ctype.h>
  21. #include <windows.h>
  22. #endif
  23. #include <sys/stat.h>
  24. #include "dbuf.h"
  25. #include "SDCCglobl.h"
  26. #include "SDCCmacro.h"
  27. #include "SDCCutil.h"
  28. #include "newalloc.h"
  29. /** Given an array of name, value string pairs creates a new hash
  30. containing all of the pairs.
  31. */
  32. hTab *
  33. populateStringHash(const char **pin)
  34. {
  35. hTab *pret = NULL;
  36. while (*pin)
  37. {
  38. shash_add (&pret, pin[0], pin[1]);
  39. pin += 2;
  40. }
  41. return pret;
  42. }
  43. /** Prints elements of the set to the file, each element on new line
  44. */
  45. void
  46. fputStrSet(FILE *fp, set *list)
  47. {
  48. const char *s;
  49. for (s = setFirstItem(list); s != NULL; s = setNextItem(list)) {
  50. fputs(s, fp);
  51. fputc('\n', fp);
  52. }
  53. }
  54. /** Prepend / append given strings to each item of string set. The result is in a
  55. new string set.
  56. */
  57. set *
  58. appendStrSet(set *list, const char *pre, const char *post)
  59. {
  60. set *new_list = NULL;
  61. const char *item;
  62. struct dbuf_s dbuf;
  63. for (item = setFirstItem(list); item != NULL; item = setNextItem(list)) {
  64. dbuf_init(&dbuf, PATH_MAX);
  65. if (pre != NULL)
  66. dbuf_append(&dbuf, pre, strlen(pre));
  67. dbuf_append(&dbuf, item, strlen(item));
  68. if (post != NULL)
  69. dbuf_append(&dbuf, post, strlen(post));
  70. addSet(&new_list, (void *)dbuf_c_str(&dbuf));
  71. dbuf_detach(&dbuf);
  72. }
  73. return new_list;
  74. }
  75. /** Given a set returns a string containing all of the strings seperated
  76. by spaces. The returned string is on the heap.
  77. */
  78. const char *
  79. joinStrSet(set *list)
  80. {
  81. const char *s;
  82. struct dbuf_s dbuf;
  83. dbuf_init(&dbuf, PATH_MAX);
  84. for (s = setFirstItem(list); s != NULL; s = setNextItem(list))
  85. {
  86. dbuf_append(&dbuf, s, strlen(s));
  87. dbuf_append(&dbuf, " ", 1);
  88. }
  89. s = dbuf_c_str(&dbuf);
  90. dbuf_detach(&dbuf);
  91. return s;
  92. }
  93. /** Given a file with path information in the binary files directory,
  94. returns the directory component. Used for discovery of bin
  95. directory of SDCC installation. Returns NULL if the path is
  96. impossible.
  97. */
  98. #ifdef _WIN32
  99. char *
  100. getBinPath(const char *prel)
  101. {
  102. char *p;
  103. size_t len;
  104. static char path[PATH_MAX];
  105. /* try DOS and *nix dir separator on WIN32 */
  106. if (NULL != (p = strrchr(prel, DIR_SEPARATOR_CHAR)) ||
  107. NULL != (p = strrchr(prel, UNIX_DIR_SEPARATOR_CHAR))) {
  108. len = min((sizeof path) - 1, p - prel);
  109. strncpy(path, prel, len);
  110. path[len] = '\0';
  111. return path;
  112. }
  113. /* not enough info in prel; do it with module name */
  114. else if (0 != GetModuleFileName(NULL, path, sizeof path) != 0 &&
  115. NULL != (p = strrchr(path, DIR_SEPARATOR_CHAR))) {
  116. *p = '\0';
  117. return path;
  118. }
  119. else
  120. return NULL;
  121. }
  122. #else
  123. char *
  124. getBinPath(const char *prel)
  125. {
  126. char *p;
  127. size_t len;
  128. static char path[PATH_MAX];
  129. if ((p = strrchr(prel, DIR_SEPARATOR_CHAR)) == NULL)
  130. return NULL;
  131. len = min((sizeof path) - 1, p - prel);
  132. strncpy(path, prel, len);
  133. path[len] = '\0';
  134. return path;
  135. }
  136. #endif
  137. /** Returns true if the given path exists.
  138. */
  139. bool
  140. pathExists (const char *ppath)
  141. {
  142. struct stat s;
  143. return stat (ppath, &s) == 0;
  144. }
  145. static hTab *_mainValues;
  146. void
  147. setMainValue (const char *pname, const char *pvalue)
  148. {
  149. assert(pname);
  150. shash_add (&_mainValues, pname, pvalue);
  151. }
  152. void
  153. buildCmdLine2 (char *pbuffer, size_t len, const char *pcmd, ...)
  154. {
  155. va_list ap;
  156. char *poutcmd;
  157. assert(pbuffer && pcmd);
  158. assert(_mainValues);
  159. va_start(ap, pcmd);
  160. poutcmd = mvsprintf(_mainValues, pcmd, ap);
  161. va_end(ap);
  162. strncpyz(pbuffer, poutcmd, len);
  163. Safe_free(poutcmd);
  164. }
  165. void
  166. populateMainValues (const char **ppin)
  167. {
  168. _mainValues = populateStringHash(ppin);
  169. }
  170. /** Returns true if sz starts with the string given in key.
  171. */
  172. bool
  173. startsWith (const char *sz, const char *key)
  174. {
  175. return !strncmp (sz, key, strlen (key));
  176. }
  177. /** Removes any newline characters from the string. Not strictly the
  178. same as perl's chomp.
  179. */
  180. void
  181. chomp (char *sz)
  182. {
  183. char *nl;
  184. while ((nl = strrchr (sz, '\n')))
  185. *nl = '\0';
  186. }
  187. hTab *
  188. getRuntimeVariables(void)
  189. {
  190. return _mainValues;
  191. }
  192. /* strncpy() with guaranteed NULL termination. */
  193. char *strncpyz(char *dest, const char *src, size_t n)
  194. {
  195. assert(n > 0);
  196. --n;
  197. /* paranoia... */
  198. if (strlen(src) > n)
  199. {
  200. fprintf(stderr, "strncpyz prevented buffer overrun!\n");
  201. }
  202. strncpy(dest, src, n);
  203. dest[n] = 0;
  204. return dest;
  205. }
  206. /* like strncat() with guaranteed NULL termination
  207. * The passed size should be the size of the dest buffer, not the number of
  208. * bytes to copy.
  209. */
  210. char *strncatz(char *dest, const char *src, size_t n)
  211. {
  212. size_t maxToCopy;
  213. size_t destLen = strlen(dest);
  214. assert(n > 0);
  215. assert(n > destLen);
  216. maxToCopy = n - destLen - 1;
  217. /* paranoia... */
  218. if (strlen(src) + destLen >= n)
  219. {
  220. fprintf(stderr, "strncatz prevented buffer overrun!\n");
  221. }
  222. strncat(dest, src, maxToCopy);
  223. dest[n - 1] = 0;
  224. return dest;
  225. }
  226. #if defined(HAVE_VSNPRINTF) || defined(HAVE_VSPRINTF)
  227. size_t SDCCsnprintf(char *dst, size_t n, const char *fmt, ...)
  228. {
  229. va_list args;
  230. int len;
  231. va_start(args, fmt);
  232. # if defined(HAVE_VSNPRINTF)
  233. len = vsnprintf(dst, n, fmt, args);
  234. # else
  235. vsprintf(dst, fmt, args);
  236. len = strlen(dst) + 1;
  237. # endif
  238. va_end(args);
  239. /* on some gnu systems, vsnprintf returns -1 if output is truncated.
  240. * In the C99 spec, vsnprintf returns the number of characters that
  241. * would have been written, were space available.
  242. */
  243. if ((len < 0) || (size_t) len >= n) {
  244. fprintf(stderr, "internal error: sprintf truncated.\n");
  245. }
  246. return len;
  247. }
  248. #endif