2 * Initialization-File Functions.
4 * Copyright (c) 1993 Miguel de Icaza
6 * 1/Dec o Corrected return values for Get*ProfileString
8 * o Now, if AppName == NULL in Get*ProfileString it returns a list
9 * of the KeyNames (as documented in the MS-SDK).
11 * o if KeyValue == NULL now clears the value in Get*ProfileString
13 * 20/Apr SL - I'm not sure where these definitions came from, but my SDK
14 * has a NULL KeyValue returning a list of KeyNames, and a NULL
15 * AppName undefined. I changed GetSetProfile to match. This makes
16 * PROGMAN.EXE do the right thing.
18 static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza";
30 /* #define DEBUG_PROFILE */
34 #define xmalloc(x) malloc(x)
35 #define overflow (next == &CharBuffer [STRSIZE-1])
37 enum { FirstBrace, OnSecHeader, IgnoreToEOL, KeyDef, KeyValue };
39 typedef struct TKeys {
45 typedef struct TSecHeader {
48 struct TSecHeader *link;
51 typedef struct TProfile {
55 struct TProfile *link;
59 TProfile *Current = 0;
62 static TSecHeader *is_loaded (char *FileName)
67 if (!strcasecmp (FileName, p->FileName)){
76 static char *GetIniFileName(char *name, char *dir)
80 if (strchr(name, '/'))
83 if (strchr(name, '\\'))
84 return DOS_GetUnixFileName(name);
90 return DOS_GetUnixFileName(temp);
93 static TSecHeader *load (char *filename, char **pfullname)
97 TSecHeader *SecHeader = 0;
98 char CharBuffer [STRSIZE];
102 char path[MAX_PATH+1];
104 /* Try the Windows directory */
106 GetWindowsDirectory(path, sizeof(path));
107 file = GetIniFileName(filename, path);
109 dprintf_profile(stddeb,"Load %s\n", file);
110 f = fopen(file, "r");
113 /* Try the path of the current executable */
115 if (GetCurrentTask())
118 GetModuleFileName( GetCurrentTask(), path, MAX_PATH );
119 if ((p = strrchr( path, '\\' )))
122 file = GetIniFileName(filename, path);
123 f = fopen(file, "r");
128 fprintf(stderr, "profile.c: load() can't find file %s\n", filename);
132 *pfullname = strdup(file);
133 dprintf_profile(stddeb,"Loading %s\n", file);
137 while ((c = fgetc (f)) != EOF){
138 if (c == '\r') /* Ignore Carriage Return */
144 if (c == ']' || overflow){
147 SecHeader->AppName = strdup (CharBuffer);
149 dprintf_profile(stddeb,"%s: section %s\n", file, CharBuffer);
167 SecHeader = (TSecHeader *) xmalloc (sizeof (TSecHeader));
168 SecHeader->link = temp;
174 if (state == FirstBrace) /* On first pass, don't allow dangling keys */
180 if (c == '\n' || c == ';' || overflow) /* Abort Definition */
192 if (c == '=' || overflow){
195 temp = SecHeader->Keys;
196 while(next[-1]==' ')next--;
198 SecHeader->Keys = (TKeys *) xmalloc (sizeof (TKeys));
199 SecHeader->Keys->link = temp;
200 SecHeader->Keys->KeyName = strdup (CharBuffer);
203 dprintf_profile(stddeb,"%s: key %s\n", file, CharBuffer);
210 if (overflow || c == '\n'){
212 SecHeader->Keys->Value = strdup (CharBuffer);
213 state = c == '\n' ? KeyDef : IgnoreToEOL;
215 dprintf_profile (stddeb, "[%s] (%s)=%s\n", SecHeader->AppName,
216 SecHeader->Keys->KeyName, SecHeader->Keys->Value);
223 } /* while ((c = fgetc (f)) != EOF) */
227 static void new_key (TSecHeader *section, char *KeyName, char *Value)
231 key = (TKeys *) xmalloc (sizeof (TKeys));
232 key->KeyName = strdup (KeyName);
233 key->Value = strdup (Value);
234 key->link = section->Keys;
238 static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName,
239 LPSTR Default, LPSTR ReturnedString, short Size,
247 /* Supposedly Default should NEVER be NULL. But sometimes it is. */
251 if (!(section = is_loaded (FileName))){
252 New = (TProfile *) xmalloc (sizeof (TProfile));
254 New->FileName = strdup (FileName);
255 New->Section = load (FileName, &New->FullName);
256 New->changed = FALSE;
258 section = New->Section;
262 for (; section; section = section->link){
263 if (strcasecmp (section->AppName, AppName))
266 /* If no key value given, then list all the keys */
267 if ((!KeyName) && (!set)){
268 char *p = ReturnedString;
272 dprintf_profile(stddeb,"GetSetProfile // KeyName == NULL, Enumeration !\n");
273 for (key = section->Keys; key; key = key->link){
275 dprintf_profile(stddeb,"GetSetProfile // No more storage for enum !\n");
278 slen = min(strlen(key->KeyName) + 1, left);
279 dprintf_profile(stddeb,"GetSetProfile // strncpy(%p, %p, %d);\n",
280 ReturnedString, key->Value, slen);
281 strncpy (p, key->KeyName, slen);
282 dprintf_profile(stddeb,"GetSetProfile // enum '%s' !\n", p);
287 dprintf_profile(stddeb,"GetSetProfile // normal end of enum !\n");
288 return (Size - 2 - left);
290 for (key = section->Keys; key; key = key->link){
292 if (strcasecmp (key->KeyName, KeyName))
296 key->Value = strdup (Default ? Default : "");
297 Current->changed=TRUE;
300 slen = min(strlen(key->Value), Size - 1);
301 ReturnedString[slen] = 0;
302 strncpy (ReturnedString, key->Value, slen);
303 dprintf_profile(stddeb,"GetSetProfile // Return ``%s''\n", ReturnedString);
306 /* If Getting the information, then don't write the information
307 to the INI file, need to run a couple of tests with windog */
310 new_key (section, KeyName, Default);
312 int slen = min(strlen(Default), Size - 1);
313 ReturnedString[slen] = 0;
314 strncpy(ReturnedString, Default, slen);
315 dprintf_profile(stddeb,"GetSetProfile // Key not found\n");
319 /* Non existent section */
321 section = (TSecHeader *) xmalloc (sizeof (TSecHeader));
322 section->AppName = strdup (AppName);
324 new_key (section, KeyName, Default);
325 section->link = Current->Section;
326 Current->Section = section;
327 Current->changed = TRUE;
329 int slen = min(strlen(Default), Size - 1);
330 ReturnedString[slen] = 0;
331 strncpy(ReturnedString, Default, slen);
332 dprintf_profile(stddeb,"GetSetProfile // Section not found\n");
337 short GetPrivateProfileString (LPSTR AppName, LPSTR KeyName,
338 LPSTR Default, LPSTR ReturnedString,
339 short Size, LPSTR FileName)
343 dprintf_profile(stddeb,"GetPrivateProfileString ('%s', '%s', '%s', %p, %d, %s\n",
344 AppName, KeyName, Default, ReturnedString, Size, FileName);
345 v = GetSetProfile (0,AppName,KeyName,Default,ReturnedString,Size,FileName);
347 return strlen (ReturnedString);
352 int GetProfileString (LPSTR AppName, LPSTR KeyName, LPSTR Default,
353 LPSTR ReturnedString, int Size)
355 return GetPrivateProfileString (AppName, KeyName, Default,
356 ReturnedString, Size, WIN_INI);
359 WORD GetPrivateProfileInt (LPSTR AppName, LPSTR KeyName, short Default,
362 static char IntBuf[10];
365 sprintf (buf, "%d", Default);
367 /* Check the exact semantic with the SDK */
368 GetPrivateProfileString (AppName, KeyName, buf, IntBuf, 10, File);
369 if (!strcasecmp (IntBuf, "true"))
371 if (!strcasecmp (IntBuf, "yes"))
373 return strtoul( IntBuf, NULL, 0 );
376 WORD GetProfileInt (LPSTR AppName, LPSTR KeyName, int Default)
378 return GetPrivateProfileInt (AppName, KeyName, Default, WIN_INI);
381 BOOL WritePrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String,
384 return GetSetProfile (1, AppName, KeyName, String, "", 0, FileName);
387 BOOL WriteProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String)
389 return (WritePrivateProfileString (AppName, KeyName, String, WIN_INI));
392 static void dump_keys (FILE *profile, TKeys *p)
396 dump_keys (profile, p->link);
397 fprintf (profile, "%s=%s\r\n", p->KeyName, p->Value);
400 static void dump_sections (FILE *profile, TSecHeader *p)
404 dump_sections (profile, p->link);
405 fprintf (profile, "\r\n[%s]\r\n", p->AppName);
406 dump_keys (profile, p->Keys);
409 static void dump_profile (TProfile *p)
415 dump_profile (p->link);
418 if ((profile = fopen (p->FullName, "w")) != NULL){
419 dump_sections (profile, p->Section);
424 void sync_profiles (void)