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