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);
138 while ((c = fgetc (f)) != EOF){
139 if (c == '\r') /* Ignore Carriage Return */
145 if (c == ']' || overflow){
148 SecHeader->AppName = strdup (CharBuffer);
150 dprintf_profile(stddeb,"%s: section %s\n", file, CharBuffer);
168 SecHeader = (TSecHeader *) xmalloc (sizeof (TSecHeader));
169 SecHeader->link = temp;
175 if (state == FirstBrace) /* On first pass, don't allow dangling keys */
181 if (c == '\n' || c == ';' || overflow) /* Abort Definition */
193 if (c == '=' || overflow){
196 temp = SecHeader->Keys;
197 while(next[-1]==' ')next--;
199 SecHeader->Keys = (TKeys *) xmalloc (sizeof (TKeys));
200 SecHeader->Keys->link = temp;
201 SecHeader->Keys->KeyName = strdup (CharBuffer);
204 dprintf_profile(stddeb,"%s: key %s\n", file, CharBuffer);
211 if (overflow || c == '\n'){
213 SecHeader->Keys->Value = strdup (CharBuffer);
214 state = c == '\n' ? KeyDef : IgnoreToEOL;
216 dprintf_profile (stddeb, "[%s] (%s)=%s\n", SecHeader->AppName,
217 SecHeader->Keys->KeyName, SecHeader->Keys->Value);
224 } /* while ((c = fgetc (f)) != EOF) */
228 static void new_key (TSecHeader *section, char *KeyName, char *Value)
232 key = (TKeys *) xmalloc (sizeof (TKeys));
233 key->KeyName = strdup (KeyName);
234 key->Value = strdup (Value);
235 key->link = section->Keys;
239 static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName,
240 LPSTR Default, LPSTR ReturnedString, short Size,
248 /* Supposedly Default should NEVER be NULL. But sometimes it is. */
252 if (!(section = is_loaded (FileName))){
253 New = (TProfile *) xmalloc (sizeof (TProfile));
255 New->FileName = strdup (FileName);
256 New->Section = load (FileName, &New->FullName);
257 New->changed = FALSE;
259 section = New->Section;
263 for (; section; section = section->link){
264 if (strcasecmp (section->AppName, AppName))
267 /* If no key value given, then list all the keys */
268 if ((!KeyName) && (!set)){
269 char *p = ReturnedString;
273 dprintf_profile(stddeb,"GetSetProfile // KeyName == NULL, Enumeration !\n");
274 for (key = section->Keys; key; key = key->link){
276 dprintf_profile(stddeb,"GetSetProfile // No more storage for enum !\n");
279 slen = min(strlen(key->KeyName) + 1, left);
280 dprintf_profile(stddeb,"GetSetProfile // strncpy(%p, %p, %d);\n",
281 ReturnedString, key->Value, slen);
282 strncpy (p, key->KeyName, slen);
283 dprintf_profile(stddeb,"GetSetProfile // enum '%s' !\n", p);
288 dprintf_profile(stddeb,"GetSetProfile // normal end of enum !\n");
289 return (Size - 2 - left);
291 for (key = section->Keys; key; key = key->link){
293 if (strcasecmp (key->KeyName, KeyName))
297 key->Value = strdup (Default ? Default : "");
298 Current->changed=TRUE;
301 slen = min(strlen(key->Value), Size - 1);
302 ReturnedString[slen] = 0;
303 strncpy (ReturnedString, key->Value, slen);
304 dprintf_profile(stddeb,"GetSetProfile // Return ``%s''\n", ReturnedString);
307 /* If Getting the information, then don't write the information
308 to the INI file, need to run a couple of tests with windog */
311 new_key (section, KeyName, Default);
313 int slen = min(strlen(Default), Size - 1);
314 ReturnedString[slen] = 0;
315 strncpy(ReturnedString, Default, slen);
316 dprintf_profile(stddeb,"GetSetProfile // Key not found\n");
320 /* Non existent section */
322 section = (TSecHeader *) xmalloc (sizeof (TSecHeader));
323 section->AppName = strdup (AppName);
325 new_key (section, KeyName, Default);
326 section->link = Current->Section;
327 Current->Section = section;
328 Current->changed = TRUE;
330 int slen = min(strlen(Default), Size - 1);
331 ReturnedString[slen] = 0;
332 strncpy(ReturnedString, Default, slen);
333 dprintf_profile(stddeb,"GetSetProfile // Section not found\n");
338 short GetPrivateProfileString (LPSTR AppName, LPSTR KeyName,
339 LPSTR Default, LPSTR ReturnedString,
340 short Size, LPSTR FileName)
344 dprintf_profile(stddeb,"GetPrivateProfileString ('%s', '%s', '%s', %p, %d, %s\n",
345 AppName, KeyName, Default, ReturnedString, Size, FileName);
346 v = GetSetProfile (0,AppName,KeyName,Default,ReturnedString,Size,FileName);
348 return strlen (ReturnedString);
353 int GetProfileString (LPSTR AppName, LPSTR KeyName, LPSTR Default,
354 LPSTR ReturnedString, int Size)
356 return GetPrivateProfileString (AppName, KeyName, Default,
357 ReturnedString, Size, WIN_INI);
360 WORD GetPrivateProfileInt (LPSTR AppName, LPSTR KeyName, short Default,
363 static char IntBuf[10];
366 sprintf (buf, "%d", Default);
368 /* Check the exact semantic with the SDK */
369 GetPrivateProfileString (AppName, KeyName, buf, IntBuf, 10, File);
370 if (!strcasecmp (IntBuf, "true"))
372 if (!strcasecmp (IntBuf, "yes"))
374 return strtoul( IntBuf, NULL, 0 );
377 WORD GetProfileInt (LPSTR AppName, LPSTR KeyName, int Default)
379 return GetPrivateProfileInt (AppName, KeyName, Default, WIN_INI);
382 BOOL WritePrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String,
385 if (!AppName || !KeyName || !String) /* Flush file to disk */
387 return GetSetProfile (1, AppName, KeyName, String, "", 0, FileName);
390 BOOL WriteProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String)
392 return (WritePrivateProfileString (AppName, KeyName, String, WIN_INI));
395 static void dump_keys (FILE *profile, TKeys *p)
399 dump_keys (profile, p->link);
400 fprintf (profile, "%s=%s\r\n", p->KeyName, p->Value);
403 static void dump_sections (FILE *profile, TSecHeader *p)
407 dump_sections (profile, p->link);
408 fprintf (profile, "\r\n[%s]\r\n", p->AppName);
409 dump_keys (profile, p->Keys);
412 static void dump_profile (TProfile *p)
418 dump_profile (p->link);
421 if ((profile = fopen (p->FullName, "w")) != NULL){
422 dump_sections (profile, p->Section);
427 void sync_profiles (void)