2003-10-08 Roland McGrath <roland@redhat.com>
[deliverable/binutils-gdb.git] / sim / ppc / table.c
index cc065fce2717fe03abf7517e563e77faa76033c3..d9538b3d7d87a4f9c8bf63db3013da8debb85927 100644 (file)
@@ -25,6 +25,7 @@
 #include <fcntl.h>
 #include <ctype.h>
 
+#include "config.h"
 #include "misc.h"
 #include "lf.h"
 #include "table.h"
 #include <stdlib.h>
 #endif
 
-struct _table {
+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;
 };
 
-extern table *
-table_open(char *file_name,
-          int nr_fields)
+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;
-  table *file;
+  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(table);
+  file = ZALLOC (open_table);
   ASSERT(file != NULL);
   file->nr_fields = nr_fields;
-
-  /* save the file name */
-  file->file_name = (char*)zalloc(strlen(file_name) + 1);
-  ASSERT(file->file_name != NULL);
-  strcpy(file->file_name, file_name);
-
-  /* open the file */
-  fd = open(file->file_name, O_RDONLY, 0);
-  ASSERT(fd >= 0);
+  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;
+      /* zfree (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) {
@@ -84,26 +128,60 @@ table_open(char *file_name,
   file->pos = file->buffer;
 
   /* read it in */
-  if (read(fd, file->buffer, file->size) < file->size) {
+#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);
-  return file;
 }
 
+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 *file)
+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'
@@ -123,8 +201,6 @@ table_entry_read(table *file)
     else
       break;
   }
-  if (*file->pos == '\0')
-    return NULL;
 
   /* create this new entry */
   entry = (table_entry*)zalloc(sizeof(table_entry)
@@ -155,9 +231,48 @@ table_entry_read(table *file)
     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 tab indented, put in the annex */
+  /* if following lines are tab indented, put in the annex */
   if (*file->pos == '\t') {
     entry->annex = file->pos;
     do {
@@ -165,8 +280,18 @@ table_entry_read(table *file)
        file->pos++;
       } while (*file->pos != '\0' && *file->pos != '\n');
       if (*file->pos == '\n') {
-       file->pos++;
+       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')
@@ -211,10 +336,10 @@ dump_table_entry(table_entry *entry,
 
 
 extern void
-table_entry_lf_c_line_nr(lf *file,
-                        table_entry *entry)
+table_entry_print_cpp_line_nr(lf *file,
+                             table_entry *entry)
 {
-  lf_print_c_line_nr(file, entry->line_nr, entry->file_name);
+  lf_print__external_reference(file, entry->line_nr, entry->file_name);
 }
 
 
This page took 0.026173 seconds and 4 git commands to generate.