srcpos.c (204488) | srcpos.c (238742) |
---|---|
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 * --- 10 unchanged lines hidden (view full) --- 19 20#define _GNU_SOURCE 21 22#include <stdio.h> 23 24#include "dtc.h" 25#include "srcpos.h" 26 | 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 * --- 10 unchanged lines hidden (view full) --- 19 20#define _GNU_SOURCE 21 22#include <stdio.h> 23 24#include "dtc.h" 25#include "srcpos.h" 26 |
27/* A node in our list of directories to search for source/include files */ 28struct search_path { 29 struct search_path *next; /* next node in list, NULL for end */ 30 const char *dirname; /* name of directory to search */ 31}; |
|
27 | 32 |
28/* 29 * Like yylineno, this is the current open file pos. 30 */ 31struct dtc_file *srcpos_file; | 33/* This is the list of directories that we search for source files */ 34static struct search_path *search_path_head, **search_path_tail; |
32 | 35 |
33/* 34 * The empty source position. 35 */ | |
36 | 36 |
37struct dtc_file dtc_empty_file = { 38 .dir = NULL, 39 .name = "<no file>", 40 .file = NULL 41}; | 37static char *dirname(const char *path) 38{ 39 const char *slash = strrchr(path, '/'); |
42 | 40 |
43srcpos srcpos_empty = { 44 .first_line = 0, 45 .first_column = 0, 46 .last_line = 0, 47 .last_column = 0, 48 .file = &dtc_empty_file 49}; | 41 if (slash) { 42 int len = slash - path; 43 char *dir = xmalloc(len + 1); |
50 | 44 |
45 memcpy(dir, path, len); 46 dir[len] = '\0'; 47 return dir; 48 } 49 return NULL; 50} |
|
51 | 51 |
52static int 53dtc_open_one(struct dtc_file *file, const char *search, const char *fname) | 52FILE *depfile; /* = NULL */ 53struct srcfile_state *current_srcfile; /* = NULL */ 54 55/* Detect infinite include recursion. */ 56#define MAX_SRCFILE_DEPTH (100) 57static int srcfile_depth; /* = 0 */ 58 59 60/** 61 * Try to open a file in a given directory. 62 * 63 * If the filename is an absolute path, then dirname is ignored. If it is a 64 * relative path, then we look in that directory for the file. 65 * 66 * @param dirname Directory to look in, or NULL for none 67 * @param fname Filename to look for 68 * @param fp Set to NULL if file did not open 69 * @return allocated filename on success (caller must free), NULL on failure 70 */ 71static char *try_open(const char *dirname, const char *fname, FILE **fp) |
54{ 55 char *fullname; 56 | 72{ 73 char *fullname; 74 |
57 if (search) { 58 fullname = xmalloc(strlen(search) + strlen(fname) + 2); 59 60 strcpy(fullname, search); 61 strcat(fullname, "/"); 62 strcat(fullname, fname); 63 } else { | 75 if (!dirname || fname[0] == '/') |
64 fullname = xstrdup(fname); | 76 fullname = xstrdup(fname); |
65 } | 77 else 78 fullname = join_path(dirname, fname); |
66 | 79 |
67 file->file = fopen(fullname, "r"); 68 if (!file->file) { | 80 *fp = fopen(fullname, "r"); 81 if (!*fp) { |
69 free(fullname); | 82 free(fullname); |
70 return 0; | 83 fullname = NULL; |
71 } 72 | 84 } 85 |
73 file->name = fullname; 74 return 1; | 86 return fullname; |
75} 76 | 87} 88 |
77 78struct dtc_file * 79dtc_open_file(const char *fname, const struct search_path *search) | 89/** 90 * Open a file for read access 91 * 92 * If it is a relative filename, we search the full search path for it. 93 * 94 * @param fname Filename to open 95 * @param fp Returns pointer to opened FILE, or NULL on failure 96 * @return pointer to allocated filename, which caller must free 97 */ 98static char *fopen_any_on_path(const char *fname, FILE **fp) |
80{ | 99{ |
81 static const struct search_path default_search = { NULL, NULL, NULL }; | 100 const char *cur_dir = NULL; 101 struct search_path *node; 102 char *fullname; |
82 | 103 |
83 struct dtc_file *file; 84 const char *slash; | 104 /* Try current directory first */ 105 assert(fp); 106 if (current_srcfile) 107 cur_dir = current_srcfile->dir; 108 fullname = try_open(cur_dir, fname, fp); |
85 | 109 |
86 file = xmalloc(sizeof(struct dtc_file)); | 110 /* Failing that, try each search path in turn */ 111 for (node = search_path_head; !*fp && node; node = node->next) 112 fullname = try_open(node->dirname, fname, fp); |
87 | 113 |
88 slash = strrchr(fname, '/'); 89 if (slash) { 90 char *dir = xmalloc(slash - fname + 1); | 114 return fullname; 115} |
91 | 116 |
92 memcpy(dir, fname, slash - fname); 93 dir[slash - fname] = 0; 94 file->dir = dir; 95 } else { 96 file->dir = NULL; 97 } | 117FILE *srcfile_relative_open(const char *fname, char **fullnamep) 118{ 119 FILE *f; 120 char *fullname; |
98 99 if (streq(fname, "-")) { | 121 122 if (streq(fname, "-")) { |
100 file->name = "stdin"; 101 file->file = stdin; 102 return file; | 123 f = stdin; 124 fullname = xstrdup("<stdin>"); 125 } else { 126 fullname = fopen_any_on_path(fname, &f); 127 if (!f) 128 die("Couldn't open \"%s\": %s\n", fname, 129 strerror(errno)); |
103 } 104 | 130 } 131 |
105 if (fname[0] == '/') { 106 file->file = fopen(fname, "r"); 107 if (!file->file) 108 goto fail; | 132 if (depfile) 133 fprintf(depfile, " %s", fullname); |
109 | 134 |
110 file->name = xstrdup(fname); 111 return file; 112 } | 135 if (fullnamep) 136 *fullnamep = fullname; 137 else 138 free(fullname); |
113 | 139 |
114 if (!search) 115 search = &default_search; | 140 return f; 141} |
116 | 142 |
117 while (search) { 118 if (dtc_open_one(file, search->dir, fname)) 119 return file; | 143void srcfile_push(const char *fname) 144{ 145 struct srcfile_state *srcfile; |
120 | 146 |
121 if (errno != ENOENT) 122 goto fail; | 147 if (srcfile_depth++ >= MAX_SRCFILE_DEPTH) 148 die("Includes nested too deeply"); |
123 | 149 |
124 search = search->next; 125 } | 150 srcfile = xmalloc(sizeof(*srcfile)); |
126 | 151 |
127fail: 128 die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); | 152 srcfile->f = srcfile_relative_open(fname, &srcfile->name); 153 srcfile->dir = dirname(srcfile->name); 154 srcfile->prev = current_srcfile; 155 156 srcfile->lineno = 1; 157 srcfile->colno = 1; 158 159 current_srcfile = srcfile; |
129} 130 | 160} 161 |
162int srcfile_pop(void) 163{ 164 struct srcfile_state *srcfile = current_srcfile; |
|
131 | 165 |
132void 133dtc_close_file(struct dtc_file *file) | 166 assert(srcfile); 167 168 current_srcfile = srcfile->prev; 169 170 if (fclose(srcfile->f)) 171 die("Error closing \"%s\": %s\n", srcfile->name, 172 strerror(errno)); 173 174 /* FIXME: We allow the srcfile_state structure to leak, 175 * because it could still be referenced from a location 176 * variable being carried through the parser somewhere. To 177 * fix this we could either allocate all the files from a 178 * table, or use a pool allocator. */ 179 180 return current_srcfile ? 1 : 0; 181} 182 183void srcfile_add_search_path(const char *dirname) |
134{ | 184{ |
135 if (fclose(file->file)) 136 die("Error closing \"%s\": %s\n", file->name, strerror(errno)); | 185 struct search_path *node; 186 187 /* Create the node */ 188 node = xmalloc(sizeof(*node)); 189 node->next = NULL; 190 node->dirname = xstrdup(dirname); 191 192 /* Add to the end of our list */ 193 if (search_path_tail) 194 *search_path_tail = node; 195 else 196 search_path_head = node; 197 search_path_tail = &node->next; |
137} 138 | 198} 199 |
200/* 201 * The empty source position. 202 */ |
|
139 | 203 |
140srcpos * 141srcpos_copy(srcpos *pos) | 204struct srcpos srcpos_empty = { 205 .first_line = 0, 206 .first_column = 0, 207 .last_line = 0, 208 .last_column = 0, 209 .file = NULL, 210}; 211 212#define TAB_SIZE 8 213 214void srcpos_update(struct srcpos *pos, const char *text, int len) |
142{ | 215{ |
143 srcpos *pos_new; | 216 int i; |
144 | 217 |
145 pos_new = xmalloc(sizeof(srcpos)); 146 memcpy(pos_new, pos, sizeof(srcpos)); | 218 pos->file = current_srcfile; |
147 | 219 |
220 pos->first_line = current_srcfile->lineno; 221 pos->first_column = current_srcfile->colno; 222 223 for (i = 0; i < len; i++) 224 if (text[i] == '\n') { 225 current_srcfile->lineno++; 226 current_srcfile->colno = 1; 227 } else if (text[i] == '\t') { 228 current_srcfile->colno = 229 ALIGN(current_srcfile->colno, TAB_SIZE); 230 } else { 231 current_srcfile->colno++; 232 } 233 234 pos->last_line = current_srcfile->lineno; 235 pos->last_column = current_srcfile->colno; 236} 237 238struct srcpos * 239srcpos_copy(struct srcpos *pos) 240{ 241 struct srcpos *pos_new; 242 243 pos_new = xmalloc(sizeof(struct srcpos)); 244 memcpy(pos_new, pos, sizeof(struct srcpos)); 245 |
|
148 return pos_new; 149} 150 151 152 153void | 246 return pos_new; 247} 248 249 250 251void |
154srcpos_dump(srcpos *pos) | 252srcpos_dump(struct srcpos *pos) |
155{ 156 printf("file : \"%s\"\n", 157 pos->file ? (char *) pos->file : "<no file>"); 158 printf("first_line : %d\n", pos->first_line); 159 printf("first_column: %d\n", pos->first_column); 160 printf("last_line : %d\n", pos->last_line); 161 printf("last_column : %d\n", pos->last_column); 162 printf("file : %s\n", pos->file->name); 163} 164 165 166char * | 253{ 254 printf("file : \"%s\"\n", 255 pos->file ? (char *) pos->file : "<no file>"); 256 printf("first_line : %d\n", pos->first_line); 257 printf("first_column: %d\n", pos->first_column); 258 printf("last_line : %d\n", pos->last_line); 259 printf("last_column : %d\n", pos->last_column); 260 printf("file : %s\n", pos->file->name); 261} 262 263 264char * |
167srcpos_string(srcpos *pos) | 265srcpos_string(struct srcpos *pos) |
168{ | 266{ |
169 const char *fname; 170 char col_buf[100]; | 267 const char *fname = "<no-file>"; |
171 char *pos_str; | 268 char *pos_str; |
269 int rc; |
|
172 | 270 |
173 if (!pos) { 174 fname = "<no-file>"; 175 } else if (pos->file->name) { | 271 if (pos) |
176 fname = pos->file->name; | 272 fname = pos->file->name; |
177 if (strcmp(fname, "-") == 0) 178 fname = "stdin"; 179 } else { 180 fname = "<no-file>"; 181 } | |
182 | 273 |
183 if (pos->first_line == pos->last_line) { 184 if (pos->first_column == pos->last_column) { 185 snprintf(col_buf, sizeof(col_buf), 186 "%d:%d", 187 pos->first_line, pos->first_column); 188 } else { 189 snprintf(col_buf, sizeof(col_buf), 190 "%d:%d-%d", 191 pos->first_line, 192 pos->first_column, pos->last_column); 193 } | |
194 | 274 |
195 } else { 196 snprintf(col_buf, sizeof(col_buf), 197 "%d:%d - %d:%d", 198 pos->first_line, pos->first_column, 199 pos->last_line, pos->last_column); 200 } | 275 if (pos->first_line != pos->last_line) 276 rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname, 277 pos->first_line, pos->first_column, 278 pos->last_line, pos->last_column); 279 else if (pos->first_column != pos->last_column) 280 rc = asprintf(&pos_str, "%s:%d.%d-%d", fname, 281 pos->first_line, pos->first_column, 282 pos->last_column); 283 else 284 rc = asprintf(&pos_str, "%s:%d.%d", fname, 285 pos->first_line, pos->first_column); |
201 | 286 |
202 if (asprintf(&pos_str, "%s %s", fname, col_buf) == -1) 203 return "<unknown source position?"; | 287 if (rc == -1) 288 die("Couldn't allocate in srcpos string"); |
204 205 return pos_str; 206} 207 | 289 290 return pos_str; 291} 292 |
208 | |
209void | 293void |
210srcpos_error(srcpos *pos, char const *fmt, ...) | 294srcpos_verror(struct srcpos *pos, char const *fmt, va_list va) |
211{ | 295{ |
212 const char *srcstr; 213 va_list va; 214 va_start(va, fmt); | 296 const char *srcstr; |
215 | 297 |
216 srcstr = srcpos_string(pos); | 298 srcstr = srcpos_string(pos); |
217 | 299 |
218 fprintf(stderr, "Error: %s ", srcstr); 219 vfprintf(stderr, fmt, va); 220 fprintf(stderr, "\n"); | 300 fprintf(stdout, "Error: %s ", srcstr); 301 vfprintf(stdout, fmt, va); 302 fprintf(stdout, "\n"); 303} |
221 | 304 |
305void 306srcpos_error(struct srcpos *pos, char const *fmt, ...) 307{ 308 va_list va; 309 310 va_start(va, fmt); 311 srcpos_verror(pos, fmt, va); |
|
222 va_end(va); 223} 224 225 226void | 312 va_end(va); 313} 314 315 316void |
227srcpos_warn(srcpos *pos, char const *fmt, ...) | 317srcpos_warn(struct srcpos *pos, char const *fmt, ...) |
228{ 229 const char *srcstr; 230 va_list va; 231 va_start(va, fmt); 232 233 srcstr = srcpos_string(pos); 234 235 fprintf(stderr, "Warning: %s ", srcstr); 236 vfprintf(stderr, fmt, va); 237 fprintf(stderr, "\n"); 238 239 va_end(va); 240} | 318{ 319 const char *srcstr; 320 va_list va; 321 va_start(va, fmt); 322 323 srcstr = srcpos_string(pos); 324 325 fprintf(stderr, "Warning: %s ", srcstr); 326 vfprintf(stderr, fmt, va); 327 fprintf(stderr, "\n"); 328 329 va_end(va); 330} |