/*  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
#include <stdlib.h>

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);
}


