6
|
1 #include <stdbool.h>
|
|
2 #include <stdio.h>
|
|
3 #include <stdlib.h>
|
13
|
4 #include <string.h>
|
6
|
5 #include <unistd.h>
|
|
6 #include <fcntl.h>
|
|
7 #include <err.h>
|
|
8
|
|
9 #include "array.h"
|
8
|
10 #include "place.h"
|
6
|
11 #include "files.h"
|
|
12
|
|
13 struct incdir {
|
|
14 const char *name;
|
|
15 bool issystem;
|
|
16 };
|
|
17
|
|
18 DECLARRAY(incdir);
|
|
19 DEFARRAY(incdir, );
|
|
20
|
|
21 static struct incdirarray quotepath, bracketpath;
|
|
22
|
|
23 ////////////////////////////////////////////////////////////
|
|
24 // management
|
|
25
|
|
26 static
|
|
27 struct incdir *
|
|
28 incdir_create(const char *name, bool issystem)
|
|
29 {
|
|
30 struct incdir *id;
|
|
31
|
|
32 id = domalloc(sizeof(*id));
|
|
33 id->name = name;
|
|
34 id->issystem = issystem;
|
|
35 return id;
|
|
36 }
|
|
37
|
|
38 static
|
|
39 void
|
|
40 incdir_destroy(struct incdir *id)
|
|
41 {
|
|
42 free(id);
|
|
43 }
|
|
44
|
|
45 void
|
|
46 files_init(void)
|
|
47 {
|
|
48 incdirarray_init("epath);
|
|
49 incdirarray_init(&bracketpath);
|
|
50 }
|
|
51
|
9
|
52 DESTROYALL_ARRAY(incdir, );
|
6
|
53
|
|
54 void
|
|
55 files_cleanup(void)
|
|
56 {
|
|
57 incdirarray_destroyall("epath);
|
|
58 incdirarray_cleanup("epath);
|
|
59 incdirarray_destroyall(&bracketpath);
|
|
60 incdirarray_cleanup(&bracketpath);
|
|
61 }
|
|
62
|
|
63 ////////////////////////////////////////////////////////////
|
|
64 // path setup
|
|
65
|
|
66 void
|
|
67 files_addquotepath(const char *dir, bool issystem)
|
|
68 {
|
|
69 struct incdir *id;
|
|
70
|
|
71 id = incdir_create(dir, issystem);
|
|
72 incdirarray_add("epath, id, NULL);
|
|
73 }
|
|
74
|
|
75 void
|
|
76 files_addbracketpath(const char *dir, bool issystem)
|
|
77 {
|
|
78 struct incdir *id;
|
|
79
|
|
80 id = incdir_create(dir, issystem);
|
|
81 incdirarray_add(&bracketpath, id, NULL);
|
|
82 }
|
|
83
|
|
84 ////////////////////////////////////////////////////////////
|
|
85 // parsing
|
|
86
|
|
87 void
|
13
|
88 file_read(const struct placefile *pf, int fd);
|
6
|
89
|
|
90 ////////////////////////////////////////////////////////////
|
|
91 // path search
|
|
92
|
|
93 static
|
13
|
94 char *
|
|
95 mkfilename(const char *dir, const char *file)
|
|
96 {
|
|
97 size_t dlen, flen, rlen;
|
|
98 char *ret;
|
|
99 bool needslash = false;
|
|
100
|
|
101 dlen = strlen(dir);
|
|
102 flen = strlen(file);
|
|
103 if (dlen > 0 && dir[dlen-1] != '/') {
|
|
104 needslash = true;
|
|
105 }
|
|
106
|
|
107 rlen = dlen + (needslash ? 1 : 0) + flen;
|
|
108 ret = domalloc(rlen + 1);
|
|
109 strcpy(ret, dir);
|
|
110 if (needslash) {
|
|
111 strcat(ret, "/");
|
|
112 }
|
|
113 strcat(ret, file);
|
|
114 return ret;
|
|
115 }
|
|
116
|
|
117 static
|
6
|
118 int
|
|
119 file_tryopen(const char *file)
|
|
120 {
|
|
121 int fd;
|
|
122
|
|
123 fd = open(file, O_RDONLY);
|
|
124 if (fd < 0) {
|
|
125 return -1;
|
|
126 }
|
|
127 /* XXX: do we need to do anything here or is this function pointless?*/
|
|
128 return fd;
|
|
129 }
|
|
130
|
|
131 static
|
|
132 void
|
|
133 file_search(struct place *place, struct incdirarray *path, const char *name)
|
|
134 {
|
|
135 unsigned i, num;
|
|
136 struct incdir *id;
|
13
|
137 const struct placefile *pf;
|
6
|
138 char *file;
|
|
139 int fd;
|
|
140
|
|
141 assert(place != NULL);
|
|
142
|
|
143 num = incdirarray_num(path);
|
|
144 for (i=0; i<num; i++) {
|
|
145 id = incdirarray_get(path, i);
|
13
|
146 file = mkfilename(id->name, name);
|
6
|
147 fd = file_tryopen(file);
|
|
148 if (fd >= 0) {
|
13
|
149 pf = place_addfile(place, file, id->issystem);
|
|
150 free(file);
|
|
151 file_read(pf, fd);
|
6
|
152 close(fd);
|
|
153 return;
|
|
154 }
|
|
155 free(file);
|
|
156 }
|
|
157 complain(place, "Include file %s not found", name);
|
|
158 complain_fail();
|
|
159 }
|
|
160
|
|
161 void
|
|
162 file_readquote(struct place *place, const char *name)
|
|
163 {
|
|
164 file_search(place, "epath, name);
|
|
165 }
|
|
166
|
|
167 void
|
|
168 file_readbracket(struct place *place, const char *name)
|
|
169 {
|
|
170 file_search(place, &bracketpath, name);
|
|
171 }
|
|
172
|
|
173 void
|
|
174 file_readabsolute(struct place *place, const char *name)
|
|
175 {
|
13
|
176 const struct placefile *pf;
|
6
|
177 int fd;
|
|
178
|
|
179 assert(place != NULL);
|
|
180
|
|
181 fd = file_tryopen(name);
|
|
182 if (fd < 0) {
|
|
183 warn("%s", name);
|
|
184 die();
|
|
185 }
|
13
|
186 pf = place_addfile(place, name, false);
|
|
187 file_read(pf, fd);
|
6
|
188 close(fd);
|
|
189 }
|