PageRenderTime 54ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/sdcc-290-pre1/binutils-avr/ld/deffilep.y

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