srcpos.c revision 204431
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
20204431Sraj#include "dtc.h"
21204431Sraj#include "srcpos.h"
22204431Sraj
23204431Sraj/*
24204431Sraj * Like yylineno, this is the current open file pos.
25204431Sraj */
26204431Sraj
27204431Srajstruct dtc_file *srcpos_file;
28204431Sraj
29204431Srajstatic int dtc_open_one(struct dtc_file *file,
30204431Sraj                        const char *search,
31204431Sraj                        const char *fname)
32204431Sraj{
33204431Sraj	char *fullname;
34204431Sraj
35204431Sraj	if (search) {
36204431Sraj		fullname = xmalloc(strlen(search) + strlen(fname) + 2);
37204431Sraj
38204431Sraj		strcpy(fullname, search);
39204431Sraj		strcat(fullname, "/");
40204431Sraj		strcat(fullname, fname);
41204431Sraj	} else {
42204431Sraj		fullname = strdup(fname);
43204431Sraj	}
44204431Sraj
45204431Sraj	file->file = fopen(fullname, "r");
46204431Sraj	if (!file->file) {
47204431Sraj		free(fullname);
48204431Sraj		return 0;
49204431Sraj	}
50204431Sraj
51204431Sraj	file->name = fullname;
52204431Sraj	return 1;
53204431Sraj}
54204431Sraj
55204431Sraj
56204431Srajstruct dtc_file *dtc_open_file(const char *fname,
57204431Sraj                               const struct search_path *search)
58204431Sraj{
59204431Sraj	static const struct search_path default_search = { NULL, NULL, NULL };
60204431Sraj
61204431Sraj	struct dtc_file *file;
62204431Sraj	const char *slash;
63204431Sraj
64204431Sraj	file = xmalloc(sizeof(struct dtc_file));
65204431Sraj
66204431Sraj	slash = strrchr(fname, '/');
67204431Sraj	if (slash) {
68204431Sraj		char *dir = xmalloc(slash - fname + 1);
69204431Sraj
70204431Sraj		memcpy(dir, fname, slash - fname);
71204431Sraj		dir[slash - fname] = 0;
72204431Sraj		file->dir = dir;
73204431Sraj	} else {
74204431Sraj		file->dir = NULL;
75204431Sraj	}
76204431Sraj
77204431Sraj	if (streq(fname, "-")) {
78204431Sraj		file->name = "stdin";
79204431Sraj		file->file = stdin;
80204431Sraj		return file;
81204431Sraj	}
82204431Sraj
83204431Sraj	if (fname[0] == '/') {
84204431Sraj		file->file = fopen(fname, "r");
85204431Sraj		if (!file->file)
86204431Sraj			goto fail;
87204431Sraj
88204431Sraj		file->name = strdup(fname);
89204431Sraj		return file;
90204431Sraj	}
91204431Sraj
92204431Sraj	if (!search)
93204431Sraj		search = &default_search;
94204431Sraj
95204431Sraj	while (search) {
96204431Sraj		if (dtc_open_one(file, search->dir, fname))
97204431Sraj			return file;
98204431Sraj
99204431Sraj		if (errno != ENOENT)
100204431Sraj			goto fail;
101204431Sraj
102204431Sraj		search = search->next;
103204431Sraj	}
104204431Sraj
105204431Srajfail:
106204431Sraj	die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
107204431Sraj}
108204431Sraj
109204431Srajvoid dtc_close_file(struct dtc_file *file)
110204431Sraj{
111204431Sraj	if (fclose(file->file))
112204431Sraj		die("Error closing \"%s\": %s\n", file->name, strerror(errno));
113204431Sraj
114204431Sraj	free(file->dir);
115204431Sraj	free(file);
116204431Sraj}
117