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";
28 /* #define DEBUG_PROFILE */
32 #define xmalloc(x) malloc(x)
33 #define overflow (next == &CharBuffer [STRSIZE-1])
35 enum { FirstBrace
, OnSecHeader
, IgnoreToEOL
, KeyDef
, KeyValue
};
37 typedef struct TKeys
{
43 typedef struct TSecHeader
{
46 struct TSecHeader
*link
;
49 typedef struct TProfile
{
52 struct TProfile
*link
;
56 TProfile
*Current
= 0;
59 static TSecHeader
*is_loaded (char *FileName
)
64 if (!strcasecmp (FileName
, p
->FileName
)){
73 static char *GetIniFileName(char *name
)
77 if (strchr(name
, '/'))
80 if (strchr(name
, '\\'))
81 return DOS_GetUnixFileName(name
);
83 GetWindowsDirectory(temp
, sizeof(temp
) );
87 return DOS_GetUnixFileName(temp
);
90 static TSecHeader
*load (char *filename
)
94 TSecHeader
*SecHeader
= 0;
95 char CharBuffer
[STRSIZE
];
99 file
= GetIniFileName(filename
);
101 dprintf_profile(stddeb
,"Load %s\n", file
);
102 if ((f
= fopen (file
, "r"))==NULL
)
105 dprintf_profile(stddeb
,"Loading %s\n", file
);
109 while ((c
= getc (f
)) != EOF
){
110 if (c
== '\r') /* Ignore Carriage Return */
116 if (c
== ']' || overflow
){
119 SecHeader
->AppName
= strdup (CharBuffer
);
121 dprintf_profile(stddeb
,"%s: section %s\n", file
, CharBuffer
);
139 SecHeader
= (TSecHeader
*) xmalloc (sizeof (TSecHeader
));
140 SecHeader
->link
= temp
;
146 if (state
== FirstBrace
) /* On first pass, don't allow dangling keys */
152 if (c
== '\n' || c
== ';' || overflow
) /* Abort Definition */
161 if (c
== '=' || overflow
){
164 temp
= SecHeader
->Keys
;
165 while(next
[-1]==' ')next
--;
167 SecHeader
->Keys
= (TKeys
*) xmalloc (sizeof (TKeys
));
168 SecHeader
->Keys
->link
= temp
;
169 SecHeader
->Keys
->KeyName
= strdup (CharBuffer
);
172 dprintf_profile(stddeb
,"%s: key %s\n", file
, CharBuffer
);
178 if (overflow
|| c
== '\n'){
180 SecHeader
->Keys
->Value
= strdup (CharBuffer
);
181 state
= c
== '\n' ? KeyDef
: IgnoreToEOL
;
183 dprintf_profile (stddeb
, "[%s] (%s)=%s\n", SecHeader
->AppName
,
184 SecHeader
->Keys
->KeyName
, SecHeader
->Keys
->Value
);
191 } /* while ((c = getc (f)) != EOF) */
195 static void new_key (TSecHeader
*section
, char *KeyName
, char *Value
)
199 key
= (TKeys
*) xmalloc (sizeof (TKeys
));
200 key
->KeyName
= strdup (KeyName
);
201 key
->Value
= strdup (Value
);
202 key
->link
= section
->Keys
;
206 static short GetSetProfile (int set
, LPSTR AppName
, LPSTR KeyName
,
207 LPSTR Default
, LPSTR ReturnedString
, short Size
,
215 /* Supposedly Default should NEVER be NULL. But sometimes it is. */
219 if (!(section
= is_loaded (FileName
))){
220 New
= (TProfile
*) xmalloc (sizeof (TProfile
));
222 New
->FileName
= strdup (FileName
);
223 New
->Section
= load (FileName
);
224 New
->changed
= FALSE
;
226 section
= New
->Section
;
230 for (; section
; section
= section
->link
){
231 if (strcasecmp (section
->AppName
, AppName
))
234 /* If no key value given, then list all the keys */
235 if ((!KeyName
) && (!set
)){
236 char *p
= ReturnedString
;
240 dprintf_profile(stddeb
,"GetSetProfile // KeyName == NULL, Enumeration !\n");
241 for (key
= section
->Keys
; key
; key
= key
->link
){
243 dprintf_profile(stddeb
,"GetSetProfile // No more storage for enum !\n");
246 slen
= min(strlen(key
->KeyName
) + 1, left
);
247 dprintf_profile(stddeb
,"GetSetProfile // strncpy(%p, %p, %d);\n",
248 ReturnedString
, key
->Value
, slen
);
249 strncpy (p
, key
->KeyName
, slen
);
250 dprintf_profile(stddeb
,"GetSetProfile // enum '%s' !\n", p
);
255 dprintf_profile(stddeb
,"GetSetProfile // normal end of enum !\n");
256 return (Size
- 2 - left
);
258 for (key
= section
->Keys
; key
; key
= key
->link
){
259 if (strcasecmp (key
->KeyName
, KeyName
))
263 key
->Value
= strdup (Default
? Default
: "");
264 Current
->changed
=TRUE
;
267 ReturnedString
[Size
-1] = 0;
268 strncpy (ReturnedString
, key
->Value
, Size
-1);
271 /* If Getting the information, then don't write the information
272 to the INI file, need to run a couple of tests with windog */
275 new_key (section
, KeyName
, Default
);
277 ReturnedString
[Size
-1] = 0;
278 strncpy (ReturnedString
, Default
, Size
-1);
282 /* Non existent section */
284 section
= (TSecHeader
*) xmalloc (sizeof (TSecHeader
));
285 section
->AppName
= strdup (AppName
);
287 new_key (section
, KeyName
, Default
);
288 section
->link
= Current
->Section
;
289 Current
->Section
= section
;
290 Current
->changed
= TRUE
;
292 ReturnedString
[Size
-1] = 0;
293 strncpy (ReturnedString
, Default
, Size
-1);
298 short GetPrivateProfileString (LPSTR AppName
, LPSTR KeyName
,
299 LPSTR Default
, LPSTR ReturnedString
,
300 short Size
, LPSTR FileName
)
304 dprintf_profile(stddeb
,"GetPrivateProfileString ('%s', '%s', '%s', %p, %d, %s\n",
305 AppName
, KeyName
, Default
, ReturnedString
, Size
, FileName
);
306 v
= GetSetProfile (0,AppName
,KeyName
,Default
,ReturnedString
,Size
,FileName
);
308 return strlen (ReturnedString
);
313 int GetProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR Default
,
314 LPSTR ReturnedString
, int Size
)
316 return GetPrivateProfileString (AppName
, KeyName
, Default
,
317 ReturnedString
, Size
, WIN_INI
);
320 WORD
GetPrivateProfileInt (LPSTR AppName
, LPSTR KeyName
, short Default
,
323 static char IntBuf
[6];
326 sprintf (buf
, "%d", Default
);
328 /* Check the exact semantic with the SDK */
329 GetPrivateProfileString (AppName
, KeyName
, buf
, IntBuf
, 6, File
);
330 if (!strcasecmp (IntBuf
, "true"))
332 if (!strcasecmp (IntBuf
, "yes"))
334 return atoi (IntBuf
);
337 WORD
GetProfileInt (LPSTR AppName
, LPSTR KeyName
, int Default
)
339 return GetPrivateProfileInt (AppName
, KeyName
, Default
, WIN_INI
);
342 BOOL
WritePrivateProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR String
,
345 return GetSetProfile (1, AppName
, KeyName
, String
, "", 0, FileName
);
348 BOOL
WriteProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR String
)
350 return (WritePrivateProfileString (AppName
, KeyName
, String
, WIN_INI
));
353 static void dump_keys (FILE *profile
, TKeys
*p
)
357 dump_keys (profile
, p
->link
);
358 fprintf (profile
, "%s=%s\r\n", p
->KeyName
, p
->Value
);
361 static void dump_sections (FILE *profile
, TSecHeader
*p
)
365 dump_sections (profile
, p
->link
);
366 fprintf (profile
, "\r\n[%s]\r\n", p
->AppName
);
367 dump_keys (profile
, p
->Keys
);
370 static void dump_profile (TProfile
*p
)
376 dump_profile (p
->link
);
379 if ((profile
= fopen (GetIniFileName(p
->FileName
), "w")) != NULL
){
380 dump_sections (profile
, p
->Section
);
385 void sync_profiles (void)