head	1.1;
access;
symbols;
locks;
comment	@ * @;


1.1
date	93.07.02.18.26.52;	author wolff;	state Exp;
branches;
next	;


desc
@@


1.1
log
@Initial revision
@
text
@#define BEZLEN 21
#define ABEZLEN 80
#define BUFSIZE 4096
#define FILEANZ 10

#include <stdio.h>
#include "pool.h"
#include "structs.h"

/* PROCEDUREN:

  initscanner()
  
  freescanner()

  load("filename")
  
  save("filename")
  
*/
  
/* globale Variablen */
char ch, *filenames[FILEANZ];
FILE *file;
int filecnt=0;
FILE *files[FILEANZ];
char symbol;
int line=1, oldline;
int classcnt=0, compcnt=0;

struct shipclass shipclasses[CLASSMAX];
struct component components[COMPMAX];
char *waffen[WEAPONMAX];


void getch() /* eof ist ein char */
{
  ch=getc(file);
}

keyword(char *word, char abbrev)
{
  pool_new();
  pool_put(word, strlen(word));
  pool_id();
  pool_set(id);
  pool_sym(abbrev);
}

change(int id, char abbrev)
{
  pool_set(id);
  pool_change_sym(abbrev);
}

setinfo(char *word, char abbrev, char *info)
{
  pool_new();
  pool_put(word, strlen(word));
  pool_id();
  pool_set(id);
  pool_sym(abbrev);
  pool_set_info(info);
}

addinfo(int id, char *info)
{
  pool_set(id);
  pool_set_info(info);
}

void closefiles()
{
  while(filecnt>0)
  {
    free(filenames[filecnt]);
    fclose(files[--filecnt]);
  }
}

void closefile()
{
  free(filenames[filecnt]);
  fclose(files[--filecnt]);
  if (filecnt>0) file=files[filecnt-1];
}

int openfile(char *filename)
{
  if (filecnt==FILEANZ) error("ERROR: too many files. line %d\n", line);
  files[filecnt]=fopen(filename, "r");
  if (!files[filecnt]) error("ERROR: cannot open %s.\n", (int)filename);
  filenames[filecnt]=(char *)malloc(strlen(filename)+1);
  strcpy(filenames[filecnt], filename);
  file=files[filecnt++];
}


void Bezeichner()
{
  char bez[BEZLEN];
  int i;

  i=0;
  if (ch=='a')
  { 
    bez[i++]=ch;
    getch();
    if ((ch>='0')&&(ch<='9')) 
    {
      symbol='A';
      return;
    }
  }
  while(((ch>='a')&&(ch<='z')) || ((ch>='A')&&(ch<='Z')) || ((ch>='0')&&(ch<='9')) || (ch=='-') )
  {
    if (i<BEZLEN) 
    {
      bez[i]=ch;
      i++;
    }
    getch();
  }
  pool_new(); pool_put(bez,i); pool_id();
  pool_set(id);
  symbol=pool_sym('1');
}

void ABezeichner()
{
  char bez[ABEZLEN];
  int i;

  i=0;
  getch();
  while((ch!='"'))
  {
    if ((ch==EOF)||(ch=='\n')) error("ERROR: unmatched quotes. line %d\n", line);
    if (i<ABEZLEN) 
    {
      bez[i]=ch;
      i++;
    }
    getch();
  }
  pool_new(); pool_put(bez,i); pool_id();
  getch();
  symbol=pool_sym('2');
}

char Zahl()
{
  char bez[BEZLEN];
  int i;

  i=0;
  while((ch>='0')&&(ch<='9'))
  {
    bez[i]=ch;
    i++;
    getch();
  }
  bez[i]='\0';
  id=atol(bez);
  symbol='3';
}

void Kommentar()
{
  while((ch!='\n')&&(ch!=EOF)) getch();
}

error(char *err, int arg)
{
  printf("FILE: %s\n", filenames[filecnt-1]);
  closefiles();
  printf(err, arg);
  _abort();
}

warning(char *warn, int arg)
{
  printf("FILE: %s\n", filenames[filecnt-1]);
  printf(warn, arg);
}

int getsym()
{
  while(ch!=EOF)
  {	
    if ((ch==' ')||(ch=='\t')||(ch=='=')||(ch==':')) getch();
    else
    if (((ch>='a')&&(ch<='z')) || ((ch>='A')&&(ch<='Z'))) 
    {
      Bezeichner();
      return 1;
    }
    else 
    if (((ch>='0')&&(ch<='9'))) 
    {
      Zahl();
      return 1;
    }
    else
    if (ch=='"')
    {
      ABezeichner();
      return '1';
    }
    else
    if (ch=='{')
    { 
      getch();
      symbol='{';
      return 1;
    }
    else
    if (ch=='}')
    { 
      getch();
      symbol='}';
      return 1;
    }
    else
    if (ch=='/')
    {
      getch();
      symbol='/';
      return 1;
    }
    else
    if (ch=='\n')
    {
      line++;
      getch();
    }
    else
    if (ch=='-')
    {
      getch();
      symbol='-';
      return 1;
    }
    else
    if (ch=='+')
    { 
      getch();
      symbol='+';
      return 1;
    }
    else
    if (ch=='(')
    {
      getch();
      symbol='(';
      return 1;
    }
    else
    if (ch==')')
    {
      getch();
      symbol=')';
      return 1;
    }
    else
    if (ch==',')
    {
      getch();
      symbol=',';
      return 1;
    }
    else
    if (ch==';') Kommentar();
    else
    {
      error("unknown char at line %d\n", line);
    }
  }
  return EOF;
}

int Plusminus() /* -1 = '-', +1 = '+' & ''. geht weiter */ 
{
  switch(symbol)
  {
    case '-':
      getsym();
      return -1;
    case '+': 
      getsym();
    default:
      return +1;
  }
}

int getzahl() /* geht NICHT weiter */
{
  getsym();
  if (symbol!='3') error("ERROR: zahl erwartet. line %d\n", line);
  return id;
}
  
parser()
{
  int quit=0;
  
  getch();
  getsym();
  while((!feof(file))&&!quit)
  {
    switch (symbol)
    {
      case 'L': 
        class();
        break;
      case 'O':
        component();
        break;
      case 'W':
        weapons();
        break;
      default:
        error("ERROR: unknown symbol. line %d\n", line);
    }
  }    
}


load(char *filename)
{
  openfile(filename);
  parser();
  closefile();
}

initscanner()
{
  pool_init();

  keyword("CLASS", 'L');
  keyword("COMPONENT", 'O');
  keyword("SB", 'S');
  keyword("WEM", 'W');
  keyword("WM", 'w');
  keyword("FM", 'F');
  keyword("RMIN", 'R');
  keyword("RMAX", 'r');
  keyword("SMIN", 's');
  keyword("SM", 'M');
  keyword("SN", 'N');
  keyword("LIMIT", 'l');
  keyword("EXCL", 'E');
  keyword("COSTS", 'C');
  keyword("EXTRA", 'e');
  keyword("TEXT", 't');
  keyword("WEAPONS", 'W');
}

freescanner()
{
  pool_free();
}

class()
{

  shipclasses[classcnt].sb=100;
  shipclasses[classcnt].wem=-1;
  shipclasses[classcnt].wm=100;
  shipclasses[classcnt].sm=0;
  shipclasses[classcnt].smanz=0;
  shipclasses[classcnt].fm=100;
  shipclasses[classcnt].rmin=0;
  shipclasses[classcnt].rmax=100;
  shipclasses[classcnt].smin=0;
  shipclasses[classcnt].sn=0;
  
  getsym();
  if (symbol=='1')
  {
    pool_set(id);
    shipclasses[classcnt].abr=(char *)malloc(strlen(pool+position)+1);
    strcpy(shipclasses[classcnt].abr, pool+position);
  }
  else
    error("ERROR: <Bez> erwartet. line %d\n", line);
  getsym();
  if (symbol=='2')
  {
    pool_set(id);
    shipclasses[classcnt].name=(char *)malloc(strlen(pool+position)+1);
    strcpy(shipclasses[classcnt].name, pool+position);
  }
  else
    error("ERROR: <ABez> erwartet. line %d\n", line);
  shipclasses[classcnt].tonage=getzahl();
  getsym();
  if (symbol=='{')
  {
    int quit=0;
    
    while (!quit&&!feof(file))
    {
      getsym();
      switch (symbol)
      {
        case 'S': 
          shipclasses[classcnt].sb=getzahl();
          break;
        case 'W': 
          shipclasses[classcnt].wem=getzahl();
          break;
        case 'w': 
          shipclasses[classcnt].wm=getzahl();
          break;
        case 'F': 
          shipclasses[classcnt].fm=getzahl();
          break;
        case 'R': 
          shipclasses[classcnt].rmin=getzahl();
          break;
        case 'r': 
          shipclasses[classcnt].rmax=getzahl();
          break;
        case 's': 
          shipclasses[classcnt].smin=getzahl();
          break;
        case 'M': 
          getsym();
          shipclasses[classcnt].sm=id;
          shipclasses[classcnt].smanz=getzahl();
          break;
        case 'N': 
          getsym();
          shipclasses[classcnt].sn=id;
          break;
        case '}':
          classcnt++;
          if (classcnt==CLASSMAX) error("ERROR: Too many Classes. line %d\n", line);
          shipclasses[classcnt].abr=NULL;
          quit=1;
          break;
        default:
          error("ERROR: Syntax fehler. line %d\n", line);
      }
    }
  }
  else
    error("ERROR: Block '{' erwartet. line %d\n", line);
  getsym();
}

component()
{
  int i;

  components[compcnt].limit[0]=0;
  components[compcnt].excl[0]=0;

  getsym();
  if (symbol=='1')
  {
    pool_set(id);
    components[compcnt].typ=(char *)malloc(strlen(pool+position)+1);
    strcpy(components[compcnt].typ, pool+position);
  }
  else
    error("ERROR: <Bez> erwartet. line %d\n", line);
  getsym();
  if (symbol=='1')
  {
    pool_set(id);
    components[compcnt].abr=(char *)malloc(strlen(pool+position)+1);
    strcpy(components[compcnt].abr, pool+position);
  }
  else
    error("ERROR: <Bez> erwartet. line %d\n", line);
  getsym();
  if (symbol=='2')
  {
    pool_set(id);
    components[compcnt].name=(char *)malloc(strlen(pool+position)+1);
    strcpy(components[compcnt].name, pool+position);
  }
  else
    error("ERROR: <ABez> erwartet. line %d\n", line);
  getsym();
  if (symbol=='{')
  {
    int quit=0;
    
    getsym();
    while (!quit&&!feof(file))
    {
      switch (symbol)
      {
        case 'l': 
          getsym();
          i=0;
          if (symbol=='1')
          {
            pool_set(id);
            components[compcnt].limit[i]=(char *)malloc(strlen(pool+position)+1);
            strcpy(components[compcnt].limit[i++], pool+position);
            getsym();
            if (symbol==',')
            {
              int quit=0;
        
              while(!quit&&!feof(file)&&(i<10))
              {
                getsym();
                pool_set(id);
                components[compcnt].limit[i]=(char *)malloc(strlen(pool+position)+1);
                strcpy(components[compcnt].limit[i++], pool+position);
                getsym();
                if (symbol!=',') quit=1;
              }
            } 
            if (i<10) components[compcnt].limit[i]=0;
          }    
          break;
        case 'E': 
          getsym();
          i=0;
          if (symbol=='1')
          {
            pool_set(id);
            components[compcnt].excl[i]=(char *)malloc(strlen(pool+position)+1);
            strcpy(components[compcnt].excl[i++], pool+position);
            getsym();
            if (symbol==',')
            {
              int quit=0;
        
              while(!quit&&!feof(file)&&(i<10))
              {
                getsym();
                pool_set(id);
                components[compcnt].excl[i]=(char *)malloc(strlen(pool+position)+1);
                strcpy(components[compcnt].excl[i++], pool+position);
                getsym();
                if (symbol!=',') quit=1;
              }
            } 
            if (i<10) components[compcnt].excl[i]=0;
          }    
          break;
        case 'C': 
          components[compcnt].iep=getzahl();
          components[compcnt].mcr=getzahl();
          getsym();
          break;
        case 'e': 
          components[compcnt].extra=getzahl();
          getsym();
          break;
        case 't':
          getsym();
          if (symbol=='2')
          {
            pool_set(id);
            components[compcnt].text=(char *)malloc(strlen(pool+position)+1);
            strcpy(components[compcnt].text, pool+position);
            getsym();
          }
          else
            error("ERROR: <ABez> erwartet. line %d\n", line);
          break;
        case '}':
          compcnt++;
          if (compcnt==CLASSMAX) error("ERROR: Too many Components. line %d\n", line);
          components[compcnt].typ=NULL;
          quit=1;
          break;
        default:
          error("ERROR: Syntax fehler. line %d\n", line);
      }
    }
  }
  else
    error("ERROR: Block '{' erwartet. line %d\n", line);
  getsym();
}

weapons()
{
  int i;

  getsym();
  i=0;
  if (symbol=='1')
  {
    pool_set(id);
    waffen[i]=(char *)malloc(strlen(pool+position)+1);
    strcpy(waffen[i++], pool+position);
    getsym();
    if (symbol==',')
    {
      int quit=0;

      while(!quit&&!feof(file)&&(i<10))
      {
        getsym();
        pool_set(id);
        waffen[i]=(char *)malloc(strlen(pool+position)+1);
        strcpy(waffen[i++], pool+position);
        getsym();
        if (symbol!=',') quit=1;
      }
    } 
    if (i<10) waffen[i]=NULL;
  }    
}
@
