srcpos.c revision 204433
1204431Sraj/* 2204431Sraj * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc. 3204431Sraj * 4204431Sraj * This program is free software; you can redistribute it and/or 5204431Sraj * modify it under the terms of the GNU General Public License as 6204431Sraj * published by the Free Software Foundation; either version 2 of the 7204431Sraj * License, or (at your option) any later version. 8204431Sraj * 9204431Sraj * This program is distributed in the hope that it will be useful, 10204431Sraj * but WITHOUT ANY WARRANTY; without even the implied warranty of 11204431Sraj * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12204431Sraj * General Public License for more details. 13204431Sraj * 14204431Sraj * You should have received a copy of the GNU General Public License 15204431Sraj * along with this program; if not, write to the Free Software 16204431Sraj * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 17204431Sraj * USA 18204431Sraj */ 19204431Sraj 20204433Sraj#define _GNU_SOURCE 21204433Sraj 22204433Sraj#include <stdio.h> 23204433Sraj 24204431Sraj#include "dtc.h" 25204431Sraj#include "srcpos.h" 26204431Sraj 27204433Sraj 28204431Sraj/* 29204431Sraj * Like yylineno, this is the current open file pos. 30204431Sraj */ 31204431Srajstruct dtc_file *srcpos_file; 32204431Sraj 33204433Sraj/* 34204433Sraj * The empty source position. 35204433Sraj */ 36204433Sraj 37204433Srajstruct dtc_file dtc_empty_file = { 38204433Sraj .dir = NULL, 39204433Sraj .name = "<no file>", 40204433Sraj .file = NULL 41204433Sraj}; 42204433Sraj 43204433Srajsrcpos srcpos_empty = { 44204433Sraj .first_line = 0, 45204433Sraj .first_column = 0, 46204433Sraj .last_line = 0, 47204433Sraj .last_column = 0, 48204433Sraj .file = &dtc_empty_file 49204433Sraj}; 50204433Sraj 51204433Sraj 52204433Srajstatic int 53204433Srajdtc_open_one(struct dtc_file *file, const char *search, const char *fname) 54204431Sraj{ 55204431Sraj char *fullname; 56204431Sraj 57204431Sraj if (search) { 58204431Sraj fullname = xmalloc(strlen(search) + strlen(fname) + 2); 59204431Sraj 60204431Sraj strcpy(fullname, search); 61204431Sraj strcat(fullname, "/"); 62204431Sraj strcat(fullname, fname); 63204431Sraj } else { 64204433Sraj fullname = xstrdup(fname); 65204431Sraj } 66204431Sraj 67204431Sraj file->file = fopen(fullname, "r"); 68204431Sraj if (!file->file) { 69204431Sraj free(fullname); 70204431Sraj return 0; 71204431Sraj } 72204431Sraj 73204431Sraj file->name = fullname; 74204431Sraj return 1; 75204431Sraj} 76204431Sraj 77204431Sraj 78204433Srajstruct dtc_file * 79204433Srajdtc_open_file(const char *fname, const struct search_path *search) 80204431Sraj{ 81204431Sraj static const struct search_path default_search = { NULL, NULL, NULL }; 82204431Sraj 83204431Sraj struct dtc_file *file; 84204431Sraj const char *slash; 85204431Sraj 86204431Sraj file = xmalloc(sizeof(struct dtc_file)); 87204431Sraj 88204431Sraj slash = strrchr(fname, '/'); 89204431Sraj if (slash) { 90204431Sraj char *dir = xmalloc(slash - fname + 1); 91204431Sraj 92204431Sraj memcpy(dir, fname, slash - fname); 93204431Sraj dir[slash - fname] = 0; 94204431Sraj file->dir = dir; 95204431Sraj } else { 96204431Sraj file->dir = NULL; 97204431Sraj } 98204431Sraj 99204431Sraj if (streq(fname, "-")) { 100204431Sraj file->name = "stdin"; 101204431Sraj file->file = stdin; 102204431Sraj return file; 103204431Sraj } 104204431Sraj 105204431Sraj if (fname[0] == '/') { 106204431Sraj file->file = fopen(fname, "r"); 107204431Sraj if (!file->file) 108204431Sraj goto fail; 109204431Sraj 110204433Sraj file->name = xstrdup(fname); 111204431Sraj return file; 112204431Sraj } 113204431Sraj 114204431Sraj if (!search) 115204431Sraj search = &default_search; 116204431Sraj 117204431Sraj while (search) { 118204431Sraj if (dtc_open_one(file, search->dir, fname)) 119204431Sraj return file; 120204431Sraj 121204431Sraj if (errno != ENOENT) 122204431Sraj goto fail; 123204431Sraj 124204431Sraj search = search->next; 125204431Sraj } 126204431Sraj 127204431Srajfail: 128204431Sraj die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); 129204431Sraj} 130204431Sraj 131204433Sraj 132204433Srajvoid 133204433Srajdtc_close_file(struct dtc_file *file) 134204431Sraj{ 135204431Sraj if (fclose(file->file)) 136204431Sraj die("Error closing \"%s\": %s\n", file->name, strerror(errno)); 137204433Sraj} 138204431Sraj 139204433Sraj 140204433Srajsrcpos * 141204433Srajsrcpos_copy(srcpos *pos) 142204433Sraj{ 143204433Sraj srcpos *pos_new; 144204433Sraj 145204433Sraj pos_new = xmalloc(sizeof(srcpos)); 146204433Sraj memcpy(pos_new, pos, sizeof(srcpos)); 147204433Sraj 148204433Sraj return pos_new; 149204431Sraj} 150204433Sraj 151204433Sraj 152204433Sraj 153204433Srajvoid 154204433Srajsrcpos_dump(srcpos *pos) 155204433Sraj{ 156204433Sraj printf("file : \"%s\"\n", 157204433Sraj pos->file ? (char *) pos->file : "<no file>"); 158204433Sraj printf("first_line : %d\n", pos->first_line); 159204433Sraj printf("first_column: %d\n", pos->first_column); 160204433Sraj printf("last_line : %d\n", pos->last_line); 161204433Sraj printf("last_column : %d\n", pos->last_column); 162204433Sraj printf("file : %s\n", pos->file->name); 163204433Sraj} 164204433Sraj 165204433Sraj 166204433Srajchar * 167204433Srajsrcpos_string(srcpos *pos) 168204433Sraj{ 169204433Sraj const char *fname; 170204433Sraj char col_buf[100]; 171204433Sraj char *pos_str; 172204433Sraj 173204433Sraj if (!pos) { 174204433Sraj fname = "<no-file>"; 175204433Sraj } else if (pos->file->name) { 176204433Sraj fname = pos->file->name; 177204433Sraj if (strcmp(fname, "-") == 0) 178204433Sraj fname = "stdin"; 179204433Sraj } else { 180204433Sraj fname = "<no-file>"; 181204433Sraj } 182204433Sraj 183204433Sraj if (pos->first_line == pos->last_line) { 184204433Sraj if (pos->first_column == pos->last_column) { 185204433Sraj snprintf(col_buf, sizeof(col_buf), 186204433Sraj "%d:%d", 187204433Sraj pos->first_line, pos->first_column); 188204433Sraj } else { 189204433Sraj snprintf(col_buf, sizeof(col_buf), 190204433Sraj "%d:%d-%d", 191204433Sraj pos->first_line, 192204433Sraj pos->first_column, pos->last_column); 193204433Sraj } 194204433Sraj 195204433Sraj } else { 196204433Sraj snprintf(col_buf, sizeof(col_buf), 197204433Sraj "%d:%d - %d:%d", 198204433Sraj pos->first_line, pos->first_column, 199204433Sraj pos->last_line, pos->last_column); 200204433Sraj } 201204433Sraj 202204433Sraj if (asprintf(&pos_str, "%s %s", fname, col_buf) == -1) 203204433Sraj return "<unknown source position?"; 204204433Sraj 205204433Sraj return pos_str; 206204433Sraj} 207204433Sraj 208204433Sraj 209204433Srajvoid 210204433Srajsrcpos_error(srcpos *pos, char const *fmt, ...) 211204433Sraj{ 212204433Sraj const char *srcstr; 213204433Sraj va_list va; 214204433Sraj va_start(va, fmt); 215204433Sraj 216204433Sraj srcstr = srcpos_string(pos); 217204433Sraj 218204433Sraj fprintf(stderr, "Error: %s ", srcstr); 219204433Sraj vfprintf(stderr, fmt, va); 220204433Sraj fprintf(stderr, "\n"); 221204433Sraj 222204433Sraj va_end(va); 223204433Sraj} 224204433Sraj 225204433Sraj 226204433Srajvoid 227204433Srajsrcpos_warn(srcpos *pos, char const *fmt, ...) 228204433Sraj{ 229204433Sraj const char *srcstr; 230204433Sraj va_list va; 231204433Sraj va_start(va, fmt); 232204433Sraj 233204433Sraj srcstr = srcpos_string(pos); 234204433Sraj 235204433Sraj fprintf(stderr, "Warning: %s ", srcstr); 236204433Sraj vfprintf(stderr, fmt, va); 237204433Sraj fprintf(stderr, "\n"); 238204433Sraj 239204433Sraj va_end(va); 240204433Sraj} 241