Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenparse.c
Go to the documentation of this file.
00001 /* 00002 * FreeLoader 00003 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 00020 #include <freeldr.h> 00021 #include <debug.h> 00022 00023 DBG_DEFAULT_CHANNEL(INIFILE); 00024 00025 LIST_ENTRY IniFileSectionListHead; 00026 BOOLEAN IniFileSectionInitialized = FALSE; 00027 ULONG IniFileSectionCount = 0; 00028 ULONG IniFileSettingCount = 0; 00029 00030 00031 BOOLEAN IniParseFile(PCHAR IniFileData, ULONG IniFileSize) 00032 { 00033 ULONG CurrentOffset; 00034 ULONG CurrentLineNumber; 00035 PCHAR IniFileLine; 00036 ULONG IniFileLineSize; 00037 ULONG LineLength; 00038 PINI_SECTION CurrentSection = NULL; 00039 PINI_SECTION_ITEM CurrentItem = NULL; 00040 00041 TRACE("IniParseFile() IniFileSize: %d\n", IniFileSize); 00042 00043 if (!IniFileSectionInitialized) 00044 { 00045 InitializeListHead(&IniFileSectionListHead); 00046 IniFileSectionInitialized = TRUE; 00047 } 00048 00049 // Start with an 80-byte buffer 00050 IniFileLineSize = 80; 00051 IniFileLine = MmHeapAlloc(IniFileLineSize); 00052 if (!IniFileLine) 00053 { 00054 return FALSE; 00055 } 00056 00057 // Loop through each line and parse it 00058 CurrentLineNumber = 0; 00059 CurrentOffset = 0; 00060 while (CurrentOffset < IniFileSize) 00061 { 00062 // First check the line size and increase our buffer if necessary 00063 if (IniFileLineSize < IniGetNextLineSize(IniFileData, IniFileSize, CurrentOffset)) 00064 { 00065 IniFileLineSize = IniGetNextLineSize(IniFileData, IniFileSize, CurrentOffset); 00066 MmHeapFree(IniFileLine); 00067 IniFileLine = MmHeapAlloc(IniFileLineSize); 00068 if (!IniFileLine) 00069 { 00070 return FALSE; 00071 } 00072 } 00073 00074 // Get the line of data 00075 CurrentOffset = IniGetNextLine(IniFileData, IniFileSize, IniFileLine, IniFileLineSize, CurrentOffset); 00076 LineLength = (ULONG)strlen(IniFileLine); 00077 00078 // If it is a blank line or a comment then skip it 00079 if (IniIsLineEmpty(IniFileLine, LineLength) || IniIsCommentLine(IniFileLine, LineLength)) 00080 { 00081 CurrentLineNumber++; 00082 continue; 00083 } 00084 00085 // Check if it is a new section 00086 if (IniIsSectionName(IniFileLine, LineLength)) 00087 { 00088 // Allocate a new section structure 00089 CurrentSection = MmHeapAlloc(sizeof(INI_SECTION)); 00090 if (!CurrentSection) 00091 { 00092 MmHeapFree(IniFileLine); 00093 return FALSE; 00094 } 00095 00096 RtlZeroMemory(CurrentSection, sizeof(INI_SECTION)); 00097 00098 // Allocate the section name buffer 00099 CurrentSection->SectionName = MmHeapAlloc(IniGetSectionNameSize(IniFileLine, LineLength)); 00100 if (!CurrentSection->SectionName) 00101 { 00102 MmHeapFree(CurrentSection); 00103 MmHeapFree(IniFileLine); 00104 return FALSE; 00105 } 00106 00107 // Get the section name 00108 IniExtractSectionName(CurrentSection->SectionName, IniFileLine, LineLength); 00109 InitializeListHead(&CurrentSection->SectionItemList); 00110 00111 // Add it to the section list head 00112 IniFileSectionCount++; 00113 InsertTailList(&IniFileSectionListHead, &CurrentSection->ListEntry); 00114 00115 CurrentLineNumber++; 00116 continue; 00117 } 00118 00119 // Check if it is a setting 00120 if (IniIsSetting(IniFileLine, LineLength)) 00121 { 00122 // First check to make sure we're inside a [section] 00123 if (CurrentSection == NULL) 00124 { 00125 printf("Error: freeldr.ini:%ld: Setting '%s' found outside of a [section].\n", CurrentLineNumber, IniFileLine); 00126 printf("Press any key to continue...\n"); 00127 MachConsGetCh(); 00128 CurrentLineNumber++; 00129 continue; 00130 } 00131 00132 // Allocate a new item structure 00133 CurrentItem = MmHeapAlloc(sizeof(INI_SECTION_ITEM)); 00134 if (!CurrentItem) 00135 { 00136 MmHeapFree(IniFileLine); 00137 return FALSE; 00138 } 00139 00140 RtlZeroMemory(CurrentItem, sizeof(INI_SECTION_ITEM)); 00141 00142 // Allocate the setting name buffer 00143 CurrentItem->ItemName = MmHeapAlloc(IniGetSettingNameSize(IniFileLine, LineLength)); 00144 if (!CurrentItem->ItemName) 00145 { 00146 MmHeapFree(CurrentItem); 00147 MmHeapFree(IniFileLine); 00148 return FALSE; 00149 } 00150 00151 // Allocate the setting value buffer 00152 CurrentItem->ItemValue = MmHeapAlloc(IniGetSettingValueSize(IniFileLine, LineLength)); 00153 if (!CurrentItem->ItemValue) 00154 { 00155 MmHeapFree(CurrentItem->ItemName); 00156 MmHeapFree(CurrentItem); 00157 MmHeapFree(IniFileLine); 00158 return FALSE; 00159 } 00160 00161 // Get the section name 00162 IniExtractSettingName(CurrentItem->ItemName, IniFileLine, LineLength); 00163 IniExtractSettingValue(CurrentItem->ItemValue, IniFileLine, LineLength); 00164 00165 // Add it to the current section 00166 IniFileSettingCount++; 00167 CurrentSection->SectionItemCount++; 00168 InsertTailList(&CurrentSection->SectionItemList, &CurrentItem->ListEntry); 00169 00170 CurrentLineNumber++; 00171 continue; 00172 } 00173 00174 CurrentLineNumber++; 00175 } 00176 00177 TRACE("Parsed %d sections and %d settings.\n", IniFileSectionCount, IniFileSettingCount); 00178 TRACE("IniParseFile() done.\n"); 00179 00180 return TRUE; 00181 } 00182 00183 ULONG IniGetNextLineSize(PCHAR IniFileData, ULONG IniFileSize, ULONG CurrentOffset) 00184 { 00185 ULONG LineCharCount = 0; 00186 00187 // Loop through counting chars until we hit the end of the 00188 // file or we encounter a new line char 00189 for (; (CurrentOffset < IniFileSize); CurrentOffset++) 00190 { 00191 // Increment the line character count 00192 LineCharCount++; 00193 00194 // Check for new line char 00195 if (IniFileData[CurrentOffset] == '\n') 00196 { 00197 break; 00198 } 00199 } 00200 00201 // Add one for the NULL-terminator 00202 LineCharCount++; 00203 00204 // Send back line character count 00205 return LineCharCount; 00206 } 00207 00208 ULONG IniGetNextLine(PCHAR IniFileData, ULONG IniFileSize, PCHAR Buffer, ULONG BufferSize, ULONG CurrentOffset) 00209 { 00210 ULONG Idx; 00211 00212 // Loop through grabbing chars until we hit the end of the 00213 // file or we encounter a new line char 00214 for (Idx=0; (CurrentOffset < IniFileSize); CurrentOffset++) 00215 { 00216 // If we haven't exceeded our buffer size yet 00217 // then store another char 00218 if (Idx < (BufferSize - 1)) 00219 { 00220 Buffer[Idx++] = IniFileData[CurrentOffset]; 00221 } 00222 00223 // Check for new line char 00224 if (IniFileData[CurrentOffset] == '\n') 00225 { 00226 CurrentOffset++; 00227 break; 00228 } 00229 } 00230 00231 // Terminate the string 00232 Buffer[Idx] = '\0'; 00233 00234 // Get rid of newline & linefeed characters (if any) 00235 while(Idx && (Buffer[--Idx] == '\n' || Buffer[Idx] == '\r')) 00236 Buffer[Idx] = '\0'; 00237 00238 // Send back new offset 00239 return CurrentOffset; 00240 } 00241 00242 BOOLEAN IniIsLineEmpty(PCHAR LineOfText, ULONG TextLength) 00243 { 00244 ULONG Idx; 00245 00246 // Check for text (skipping whitespace) 00247 for (Idx=0; Idx<TextLength; Idx++) 00248 { 00249 if ((LineOfText[Idx] == ' ') || 00250 (LineOfText[Idx] == '\t') || 00251 (LineOfText[Idx] == '\n') || 00252 (LineOfText[Idx] == '\r')) 00253 { 00254 continue; 00255 } 00256 else 00257 { 00258 return FALSE; 00259 } 00260 } 00261 00262 return TRUE; 00263 } 00264 00265 BOOLEAN IniIsCommentLine(PCHAR LineOfText, ULONG TextLength) 00266 { 00267 ULONG Idx; 00268 00269 // Check the first character (skipping whitespace) 00270 // and make sure that it is an opening bracket 00271 for (Idx=0; Idx<TextLength; Idx++) 00272 { 00273 if ((LineOfText[Idx] == ' ') || 00274 (LineOfText[Idx] == '\t')) 00275 { 00276 continue; 00277 } 00278 else if (LineOfText[Idx] == INI_FILE_COMMENT_CHAR) 00279 { 00280 return TRUE; 00281 } 00282 else 00283 { 00284 break; 00285 } 00286 } 00287 00288 return FALSE; 00289 } 00290 00291 BOOLEAN IniIsSectionName(PCHAR LineOfText, ULONG TextLength) 00292 { 00293 ULONG Idx; 00294 00295 // Check the first character (skipping whitespace) 00296 // and make sure that it is an opening bracket 00297 for (Idx=0; Idx<TextLength; Idx++) 00298 { 00299 if ((LineOfText[Idx] == ' ') || 00300 (LineOfText[Idx] == '\t')) 00301 { 00302 continue; 00303 } 00304 else if (LineOfText[Idx] == '[') 00305 { 00306 return TRUE; 00307 } 00308 else 00309 { 00310 break; 00311 } 00312 } 00313 00314 return FALSE; 00315 } 00316 00317 ULONG IniGetSectionNameSize(PCHAR SectionNameLine, ULONG LineLength) 00318 { 00319 ULONG Idx; 00320 ULONG NameSize; 00321 00322 // Find the opening bracket (skipping whitespace) 00323 for (Idx=0; Idx<LineLength; Idx++) 00324 { 00325 if ((SectionNameLine[Idx] == ' ') || 00326 (SectionNameLine[Idx] == '\t')) 00327 { 00328 continue; 00329 } 00330 else //if (SectionNameLine[Idx] == '[') 00331 { 00332 break; 00333 } 00334 } 00335 00336 // Skip past the opening bracket 00337 Idx++; 00338 00339 // Count the characters up until the closing bracket or EOL 00340 for (NameSize=0; Idx<LineLength; Idx++) 00341 { 00342 if ((SectionNameLine[Idx] == ']') || 00343 (SectionNameLine[Idx] == '\0')) 00344 { 00345 break; 00346 } 00347 00348 // Increment the count 00349 NameSize++; 00350 } 00351 00352 // Add one for the NULL-terminator 00353 NameSize++; 00354 00355 return NameSize; 00356 } 00357 00358 VOID IniExtractSectionName(PCHAR SectionName, PCHAR SectionNameLine, ULONG LineLength) 00359 { 00360 ULONG Idx; 00361 ULONG DestIdx; 00362 00363 // Find the opening bracket (skipping whitespace) 00364 for (Idx=0; Idx<LineLength; Idx++) 00365 { 00366 if ((SectionNameLine[Idx] == ' ') || 00367 (SectionNameLine[Idx] == '\t')) 00368 { 00369 continue; 00370 } 00371 else //if (SectionNameLine[Idx] == '[') 00372 { 00373 break; 00374 } 00375 } 00376 00377 // Skip past the opening bracket 00378 Idx++; 00379 00380 // Count the characters up until the closing bracket or EOL 00381 for (DestIdx=0; Idx<LineLength; Idx++) 00382 { 00383 if ((SectionNameLine[Idx] == ']') || 00384 (SectionNameLine[Idx] == '\0')) 00385 { 00386 break; 00387 } 00388 00389 // Grab a character and increment DestIdx 00390 SectionName[DestIdx] = SectionNameLine[Idx]; 00391 DestIdx++; 00392 } 00393 00394 // Terminate the string 00395 SectionName[DestIdx] = '\0'; 00396 } 00397 00398 BOOLEAN IniIsSetting(PCHAR LineOfText, ULONG TextLength) 00399 { 00400 ULONG Idx; 00401 00402 // Basically just check for an '=' equals sign 00403 for (Idx=0; Idx<TextLength; Idx++) 00404 { 00405 if (LineOfText[Idx] == '=') 00406 { 00407 return TRUE; 00408 } 00409 } 00410 00411 return FALSE; 00412 } 00413 00414 ULONG IniGetSettingNameSize(PCHAR SettingNameLine, ULONG LineLength) 00415 { 00416 ULONG Idx; 00417 ULONG NameSize; 00418 00419 // Skip whitespace 00420 for (Idx=0; Idx<LineLength; Idx++) 00421 { 00422 if ((SettingNameLine[Idx] == ' ') || 00423 (SettingNameLine[Idx] == '\t')) 00424 { 00425 continue; 00426 } 00427 else 00428 { 00429 break; 00430 } 00431 } 00432 00433 // Count the characters up until the '=' equals sign or EOL 00434 for (NameSize=0; Idx<LineLength; Idx++) 00435 { 00436 if ((SettingNameLine[Idx] == '=') || 00437 (SettingNameLine[Idx] == '\0')) 00438 { 00439 break; 00440 } 00441 00442 // Increment the count 00443 NameSize++; 00444 } 00445 00446 // Add one for the NULL-terminator 00447 NameSize++; 00448 00449 return NameSize; 00450 } 00451 00452 ULONG IniGetSettingValueSize(PCHAR SettingValueLine, ULONG LineLength) 00453 { 00454 ULONG Idx; 00455 ULONG ValueSize; 00456 00457 // Skip whitespace 00458 for (Idx=0; Idx<LineLength; Idx++) 00459 { 00460 if ((SettingValueLine[Idx] == ' ') || 00461 (SettingValueLine[Idx] == '\t')) 00462 { 00463 continue; 00464 } 00465 else 00466 { 00467 break; 00468 } 00469 } 00470 00471 // Skip the characters up until the '=' equals sign or EOL 00472 for (; Idx<LineLength; Idx++) 00473 { 00474 if (SettingValueLine[Idx] == '=') 00475 { 00476 Idx++; 00477 break; 00478 } 00479 00480 // If we hit EOL then obviously the value size is zero 00481 if (SettingValueLine[Idx] == '\0') 00482 { 00483 return 0; 00484 } 00485 } 00486 00487 // Count the characters up until the EOL 00488 for (ValueSize=0; Idx<LineLength; Idx++) 00489 { 00490 if (SettingValueLine[Idx] == '\0') 00491 { 00492 break; 00493 } 00494 00495 // Increment the count 00496 ValueSize++; 00497 } 00498 00499 // Add one for the NULL-terminator 00500 ValueSize++; 00501 00502 return ValueSize; 00503 } 00504 00505 VOID IniExtractSettingName(PCHAR SettingName, PCHAR SettingNameLine, ULONG LineLength) 00506 { 00507 ULONG Idx; 00508 ULONG DestIdx; 00509 00510 // Skip whitespace 00511 for (Idx=0; Idx<LineLength; Idx++) 00512 { 00513 if ((SettingNameLine[Idx] == ' ') || 00514 (SettingNameLine[Idx] == '\t')) 00515 { 00516 continue; 00517 } 00518 else 00519 { 00520 break; 00521 } 00522 } 00523 00524 // Get the characters up until the '=' equals sign or EOL 00525 for (DestIdx=0; Idx<LineLength; Idx++) 00526 { 00527 if ((SettingNameLine[Idx] == '=') || 00528 (SettingNameLine[Idx] == '\0')) 00529 { 00530 break; 00531 } 00532 00533 // Grab a character and increment DestIdx 00534 SettingName[DestIdx] = SettingNameLine[Idx]; 00535 DestIdx++; 00536 } 00537 00538 // Terminate the string 00539 SettingName[DestIdx] = '\0'; 00540 } 00541 00542 VOID IniExtractSettingValue(PCHAR SettingValue, PCHAR SettingValueLine, ULONG LineLength) 00543 { 00544 ULONG Idx; 00545 ULONG DestIdx; 00546 00547 // Skip whitespace 00548 for (Idx=0; Idx<LineLength; Idx++) 00549 { 00550 if ((SettingValueLine[Idx] == ' ') || 00551 (SettingValueLine[Idx] == '\t')) 00552 { 00553 continue; 00554 } 00555 else 00556 { 00557 break; 00558 } 00559 } 00560 00561 // Skip the characters up until the '=' equals sign or EOL 00562 for (; Idx<LineLength; Idx++) 00563 { 00564 if (SettingValueLine[Idx] == '=') 00565 { 00566 Idx++; 00567 break; 00568 } 00569 00570 // If we hit EOL then obviously the value size is zero 00571 if (SettingValueLine[Idx] == '\0') 00572 { 00573 SettingValue[0] = '\0'; 00574 return; 00575 } 00576 } 00577 00578 // Get the characters up until the EOL 00579 for (DestIdx=0; Idx<LineLength; Idx++) 00580 { 00581 if (SettingValueLine[Idx] == '\0') 00582 { 00583 break; 00584 } 00585 00586 // Grab a character and increment DestIdx 00587 SettingValue[DestIdx] = SettingValueLine[Idx]; 00588 DestIdx++; 00589 } 00590 00591 // Terminate the string 00592 SettingValue[DestIdx] = '\0'; 00593 } Generated on Sun May 27 2012 04:19:15 for ReactOS by
1.7.6.1
|