srcpos.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  17. * USA
  18. */
  19. #define _GNU_SOURCE
  20. #include <stdio.h>
  21. #include "dtc.h"
  22. #include "srcpos.h"
  23. static char *dirname(const char *path)
  24. {
  25. const char *slash = strrchr(path, '/');
  26. if (slash) {
  27. int len = slash - path;
  28. char *dir = xmalloc(len + 1);
  29. memcpy(dir, path, len);
  30. dir[len] = '\0';
  31. return dir;
  32. }
  33. return NULL;
  34. }
  35. FILE *depfile; /* = NULL */
  36. struct srcfile_state *current_srcfile; /* = NULL */
  37. /* Detect infinite include recursion. */
  38. #define MAX_SRCFILE_DEPTH (100)
  39. static int srcfile_depth; /* = 0 */
  40. FILE *srcfile_relative_open(const char *fname, char **fullnamep)
  41. {
  42. FILE *f;
  43. char *fullname;
  44. if (streq(fname, "-")) {
  45. f = stdin;
  46. fullname = xstrdup("<stdin>");
  47. } else {
  48. if (!current_srcfile || !current_srcfile->dir
  49. || (fname[0] == '/'))
  50. fullname = xstrdup(fname);
  51. else
  52. fullname = join_path(current_srcfile->dir, fname);
  53. f = fopen(fullname, "r");
  54. if (!f)
  55. die("Couldn't open \"%s\": %s\n", fname,
  56. strerror(errno));
  57. }
  58. if (depfile)
  59. fprintf(depfile, " %s", fullname);
  60. if (fullnamep)
  61. *fullnamep = fullname;
  62. else
  63. free(fullname);
  64. return f;
  65. }
  66. void srcfile_push(const char *fname)
  67. {
  68. struct srcfile_state *srcfile;
  69. if (srcfile_depth++ >= MAX_SRCFILE_DEPTH)
  70. die("Includes nested too deeply");
  71. srcfile = xmalloc(sizeof(*srcfile));
  72. srcfile->f = srcfile_relative_open(fname, &srcfile->name);
  73. srcfile->dir = dirname(srcfile->name);
  74. srcfile->prev = current_srcfile;
  75. srcfile->lineno = 1;
  76. srcfile->colno = 1;
  77. current_srcfile = srcfile;
  78. }
  79. int srcfile_pop(void)
  80. {
  81. struct srcfile_state *srcfile = current_srcfile;
  82. assert(srcfile);
  83. current_srcfile = srcfile->prev;
  84. if (fclose(srcfile->f))
  85. die("Error closing \"%s\": %s\n", srcfile->name,
  86. strerror(errno));
  87. /* FIXME: We allow the srcfile_state structure to leak,
  88. * because it could still be referenced from a location
  89. * variable being carried through the parser somewhere. To
  90. * fix this we could either allocate all the files from a
  91. * table, or use a pool allocator. */
  92. return current_srcfile ? 1 : 0;
  93. }
  94. /*
  95. * The empty source position.
  96. */
  97. struct srcpos srcpos_empty = {
  98. .first_line = 0,
  99. .first_column = 0,
  100. .last_line = 0,
  101. .last_column = 0,
  102. .file = NULL,
  103. };
  104. #define TAB_SIZE 8
  105. void srcpos_update(struct srcpos *pos, const char *text, int len)
  106. {
  107. int i;
  108. pos->file = current_srcfile;
  109. pos->first_line = current_srcfile->lineno;
  110. pos->first_column = current_srcfile->colno;
  111. for (i = 0; i < len; i++)
  112. if (text[i] == '\n') {
  113. current_srcfile->lineno++;
  114. current_srcfile->colno = 1;
  115. } else if (text[i] == '\t') {
  116. current_srcfile->colno =
  117. ALIGN(current_srcfile->colno, TAB_SIZE);
  118. } else {
  119. current_srcfile->colno++;
  120. }
  121. pos->last_line = current_srcfile->lineno;
  122. pos->last_column = current_srcfile->colno;
  123. }
  124. struct srcpos *
  125. srcpos_copy(struct srcpos *pos)
  126. {
  127. struct srcpos *pos_new;
  128. pos_new = xmalloc(sizeof(struct srcpos));
  129. memcpy(pos_new, pos, sizeof(struct srcpos));
  130. return pos_new;
  131. }
  132. void
  133. srcpos_dump(struct srcpos *pos)
  134. {
  135. printf("file : \"%s\"\n",
  136. pos->file ? (char *) pos->file : "<no file>");
  137. printf("first_line : %d\n", pos->first_line);
  138. printf("first_column: %d\n", pos->first_column);
  139. printf("last_line : %d\n", pos->last_line);
  140. printf("last_column : %d\n", pos->last_column);
  141. printf("file : %s\n", pos->file->name);
  142. }
  143. char *
  144. srcpos_string(struct srcpos *pos)
  145. {
  146. const char *fname = "<no-file>";
  147. char *pos_str;
  148. int rc;
  149. if (pos)
  150. fname = pos->file->name;
  151. if (pos->first_line != pos->last_line)
  152. rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname,
  153. pos->first_line, pos->first_column,
  154. pos->last_line, pos->last_column);
  155. else if (pos->first_column != pos->last_column)
  156. rc = asprintf(&pos_str, "%s:%d.%d-%d", fname,
  157. pos->first_line, pos->first_column,
  158. pos->last_column);
  159. else
  160. rc = asprintf(&pos_str, "%s:%d.%d", fname,
  161. pos->first_line, pos->first_column);
  162. if (rc == -1)
  163. die("Couldn't allocate in srcpos string");
  164. return pos_str;
  165. }
  166. void
  167. srcpos_verror(struct srcpos *pos, char const *fmt, va_list va)
  168. {
  169. const char *srcstr;
  170. srcstr = srcpos_string(pos);
  171. fprintf(stdout, "Error: %s ", srcstr);
  172. vfprintf(stdout, fmt, va);
  173. fprintf(stdout, "\n");
  174. }
  175. void
  176. srcpos_error(struct srcpos *pos, char const *fmt, ...)
  177. {
  178. va_list va;
  179. va_start(va, fmt);
  180. srcpos_verror(pos, fmt, va);
  181. va_end(va);
  182. }
  183. void
  184. srcpos_warn(struct srcpos *pos, char const *fmt, ...)
  185. {
  186. const char *srcstr;
  187. va_list va;
  188. va_start(va, fmt);
  189. srcstr = srcpos_string(pos);
  190. fprintf(stderr, "Warning: %s ", srcstr);
  191. vfprintf(stderr, fmt, va);
  192. fprintf(stderr, "\n");
  193. va_end(va);
  194. }