/* 
   * Copyright (C) 2001-2003, CompHEP Collaboration
   *------------------------------------------------------
   * $Id: tag_reader.c,v 1.8 2003/08/25 09:33:18 sherstnv Exp $
   *
   * $Log: tag_reader.c,v $
   * Revision 1.8  2003/08/25 09:33:18  sherstnv
   * type midstr - middlestr is changed
   *
   * Revision 1.7  2003/06/25 18:46:41  kryukov
   * *** empty log message ***
   *
   * Revision 1.6  2003/06/17 11:15:26  sherstnv
   * An error in memory usage has been fixed.
   *
   * Revision 1.5  2003/04/22 09:01:19  kryukov
   * Apply indent to improve readability of files
   *
   * Revision 1.4  2003/04/20 17:55:02  kryukov
   * Clean up warnings during make
   *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "evnt_tools.h"

#include "tag_reader.h"

FILE *evfile;


static int command_reader (char *command_buffer) {
  char symb = '0';
  char buff[MAX_COMMAND_LENTH];
  int i = 0;

  for (;; ++i) {
    symb = new_symbol (evfile);
    if (i == MAX_COMMAND_LENTH - 1) {
      fprintf (stderr, "\nWarning: size of the command exceeds limit (%i tokens)! Command: %s\n", MAX_COMMAND_LENTH, command_buffer);
    }

    if (symb == '\'') {
      buff[i++] = symb;
      char allsymb = fgetc (evfile);
      while (allsymb != '\'') {
        buff[i++] = allsymb;
        allsymb = fgetc (evfile);
        if (i >= MAX_COMMAND_LENTH) {
          strncpy (command_buffer, buff, i);
          return 0;
        }
      }
      buff[i++] = allsymb;
      symb = new_symbol (evfile);
    }

    if (symb != ',' && i < MAX_COMMAND_LENTH) {
      buff[i] = symb;
    } else {
      strncpy (command_buffer, buff, i);
      return 0;
    }
  }
  return 1;
}


static int
tagname_reader (middlestr tagname)
{
  int i;
  char symb;

  int max_tg_l = sizeof (middlestr) / sizeof (char);
  for (i = 0;; i++)
    {
      symb = new_symbol (evfile);
      if (i == max_tg_l)
        {
          fprintf (stderr, "\nWarning: size of the tag name exceeds limit (%i tokens)! Tag name: %s\n",
                   max_tg_l, tagname);
        }
      if (symb != ':' && i <= max_tg_l)
        {
          tagname[i] = symb;
          tagname[i + 1] = '\0';
        }
      else
        {
          return 0;
        }
    }
}


static void
tag_reader (elementary_tag * tag)
{
  int i;
  char symb;
  middlestr tagname;
  char *com;

  if (tagname_reader (tagname))
    {
      fprintf (stderr, "\n***Error! function: command_reader, error with tag syntax in tag %s\n", tagname);
      exit (1);
    }
  strcpy (tag->tagname, tagname);

  for (i = 0; i < MAX_COMMAND_NUMBER; i++)
    {
      symb = new_symbol (evfile);
      if (symb == ';')
        {
          tag->tagsize = i;
          return;
        }
      else
        {
          fseek (evfile, -1, 1);
        }
      com = calloc (MAX_COMMAND_LENTH, sizeof (char));
      if (command_reader (com))
        {
          fprintf (stderr, "\n***Error! function: command_reader, error with command syntax in tag %s\n", tag->tagname);
          exit (1);
        }
      tag->commands[i] = com;
      tag->commands = realloc (tag->commands, (2 + i) * sizeof (char *));
    }

  fprintf (stderr, "\nWarning: number of commands in the tag %s exceeds limit (%i commands)!\n",
           tag->tagname, MAX_COMMAND_NUMBER);
  for (;;)
    {
      symb = new_symbol (evfile);
      if (symb == ';')
        return;
    }
}


extern int
cup_reader (FILE * inFile, tags * all_tags)
{
  int j = 0, y;
  char symbol;
  elementary_tag *tag;

  evfile = inFile;
  for (y = 0;; y++)
    {
      symbol = new_symbol (evfile);
      if (symbol == '#')
        {
          symbol = new_symbol (evfile);
          if (symbol != '#')
            {
              fprintf (stderr, "CPYTH format error ...");
              return -1;
            }
        }
      else
        {
          fprintf (stderr, "This file is not in CPYTH format!");
          return -2;
        }
      tag = init_tag (1);
      tag_reader (tag);
      if (strlen (tag->tagname) > 0)
        {
          all_tags->tag[j] = tag;
          j++;
          all_tags->tag = realloc (all_tags->tag, (j + 1) * sizeof (elementary_tag));
        }
      else
        {
          free (tag);
        }
      symbol = new_symbol (evfile);
      if (symbol == ';' || y > 10000)
        {
          all_tags->number_of_tags = j;
          return 0;
        }
      else
        fseek (evfile, -1, SEEK_CUR);
    }
}


extern elementary_tag *
init_tag (int n)
{
  int i;
  elementary_tag *tag;

  tag = malloc (sizeof (elementary_tag));
  tag->used = 0;
  tag->tagsize = n;
  tag->commands = malloc (n * sizeof (char *));
  for (i = 0; i < n; i++)
    {
      tag->commands[i] = malloc (MAX_COMMAND_LENTH * sizeof (char));
    }
  return tag;
}


tags *
init_cap (int in)
{
  tags *the_tags;
  int i;

  the_tags = malloc (sizeof (tags));
  the_tags->number_of_tags = in;
  the_tags->tag = malloc (in * sizeof (elementary_tag));
  for (i = 0; i < in; i++)
    the_tags->tag[i] = init_tag (1);

  return the_tags;
}
