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.
19 static char Copyright
[] = "Copyright (C) 1993 Miguel de Icaza";
27 #include "prototypes.h"
29 /* #define DEBUG_PROFILE */
30 /* #undef DEBUG_PROFILE */
35 #define xmalloc(x) malloc(x)
36 #define overflow (next == &CharBuffer [STRSIZE-1])
38 enum { FirstBrace
, OnSecHeader
, IgnoreToEOL
, KeyDef
, KeyValue
};
40 typedef struct TKeys
{
46 typedef struct TSecHeader
{
49 struct TSecHeader
*link
;
52 typedef struct TProfile
{
55 struct TProfile
*link
;
58 TProfile
*Current
= 0;
61 static TSecHeader
*is_loaded (char *FileName
)
66 if (!strcasecmp (FileName
, p
->FileName
)){
75 static char *GetIniFileName(char *name
)
79 if (strchr(name
, '/'))
82 if (strchr(name
, '\\'))
83 return GetUnixFileName(name
);
85 GetWindowsDirectory(temp
, sizeof(temp
) );
89 return GetUnixFileName(temp
);
92 static TSecHeader
*load (char *filename
)
96 TSecHeader
*SecHeader
= 0;
97 char CharBuffer
[STRSIZE
];
101 file
= GetIniFileName(filename
);
103 dprintf_profile(stddeb
,"Load %s\n", file
);
104 if ((f
= fopen (file
, "r"))==NULL
)
107 dprintf_profile(stddeb
,"Loading %s\n", file
);
111 while ((c
= getc (f
)) != EOF
){
112 if (c
== '\r') /* Ignore Carriage Return */
118 if (c
== ']' || overflow
){
121 SecHeader
->AppName
= strdup (CharBuffer
);
123 dprintf_profile(stddeb
,"%s: section %s\n", file
, CharBuffer
);
141 SecHeader
= (TSecHeader
*) xmalloc (sizeof (TSecHeader
));
142 SecHeader
->link
= temp
;
148 if (state
== FirstBrace
) /* On first pass, don't allow dangling keys */
154 if (c
== '\n' || c
== ';' || overflow
) /* Abort Definition */
163 if (c
== '=' || overflow
){
166 temp
= SecHeader
->Keys
;
167 while(next
[-1]==' ')next
--;
169 SecHeader
->Keys
= (TKeys
*) xmalloc (sizeof (TKeys
));
170 SecHeader
->Keys
->link
= temp
;
171 SecHeader
->Keys
->KeyName
= strdup (CharBuffer
);
174 dprintf_profile(stddeb
,"%s: key %s\n", file
, CharBuffer
);
180 if (overflow
|| c
== '\n'){
182 SecHeader
->Keys
->Value
= strdup (CharBuffer
);
183 state
= c
== '\n' ? KeyDef
: IgnoreToEOL
;
185 dprintf_profile (stddeb
, "[%s] (%s)=%s\n", SecHeader
->AppName
,
186 SecHeader
->Keys
->KeyName
, SecHeader
->Keys
->Value
);
193 } /* while ((c = getc (f)) != EOF) */
197 static void new_key (TSecHeader
*section
, char *KeyName
, char *Value
)
201 key
= (TKeys
*) xmalloc (sizeof (TKeys
));
202 key
->KeyName
= strdup (KeyName
);
203 key
->Value
= strdup (Value
);
204 key
->link
= section
->Keys
;
208 static short GetSetProfile (int set
, LPSTR AppName
, LPSTR KeyName
,
209 LPSTR Default
, LPSTR ReturnedString
, short Size
,
217 /* Supposedly Default should NEVER be NULL. But sometimes it is. */
221 if (!(section
= is_loaded (FileName
))){
222 New
= (TProfile
*) xmalloc (sizeof (TProfile
));
224 New
->FileName
= strdup (FileName
);
225 New
->Section
= load (FileName
);
227 section
= New
->Section
;
231 for (; section
; section
= section
->link
){
232 if (strcasecmp (section
->AppName
, AppName
))
235 /* If no key value given, then list all the keys */
236 if ((!KeyName
) && (!set
)){
237 char *p
= ReturnedString
;
241 dprintf_profile(stddeb
,"GetSetProfile // KeyName == NULL, Enumeration !\n");
242 for (key
= section
->Keys
; key
; key
= key
->link
){
244 dprintf_profile(stddeb
,"GetSetProfile // No more storage for enum !\n");
247 slen
= min(strlen(key
->KeyName
) + 1, left
);
248 dprintf_profile(stddeb
,"GetSetProfile // strncpy(%p, %p, %d);\n",
249 ReturnedString
, key
->Value
, slen
);
250 strncpy (p
, key
->KeyName
, slen
);
251 dprintf_profile(stddeb
,"GetSetProfile // enum '%s' !\n", p
);
257 printf("GetSetProfile // normal end of enum !\n");
259 return (Size
- 2 - left
);
261 for (key
= section
->Keys
; key
; key
= key
->link
){
262 if (strcasecmp (key
->KeyName
, KeyName
))
266 key
->Value
= strdup (Default
? Default
: "");
269 ReturnedString
[Size
-1] = 0;
270 strncpy (ReturnedString
, key
->Value
, Size
-1);
273 /* If Getting the information, then don't write the information
274 to the INI file, need to run a couple of tests with windog */
277 new_key (section
, KeyName
, Default
);
279 ReturnedString
[Size
-1] = 0;
280 strncpy (ReturnedString
, Default
, Size
-1);
284 /* Non existent section */
286 section
= (TSecHeader
*) xmalloc (sizeof (TSecHeader
));
287 section
->AppName
= strdup (AppName
);
289 new_key (section
, KeyName
, Default
);
290 section
->link
= Current
->Section
;
291 Current
->Section
= section
;
293 ReturnedString
[Size
-1] = 0;
294 strncpy (ReturnedString
, Default
, Size
-1);
299 short GetPrivateProfileString (LPSTR AppName
, LPSTR KeyName
,
300 LPSTR Default
, LPSTR ReturnedString
,
301 short Size
, LPSTR FileName
)
305 dprintf_profile(stddeb
,"GetPrivateProfileString ('%s', '%s', '%s', %p, %d, %s\n",
306 AppName
, KeyName
, Default
, ReturnedString
, Size
, FileName
);
307 v
= GetSetProfile (0,AppName
,KeyName
,Default
,ReturnedString
,Size
,FileName
);
309 return strlen (ReturnedString
);
314 int GetProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR Default
,
315 LPSTR ReturnedString
, int Size
)
317 return GetPrivateProfileString (AppName
, KeyName
, Default
,
318 ReturnedString
, Size
, WIN_INI
);
321 WORD
GetPrivateProfileInt (LPSTR AppName
, LPSTR KeyName
, short Default
,
324 static char IntBuf
[6];
327 sprintf (buf
, "%d", Default
);
329 /* Check the exact semantic with the SDK */
330 GetPrivateProfileString (AppName
, KeyName
, buf
, IntBuf
, 6, File
);
331 if (!strcasecmp (IntBuf
, "true"))
333 if (!strcasecmp (IntBuf
, "yes"))
335 return atoi (IntBuf
);
338 WORD
GetProfileInt (LPSTR AppName
, LPSTR KeyName
, int Default
)
340 return GetPrivateProfileInt (AppName
, KeyName
, Default
, WIN_INI
);
343 BOOL
WritePrivateProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR String
,
346 return GetSetProfile (1, AppName
, KeyName
, String
, "", 0, FileName
);
349 BOOL
WriteProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR String
)
351 return (WritePrivateProfileString (AppName
, KeyName
, String
, WIN_INI
));
354 static void dump_keys (FILE *profile
, TKeys
*p
)
358 dump_keys (profile
, p
->link
);
359 fprintf (profile
, "%s=%s\r\n", p
->KeyName
, p
->Value
);
362 static void dump_sections (FILE *profile
, TSecHeader
*p
)
366 dump_sections (profile
, p
->link
);
367 fprintf (profile
, "\r\n[%s]\r\n", p
->AppName
);
368 dump_keys (profile
, p
->Keys
);
371 static void dump_profile (TProfile
*p
)
377 dump_profile (p
->link
);
378 if ((profile
= fopen (GetIniFileName(p
->FileName
), "w")) != NULL
){
379 dump_sections (profile
, p
->Section
);
384 void sync_profiles (void)