Mercurial > projects > ldc
annotate dmd/inifile.c @ 622:26fce59fe80a
Wrapped all the most potentially expensive logging calls in a conditional to only do work when actually requested.
Commented some logging calls that could potentially write out many megabytes of type dumps.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Wed, 01 Oct 2008 18:32:31 +0200 |
parents | cbd6c8073a32 |
children | aa953cc960b6 |
rev | line source |
---|---|
1 | 1 |
2 // Copyright (c) 1999-2006 by Digital Mars | |
3 // All Rights Reserved | |
4 // written by Walter Bright | |
5 // http://www.digitalmars.com | |
6 | |
7 | |
8 #include <stdio.h> | |
9 #include <string.h> | |
10 #include <stdlib.h> | |
11 #include <ctype.h> | |
12 | |
13 #include "root.h" | |
14 #include "mem.h" | |
15 | |
285
297690b5d4a5
[svn r306] Fixed: it's now possible to compile and link llvmdc with MinGW32 and msys on Win32 :D I tried it myself ;) Building the runtime still needs some work, but it's a step in the right direction.
lindquist
parents:
35
diff
changeset
|
16 #ifdef __MINGW32__ |
297690b5d4a5
[svn r306] Fixed: it's now possible to compile and link llvmdc with MinGW32 and msys on Win32 :D I tried it myself ;) Building the runtime still needs some work, but it's a step in the right direction.
lindquist
parents:
35
diff
changeset
|
17 #include <malloc.h> |
297690b5d4a5
[svn r306] Fixed: it's now possible to compile and link llvmdc with MinGW32 and msys on Win32 :D I tried it myself ;) Building the runtime still needs some work, but it's a step in the right direction.
lindquist
parents:
35
diff
changeset
|
18 #endif |
297690b5d4a5
[svn r306] Fixed: it's now possible to compile and link llvmdc with MinGW32 and msys on Win32 :D I tried it myself ;) Building the runtime still needs some work, but it's a step in the right direction.
lindquist
parents:
35
diff
changeset
|
19 |
1 | 20 #define LOG 0 |
21 | |
22 char *skipspace(const char *p); | |
23 | |
24 #if __GNUC__ | |
25 char *strupr(char *s) | |
26 { | |
27 char *t = s; | |
28 | |
29 while (*s) | |
30 { | |
31 *s = toupper(*s); | |
32 s++; | |
33 } | |
34 | |
35 return t; | |
36 } | |
37 #endif /* unix */ | |
38 | |
39 /***************************** | |
40 * Read and analyze .ini file. | |
41 * Input: | |
42 * argv0 program name (argv[0]) | |
43 * inifile .ini file name | |
44 */ | |
45 | |
46 void inifile(char *argv0, char *inifile) | |
47 { | |
48 char *path; // need path for @P macro | |
49 char *filename; | |
50 OutBuffer buf; | |
51 int i; | |
52 int k; | |
53 int envsection = 0; | |
54 | |
55 #if LOG | |
56 printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile); | |
57 #endif | |
58 if (FileName::absolute(inifile)) | |
59 { | |
60 filename = inifile; | |
61 } | |
62 else | |
63 { | |
64 /* Look for inifile in the following sequence of places: | |
65 * o current directory | |
66 * o home directory | |
67 * o directory off of argv0 | |
68 * o /etc/ | |
69 */ | |
70 if (FileName::exists(inifile)) | |
71 { | |
72 filename = inifile; | |
73 } | |
74 else | |
75 { | |
76 filename = FileName::combine(getenv("HOME"), inifile); | |
77 if (!FileName::exists(filename)) | |
78 { | |
79 filename = FileName::replaceName(argv0, inifile); | |
80 if (!FileName::exists(filename)) | |
81 { | |
571
cbd6c8073a32
Changed all '#if linux || __APPLE__' to '#if POSIX' so we can support other platforms too, thanx for the suggestion anders.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
535
diff
changeset
|
82 #if POSIX |
35
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
83 |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
84 #if 0 |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
85 #if __GLIBC__ // This fix by Thomas Kuehne |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
86 /* argv0 might be a symbolic link, |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
87 * so try again looking past it to the real path |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
88 */ |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
89 char* real_argv0 = realpath(argv0, NULL); |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
90 if (real_argv0) |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
91 { |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
92 filename = FileName::replaceName(real_argv0, inifile); |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
93 free(real_argv0); |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
94 if (FileName::exists(filename)) |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
95 goto Ldone; |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
96 } |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
97 #else |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
98 #error use of glibc non-standard extension realpath(char*, NULL) |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
99 #endif |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
100 #endif |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
101 |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
102 // old way; problem is that argv0 might not be on the PATH at all |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
103 // and some other instance might be found |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
104 |
1 | 105 // Search PATH for argv0 |
106 const char *p = getenv("PATH"); | |
107 Array *paths = FileName::splitPath(p); | |
108 filename = FileName::searchPath(paths, argv0, 0); | |
109 if (!filename) | |
110 goto Letc; // argv0 not found on path | |
111 filename = FileName::replaceName(filename, inifile); | |
112 if (FileName::exists(filename)) | |
113 goto Ldone; | |
114 #endif | |
115 | |
116 // Search /etc/ for inifile | |
117 Letc: | |
118 filename = FileName::combine("/etc/", inifile); | |
119 | |
120 Ldone: | |
121 ; | |
122 } | |
123 } | |
124 } | |
125 } | |
126 path = FileName::path(filename); | |
127 #if LOG | |
128 printf("\tpath = '%s', filename = '%s'\n", path, filename); | |
129 #endif | |
130 | |
131 File file(filename); | |
132 | |
133 if (file.read()) | |
134 return; // error reading file | |
135 | |
136 // Parse into lines | |
137 int eof = 0; | |
138 for (i = 0; i < file.len && !eof; i++) | |
139 { | |
140 int linestart = i; | |
141 | |
142 for (; i < file.len; i++) | |
143 { | |
144 switch (file.buffer[i]) | |
145 { | |
146 case '\r': | |
147 break; | |
148 | |
149 case '\n': | |
150 // Skip if it was preceded by '\r' | |
151 if (i && file.buffer[i - 1] == '\r') | |
152 goto Lskip; | |
153 break; | |
154 | |
155 case 0: | |
156 case 0x1A: | |
157 eof = 1; | |
158 break; | |
159 | |
160 default: | |
161 continue; | |
162 } | |
163 break; | |
164 } | |
165 | |
166 // The line is file.buffer[linestart..i] | |
167 char *line; | |
168 int len; | |
169 char *p; | |
170 char *pn; | |
171 | |
172 line = (char *)&file.buffer[linestart]; | |
173 len = i - linestart; | |
174 | |
175 buf.reset(); | |
176 | |
177 // First, expand the macros. | |
178 // Macros are bracketed by % characters. | |
179 | |
180 for (k = 0; k < len; k++) | |
181 { | |
182 if (line[k] == '%') | |
183 { | |
184 int j; | |
185 | |
186 for (j = k + 1; j < len; j++) | |
187 { | |
188 if (line[j] == '%') | |
189 { | |
190 if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0) | |
191 { | |
192 // %@P% is special meaning the path to the .ini file | |
193 p = path; | |
194 if (!*p) | |
195 p = "."; | |
196 } | |
197 else | |
198 { int len = j - k; | |
199 char tmp[10]; // big enough most of the time | |
200 | |
201 if (len <= sizeof(tmp)) | |
202 p = tmp; | |
203 else | |
204 p = (char *)alloca(len); | |
205 len--; | |
206 memcpy(p, &line[k + 1], len); | |
207 p[len] = 0; | |
208 strupr(p); | |
209 p = getenv(p); | |
210 if (!p) | |
211 p = ""; | |
212 } | |
213 buf.writestring(p); | |
214 k = j; | |
215 goto L1; | |
216 } | |
217 } | |
218 } | |
219 buf.writeByte(line[k]); | |
220 L1: | |
221 ; | |
222 } | |
223 | |
224 // Remove trailing spaces | |
225 while (buf.offset && isspace(buf.data[buf.offset - 1])) | |
226 buf.offset--; | |
227 | |
228 p = buf.toChars(); | |
229 | |
230 // The expanded line is in p. | |
231 // Now parse it for meaning. | |
232 | |
233 p = skipspace(p); | |
234 switch (*p) | |
235 { | |
236 case ';': // comment | |
237 case 0: // blank | |
238 break; | |
239 | |
240 case '[': // look for [Environment] | |
241 p = skipspace(p + 1); | |
242 for (pn = p; isalnum(*pn); pn++) | |
243 ; | |
244 if (pn - p == 11 && | |
245 memicmp(p, "Environment", 11) == 0 && | |
246 *skipspace(pn) == ']' | |
247 ) | |
248 envsection = 1; | |
249 else | |
250 envsection = 0; | |
251 break; | |
252 | |
253 default: | |
254 if (envsection) | |
255 { | |
256 pn = p; | |
257 | |
258 // Convert name to upper case; | |
259 // remove spaces bracketing = | |
260 for (p = pn; *p; p++) | |
261 { if (islower(*p)) | |
262 *p &= ~0x20; | |
263 else if (isspace(*p)) | |
264 memmove(p, p + 1, strlen(p)); | |
265 else if (*p == '=') | |
266 { | |
267 p++; | |
268 while (isspace(*p)) | |
269 memmove(p, p + 1, strlen(p)); | |
270 break; | |
271 } | |
272 } | |
273 | |
274 putenv(strdup(pn)); | |
275 #if LOG | |
276 printf("\tputenv('%s')\n", pn); | |
277 //printf("getenv(\"TEST\") = '%s'\n",getenv("TEST")); | |
278 #endif | |
279 } | |
280 break; | |
281 } | |
282 | |
283 Lskip: | |
284 ; | |
285 } | |
286 } | |
287 | |
288 /******************** | |
289 * Skip spaces. | |
290 */ | |
291 | |
292 char *skipspace(const char *p) | |
293 { | |
294 while (isspace(*p)) | |
295 p++; | |
296 return (char *)p; | |
297 } | |
298 |