d3d11/tests: Add some tests for ID3DUserDefinedAnnotation.
[wine.git] / dlls / uxtheme / uxini.c
blob41a0551f82bdcff5d85dd821c9baddae63dd4f9c
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 typedef struct _UXINI_FILE {
37 LPCWSTR lpIni;
38 LPCWSTR lpCurLoc;
39 LPCWSTR lpEnd;
40 } UXINI_FILE, *PUXINI_FILE;
42 /***********************************************************************/
44 /**********************************************************************
45 * UXINI_LoadINI
47 * Load a theme INI file out of resources from the specified
48 * theme
50 * PARAMS
51 * tf Theme to load INI file out of resources
52 * lpName Resource name of the INI file
54 * RETURNS
55 * INI file, or NULL if not found
57 PUXINI_FILE UXINI_LoadINI(HMODULE hTheme, LPCWSTR lpName) {
58 HRSRC hrsc;
59 LPCWSTR lpThemesIni = NULL;
60 PUXINI_FILE uf;
61 DWORD dwIniSize;
63 TRACE("Loading resource INI %s\n", debugstr_w(lpName));
65 if((hrsc = FindResourceW(hTheme, lpName, L"TEXTFILE"))) {
66 if(!(lpThemesIni = LoadResource(hTheme, hrsc))) {
67 TRACE("%s resource not found\n", debugstr_w(lpName));
68 return NULL;
72 dwIniSize = SizeofResource(hTheme, hrsc) / sizeof(WCHAR);
73 uf = heap_alloc(sizeof(*uf));
74 uf->lpIni = lpThemesIni;
75 uf->lpCurLoc = lpThemesIni;
76 uf->lpEnd = lpThemesIni + dwIniSize;
77 return uf;
80 /**********************************************************************
81 * UXINI_CloseINI
83 * Close an open theme INI file
85 * PARAMS
86 * uf Theme INI file to close
88 void UXINI_CloseINI(PUXINI_FILE uf)
90 heap_free(uf);
93 /**********************************************************************
94 * UXINI_eof
96 * Determines if we are at the end of the INI file
98 * PARAMS
99 * uf Theme INI file to test
101 static inline BOOL UXINI_eof(PUXINI_FILE uf)
103 return uf->lpCurLoc >= uf->lpEnd;
106 /**********************************************************************
107 * UXINI_isspace
109 * Check if a character is a space character
111 * PARAMS
112 * c Character to test
114 static inline BOOL UXINI_isspace(WCHAR c)
116 if (isspace(c)) return TRUE;
117 if (c=='\r') return TRUE;
118 return FALSE;
121 /**********************************************************************
122 * UXINI_GetNextLine
124 * Get the next line in the INI file, non NULL terminated
125 * removes whitespace at beginning and end of line, and removes comments
127 * PARAMS
128 * uf INI file to retrieve next line
129 * dwLen Location to store pointer to line length
131 * RETURNS
132 * The section name, non NULL terminated
134 static LPCWSTR UXINI_GetNextLine(PUXINI_FILE uf, DWORD *dwLen)
136 LPCWSTR lpLineEnd;
137 LPCWSTR lpLineStart;
138 DWORD len;
139 do {
140 if(UXINI_eof(uf)) return NULL;
141 /* Skip whitespace and empty lines */
142 while(!UXINI_eof(uf) && (UXINI_isspace(*uf->lpCurLoc) || *uf->lpCurLoc == '\n')) uf->lpCurLoc++;
143 lpLineStart = uf->lpCurLoc;
144 lpLineEnd = uf->lpCurLoc;
145 while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n' && *uf->lpCurLoc != ';') lpLineEnd = ++uf->lpCurLoc;
146 /* If comment was found, skip the rest of the line */
147 if(*uf->lpCurLoc == ';')
148 while(!UXINI_eof(uf) && *uf->lpCurLoc != '\n') uf->lpCurLoc++;
149 len = (lpLineEnd - lpLineStart);
150 if(*lpLineStart != ';' && len == 0)
151 return NULL;
152 } while(*lpLineStart == ';');
153 /* Remove whitespace from end of line */
154 while(UXINI_isspace(lpLineStart[len-1])) len--;
155 *dwLen = len;
157 return lpLineStart;
160 static inline void UXINI_UnGetToLine(PUXINI_FILE uf, LPCWSTR lpLine)
162 uf->lpCurLoc = lpLine;
165 /**********************************************************************
166 * UXINI_GetNextSection
168 * Locate the next section in the ini file, and return pointer to
169 * section name, non NULL terminated. Use dwLen to determine length
171 * PARAMS
172 * uf INI file to search, search starts at current location
173 * dwLen Location to store pointer to section name length
175 * RETURNS
176 * The section name, non NULL terminated
178 LPCWSTR UXINI_GetNextSection(PUXINI_FILE uf, DWORD *dwLen)
180 LPCWSTR lpLine;
181 while((lpLine = UXINI_GetNextLine(uf, dwLen))) {
182 /* Assuming a ']' ending to the section name */
183 if(lpLine[0] == '[') {
184 lpLine++;
185 *dwLen -= 2;
186 break;
189 return lpLine;
192 /**********************************************************************
193 * UXINI_FindSection
195 * Locate a section with the specified name, search starts
196 * at current location in ini file
198 * PARAMS
199 * uf INI file to search, search starts at current location
200 * lpName Name of the section to locate
202 * RETURNS
203 * TRUE if section was found, FALSE otherwise
205 BOOL UXINI_FindSection(PUXINI_FILE uf, LPCWSTR lpName)
207 LPCWSTR lpSection;
208 DWORD dwLen;
209 while((lpSection = UXINI_GetNextSection(uf, &dwLen))) {
210 if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpSection, dwLen, lpName, -1) == CSTR_EQUAL) {
211 return TRUE;
214 return FALSE;
217 /**********************************************************************
218 * UXINI_GetNextValue
220 * Locate the next value in the current section
222 * PARAMS
223 * uf INI file to search, search starts at current location
224 * dwNameLen Location to store pointer to value name length
225 * lpValue Location to store pointer to the value
226 * dwValueLen Location to store pointer to value length
228 * RETURNS
229 * The value name, non NULL terminated
231 LPCWSTR UXINI_GetNextValue(PUXINI_FILE uf, DWORD *dwNameLen, LPCWSTR *lpValue, DWORD *dwValueLen)
233 LPCWSTR lpLine;
234 LPCWSTR lpLineEnd;
235 LPCWSTR name = NULL;
236 LPCWSTR value = NULL;
237 DWORD vallen = 0;
238 DWORD namelen = 0;
239 DWORD dwLen;
240 lpLine = UXINI_GetNextLine(uf, &dwLen);
241 if(!lpLine)
242 return NULL;
243 if(lpLine[0] == '[') {
244 UXINI_UnGetToLine(uf, lpLine);
245 return NULL;
247 lpLineEnd = lpLine + dwLen;
249 name = lpLine;
250 while(namelen < dwLen && *lpLine != '=') {
251 lpLine++;
252 namelen++;
254 if(*lpLine != '=') return NULL;
255 lpLine++;
257 /* Remove whitespace from end of name */
258 while(UXINI_isspace(name[namelen-1])) namelen--;
259 /* Remove whitespace from beginning of value */
260 while(UXINI_isspace(*lpLine) && lpLine < lpLineEnd) lpLine++;
261 value = lpLine;
262 vallen = dwLen-(value-name);
264 *dwNameLen = namelen;
265 *dwValueLen = vallen;
266 *lpValue = value;
268 return name;
271 /**********************************************************************
272 * UXINI_FindValue
274 * Locate a value by name
276 * PARAMS
277 * uf INI file to search, search starts at current location
278 * lpName Value name to locate
279 * lpValue Location to store pointer to the value
280 * dwValueLen Location to store pointer to value length
282 * RETURNS
283 * The value name, non NULL terminated
285 BOOL UXINI_FindValue(PUXINI_FILE uf, LPCWSTR lpName, LPCWSTR *lpValue, DWORD *dwValueLen)
287 LPCWSTR name;
288 DWORD namelen;
290 while((name = UXINI_GetNextValue(uf, &namelen, lpValue, dwValueLen))) {
291 if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, name, namelen, lpName, -1) == CSTR_EQUAL) {
292 return TRUE;
295 return FALSE;