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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [sim/] [igen/] [table.c] - Blame information for rev 438

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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