/* This file has been generated by the Hex-Rays decompiler.
   Copyright (c) 2007 Hex-Rays.Com <ig@hexblog.com>

   Detected compiler: Borland C++
*/

#include <windows.h>
#include <defs.h>

#include <stdarg.h>


//-------------------------------------------------------------------------
// Data declarations

extern _UNKNOWN sub_40114C;
extern _UNKNOWN sub_40901C;
extern DWORD TlsIndex; // idb
extern char arglist[]; // idb
extern int dword_40D0A8; // weak
extern int dword_40D0AC; // weak
extern char aL_eof[10]; // weak
extern void *off_40D0BC; // weak
extern char (*off_40D0C0)[6]; // weak
extern char (*off_40D0C4)[5]; // weak
extern int dword_40D0C8; // weak
extern int dword_40D0CC; // weak
extern int dword_40D0D0; // weak
extern _UNKNOWN unk_40D0D4; // weak
extern char byte_40D0E8[]; // idb
extern char *s1; // idb
extern int dword_40D1EC[]; // idb
extern int dword_40D1F0[]; // idb
extern int dword_40D5F0[]; // idb
extern int dword_40D9F0; // idb
extern int dword_40D9F4[]; // idb
extern _UNKNOWN unk_40DDF5; // weak
extern char aNoMemory[]; // idb
extern char format[]; // idb
extern char aHpp[4]; // weak
extern char aUsageStmIinclI[]; // idb
extern char aBadSwitchC[]; // idb
extern char mode[]; // idb
extern char aCanTOpenInputF[]; // idb
extern char aW[]; // idb
extern char aCanTOpenOutput[]; // idb
extern char aCanTOpenHeader[]; // idb
extern char aAny[]; // idb
extern char aNext[]; // idb
extern char aThis[]; // idb
extern char aStart[]; // idb
extern char aError[]; // idb
extern char aEnd[]; // idb
extern char a0[]; // idb
extern char aEot[4]; // weak
extern char s2[]; // idb
extern char aTermCodeErrorA[]; // idb
extern char aTermRedeclarat[]; // idb
extern char aSymbol[7]; // weak
extern char aSymbolErrorAtL[]; // idb
extern char aMetaRedeclarat[]; // idb
extern char aEos[4]; // weak
extern char asc_40DFDA[2]; // weak
extern char aLabelRedeclara[]; // idb
extern char aUndefinedTermA[]; // idb
extern char aIllegalUseOfAc[]; // idb
extern char aThisFileIsGene[]; // idb
extern char aThisFileIsGe_0[]; // idb
extern char aMetaNotFoundAt[]; // idb
extern char aSymbolSIsEmpty[]; // idb
extern char aStaticConstSSD[]; // idb
extern char aPsymbol_t[10]; // weak
extern char aBadLastChoiceA[]; // idb
extern char asc_40E1EF[]; // idb
extern char aTermMismatchAt[]; // idb
extern char aUndefinedMetaA[]; // idb
extern char aMetaMismatchAt[]; // idb
extern char aUndefinedNextL[]; // idb
extern char aNextLabelIsDef[]; // idb
extern char aUnknownSystemL[]; // idb
extern char aTypeMismatchOf[]; // idb
extern char asc_40E2ED[]; // idb
extern char a2d8sD[]; // idb
extern char aD[]; // idb
extern char aS[]; // idb
extern char aDDSS[]; // idb
extern char aSconstSConstSD[]; // idb
extern char aStatic[8]; // weak
extern char a2dS[]; // idb
extern char asc_40E358[]; // idb
extern char a2dSIdaapiSVoid[]; // idb
extern char aError_t[8]; // weak
extern char aSconstSSD[]; // idb
extern char aAction_t[9]; // weak
extern char a2dParser_tS[]; // idb
extern int (__cdecl *off_40E414)(int handle, char); // weak
extern int (__cdecl *off_40E428)(int handle, char); // weak
extern int (__cdecl *off_40E620)(int handle, char); // weak
extern int (__cdecl *off_40E634)(int handle, char); // weak
extern char (*off_40E63C)[26]; // weak
extern char (*off_40E644)[27]; // weak
extern int dword_40EB74; // weak
extern char aStackOverflow[]; // idb
extern FILE stru_40EBC4; // idb
extern UINT uNumber[]; // idb
extern _UNKNOWN unk_40F048; // weak
extern int (*off_40FD38)(void); // idb
extern char aPrintfFloati_0[]; // idb
extern char aScanfFloatin_0[]; // idb
extern char aNoSpaceForComm[]; // idb
extern char aNoSpaceForCo_0[]; // idb
extern FILE *stream; // idb
extern FILE *dword_410A9C; // idb
extern FILE *dword_410AA0; // idb
extern _UNKNOWN unk_410AA4; // weak
extern int dword_410AF4; // weak
extern int dword_410AFC; // weak
extern struct _RTL_CRITICAL_SECTION stru_410B1C; // idb
extern int dword_410B34; // weak
extern int dword_410B38; // weak
extern int dword_410B3C; // weak
extern struct _RTL_CRITICAL_SECTION stru_410B40; // idb
extern int dword_410B58; // weak
extern int dword_410B5C; // weak
extern int dword_410B60[]; // idb
extern int dword_410F60; // weak
extern int (__cdecl *dword_410F6C)(_DWORD, _DWORD, _DWORD, _DWORD); // idb
extern int (__cdecl *dword_410F70)(_DWORD, _DWORD, _DWORD, _DWORD); // idb
extern HANDLE hObject; // idb
extern void *dword_411340; // idb
extern int dword_411344; // weak
extern int dword_411378; // weak
extern int dword_411384; // weak
extern int dword_4143B8; // weak

//-------------------------------------------------------------------------
// Function declarations

int __cdecl sub_4011D3();
int sub_401230(char *format, ...); // idb
int sub_40124C(char *format, ...); // idb
int __fastcall sub_401268(int a1);
int __fastcall sub_401274(int a1, const char *a2);
void *__fastcall sub_401304(size_t size); // idb
int __cdecl main(int argc, const char **argv, const char *envp); // idb
char *__cdecl sub_401620();
char *__cdecl sub_4016EC();
// int __cdecl atoi_0(const char *s); idb
char *__cdecl sub_401800();
int __cdecl sub_401A04();
int __cdecl sub_401EE4();
int __cdecl sub_401F5C();
__int64 __cdecl sub_402010();
int __fastcall sub_402034(int a1, char *s, int a3, int a4); // idb
int __fastcall sub_4020E0(int a1, const char *a2);
int __fastcall sub_402140(int result, int a2, int a3);
// _DWORD __cdecl std__set_new_handler(_DWORD); weak
char (*__cdecl sub_402394())[26];
char (*__cdecl sub_4023A0())[27];
// int unknown_libname_1(); weak
int __cdecl sub_402410();
int __cdecl sub_40241C();
int __cdecl sub_40245C();
// void *__cdecl malloc(size_t size); idb
// void *__cdecl realloc(void *block, size_t size); idb
int (__cdecl **__cdecl sub_403464())(int, char);
void __cdecl sub_4034D8();
void __cdecl sub_403728();
// int __cdecl unknown_libname_4(int handle, char); idb
// int __cdecl unknown_libname_5(int handle, char); idb
// void *__cdecl memcpy(void *dest, const void *src, size_t n); idb
// size_t __cdecl strlen(const char *s); idb
// int __cdecl strncmp(const char *s1, const char *s2, size_t maxlen); idb
// char *__cdecl strdup(const char *s); idb
// _DWORD __cdecl __InitExceptBlockLDTC(char); weak
int __cdecl sub_403D3B();
int (__cdecl **__cdecl sub_404097())(int, char);
int __cdecl sub_4040C2();
// _DWORD __call_terminate(); weak
signed int __cdecl sub_404894(int a1, int a2, int a3, int a4);
int __cdecl sub_404980(int a1);
int __cdecl sub_4049F8();
// _DWORD __cdecl _SetExceptionHandler(_DWORD); weak
// _DWORD __doGlobalUnwind(); weak
// int __cdecl fclose(FILE *stream); idb
// char *__cdecl fgets(char *s, int n, FILE *stream); idb
// FILE *__cdecl fopen(const char *path, const char *mode); idb
// int fprintf(FILE *stream, const char *format, ...); idb
int __cdecl sub_405C58(int a1);
// _DWORD __cdecl unknown_libname_12(_DWORD); weak
// int printf(const char *format, ...); idb
// void __cdecl rewind(FILE *stream); idb
// _DWORD __cdecl _lock_stream(_DWORD); weak
// _DWORD __cdecl _unlock_stream(_DWORD); weak
// int __cdecl vfprintf(FILE *stream, const char *format, void *arglist); idb
int __cdecl sub_407024(int a1);
// int __cdecl isspace(int c); idb
int __cdecl sub_407C5E();
void __cdecl sub_407C88();
void __cdecl sub_407C94();
// int __cdecl __ldtrunc(int, long double, int, int); idb
int __cdecl sub_40838C(int a1, int a2);
int __cdecl sub_4086C0(int a1, int a2);
// int __cdecl _ErrorExit(LPCSTR lpBuffer); idb
// void __cdecl exit(int status); idb
void *__cdecl sub_409DE0(char *s, int a2); // idb
signed int __cdecl sub_40AB54();
// int __stdcall __CRTL_TLS_GetValue(DWORD dwTlsIndex); idb
// _DWORD __stdcall __CRTL_TLS_ExitThread(_DWORD); weak
// int __cdecl __raiseDebuggerException(ULONG_PTR Arguments, int); idb
// void __stdcall DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection); idb
// HANDLE GetProcessHeap(void); idb
// void __stdcall GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo); idb
// BOOL __stdcall HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem); idb
// void __stdcall InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); idb


//----- (0040114C) --------------------------------------------------------
#error "401158: invalid basic block (funcsize=5)"

//----- (004011D3) --------------------------------------------------------
int __cdecl sub_4011D3()
{
  int result; // eax@1
  void *v1; // ST08_4@2
  HANDLE v2; // eax@2

  result = __CRTL_TLS_GetValue(TlsIndex);
  if ( result )
  {
    v1 = (void *)result;
    v2 = GetProcessHeap();
    HeapFree(v2, 8u, v1);
    result = __CRTL_TLS_ExitThread(TlsIndex);
  }
  return result;
}

//----- (00401230) --------------------------------------------------------
int sub_401230(char *format, ...)
{
  va_list va; // [sp+Ch] [bp+Ch]@1

  va_start(va, format);
  return vfprintf(dword_410A9C, format, va);
}

//----- (0040124C) --------------------------------------------------------
int sub_40124C(char *format, ...)
{
  va_list va; // [sp+Ch] [bp+Ch]@1

  va_start(va, format);
  return vfprintf(dword_410AA0, format, va);
}

//----- (00401268) --------------------------------------------------------
int __fastcall sub_401268(int a1)
{
  char v2; // dl@1

  do
    v2 = *(_BYTE *)a1++;
  while ( v2 );
  return a1 - 1;
}

//----- (00401274) --------------------------------------------------------
int __fastcall sub_401274(int a1, const char *a2)
{
  int v2; // eax@1
  int v3; // ebx@1
  int v4; // esi@1
  const char *v6; // [sp+Ch] [bp-4h]@1

  v6 = a2;
  v4 = a1;
  v2 = sub_401268(a1);
  v3 = v2;
  if ( v4 <= (unsigned int)v2 )
  {
    while ( *(_BYTE *)v3 != 92 )
    {
      if ( *(_BYTE *)v3 == 46 )
      {
        strcpy((char *)(v3 + 1), v6);
        return v4;
      }
      --v3;
      if ( v4 > (unsigned int)v3 )
        break;
    }
  }
  *(_BYTE *)v2 = 46;
  strcpy((char *)(v2 + 1), v6);
  return v4;
}

//----- (00401304) --------------------------------------------------------
void *__fastcall sub_401304(size_t size)
{
  void *result; // eax@1

  result = malloc(size);
  if ( !result )
  {
    fprintf(&stru_40EBC4, "\n\n\aNo memory !!!\n");
    exit(1);
  }
  return result;
}

//----- (00401330) --------------------------------------------------------
int __cdecl main(int argc, const char **argv, const char *envp)
{
  const char **v3; // ebx@1
  int v4; // esi@1
  signed int v5; // eax@3
  int v6; // eax@5
  int v7; // eax@6
  int v8; // eax@7
  int v9; // eax@10
  int v10; // eax@11
  int v11; // eax@12
  int result; // eax@21
  char *v13; // eax@35
  char *v14; // edx@35
  char v15; // cl@36
  char v16; // zf@37
  char v17; // cl@38
  int v18; // eax@31

  v3 = argv;
  v4 = argc;
  printf(
    "Symbol Table Maker v%d.%02d. Copyright 1991-2007 Ilfak Guilfanov. Apr 30 2007\n",
    *(_DWORD *)&arglist[0],
    dword_40D0A8);
  for ( ; v4 > 3; ++v3 )
  {
    if ( **(v3 + 1) != 45 )
      break;
    v5 = *(*(v3 + 1) + 1);
    if ( v5 > 97 )
    {
      v9 = v5 - 104;
      if ( !v9 )
        goto LABEL_21;
      v10 = v9 - 1;
      if ( !v10 )
      {
        dword_40D0CC = 1;
LABEL_16:
        dword_40D0C8 = (int)(*(v3 + 1) + 2);
        goto LABEL_23;
      }
      v11 = v10 - 4;
      if ( v11 )
      {
        if ( v11 != 6 )
        {
LABEL_22:
          printf("Bad switch '%c'\n", *(*(v3 + 1) + 1));
          return 1;
        }
        dword_40D0D0 = 1;
      }
      else
      {
        off_40D0C0 = (char (*)[6])(*(v3 + 1) + 2);
      }
    }
    else
    {
      if ( v5 == 97 )
      {
        off_40D0C4 = (char (*)[5])(*(v3 + 1) + 2);
        goto LABEL_23;
      }
      v6 = v5 - 63;
      if ( !v6 || (v7 = v6 - 9, !v7) )
        goto LABEL_21;
      v8 = v7 - 1;
      if ( !v8 )
        goto LABEL_16;
      if ( v8 != 7 )
        goto LABEL_22;
      off_40D0BC = "hpp";
    }
LABEL_23:
    --v4;
  }
  if ( v4 == 3 )
  {
    stream = fopen(*(v3 + 1), "r");
    if ( !stream )
    {
      printf("Can't open input file %s\n", *(v3 + 1));
      exit(1);
    }
    dword_410A9C = fopen(*(v3 + 2), "w");
    if ( !dword_410A9C )
    {
      printf("Can't open output file %s\n", *(v3 + 2));
      exit(1);
    }
    strcpy((char *)&unk_410AA4, *(v3 + 2));
    v18 = sub_401274((int)&unk_410AA4, (const char *)off_40D0BC);
    dword_410AA0 = fopen((const char *)v18, "w");
    if ( !dword_410AA0 )
    {
      printf("Can't open header file %s\n", &unk_410AA4);
      exit(1);
    }
    sub_402034((int)&unk_40D0D4, "any", 3, 0);
    sub_402034((int)&unk_40D0D4, "next", 3, 1);
    sub_402034((int)&unk_40D0D4, "this", 3, 2);
    sub_402034((int)&unk_40D0D4, "start", 3, 3);
    sub_402034((int)&unk_40D0D4, "error", 3, -1);
    sub_402034((int)&unk_40D0D4, "end", 3, 5);
    sub_402034((int)&unk_40D0D4, "0", 3, 4);
    sub_4016EC();
    sub_401800();
    rewind(stream);
    dword_40D0AC = 0;
    do
    {
LABEL_35:
      v13 = sub_401620();
      v14 = "EOT";
      do
      {
        v15 = *v13;
        if ( *v13 != *v14 )
          goto LABEL_35;
        v16 = v15 == 0;
        if ( !v15 )
          break;
        v17 = *(v13 + 1);
        if ( v17 != *(v14 + 1) )
          goto LABEL_35;
        v13 += 2;
        v14 += 2;
        v16 = v17 == 0;
      }
      while ( v17 );
    }
    while ( !v16 );
    sub_401A04();
    fclose(stream);
    fclose(dword_410A9C);
    fclose(dword_410AA0);
    result = 0;
  }
  else
  {
LABEL_21:
    printf("Usage: stm [-Iincl] [-iincl] [-P] [-aacts] [-mmetas] infile outfile\n");
    result = 1;
  }
  return result;
}

//----- (00401620) --------------------------------------------------------
char *__cdecl sub_401620()
{
  char *v1; // ebx@10

  while ( 1 )
  {
    do
    {
      while ( !*s1 )
      {
        if ( !fgets(byte_40D0E8, 256, stream) )
          return "**l_eof**";
        ++dword_40D0AC;
        s1 = byte_40D0E8;
      }
      while ( isspace(*s1) )
        ++s1;
    }
    while ( !*s1 );
    v1 = s1;
    while ( !isspace(*s1) )
      ++s1;
    if ( *s1 )
      *s1++ = 0;
    if ( strncmp(v1, "//", 2u) )
      break;
    *s1 = 0;
  }
  return v1;
}

//----- (004016EC) --------------------------------------------------------
char *__cdecl sub_4016EC()
{
  char *v0; // eax@3
  int v1; // eax@4
  int v2; // ebx@4
  int v3; // eax@6
  int v4; // eax@11
  char *result; // eax@17
  char *v6; // edx@17
  char *v7; // esi@17
  char v8; // cl@18
  char v9; // zf@19
  char v10; // cl@20
  int v11; // eax@4

LABEL_17:
  result = sub_401620();
  v7 = result;
  v6 = "EOT";
  do
  {
    v8 = *result;
    if ( *result != *v6 )
      goto LABEL_2;
    v9 = v8 == 0;
    if ( !v8 )
      break;
    v10 = *(result + 1);
    if ( v10 != *(v6 + 1) )
    {
LABEL_2:
      if ( v7 != "**l_eof**" )
      {
        v0 = sub_401620();
        if ( *v0 == 39 )
        {
          v11 = (int)(v0 + 1);
          v2 = *(_BYTE *)v11;
          v1 = v11 + 1;
          if ( *(_BYTE *)v1 != 39 )
            v2 = *(_BYTE *)v1 + 256 * v2;
          v3 = v1 + 1;
          if ( *(_BYTE *)v3 == 61 )
          {
            v2 += 61;
          }
          else
          {
            if ( *(_BYTE *)v3 == 46 )
              v2 += 46;
          }
        }
        else
        {
          v2 = atoi_0(v0);
        }
        v4 = sub_402140((int)&unk_40D0D4, 1, v2);
        if ( v4 )
        {
          printf("Term Code Error at line %d: %s and %s\n", dword_40D0AC, v7, *(_DWORD *)(v4 + 8));
          exit(1);
        }
        sub_402034((int)&unk_40D0D4, v7, 1, v2);
        if ( dword_410AF4 )
        {
          printf("Term Redeclaration Error at line %d (%s)\n", dword_40D0AC, v7);
          exit(1);
        }
      }
      goto LABEL_17;
    }
    result += 2;
    v6 += 2;
    v9 = v10 == 0;
  }
  while ( v10 );
  if ( !v9 )
    goto LABEL_2;
  return result;
}

//----- (00401800) --------------------------------------------------------
char *__cdecl sub_401800()
{
  char *result; // eax@1
  char *v1; // edx@2
  char v2; // zf@3
  char v3; // cl@5
  char *v4; // ebx@10
  int v5; // edi@13
  char *v6; // eax@14
  char *v7; // edx@14
  char *v8; // ebx@14
  char v9; // cl@15
  char v10; // zf@16
  char v11; // cl@17
  char *v12; // esi@21
  char *v13; // eax@26
  char *v14; // edx@26
  char v15; // zf@27
  char v16; // cl@29
  int v17; // esi@32
  char *v18; // ebx@35
  char *v19; // eax@10
  int v20; // eax@32
  char *v21; // eax@35

  while ( 1 )
  {
    result = sub_401620();
    if ( result == "**l_eof**" )
      return result;
    v1 = "symbol";
    do
    {
      v2 = *result == *v1;
      if ( *result != *v1 )
        break;
      if ( !*result )
        goto LABEL_10;
      v3 = *(result + 1);
      v2 = v3 == *(v1 + 1);
      if ( v3 != *(v1 + 1) )
        break;
      result += 2;
      v1 += 2;
      v2 = v3 == 0;
    }
    while ( v3 );
    if ( !v2 )
    {
      printf("Symbol Error at line %d\n", dword_40D0AC);
      exit(1);
    }
LABEL_10:
    v19 = sub_401620();
    v4 = v19;
    dword_40D5F0[dword_40D1EC[0]++] = sub_402034((int)&unk_40D0D4, v19, 2, dword_40D1EC[0]);
    if ( dword_410AF4 )
    {
      printf("Meta Redeclaration Error at line %d (%s)\n", dword_40D0AC, v4);
      exit(1);
    }
    v5 = -1;
LABEL_14:
    ++v5;
    v6 = sub_401620();
    v8 = v6;
    v7 = "EOS";
    do
    {
      v9 = *v6;
      if ( *v6 != *v7 )
        goto LABEL_21;
      v10 = v9 == 0;
      if ( !v9 )
        break;
      v11 = *(v6 + 1);
      if ( v11 != *(v7 + 1) )
      {
LABEL_21:
        v12 = sub_401620();
LABEL_26:
        v13 = v12;
        v14 = ":";
        while ( 1 )
        {
          v15 = *v13 == *v14;
          if ( *v13 != *v14 )
            break;
          if ( !*v13 )
          {
LABEL_22:
            sub_402034((int)&unk_40D0D4, v8, 5, v5);
            if ( dword_410AF4 )
            {
              printf("Label Redeclaration Error at line %d (%s)\n", dword_40D0AC, v8);
              exit(1);
            }
            v8 = sub_401620();
            v12 = sub_401620();
            goto LABEL_26;
          }
          v16 = *(v13 + 1);
          v15 = v16 == *(v14 + 1);
          if ( v16 == *(v14 + 1) )
          {
            v13 += 2;
            v14 += 2;
            v15 = v16 == 0;
            if ( v16 )
              continue;
          }
          break;
        }
        if ( v15 )
          goto LABEL_22;
        v20 = sub_4020E0((int)&unk_40D0D4, v8);
        v17 = v20;
        if ( !v20 )
        {
          printf("Undefined term at line %d (%s)\n", dword_40D0AC, v8);
          exit(1);
        }
        sub_401620();
        v21 = sub_401620();
        v18 = v21;
        if ( !sub_4020E0((int)&unk_40D0D4, v21) )
        {
          if ( *(_DWORD *)(v17 + 12) == -1 )
          {
            printf("Illegal use of action at line %d (%s)\n", dword_40D0AC, v18);
            exit(1);
          }
          dword_40D9F4[dword_40D9F0] = sub_402034((int)&unk_40D0D4, v18, 4, dword_40D9F0);
          ++dword_40D9F0;
        }
        goto LABEL_14;
      }
      v6 += 2;
      v7 += 2;
      v10 = v11 == 0;
    }
    while ( v11 );
    if ( !v10 )
      goto LABEL_21;
    dword_40D1EC[dword_40D1EC[0]] = v5;
  }
}

//----- (00401A04) --------------------------------------------------------
int __cdecl sub_401A04()
{
  char *v0; // eax@2
  char *v2; // edx@4
  char v3; // zf@5
  char v4; // cl@7
  int v5; // eax@12
  char *v6; // ebx@12
  char *v7; // eax@19
  char *v8; // edx@19
  char *v9; // edi@19
  char v10; // cl@20
  char v11; // zf@21
  char v12; // cl@22
  char *v13; // ebx@29
  char *v14; // eax@31
  char *v15; // edx@31
  char v16; // zf@32
  char v17; // cl@34
  int v18; // esi@37
  int v19; // eax@77
  int v20; // edi@77
  bool v21; // ecx@86
  int v22; // edx@91
  _UNKNOWN *v23; // ecx@97
  _UNKNOWN *v24; // ST10_4@99
  char *v25; // edx@100
  signed int v26; // eax@103
  signed int v27; // ecx@106
  char *v28; // eax@12
  char *v29; // eax@37
  char *v30; // eax@77
  int v31; // eax@93
  signed int v32; // [sp+18h] [bp-18h]@1
  bool v33; // [sp+14h] [bp-1Ch]@1
  int v34; // [sp+10h] [bp-20h]@1
  char arglist; // [sp+2Ch] [bp-4h]@18
  int v36; // [sp+28h] [bp-8h]@37
  int v37; // [sp+24h] [bp-Ch]@37
  int v38; // [sp+20h] [bp-10h]@40
  int v39; // [sp+1Ch] [bp-14h]@66
  signed int v40; // [sp+Ch] [bp-24h]@77

  v32 = 0;
  v33 = 0;
  v34 = 0;
  sub_401230(
    "\n/*\tThis file is generated by Symbol Table Maker.\n\tCopyright (c) 1991-2006 by I.Guilfanov. Version %d.%02d */\n\n",
    *(_DWORD *)&arglist[0],
    dword_40D0A8);
  sub_40124C(
    "/*\n\tThis file is generated by Symbol Table Maker.\n\tCopyright (c) 1991-2006 by I.Guilfanov. Version %d.%02d\n\n\tThis file must be included as a part of the parser_t class definition.\n*/\n\n",
    *(_DWORD *)&arglist[0],
    dword_40D0A8);
  sub_401F5C();
  while ( 1 )
  {
    v0 = sub_401620();
    if ( v0 == "**l_eof**" )
      return sub_401EE4();
    v2 = "symbol";
    do
    {
      v3 = *v0 == *v2;
      if ( *v0 != *v2 )
        break;
      if ( !*v0 )
        goto LABEL_12;
      v4 = *(v0 + 1);
      v3 = v4 == *(v2 + 1);
      if ( v4 != *(v2 + 1) )
        break;
      v0 += 2;
      v2 += 2;
      v3 = v4 == 0;
    }
    while ( v4 );
    if ( !v3 )
    {
      printf("Symbol Error at line %d\n", dword_40D0AC);
      exit(1);
    }
LABEL_12:
    v28 = sub_401620();
    v6 = v28;
    v5 = sub_4020E0((int)&unk_40D0D4, v28);
    if ( !v5 )
    {
      printf("Meta not found at line %d (%s)\n", dword_40D0AC, v6);
      exit(1);
    }
    if ( !dword_40D1F0[v34] )
    {
      printf("Symbol %s is empty !\n", *(_DWORD *)(v5 + 8));
      exit(1);
    }
    sub_401230("static const %s %s[%d] =\n{\n", "psymbol_t", *(_DWORD *)(v5 + 8), dword_40D1F0[v34++]);
    *(_DWORD *)&arglist = -1;
    while ( 1 )
    {
      ++*(_DWORD *)&arglist;
      v7 = sub_401620();
      v9 = v7;
      v8 = "EOS";
      do
      {
        v10 = *v7;
        if ( *v7 != *v8 )
          goto LABEL_29;
        v11 = v10 == 0;
        if ( !v10 )
          break;
        v12 = *(v7 + 1);
        if ( v12 != *(v8 + 1) )
          goto LABEL_29;
        v7 += 2;
        v8 += 2;
        v11 = v12 == 0;
      }
      while ( v12 );
      if ( v11 )
        break;
LABEL_29:
      v13 = sub_401620();
LABEL_31:
      v14 = v13;
      v15 = ":";
      while ( 1 )
      {
        v16 = *v14 == *v15;
        if ( *v14 != *v15 )
          break;
        if ( !*v14 )
        {
LABEL_30:
          v9 = sub_401620();
          v13 = sub_401620();
          goto LABEL_31;
        }
        v17 = *(v14 + 1);
        v16 = v17 == *(v15 + 1);
        if ( v17 == *(v15 + 1) )
        {
          v14 += 2;
          v15 += 2;
          v16 = v17 == 0;
          if ( v17 )
            continue;
        }
        break;
      }
      if ( v16 )
        goto LABEL_30;
      v18 = sub_4020E0((int)&unk_40D0D4, v9);
      v36 = sub_4020E0((int)&unk_40D0D4, v13);
      v29 = sub_401620();
      v37 = sub_4020E0((int)&unk_40D0D4, v29);
      if ( !v18 )
      {
        printf("Undefined term at line %d (%s)\n", dword_40D0AC, v9);
        exit(1);
      }
      v38 = *(_DWORD *)(v18 + 12);
      if ( *(_DWORD *)(v18 + 16) == 3 )
      {
        if ( *(_DWORD *)(v18 + 12) && *(_DWORD *)(v18 + 12) != -1 )
        {
LABEL_46:
          printf("Term mismatch at line %d (%s)\n", dword_40D0AC, v9);
          exit(1);
        }
      }
      else
      {
        if ( *(_DWORD *)(v18 + 16) != 1 )
          goto LABEL_46;
        v38 = *(_DWORD *)(v18 + 12);
      }
      if ( *(_DWORD *)(v18 + 12) != -1 )
      {
        if ( !v36 )
        {
          printf("Undefined meta at line %d (%s)\n", dword_40D0AC, v13);
          exit(1);
        }
        v32 = *(_DWORD *)(v36 + 12);
        if ( *(_DWORD *)(v36 + 16) != 3 || *(_DWORD *)(v36 + 12) != 4 )
        {
          if ( *(_DWORD *)(v36 + 16) != 2 )
          {
            printf("Meta mismatch at line %d (%s)\n", dword_40D0AC, v13);
            exit(1);
          }
        }
        else
        {
          v32 = -1;
        }
      }
      if ( !v37 )
      {
        printf("Undefined next label at line %d\n", dword_40D0AC);
        exit(1);
      }
      if ( *(_DWORD *)(v37 + 16) != 3 )
      {
        if ( *(_DWORD *)(v37 + 16) != 5 )
        {
          printf("Next label is defined as term or meta at line %d (%s)\n", dword_40D0AC, v37);
          exit(1);
        }
      }
      if ( *(_DWORD *)(v37 + 16) == 5 )
      {
        v39 = *(_DWORD *)(v37 + 12);
      }
      else
      {
        switch ( *(_DWORD *)(v37 + 12) )
        {
          case 1:
            v39 = *(_DWORD *)&arglist + 1;
            break;
          case 2:
            v39 = *(_DWORD *)&arglist;
            break;
          case 3:
            v39 = 0;
            break;
          default:
            if ( (unsigned int)(*(_DWORD *)(v37 + 12) - 4) >= 2 )
            {
              printf("Unknown system label type %d\n", *(_DWORD *)(v37 + 12));
              exit(1);
            }
            v39 = -1;
            break;
        }
      }
      v30 = sub_401620();
      v19 = sub_4020E0((int)&unk_40D0D4, v30);
      v20 = v19;
      v40 = *(_DWORD *)(v19 + 12);
      if ( *(_DWORD *)(v19 + 16) != 4 )
      {
        if ( *(_DWORD *)(v19 + 12) != 4 || *(_DWORD *)(v19 + 16) != 3 )
        {
          printf("Type mismatch of Action at line %d\n", dword_40D0AC);
          exit(1);
        }
        v40 = -1;
      }
      v21 = *(_DWORD *)(v18 + 12) == -1 || !*(_DWORD *)(v18 + 12) && v39 <= *(_DWORD *)&arglist;
      v33 = v21;
      if ( *(_DWORD *)&arglist )
        sub_401230(",\n");
      if ( v38 > 0 )
        v22 = 1;
      else
        v22 = 3;
      v31 = sub_402140((int)&unk_40D0D4, v22, v38);
      sub_401230("/* %2d %-8s*/ { %d,\t", *(_DWORD *)&arglist, *(_DWORD *)(v31 + 8), v38);
      if ( *(_DWORD *)(v18 + 12) == -1 )
        sub_401230("%s", v13);
      else
        sub_401230("%d", v32);
      if ( *(_DWORD *)(v20 + 8) )
        v23 = *(_UNKNOWN **)(v20 + 8);
      else
        v23 = &unk_40DDF5;
      v24 = v23;
      if ( *(_DWORD *)(v18 + 12) == -1 )
        v25 = "error";
      else
        v25 = *(char **)(v36 + 8);
      if ( v40 == -1 )
        v26 = 255;
      else
        v26 = v40;
      if ( v39 == -1 )
        v27 = 255;
      else
        v27 = v39;
      sub_401230(",\t%d,\t%d,\t} /* %s,%s */", v27, v26, v25, v24);
    }
    if ( !v33 )
    {
      printf("Bad last choice at line %d\n", dword_40D0AC - 1);
      exit(1);
    }
    sub_401230("\n};\n\n");
  }
}

//----- (00401EE4) --------------------------------------------------------
int __cdecl sub_401EE4()
{
  char *v0; // edx@2
  int v1; // ebx@4

  if ( dword_40D0D0 )
    v0 = "static ";
  else
    v0 = (char *)&unk_40DDF5;
  sub_401230("%sconst %s *const %s[ %d ] = {\n", v0, "psymbol_t", off_40D0C0, dword_40D1EC[0]);
  v1 = 0;
  while ( v1 < dword_40D1EC[0] )
  {
    if ( v1 )
      sub_401230(",\n");
    sub_401230("/* %2d */ %s", v1, *(_DWORD *)(dword_40D5F0[v1] + 8));
    ++v1;
  }
  return sub_401230("\n};\n");
}

//----- (00401F5C) --------------------------------------------------------
int __cdecl sub_401F5C()
{
  int result; // eax@1
  int v1; // ebx@2
  char *v2; // eax@6
  int v3; // ebx@8

  result = dword_40D9F0;
  if ( dword_40D9F0 )
  {
    v1 = 0;
    while ( v1 < dword_40D9F0 )
    {
      sub_40124C("/* %2d */ %s idaapi %s(void);\n", v1, "error_t", *(_DWORD *)(dword_40D9F4[v1] + 8));
      ++v1;
    }
    if ( dword_40D0D0 )
      v2 = "static ";
    else
      v2 = (char *)&unk_40DDF5;
    sub_401230("\n%sconst %s %s[%d] =\n{\n", v2, "action_t", off_40D0C4, dword_40D9F0);
    v3 = 0;
    while ( v3 < dword_40D9F0 )
    {
      if ( v3 )
        sub_401230(",\n");
      sub_401230("/* %2d */ &parser_t::%s", v3, *(_DWORD *)(dword_40D9F4[v3] + 8));
      ++v3;
    }
    result = sub_401230("\n};\n\n");
  }
  return result;
}

//----- (00402010) --------------------------------------------------------
__int64 __cdecl sub_402010()
{
  __int64 result; // qax@1

  *(_DWORD *)&result = sub_401304(0x14u);
  *(_DWORD *)result = 0;
  *(_DWORD *)((_DWORD)result + 4) = 0;
  *(_DWORD *)((_DWORD)result + 8) = 0;
  result = (unsigned int)result;
  *(_DWORD *)((_DWORD)result + 12) = 0;
  *(_DWORD *)((_DWORD)result + 16) = 0;
  return result;
}

//----- (00402034) --------------------------------------------------------
int __fastcall sub_402034(int a1, char *s, int a3, int a4)
{
  int v4; // ebx@1
  char *v5; // edi@1
  int v6; // eax@2
  int v8; // ebx@7
  int v9; // [sp+Ch] [bp-4h]@1

  v9 = a3;
  v5 = s;
  v4 = a1;
  dword_410AF4 = 1;
  while ( 1 )
  {
    while ( 1 )
    {
      v6 = strcmp(v5, *(const char **)(v4 + 8));
      if ( !v6 )
        return v4;
      if ( v6 <= 0 )
        break;
      if ( !*(_DWORD *)(v4 + 4) )
      {
        *(_DWORD *)(v4 + 4) = sub_402010();
        v8 = *(_DWORD *)(v4 + 4);
        goto LABEL_11;
      }
      v4 = *(_DWORD *)(v4 + 4);
    }
    if ( !*(_DWORD *)v4 )
      break;
    v4 = *(_DWORD *)v4;
  }
  *(_DWORD *)v4 = sub_402010();
  v8 = *(_DWORD *)v4;
LABEL_11:
  dword_410AF4 = 0;
  *(_DWORD *)(v8 + 12) = a4;
  *(_DWORD *)(v8 + 16) = v9;
  *(_DWORD *)(v8 + 4) = 0;
  *(_DWORD *)v8 = 0;
  *(_DWORD *)(v8 + 8) = strdup(v5);
  return v8;
}

//----- (004020E0) --------------------------------------------------------
int __fastcall sub_4020E0(int a1, const char *a2)
{
  int v2; // ebx@1
  const char *v3; // edi@1
  int v4; // eax@2

  v3 = a2;
  v2 = a1;
  while ( 1 )
  {
    while ( 1 )
    {
      v4 = strcmp(v3, *(const char **)(v2 + 8));
      if ( !v4 )
        return v2;
      if ( v4 <= 0 )
        break;
      if ( !*(_DWORD *)(v2 + 4) )
        return 0;
      v2 = *(_DWORD *)(v2 + 4);
    }
    if ( !*(_DWORD *)v2 )
      break;
    v2 = *(_DWORD *)v2;
  }
  return 0;
}

//----- (00402140) --------------------------------------------------------
int __fastcall sub_402140(int result, int a2, int a3)
{
  int v3; // ebx@1
  int v4; // [sp+Ch] [bp-4h]@1

  v3 = result;
  v4 = a3;
  if ( a2 != *(_DWORD *)(result + 16) || v4 != *(_DWORD *)(result + 12) )
  {
    if ( !*(_DWORD *)result || (result = sub_402140(), !result) )
    {
      if ( !*(_DWORD *)(v3 + 4) || (result = sub_402140(), !result) )
        result = 0;
    }
  }
  return result;
}

//----- (00402394) --------------------------------------------------------
char (*__cdecl sub_402394())[26]
{
  return off_40E63C;
}

//----- (004023A0) --------------------------------------------------------
char (*__cdecl sub_4023A0())[27]
{
  return off_40E644;
}

//----- (00402410) --------------------------------------------------------
int __cdecl sub_402410()
{
  return std__set_new_handler(unknown_libname_1);
}

//----- (0040241C) --------------------------------------------------------
int __cdecl sub_40241C()
{
  char ST00_1_0; // ST00_1@0
  int v2; // ST00_4@1

  __InitExceptBlockLDTC(ST00_1_0);
  dword_410AFC = (int)&off_40E428;
  return v2;
}

//----- (0040245C) --------------------------------------------------------
int __cdecl sub_40245C()
{
  char ST08_1_0; // ST08_1@0

  __InitExceptBlockLDTC(ST08_1_0);
  return unknown_libname_5((int)&dword_410AFC, 2);
}

//----- (00403464) --------------------------------------------------------
int (__cdecl **__cdecl sub_403464())(int, char)
{
  char ST04_1_0; // ST04_1@0
  int (__cdecl **result)(int, char); // eax@1

  __InitExceptBlockLDTC(ST04_1_0);
  InitializeCriticalSection(&stru_410B1C);
  dword_410B34 = 1;
  dword_410B38 = (int)&off_40E634;
  result = &off_40E414;
  dword_410B3C = (int)&off_40E620;
  return result;
}

//----- (004034D8) --------------------------------------------------------
void __cdecl sub_4034D8()
{
  char ST08_1_0; // ST08_1@0
  int v1; // [sp+1Ch] [bp-8h]@1

  __InitExceptBlockLDTC(ST08_1_0);
  --v1;
  --v1;
  unknown_libname_4((int)&dword_410B3C, 0);
  --v1;
  --v1;
  unknown_libname_4((int)&dword_410B38, 0);
  --v1;
  if ( dword_410B34 )
  {
    dword_410B34 = 0;
    DeleteCriticalSection(&stru_410B1C);
  }
}

//----- (00403728) --------------------------------------------------------
void __cdecl sub_403728()
{
  char ST04_1_0; // ST04_1@0
  int v1; // [sp+1Ch] [bp-8h]@1

  __InitExceptBlockLDTC(ST04_1_0);
  --v1;
  if ( dword_410B58 )
  {
    dword_410B58 = 0;
    DeleteCriticalSection(&stru_410B40);
  }
}

//----- (00403D3B) --------------------------------------------------------
int __cdecl sub_403D3B()
{
  char ST08_1_0; // ST08_1@0
  signed int v1; // esi@1
  int result; // eax@2
  int v3; // ebx@4

  __InitExceptBlockLDTC(ST08_1_0);
  v1 = 0;
  do
  {
    result = dword_410B60[v1];
    if ( result )
    {
      if ( result )
      {
        do
        {
          v3 = *(_DWORD *)(result + 12);
          if ( result )
            (**(int (__cdecl ***)(_DWORD, _DWORD))result)(result, 3);
          result = v3;
        }
        while ( v3 );
      }
    }
    ++v1;
  }
  while ( v1 < 256 );
  return result;
}

//----- (00404097) --------------------------------------------------------
int (__cdecl **__cdecl sub_404097())(int, char)
{
  int (__cdecl **result)(int, char); // eax@1

  dword_410B5C = (int)&off_40E620;
  result = &off_40E634;
  dword_410F60 = (int)&off_40E634;
  return result;
}

//----- (004040C2) --------------------------------------------------------
int __cdecl sub_4040C2()
{
  unknown_libname_4((int)&dword_410F60, 0);
  return unknown_libname_4((int)&dword_410B5C, 0);
}

//----- (00404894) --------------------------------------------------------
signed int __cdecl sub_404894(int a1, int a2, int a3, int a4)
{
  int v4; // ebx@1
  int v5; // edi@1
  int v6; // esi@1
  signed int result; // eax@2

  v5 = a3;
  v6 = a2;
  v4 = a1;
  if ( *(_DWORD *)a1 == 250477286 )
  {
    result = 0;
  }
  else
  {
    if ( *(_DWORD *)a1 == 250608334 || *(_DWORD *)a1 == 250477262 )
    {
      __doGlobalUnwind();
      __call_terminate();
    }
    if ( *(_DWORD *)a1 == -1073741571 )
    {
      if ( dword_40EB74 )
        _ErrorExit("Stack Overflow!");
    }
    if ( !dword_410F70 || dword_410F70(a1, a2, a3, a4) )
    {
      if ( !dword_410F6C || dword_410F6C(v4, v6, v5, a4) )
      {
        if ( dword_4143B8 )
        {
          if ( *(_DWORD *)dword_4143B8 == 1 || *(_DWORD *)dword_4143B8 == 2 )
          {
            if ( *(_DWORD *)v4 < 0xEEDFACEu || *(_DWORD *)v4 > 0xEEFFACEu )
              __raiseDebuggerException(2u, 3);
          }
        }
        if ( *(_BYTE *)(v4 + 4) & 6 )
          result = 1;
        else
          result = 2;
      }
      else
      {
        result = 0;
      }
    }
    else
    {
      result = 0;
    }
  }
  return result;
}

//----- (00404980) --------------------------------------------------------
int __cdecl sub_404980(int a1)
{
  *(_DWORD *)a1 = 0;
  *(_DWORD *)(a1 + 4) = sub_404894;
  return _SetExceptionHandler(a1);
}

//----- (004049F8) --------------------------------------------------------
int __cdecl sub_4049F8()
{
  int result; // eax@1

  result = dword_411384;
  if ( dword_411384 )
    result = sub_404980(dword_411384);
  return result;
}

//----- (00405C58) --------------------------------------------------------
int __cdecl sub_405C58(int a1)
{
  UINT v1; // eax@1
  UINT *i; // edx@1
  int result; // eax@6
  void *v4; // esi@8
  int v5; // edx@9
  unsigned __int8 v6; // cl@9
  signed int v7; // [sp+8h] [bp-4h]@8
  _UNKNOWN *j; // [sp+4h] [bp-8h]@8

  v1 = uNumber[0];
  for ( i = &uNumber[uNumber[0]]; v1; --i )
  {
    if ( *i )
      break;
    --v1;
  }
  if ( a1 )
  {
    *(_DWORD *)a1 = v1;
    v7 = 0;
    v4 = (void *)(a1 + 4);
    for ( j = &unk_40F048; (signed int)v1 > v7; j = (char *)j + 4 )
    {
      v6 = 1;
      v5 = *(_DWORD *)j;
      if ( BYTE1(v5) & 8 )
        v6 = 33;
      if ( !(BYTE1(v5) & 0x80) )
        v6 |= 0x80u;
      if ( BYTE1(v5) & 0x20 )
        v6 |= 0x40u;
      *(_BYTE *)v4 = v6;
      v4 = (char *)v4 + 1;
      ++v7;
    }
    memcpy(v4, &hObject, 4 * v1);
    result = 0;
  }
  else
  {
    if ( v1 )
      result = 5 * v1 + 4;
    else
      result = 0;
  }
  return result;
}

//----- (00407024) --------------------------------------------------------
int __cdecl sub_407024(int a1)
{
  int v2; // ebx@1
  int v3; // esi@1

  v2 = a1;
  _lock_stream(a1);
  v3 = unknown_libname_12(v2);
  _unlock_stream(v2);
  return v3;
}

//----- (00407C5E) --------------------------------------------------------
int __cdecl sub_407C5E()
{
  return off_40FD38();
}

//----- (00407C88) --------------------------------------------------------
void __cdecl sub_407C88()
{
  _ErrorExit("printf : floating point formats not linked");
}

//----- (00407C94) --------------------------------------------------------
void __cdecl sub_407C94()
{
  _ErrorExit("scanf : floating point formats not linked");
}

//----- (0040838C) --------------------------------------------------------
int __cdecl sub_40838C(int a1, int a2)
{
  int result; // eax@2

  if ( a2 )
    result = a1 + 12;
  else
    result = a1 + 8;
  return result;
}

//----- (004086C0) --------------------------------------------------------
int __cdecl sub_4086C0(int a1, int a2)
{
  int result; // eax@2

  if ( a2 )
    result = a1 + 12;
  else
    result = a1 + 8;
  return result;
}

//----- (0040901C) --------------------------------------------------------
#error "FFFFFFFF: local variable allocation failed (funcsize=52)"

//----- (00409DE0) --------------------------------------------------------
void *__cdecl sub_409DE0(char *s, int a2)
{
  char *v2; // esi@1
  void *v3; // eax@5
  void *v4; // ebx@5
  void *result; // eax@9
  void *v6; // eax@2
  size_t v7; // eax@5

  v2 = s;
  if ( dword_411378 == dword_411344 )
  {
    dword_411344 += 16;
    v6 = realloc(dword_411340, 4 * dword_411344);
    dword_411340 = v6;
    if ( !v6 )
      _ErrorExit("No space for command line argument vector");
  }
  if ( a2 )
  {
    v7 = strlen(v2);
    v3 = malloc(v7 + 1);
    v4 = v3;
    if ( !v3 )
      _ErrorExit("No space for command line argument");
    strcpy((char *)v3, v2);
  }
  else
  {
    v4 = v2;
  }
  result = dword_411340;
  *((_DWORD *)dword_411340 + dword_411378++) = v4;
  return result;
}

//----- (0040AB54) --------------------------------------------------------
signed int __cdecl sub_40AB54()
{
  signed int result; // eax@2
  int v1; // [sp+0h] [bp-44h]@1
  char v2; // [sp+2Ch] [bp-18h]@1
  unsigned __int16 v3; // [sp+30h] [bp-14h]@2

  GetStartupInfoA((struct _STARTUPINFOA *)&v1);
  if ( v2 & 1 )
    result = v3;
  else
    result = 10;
  return result;
}

#error "There were 2 decompilation failure(s) on 42 function(s)"
