PageRenderTime 64ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/opensource.apple.com/source/cxxfilt/cxxfilt-1/src/ld/deffilep.y

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