OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [sim/] [igen/] [table.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*  This file is part of the program psim.
2
 
3
    Copyright (C) 1994-1995,1997 Andrew Cagney <cagney@highland.com.au>
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 
19
    */
20
 
21
 
22
#include <sys/types.h>
23
#include <sys/stat.h>
24
#include <stdio.h>
25
#include <fcntl.h>
26
#include <ctype.h>
27
 
28
#include "config.h"
29
#include "misc.h"
30
#include "lf.h"
31
#include "table.h"
32
 
33
#ifdef HAVE_UNISTD_H
34
#include <unistd.h>
35
#endif
36
 
37
#ifdef HAVE_STDLIB_H
38
#include <stdlib.h>
39
#endif
40
 
41
typedef struct _open_table open_table;
42
struct _open_table {
43
  size_t size;
44
  char *buffer;
45
  char *pos;
46
  line_ref pseudo_line;
47
  line_ref real_line;
48
  open_table *parent;
49
  table *root;
50
};
51
struct _table {
52
  open_table *current;
53
};
54
 
55
 
56
static line_ref *
57
current_line (open_table *file)
58
{
59
  line_ref *entry = ZALLOC (line_ref);
60
  *entry = file->pseudo_line;
61
  return entry;
62
}
63
 
64
static table_entry *
65
new_table_entry (open_table *file,
66
                 table_entry_type type)
67
{
68
  table_entry *entry;
69
  entry = ZALLOC (table_entry);
70
  entry->file = file->root;
71
  entry->line = current_line (file);
72
  entry->type = type;
73
  return entry;
74
}
75
 
76
static void
77
set_nr_table_entry_fields (table_entry *entry,
78
                           int nr_fields)
79
{
80
  entry->field = NZALLOC (char*, nr_fields + 1);
81
  entry->nr_fields = nr_fields;
82
}
83
 
84
 
85
void
86
table_push (table *root,
87
            line_ref *line,
88
            table_include *includes,
89
            const char *file_name)
90
{
91
  FILE *ff;
92
  open_table *file;
93
  table_include dummy;
94
  table_include *include = &dummy;
95
 
96
  /* dummy up a search of this directory */
97
  dummy.next = includes;
98
  dummy.dir = "";
99
 
100
  /* create a file descriptor */
101
  file = ZALLOC (open_table);
102
  if (file == NULL)
103
    {
104
      perror (file_name);
105
      exit (1);
106
    }
107
  file->root = root;
108
  file->parent = root->current;
109
  root->current = file;
110
 
111
  while (1)
112
    {
113
      /* save the file name */
114
      char *dup_name = NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2);
115
      if (dup_name == NULL)
116
        {
117
          perror (file_name);
118
          exit (1);
119
        }
120
      if (include->dir[0] != '\0')
121
        {
122
          strcat (dup_name, include->dir);
123
          strcat (dup_name, "/");
124
        }
125
      strcat (dup_name, file_name);
126
      file->real_line.file_name = dup_name;
127
      file->pseudo_line.file_name = dup_name;
128
      /* open the file */
129
 
130
      ff = fopen (dup_name, "rb");
131
      if (ff)
132
        break;
133
      /* zfree (dup_name); */
134
      if (include->next == NULL)
135
        {
136
          if (line != NULL)
137
            error (line, "Problem opening file `%s'\n", file_name);
138
          perror (file_name);
139
          exit (1);
140
        }
141
      include = include->next;
142
  }
143
 
144
 
145
  /* determine the size */
146
  fseek (ff, 0, SEEK_END);
147
  file->size = ftell (ff);
148
  fseek (ff, 0, SEEK_SET);
149
 
150
  /* allocate this much memory */
151
  file->buffer = (char*) zalloc (file->size + 1);
152
  if (file->buffer == NULL)
153
    {
154
      perror (file_name);
155
      exit (1);
156
    }
157
  file->pos = file->buffer;
158
 
159
  /* read it all in */
160
  if (fread (file->buffer, 1, file->size, ff) < file->size) {
161
    perror (file_name);
162
    exit (1);
163
  }
164
  file->buffer[file->size] = '\0';
165
 
166
  /* set the initial line numbering */
167
  file->real_line.line_nr = 1; /* specifies current line */
168
  file->pseudo_line.line_nr = 1; /* specifies current line */
169
 
170
  /* done */
171
  fclose (ff);
172
}
173
 
174
table *
175
table_open (const char *file_name)
176
{
177
  table *root;
178
 
179
  /* create a file descriptor */
180
  root = ZALLOC (table);
181
  if (root == NULL)
182
    {
183
      perror (file_name);
184
      exit (1);
185
    }
186
 
187
  table_push (root, NULL, NULL, file_name);
188
  return root;
189
}
190
 
191
char *
192
skip_spaces (char *chp)
193
{
194
  while (1)
195
    {
196
      if (*chp == '\0'
197
          || *chp == '\n'
198
          || !isspace (*chp))
199
        return chp;
200
      chp++;
201
    }
202
}
203
 
204
 
205
char *
206
back_spaces (char *start, char *chp)
207
{
208
  while (1)
209
    {
210
      if (chp <= start
211
          || !isspace (chp[-1]))
212
        return chp;
213
      chp--;
214
    }
215
}
216
 
217
char *
218
skip_digits (char *chp)
219
{
220
  while (1)
221
    {
222
      if (*chp == '\0'
223
          || *chp == '\n'
224
          || !isdigit (*chp))
225
        return chp;
226
      chp++;
227
    }
228
}
229
 
230
char *
231
skip_to_separator (char *chp,
232
                   char *separators)
233
{
234
  while (1)
235
    {
236
      char *sep = separators;
237
      while (1)
238
        {
239
          if (*chp == *sep)
240
            return chp;
241
          if (*sep == '\0')
242
            break;
243
          sep++;
244
        }
245
      chp++;
246
    }
247
}
248
 
249
static char *
250
skip_to_null (char *chp)
251
{
252
  return skip_to_separator (chp, "");
253
}
254
 
255
 
256
static char *
257
skip_to_nl (char * chp)
258
{
259
  return skip_to_separator (chp, "\n");
260
}
261
 
262
 
263
static void
264
next_line (open_table *file)
265
{
266
  file->pos = skip_to_nl (file->pos);
267
  if (*file->pos == '0')
268
    error (&file->pseudo_line, "Missing <nl> at end of line\n");
269
  *file->pos = '\0';
270
  file->pos += 1;
271
  file->real_line.line_nr += 1;
272
  file->pseudo_line.line_nr += 1;
273
}
274
 
275
 
276
extern table_entry *
277
table_read (table *root)
278
{
279
  open_table *file = root->current;
280
  table_entry *entry = NULL;
281
  while(1)
282
    {
283
 
284
      /* end-of-file? */
285
      while (*file->pos == '\0')
286
        {
287
          if (file->parent != NULL)
288
            {
289
              file = file->parent;
290
              root->current = file;
291
            }
292
          else
293
            return NULL;
294
        }
295
 
296
      /* code_block? */
297
      if (*file->pos == '{')
298
        {
299
          char *chp;
300
          next_line (file); /* discard leading brace */
301
          entry = new_table_entry (file, table_code_entry);
302
          chp = file->pos;
303
          /* determine how many lines are involved - look for <nl> "}" */
304
          {
305
            int nr_lines = 0;
306
            while (*file->pos != '}')
307
              {
308
                next_line (file);
309
                nr_lines++;
310
              }
311
            set_nr_table_entry_fields (entry, nr_lines);
312
          }
313
          /* now enter each line */
314
          {
315
            int line_nr;
316
            for (line_nr = 0; line_nr < entry->nr_fields; line_nr++)
317
              {
318
                if (strncmp (chp, "  ", 2) == 0)
319
                  entry->field[line_nr] = chp + 2;
320
                else
321
                  entry->field[line_nr] = chp;
322
                chp = skip_to_null (chp) + 1;
323
              }
324
            /* skip trailing brace */
325
            ASSERT (*file->pos == '}');
326
            next_line (file);
327
          }
328
          break;
329
        }
330
 
331
      /* tab block? */
332
      if (*file->pos == '\t')
333
        {
334
          char *chp = file->pos;
335
          entry = new_table_entry (file, table_code_entry);
336
          /* determine how many lines are involved - look for <nl> !<tab> */
337
          {
338
            int nr_lines = 0;
339
            int nr_blank_lines = 0;
340
            while (1)
341
              {
342
                if (*file->pos == '\t')
343
                  {
344
                    nr_lines = nr_lines + nr_blank_lines + 1;
345
                    nr_blank_lines = 0;
346
                    next_line (file);
347
                  }
348
                else
349
                  {
350
                    file->pos = skip_spaces (file->pos);
351
                    if (*file->pos != '\n')
352
                      break;
353
                    nr_blank_lines++;
354
                    next_line (file);
355
                  }
356
              }
357
            set_nr_table_entry_fields (entry, nr_lines);
358
          }
359
          /* now enter each line */
360
          {
361
            int line_nr;
362
            for (line_nr = 0; line_nr < entry->nr_fields; line_nr++)
363
              {
364
                if (*chp == '\t')
365
                  entry->field[line_nr] = chp + 1;
366
                else
367
                  entry->field[line_nr] = ""; /* blank */
368
                chp = skip_to_null (chp) + 1;
369
              }
370
          }
371
          break;
372
        }
373
 
374
      /* cpp directive? */
375
      if (file->pos[0] == '#')
376
        {
377
          char *chp = skip_spaces (file->pos + 1);
378
 
379
          /* cpp line-nr directive - # <line-nr> "<file>" */
380
          if (isdigit (*chp)
381
              && *skip_digits (chp) == ' '
382
              && *skip_spaces (skip_digits (chp)) == '"')
383
            {
384
              int line_nr;
385
              char *file_name;
386
              file->pos = chp;
387
              /* parse the number */
388
              line_nr = atoi(file->pos) - 1;
389
              /* skip to the file name */
390
              while (file->pos[0] != '0'
391
                     && file->pos[0] != '"'
392
                     && file->pos[0] != '\0')
393
                file->pos++;
394
              if (file->pos[0] != '"')
395
                error (&file->real_line, "Missing opening quote in cpp directive\n");
396
              /* parse the file name */
397
              file->pos++;
398
              file_name = file->pos;
399
              while (file->pos[0] != '"'
400
                     && file->pos[0] != '\0')
401
                file->pos++;
402
              if (file->pos[0] != '"')
403
                error (&file->real_line, "Missing closing quote in cpp directive\n");
404
              file->pos[0] = '\0';
405
              file->pos++;
406
              file->pos = skip_to_nl (file->pos);
407
              if (file->pos[0] != '\n')
408
                error (&file->real_line, "Missing newline in cpp directive\n");
409
              file->pseudo_line.file_name = file_name;
410
              file->pseudo_line.line_nr = line_nr;
411
              next_line (file);
412
              continue;
413
            }
414
 
415
          /* #define and #undef - not implemented yet */
416
 
417
          /* Old style # comment */
418
          next_line (file);
419
          continue;
420
        }
421
 
422
      /* blank line or end-of-file? */
423
      file->pos = skip_spaces (file->pos);
424
      if (*file->pos == '\0')
425
        error (&file->pseudo_line, "Missing <nl> at end of file\n");
426
      if (*file->pos == '\n')
427
        {
428
          next_line (file);
429
          continue;
430
        }
431
 
432
      /* comment - leading // or # - skip */
433
      if ((file->pos[0] == '/' && file->pos[1] == '/')
434
          || (file->pos[0] == '#'))
435
        {
436
          next_line (file);
437
          continue;
438
        }
439
 
440
      /* colon field */
441
      {
442
        char *chp = file->pos;
443
        entry = new_table_entry (file, table_colon_entry);
444
        next_line (file);
445
        /* figure out how many fields */
446
        {
447
          int nr_fields = 1;
448
          char *tmpch = chp;
449
          while (1)
450
            {
451
              tmpch = skip_to_separator (tmpch, "\\:");
452
              if (*tmpch == '\\')
453
                {
454
                  /* eat the escaped character */
455
                  char *cp = tmpch;
456
                  while (cp[1] != '\0')
457
                    {
458
                      cp[0] = cp[1];
459
                      cp++;
460
                    }
461
                  cp[0] = '\0';
462
                  tmpch++;
463
                }
464
              else if (*tmpch != ':')
465
                break;
466
              else
467
                {
468
                  *tmpch = '\0';
469
                  tmpch++;
470
                  nr_fields++;
471
                }
472
            }
473
          set_nr_table_entry_fields (entry, nr_fields);
474
        }
475
        /* now parse them */
476
        {
477
          int field_nr;
478
          for (field_nr = 0; field_nr < entry->nr_fields; field_nr++)
479
            {
480
              chp = skip_spaces (chp);
481
              entry->field[field_nr] = chp;
482
              chp = skip_to_null (chp);
483
              *back_spaces (entry->field[field_nr], chp) = '\0';
484
              chp++;
485
            }
486
        }
487
        break;
488
      }
489
 
490
    }
491
 
492
  ASSERT (entry == NULL || entry->field[entry->nr_fields] == NULL);
493
  return entry;
494
}
495
 
496
extern void
497
table_print_code (lf *file,
498
                  table_entry *entry)
499
{
500
  int field_nr;
501
  int nr = 0;
502
  for (field_nr = 0;
503
       field_nr < entry->nr_fields;
504
       field_nr++)
505
    {
506
      char *chp = entry->field[field_nr];
507
      int in_bit_field = 0;
508
      if (*chp == '#')
509
        lf_indent_suppress(file);
510
      while (*chp != '\0')
511
        {
512
          if (chp[0] == '{'
513
              && !isspace(chp[1])
514
              && chp[1] != '\0')
515
            {
516
              in_bit_field = 1;
517
              nr += lf_putchr(file, '_');
518
            }
519
          else if (in_bit_field && chp[0] == ':')
520
            {
521
              nr += lf_putchr(file, '_');
522
            }
523
          else if (in_bit_field && *chp == '}')
524
            {
525
              nr += lf_putchr(file, '_');
526
              in_bit_field = 0;
527
            }
528
          else
529
            {
530
              nr += lf_putchr(file, *chp);
531
            }
532
          chp++;
533
        }
534
      if (in_bit_field)
535
        {
536
          line_ref line = *entry->line;
537
          line.line_nr += field_nr;
538
          error (&line, "Bit field brace miss match\n");
539
        }
540
      nr += lf_putchr(file, '\n');
541
    }
542
}
543
 
544
 
545
 
546
void
547
dump_line_ref (lf *file,
548
                 char *prefix,
549
                 const line_ref *line,
550
                 char *suffix)
551
{
552
  lf_printf (file, "%s(line_ref*) 0x%lx", prefix, (long) line);
553
  if (line != NULL)
554
    {
555
      lf_indent (file, +1);
556
      lf_printf (file, "\n(line_nr %d)", line->line_nr);
557
      lf_printf (file, "\n(file_name %s)", line->file_name);
558
      lf_indent (file, -1);
559
    }
560
  lf_printf (file, "%s", suffix);
561
}
562
 
563
 
564
static const char *
565
table_entry_type_to_str (table_entry_type type)
566
{
567
  switch (type)
568
    {
569
    case table_code_entry: return "code-entry";
570
    case table_colon_entry: return "colon-entry";
571
    }
572
  return "*invalid*";
573
}
574
 
575
void
576
dump_table_entry(lf *file,
577
                 char *prefix,
578
                 const table_entry *entry,
579
                 char *suffix)
580
{
581
  lf_printf (file, "%s(table_entry*) 0x%lx", prefix, (long) entry);
582
  if (entry != NULL)
583
    {
584
      int field;
585
      lf_indent (file, +1);
586
      dump_line_ref (file, "\n(line ", entry->line, ")");
587
      lf_printf (file, "\n(type %s)", table_entry_type_to_str (entry->type));
588
      lf_printf (file, "\n(nr_fields %d)", entry->nr_fields);
589
      lf_printf (file, "\n(fields");
590
      lf_indent (file, +1);
591
      for (field = 0; field < entry->nr_fields; field++)
592
        lf_printf (file, "\n\"%s\"", entry->field[field]);
593
      lf_indent (file, -1);
594
      lf_printf (file, ")");
595
      lf_indent (file, -1);
596
    }
597
  lf_printf (file, "%s", suffix);
598
}
599
 
600
 
601
#ifdef MAIN
602
int
603
main(int argc, char **argv)
604
{
605
  table *t;
606
  table_entry *entry;
607
  lf *l;
608
  int line_nr;
609
 
610
  if (argc != 2)
611
    {
612
      printf("Usage: table <file>\n");
613
      exit (1);
614
    }
615
 
616
  t = table_open (argv[1]);
617
  l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-table");
618
 
619
  line_nr = 0;
620
  do
621
    {
622
      char line[10];
623
      entry = table_read (t);
624
      line_nr ++;
625
      sprintf (line, "(%d ", line_nr);
626
      dump_table_entry (l, line, entry, ")\n");
627
    }
628
  while (entry != NULL);
629
 
630
  return 0;
631
}
632
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.