Mercurial > projects > ldc
annotate dmd/inifile.c @ 932:5e3bb0c3ea8b
Fixed dstress/run/a/array_initialization_17_A.d regression. default initialized static array elements in a constant static array initializer was getting incorrect values.
Fixed minor version problem in mini/naked_asm4.d test case.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Tue, 03 Feb 2009 23:48:47 +0100 |
parents | aa953cc960b6 |
children | 2667e3a145be |
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 | |
872
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
571
diff
changeset
|
13 #if (defined (__SVR4) && defined (__sun)) |
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
571
diff
changeset
|
14 #include <alloca.h> |
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
571
diff
changeset
|
15 #endif |
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
571
diff
changeset
|
16 |
1 | 17 #include "root.h" |
18 #include "mem.h" | |
19 | |
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
|
20 #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
|
21 #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
|
22 #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
|
23 |
1 | 24 #define LOG 0 |
25 | |
26 char *skipspace(const char *p); | |
27 | |
28 #if __GNUC__ | |
29 char *strupr(char *s) | |
30 { | |
31 char *t = s; | |
32 | |
33 while (*s) | |
34 { | |
35 *s = toupper(*s); | |
36 s++; | |
37 } | |
38 | |
39 return t; | |
40 } | |
41 #endif /* unix */ | |
42 | |
43 /***************************** | |
44 * Read and analyze .ini file. | |
45 * Input: | |
46 * argv0 program name (argv[0]) | |
47 * inifile .ini file name | |
48 */ | |
49 | |
50 void inifile(char *argv0, char *inifile) | |
51 { | |
52 char *path; // need path for @P macro | |
53 char *filename; | |
54 OutBuffer buf; | |
55 int i; | |
56 int k; | |
57 int envsection = 0; | |
58 | |
59 #if LOG | |
60 printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile); | |
61 #endif | |
62 if (FileName::absolute(inifile)) | |
63 { | |
64 filename = inifile; | |
65 } | |
66 else | |
67 { | |
68 /* Look for inifile in the following sequence of places: | |
69 * o current directory | |
70 * o home directory | |
71 * o directory off of argv0 | |
72 * o /etc/ | |
73 */ | |
74 if (FileName::exists(inifile)) | |
75 { | |
76 filename = inifile; | |
77 } | |
78 else | |
79 { | |
80 filename = FileName::combine(getenv("HOME"), inifile); | |
81 if (!FileName::exists(filename)) | |
82 { | |
83 filename = FileName::replaceName(argv0, inifile); | |
84 if (!FileName::exists(filename)) | |
85 { | |
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
|
86 #if POSIX |
35
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
87 |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
88 #if 0 |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
89 #if __GLIBC__ // This fix by Thomas Kuehne |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
90 /* argv0 might be a symbolic link, |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
91 * 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
|
92 */ |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
93 char* real_argv0 = realpath(argv0, NULL); |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
94 if (real_argv0) |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
95 { |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
96 filename = FileName::replaceName(real_argv0, inifile); |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
97 free(real_argv0); |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
98 if (FileName::exists(filename)) |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
99 goto Ldone; |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
100 } |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
101 #else |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
102 #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
|
103 #endif |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
104 #endif |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
105 |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
106 // 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
|
107 // and some other instance might be found |
3cfcb944304e
[svn r39] * Updated to DMD 1.022 with the exception of:
lindquist
parents:
1
diff
changeset
|
108 |
1 | 109 // Search PATH for argv0 |
110 const char *p = getenv("PATH"); | |
111 Array *paths = FileName::splitPath(p); | |
112 filename = FileName::searchPath(paths, argv0, 0); | |
113 if (!filename) | |
114 goto Letc; // argv0 not found on path | |
115 filename = FileName::replaceName(filename, inifile); | |
116 if (FileName::exists(filename)) | |
117 goto Ldone; | |
118 #endif | |
119 | |
120 // Search /etc/ for inifile | |
121 Letc: | |
122 filename = FileName::combine("/etc/", inifile); | |
123 | |
124 Ldone: | |
125 ; | |
126 } | |
127 } | |
128 } | |
129 } | |
130 path = FileName::path(filename); | |
131 #if LOG | |
132 printf("\tpath = '%s', filename = '%s'\n", path, filename); | |
133 #endif | |
134 | |
135 File file(filename); | |
136 | |
137 if (file.read()) | |
138 return; // error reading file | |
139 | |
140 // Parse into lines | |
141 int eof = 0; | |
142 for (i = 0; i < file.len && !eof; i++) | |
143 { | |
144 int linestart = i; | |
145 | |
146 for (; i < file.len; i++) | |
147 { | |
148 switch (file.buffer[i]) | |
149 { | |
150 case '\r': | |
151 break; | |
152 | |
153 case '\n': | |
154 // Skip if it was preceded by '\r' | |
155 if (i && file.buffer[i - 1] == '\r') | |
156 goto Lskip; | |
157 break; | |
158 | |
159 case 0: | |
160 case 0x1A: | |
161 eof = 1; | |
162 break; | |
163 | |
164 default: | |
165 continue; | |
166 } | |
167 break; | |
168 } | |
169 | |
170 // The line is file.buffer[linestart..i] | |
171 char *line; | |
172 int len; | |
173 char *p; | |
174 char *pn; | |
175 | |
176 line = (char *)&file.buffer[linestart]; | |
177 len = i - linestart; | |
178 | |
179 buf.reset(); | |
180 | |
181 // First, expand the macros. | |
182 // Macros are bracketed by % characters. | |
183 | |
184 for (k = 0; k < len; k++) | |
185 { | |
186 if (line[k] == '%') | |
187 { | |
188 int j; | |
189 | |
190 for (j = k + 1; j < len; j++) | |
191 { | |
192 if (line[j] == '%') | |
193 { | |
194 if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0) | |
195 { | |
196 // %@P% is special meaning the path to the .ini file | |
197 p = path; | |
198 if (!*p) | |
199 p = "."; | |
200 } | |
201 else | |
202 { int len = j - k; | |
203 char tmp[10]; // big enough most of the time | |
204 | |
205 if (len <= sizeof(tmp)) | |
206 p = tmp; | |
207 else | |
208 p = (char *)alloca(len); | |
209 len--; | |
210 memcpy(p, &line[k + 1], len); | |
211 p[len] = 0; | |
212 strupr(p); | |
213 p = getenv(p); | |
214 if (!p) | |
215 p = ""; | |
216 } | |
217 buf.writestring(p); | |
218 k = j; | |
219 goto L1; | |
220 } | |
221 } | |
222 } | |
223 buf.writeByte(line[k]); | |
224 L1: | |
225 ; | |
226 } | |
227 | |
228 // Remove trailing spaces | |
229 while (buf.offset && isspace(buf.data[buf.offset - 1])) | |
230 buf.offset--; | |
231 | |
232 p = buf.toChars(); | |
233 | |
234 // The expanded line is in p. | |
235 // Now parse it for meaning. | |
236 | |
237 p = skipspace(p); | |
238 switch (*p) | |
239 { | |
240 case ';': // comment | |
241 case 0: // blank | |
242 break; | |
243 | |
244 case '[': // look for [Environment] | |
245 p = skipspace(p + 1); | |
246 for (pn = p; isalnum(*pn); pn++) | |
247 ; | |
248 if (pn - p == 11 && | |
249 memicmp(p, "Environment", 11) == 0 && | |
250 *skipspace(pn) == ']' | |
251 ) | |
252 envsection = 1; | |
253 else | |
254 envsection = 0; | |
255 break; | |
256 | |
257 default: | |
258 if (envsection) | |
259 { | |
260 pn = p; | |
261 | |
262 // Convert name to upper case; | |
263 // remove spaces bracketing = | |
264 for (p = pn; *p; p++) | |
265 { if (islower(*p)) | |
266 *p &= ~0x20; | |
267 else if (isspace(*p)) | |
268 memmove(p, p + 1, strlen(p)); | |
269 else if (*p == '=') | |
270 { | |
271 p++; | |
272 while (isspace(*p)) | |
273 memmove(p, p + 1, strlen(p)); | |
274 break; | |
275 } | |
276 } | |
277 | |
278 putenv(strdup(pn)); | |
279 #if LOG | |
280 printf("\tputenv('%s')\n", pn); | |
281 //printf("getenv(\"TEST\") = '%s'\n",getenv("TEST")); | |
282 #endif | |
283 } | |
284 break; | |
285 } | |
286 | |
287 Lskip: | |
288 ; | |
289 } | |
290 } | |
291 | |
292 /******************** | |
293 * Skip spaces. | |
294 */ | |
295 | |
296 char *skipspace(const char *p) | |
297 { | |
298 while (isspace(*p)) | |
299 p++; | |
300 return (char *)p; | |
301 } | |
302 |