/*  This file is part of the program psim.

    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, see <http://www.gnu.org/licenses/>.
 
    */


#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>

#include "build-config.h"
#include "misc.h"
#include "lf.h"
#include "table.h"

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

typedef struct _open_table open_table;
struct _open_table {
  size_t size;
  char *buffer;
  char *pos;
  int line_nr;
  int nr_fields;
  int nr_model_fields;
  char *file_name;
  open_table *parent;
  table *root;
};
struct _table {
  open_table *current;
};

void
table_push (table *root,
	    table_include *includes,
	    const char *file_name,
	    int nr_fields,
	    int nr_model_fields)

{
  int fd;
  struct stat stat_buf;
  open_table *file;
  table_include dummy;
  table_include *include = &dummy;
  int nr;

  /* dummy up a search of this directory */
  dummy.next = includes;
  dummy.dir = "";

  /* create a file descriptor */
  file = ZALLOC (open_table);
  ASSERT(file != NULL);
  file->nr_fields = nr_fields;
  file->nr_model_fields = nr_model_fields;
  file->root = root;
  file->parent = root->current;
  root->current = file;
  
  while (1)
    {
      /* save the file name */
      char *dup_name = NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2);
      if (dup_name == NULL)
	{
	  perror (file_name);
	  exit (1);
	}
      if (include->dir[0] != '\0')
	{
	  strcat (dup_name, include->dir);
	  strcat (dup_name, "/");
	}
      strcat (dup_name, file_name);
      file->file_name = dup_name;
      /* open the file */
      fd = open (dup_name, O_RDONLY, 0);
      if (fd >= 0)
	break;
      /* free (dup_name); */
      if (include->next == NULL)
	{
	  error ("Problem opening file `%s'\n", file_name);
	  perror (file_name);
	  exit (1);
	}
      include = include->next;
  }

  /* determine the size */
  if (fstat(fd, &stat_buf) < 0) {
    perror("table_open.fstat");
    exit(1);
  }
  file->size = stat_buf.st_size;

  /* allocate this much memory */
  file->buffer = (char*)zalloc(file->size+1);
  if(file->buffer == NULL) {
    perror("table_open.calloc.file->size+1");
    exit(1);
  }
  file->pos = file->buffer;

  /* read it in */
#ifdef __CYGWIN32__
  if ((file->size) && ((nr = read(fd, file->buffer, file->size)) <= 0)) {
#else
  if ((nr = read(fd, file->buffer, file->size)) < file->size) {
#endif
    perror("table_open.read");
    exit(1);
  }
  file->size = nr;
  file->buffer[file->size] = '\0';

  /* done */
  close(fd);
}

extern table *
table_open(const char *file_name,
	   int nr_fields,
	   int nr_model_fields)
{
  table *root;

  /* create a file descriptor */
  root = ZALLOC (table);
  if (root == NULL)
    {
      perror (file_name);
      exit (1);
    }

  table_push (root, NULL, file_name, nr_fields, nr_model_fields);
  return root;
}

extern table_entry *
table_entry_read(table *root)
{
  open_table *file = root->current;
  int field;
  table_entry *entry;

  /* skip comments/blanks */
  while(1) {
    /* end-of-file? */
    while (*file->pos == '\0')
      {
        if (file->parent != NULL)
          {
            file = file->parent;
            root->current = file;
          }
        else
          return NULL;
      }
    /* leading white space */
    while (*file->pos != '\0'
	   && *file->pos != '\n'
	   && isspace(*file->pos))
      file->pos++;
    /* comment */
    if (*file->pos == '#') {
      do {
	file->pos++;
      } while (*file->pos != '\0' && *file->pos != '\n');
    }
    /* end of line? */
    if (*file->pos == '\n') {
      file->pos++;
      file->line_nr++;
    }
    else
      break;
  }

  /* create this new entry */
  entry = (table_entry*)zalloc(sizeof(table_entry)
			       + (file->nr_fields + 1) * sizeof(char*));
  ASSERT(entry != NULL);
  entry->file_name = file->file_name;
  entry->nr_fields = file->nr_fields;

  /* break the line into its colon delimitered fields */
  for (field = 0; field < file->nr_fields-1; field++) {
    entry->fields[field] = file->pos;
    while(*file->pos && *file->pos != ':' && *file->pos != '\n')
      file->pos++;
    if (*file->pos == ':') {
      *file->pos = '\0';
      file->pos++;
    }
  }

  /* any trailing stuff not the last field */
  ASSERT(field == file->nr_fields-1);
  entry->fields[field] = file->pos;
  while (*file->pos && *file->pos != '\n') {
    file->pos++;
  }
  if (*file->pos == '\n') {
    *file->pos = '\0';
    file->pos++;
  }
  file->line_nr++;

  /* if following lines begin with a star, add them to the model
     section.  */
  while ((file->nr_model_fields > 0) && (*file->pos == '*')) {
    table_model_entry *model = (table_model_entry*)zalloc(sizeof(table_model_entry)
							  + (file->nr_model_fields + 1) * sizeof(char*));
    if (entry->model_last)
      entry->model_last->next = model;
    else
      entry->model_first = model;
    entry->model_last = model;

    /* break the line into its colon delimitered fields */
    file->pos++;
    for (field = 0; field < file->nr_model_fields-1; field++) {
      model->fields[field] = file->pos;
      while(*file->pos && *file->pos != ':' && *file->pos != '\n')
	file->pos++;
      if (*file->pos == ':') {
	*file->pos = '\0';
	file->pos++;
      }
    }

    /* any trailing stuff not the last field */
    ASSERT(field == file->nr_model_fields-1);
    model->fields[field] = file->pos;
    while (*file->pos && *file->pos != '\n') {
      file->pos++;
    }
    if (*file->pos == '\n') {
      *file->pos = '\0';
      file->pos++;
    }

    file->line_nr++;
    model->line_nr = file->line_nr;
  }

  entry->line_nr = file->line_nr;

  /* if following lines are tab indented, put in the annex */
  if (*file->pos == '\t') {
    entry->annex = file->pos;
    do {
      do {
	file->pos++;
      } while (*file->pos != '\0' && *file->pos != '\n');
      if (*file->pos == '\n') {
	char *save_pos = ++file->pos;
	int extra_lines = 0;
	file->line_nr++;
	/* Allow tab indented to have blank lines */
	while (*save_pos == '\n') {
	  save_pos++;
	  extra_lines++;
	}
	if (*save_pos == '\t') {
	  file->pos = save_pos;
	  file->line_nr += extra_lines;
	}
      }
    } while (*file->pos != '\0' && *file->pos == '\t');
    if (file->pos[-1] == '\n')
      file->pos[-1] = '\0';
  }
  else
    entry->annex = NULL;

  /* return it */
  return entry;

}


extern void
dump_table_entry(table_entry *entry,
		 int indent)
{
  printf("(table_entry*)%p\n", entry);

  if (entry != NULL) {
    int field;
    char sep;

    sep = ' ';
    dumpf(indent, "(fields");
    for (field = 0; field < entry->nr_fields; field++) {
      printf("%c%s", sep, entry->fields[field]);
      sep = ':';
    }
    printf(")\n");

    dumpf(indent, "(line_nr %d)\n", entry->line_nr);

    dumpf(indent, "(file_name %s)\n", entry->file_name);

    dumpf(indent, "(annex\n%s\n", entry->annex);
    dumpf(indent, " )\n");

  }
}


extern void
table_entry_print_cpp_line_nr(lf *file,
			      table_entry *entry)
{
  lf_print__external_reference(file, entry->line_nr, entry->file_name);
}


