6
|
1 #include <stdbool.h>
|
|
2 #include <stdio.h>
|
|
3 #include <stdlib.h>
|
|
4 #include <unistd.h>
|
|
5 #include <fcntl.h>
|
|
6 #include <err.h>
|
|
7
|
|
8 #include "array.h"
|
8
|
9 #include "place.h"
|
6
|
10 #include "files.h"
|
|
11
|
|
12 struct incdir {
|
|
13 const char *name;
|
|
14 bool issystem;
|
|
15 };
|
|
16
|
|
17 struct seenfile {
|
|
18 struct place includedfrom;
|
|
19 char *name;
|
|
20 bool fromsystemdir;
|
|
21 };
|
|
22
|
|
23 DECLARRAY(incdir);
|
|
24 DECLARRAY(seenfile);
|
|
25 DEFARRAY(incdir, );
|
|
26 DEFARRAY(seenfile, );
|
|
27
|
|
28 static struct incdirarray quotepath, bracketpath;
|
|
29 static struct seenfilearray seenfiles;
|
|
30
|
|
31 ////////////////////////////////////////////////////////////
|
|
32 // management
|
|
33
|
|
34 #define DESTROYALL(T) \
|
|
35 static \
|
|
36 void \
|
|
37 T##array_destroyall(struct T##array *arr) \
|
|
38 { \
|
|
39 unsigned i, num; \
|
|
40 struct T *t; \
|
|
41 \
|
|
42 num = T##array_num(arr); \
|
|
43 for (i=0; i<num; i++) { \
|
|
44 t = T##array_get(arr, i); \
|
|
45 T##_destroy(t); \
|
|
46 } \
|
|
47 T##array_setsize(arr, 0); \
|
|
48 }
|
|
49
|
|
50 static
|
|
51 struct incdir *
|
|
52 incdir_create(const char *name, bool issystem)
|
|
53 {
|
|
54 struct incdir *id;
|
|
55
|
|
56 id = domalloc(sizeof(*id));
|
|
57 id->name = name;
|
|
58 id->issystem = issystem;
|
|
59 return id;
|
|
60 }
|
|
61
|
|
62 static
|
|
63 void
|
|
64 incdir_destroy(struct incdir *id)
|
|
65 {
|
|
66 free(id);
|
|
67 }
|
|
68
|
|
69 static
|
|
70 struct seenfile *
|
|
71 seenfile_create(const struct place *from, char *name, bool fromsystemdir)
|
|
72 {
|
|
73 struct seenfile *sf;
|
|
74
|
|
75 sf = domalloc(sizeof(*sf));
|
|
76 sf->includedfrom = *from;
|
|
77 sf->name = name;
|
|
78 sf->fromsystemdir = fromsystemdir;
|
|
79 return sf;
|
|
80 }
|
|
81
|
|
82 static
|
|
83 void
|
|
84 seenfile_destroy(struct seenfile *sf)
|
|
85 {
|
|
86 free(sf->name);
|
|
87 free(sf);
|
|
88 }
|
|
89
|
|
90 void
|
|
91 files_init(void)
|
|
92 {
|
|
93 incdirarray_init("epath);
|
|
94 incdirarray_init(&bracketpath);
|
|
95 }
|
|
96
|
|
97 DESTROYALL(incdir);
|
|
98 DESTROYALL(seenfile);
|
|
99
|
|
100 void
|
|
101 files_cleanup(void)
|
|
102 {
|
|
103 seenfilearray_destroyall(&seenfiles);
|
|
104 seenfilearray_cleanup(&seenfiles);
|
|
105
|
|
106 incdirarray_destroyall("epath);
|
|
107 incdirarray_cleanup("epath);
|
|
108 incdirarray_destroyall(&bracketpath);
|
|
109 incdirarray_cleanup(&bracketpath);
|
|
110 }
|
|
111
|
|
112 ////////////////////////////////////////////////////////////
|
|
113 // path setup
|
|
114
|
|
115 void
|
|
116 files_addquotepath(const char *dir, bool issystem)
|
|
117 {
|
|
118 struct incdir *id;
|
|
119
|
|
120 id = incdir_create(dir, issystem);
|
|
121 incdirarray_add("epath, id, NULL);
|
|
122 }
|
|
123
|
|
124 void
|
|
125 files_addbracketpath(const char *dir, bool issystem)
|
|
126 {
|
|
127 struct incdir *id;
|
|
128
|
|
129 id = incdir_create(dir, issystem);
|
|
130 incdirarray_add(&bracketpath, id, NULL);
|
|
131 }
|
|
132
|
|
133 ////////////////////////////////////////////////////////////
|
8
|
134 // seenfile functions exposed for places.c
|
6
|
135
|
8
|
136 const char *
|
|
137 seenfile_getname(const struct seenfile *file)
|
6
|
138 {
|
8
|
139 return file->name;
|
7
|
140 }
|
|
141
|
8
|
142 const struct place *
|
|
143 seenfile_getincludeplace(const struct seenfile *file)
|
6
|
144 {
|
8
|
145 return &file->includedfrom;
|
6
|
146 }
|
|
147
|
|
148 ////////////////////////////////////////////////////////////
|
|
149 // parsing
|
|
150
|
|
151 void
|
|
152 file_read(struct seenfile *sf, int fd);
|
|
153
|
|
154 ////////////////////////////////////////////////////////////
|
|
155 // path search
|
|
156
|
|
157 static
|
|
158 int
|
|
159 file_tryopen(const char *file)
|
|
160 {
|
|
161 int fd;
|
|
162
|
|
163 fd = open(file, O_RDONLY);
|
|
164 if (fd < 0) {
|
|
165 return -1;
|
|
166 }
|
|
167 /* XXX: do we need to do anything here or is this function pointless?*/
|
|
168 return fd;
|
|
169 }
|
|
170
|
|
171 static
|
|
172 void
|
|
173 file_search(struct place *place, struct incdirarray *path, const char *name)
|
|
174 {
|
|
175 unsigned i, num;
|
|
176 struct incdir *id;
|
|
177 struct seenfile *sf;
|
|
178 char *file;
|
|
179 int fd;
|
|
180
|
|
181 assert(place != NULL);
|
|
182
|
|
183 num = incdirarray_num(path);
|
|
184 for (i=0; i<num; i++) {
|
|
185 id = incdirarray_get(path, i);
|
|
186 file = dostrdup3(id->name, "/", name);
|
|
187 fd = file_tryopen(file);
|
|
188 if (fd >= 0) {
|
|
189 sf = seenfile_create(place, file, id->issystem);
|
|
190 seenfilearray_add(&seenfiles, sf, NULL);
|
|
191 file_read(sf, fd);
|
|
192 close(fd);
|
|
193 return;
|
|
194 }
|
|
195 free(file);
|
|
196 }
|
|
197 complain(place, "Include file %s not found", name);
|
|
198 complain_fail();
|
|
199 }
|
|
200
|
|
201 void
|
|
202 file_readquote(struct place *place, const char *name)
|
|
203 {
|
|
204 file_search(place, "epath, name);
|
|
205 }
|
|
206
|
|
207 void
|
|
208 file_readbracket(struct place *place, const char *name)
|
|
209 {
|
|
210 file_search(place, &bracketpath, name);
|
|
211 }
|
|
212
|
|
213 void
|
|
214 file_readabsolute(struct place *place, const char *name)
|
|
215 {
|
|
216 struct seenfile *sf;
|
|
217 int fd;
|
|
218
|
|
219 assert(place != NULL);
|
|
220
|
|
221 fd = file_tryopen(name);
|
|
222 if (fd < 0) {
|
|
223 warn("%s", name);
|
|
224 die();
|
|
225 }
|
|
226 sf = seenfile_create(place, dostrdup(name), false);
|
|
227 seenfilearray_add(&seenfiles, sf, NULL);
|
|
228 file_read(sf, fd);
|
|
229 close(fd);
|
|
230 }
|