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 27 struct dtc_file *srcpos_file; 28 29 static 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 = xmalloc(strlen(search) + strlen(fname) + 2); 37 38 strcpy(fullname, search); 39 strcat(fullname, "/"); 40 strcat(fullname, fname); 41 } else { 42 fullname = strdup(fname); 43 } 44 45 file->file = fopen(fullname, "r"); 46 if (!file->file) { 47 free(fullname); 48 return 0; 49 } 50 51 file->name = fullname; 52 return 1; 53 } 54 55 56 struct dtc_file *dtc_open_file(const char *fname, 57 const struct search_path *search) 58 { 59 static const struct search_path default_search = { NULL, NULL, NULL }; 60 61 struct dtc_file *file; 62 const char *slash; 63 64 file = xmalloc(sizeof(struct dtc_file)); 65 66 slash = strrchr(fname, '/'); 67 if (slash) { 68 char *dir = xmalloc(slash - fname + 1); 69 70 memcpy(dir, fname, slash - fname); 71 dir[slash - fname] = 0; 72 file->dir = dir; 73 } else { 74 file->dir = NULL; 75 } 76 77 if (streq(fname, "-")) { 78 file->name = "stdin"; 79 file->file = stdin; 80 return file; 81 } 82 83 if (fname[0] == '/') { 84 file->file = fopen(fname, "r"); 85 if (!file->file) 86 goto fail; 87 88 file->name = strdup(fname); 89 return file; 90 } 91 92 if (!search) 93 search = &default_search; 94 95 while (search) { 96 if (dtc_open_one(file, search->dir, fname)) 97 return file; 98 99 if (errno != ENOENT) 100 goto fail; 101 102 search = search->next; 103 } 104 105 fail: 106 die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); 107 } 108 109 void dtc_close_file(struct dtc_file *file) 110 { 111 if (fclose(file->file)) 112 die("Error closing \"%s\": %s\n", file->name, strerror(errno)); 113 114 free(file->dir); 115 free(file); 116 } 117