[SDK] One step further towards ReactOS source code tree restructure: the sdk folder...
[reactos.git] / reactos / lib / inflib / infcore.c
diff --git a/reactos/lib/inflib/infcore.c b/reactos/lib/inflib/infcore.c
deleted file mode 100644 (file)
index 7e18735..0000000
+++ /dev/null
@@ -1,832 +0,0 @@
-/*
- * PROJECT:    .inf file parser
- * LICENSE:    GPL - See COPYING in the top level directory
- * PROGRAMMER: Royce Mitchell III
- *             Eric Kohl
- *             Ge van Geldorp <gvg@reactos.org>
- */
-
-/* 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 WCHAR       *start;       /* start position of item being parsed */
-  const WCHAR       *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 */
-  INFSTATUS        error;         /* error code */
-  unsigned int     token_len;     /* current token len */
-  WCHAR token[MAX_FIELD_LEN+1];   /* current token */
-};
-
-typedef const WCHAR * (*parser_state_func)( struct parser *parser, const WCHAR *pos );
-
-/* parser state machine functions */
-static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos );
-static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos );
-static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos );
-static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos );
-static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos );
-static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos );
-static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos );
-static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos );
-static const WCHAR *comment_state( struct parser *parser, const WCHAR *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
-InfpFreeLine (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
-InfpFreeSection (PINFCACHESECTION Section)
-{
-  PINFCACHESECTION Next;
-
-  if (Section == NULL)
-    {
-      return NULL;
-    }
-
-  /* Release all keys */
-  Next = Section->Next;
-  while (Section->FirstLine != NULL)
-    {
-      Section->FirstLine = InfpFreeLine (Section->FirstLine);
-    }
-  Section->LastLine = NULL;
-
-  FREE (Section);
-
-  return Next;
-}
-
-
-PINFCACHESECTION
-InfpFindSection(PINFCACHE Cache,
-                PCWSTR Name)
-{
-  PINFCACHESECTION Section = NULL;
-
-  if (Cache == NULL || Name == NULL)
-    {
-      return NULL;
-    }
-
-  /* iterate through list of sections */
-  Section = Cache->FirstSection;
-  while (Section != NULL)
-    {
-      if (strcmpiW(Section->Name, Name) == 0)
-        {
-          return Section;
-        }
-
-      /* get the next section*/
-      Section = Section->Next;
-    }
-
-  return NULL;
-}
-
-
-PINFCACHESECTION
-InfpAddSection(PINFCACHE Cache,
-               PCWSTR Name)
-{
-  PINFCACHESECTION Section = NULL;
-  ULONG Size;
-
-  if (Cache == NULL || Name == NULL)
-    {
-      DPRINT("Invalid parameter\n");
-      return NULL;
-    }
-
-  /* Allocate and initialize the new section */
-  Size = (ULONG)FIELD_OFFSET(INFCACHESECTION,
-                             Name[strlenW(Name) + 1]);
-  Section = (PINFCACHESECTION)MALLOC(Size);
-  if (Section == NULL)
-    {
-      DPRINT("MALLOC() failed\n");
-      return NULL;
-    }
-  ZEROMEMORY (Section,
-              Size);
-
-  /* Copy section name */
-  strcpyW(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;
-}
-
-
-PINFCACHELINE
-InfpAddLine(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;
-}
-
-
-PVOID
-InfpAddKeyToLine(PINFCACHELINE Line,
-                 PCWSTR Key)
-{
-  if (Line == NULL)
-    {
-      DPRINT1("Invalid Line\n");
-      return NULL;
-    }
-
-  if (Line->Key != NULL)
-    {
-      DPRINT1("Line already has a key\n");
-      return NULL;
-    }
-
-  Line->Key = (PWCHAR)MALLOC((strlenW(Key) + 1) * sizeof(WCHAR));
-  if (Line->Key == NULL)
-    {
-      DPRINT1("MALLOC() failed\n");
-      return NULL;
-    }
-
-  strcpyW(Line->Key, Key);
-
-  return (PVOID)Line->Key;
-}
-
-
-PVOID
-InfpAddFieldToLine(PINFCACHELINE Line,
-                   PCWSTR Data)
-{
-  PINFCACHEFIELD Field;
-  ULONG Size;
-
-  Size = (ULONG)FIELD_OFFSET(INFCACHEFIELD,
-                             Data[strlenW(Data) + 1]);
-  Field = (PINFCACHEFIELD)MALLOC(Size);
-  if (Field == NULL)
-    {
-      DPRINT1("MALLOC() failed\n");
-      return NULL;
-    }
-  ZEROMEMORY (Field,
-              Size);
-  strcpyW(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
-InfpFindKeyLine(PINFCACHESECTION Section,
-                PCWSTR Key)
-{
-  PINFCACHELINE Line;
-
-  Line = Section->FirstLine;
-  while (Line != NULL)
-    {
-      if (Line->Key != NULL && strcmpiW(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 WCHAR *ptr )
-{
-  return (ptr >= parser->end || *ptr == CONTROL_Z || *ptr == 0);
-}
-
-
-/* check if the pointer points to an end of line */
-__inline static int is_eol( struct parser *parser, const WCHAR *ptr )
-{
-  return (ptr >= parser->end ||
-          *ptr == CONTROL_Z ||
-          *ptr == '\n' ||
-          (*ptr == '\r' && *(ptr + 1) == '\n') ||
-          *ptr == 0);
-}
-
-
-/* push data from current token start up to pos into the current token */
-static int push_token( struct parser *parser, const WCHAR *pos )
-{
-  UINT len = (UINT)(pos - parser->start);
-  const WCHAR *src = parser->start;
-  WCHAR *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++)
-  {
-    if (*src)
-    {
-      *dst = *src;
-    }
-    else
-    {
-      *dst = ' ';
-    }
-  }
-
-  *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 = InfpFindSection(parser->file,
-                            parser->token);
-  if (Section == NULL)
-    {
-      /* need to create a new one */
-      Section= InfpAddSection(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 = InfpAddLine(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 WCHAR *line_start_state( struct parser *parser, const WCHAR *pos )
-{
-  const WCHAR *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 (!isspaceW(*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 WCHAR *section_name_state( struct parser *parser, const WCHAR *pos )
-{
-  const WCHAR *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 WCHAR *key_name_state( struct parser *parser, const WCHAR *pos )
-{
-    const WCHAR *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 (!isspaceW(*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 WCHAR *value_name_state( struct parser *parser, const WCHAR *pos )
-{
-    const WCHAR *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 (!isspaceW(*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 WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos )
-{
-  const WCHAR *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 (isspaceW(*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 WCHAR *quotes_state( struct parser *parser, const WCHAR *pos )
-{
-  const WCHAR *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 WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos )
-{
-  const WCHAR *p;
-
-  for (p = pos; !is_eol( parser, p ); p++)
-    {
-      if (*p == '\\')
-        {
-          parser->start = p;
-          set_state( parser, EOL_BACKSLASH );
-          return p;
-        }
-      if (!isspaceW(*p))
-        break;
-    }
-  parser->start = p;
-  pop_state( parser );
-  return p;
-}
-
-
-/* handler for parser TRAILING_SPACES state */
-static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos )
-{
-  const WCHAR *p;
-
-  for (p = pos; !is_eol( parser, p ); p++)
-    {
-      if (*p == '\\')
-        {
-          set_state( parser, EOL_BACKSLASH );
-          return p;
-        }
-      if (!isspaceW(*p))
-        break;
-    }
-  pop_state( parser );
-  return p;
-}
-
-
-/* handler for parser COMMENT state */
-static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos )
-{
-  const WCHAR *p = pos;
-
-  while (!is_eol( parser, p ))
-     p++;
-  pop_state( parser );
-  return p;
-}
-
-
-/* parse a complete buffer */
-INFSTATUS
-InfpParseBuffer (PINFCACHE file,
-                 const WCHAR *buffer,
-                 const WCHAR *end,
-                 PULONG error_line)
-{
-  struct parser parser;
-  const WCHAR *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 = InfpFindSection(file,
-                                         L"Strings");
-
-  return INF_STATUS_SUCCESS;
-}
-
-/* EOF */