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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [ld/] [deffilep.y] - Blame information for rev 853

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

Line No. Rev Author Line
1 38 julius
%{ /* deffilep.y - parser for .def files */
2
 
3
/*   Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
4
     Free Software Foundation, Inc.
5
 
6
     This file is part of GNU Binutils.
7
 
8
     This program is free software; you can redistribute it and/or modify
9
     it under the terms of the GNU General Public License as published by
10
     the Free Software Foundation; either version 3 of the License, or
11
     (at your option) any later version.
12
 
13
     This program is distributed in the hope that it will be useful,
14
     but WITHOUT ANY WARRANTY; without even the implied warranty of
15
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
     GNU General Public License for more details.
17
 
18
     You should have received a copy of the GNU General Public License
19
     along with this program; if not, write to the Free Software
20
     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
     MA 02110-1301, USA.  */
22
 
23
#include "sysdep.h"
24
#include "libiberty.h"
25
#include "safe-ctype.h"
26
#include "bfd.h"
27
#include "ld.h"
28
#include "ldmisc.h"
29
#include "deffile.h"
30
 
31
#define TRACE 0
32
 
33
#define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
34
 
35
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
36
   as well as gratuitiously global symbol names, so we can have multiple
37
   yacc generated parsers in ld.  Note that these are only the variables
38
   produced by yacc.  If other parser generators (bison, byacc, etc) produce
39
   additional global names that conflict at link time, then those parser
40
   generators need to be fixed instead of adding those names to this list.  */
41
 
42
#define yymaxdepth def_maxdepth
43
#define yyparse def_parse
44
#define yylex   def_lex
45
#define yyerror def_error
46
#define yylval  def_lval
47
#define yychar  def_char
48
#define yydebug def_debug
49
#define yypact  def_pact
50
#define yyr1    def_r1
51
#define yyr2    def_r2
52
#define yydef   def_def
53
#define yychk   def_chk
54
#define yypgo   def_pgo
55
#define yyact   def_act
56
#define yyexca  def_exca
57
#define yyerrflag def_errflag
58
#define yynerrs def_nerrs
59
#define yyps    def_ps
60
#define yypv    def_pv
61
#define yys     def_s
62
#define yy_yys  def_yys
63
#define yystate def_state
64
#define yytmp   def_tmp
65
#define yyv     def_v
66
#define yy_yyv  def_yyv
67
#define yyval   def_val
68
#define yylloc  def_lloc
69
#define yyreds  def_reds                /* With YYDEBUG defined.  */
70
#define yytoks  def_toks                /* With YYDEBUG defined.  */
71
#define yylhs   def_yylhs
72
#define yylen   def_yylen
73
#define yydefred def_yydefred
74
#define yydgoto def_yydgoto
75
#define yysindex def_yysindex
76
#define yyrindex def_yyrindex
77
#define yygindex def_yygindex
78
#define yytable  def_yytable
79
#define yycheck  def_yycheck
80
 
81
static void def_description (const char *);
82
static void def_exports (const char *, const char *, int, int);
83
static void def_heapsize (int, int);
84
static void def_import (const char *, const char *, const char *, const char *,
85
                        int);
86
static void def_image_name (const char *, int, int);
87
static void def_section (const char *, int);
88
static void def_section_alt (const char *, const char *);
89
static void def_stacksize (int, int);
90
static void def_version (int, int);
91
static void def_directive (char *);
92
static int def_parse (void);
93
static int def_error (const char *);
94
static int def_lex (void);
95
 
96
static int lex_forced_token = 0;
97
static const char *lex_parse_string = 0;
98
static const char *lex_parse_string_end = 0;
99
 
100
%}
101
 
102
%union {
103
  char *id;
104
  int number;
105
};
106
 
107
%token NAME LIBRARY DESCRIPTION STACKSIZE HEAPSIZE CODE DATAU DATAL
108
%token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
109
%token PRIVATEU PRIVATEL
110
%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
111
%token  ID
112
%token  NUMBER
113
%type   opt_base opt_ordinal
114
%type   attr attr_list opt_number exp_opt_list exp_opt
115
%type   opt_name opt_equal_name dot_name
116
 
117
%%
118
 
119
start: start command
120
        | command
121
        ;
122
 
123
command:
124
                NAME opt_name opt_base { def_image_name ($2, $3, 0); }
125
        |       LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
126
        |       DESCRIPTION ID { def_description ($2);}
127
        |       STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
128
        |       HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
129
        |       CODE attr_list { def_section ("CODE", $2);}
130
        |       DATAU attr_list  { def_section ("DATA", $2);}
131
        |       SECTIONS seclist
132
        |       EXPORTS explist
133
        |       IMPORTS implist
134
        |       VERSIONK NUMBER { def_version ($2, 0);}
135
        |       VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
136
        |       DIRECTIVE ID { def_directive ($2);}
137
        ;
138
 
139
 
140
explist:
141
                /* EMPTY */
142
        |       expline
143
        |       explist expline
144
        ;
145
 
146
expline:
147
                /* The opt_comma is necessary to support both the usual
148
                  DEF file syntax as well as .drectve syntax which
149
                  mandates ,.  */
150
                dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
151
                        { def_exports ($1, $2, $3, $5); }
152
        ;
153
exp_opt_list:
154
                /* The opt_comma is necessary to support both the usual
155
                   DEF file syntax as well as .drectve syntax which
156
                   allows for comma separated opt list.  */
157
                exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
158
        |       { $$ = 0; }
159
        ;
160
exp_opt:
161
                NONAMEU         { $$ = 1; }
162
        |       NONAMEL         { $$ = 1; }
163
        |       CONSTANTU       { $$ = 2; }
164
        |       CONSTANTL       { $$ = 2; }
165
        |       DATAU           { $$ = 4; }
166
        |       DATAL           { $$ = 4; }
167
        |       PRIVATEU        { $$ = 8; }
168
        |       PRIVATEL        { $$ = 8; }
169
        ;
170
implist:
171
                implist impline
172
        |       impline
173
        ;
174
 
175
impline:
176
               ID '=' ID '.' ID '.' ID     { def_import ($1, $3, $5, $7, -1); }
177
       |       ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5,  0, $7); }
178
       |       ID '=' ID '.' ID            { def_import ($1, $3,  0, $5, -1); }
179
       |       ID '=' ID '.' NUMBER        { def_import ($1, $3,  0,  0, $5); }
180
       |       ID '.' ID '.' ID            { def_import ( 0, $1, $3, $5, -1); }
181
       |       ID '.' ID                   { def_import ( 0, $1,  0, $3, -1); }
182
;
183
 
184
seclist:
185
                seclist secline
186
        |       secline
187
        ;
188
 
189
secline:
190
        ID attr_list { def_section ($1, $2);}
191
        | ID ID { def_section_alt ($1, $2);}
192
        ;
193
 
194
attr_list:
195
        attr_list opt_comma attr { $$ = $1 | $3; }
196
        | attr { $$ = $1; }
197
        ;
198
 
199
opt_comma:
200
        ','
201
        |
202
        ;
203
opt_number: ',' NUMBER { $$=$2;}
204
        |          { $$=-1;}
205
        ;
206
 
207
attr:
208
                READ    { $$ = 1;}
209
        |       WRITE   { $$ = 2;}
210
        |       EXECUTE { $$=4;}
211
        |       SHARED  { $$=8;}
212
        ;
213
 
214
opt_name: ID            { $$ = $1; }
215
        | ID '.' ID
216
          {
217
            char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
218
            sprintf (name, "%s.%s", $1, $3);
219
            $$ = name;
220
          }
221
        |               { $$ = ""; }
222
        ;
223
 
224
opt_ordinal:
225
          '@' NUMBER     { $$ = $2;}
226
        |                { $$ = -1;}
227
        ;
228
 
229
opt_equal_name:
230
          '=' dot_name  { $$ = $2; }
231
        |               { $$ =  0; }
232
        ;
233
 
234
opt_base: BASE  '=' NUMBER      { $$ = $3;}
235
        |       { $$ = -1;}
236
        ;
237
 
238
dot_name: ID            { $$ = $1; }
239
        | dot_name '.' ID
240
          {
241
            char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
242
            sprintf (name, "%s.%s", $1, $3);
243
            $$ = name;
244
          }
245
        ;
246
 
247
 
248
%%
249
 
250
/*****************************************************************************
251
 API
252
 *****************************************************************************/
253
 
254
static FILE *the_file;
255
static const char *def_filename;
256
static int linenumber;
257
static def_file *def;
258
static int saw_newline;
259
 
260
struct directive
261
  {
262
    struct directive *next;
263
    char *name;
264
    int len;
265
  };
266
 
267
static struct directive *directives = 0;
268
 
269
def_file *
270
def_file_empty (void)
271
{
272
  def_file *rv = xmalloc (sizeof (def_file));
273
  memset (rv, 0, sizeof (def_file));
274
  rv->is_dll = -1;
275
  rv->base_address = (bfd_vma) -1;
276
  rv->stack_reserve = rv->stack_commit = -1;
277
  rv->heap_reserve = rv->heap_commit = -1;
278
  rv->version_major = rv->version_minor = -1;
279
  return rv;
280
}
281
 
282
def_file *
283
def_file_parse (const char *filename, def_file *add_to)
284
{
285
  struct directive *d;
286
 
287
  the_file = fopen (filename, "r");
288
  def_filename = filename;
289
  linenumber = 1;
290
  if (!the_file)
291
    {
292
      perror (filename);
293
      return 0;
294
    }
295
  if (add_to)
296
    {
297
      def = add_to;
298
    }
299
  else
300
    {
301
      def = def_file_empty ();
302
    }
303
 
304
  saw_newline = 1;
305
  if (def_parse ())
306
    {
307
      def_file_free (def);
308
      fclose (the_file);
309
      return 0;
310
    }
311
 
312
  fclose (the_file);
313
 
314
  for (d = directives; d; d = d->next)
315
    {
316
#if TRACE
317
      printf ("Adding directive %08x `%s'\n", d->name, d->name);
318
#endif
319
      def_file_add_directive (def, d->name, d->len);
320
    }
321
 
322
  return def;
323
}
324
 
325
void
326
def_file_free (def_file *def)
327
{
328
  int i;
329
 
330
  if (!def)
331
    return;
332
  if (def->name)
333
    free (def->name);
334
  if (def->description)
335
    free (def->description);
336
 
337
  if (def->section_defs)
338
    {
339
      for (i = 0; i < def->num_section_defs; i++)
340
        {
341
          if (def->section_defs[i].name)
342
            free (def->section_defs[i].name);
343
          if (def->section_defs[i].class)
344
            free (def->section_defs[i].class);
345
        }
346
      free (def->section_defs);
347
    }
348
 
349
  if (def->exports)
350
    {
351
      for (i = 0; i < def->num_exports; i++)
352
        {
353
          if (def->exports[i].internal_name
354
              && def->exports[i].internal_name != def->exports[i].name)
355
            free (def->exports[i].internal_name);
356
          if (def->exports[i].name)
357
            free (def->exports[i].name);
358
        }
359
      free (def->exports);
360
    }
361
 
362
  if (def->imports)
363
    {
364
      for (i = 0; i < def->num_imports; i++)
365
        {
366
          if (def->imports[i].internal_name
367
              && def->imports[i].internal_name != def->imports[i].name)
368
            free (def->imports[i].internal_name);
369
          if (def->imports[i].name)
370
            free (def->imports[i].name);
371
        }
372
      free (def->imports);
373
    }
374
 
375
  while (def->modules)
376
    {
377
      def_file_module *m = def->modules;
378
      def->modules = def->modules->next;
379
      free (m);
380
    }
381
 
382
  free (def);
383
}
384
 
385
#ifdef DEF_FILE_PRINT
386
void
387
def_file_print (FILE *file, def_file *def)
388
{
389
  int i;
390
 
391
  fprintf (file, ">>>> def_file at 0x%08x\n", def);
392
  if (def->name)
393
    fprintf (file, "  name: %s\n", def->name ? def->name : "(unspecified)");
394
  if (def->is_dll != -1)
395
    fprintf (file, "  is dll: %s\n", def->is_dll ? "yes" : "no");
396
  if (def->base_address != (bfd_vma) -1)
397
    fprintf (file, "  base address: 0x%08x\n", def->base_address);
398
  if (def->description)
399
    fprintf (file, "  description: `%s'\n", def->description);
400
  if (def->stack_reserve != -1)
401
    fprintf (file, "  stack reserve: 0x%08x\n", def->stack_reserve);
402
  if (def->stack_commit != -1)
403
    fprintf (file, "  stack commit: 0x%08x\n", def->stack_commit);
404
  if (def->heap_reserve != -1)
405
    fprintf (file, "  heap reserve: 0x%08x\n", def->heap_reserve);
406
  if (def->heap_commit != -1)
407
    fprintf (file, "  heap commit: 0x%08x\n", def->heap_commit);
408
 
409
  if (def->num_section_defs > 0)
410
    {
411
      fprintf (file, "  section defs:\n");
412
 
413
      for (i = 0; i < def->num_section_defs; i++)
414
        {
415
          fprintf (file, "    name: `%s', class: `%s', flags:",
416
                   def->section_defs[i].name, def->section_defs[i].class);
417
          if (def->section_defs[i].flag_read)
418
            fprintf (file, " R");
419
          if (def->section_defs[i].flag_write)
420
            fprintf (file, " W");
421
          if (def->section_defs[i].flag_execute)
422
            fprintf (file, " X");
423
          if (def->section_defs[i].flag_shared)
424
            fprintf (file, " S");
425
          fprintf (file, "\n");
426
        }
427
    }
428
 
429
  if (def->num_exports > 0)
430
    {
431
      fprintf (file, "  exports:\n");
432
 
433
      for (i = 0; i < def->num_exports; i++)
434
        {
435
          fprintf (file, "    name: `%s', int: `%s', ordinal: %d, flags:",
436
                   def->exports[i].name, def->exports[i].internal_name,
437
                   def->exports[i].ordinal);
438
          if (def->exports[i].flag_private)
439
            fprintf (file, " P");
440
          if (def->exports[i].flag_constant)
441
            fprintf (file, " C");
442
          if (def->exports[i].flag_noname)
443
            fprintf (file, " N");
444
          if (def->exports[i].flag_data)
445
            fprintf (file, " D");
446
          fprintf (file, "\n");
447
        }
448
    }
449
 
450
  if (def->num_imports > 0)
451
    {
452
      fprintf (file, "  imports:\n");
453
 
454
      for (i = 0; i < def->num_imports; i++)
455
        {
456
          fprintf (file, "    int: %s, from: `%s', name: `%s', ordinal: %d\n",
457
                   def->imports[i].internal_name,
458
                   def->imports[i].module,
459
                   def->imports[i].name,
460
                   def->imports[i].ordinal);
461
        }
462
    }
463
 
464
  if (def->version_major != -1)
465
    fprintf (file, "  version: %d.%d\n", def->version_major, def->version_minor);
466
 
467
  fprintf (file, "<<<< def_file at 0x%08x\n", def);
468
}
469
#endif
470
 
471
def_file_export *
472
def_file_add_export (def_file *def,
473
                     const char *external_name,
474
                     const char *internal_name,
475
                     int ordinal)
476
{
477
  def_file_export *e;
478
  int max_exports = ROUND_UP(def->num_exports, 32);
479
 
480
  if (def->num_exports >= max_exports)
481
    {
482
      max_exports = ROUND_UP(def->num_exports + 1, 32);
483
      if (def->exports)
484
        def->exports = xrealloc (def->exports,
485
                                 max_exports * sizeof (def_file_export));
486
      else
487
        def->exports = xmalloc (max_exports * sizeof (def_file_export));
488
    }
489
  e = def->exports + def->num_exports;
490
  memset (e, 0, sizeof (def_file_export));
491
  if (internal_name && !external_name)
492
    external_name = internal_name;
493
  if (external_name && !internal_name)
494
    internal_name = external_name;
495
  e->name = xstrdup (external_name);
496
  e->internal_name = xstrdup (internal_name);
497
  e->ordinal = ordinal;
498
  def->num_exports++;
499
  return e;
500
}
501
 
502
def_file_module *
503
def_get_module (def_file *def, const char *name)
504
{
505
  def_file_module *s;
506
 
507
  for (s = def->modules; s; s = s->next)
508
    if (strcmp (s->name, name) == 0)
509
      return s;
510
 
511
  return NULL;
512
}
513
 
514
static def_file_module *
515
def_stash_module (def_file *def, const char *name)
516
{
517
  def_file_module *s;
518
 
519
  if ((s = def_get_module (def, name)) != NULL)
520
      return s;
521
  s = xmalloc (sizeof (def_file_module) + strlen (name));
522
  s->next = def->modules;
523
  def->modules = s;
524
  s->user_data = 0;
525
  strcpy (s->name, name);
526
  return s;
527
}
528
 
529
def_file_import *
530
def_file_add_import (def_file *def,
531
                     const char *name,
532
                     const char *module,
533
                     int ordinal,
534
                     const char *internal_name)
535
{
536
  def_file_import *i;
537
  int max_imports = ROUND_UP (def->num_imports, 16);
538
 
539
  if (def->num_imports >= max_imports)
540
    {
541
      max_imports = ROUND_UP (def->num_imports+1, 16);
542
 
543
      if (def->imports)
544
        def->imports = xrealloc (def->imports,
545
                                 max_imports * sizeof (def_file_import));
546
      else
547
        def->imports = xmalloc (max_imports * sizeof (def_file_import));
548
    }
549
  i = def->imports + def->num_imports;
550
  memset (i, 0, sizeof (def_file_import));
551
  if (name)
552
    i->name = xstrdup (name);
553
  if (module)
554
    i->module = def_stash_module (def, module);
555
  i->ordinal = ordinal;
556
  if (internal_name)
557
    i->internal_name = xstrdup (internal_name);
558
  else
559
    i->internal_name = i->name;
560
  def->num_imports++;
561
 
562
  return i;
563
}
564
 
565
struct
566
{
567
  char *param;
568
  int token;
569
}
570
diropts[] =
571
{
572
  { "-heap", HEAPSIZE },
573
  { "-stack", STACKSIZE },
574
  { "-attr", SECTIONS },
575
  { "-export", EXPORTS },
576
  { 0, 0 }
577
};
578
 
579
void
580
def_file_add_directive (def_file *my_def, const char *param, int len)
581
{
582
  def_file *save_def = def;
583
  const char *pend = param + len;
584
  char * tend = (char *) param;
585
  int i;
586
 
587
  def = my_def;
588
 
589
  while (param < pend)
590
    {
591
      while (param < pend
592
             && (ISSPACE (*param) || *param == '\n' || *param == 0))
593
        param++;
594
 
595
      if (param == pend)
596
        break;
597
 
598
      /* Scan forward until we encounter any of:
599
          - the end of the buffer
600
          - the start of a new option
601
          - a newline seperating options
602
          - a NUL seperating options.  */
603
      for (tend = (char *) (param + 1);
604
           (tend < pend
605
            && !(ISSPACE (tend[-1]) && *tend == '-')
606
            && *tend != '\n' && *tend != 0);
607
           tend++)
608
        ;
609
 
610
      for (i = 0; diropts[i].param; i++)
611
        {
612
          int len = strlen (diropts[i].param);
613
 
614
          if (tend - param >= len
615
              && strncmp (param, diropts[i].param, len) == 0
616
              && (param[len] == ':' || param[len] == ' '))
617
            {
618
              lex_parse_string_end = tend;
619
              lex_parse_string = param + len + 1;
620
              lex_forced_token = diropts[i].token;
621
              saw_newline = 0;
622
              if (def_parse ())
623
                continue;
624
              break;
625
            }
626
        }
627
 
628
      if (!diropts[i].param)
629
        {
630
          char saved;
631
 
632
          saved = * tend;
633
          * tend = 0;
634
          /* xgettext:c-format */
635
          einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
636
          * tend = saved;
637
        }
638
 
639
      lex_parse_string = 0;
640
      param = tend;
641
    }
642
 
643
  def = save_def;
644
}
645
 
646
/* Parser Callbacks.  */
647
 
648
static void
649
def_image_name (const char *name, int base, int is_dll)
650
{
651
  /* If a LIBRARY or NAME statement is specified without a name, there is nothing
652
     to do here.  We retain the output filename specified on command line.  */
653
  if (*name)
654
    {
655
      const char* image_name = lbasename (name);
656
      if (image_name != name)
657
        einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
658
               def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
659
               name);
660
      if (def->name)
661
        free (def->name);
662
      /* Append the default suffix, if none specified.  */
663
      if (strchr (image_name, '.') == 0)
664
        {
665
          const char * suffix = is_dll ? ".dll" : ".exe";
666
 
667
          def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
668
          sprintf (def->name, "%s%s", image_name, suffix);
669
        }
670
      else
671
        def->name = xstrdup (image_name);
672
    }
673
 
674
  /* Honor a BASE address statement, even if LIBRARY string is empty.  */
675
  def->base_address = base;
676
  def->is_dll = is_dll;
677
}
678
 
679
static void
680
def_description (const char *text)
681
{
682
  int len = def->description ? strlen (def->description) : 0;
683
 
684
  len += strlen (text) + 1;
685
  if (def->description)
686
    {
687
      def->description = xrealloc (def->description, len);
688
      strcat (def->description, text);
689
    }
690
  else
691
    {
692
      def->description = xmalloc (len);
693
      strcpy (def->description, text);
694
    }
695
}
696
 
697
static void
698
def_stacksize (int reserve, int commit)
699
{
700
  def->stack_reserve = reserve;
701
  def->stack_commit = commit;
702
}
703
 
704
static void
705
def_heapsize (int reserve, int commit)
706
{
707
  def->heap_reserve = reserve;
708
  def->heap_commit = commit;
709
}
710
 
711
static void
712
def_section (const char *name, int attr)
713
{
714
  def_file_section *s;
715
  int max_sections = ROUND_UP (def->num_section_defs, 4);
716
 
717
  if (def->num_section_defs >= max_sections)
718
    {
719
      max_sections = ROUND_UP (def->num_section_defs+1, 4);
720
 
721
      if (def->section_defs)
722
        def->section_defs = xrealloc (def->section_defs,
723
                                      max_sections * sizeof (def_file_import));
724
      else
725
        def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
726
    }
727
  s = def->section_defs + def->num_section_defs;
728
  memset (s, 0, sizeof (def_file_section));
729
  s->name = xstrdup (name);
730
  if (attr & 1)
731
    s->flag_read = 1;
732
  if (attr & 2)
733
    s->flag_write = 1;
734
  if (attr & 4)
735
    s->flag_execute = 1;
736
  if (attr & 8)
737
    s->flag_shared = 1;
738
 
739
  def->num_section_defs++;
740
}
741
 
742
static void
743
def_section_alt (const char *name, const char *attr)
744
{
745
  int aval = 0;
746
 
747
  for (; *attr; attr++)
748
    {
749
      switch (*attr)
750
        {
751
        case 'R':
752
        case 'r':
753
          aval |= 1;
754
          break;
755
        case 'W':
756
        case 'w':
757
          aval |= 2;
758
          break;
759
        case 'X':
760
        case 'x':
761
          aval |= 4;
762
          break;
763
        case 'S':
764
        case 's':
765
          aval |= 8;
766
          break;
767
        }
768
    }
769
  def_section (name, aval);
770
}
771
 
772
static void
773
def_exports (const char *external_name,
774
             const char *internal_name,
775
             int ordinal,
776
             int flags)
777
{
778
  def_file_export *dfe;
779
 
780
  if (!internal_name && external_name)
781
    internal_name = external_name;
782
#if TRACE
783
  printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
784
#endif
785
 
786
  dfe = def_file_add_export (def, external_name, internal_name, ordinal);
787
  if (flags & 1)
788
    dfe->flag_noname = 1;
789
  if (flags & 2)
790
    dfe->flag_constant = 1;
791
  if (flags & 4)
792
    dfe->flag_data = 1;
793
  if (flags & 8)
794
    dfe->flag_private = 1;
795
}
796
 
797
static void
798
def_import (const char *internal_name,
799
            const char *module,
800
            const char *dllext,
801
            const char *name,
802
            int ordinal)
803
{
804
  char *buf = 0;
805
  const char *ext = dllext ? dllext : "dll";
806
 
807
  buf = xmalloc (strlen (module) + strlen (ext) + 2);
808
  sprintf (buf, "%s.%s", module, ext);
809
  module = buf;
810
 
811
  def_file_add_import (def, name, module, ordinal, internal_name);
812
  if (buf)
813
    free (buf);
814
}
815
 
816
static void
817
def_version (int major, int minor)
818
{
819
  def->version_major = major;
820
  def->version_minor = minor;
821
}
822
 
823
static void
824
def_directive (char *str)
825
{
826
  struct directive *d = xmalloc (sizeof (struct directive));
827
 
828
  d->next = directives;
829
  directives = d;
830
  d->name = xstrdup (str);
831
  d->len = strlen (str);
832
}
833
 
834
static int
835
def_error (const char *err)
836
{
837
  einfo ("%P: %s:%d: %s\n",
838
         def_filename ? def_filename : "", linenumber, err);
839
  return 0;
840
}
841
 
842
 
843
/* Lexical Scanner.  */
844
 
845
#undef TRACE
846
#define TRACE 0
847
 
848
/* Never freed, but always reused as needed, so no real leak.  */
849
static char *buffer = 0;
850
static int buflen = 0;
851
static int bufptr = 0;
852
 
853
static void
854
put_buf (char c)
855
{
856
  if (bufptr == buflen)
857
    {
858
      buflen += 50;             /* overly reasonable, eh?  */
859
      if (buffer)
860
        buffer = xrealloc (buffer, buflen + 1);
861
      else
862
        buffer = xmalloc (buflen + 1);
863
    }
864
  buffer[bufptr++] = c;
865
  buffer[bufptr] = 0;           /* not optimal, but very convenient.  */
866
}
867
 
868
static struct
869
{
870
  char *name;
871
  int token;
872
}
873
tokens[] =
874
{
875
  { "BASE", BASE },
876
  { "CODE", CODE },
877
  { "CONSTANT", CONSTANTU },
878
  { "constant", CONSTANTL },
879
  { "DATA", DATAU },
880
  { "data", DATAL },
881
  { "DESCRIPTION", DESCRIPTION },
882
  { "DIRECTIVE", DIRECTIVE },
883
  { "EXECUTE", EXECUTE },
884
  { "EXPORTS", EXPORTS },
885
  { "HEAPSIZE", HEAPSIZE },
886
  { "IMPORTS", IMPORTS },
887
  { "LIBRARY", LIBRARY },
888
  { "NAME", NAME },
889
  { "NONAME", NONAMEU },
890
  { "noname", NONAMEL },
891
  { "PRIVATE", PRIVATEU },
892
  { "private", PRIVATEL },
893
  { "READ", READ },
894
  { "SECTIONS", SECTIONS },
895
  { "SEGMENTS", SECTIONS },
896
  { "SHARED", SHARED },
897
  { "STACKSIZE", STACKSIZE },
898
  { "VERSION", VERSIONK },
899
  { "WRITE", WRITE },
900
  { 0, 0 }
901
};
902
 
903
static int
904
def_getc (void)
905
{
906
  int rv;
907
 
908
  if (lex_parse_string)
909
    {
910
      if (lex_parse_string >= lex_parse_string_end)
911
        rv = EOF;
912
      else
913
        rv = *lex_parse_string++;
914
    }
915
  else
916
    {
917
      rv = fgetc (the_file);
918
    }
919
  if (rv == '\n')
920
    saw_newline = 1;
921
  return rv;
922
}
923
 
924
static int
925
def_ungetc (int c)
926
{
927
  if (lex_parse_string)
928
    {
929
      lex_parse_string--;
930
      return c;
931
    }
932
  else
933
    return ungetc (c, the_file);
934
}
935
 
936
static int
937
def_lex (void)
938
{
939
  int c, i, q;
940
 
941
  if (lex_forced_token)
942
    {
943
      i = lex_forced_token;
944
      lex_forced_token = 0;
945
#if TRACE
946
      printf ("lex: forcing token %d\n", i);
947
#endif
948
      return i;
949
    }
950
 
951
  c = def_getc ();
952
 
953
  /* Trim leading whitespace.  */
954
  while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
955
    c = def_getc ();
956
 
957
  if (c == EOF)
958
    {
959
#if TRACE
960
      printf ("lex: EOF\n");
961
#endif
962
      return 0;
963
    }
964
 
965
  if (saw_newline && c == ';')
966
    {
967
      do
968
        {
969
          c = def_getc ();
970
        }
971
      while (c != EOF && c != '\n');
972
      if (c == '\n')
973
        return def_lex ();
974
      return 0;
975
    }
976
 
977
  /* Must be something else.  */
978
  saw_newline = 0;
979
 
980
  if (ISDIGIT (c))
981
    {
982
      bufptr = 0;
983
      while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
984
        {
985
          put_buf (c);
986
          c = def_getc ();
987
        }
988
      if (c != EOF)
989
        def_ungetc (c);
990
      yylval.number = strtoul (buffer, 0, 0);
991
#if TRACE
992
      printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
993
#endif
994
      return NUMBER;
995
    }
996
 
997
  if (ISALPHA (c) || strchr ("$:-_?@", c))
998
    {
999
      bufptr = 0;
1000
      q = c;
1001
      put_buf (c);
1002
      c = def_getc ();
1003
 
1004
      if (q == '@')
1005
        {
1006
          if (ISBLANK (c) ) /* '@' followed by whitespace.  */
1007
            return (q);
1008
          else if (ISDIGIT (c)) /* '@' followed by digit.  */
1009
            {
1010
              def_ungetc (c);
1011
              return (q);
1012
            }
1013
#if TRACE
1014
          printf ("lex: @ returns itself\n");
1015
#endif
1016
        }
1017
 
1018
      while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
1019
        {
1020
          put_buf (c);
1021
          c = def_getc ();
1022
        }
1023
      if (c != EOF)
1024
        def_ungetc (c);
1025
      if (ISALPHA (q)) /* Check for tokens.  */
1026
        {
1027
          for (i = 0; tokens[i].name; i++)
1028
            if (strcmp (tokens[i].name, buffer) == 0)
1029
              {
1030
#if TRACE
1031
                printf ("lex: `%s' is a string token\n", buffer);
1032
#endif
1033
                return tokens[i].token;
1034
              }
1035
        }
1036
#if TRACE
1037
      printf ("lex: `%s' returns ID\n", buffer);
1038
#endif
1039
      yylval.id = xstrdup (buffer);
1040
      return ID;
1041
    }
1042
 
1043
  if (c == '\'' || c == '"')
1044
    {
1045
      q = c;
1046
      c = def_getc ();
1047
      bufptr = 0;
1048
 
1049
      while (c != EOF && c != q)
1050
        {
1051
          put_buf (c);
1052
          c = def_getc ();
1053
        }
1054
      yylval.id = xstrdup (buffer);
1055
#if TRACE
1056
      printf ("lex: `%s' returns ID\n", buffer);
1057
#endif
1058
      return ID;
1059
    }
1060
 
1061
  if (c == '=' || c == '.' || c == ',')
1062
    {
1063
#if TRACE
1064
      printf ("lex: `%c' returns itself\n", c);
1065
#endif
1066
      return c;
1067
    }
1068
 
1069
  if (c == '\n')
1070
    {
1071
      linenumber++;
1072
      saw_newline = 1;
1073
    }
1074
 
1075
  /*printf ("lex: 0x%02x ignored\n", c); */
1076
  return def_lex ();
1077
}

powered by: WebSVN 2.1.0

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