ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

parse.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.