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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [sim/] [igen/] [table.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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