- Factor out .inf handling code from usetup - Provide a dual interface, for use in build tools and for use in ReactOS code Modified: trunk/reactos/lib/directory.xml Added: trunk/reactos/lib/inflib/ Added: trunk/reactos/lib/inflib/README.txt Added: trunk/reactos/lib/inflib/builddep.h Added: trunk/reactos/lib/inflib/infcommon.h Added: trunk/reactos/lib/inflib/infcore.c Added: trunk/reactos/lib/inflib/infget.c Added: trunk/reactos/lib/inflib/infhost.h Added: trunk/reactos/lib/inflib/infhostgen.c Added: trunk/reactos/lib/inflib/infhostget.c Added: trunk/reactos/lib/inflib/inflib.h Added: trunk/reactos/lib/inflib/inflib.mak Added: trunk/reactos/lib/inflib/inflib.xml Added: trunk/reactos/lib/inflib/infpriv.h Added: trunk/reactos/lib/inflib/infros.h Added: trunk/reactos/lib/inflib/infrosgen.c Added: trunk/reactos/lib/inflib/infrosget.c Modified: trunk/reactos/lib/lib.mak _____
Modified: trunk/reactos/lib/directory.xml --- trunk/reactos/lib/directory.xml 2005-11-24 06:07:04 UTC (rev 19515) +++ trunk/reactos/lib/directory.xml 2005-11-24 08:07:12 UTC (rev 19516) @@ -119,6 +119,9 @@
<directory name="imm32"> <xi:include href="imm32/imm32.xml" /> </directory> +<directory name="inflib"> + <xi:include href="inflib/inflib.xml" /> +</directory> <directory name="intrlck"> <xi:include href="intrlck/intrlck.xml" /> </directory> _____
Added: trunk/reactos/lib/inflib/README.txt --- trunk/reactos/lib/inflib/README.txt 2005-11-24 06:07:04 UTC (rev 19515) +++ trunk/reactos/lib/inflib/README.txt 2005-11-24 08:07:12 UTC (rev 19516) @@ -0,0 +1,14 @@
+Routines to handle .inf files. + +This library is used to share .inf handling code between build tools and +ReactOS code. Two versions are built, "inflib_host" (for use by build tools) +and "inflib" (for use by ReactOS code). Both depend on the same core source, +with a wrapper for the appropriate interface. +Most of the differences between the host and the ReactOS environment are +abstracted away in builddep.h. Of particular note is that the host version +uses Ansi characters while the ReactOS version uses Unicode. So, the core +source uses TCHARs. builddep.h depends on a preprocessor variable INFLIB_HOST +which is defined when building the host version (inflib.mak) but not defined +when building the ReactOS version (inflib.xml). +The wrappers have "host" or "ros" in their filename. The library interface is +"infhost.h" for the host version, "infros.h" for the ReactOS version. Property changes on: trunk/reactos/lib/inflib/README.txt ___________________________________________________________________ Name: svn:eol-style + native _____
Added: trunk/reactos/lib/inflib/builddep.h --- trunk/reactos/lib/inflib/builddep.h 2005-11-24 06:07:04 UTC (rev 19515) +++ trunk/reactos/lib/inflib/builddep.h 2005-11-24 08:07:12 UTC (rev 19516) @@ -0,0 +1,75 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: .inf file parser + * FILE: lib/inflib/builddep.h + * PURPOSE: Build dependent definitions + * PROGRAMMER: Ge van Geldorp gvg@reactos.org + */ + +#ifdef INFLIB_HOST + +/* Definitions native to the host on which we're building */ + +#include <string.h> +#include <errno.h> + +#define FREE(Area) free(Area) +#define MALLOC(Size) malloc(Size) +#define ZEROMEMORY(Area, Size) memset((Area), '\0', (Size)) +#define MEMCPY(Dest, Src, Size) memcpy((Dest), (Src), (Size)) + +#define INF_STATUS_SUCCESS 0 +#define INF_STATUS_NO_MEMORY ENOMEM +#define INF_STATUS_INVALID_PARAMETER EINVAL +#define INF_STATUS_NOT_FOUND ENOENT +#define INF_STATUS_BUFFER_OVERFLOW E2BIG +#define INF_SUCCESS(x) (0 == (x)) + +typedef char CHAR, *PCHAR; +typedef unsigned char UCHAR, *PUCHAR; +typedef long LONG, *PLONG; +typedef unsigned long ULONG, *PULONG; +typedef void VOID, *PVOID; +typedef UCHAR BOOLEAN, *PBOOLEAN; + +typedef char TCHAR, *PTCHAR, *PTSTR; +#define _T(x) x +#define _tcsicmp strcasecmp +#define _tcslen strlen +#define _tcscpy strcpy +#define _tcstoul strtoul +#define _tcstol strtol + +extern void DbgPrint(const char *Fmt, ...); + +#else /* ! defined(INFLIB_HOST) */ + +/* ReactOS definitions */ + +#define UNICODE +#define _UNICODE +#include <tchar.h> +#define WIN32_NO_STATUS +#include <windows.h> +#define NTOS_MODE_USER +#include <ndk/ntndk.h> + +extern PVOID InfpHeap; + +#define FREE(Area) RtlFreeHeap(InfpHeap, 0, (Area)) +#define MALLOC(Size) RtlAllocateHeap(InfpHeap, 0, (Size)) +#define ZEROMEMORY(Area, Size) RtlZeroMemory((Area), (Size)) +#define MEMCPY(Dest, Src, Size) RtlCopyMemory((Dest), (Src), (Size)) + +#define INF_STATUS_SUCCESS STATUS_SUCCESS +#define INF_STATUS_NO_MEMORY STATUS_NO_MEMORY +#define INF_STATUS_INVALID_PARAMETER STATUS_INVALID_PARAMETER +#define INF_STATUS_NOT_FOUND STATUS_NOT_FOUND +#define INF_STATUS_BUFFER_OVERFLOW STATUS_BUFFER_OVERFLOW +#define INF_SUCCESS(x) (0 <= (x)) + +#endif /* INFLIB_HOST */ + +typedef const TCHAR *PCTSTR; + +/* EOF */ Property changes on: trunk/reactos/lib/inflib/builddep.h ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native _____
Added: trunk/reactos/lib/inflib/infcommon.h --- trunk/reactos/lib/inflib/infcommon.h 2005-11-24 06:07:04 UTC (rev 19515) +++ trunk/reactos/lib/inflib/infcommon.h 2005-11-24 08:07:12 UTC (rev 19516) @@ -0,0 +1,21 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: .inf file parser + * FILE: lib/inflib/infcommon.h + * PURPOSE: Public .inf routines + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + * Ge van Geldorp + */ + +#ifndef INFCOMMON_H_INCLUDED +#define INFCOMMON_H_INCLUDED + +#define MAX_INF_STRING_LENGTH 512 + +typedef void *HINF, **PHINF; +typedef struct _INFCONTEXT *PINFCONTEXT; + +#endif /* INFCOMMON_H_INCLUDED */ + +/* EOF */ Property changes on: trunk/reactos/lib/inflib/infcommon.h ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native _____
Copied: trunk/reactos/lib/inflib/infcore.c (from rev 19508, trunk/reactos/subsys/system/usetup/infcache.c) --- trunk/reactos/subsys/system/usetup/infcache.c 2005-11-23 23:02:35 UTC (rev 19508) +++ trunk/reactos/lib/inflib/infcore.c 2005-11-24 08:07:12 UTC (rev 19516) @@ -0,0 +1,811 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: .inf file parser + * FILE: lib/inflib/infcore.c + * PURPOSE: INF file parser that caches contents of INF file in memory + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + * Ge van Geldorp + */ + +/* INCLUDES *****************************************************************/ + +#include "inflib.h" + +#define NDEBUG +#include <debug.h> + +#define CONTROL_Z '\x1a' +#define MAX_SECTION_NAME_LEN 255 +#define MAX_FIELD_LEN 511 /* larger fields get silently truncated */ +/* actual string limit is MAX_INF_STRING_LENGTH+1 (plus terminating null) under Windows */ +#define MAX_STRING_LEN (MAX_INF_STRING_LENGTH+1) + + +/* parser definitions */ + +enum parser_state +{ + LINE_START, /* at beginning of a line */ + SECTION_NAME, /* parsing a section name */ + KEY_NAME, /* parsing a key name */ + VALUE_NAME, /* parsing a value name */ + EOL_BACKSLASH, /* backslash at end of line */ + QUOTES, /* inside quotes */ + LEADING_SPACES, /* leading spaces */ + TRAILING_SPACES, /* trailing spaces */ + COMMENT, /* inside a comment */ + NB_PARSER_STATES +}; + +struct parser +{ + const CHAR *start; /* start position of item being parsed */ + const CHAR *end; /* end of buffer */ + PINFCACHE file; /* file being built */ + enum parser_state state; /* current parser state */ + enum parser_state stack[4]; /* state stack */ + int stack_pos; /* current pos in stack */ + + PINFCACHESECTION cur_section; /* pointer to the section being parsed*/ + PINFCACHELINE line; /* current line */ + unsigned int line_pos; /* current line position in file */ + unsigned int error; /* error code */ + unsigned int token_len; /* current token len */ + TCHAR token[MAX_FIELD_LEN+1]; /* current token */ +}; + +typedef const CHAR * (*parser_state_func)( struct parser *parser, const CHAR *pos ); + +/* parser state machine functions */ +static const CHAR *line_start_state( struct parser *parser, const CHAR *pos ); +static const CHAR *section_name_state( struct parser *parser, const CHAR *pos ); +static const CHAR *key_name_state( struct parser *parser, const CHAR *pos ); +static const CHAR *value_name_state( struct parser *parser, const CHAR *pos ); +static const CHAR *eol_backslash_state( struct parser *parser, const CHAR *pos ); +static const CHAR *quotes_state( struct parser *parser, const CHAR *pos ); +static const CHAR *leading_spaces_state( struct parser *parser, const CHAR *pos ); +static const CHAR *trailing_spaces_state( struct parser *parser, const CHAR *pos ); +static const CHAR *comment_state( struct parser *parser, const CHAR *pos ); + +static const parser_state_func parser_funcs[NB_PARSER_STATES] = +{ + line_start_state, /* LINE_START */ + section_name_state, /* SECTION_NAME */ + key_name_state, /* KEY_NAME */ + value_name_state, /* VALUE_NAME */ + eol_backslash_state, /* EOL_BACKSLASH */ + quotes_state, /* QUOTES */ + leading_spaces_state, /* LEADING_SPACES */ + trailing_spaces_state, /* TRAILING_SPACES */ + comment_state /* COMMENT */ +}; + + +/* PRIVATE FUNCTIONS ********************************************************/ + +static PINFCACHELINE +InfpCacheFreeLine (PINFCACHELINE Line) +{ + PINFCACHELINE Next; + PINFCACHEFIELD Field; + + if (Line == NULL) + { + return NULL; + } + + Next = Line->Next; + if (Line->Key != NULL) + { + FREE (Line->Key); + Line->Key = NULL; + } + + /* Remove data fields */ + while (Line->FirstField != NULL) + { + Field = Line->FirstField->Next; + FREE (Line->FirstField); + Line->FirstField = Field; + } + Line->LastField = NULL; + + FREE (Line); + + return Next; +} + + +PINFCACHESECTION +InfpCacheFreeSection (PINFCACHESECTION Section) +{ + PINFCACHESECTION Next; + + if (Section == NULL) + { + return NULL; + } + + /* Release all keys */ + Next = Section->Next; + while (Section->FirstLine != NULL) + { + Section->FirstLine = InfpCacheFreeLine (Section->FirstLine); + } + Section->LastLine = NULL; + + FREE (Section); + + return Next; +} + + +static PINFCACHESECTION +InfpCacheFindSection (PINFCACHE Cache, + PCTSTR Name) +{ + PINFCACHESECTION Section = NULL; + + if (Cache == NULL || Name == NULL) + { + return NULL; + } + + /* iterate through list of sections */ + Section = Cache->FirstSection; + while (Section != NULL) + { + if (_tcsicmp (Section->Name, Name) == 0) + { + return Section; + } + + /* get the next section*/ + Section = Section->Next; + } + + return NULL; +} + + +static PINFCACHESECTION +InfpCacheAddSection (PINFCACHE Cache, + PTCHAR Name) +{ + PINFCACHESECTION Section = NULL; + ULONG Size; + + if (Cache == NULL || Name == NULL) + { + DPRINT("Invalid parameter\n"); + return NULL; + } + + /* Allocate and initialize the new section */ + Size = sizeof(INFCACHESECTION) + (_tcslen (Name) * sizeof(TCHAR)); + Section = (PINFCACHESECTION)MALLOC (Size); + if (Section == NULL) + { + DPRINT("MALLOC() failed\n"); + return NULL; + } + ZEROMEMORY (Section, + Size); + + /* Copy section name */ + _tcscpy (Section->Name, Name); + + /* Append section */ + if (Cache->FirstSection == NULL) + { + Cache->FirstSection = Section; + Cache->LastSection = Section; + } + else + { + Cache->LastSection->Next = Section; + Section->Prev = Cache->LastSection; + Cache->LastSection = Section; + } + + return Section; +} + + +static PINFCACHELINE +InfpCacheAddLine (PINFCACHESECTION Section) +{ + PINFCACHELINE Line; + + if (Section == NULL) + { + DPRINT("Invalid parameter\n"); + return NULL; + } + + Line = (PINFCACHELINE)MALLOC (sizeof(INFCACHELINE)); + if (Line == NULL) + { + DPRINT("MALLOC() failed\n"); + return NULL; + } + ZEROMEMORY(Line, + sizeof(INFCACHELINE)); + + /* Append line */ + if (Section->FirstLine == NULL) + { + Section->FirstLine = Line; + Section->LastLine = Line; + } + else + { + Section->LastLine->Next = Line; + Line->Prev = Section->LastLine; + Section->LastLine = Line; + } + Section->LineCount++; + + return Line; +} + + +static PVOID +InfpAddKeyToLine (PINFCACHELINE Line, + PTCHAR Key) +{ + if (Line == NULL) + return NULL; + + if (Line->Key != NULL) + return NULL; + + Line->Key = (PTCHAR)MALLOC ((_tcslen (Key) + 1) * sizeof(TCHAR)); + if (Line->Key == NULL) + return NULL; + + _tcscpy (Line->Key, Key); + + return (PVOID)Line->Key; +} + + +static PVOID +InfpAddFieldToLine (PINFCACHELINE Line, + PTCHAR Data) +{ + PINFCACHEFIELD Field; + ULONG Size; + + Size = sizeof(INFCACHEFIELD) + (_tcslen(Data) * sizeof(TCHAR)); + Field = (PINFCACHEFIELD)MALLOC (Size); + if (Field == NULL) + { + return NULL; + } + ZEROMEMORY (Field, + Size); + _tcscpy (Field->Data, Data); + + /* Append key */ + if (Line->FirstField == NULL) + { + Line->FirstField = Field; + Line->LastField = Field; + } + else + { + Line->LastField->Next = Field; + Field->Prev = Line->LastField; + Line->LastField = Field; + } + Line->FieldCount++; + + return (PVOID)Field; +} + + +PINFCACHELINE +InfpCacheFindKeyLine (PINFCACHESECTION Section, + PTCHAR Key) +{ + PINFCACHELINE Line; + + Line = Section->FirstLine; + while (Line != NULL) + { + if (Line->Key != NULL && _tcsicmp (Line->Key, Key) == 0) + { + return Line; + } + + Line = Line->Next; + } + + return NULL; +} + + +/* push the current state on the parser stack */ +inline static void push_state( struct parser *parser, enum parser_state state ) +{ +// assert( parser->stack_pos < sizeof(parser->stack)/sizeof(parser->stack[0]) ); + parser->stack[parser->stack_pos++] = state; +} + + +/* pop the current state */ +inline static void pop_state( struct parser *parser ) +{ +// assert( parser->stack_pos ); + parser->state = parser->stack[--parser->stack_pos]; +} + + +/* set the parser state and return the previous one */ +inline static enum parser_state set_state( struct parser *parser, enum parser_state state ) +{ + enum parser_state ret = parser->state; + parser->state = state; + return ret; +} + + +/* check if the pointer points to an end of file */ +inline static int is_eof( struct parser *parser, const CHAR *ptr ) +{ + return (ptr >= parser->end || *ptr == CONTROL_Z); +} + + +/* check if the pointer points to an end of line */ +inline static int is_eol( struct parser *parser, const CHAR *ptr ) +{ + return (ptr >= parser->end || + *ptr == CONTROL_Z || + *ptr == '\n' || + (*ptr == '\r' && *(ptr + 1) == '\n')); +} + + +/* push data from current token start up to pos into the current token */ +static int push_token( struct parser *parser, const CHAR *pos ) +{ + unsigned int len = pos - parser->start; + const CHAR *src = parser->start; + TCHAR *dst = parser->token + parser->token_len; + + if (len > MAX_FIELD_LEN - parser->token_len) + len = MAX_FIELD_LEN - parser->token_len; + + parser->token_len += len; + for ( ; len > 0; len--, dst++, src++) + *dst = *src ? (TCHAR)*src : L' '; + *dst = 0; + parser->start = pos; + + return 0; +} + + + +/* add a section with the current token as name */ +static PVOID add_section_from_token( struct parser *parser ) +{ + PINFCACHESECTION Section; + + if (parser->token_len > MAX_SECTION_NAME_LEN) + { + parser->error = INF_STATUS_SECTION_NAME_TOO_LONG; + return NULL; + } + + Section = InfpCacheFindSection (parser->file, + parser->token); + if (Section == NULL) + { + /* need to create a new one */ + Section= InfpCacheAddSection (parser->file, + parser->token); + if (Section == NULL) + { + parser->error = INF_STATUS_NOT_ENOUGH_MEMORY; + return NULL; + } + } + + parser->token_len = 0; + parser->cur_section = Section; + + return (PVOID)Section; +} + + +/* add a field containing the current token to the current line */ +static struct field *add_field_from_token( struct parser *parser, int is_key ) +{ + PVOID field; + + if (!parser->line) /* need to start a new line */ + { + if (parser->cur_section == NULL) /* got a line before the first section */ + { + parser->error = INF_STATUS_WRONG_INF_STYLE; + return NULL; + } + + parser->line = InfpCacheAddLine (parser->cur_section); + if (parser->line == NULL) + goto error; + } + else + { +// assert(!is_key); + } + + if (is_key) + { + field = InfpAddKeyToLine(parser->line, parser->token); + } + else + { + field = InfpAddFieldToLine(parser->line, parser->token); + } + + if (field != NULL) + { + parser->token_len = 0; + return field; + } + +error: + parser->error = INF_STATUS_NOT_ENOUGH_MEMORY; + return NULL; +} + + +/* close the current line and prepare for parsing a new one */ +static void close_current_line( struct parser *parser ) +{ + parser->line = NULL; +} + + + +/* handler for parser LINE_START state */ +static const CHAR *line_start_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eof( parser, p ); p++) + { + switch(*p) + { + case '\r': + continue; + + case '\n': + parser->line_pos++; + close_current_line( parser ); + break; + + case ';': + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); + return p + 1; + + case '[': + parser->start = p + 1; + set_state( parser, SECTION_NAME ); + return p + 1; + + default: + if (!isspace(*p)) + { + parser->start = p; + set_state( parser, KEY_NAME ); + return p; + } + break; + } + } + close_current_line( parser ); + return NULL; +} + + +/* handler for parser SECTION_NAME state */ +static const CHAR *section_name_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == ']') + { + push_token( parser, p ); + if (add_section_from_token( parser ) == NULL) + return NULL; + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); /* ignore everything else on the line */ + return p + 1; + } + } + parser->error = INF_STATUS_BAD_SECTION_NAME_LINE; /* unfinished section name */ + return NULL; +} + + +/* handler for parser KEY_NAME state */ +static const CHAR *key_name_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p, *token_end = parser->start; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == ',') break; + switch(*p) + { + + case '=': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 1 )) return NULL; + parser->start = p + 1; + push_state( parser, VALUE_NAME ); + set_state( parser, LEADING_SPACES ); + return p + 1; + case ';': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); + return p + 1; + case '"': + push_token( parser, token_end ); + parser->start = p + 1; + push_state( parser, KEY_NAME ); + set_state( parser, QUOTES ); + return p + 1; + case '\': + push_token( parser, token_end ); + parser->start = p; + push_state( parser, KEY_NAME ); + set_state( parser, EOL_BACKSLASH ); + return p; + default: + if (!isspace(*p)) token_end = p + 1; + else + { + push_token( parser, p ); + push_state( parser, KEY_NAME ); + set_state( parser, TRAILING_SPACES ); + return p; + } + break; + } + } + push_token( parser, token_end ); + set_state( parser, VALUE_NAME ); + return p; +} + + +/* handler for parser VALUE_NAME state */ +static const CHAR *value_name_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p, *token_end = parser->start; + + for (p = pos; !is_eol( parser, p ); p++) + { + switch(*p) + { + case ';': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); + return p + 1; + case ',': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + parser->start = p + 1; + push_state( parser, VALUE_NAME ); + set_state( parser, LEADING_SPACES ); + return p + 1; + case '"': + push_token( parser, token_end ); + parser->start = p + 1; + push_state( parser, VALUE_NAME ); + set_state( parser, QUOTES ); + return p + 1; + case '\': + push_token( parser, token_end ); + parser->start = p; + push_state( parser, VALUE_NAME ); + set_state( parser, EOL_BACKSLASH ); + return p; + default: + if (!isspace(*p)) token_end = p + 1; + else + { + push_token( parser, p ); + push_state( parser, VALUE_NAME ); + set_state( parser, TRAILING_SPACES ); + return p; + } + break; + } + } + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + set_state( parser, LINE_START ); + return p; +} + + +/* handler for parser EOL_BACKSLASH state */ +static const CHAR *eol_backslash_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eof( parser, p ); p++) + { + switch(*p) + { + case '\r': + continue; + + case '\n': + parser->line_pos++; + parser->start = p + 1; + set_state( parser, LEADING_SPACES ); + return p + 1; + + case '\': + continue; + + case ';': + push_state( parser, EOL_BACKSLASH ); + set_state( parser, COMMENT ); + return p + 1; + + default: + if (isspace(*p)) + continue; + push_token( parser, p ); + pop_state( parser ); + return p; + } + } + parser->start = p; + pop_state( parser ); + + return p; +} + + +/* handler for parser QUOTES state */ +static const CHAR *quotes_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p, *token_end = parser->start; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == '"') + { + if (p+1 < parser->end && p[1] == '"') /* double quotes */ + { + push_token( parser, p + 1 ); + parser->start = token_end = p + 2; + p++; + } + else /* end of quotes */ + { + push_token( parser, p ); + parser->start = p + 1; + pop_state( parser ); + return p + 1; + } + } + } + push_token( parser, p ); + pop_state( parser ); + return p; +} + + +/* handler for parser LEADING_SPACES state */ +static const CHAR *leading_spaces_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == '\') + { + parser->start = p; + set_state( parser, EOL_BACKSLASH ); + return p; + } + if (!isspace(*p)) + break; + } + parser->start = p; + pop_state( parser ); + return p; +} + + +/* handler for parser TRAILING_SPACES state */ +static const CHAR *trailing_spaces_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == '\') + { + set_state( parser, EOL_BACKSLASH ); + return p; + } + if (!isspace(*p)) + break; + } + pop_state( parser ); + return p; +} + + +/* handler for parser COMMENT state */ +static const CHAR *comment_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p = pos; + + while (!is_eol( parser, p )) + p++; + pop_state( parser ); + return p; +} + + +/* parse a complete buffer */ +INFSTATUS +InfpParseBuffer (PINFCACHE file, + const CHAR *buffer, + const CHAR *end, + PULONG error_line) +{ + struct parser parser; + const CHAR *pos = buffer; + + parser.start = buffer; + parser.end = end; + parser.file = file; + parser.line = NULL; + parser.state = LINE_START; + parser.stack_pos = 0; + parser.cur_section = NULL; + parser.line_pos = 1; + parser.error = 0; + parser.token_len = 0; + + /* parser main loop */ + while (pos) + pos = (parser_funcs[parser.state])(&parser, pos); + + if (parser.error) + { + if (error_line) + *error_line = parser.line_pos; + return parser.error; + } + + /* find the [strings] section */ + file->StringsSection = InfpCacheFindSection (file, + _T("Strings")); + + return INF_STATUS_SUCCESS; +} + +/* EOF */ _____
Copied: trunk/reactos/lib/inflib/infget.c (from rev 19508, trunk/reactos/subsys/system/usetup/infcache.c) --- trunk/reactos/subsys/system/usetup/infcache.c 2005-11-23 23:02:35 UTC (rev 19508) +++ trunk/reactos/lib/inflib/infget.c 2005-11-24 08:07:12 UTC (rev 19516) @@ -0,0 +1,529 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: .inf file parser + * FILE: lib/inflib/infrosget.c + * PURPOSE: Read .inf routines for use in ReactOS + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + * Ge van Geldorp + */ + +/* INCLUDES *****************************************************************/ + +#include "inflib.h" + +#define NDEBUG +#include <debug.h> + + +INFSTATUS +InfpFindFirstLine(HINF InfHandle, + PCTSTR Section, + PCTSTR Key, + PINFCONTEXT *Context) +{ [truncated at 1000 lines; 1832 more skipped]