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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [read-md.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* MD reader for GCC.
2
   Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
3
   2003, 2004, 2005, 2006, 2007, 2008, 2010
4
   Free Software Foundation, Inc.
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
#include "bconfig.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "hashtab.h"
26
#include "errors.h"
27
#include "read-md.h"
28
 
29
/* Associates PTR (which can be a string, etc.) with the file location
30
   specified by FILENAME and LINENO.  */
31
struct ptr_loc {
32
  const void *ptr;
33
  const char *filename;
34
  int lineno;
35
};
36
 
37
/* A singly-linked list of filenames.  */
38
struct file_name_list {
39
  struct file_name_list *next;
40
  const char *fname;
41
};
42
 
43
/* Obstack used for allocating MD strings.  */
44
struct obstack string_obstack;
45
 
46
/* A table of ptr_locs, hashed on the PTR field.  */
47
static htab_t ptr_locs;
48
 
49
/* An obstack for the above.  Plain xmalloc is a bit heavyweight for a
50
   small structure like ptr_loc.  */
51
static struct obstack ptr_loc_obstack;
52
 
53
/* A hash table of triples (A, B, C), where each of A, B and C is a condition
54
   and A is equivalent to "B && C".  This is used to keep track of the source
55
   of conditions that are made up of separate MD strings (such as the split
56
   condition of a define_insn_and_split).  */
57
static htab_t joined_conditions;
58
 
59
/* An obstack for allocating joined_conditions entries.  */
60
static struct obstack joined_conditions_obstack;
61
 
62
/* The file we are reading.  */
63
FILE *read_md_file;
64
 
65
/* The filename of READ_MD_FILE.  */
66
const char *read_md_filename;
67
 
68
/* The current line number in READ_MD_FILE.  */
69
int read_md_lineno;
70
 
71
/* The name of the toplevel file that indirectly included READ_MD_FILE.  */
72
const char *in_fname;
73
 
74
/* The directory part of IN_FNAME.  NULL if IN_FNAME is a bare filename.  */
75
static char *base_dir;
76
 
77
/* The first directory to search.  */
78
static struct file_name_list *first_dir_md_include;
79
 
80
/* A pointer to the null terminator of the md include chain.  */
81
static struct file_name_list **last_dir_md_include_ptr = &first_dir_md_include;
82
 
83
/* This callback will be invoked whenever an md include directive is
84
   processed.  To be used for creation of the dependency file.  */
85
void (*include_callback) (const char *);
86
 
87
/* The current maximum length of directory names in the search path
88
   for include files.  (Altered as we get more of them.)  */
89
static size_t max_include_len;
90
 
91
/* A table of md_constant structures, hashed by name.  Null if no
92
   constant expansion should occur.  */
93
static htab_t md_constants;
94
 
95
/* A table of enum_type structures, hashed by name.  */
96
static htab_t enum_types;
97
 
98
static void handle_file (directive_handler_t);
99
 
100
/* Given an object that starts with a char * name field, return a hash
101
   code for its name.  */
102
 
103
hashval_t
104
leading_string_hash (const void *def)
105
{
106
  return htab_hash_string (*(const char *const *) def);
107
}
108
 
109
/* Given two objects that start with char * name fields, return true if
110
   they have the same name.  */
111
 
112
int
113
leading_string_eq_p (const void *def1, const void *def2)
114
{
115
  return strcmp (*(const char *const *) def1,
116
                 *(const char *const *) def2) == 0;
117
}
118
 
119
/* Return a hash value for the pointer pointed to by DEF.  */
120
 
121
static hashval_t
122
leading_ptr_hash (const void *def)
123
{
124
  return htab_hash_pointer (*(const void *const *) def);
125
}
126
 
127
/* Return true if DEF1 and DEF2 are pointers to the same pointer.  */
128
 
129
static int
130
leading_ptr_eq_p (const void *def1, const void *def2)
131
{
132
  return *(const void *const *) def1 == *(const void *const *) def2;
133
}
134
 
135
/* Associate PTR with the file position given by FILENAME and LINENO.  */
136
 
137
static void
138
set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
139
{
140
  struct ptr_loc *loc;
141
 
142
  loc = (struct ptr_loc *) obstack_alloc (&ptr_loc_obstack,
143
                                          sizeof (struct ptr_loc));
144
  loc->ptr = ptr;
145
  loc->filename = filename;
146
  loc->lineno = lineno;
147
  *htab_find_slot (ptr_locs, loc, INSERT) = loc;
148
}
149
 
150
/* Return the position associated with pointer PTR.  Return null if no
151
   position was set.  */
152
 
153
static const struct ptr_loc *
154
get_md_ptr_loc (const void *ptr)
155
{
156
  return (const struct ptr_loc *) htab_find (ptr_locs, &ptr);
157
}
158
 
159
/* Associate NEW_PTR with the same file position as OLD_PTR.  */
160
 
161
void
162
copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
163
{
164
  const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
165
  if (loc != 0)
166
    set_md_ptr_loc (new_ptr, loc->filename, loc->lineno);
167
}
168
 
169
/* If PTR is associated with a known file position, print a #line
170
   directive for it.  */
171
 
172
void
173
print_md_ptr_loc (const void *ptr)
174
{
175
  const struct ptr_loc *loc = get_md_ptr_loc (ptr);
176
  if (loc != 0)
177
    printf ("#line %d \"%s\"\n", loc->lineno, loc->filename);
178
}
179
 
180
/* Return a condition that satisfies both COND1 and COND2.  Either string
181
   may be null or empty.  */
182
 
183
const char *
184
join_c_conditions (const char *cond1, const char *cond2)
185
{
186
  char *result;
187
  const void **entry;
188
 
189
  if (cond1 == 0 || cond1[0] == 0)
190
    return cond2;
191
 
192
  if (cond2 == 0 || cond2[0] == 0)
193
    return cond1;
194
 
195
  if (strcmp (cond1, cond2) == 0)
196
    return cond1;
197
 
198
  result = concat ("(", cond1, ") && (", cond2, ")", NULL);
199
  obstack_ptr_grow (&joined_conditions_obstack, result);
200
  obstack_ptr_grow (&joined_conditions_obstack, cond1);
201
  obstack_ptr_grow (&joined_conditions_obstack, cond2);
202
  entry = XOBFINISH (&joined_conditions_obstack, const void **);
203
  *htab_find_slot (joined_conditions, entry, INSERT) = entry;
204
  return result;
205
}
206
 
207
/* Print condition COND, wrapped in brackets.  If COND was created by
208
   join_c_conditions, recursively invoke this function for the original
209
   conditions and join the result with "&&".  Otherwise print a #line
210
   directive for COND if its original file position is known.  */
211
 
212
void
213
print_c_condition (const char *cond)
214
{
215
  const char **halves = (const char **) htab_find (joined_conditions, &cond);
216
  if (halves != 0)
217
    {
218
      printf ("(");
219
      print_c_condition (halves[1]);
220
      printf (" && ");
221
      print_c_condition (halves[2]);
222
      printf (")");
223
    }
224
  else
225
    {
226
      putc ('\n', stdout);
227
      print_md_ptr_loc (cond);
228
      printf ("(%s)", cond);
229
    }
230
}
231
 
232
/* A vfprintf-like function for reporting an error against line LINENO
233
   of the current MD file.  */
234
 
235
static void ATTRIBUTE_PRINTF(2,0)
236
message_with_line_1 (int lineno, const char *msg, va_list ap)
237
{
238
  fprintf (stderr, "%s:%d: ", read_md_filename, lineno);
239
  vfprintf (stderr, msg, ap);
240
  fputc ('\n', stderr);
241
}
242
 
243
/* A printf-like function for reporting an error against line LINENO
244
   in the current MD file.  */
245
 
246
void
247
message_with_line (int lineno, const char *msg, ...)
248
{
249
  va_list ap;
250
 
251
  va_start (ap, msg);
252
  message_with_line_1 (lineno, msg, ap);
253
  va_end (ap);
254
}
255
 
256
/* Like message_with_line, but treat the condition as an error.  */
257
 
258
void
259
error_with_line (int lineno, const char *msg, ...)
260
{
261
  va_list ap;
262
 
263
  va_start (ap, msg);
264
  message_with_line_1 (lineno, msg, ap);
265
  va_end (ap);
266
  have_error = 1;
267
}
268
 
269
/* A printf-like function for reporting an error against the current
270
   position in the MD file.  */
271
 
272
void
273
fatal_with_file_and_line (const char *msg, ...)
274
{
275
  char context[64];
276
  size_t i;
277
  int c;
278
  va_list ap;
279
 
280
  va_start (ap, msg);
281
 
282
  fprintf (stderr, "%s:%d: ", read_md_filename, read_md_lineno);
283
  vfprintf (stderr, msg, ap);
284
  putc ('\n', stderr);
285
 
286
  /* Gather some following context.  */
287
  for (i = 0; i < sizeof (context)-1; ++i)
288
    {
289
      c = read_char ();
290
      if (c == EOF)
291
        break;
292
      if (c == '\r' || c == '\n')
293
        {
294
          unread_char (c);
295
          break;
296
        }
297
      context[i] = c;
298
    }
299
  context[i] = '\0';
300
 
301
  fprintf (stderr, "%s:%d: following context is `%s'\n",
302
           read_md_filename, read_md_lineno, context);
303
 
304
  va_end (ap);
305
  exit (1);
306
}
307
 
308
/* Report that we found character ACTUAL when we expected to find
309
   character EXPECTED.  */
310
 
311
void
312
fatal_expected_char (int expected, int actual)
313
{
314
  if (actual == EOF)
315
    fatal_with_file_and_line ("expected character `%c', found EOF",
316
                              expected);
317
  else
318
    fatal_with_file_and_line ("expected character `%c', found `%c'",
319
                              expected, actual);
320
}
321
 
322
/* Read chars from the MD file until a non-whitespace char and return that.
323
   Comments, both Lisp style and C style, are treated as whitespace.  */
324
 
325
int
326
read_skip_spaces (void)
327
{
328
  int c;
329
 
330
  while (1)
331
    {
332
      c = read_char ();
333
      switch (c)
334
        {
335
        case ' ': case '\t': case '\f': case '\r': case '\n':
336
          break;
337
 
338
        case ';':
339
          do
340
            c = read_char ();
341
          while (c != '\n' && c != EOF);
342
          break;
343
 
344
        case '/':
345
          {
346
            int prevc;
347
            c = read_char ();
348
            if (c != '*')
349
              {
350
                unread_char (c);
351
                fatal_with_file_and_line ("stray '/' in file");
352
              }
353
 
354
            prevc = 0;
355
            while ((c = read_char ()) && c != EOF)
356
              {
357
                if (prevc == '*' && c == '/')
358
                  break;
359
                prevc = c;
360
              }
361
          }
362
          break;
363
 
364
        default:
365
          return c;
366
        }
367
    }
368
}
369
 
370
/* Read an rtx code name into NAME.  It is terminated by any of the
371
   punctuation chars of rtx printed syntax.  */
372
 
373
void
374
read_name (struct md_name *name)
375
{
376
  int c;
377
  size_t i;
378
 
379
  c = read_skip_spaces ();
380
 
381
  i = 0;
382
  while (1)
383
    {
384
      if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r'
385
          || c == EOF)
386
        break;
387
      if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
388
          || c == '(' || c == '[')
389
        {
390
          unread_char (c);
391
          break;
392
        }
393
 
394
      if (i == sizeof (name->buffer) - 1)
395
        fatal_with_file_and_line ("name too long");
396
      name->buffer[i++] = c;
397
 
398
      c = read_char ();
399
    }
400
 
401
  if (i == 0)
402
    fatal_with_file_and_line ("missing name or number");
403
 
404
  name->buffer[i] = 0;
405
  name->string = name->buffer;
406
 
407
  if (md_constants)
408
    {
409
      /* Do constant expansion.  */
410
      struct md_constant *def;
411
 
412
      do
413
        {
414
          struct md_constant tmp_def;
415
 
416
          tmp_def.name = name->string;
417
          def = (struct md_constant *) htab_find (md_constants, &tmp_def);
418
          if (def)
419
            name->string = def->value;
420
        }
421
      while (def);
422
    }
423
}
424
 
425
/* Subroutine of the string readers.  Handles backslash escapes.
426
   Caller has read the backslash, but not placed it into the obstack.  */
427
 
428
static void
429
read_escape (void)
430
{
431
  int c = read_char ();
432
 
433
  switch (c)
434
    {
435
      /* Backslash-newline is replaced by nothing, as in C.  */
436
    case '\n':
437
      return;
438
 
439
      /* \" \' \\ are replaced by the second character.  */
440
    case '\\':
441
    case '"':
442
    case '\'':
443
      break;
444
 
445
      /* Standard C string escapes:
446
         \a \b \f \n \r \t \v
447
         \[0-7] \x
448
         all are passed through to the output string unmolested.
449
         In normal use these wind up in a string constant processed
450
         by the C compiler, which will translate them appropriately.
451
         We do not bother checking that \[0-7] are followed by up to
452
         two octal digits, or that \x is followed by N hex digits.
453
         \? \u \U are left out because they are not in traditional C.  */
454
    case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
455
    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
456
    case '7': case 'x':
457
      obstack_1grow (&string_obstack, '\\');
458
      break;
459
 
460
      /* \; makes stuff for a C string constant containing
461
         newline and tab.  */
462
    case ';':
463
      obstack_grow (&string_obstack, "\\n\\t", 4);
464
      return;
465
 
466
      /* pass anything else through, but issue a warning.  */
467
    default:
468
      fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
469
               read_md_filename, read_md_lineno, c);
470
      obstack_1grow (&string_obstack, '\\');
471
      break;
472
    }
473
 
474
  obstack_1grow (&string_obstack, c);
475
}
476
 
477
/* Read a double-quoted string onto the obstack.  Caller has scanned
478
   the leading quote.  */
479
 
480
char *
481
read_quoted_string (void)
482
{
483
  int c;
484
 
485
  while (1)
486
    {
487
      c = read_char (); /* Read the string  */
488
      if (c == '\\')
489
        {
490
          read_escape ();
491
          continue;
492
        }
493
      else if (c == '"' || c == EOF)
494
        break;
495
 
496
      obstack_1grow (&string_obstack, c);
497
    }
498
 
499
  obstack_1grow (&string_obstack, 0);
500
  return XOBFINISH (&string_obstack, char *);
501
}
502
 
503
/* Read a braced string (a la Tcl) onto the string obstack.  Caller
504
   has scanned the leading brace.  Note that unlike quoted strings,
505
   the outermost braces _are_ included in the string constant.  */
506
 
507
static char *
508
read_braced_string (void)
509
{
510
  int c;
511
  int brace_depth = 1;  /* caller-processed */
512
  unsigned long starting_read_md_lineno = read_md_lineno;
513
 
514
  obstack_1grow (&string_obstack, '{');
515
  while (brace_depth)
516
    {
517
      c = read_char (); /* Read the string  */
518
 
519
      if (c == '{')
520
        brace_depth++;
521
      else if (c == '}')
522
        brace_depth--;
523
      else if (c == '\\')
524
        {
525
          read_escape ();
526
          continue;
527
        }
528
      else if (c == EOF)
529
        fatal_with_file_and_line
530
          ("missing closing } for opening brace on line %lu",
531
           starting_read_md_lineno);
532
 
533
      obstack_1grow (&string_obstack, c);
534
    }
535
 
536
  obstack_1grow (&string_obstack, 0);
537
  return XOBFINISH (&string_obstack, char *);
538
}
539
 
540
/* Read some kind of string constant.  This is the high-level routine
541
   used by read_rtx.  It handles surrounding parentheses, leading star,
542
   and dispatch to the appropriate string constant reader.  */
543
 
544
char *
545
read_string (int star_if_braced)
546
{
547
  char *stringbuf;
548
  int saw_paren = 0;
549
  int c, old_lineno;
550
 
551
  c = read_skip_spaces ();
552
  if (c == '(')
553
    {
554
      saw_paren = 1;
555
      c = read_skip_spaces ();
556
    }
557
 
558
  old_lineno = read_md_lineno;
559
  if (c == '"')
560
    stringbuf = read_quoted_string ();
561
  else if (c == '{')
562
    {
563
      if (star_if_braced)
564
        obstack_1grow (&string_obstack, '*');
565
      stringbuf = read_braced_string ();
566
    }
567
  else
568
    fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
569
 
570
  if (saw_paren)
571
    {
572
      c = read_skip_spaces ();
573
      if (c != ')')
574
        fatal_expected_char (')', c);
575
    }
576
 
577
  set_md_ptr_loc (stringbuf, read_md_filename, old_lineno);
578
  return stringbuf;
579
}
580
 
581
/* Skip the rest of a construct that started at line LINENO and that
582
   is currently nested by DEPTH levels of parentheses.  */
583
 
584
void
585
read_skip_construct (int depth, int lineno)
586
{
587
  struct md_name name;
588
  int c;
589
 
590
  do
591
    {
592
      c = read_skip_spaces ();
593
      if (c == EOF)
594
        {
595
          error_with_line (lineno, "unterminated construct");
596
          exit (1);
597
        }
598
      switch (c)
599
        {
600
        case '(':
601
          depth++;
602
          break;
603
 
604
        case ')':
605
          depth--;
606
          break;
607
 
608
        case ':':
609
        case '[':
610
        case ']':
611
        case '/':
612
          break;
613
 
614
        case '\"':
615
        case '{':
616
          unread_char (c);
617
          read_string (false);
618
          break;
619
 
620
        default:
621
          unread_char (c);
622
          read_name (&name);
623
          break;
624
        }
625
    }
626
  while (depth > 0);
627
  unread_char (c);
628
}
629
 
630
/* Given a string, return the number of comma-separated elements in it.
631
   Return 0 for the null string.  */
632
 
633
int
634
n_comma_elts (const char *s)
635
{
636
  int n;
637
 
638
  if (*s == '\0')
639
    return 0;
640
 
641
  for (n = 1; *s; s++)
642
    if (*s == ',')
643
      n++;
644
 
645
  return n;
646
}
647
 
648
/* Given a pointer to a (char *), return a pointer to the beginning of the
649
   next comma-separated element in the string.  Advance the pointer given
650
   to the end of that element.  Return NULL if at end of string.  Caller
651
   is responsible for copying the string if necessary.  White space between
652
   a comma and an element is ignored.  */
653
 
654
const char *
655
scan_comma_elt (const char **pstr)
656
{
657
  const char *start;
658
  const char *p = *pstr;
659
 
660
  if (*p == ',')
661
    p++;
662
  while (ISSPACE(*p))
663
    p++;
664
 
665
  if (*p == '\0')
666
    return NULL;
667
 
668
  start = p;
669
 
670
  while (*p != ',' && *p != '\0')
671
    p++;
672
 
673
  *pstr = p;
674
  return start;
675
}
676
 
677
/* Convert STRING to uppercase.  */
678
 
679
void
680
upcase_string (char *string)
681
{
682
  int i;
683
 
684
  for (i = 0; string[i]; i++)
685
    string[i] = TOUPPER (string[i]);
686
}
687
 
688
/* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
689
   where both NAME and VALUE are malloc()ed strings.  PARENT_ENUM is the
690
   enum to which NAME belongs, or null if NAME is a stand-alone constant.  */
691
 
692
static struct md_constant *
693
add_constant (htab_t defs, char *name, char *value,
694
              struct enum_type *parent_enum)
695
{
696
  struct md_constant *def, tmp_def;
697
  void **entry_ptr;
698
 
699
  tmp_def.name = name;
700
  entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
701
  if (*entry_ptr)
702
    {
703
      def = (struct md_constant *) *entry_ptr;
704
      if (strcmp (def->value, value) != 0)
705
        fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
706
                                  def->name, def->value, value);
707
      else if (parent_enum || def->parent_enum)
708
        fatal_with_file_and_line ("redefinition of `%s'", def->name);
709
      free (name);
710
      free (value);
711
    }
712
  else
713
    {
714
      def = XNEW (struct md_constant);
715
      def->name = name;
716
      def->value = value;
717
      def->parent_enum = parent_enum;
718
      *entry_ptr = def;
719
    }
720
  return def;
721
}
722
 
723
/* Process a define_constants directive, starting with the optional space
724
   after the "define_constants".  */
725
 
726
static void
727
handle_constants (void)
728
{
729
  int c;
730
  htab_t defs;
731
 
732
  c = read_skip_spaces ();
733
  if (c != '[')
734
    fatal_expected_char ('[', c);
735
 
736
  /* Disable constant expansion during definition processing.  */
737
  defs = md_constants;
738
  md_constants = 0;
739
  while ( (c = read_skip_spaces ()) != ']')
740
    {
741
      struct md_name name, value;
742
 
743
      if (c != '(')
744
        fatal_expected_char ('(', c);
745
 
746
      read_name (&name);
747
      read_name (&value);
748
      add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
749
 
750
      c = read_skip_spaces ();
751
      if (c != ')')
752
        fatal_expected_char (')', c);
753
    }
754
  md_constants = defs;
755
}
756
 
757
/* For every constant definition, call CALLBACK with two arguments:
758
   a pointer a pointer to the constant definition and INFO.
759
   Stop when CALLBACK returns zero.  */
760
 
761
void
762
traverse_md_constants (htab_trav callback, void *info)
763
{
764
  htab_traverse (md_constants, callback, info);
765
}
766
 
767
/* Return a malloc()ed decimal string that represents number NUMBER.  */
768
 
769
static char *
770
decimal_string (int number)
771
{
772
  /* A safe overestimate.  +1 for sign, +1 for null terminator.  */
773
  char buffer[sizeof (int) * CHAR_BIT + 1 + 1];
774
 
775
  sprintf (buffer, "%d", number);
776
  return xstrdup (buffer);
777
}
778
 
779
/* Process a define_enum or define_c_enum directive, starting with
780
   the optional space after the "define_enum".  LINENO is the line
781
   number on which the directive started and MD_P is true if the
782
   directive is a define_enum rather than a define_c_enum.  */
783
 
784
static void
785
handle_enum (int lineno, bool md_p)
786
{
787
  char *enum_name, *value_name;
788
  struct md_name name;
789
  struct enum_type *def;
790
  struct enum_value *ev;
791
  void **slot;
792
  int c;
793
 
794
  enum_name = read_string (false);
795
  slot = htab_find_slot (enum_types, &enum_name, INSERT);
796
  if (*slot)
797
    {
798
      def = (struct enum_type *) *slot;
799
      if (def->md_p != md_p)
800
        error_with_line (lineno, "redefining `%s' as a different type of enum",
801
                         enum_name);
802
    }
803
  else
804
    {
805
      def = XNEW (struct enum_type);
806
      def->name = enum_name;
807
      def->md_p = md_p;
808
      def->values = 0;
809
      def->tail_ptr = &def->values;
810
      def->num_values = 0;
811
      *slot = def;
812
    }
813
 
814
  c = read_skip_spaces ();
815
  if (c != '[')
816
    fatal_expected_char ('[', c);
817
 
818
  while ((c = read_skip_spaces ()) != ']')
819
    {
820
      if (c == EOF)
821
        {
822
          error_with_line (lineno, "unterminated construct");
823
          exit (1);
824
        }
825
      unread_char (c);
826
      read_name (&name);
827
 
828
      ev = XNEW (struct enum_value);
829
      ev->next = 0;
830
      if (md_p)
831
        {
832
          value_name = concat (def->name, "_", name.string, NULL);
833
          upcase_string (value_name);
834
          ev->name = xstrdup (name.string);
835
        }
836
      else
837
        {
838
          value_name = xstrdup (name.string);
839
          ev->name = value_name;
840
        }
841
      ev->def = add_constant (md_constants, value_name,
842
                              decimal_string (def->num_values), def);
843
 
844
      *def->tail_ptr = ev;
845
      def->tail_ptr = &ev->next;
846
      def->num_values++;
847
    }
848
}
849
 
850
/* Try to find the definition of the given enum.  Return null on failure.  */
851
 
852
struct enum_type *
853
lookup_enum_type (const char *name)
854
{
855
  return (struct enum_type *) htab_find (enum_types, &name);
856
}
857
 
858
/* For every enum definition, call CALLBACK with two arguments:
859
   a pointer to the constant definition and INFO.  Stop when CALLBACK
860
   returns zero.  */
861
 
862
void
863
traverse_enum_types (htab_trav callback, void *info)
864
{
865
  htab_traverse (enum_types, callback, info);
866
}
867
 
868
/* Process an "include" directive, starting with the optional space
869
   after the "include".  Read in the file and use HANDLE_DIRECTIVE
870
   to process each unknown directive.  LINENO is the line number on
871
   which the "include" occured.  */
872
 
873
static void
874
handle_include (int lineno, directive_handler_t handle_directive)
875
{
876
  const char *filename;
877
  const char *old_filename;
878
  int old_lineno;
879
  char *pathname;
880
  FILE *input_file, *old_file;
881
 
882
  filename = read_string (false);
883
  input_file = NULL;
884
 
885
  /* If the specified file name is absolute, skip the include stack.  */
886
  if (!IS_ABSOLUTE_PATH (filename))
887
    {
888
      struct file_name_list *stackp;
889
 
890
      /* Search the directory path, trying to open the file.  */
891
      for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
892
        {
893
          static const char sep[2] = { DIR_SEPARATOR, '\0' };
894
 
895
          pathname = concat (stackp->fname, sep, filename, NULL);
896
          input_file = fopen (pathname, "r");
897
          if (input_file != NULL)
898
            break;
899
          free (pathname);
900
        }
901
    }
902
 
903
  /* If we haven't managed to open the file yet, try combining the
904
     filename with BASE_DIR.  */
905
  if (input_file == NULL)
906
    {
907
      if (base_dir)
908
        pathname = concat (base_dir, filename, NULL);
909
      else
910
        pathname = xstrdup (filename);
911
      input_file = fopen (pathname, "r");
912
    }
913
 
914
  if (input_file == NULL)
915
    {
916
      free (pathname);
917
      error_with_line (lineno, "include file `%s' not found", filename);
918
      return;
919
    }
920
 
921
  /* Save the old cursor.  Note that the LINENO argument to this
922
     function is the beginning of the include statement, while
923
     read_md_lineno has already been advanced.  */
924
  old_file = read_md_file;
925
  old_filename = read_md_filename;
926
  old_lineno = read_md_lineno;
927
 
928
  if (include_callback)
929
    include_callback (pathname);
930
 
931
  read_md_file = input_file;
932
  read_md_filename = pathname;
933
  handle_file (handle_directive);
934
 
935
  /* Restore the old cursor.  */
936
  read_md_file = old_file;
937
  read_md_filename = old_filename;
938
  read_md_lineno = old_lineno;
939
 
940
  /* Do not free the pathname.  It is attached to the various rtx
941
     queue elements.  */
942
}
943
 
944
/* Process the current file, assuming that read_md_file and
945
   read_md_filename are valid.  Use HANDLE_DIRECTIVE to handle
946
   unknown directives.  */
947
 
948
static void
949
handle_file (directive_handler_t handle_directive)
950
{
951
  struct md_name directive;
952
  int c, lineno;
953
 
954
  read_md_lineno = 1;
955
  while ((c = read_skip_spaces ()) != EOF)
956
    {
957
      lineno = read_md_lineno;
958
      if (c != '(')
959
        fatal_expected_char ('(', c);
960
 
961
      read_name (&directive);
962
      if (strcmp (directive.string, "define_constants") == 0)
963
        handle_constants ();
964
      else if (strcmp (directive.string, "define_enum") == 0)
965
        handle_enum (lineno, true);
966
      else if (strcmp (directive.string, "define_c_enum") == 0)
967
        handle_enum (lineno, false);
968
      else if (strcmp (directive.string, "include") == 0)
969
        handle_include (lineno, handle_directive);
970
      else if (handle_directive)
971
        handle_directive (lineno, directive.string);
972
      else
973
        read_skip_construct (1, lineno);
974
 
975
      c = read_skip_spaces ();
976
      if (c != ')')
977
        fatal_expected_char (')', c);
978
    }
979
  fclose (read_md_file);
980
}
981
 
982
/* Like handle_file, but for top-level files.  Set up in_fname and
983
   base_dir accordingly.  */
984
 
985
static void
986
handle_toplevel_file (directive_handler_t handle_directive)
987
{
988
  const char *base;
989
 
990
  in_fname = read_md_filename;
991
  base = lbasename (in_fname);
992
  if (base == in_fname)
993
    base_dir = NULL;
994
  else
995
    base_dir = xstrndup (in_fname, base - in_fname);
996
 
997
  handle_file (handle_directive);
998
}
999
 
1000
/* Parse a -I option with argument ARG.  */
1001
 
1002
static void
1003
parse_include (const char *arg)
1004
{
1005
  struct file_name_list *dirtmp;
1006
 
1007
  dirtmp = XNEW (struct file_name_list);
1008
  dirtmp->next = 0;
1009
  dirtmp->fname = arg;
1010
  *last_dir_md_include_ptr = dirtmp;
1011
  last_dir_md_include_ptr = &dirtmp->next;
1012
  if (strlen (dirtmp->fname) > max_include_len)
1013
    max_include_len = strlen (dirtmp->fname);
1014
}
1015
 
1016
/* The main routine for reading .md files.  Try to process all the .md
1017
   files specified on the command line and return true if no error occured.
1018
 
1019
   ARGC and ARGV are the arguments to main.
1020
 
1021
   PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
1022
   It should return true if it recognizes the argument or false if a
1023
   generic error should be reported.
1024
 
1025
   If HANDLE_DIRECTIVE is nonnull, the parser calls it for each
1026
   unknown directive, otherwise it just skips such directives.
1027
   See the comment above the directive_handler_t definition for
1028
   details about the callback's interface.  */
1029
 
1030
bool
1031
read_md_files (int argc, char **argv, bool (*parse_opt) (const char *),
1032
               directive_handler_t handle_directive)
1033
{
1034
  int i;
1035
  bool no_more_options;
1036
  bool already_read_stdin;
1037
  int num_files;
1038
 
1039
  /* Initialize global data.  */
1040
  obstack_init (&string_obstack);
1041
  ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1042
  obstack_init (&ptr_loc_obstack);
1043
  joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1044
  obstack_init (&joined_conditions_obstack);
1045
  md_constants = htab_create (31, leading_string_hash,
1046
                              leading_string_eq_p, (htab_del) 0);
1047
  enum_types = htab_create (31, leading_string_hash,
1048
                            leading_string_eq_p, (htab_del) 0);
1049
 
1050
  /* Unlock the stdio streams.  */
1051
  unlock_std_streams ();
1052
 
1053
  /* First we loop over all the options.  */
1054
  for (i = 1; i < argc; i++)
1055
    if (argv[i][0] == '-')
1056
      {
1057
        /* An argument consisting of exactly one dash is a request to
1058
           read stdin.  This will be handled in the second loop.  */
1059
        if (argv[i][1] == '\0')
1060
          continue;
1061
 
1062
        /* An argument consisting of just two dashes causes option
1063
           parsing to cease.  */
1064
        if (argv[i][1] == '-' && argv[i][2] == '\0')
1065
          break;
1066
 
1067
        if (argv[i][1] == 'I')
1068
          {
1069
            if (argv[i][2] != '\0')
1070
              parse_include (argv[i] + 2);
1071
            else if (++i < argc)
1072
              parse_include (argv[i]);
1073
            else
1074
              fatal ("directory name missing after -I option");
1075
            continue;
1076
          }
1077
 
1078
        /* The program may have provided a callback so it can
1079
           accept its own options.  */
1080
        if (parse_opt && parse_opt (argv[i]))
1081
          continue;
1082
 
1083
        fatal ("invalid option `%s'", argv[i]);
1084
      }
1085
 
1086
  /* Now loop over all input files.  */
1087
  num_files = 0;
1088
  no_more_options = false;
1089
  already_read_stdin = false;
1090
  for (i = 1; i < argc; i++)
1091
    {
1092
      if (argv[i][0] == '-')
1093
        {
1094
          if (argv[i][1] == '\0')
1095
            {
1096
              /* Read stdin.  */
1097
              if (already_read_stdin)
1098
                fatal ("cannot read standard input twice");
1099
 
1100
              read_md_file = stdin;
1101
              read_md_filename = "<stdin>";
1102
              handle_toplevel_file (handle_directive);
1103
              already_read_stdin = true;
1104
              continue;
1105
            }
1106
          else if (argv[i][1] == '-' && argv[i][2] == '\0')
1107
            {
1108
              /* No further arguments are to be treated as options.  */
1109
              no_more_options = true;
1110
              continue;
1111
            }
1112
          else if (!no_more_options)
1113
            continue;
1114
        }
1115
 
1116
      /* If we get here we are looking at a non-option argument, i.e.
1117
         a file to be processed.  */
1118
      read_md_filename = argv[i];
1119
      read_md_file = fopen (read_md_filename, "r");
1120
      if (read_md_file == 0)
1121
        {
1122
          perror (read_md_filename);
1123
          return false;
1124
        }
1125
      handle_toplevel_file (handle_directive);
1126
      num_files++;
1127
    }
1128
 
1129
  /* If we get to this point without having seen any files to process,
1130
     read the standard input now.  */
1131
  if (num_files == 0 && !already_read_stdin)
1132
    {
1133
      read_md_file = stdin;
1134
      read_md_filename = "<stdin>";
1135
      handle_toplevel_file (handle_directive);
1136
    }
1137
 
1138
  return !have_error;
1139
}

powered by: WebSVN 2.1.0

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