]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/dtc/srcpos.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / dtc / srcpos.c
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 #define _GNU_SOURCE
21
22 #include <stdio.h>
23
24 #include "dtc.h"
25 #include "srcpos.h"
26
27
28 /*
29  * Like yylineno, this is the current open file pos.
30  */
31 struct dtc_file *srcpos_file;
32
33 /*
34  * The empty source position.
35  */
36
37 struct dtc_file dtc_empty_file = {
38         .dir = NULL,
39         .name = "<no file>",
40         .file = NULL
41 };
42
43 srcpos srcpos_empty = {
44         .first_line = 0,
45         .first_column = 0,
46         .last_line = 0,
47         .last_column = 0,
48         .file = &dtc_empty_file
49 };
50
51
52 static int
53 dtc_open_one(struct dtc_file *file, const char *search, const char *fname)
54 {
55         char *fullname;
56
57         if (search) {
58                 fullname = xmalloc(strlen(search) + strlen(fname) + 2);
59
60                 strcpy(fullname, search);
61                 strcat(fullname, "/");
62                 strcat(fullname, fname);
63         } else {
64                 fullname = xstrdup(fname);
65         }
66
67         file->file = fopen(fullname, "r");
68         if (!file->file) {
69                 free(fullname);
70                 return 0;
71         }
72
73         file->name = fullname;
74         return 1;
75 }
76
77
78 struct dtc_file *
79 dtc_open_file(const char *fname, const struct search_path *search)
80 {
81         static const struct search_path default_search = { NULL, NULL, NULL };
82
83         struct dtc_file *file;
84         const char *slash;
85
86         file = xmalloc(sizeof(struct dtc_file));
87
88         slash = strrchr(fname, '/');
89         if (slash) {
90                 char *dir = xmalloc(slash - fname + 1);
91
92                 memcpy(dir, fname, slash - fname);
93                 dir[slash - fname] = 0;
94                 file->dir = dir;
95         } else {
96                 file->dir = NULL;
97         }
98
99         if (streq(fname, "-")) {
100                 file->name = "stdin";
101                 file->file = stdin;
102                 return file;
103         }
104
105         if (fname[0] == '/') {
106                 file->file = fopen(fname, "r");
107                 if (!file->file)
108                         goto fail;
109
110                 file->name = xstrdup(fname);
111                 return file;
112         }
113
114         if (!search)
115                 search = &default_search;
116
117         while (search) {
118                 if (dtc_open_one(file, search->dir, fname))
119                         return file;
120
121                 if (errno != ENOENT)
122                         goto fail;
123
124                 search = search->next;
125         }
126
127 fail:
128         die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
129 }
130
131
132 void
133 dtc_close_file(struct dtc_file *file)
134 {
135         if (fclose(file->file))
136                 die("Error closing \"%s\": %s\n", file->name, strerror(errno));
137 }
138
139
140 srcpos *
141 srcpos_copy(srcpos *pos)
142 {
143         srcpos *pos_new;
144
145         pos_new = xmalloc(sizeof(srcpos));
146         memcpy(pos_new, pos, sizeof(srcpos));
147
148         return pos_new;
149 }
150
151
152
153 void
154 srcpos_dump(srcpos *pos)
155 {
156         printf("file        : \"%s\"\n",
157                pos->file ? (char *) pos->file : "<no file>");
158         printf("first_line  : %d\n", pos->first_line);
159         printf("first_column: %d\n", pos->first_column);
160         printf("last_line   : %d\n", pos->last_line);
161         printf("last_column : %d\n", pos->last_column);
162         printf("file        : %s\n", pos->file->name);
163 }
164
165
166 char *
167 srcpos_string(srcpos *pos)
168 {
169         const char *fname;
170         char col_buf[100];
171         char *pos_str;
172
173         if (!pos) {
174                 fname = "<no-file>";
175         } else if (pos->file->name) {
176                 fname = pos->file->name;
177                 if (strcmp(fname, "-") == 0)
178                         fname = "stdin";
179         } else {
180                 fname = "<no-file>";
181         }
182
183         if (pos->first_line == pos->last_line) {
184                 if (pos->first_column == pos->last_column) {
185                         snprintf(col_buf, sizeof(col_buf),
186                                  "%d:%d",
187                                  pos->first_line, pos->first_column);
188                 } else {
189                         snprintf(col_buf, sizeof(col_buf),
190                                  "%d:%d-%d",
191                                  pos->first_line,
192                                  pos->first_column, pos->last_column);
193                 }
194
195         } else {
196                 snprintf(col_buf, sizeof(col_buf),
197                          "%d:%d - %d:%d",
198                          pos->first_line, pos->first_column,
199                          pos->last_line, pos->last_column);
200         }
201
202         if (asprintf(&pos_str, "%s %s", fname, col_buf) == -1)
203                 return "<unknown source position?";
204
205         return pos_str;
206 }
207
208
209 void
210 srcpos_error(srcpos *pos, char const *fmt, ...)
211 {
212         const char *srcstr;
213         va_list va;
214         va_start(va, fmt);
215
216         srcstr = srcpos_string(pos);
217
218         fprintf(stderr, "Error: %s ", srcstr);
219         vfprintf(stderr, fmt, va);
220         fprintf(stderr, "\n");
221
222         va_end(va);
223 }
224
225
226 void
227 srcpos_warn(srcpos *pos, char const *fmt, ...)
228 {
229         const char *srcstr;
230         va_list va;
231         va_start(va, fmt);
232
233         srcstr = srcpos_string(pos);
234
235         fprintf(stderr, "Warning: %s ", srcstr);
236         vfprintf(stderr, fmt, va);
237         fprintf(stderr, "\n");
238
239         va_end(va);
240 }