xref: /openbmc/linux/scripts/dtc/srcpos.c (revision fd589a8f)
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