srcpos.c revision 910efac4b49f43cb1b66eef5aa0bbd020920bf2a
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 20#include "dtc.h" 21#include "srcpos.h" 22 23/* 24 * Like yylineno, this is the current open file pos. 25 */ 26 27struct dtc_file *srcpos_file; 28 29static int dtc_open_one(struct dtc_file *file, 30 const char *search, 31 const char *fname) 32{ 33 char *fullname; 34 35 if (search) { 36 fullname = malloc(strlen(search) + strlen(fname) + 2); 37 if (!fullname) 38 die("Out of memory\n"); 39 40 strcpy(fullname, search); 41 strcat(fullname, "/"); 42 strcat(fullname, fname); 43 } else { 44 fullname = strdup(fname); 45 } 46 47 file->file = fopen(fullname, "r"); 48 if (!file->file) { 49 free(fullname); 50 return 0; 51 } 52 53 file->name = fullname; 54 return 1; 55} 56 57 58struct dtc_file *dtc_open_file(const char *fname, 59 const struct search_path *search) 60{ 61 static const struct search_path default_search = { NULL, NULL, NULL }; 62 63 struct dtc_file *file; 64 const char *slash; 65 66 file = malloc(sizeof(struct dtc_file)); 67 if (!file) 68 die("Out of memory\n"); 69 70 slash = strrchr(fname, '/'); 71 if (slash) { 72 char *dir = malloc(slash - fname + 1); 73 if (!dir) 74 die("Out of memory\n"); 75 76 memcpy(dir, fname, slash - fname); 77 dir[slash - fname] = 0; 78 file->dir = dir; 79 } else { 80 file->dir = NULL; 81 } 82 83 if (streq(fname, "-")) { 84 file->name = "stdin"; 85 file->file = stdin; 86 return file; 87 } 88 89 if (!search) 90 search = &default_search; 91 92 while (search) { 93 if (dtc_open_one(file, search->dir, fname)) 94 return file; 95 96 if (errno != ENOENT) 97 goto out; 98 99 search = search->next; 100 } 101 102out: 103 free(file); 104 return NULL; 105} 106 107void dtc_close_file(struct dtc_file *file) 108{ 109 if (fclose(file->file)) 110 die("Error closing \"%s\": %s\n", file->name, strerror(errno)); 111 112 free(file); 113} 114