srcpos.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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. struct srcfile_state *current_srcfile; /* = NULL */
  36. /* Detect infinite include recursion. */
  37. #define MAX_SRCFILE_DEPTH (100)
  38. static int srcfile_depth; /* = 0 */
  39. FILE *srcfile_relative_open(const char *fname, char **fullnamep)
  40. {
  41. FILE *f;
  42. char *fullname;
  43. if (streq(fname, "-")) {
  44. f = stdin;
  45. fullname = xstrdup("<stdin>");
  46. } else {
  47. if (!current_srcfile || !current_srcfile->dir
  48. || (fname[0] == '/'))
  49. fullname = xstrdup(fname);
  50. else
  51. fullname = join_path(current_srcfile->dir, fname);
  52. f = fopen(fullname, "r");
  53. if (!f)
  54. die("Couldn't open \"%s\": %s\n", fname,
  55. strerror(errno));
  56. }
  57. if (fullnamep)
  58. *fullnamep = fullname;
  59. else
  60. free(fullname);
  61. return f;
  62. }
  63. void srcfile_push(const char *fname)
  64. {
  65. struct srcfile_state *srcfile;
  66. if (srcfile_depth++ >= MAX_SRCFILE_DEPTH)
  67. die("Includes nested too deeply");
  68. srcfile = xmalloc(sizeof(*srcfile));
  69. srcfile->f = srcfile_relative_open(fname, &srcfile->name);
  70. srcfile->dir = dirname(srcfile->name);
  71. srcfile->prev = current_srcfile;
  72. srcfile->lineno = 1;
  73. srcfile->colno = 1;
  74. current_srcfile = srcfile;
  75. }
  76. int srcfile_pop(void)
  77. {
  78. struct srcfile_state *srcfile = current_srcfile;
  79. assert(srcfile);
  80. current_srcfile = srcfile->prev;
  81. if (fclose(srcfile->f))
  82. die("Error closing \"%s\": %s\n", srcfile->name,
  83. strerror(errno));
  84. /* FIXME: We allow the srcfile_state structure to leak,
  85. * because it could still be referenced from a location
  86. * variable being carried through the parser somewhere. To
  87. * fix this we could either allocate all the files from a
  88. * table, or use a pool allocator. */
  89. return current_srcfile ? 1 : 0;
  90. }
  91. /*
  92. * The empty source position.
  93. */
  94. struct srcpos srcpos_empty = {
  95. .first_line = 0,
  96. .first_column = 0,
  97. .last_line = 0,
  98. .last_column = 0,
  99. .file = NULL,
  100. };
  101. #define TAB_SIZE 8
  102. void srcpos_update(struct srcpos *pos, const char *text, int len)
  103. {
  104. int i;
  105. pos->file = current_srcfile;
  106. pos->first_line = current_srcfile->lineno;
  107. pos->first_column = current_srcfile->colno;
  108. for (i = 0; i < len; i++)
  109. if (text[i] == '\n') {
  110. current_srcfile->lineno++;
  111. current_srcfile->colno = 1;
  112. } else if (text[i] == '\t') {
  113. current_srcfile->colno =
  114. ALIGN(current_srcfile->colno, TAB_SIZE);
  115. } else {
  116. current_srcfile->colno++;
  117. }
  118. pos->last_line = current_srcfile->lineno;
  119. pos->last_column = current_srcfile->colno;
  120. }
  121. struct srcpos *
  122. srcpos_copy(struct srcpos *pos)
  123. {
  124. struct srcpos *pos_new;
  125. pos_new = xmalloc(sizeof(struct srcpos));
  126. memcpy(pos_new, pos, sizeof(struct srcpos));
  127. return pos_new;
  128. }
  129. void
  130. srcpos_dump(struct srcpos *pos)
  131. {
  132. printf("file : \"%s\"\n",
  133. pos->file ? (char *) pos->file : "<no file>");
  134. printf("first_line : %d\n", pos->first_line);
  135. printf("first_column: %d\n", pos->first_column);
  136. printf("last_line : %d\n", pos->last_line);
  137. printf("last_column : %d\n", pos->last_column);
  138. printf("file : %s\n", pos->file->name);
  139. }
  140. char *
  141. srcpos_string(struct srcpos *pos)
  142. {
  143. const char *fname = "<no-file>";
  144. char *pos_str;
  145. int rc;
  146. if (pos)
  147. fname = pos->file->name;
  148. if (pos->first_line != pos->last_line)
  149. rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname,
  150. pos->first_line, pos->first_column,
  151. pos->last_line, pos->last_column);
  152. else if (pos->first_column != pos->last_column)
  153. rc = asprintf(&pos_str, "%s:%d.%d-%d", fname,
  154. pos->first_line, pos->first_column,
  155. pos->last_column);
  156. else
  157. rc = asprintf(&pos_str, "%s:%d.%d", fname,
  158. pos->first_line, pos->first_column);
  159. if (rc == -1)
  160. die("Couldn't allocate in srcpos string");
  161. return pos_str;
  162. }
  163. void
  164. srcpos_verror(struct srcpos *pos, char const *fmt, va_list va)
  165. {
  166. const char *srcstr;
  167. srcstr = srcpos_string(pos);
  168. fprintf(stdout, "Error: %s ", srcstr);
  169. vfprintf(stdout, fmt, va);
  170. fprintf(stdout, "\n");
  171. }
  172. void
  173. srcpos_error(struct srcpos *pos, char const *fmt, ...)
  174. {
  175. va_list va;
  176. va_start(va, fmt);
  177. srcpos_verror(pos, fmt, va);
  178. va_end(va);
  179. }
  180. void
  181. srcpos_warn(struct srcpos *pos, char const *fmt, ...)
  182. {
  183. const char *srcstr;
  184. va_list va;
  185. va_start(va, fmt);
  186. srcstr = srcpos_string(pos);
  187. fprintf(stderr, "Warning: %s ", srcstr);
  188. vfprintf(stderr, fmt, va);
  189. fprintf(stderr, "\n");
  190. va_end(va);
  191. }