2 // Copyright (c) 1999-2006 by Digital Mars
4 // written by Walter Bright
5 // http://www.digitalmars.com
18 char *skipspace(const char *p
);
35 /*****************************
36 * Read and analyze .ini file.
38 * argv0 program name (argv[0])
39 * inifile .ini file name
42 void inifile(char *argv0
, char *inifile
)
44 char *path
; // need path for @P macro
52 printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0
, inifile
);
54 if (FileName::absolute(inifile
))
60 /* Look for inifile in the following sequence of places:
63 * o directory off of argv0
66 if (FileName::exists(inifile
))
72 filename
= FileName::combine(getenv("HOME"), inifile
);
73 if (!FileName::exists(filename
))
75 filename
= FileName::replaceName(argv0
, inifile
);
76 if (!FileName::exists(filename
))
79 #if __GLIBC__ // This fix by Thomas Kuehne
80 /* argv0 might be a symbolic link,
81 * so try again looking past it to the real path
83 char* real_argv0
= realpath(argv0
, NULL
);
84 //printf("argv0 = %s, real_argv0 = %p\n", argv0, real_argv0);
87 filename
= FileName::replaceName(real_argv0
, inifile
);
89 if (FileName::exists(filename
))
93 #error use of glibc non-standard extension realpath(char*, NULL)
96 // Search PATH for argv0
97 const char *p
= getenv("PATH");
98 Array
*paths
= FileName::splitPath(p
);
99 filename
= FileName::searchPath(paths
, argv0
, 0);
101 goto Letc
; // argv0 not found on path
102 filename
= FileName::replaceName(filename
, inifile
);
103 if (FileName::exists(filename
))
108 // Search /etc/ for inifile
110 filename
= FileName::combine("/etc/", inifile
);
118 path
= FileName::path(filename
);
120 printf("\tpath = '%s', filename = '%s'\n", path
, filename
);
126 return; // error reading file
130 for (i
= 0; i
< file
.len
&& !eof
; i
++)
134 for (; i
< file
.len
; i
++)
136 switch (file
.buffer
[i
])
142 // Skip if it was preceded by '\r'
143 if (i
&& file
.buffer
[i
- 1] == '\r')
158 // The line is file.buffer[linestart..i]
164 line
= (char *)&file
.buffer
[linestart
];
169 // First, expand the macros.
170 // Macros are bracketed by % characters.
172 for (k
= 0; k
< len
; k
++)
178 for (j
= k
+ 1; j
< len
; j
++)
182 if (j
- k
== 3 && memicmp(&line
[k
+ 1], "@P", 2) == 0)
184 // %@P% is special meaning the path to the .ini file
191 char tmp
[10]; // big enough most of the time
193 if (len
<= sizeof(tmp
))
196 p
= (char *)alloca(len
);
198 memcpy(p
, &line
[k
+ 1], len
);
211 buf
.writeByte(line
[k
]);
216 // Remove trailing spaces
217 while (buf
.offset
&& isspace(buf
.data
[buf
.offset
- 1]))
222 // The expanded line is in p.
223 // Now parse it for meaning.
232 case '[': // look for [Environment]
233 p
= skipspace(p
+ 1);
234 for (pn
= p
; isalnum(*pn
); pn
++)
237 memicmp(p
, "Environment", 11) == 0 &&
238 *skipspace(pn
) == ']'
250 // Convert name to upper case;
251 // remove spaces bracketing =
252 for (p
= pn
; *p
; p
++)
255 else if (isspace(*p
))
256 memmove(p
, p
+ 1, strlen(p
));
261 memmove(p
, p
+ 1, strlen(p
));
268 printf("\tputenv('%s')\n", pn
);
269 //printf("getenv(\"TEST\") = '%s'\n",getenv("TEST"));
280 /********************
284 char *skipspace(const char *p
)