Mercurial > projects > ldc
annotate dmd/inifile.c @ 837:331a176c1f4f
Removed error on naked, not fully complete, but I'll be doing more work on it during this Christmas, and some things do work.
Fixed taking delegate of final class method. see mini/delegate3.d.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Tue, 09 Dec 2008 14:07:30 +0100 |
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 |