PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/binutils-2.17/ld/deffilep.y

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