rtworkq: Add RtwqJoinWorkQueue()/RtwqUnjoinWorkQueue() stubs.
[wine.git] / dlls / uxtheme / uxini.c
blob361e7f13fa5205a0674b03e4c58c7b3945d83c02
1 /*
2 * Win32 5.1 uxtheme ini file processing
4 * Copyright (C) 2004 Kevin Koltzau
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winnls.h"
27 #include "wine/debug.h"
28 #include "wine/heap.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
32 /***********************************************************************
33 * Defines and global variables
36 static const WCHAR szTextFileResource[] = {
37 'T','E','X','T','F','I','L','E','\0'
40 typedef struct _UXINI_FILE {
41 LPCWSTR lpIni;
42 LPCWSTR lpCurLoc;
43 LPCWSTR lpEnd;
44 } UXINI_FILE, *PUXINI_FILE;
46 /***********************************************************************/
48 /**********************************************************************
49 * UXINI_LoadINI
51 * Load a theme INI file out of resources from the specified
52 * theme
54 * PARAMS
55 * tf Theme to load INI file out of resources
56 * lpName Resource name of the INI file
58 * RETURNS
59 * INI file, or NULL if not found
61 PUXINI_FILE UXINI_LoadINI(HMODULE hTheme, LPCWSTR lpName) {
62 HRSRC hrsc;
63 LPCWSTR lpThemesIni = NULL;
64 PUXINI_FILE uf;
65 DWORD dwIniSize;
67 TRACE("Loading resource INI %s\n", debugstr_w(lpName));
69 if((hrsc = FindResourceW(hTheme, lpName, szTextFileResource))) {
70 if(!(lpThemesIni = LoadResource(hTheme, hrsc))) {
71 TRACE("%s resource not found\n", debugstr_w(lpName));
72 return NULL;
76 dwIniSize = SizeofResource(hTheme, hrsc) / sizeof(WCHAR);
77 uf = heap_alloc(sizeof(*uf));
78 uf->lpIni = lpThemesIni;
79 uf->lpCurLoc = lpThemesIni;
80 uf->lpEnd = lpThemesIni + dwIniSize;
81 return uf;
84 /**********************************************************************
85 * UXINI_CloseINI
87 * Close an open theme INI file
89 * PARAMS
90 * uf Theme INI file to close
92 void UXINI_CloseINI(PUXINI_FILE uf)
94 heap_free(uf);
97 /**********************************************************************
98 * UXINI_eof
100 * Determines if we are at the end of the INI file
102 * PARAMS
103 * uf Theme INI file to test
105 static inline BOOL UXINI_eof(PUXINI_FILE uf)
107 return uf->lpCurLoc >= uf->lpEnd;
110 /**********************************************************************
111 * UXINI_isspace
113 * Check if a character is a space character
115 * PARAMS
116 * c Character to test
118 static inline BOOL UXINI_isspace(WCHAR c)
120 if (isspace(c)) return TRUE;
121 if (c=='\r') return TRUE;
122 return FALSE;
125 /**********************************************************************
126 * UXINI_GetNextLine
128 * Get the next line in the INI file, non NULL terminated
129 * removes whitespace at beginning and end of line, and removes comments
131 * PARAMS
132 * uf INI file to retrieve next line
133 * dwLen Location to store pointer to line length
135 * RETURNS
136 * The section name, non NULL terminated
138 static LPCWSTR UXINI_GetNextLine(PUXINI_FILE uf, DWORD *dwLen)
140 LPCWSTR lpLineEnd;
141 LPCWSTR lpLineStart;
142 DWORD len;
143 do {
144 if(UXINI_eof(uf)) return NULL;
145 /* Skip whitespace and empty lines */
146 while(!UXINI_eof(uf) && (UXINI_isspace(*uf->lpCurLoc) || *uf->lpCurLoc == '\n')) uf->lpCurLoc++;
147 lpLineStart = uf->lpCurLoc;
148 lpLineEnd = uf->lpCurLoc;
149 while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n' && *uf->lpCurLoc != ';') lpLineEnd = ++uf->lpCurLoc;
150 /* If comment was found, skip the rest of the line */
151 if(*uf->lpCurLoc == ';')
152 while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n') uf->lpCurLoc++;
153 len = (lpLineEnd - lpLineStart);
154 if(*lpLineStart != ';' && len == 0)
155 return NULL;
156 } while(*lpLineStart == ';');
157 /* Remove whitespace from end of line */
158 while(UXINI_isspace(lpLineStart[len-1])) len--;
159 *dwLen = len;
161 return lpLineStart;
164 static inline void UXINI_UnGetToLine(PUXINI_FILE uf, LPCWSTR lpLine)
166 uf->lpCurLoc = lpLine;
169 /**********************************************************************
170 * UXINI_GetNextSection
172 * Locate the next section in the ini file, and return pointer to
173 * section name, non NULL terminated. Use dwLen to determine length
175 * PARAMS
176 * uf INI file to search, search starts at current location
177 * dwLen Location to store pointer to section name length
179 * RETURNS
180 * The section name, non NULL terminated
182 LPCWSTR UXINI_GetNextSection(PUXINI_FILE uf, DWORD *dwLen)
184 LPCWSTR lpLine;
185 while((lpLine = UXINI_GetNextLine(uf, dwLen))) {
186 /* Assuming a ']' ending to the section name */
187 if(lpLine[0] == '[') {
188 lpLine++;
189 *dwLen -= 2;
190 break;
193 return lpLine;
196 /**********************************************************************
197 * UXINI_FindSection
199 * Locate a section with the specified name, search starts
200 * at current location in ini file
202 * PARAMS
203 * uf INI file to search, search starts at current location
204 * lpName Name of the section to locate
206 * RETURNS
207 * TRUE if section was found, FALSE otherwise
209 BOOL UXINI_FindSection(PUXINI_FILE uf, LPCWSTR lpName)
211 LPCWSTR lpSection;
212 DWORD dwLen;
213 while((lpSection = UXINI_GetNextSection(uf, &dwLen))) {
214 if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpSection, dwLen, lpName, -1) == CSTR_EQUAL) {
215 return TRUE;
218 return FALSE;
221 /**********************************************************************
222 * UXINI_GetNextValue
224 * Locate the next value in the current section
226 * PARAMS
227 * uf INI file to search, search starts at current location
228 * dwNameLen Location to store pointer to value name length
229 * lpValue Location to store pointer to the value
230 * dwValueLen Location to store pointer to value length
232 * RETURNS
233 * The value name, non NULL terminated
235 LPCWSTR UXINI_GetNextValue(PUXINI_FILE uf, DWORD *dwNameLen, LPCWSTR *lpValue, DWORD *dwValueLen)
237 LPCWSTR lpLine;
238 LPCWSTR lpLineEnd;
239 LPCWSTR name = NULL;
240 LPCWSTR value = NULL;
241 DWORD vallen = 0;
242 DWORD namelen = 0;
243 DWORD dwLen;
244 lpLine = UXINI_GetNextLine(uf, &dwLen);
245 if(!lpLine)
246 return NULL;
247 if(lpLine[0] == '[') {
248 UXINI_UnGetToLine(uf, lpLine);
249 return NULL;
251 lpLineEnd = lpLine + dwLen;
253 name = lpLine;
254 while(namelen < dwLen && *lpLine != '=') {
255 lpLine++;
256 namelen++;
258 if(*lpLine != '=') return NULL;
259 lpLine++;
261 /* Remove whitespace from end of name */
262 while(UXINI_isspace(name[namelen-1])) namelen--;
263 /* Remove whitespace from beginning of value */
264 while(UXINI_isspace(*lpLine) && lpLine < lpLineEnd) lpLine++;
265 value = lpLine;
266 vallen = dwLen-(value-name);
268 *dwNameLen = namelen;
269 *dwValueLen = vallen;
270 *lpValue = value;
272 return name;
275 /**********************************************************************
276 * UXINI_FindValue
278 * Locate a value by name
280 * PARAMS
281 * uf INI file to search, search starts at current location
282 * lpName Value name to locate
283 * lpValue Location to store pointer to the value
284 * dwValueLen Location to store pointer to value length
286 * RETURNS
287 * The value name, non NULL terminated
289 BOOL UXINI_FindValue(PUXINI_FILE uf, LPCWSTR lpName, LPCWSTR *lpValue, DWORD *dwValueLen)
291 LPCWSTR name;
292 DWORD namelen;
294 while((name = UXINI_GetNextValue(uf, &namelen, lpValue, dwValueLen))) {
295 if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, name, namelen, lpName, -1) == CSTR_EQUAL) {
296 return TRUE;
299 return FALSE;