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

infcore.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:    .inf file parser
00003  * LICENSE:    GPL - See COPYING in the top level directory
00004  * PROGRAMMER: Royce Mitchell III
00005  *             Eric Kohl
00006  *             Ge van Geldorp <gvg@reactos.org>
00007  */
00008 
00009 /* INCLUDES *****************************************************************/
00010 
00011 #include "inflib.h"
00012 
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 #define CONTROL_Z  '\x1a'
00017 #define MAX_SECTION_NAME_LEN  255
00018 #define MAX_FIELD_LEN         511  /* larger fields get silently truncated */
00019 /* actual string limit is MAX_INF_STRING_LENGTH+1 (plus terminating null) under Windows */
00020 #define MAX_STRING_LEN        (MAX_INF_STRING_LENGTH+1)
00021 
00022 
00023 /* parser definitions */
00024 
00025 enum parser_state
00026 {
00027   LINE_START,      /* at beginning of a line */
00028   SECTION_NAME,    /* parsing a section name */
00029   KEY_NAME,        /* parsing a key name */
00030   VALUE_NAME,      /* parsing a value name */
00031   EOL_BACKSLASH,   /* backslash at end of line */
00032   QUOTES,          /* inside quotes */
00033   LEADING_SPACES,  /* leading spaces */
00034   TRAILING_SPACES, /* trailing spaces */
00035   COMMENT,         /* inside a comment */
00036   NB_PARSER_STATES
00037 };
00038 
00039 struct parser
00040 {
00041   const WCHAR       *start;       /* start position of item being parsed */
00042   const WCHAR       *end;         /* end of buffer */
00043   PINFCACHE         file;         /* file being built */
00044   enum parser_state state;        /* current parser state */
00045   enum parser_state stack[4];     /* state stack */
00046   int               stack_pos;    /* current pos in stack */
00047 
00048   PINFCACHESECTION cur_section;   /* pointer to the section being parsed*/
00049   PINFCACHELINE    line;          /* current line */
00050   unsigned int     line_pos;      /* current line position in file */
00051   INFSTATUS        error;         /* error code */
00052   unsigned int     token_len;     /* current token len */
00053   WCHAR token[MAX_FIELD_LEN+1];   /* current token */
00054 };
00055 
00056 typedef const WCHAR * (*parser_state_func)( struct parser *parser, const WCHAR *pos );
00057 
00058 /* parser state machine functions */
00059 static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos );
00060 static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos );
00061 static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos );
00062 static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos );
00063 static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos );
00064 static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos );
00065 static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos );
00066 static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos );
00067 static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos );
00068 
00069 static const parser_state_func parser_funcs[NB_PARSER_STATES] =
00070 {
00071   line_start_state,      /* LINE_START */
00072   section_name_state,    /* SECTION_NAME */
00073   key_name_state,        /* KEY_NAME */
00074   value_name_state,      /* VALUE_NAME */
00075   eol_backslash_state,   /* EOL_BACKSLASH */
00076   quotes_state,          /* QUOTES */
00077   leading_spaces_state,  /* LEADING_SPACES */
00078   trailing_spaces_state, /* TRAILING_SPACES */
00079   comment_state          /* COMMENT */
00080 };
00081 
00082 
00083 /* PRIVATE FUNCTIONS ********************************************************/
00084 
00085 static PINFCACHELINE
00086 InfpFreeLine (PINFCACHELINE Line)
00087 {
00088   PINFCACHELINE Next;
00089   PINFCACHEFIELD Field;
00090 
00091   if (Line == NULL)
00092     {
00093       return NULL;
00094     }
00095 
00096   Next = Line->Next;
00097   if (Line->Key != NULL)
00098     {
00099       FREE (Line->Key);
00100       Line->Key = NULL;
00101     }
00102 
00103   /* Remove data fields */
00104   while (Line->FirstField != NULL)
00105     {
00106       Field = Line->FirstField->Next;
00107       FREE (Line->FirstField);
00108       Line->FirstField = Field;
00109     }
00110   Line->LastField = NULL;
00111 
00112   FREE (Line);
00113 
00114   return Next;
00115 }
00116 
00117 
00118 PINFCACHESECTION
00119 InfpFreeSection (PINFCACHESECTION Section)
00120 {
00121   PINFCACHESECTION Next;
00122 
00123   if (Section == NULL)
00124     {
00125       return NULL;
00126     }
00127 
00128   /* Release all keys */
00129   Next = Section->Next;
00130   while (Section->FirstLine != NULL)
00131     {
00132       Section->FirstLine = InfpFreeLine (Section->FirstLine);
00133     }
00134   Section->LastLine = NULL;
00135 
00136   FREE (Section);
00137 
00138   return Next;
00139 }
00140 
00141 
00142 PINFCACHESECTION
00143 InfpFindSection(PINFCACHE Cache,
00144                 PCWSTR Name)
00145 {
00146   PINFCACHESECTION Section = NULL;
00147 
00148   if (Cache == NULL || Name == NULL)
00149     {
00150       return NULL;
00151     }
00152 
00153   /* iterate through list of sections */
00154   Section = Cache->FirstSection;
00155   while (Section != NULL)
00156     {
00157       if (strcmpiW(Section->Name, Name) == 0)
00158         {
00159           return Section;
00160         }
00161 
00162       /* get the next section*/
00163       Section = Section->Next;
00164     }
00165 
00166   return NULL;
00167 }
00168 
00169 
00170 PINFCACHESECTION
00171 InfpAddSection(PINFCACHE Cache,
00172                PCWSTR Name)
00173 {
00174   PINFCACHESECTION Section = NULL;
00175   ULONG Size;
00176 
00177   if (Cache == NULL || Name == NULL)
00178     {
00179       DPRINT("Invalid parameter\n");
00180       return NULL;
00181     }
00182 
00183   /* Allocate and initialize the new section */
00184   Size = (ULONG)FIELD_OFFSET(INFCACHESECTION,
00185                              Name[strlenW(Name) + 1]);
00186   Section = (PINFCACHESECTION)MALLOC(Size);
00187   if (Section == NULL)
00188     {
00189       DPRINT("MALLOC() failed\n");
00190       return NULL;
00191     }
00192   ZEROMEMORY (Section,
00193               Size);
00194 
00195   /* Copy section name */
00196   strcpyW(Section->Name, Name);
00197 
00198   /* Append section */
00199   if (Cache->FirstSection == NULL)
00200     {
00201       Cache->FirstSection = Section;
00202       Cache->LastSection = Section;
00203     }
00204   else
00205     {
00206       Cache->LastSection->Next = Section;
00207       Section->Prev = Cache->LastSection;
00208       Cache->LastSection = Section;
00209     }
00210 
00211   return Section;
00212 }
00213 
00214 
00215 PINFCACHELINE
00216 InfpAddLine(PINFCACHESECTION Section)
00217 {
00218   PINFCACHELINE Line;
00219 
00220   if (Section == NULL)
00221     {
00222       DPRINT("Invalid parameter\n");
00223       return NULL;
00224     }
00225 
00226   Line = (PINFCACHELINE)MALLOC(sizeof(INFCACHELINE));
00227   if (Line == NULL)
00228     {
00229       DPRINT("MALLOC() failed\n");
00230       return NULL;
00231     }
00232   ZEROMEMORY(Line,
00233              sizeof(INFCACHELINE));
00234 
00235   /* Append line */
00236   if (Section->FirstLine == NULL)
00237     {
00238       Section->FirstLine = Line;
00239       Section->LastLine = Line;
00240     }
00241   else
00242     {
00243       Section->LastLine->Next = Line;
00244       Line->Prev = Section->LastLine;
00245       Section->LastLine = Line;
00246     }
00247   Section->LineCount++;
00248 
00249   return Line;
00250 }
00251 
00252 
00253 PVOID
00254 InfpAddKeyToLine(PINFCACHELINE Line,
00255                  PCWSTR Key)
00256 {
00257   if (Line == NULL)
00258     {
00259       DPRINT1("Invalid Line\n");
00260       return NULL;
00261     }
00262 
00263   if (Line->Key != NULL)
00264     {
00265       DPRINT1("Line already has a key\n");
00266       return NULL;
00267     }
00268 
00269   Line->Key = (PWCHAR)MALLOC((strlenW(Key) + 1) * sizeof(WCHAR));
00270   if (Line->Key == NULL)
00271     {
00272       DPRINT1("MALLOC() failed\n");
00273       return NULL;
00274     }
00275 
00276   strcpyW(Line->Key, Key);
00277 
00278   return (PVOID)Line->Key;
00279 }
00280 
00281 
00282 PVOID
00283 InfpAddFieldToLine(PINFCACHELINE Line,
00284                    PCWSTR Data)
00285 {
00286   PINFCACHEFIELD Field;
00287   ULONG Size;
00288 
00289   Size = (ULONG)FIELD_OFFSET(INFCACHEFIELD,
00290                              Data[strlenW(Data) + 1]);
00291   Field = (PINFCACHEFIELD)MALLOC(Size);
00292   if (Field == NULL)
00293     {
00294       DPRINT1("MALLOC() failed\n");
00295       return NULL;
00296     }
00297   ZEROMEMORY (Field,
00298               Size);
00299   strcpyW(Field->Data, Data);
00300 
00301   /* Append key */
00302   if (Line->FirstField == NULL)
00303     {
00304       Line->FirstField = Field;
00305       Line->LastField = Field;
00306     }
00307   else
00308     {
00309       Line->LastField->Next = Field;
00310       Field->Prev = Line->LastField;
00311       Line->LastField = Field;
00312     }
00313   Line->FieldCount++;
00314 
00315   return (PVOID)Field;
00316 }
00317 
00318 
00319 PINFCACHELINE
00320 InfpFindKeyLine(PINFCACHESECTION Section,
00321                 PCWSTR Key)
00322 {
00323   PINFCACHELINE Line;
00324 
00325   Line = Section->FirstLine;
00326   while (Line != NULL)
00327     {
00328       if (Line->Key != NULL && strcmpiW(Line->Key, Key) == 0)
00329         {
00330           return Line;
00331         }
00332 
00333       Line = Line->Next;
00334     }
00335 
00336   return NULL;
00337 }
00338 
00339 
00340 /* push the current state on the parser stack */
00341 __inline static void push_state( struct parser *parser, enum parser_state state )
00342 {
00343 //  assert( parser->stack_pos < sizeof(parser->stack)/sizeof(parser->stack[0]) );
00344   parser->stack[parser->stack_pos++] = state;
00345 }
00346 
00347 
00348 /* pop the current state */
00349 __inline static void pop_state( struct parser *parser )
00350 {
00351 //  assert( parser->stack_pos );
00352   parser->state = parser->stack[--parser->stack_pos];
00353 }
00354 
00355 
00356 /* set the parser state and return the previous one */
00357 __inline static enum parser_state set_state( struct parser *parser, enum parser_state state )
00358 {
00359   enum parser_state ret = parser->state;
00360   parser->state = state;
00361   return ret;
00362 }
00363 
00364 
00365 /* check if the pointer points to an end of file */
00366 __inline static int is_eof( struct parser *parser, const WCHAR *ptr )
00367 {
00368   return (ptr >= parser->end || *ptr == CONTROL_Z || *ptr == 0);
00369 }
00370 
00371 
00372 /* check if the pointer points to an end of line */
00373 __inline static int is_eol( struct parser *parser, const WCHAR *ptr )
00374 {
00375   return (ptr >= parser->end ||
00376           *ptr == CONTROL_Z ||
00377           *ptr == '\n' ||
00378           (*ptr == '\r' && *(ptr + 1) == '\n') ||
00379           *ptr == 0);
00380 }
00381 
00382 
00383 /* push data from current token start up to pos into the current token */
00384 static int push_token( struct parser *parser, const WCHAR *pos )
00385 {
00386   UINT len = (UINT)(pos - parser->start);
00387   const WCHAR *src = parser->start;
00388   WCHAR *dst = parser->token + parser->token_len;
00389 
00390   if (len > MAX_FIELD_LEN - parser->token_len)
00391     len = MAX_FIELD_LEN - parser->token_len;
00392 
00393   parser->token_len += len;
00394   for ( ; len > 0; len--, dst++, src++)
00395   {
00396     if (*src)
00397     {
00398       *dst = *src;
00399     }
00400     else
00401     {
00402       *dst = ' ';
00403     }
00404   }
00405 
00406   *dst = 0;
00407   parser->start = pos;
00408 
00409   return 0;
00410 }
00411 
00412 
00413 
00414 /* add a section with the current token as name */
00415 static PVOID add_section_from_token( struct parser *parser )
00416 {
00417   PINFCACHESECTION Section;
00418 
00419   if (parser->token_len > MAX_SECTION_NAME_LEN)
00420     {
00421       parser->error = INF_STATUS_SECTION_NAME_TOO_LONG;
00422       return NULL;
00423     }
00424 
00425   Section = InfpFindSection(parser->file,
00426                             parser->token);
00427   if (Section == NULL)
00428     {
00429       /* need to create a new one */
00430       Section= InfpAddSection(parser->file,
00431                               parser->token);
00432       if (Section == NULL)
00433         {
00434           parser->error = INF_STATUS_NOT_ENOUGH_MEMORY;
00435           return NULL;
00436         }
00437     }
00438 
00439   parser->token_len = 0;
00440   parser->cur_section = Section;
00441 
00442   return (PVOID)Section;
00443 }
00444 
00445 
00446 /* add a field containing the current token to the current line */
00447 static struct field *add_field_from_token( struct parser *parser, int is_key )
00448 {
00449   PVOID field;
00450 
00451   if (!parser->line)  /* need to start a new line */
00452     {
00453       if (parser->cur_section == NULL)  /* got a line before the first section */
00454         {
00455           parser->error = INF_STATUS_WRONG_INF_STYLE;
00456           return NULL;
00457         }
00458 
00459       parser->line = InfpAddLine(parser->cur_section);
00460       if (parser->line == NULL)
00461         goto error;
00462     }
00463   else
00464     {
00465 //      assert(!is_key);
00466     }
00467 
00468   if (is_key)
00469     {
00470       field = InfpAddKeyToLine(parser->line, parser->token);
00471     }
00472   else
00473     {
00474       field = InfpAddFieldToLine(parser->line, parser->token);
00475     }
00476 
00477   if (field != NULL)
00478     {
00479       parser->token_len = 0;
00480       return field;
00481     }
00482 
00483 error:
00484   parser->error = INF_STATUS_NOT_ENOUGH_MEMORY;
00485   return NULL;
00486 }
00487 
00488 
00489 /* close the current line and prepare for parsing a new one */
00490 static void close_current_line( struct parser *parser )
00491 {
00492   parser->line = NULL;
00493 }
00494 
00495 
00496 
00497 /* handler for parser LINE_START state */
00498 static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos )
00499 {
00500   const WCHAR *p;
00501 
00502   for (p = pos; !is_eof( parser, p ); p++)
00503     {
00504       switch(*p)
00505         {
00506           case '\r':
00507             continue;
00508 
00509           case '\n':
00510             parser->line_pos++;
00511             close_current_line( parser );
00512             break;
00513 
00514           case ';':
00515             push_state( parser, LINE_START );
00516             set_state( parser, COMMENT );
00517             return p + 1;
00518 
00519           case '[':
00520             parser->start = p + 1;
00521             set_state( parser, SECTION_NAME );
00522             return p + 1;
00523 
00524           default:
00525             if (!isspaceW(*p))
00526               {
00527                 parser->start = p;
00528                 set_state( parser, KEY_NAME );
00529                 return p;
00530               }
00531             break;
00532         }
00533     }
00534   close_current_line( parser );
00535   return NULL;
00536 }
00537 
00538 
00539 /* handler for parser SECTION_NAME state */
00540 static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos )
00541 {
00542   const WCHAR *p;
00543 
00544   for (p = pos; !is_eol( parser, p ); p++)
00545     {
00546       if (*p == ']')
00547         {
00548           push_token( parser, p );
00549           if (add_section_from_token( parser ) == NULL)
00550             return NULL;
00551           push_state( parser, LINE_START );
00552           set_state( parser, COMMENT );  /* ignore everything else on the line */
00553           return p + 1;
00554         }
00555     }
00556   parser->error = INF_STATUS_BAD_SECTION_NAME_LINE; /* unfinished section name */
00557   return NULL;
00558 }
00559 
00560 
00561 /* handler for parser KEY_NAME state */
00562 static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos )
00563 {
00564     const WCHAR *p, *token_end = parser->start;
00565 
00566     for (p = pos; !is_eol( parser, p ); p++)
00567     {
00568         if (*p == ',') break;
00569         switch(*p)
00570         {
00571 
00572          case '=':
00573             push_token( parser, token_end );
00574             if (!add_field_from_token( parser, 1 )) return NULL;
00575             parser->start = p + 1;
00576             push_state( parser, VALUE_NAME );
00577             set_state( parser, LEADING_SPACES );
00578             return p + 1;
00579         case ';':
00580             push_token( parser, token_end );
00581             if (!add_field_from_token( parser, 0 )) return NULL;
00582             push_state( parser, LINE_START );
00583             set_state( parser, COMMENT );
00584             return p + 1;
00585         case '"':
00586             push_token( parser, token_end );
00587             parser->start = p + 1;
00588             push_state( parser, KEY_NAME );
00589             set_state( parser, QUOTES );
00590             return p + 1;
00591         case '\\':
00592             push_token( parser, token_end );
00593             parser->start = p;
00594             push_state( parser, KEY_NAME );
00595             set_state( parser, EOL_BACKSLASH );
00596             return p;
00597         default:
00598             if (!isspaceW(*p)) token_end = p + 1;
00599             else
00600             {
00601                 push_token( parser, p );
00602                 push_state( parser, KEY_NAME );
00603                 set_state( parser, TRAILING_SPACES );
00604                 return p;
00605             }
00606             break;
00607         }
00608     }
00609     push_token( parser, token_end );
00610     set_state( parser, VALUE_NAME );
00611     return p;
00612 }
00613 
00614 
00615 /* handler for parser VALUE_NAME state */
00616 static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos )
00617 {
00618     const WCHAR *p, *token_end = parser->start;
00619 
00620     for (p = pos; !is_eol( parser, p ); p++)
00621     {
00622         switch(*p)
00623         {
00624         case ';':
00625             push_token( parser, token_end );
00626             if (!add_field_from_token( parser, 0 )) return NULL;
00627             push_state( parser, LINE_START );
00628             set_state( parser, COMMENT );
00629             return p + 1;
00630         case ',':
00631             push_token( parser, token_end );
00632             if (!add_field_from_token( parser, 0 )) return NULL;
00633             parser->start = p + 1;
00634             push_state( parser, VALUE_NAME );
00635             set_state( parser, LEADING_SPACES );
00636             return p + 1;
00637         case '"':
00638             push_token( parser, token_end );
00639             parser->start = p + 1;
00640             push_state( parser, VALUE_NAME );
00641             set_state( parser, QUOTES );
00642             return p + 1;
00643         case '\\':
00644             push_token( parser, token_end );
00645             parser->start = p;
00646             push_state( parser, VALUE_NAME );
00647             set_state( parser, EOL_BACKSLASH );
00648             return p;
00649         default:
00650             if (!isspaceW(*p)) token_end = p + 1;
00651             else
00652             {
00653                 push_token( parser, p );
00654                 push_state( parser, VALUE_NAME );
00655                 set_state( parser, TRAILING_SPACES );
00656                 return p;
00657             }
00658             break;
00659         }
00660     }
00661     push_token( parser, token_end );
00662     if (!add_field_from_token( parser, 0 )) return NULL;
00663     set_state( parser, LINE_START );
00664     return p;
00665 }
00666 
00667 
00668 /* handler for parser EOL_BACKSLASH state */
00669 static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos )
00670 {
00671   const WCHAR *p;
00672 
00673   for (p = pos; !is_eof( parser, p ); p++)
00674     {
00675       switch(*p)
00676         {
00677           case '\r':
00678             continue;
00679 
00680           case '\n':
00681             parser->line_pos++;
00682             parser->start = p + 1;
00683             set_state( parser, LEADING_SPACES );
00684             return p + 1;
00685 
00686           case '\\':
00687             continue;
00688 
00689           case ';':
00690             push_state( parser, EOL_BACKSLASH );
00691             set_state( parser, COMMENT );
00692             return p + 1;
00693 
00694           default:
00695             if (isspaceW(*p))
00696               continue;
00697             push_token( parser, p );
00698             pop_state( parser );
00699             return p;
00700         }
00701     }
00702   parser->start = p;
00703   pop_state( parser );
00704 
00705   return p;
00706 }
00707 
00708 
00709 /* handler for parser QUOTES state */
00710 static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos )
00711 {
00712   const WCHAR *p, *token_end = parser->start;
00713 
00714   for (p = pos; !is_eol( parser, p ); p++)
00715     {
00716       if (*p == '"')
00717         {
00718           if (p+1 < parser->end && p[1] == '"')  /* double quotes */
00719             {
00720               push_token( parser, p + 1 );
00721               parser->start = token_end = p + 2;
00722               p++;
00723             }
00724           else  /* end of quotes */
00725             {
00726               push_token( parser, p );
00727               parser->start = p + 1;
00728               pop_state( parser );
00729               return p + 1;
00730             }
00731         }
00732     }
00733   push_token( parser, p );
00734   pop_state( parser );
00735   return p;
00736 }
00737 
00738 
00739 /* handler for parser LEADING_SPACES state */
00740 static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos )
00741 {
00742   const WCHAR *p;
00743 
00744   for (p = pos; !is_eol( parser, p ); p++)
00745     {
00746       if (*p == '\\')
00747         {
00748           parser->start = p;
00749           set_state( parser, EOL_BACKSLASH );
00750           return p;
00751         }
00752       if (!isspaceW(*p))
00753         break;
00754     }
00755   parser->start = p;
00756   pop_state( parser );
00757   return p;
00758 }
00759 
00760 
00761 /* handler for parser TRAILING_SPACES state */
00762 static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos )
00763 {
00764   const WCHAR *p;
00765 
00766   for (p = pos; !is_eol( parser, p ); p++)
00767     {
00768       if (*p == '\\')
00769         {
00770           set_state( parser, EOL_BACKSLASH );
00771           return p;
00772         }
00773       if (!isspaceW(*p))
00774         break;
00775     }
00776   pop_state( parser );
00777   return p;
00778 }
00779 
00780 
00781 /* handler for parser COMMENT state */
00782 static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos )
00783 {
00784   const WCHAR *p = pos;
00785 
00786   while (!is_eol( parser, p ))
00787      p++;
00788   pop_state( parser );
00789   return p;
00790 }
00791 
00792 
00793 /* parse a complete buffer */
00794 INFSTATUS
00795 InfpParseBuffer (PINFCACHE file,
00796                  const WCHAR *buffer,
00797                  const WCHAR *end,
00798                  PULONG error_line)
00799 {
00800   struct parser parser;
00801   const WCHAR *pos = buffer;
00802 
00803   parser.start       = buffer;
00804   parser.end         = end;
00805   parser.file        = file;
00806   parser.line        = NULL;
00807   parser.state       = LINE_START;
00808   parser.stack_pos   = 0;
00809   parser.cur_section = NULL;
00810   parser.line_pos    = 1;
00811   parser.error       = 0;
00812   parser.token_len   = 0;
00813 
00814   /* parser main loop */
00815   while (pos)
00816     pos = (parser_funcs[parser.state])(&parser, pos);
00817 
00818   if (parser.error)
00819     {
00820       if (error_line)
00821         *error_line = parser.line_pos;
00822       return parser.error;
00823     }
00824 
00825   /* find the [strings] section */
00826   file->StringsSection = InfpFindSection(file,
00827                                          L"Strings");
00828 
00829   return INF_STATUS_SUCCESS;
00830 }
00831 
00832 /* EOF */

Generated on Sat May 26 2012 04:35:05 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.