Release 0.4.7
[wine/testsucceed.git] / misc / profile.c
blobac50d862833b90f19a7dc3263f1836e015edad24
1 /*
2 * Initialization-File Functions.
4 * Copyright (c) 1993 Miguel de Icaza
6 */
8 static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza";
10 #include <stdio.h>
11 #include <string.h>
12 #include "windows.h"
13 #include "wine.h"
15 #define INIFILE GetSystemIniFilename()
16 #define STRSIZE 255
17 #define xmalloc(x) malloc(x)
18 #define overflow (next == &CharBuffer [STRSIZE-1])
20 enum { FirstBrace, OnSecHeader, IgnoreToEOL, KeyDef, KeyValue };
22 typedef struct TKeys {
23 char *KeyName;
24 char *Value;
25 struct TKeys *link;
26 } TKeys;
28 typedef struct TSecHeader {
29 char *AppName;
30 TKeys *Keys;
31 struct TSecHeader *link;
32 } TSecHeader;
34 typedef struct TProfile {
35 char *FileName;
36 TSecHeader *Section;
37 struct TProfile *link;
38 } TProfile;
40 TProfile *Current = 0;
41 TProfile *Base = 0;
43 static TSecHeader *is_loaded (char *FileName)
45 TProfile *p = Base;
47 while (p){
48 if (!strcasecmp (FileName, p->FileName)){
49 Current = p;
50 return p->Section;
52 p = p->link;
54 return 0;
57 static TSecHeader *load (char *file)
59 FILE *f;
60 int state;
61 TSecHeader *SecHeader = 0;
62 char CharBuffer [STRSIZE];
63 char *next;
64 char c;
66 if ((f = fopen (file, "r"))==NULL)
67 return NULL;
69 state = FirstBrace;
70 while ((c = getc (f)) != EOF){
71 if (c == '\r') /* Ignore Carriage Return */
72 continue;
74 switch (state){
76 case OnSecHeader:
77 if (c == ']' || overflow){
78 *next = '\0';
79 next = CharBuffer;
80 SecHeader->AppName = strdup (CharBuffer);
81 state = IgnoreToEOL;
82 } else
83 *next++ = c;
84 break;
86 case IgnoreToEOL:
87 if (c == '\n'){
88 state = KeyDef;
89 next = CharBuffer;
91 break;
93 case FirstBrace:
94 case KeyDef:
95 if (c == '['){
96 TSecHeader *temp;
98 temp = SecHeader;
99 SecHeader = (TSecHeader *) xmalloc (sizeof (TSecHeader));
100 SecHeader->link = temp;
101 SecHeader->Keys = 0;
102 state = OnSecHeader;
103 next = CharBuffer;
104 break;
106 if (state == FirstBrace) /* On first pass, don't allow dangling keys */
107 break;
109 if (c == ' ' || c == '\t')
110 break;
112 if (c == '\n' || overflow) /* Abort Definition */
113 next = CharBuffer;
115 if (c == '=' || overflow){
116 TKeys *temp;
118 temp = SecHeader->Keys;
119 *next = '\0';
120 SecHeader->Keys = (TKeys *) xmalloc (sizeof (TKeys));
121 SecHeader->Keys->link = temp;
122 SecHeader->Keys->KeyName = strdup (CharBuffer);
123 state = KeyValue;
124 next = CharBuffer;
125 } else
126 *next++ = c;
127 break;
129 case KeyValue:
130 if (overflow || c == '\n'){
131 *next = '\0';
132 SecHeader->Keys->Value = strdup (CharBuffer);
133 state = c == '\n' ? KeyDef : IgnoreToEOL;
134 next = CharBuffer;
135 #ifdef DEBUG
136 printf ("[%s] (%s)=%s\n", SecHeader->AppName,
137 SecHeader->Keys->KeyName, SecHeader->Keys->Value);
138 #endif
139 } else
140 *next++ = c;
141 break;
143 } /* switch */
145 } /* while ((c = getc (f)) != EOF) */
146 return SecHeader;
149 static new_key (TSecHeader *section, char *KeyName, char *Value)
151 TKeys *key;
153 key = (TKeys *) xmalloc (sizeof (TKeys));
154 key->KeyName = strdup (KeyName);
155 key->Value = strdup (Value);
156 key->link = section->Keys;
157 section->Keys = key;
160 static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName,
161 LPSTR Default, LPSTR ReturnedString, short Size,
162 LPSTR FileName)
165 TProfile *New;
166 TSecHeader *section;
167 TKeys *key;
169 if (!(section = is_loaded (FileName))){
170 New = (TProfile *) xmalloc (sizeof (TProfile));
171 New->link = Base;
172 New->FileName = strdup (FileName);
173 New->Section = load (FileName);
174 Base = New;
175 section = New->Section;
176 Current = New;
179 /* Start search */
180 for (; section; section = section->link){
181 if (strcasecmp (section->AppName, AppName))
182 continue;
183 for (key = section->Keys; key; key = key->link){
184 if (strcasecmp (key->KeyName, KeyName))
185 continue;
186 if (set){
187 free (key->Value);
188 key->Value = strdup (Default);
189 return 1;
191 ReturnedString [Size-1] = 0;
192 strncpy (ReturnedString, key->Value, Size-1);
193 return 1;
195 /* If Getting the information, then don't write the information
196 to the INI file, need to run a couple of tests with windog */
197 /* No key found */
198 if (set)
199 new_key (section, KeyName, Default);
200 else {
201 ReturnedString [Size-1] = 0;
202 strncpy (ReturnedString, Default, Size-1);
204 return 1;
206 /* Non existent section */
207 if (set){
208 section = (TSecHeader *) xmalloc (sizeof (TSecHeader));
209 section->AppName = strdup (AppName);
210 section->Keys = 0;
211 new_key (section, KeyName, Default);
212 section->link = Current->Section;
213 Current->Section = section;
214 } else {
215 ReturnedString [Size-1] = 0;
216 strncpy (ReturnedString, Default, Size-1);
218 return 1;
221 short GetPrivateProfileString (LPSTR AppName, LPSTR KeyName,
222 LPSTR Default, LPSTR ReturnedString,
223 short Size, LPSTR FileName)
225 return (GetSetProfile (0, AppName, KeyName, Default, ReturnedString, Size, FileName));
228 int GetProfileString (LPSTR AppName, LPSTR KeyName, LPSTR Default,
229 LPSTR ReturnedString, int Size)
231 return GetPrivateProfileString (AppName, KeyName, Default,
232 ReturnedString, Size, INIFILE);
235 WORD GetPrivateProfileInt (LPSTR AppName, LPSTR KeyName, short Default,
236 LPSTR File)
238 static char IntBuf [5];
239 static char buf [5];
241 sprintf (buf, "%d", Default);
243 /* Check the exact semantic with the SDK */
244 GetPrivateProfileString (AppName, KeyName, buf, IntBuf, 5, File);
245 if (!strcasecmp (IntBuf, "true"))
246 return 1;
247 if (!strcasecmp (IntBuf, "yes"))
248 return 1;
249 return atoi (IntBuf);
252 WORD GetProfileInt (LPSTR AppName, LPSTR KeyName, int Default)
254 return GetPrivateProfileInt (AppName, KeyName, Default, INIFILE);
257 BOOL WritePrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String,
258 LPSTR FileName)
260 return GetSetProfile (1, AppName, KeyName, String, "", 0, FileName);
263 BOOL WriteProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String)
265 return (WritePrivateProfileString (AppName, KeyName, String, INIFILE));
268 static void dump_keys (FILE *profile, TKeys *p)
270 if (!p)
271 return;
272 dump_keys (profile, p->link);
273 fprintf (profile, "%s=%s\r\n", p->KeyName, p->Value);
276 static void dump_sections (FILE *profile, TSecHeader *p)
278 if (!p)
279 return;
280 dump_sections (profile, p->link);
281 fprintf (profile, "\r\n[%s]\r\n", p->AppName);
282 dump_keys (profile, p->Keys);
285 static void dump_profile (TProfile *p)
287 FILE *profile;
289 if (!p)
290 return;
291 dump_profile (p->link);
292 if ((profile = fopen (p->FileName, "w")) != NULL){
293 dump_sections (profile, p->Section);
294 fclose (profile);
298 void sync_profiles ()
300 dump_profile (Base);