lex.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <ctype.h>
  10. #define EXTERN
  11. #include "a.h"
  12. #include "y.tab.h"
  13. void
  14. main(int argc, char *argv[])
  15. {
  16. char *p;
  17. int nout, nproc, status, i, c;
  18. thechar = 'k';
  19. thestring = "sparc";
  20. memset(debug, 0, sizeof(debug));
  21. cinit();
  22. outfile = 0;
  23. include[ninclude++] = ".";
  24. ARGBEGIN {
  25. default:
  26. c = ARGC();
  27. if(c >= 0 || c < sizeof(debug))
  28. debug[c] = 1;
  29. break;
  30. case 'o':
  31. outfile = ARGF();
  32. break;
  33. case 'D':
  34. p = ARGF();
  35. if(p)
  36. Dlist[nDlist++] = p;
  37. break;
  38. case 'I':
  39. p = ARGF();
  40. setinclude(p);
  41. break;
  42. } ARGEND
  43. if(*argv == 0) {
  44. print("usage: %ca [-options] file.s\n", thechar);
  45. errorexit();
  46. }
  47. if(argc > 1 && systemtype(Windows)){
  48. print("can't assemble multiple files on windows\n");
  49. errorexit();
  50. }
  51. if(argc > 1 && !systemtype(Windows)) {
  52. nproc = 1;
  53. if(p = getenv("NPROC"))
  54. nproc = atol(p); /* */
  55. c = 0;
  56. nout = 0;
  57. for(;;) {
  58. while(nout < nproc && argc > 0) {
  59. i = myfork();
  60. if(i < 0) {
  61. i = mywait(&status);
  62. if(i < 0)
  63. errorexit();
  64. if(status)
  65. c++;
  66. nout--;
  67. continue;
  68. }
  69. if(i == 0) {
  70. print("%s:\n", *argv);
  71. if(assemble(*argv))
  72. errorexit();
  73. exits(0);
  74. }
  75. nout++;
  76. argc--;
  77. argv++;
  78. }
  79. i = mywait(&status);
  80. if(i < 0) {
  81. if(c)
  82. errorexit();
  83. exits(0);
  84. }
  85. if(status)
  86. c++;
  87. nout--;
  88. }
  89. }
  90. if(assemble(argv[0]))
  91. errorexit();
  92. exits(0);
  93. }
  94. int
  95. assemble(char *file)
  96. {
  97. char ofile[100], incfile[20], *p;
  98. int i, of;
  99. strcpy(ofile, file);
  100. p = utfrrune(ofile, pathchar());
  101. if(p) {
  102. include[0] = ofile;
  103. *p++ = 0;
  104. } else
  105. p = ofile;
  106. if(outfile == 0) {
  107. outfile = p;
  108. if(outfile){
  109. p = utfrrune(outfile, '.');
  110. if(p)
  111. if(p[1] == 's' && p[2] == 0)
  112. p[0] = 0;
  113. p = utfrune(outfile, 0);
  114. p[0] = '.';
  115. p[1] = thechar;
  116. p[2] = 0;
  117. } else
  118. outfile = "/dev/null";
  119. }
  120. p = getenv("INCLUDE");
  121. if(p) {
  122. setinclude(p);
  123. } else {
  124. if(systemtype(Plan9)) {
  125. sprint(incfile,"/%s/include", thestring);
  126. setinclude(strdup(incfile));
  127. }
  128. }
  129. of = mycreat(outfile, 0664);
  130. if(of < 0) {
  131. yyerror("%ca: cannot create %s", thechar, outfile);
  132. errorexit();
  133. }
  134. Binit(&obuf, of, OWRITE);
  135. pass = 1;
  136. pinit(file);
  137. for(i=0; i<nDlist; i++)
  138. dodefine(Dlist[i]);
  139. yyparse();
  140. if(nerrors) {
  141. cclean();
  142. return nerrors;
  143. }
  144. pass = 2;
  145. outhist();
  146. pinit(file);
  147. for(i=0; i<nDlist; i++)
  148. dodefine(Dlist[i]);
  149. yyparse();
  150. cclean();
  151. return nerrors;
  152. }
  153. struct
  154. {
  155. char *name;
  156. uint16_t type;
  157. uint16_t value;
  158. } itab[] =
  159. {
  160. "SP", LSP, D_AUTO,
  161. "SB", LSB, D_EXTERN,
  162. "FP", LFP, D_PARAM,
  163. "PC", LPC, D_BRANCH,
  164. "FSR", LFSR, D_FSR,
  165. "CSR", LFSR, D_CSR,
  166. "FQ", LFPQ, D_FPQ,
  167. "CQ", LFPQ, D_CPQ,
  168. "Y", LPSR, D_Y,
  169. "PSR", LPSR, D_PSR,
  170. "WIM", LPSR, D_WIM,
  171. "TBR", LPSR, D_TBR,
  172. "R", LR, 0,
  173. "R0", LREG, 0,
  174. "R1", LREG, 1,
  175. "R2", LREG, 2,
  176. "R3", LREG, 3,
  177. "R4", LREG, 4,
  178. "R5", LREG, 5,
  179. "R6", LREG, 6,
  180. "R7", LREG, 7,
  181. "R8", LREG, 8,
  182. "R9", LREG, 9,
  183. "R10", LREG, 10,
  184. "R11", LREG, 11,
  185. "R12", LREG, 12,
  186. "R13", LREG, 13,
  187. "R14", LREG, 14,
  188. "R15", LREG, 15,
  189. "R16", LREG, 16,
  190. "R17", LREG, 17,
  191. "R18", LREG, 18,
  192. "R19", LREG, 19,
  193. "R20", LREG, 20,
  194. "R21", LREG, 21,
  195. "R22", LREG, 22,
  196. "R23", LREG, 23,
  197. "R24", LREG, 24,
  198. "R25", LREG, 25,
  199. "R26", LREG, 26,
  200. "R27", LREG, 27,
  201. "R28", LREG, 28,
  202. "R29", LREG, 29,
  203. "R30", LREG, 30,
  204. "R31", LREG, 31,
  205. "C", LC, 0,
  206. "C0", LCREG, 0,
  207. "C1", LCREG, 1,
  208. "C2", LCREG, 2,
  209. "C3", LCREG, 3,
  210. "C4", LCREG, 4,
  211. "C5", LCREG, 5,
  212. "C6", LCREG, 6,
  213. "C7", LCREG, 7,
  214. "C8", LCREG, 8,
  215. "C9", LCREG, 9,
  216. "C10", LCREG, 10,
  217. "C11", LCREG, 11,
  218. "C12", LCREG, 12,
  219. "C13", LCREG, 13,
  220. "C14", LCREG, 14,
  221. "C15", LCREG, 15,
  222. "C16", LCREG, 16,
  223. "C17", LCREG, 17,
  224. "C18", LCREG, 18,
  225. "C19", LCREG, 19,
  226. "C20", LCREG, 20,
  227. "C21", LCREG, 21,
  228. "C22", LCREG, 22,
  229. "C23", LCREG, 23,
  230. "C24", LCREG, 24,
  231. "C25", LCREG, 25,
  232. "C26", LCREG, 26,
  233. "C27", LCREG, 27,
  234. "C28", LCREG, 28,
  235. "C29", LCREG, 29,
  236. "C30", LCREG, 30,
  237. "C31", LCREG, 31,
  238. "F", LF, 0,
  239. "F0", LFREG, 0,
  240. "F2", LFREG, 2,
  241. "F4", LFREG, 4,
  242. "F6", LFREG, 6,
  243. "F8", LFREG, 8,
  244. "F10", LFREG, 10,
  245. "F12", LFREG, 12,
  246. "F14", LFREG, 14,
  247. "F16", LFREG, 16,
  248. "F18", LFREG, 18,
  249. "F20", LFREG, 20,
  250. "F22", LFREG, 22,
  251. "F24", LFREG, 24,
  252. "F26", LFREG, 26,
  253. "F28", LFREG, 28,
  254. "F30", LFREG, 30,
  255. "F1", LFREG, 1,
  256. "F3", LFREG, 3,
  257. "F5", LFREG, 5,
  258. "F7", LFREG, 7,
  259. "F9", LFREG, 9,
  260. "F11", LFREG, 11,
  261. "F13", LFREG, 13,
  262. "F15", LFREG, 15,
  263. "F17", LFREG, 17,
  264. "F19", LFREG, 19,
  265. "F21", LFREG, 21,
  266. "F23", LFREG, 23,
  267. "F25", LFREG, 25,
  268. "F27", LFREG, 27,
  269. "F29", LFREG, 29,
  270. "F31", LFREG, 31,
  271. "ADD", LADDW, AADD,
  272. "ADDCC", LADDW, AADDCC,
  273. "ADDX", LADDW, AADDX,
  274. "ADDXCC", LADDW, AADDXCC,
  275. "AND", LADDW, AAND,
  276. "ANDCC", LADDW, AANDCC,
  277. "ANDN", LADDW, AANDN,
  278. "ANDNCC", LADDW, AANDNCC,
  279. "BA", LBRA, ABA,
  280. "BCC", LBRA, ABCC,
  281. "BCS", LBRA, ABCS,
  282. "BE", LBRA, ABE,
  283. "BG", LBRA, ABG,
  284. "BGE", LBRA, ABGE,
  285. "BGU", LBRA, ABGU,
  286. "BL", LBRA, ABL,
  287. "BLE", LBRA, ABLE,
  288. "BLEU", LBRA, ABLEU,
  289. "BN", LBRA, ABN,
  290. "BNE", LBRA, ABNE,
  291. "BNEG", LBRA, ABNEG,
  292. "BPOS", LBRA, ABPOS,
  293. "BVC", LBRA, ABVC,
  294. "BVS", LBRA, ABVS,
  295. "CB0", LBRA, ACB0,
  296. "CB01", LBRA, ACB01,
  297. "CB012", LBRA, ACB012,
  298. "CB013", LBRA, ACB013,
  299. "CB02", LBRA, ACB02,
  300. "CB023", LBRA, ACB023,
  301. "CB03", LBRA, ACB03,
  302. "CB1", LBRA, ACB1,
  303. "CB12", LBRA, ACB12,
  304. "CB123", LBRA, ACB123,
  305. "CB13", LBRA, ACB13,
  306. "CB2", LBRA, ACB2,
  307. "CB23", LBRA, ACB23,
  308. "CB3", LBRA, ACB3,
  309. "CBA", LBRA, ACBA,
  310. "CBN", LBRA, ACBN,
  311. "CMP", LCMP, ACMP,
  312. "CPOP1", LCPOP, ACPOP1,
  313. "CPOP2", LCPOP, ACPOP2,
  314. "DATA", LDATA, ADATA,
  315. "DIV", LADDW, ADIV,
  316. "DIVL", LADDW, ADIVL,
  317. "END", LEND, AEND,
  318. "FABSD", LFCONV, AFABSD,
  319. "FABSF", LFCONV, AFABSF,
  320. "FABSX", LFCONV, AFABSX,
  321. "FADDD", LFADD, AFADDD,
  322. "FADDF", LFADD, AFADDF,
  323. "FADDX", LFADD, AFADDX,
  324. "FBA", LBRA, AFBA,
  325. "FBE", LBRA, AFBE,
  326. "FBG", LBRA, AFBG,
  327. "FBGE", LBRA, AFBGE,
  328. "FBL", LBRA, AFBL,
  329. "FBLE", LBRA, AFBLE,
  330. "FBLG", LBRA, AFBLG,
  331. "FBN", LBRA, AFBN,
  332. "FBNE", LBRA, AFBNE,
  333. "FBO", LBRA, AFBO,
  334. "FBU", LBRA, AFBU,
  335. "FBUE", LBRA, AFBUE,
  336. "FBUG", LBRA, AFBUG,
  337. "FBUGE", LBRA, AFBUGE,
  338. "FBUL", LBRA, AFBUL,
  339. "FBULE", LBRA, AFBULE,
  340. "FCMPD", LFADD, AFCMPD,
  341. "FCMPED", LFADD, AFCMPED,
  342. "FCMPEF", LFADD, AFCMPEF,
  343. "FCMPEX", LFADD, AFCMPEX,
  344. "FCMPF", LFADD, AFCMPF,
  345. "FCMPX", LFADD, AFCMPX,
  346. "FDIVD", LFADD, AFDIVD,
  347. "FDIVF", LFADD, AFDIVF,
  348. "FDIVX", LFADD, AFDIVX,
  349. "FMOVD", LFMOV, AFMOVD,
  350. "FMOVDF", LFCONV, AFMOVDF,
  351. "FMOVDW", LFCONV, AFMOVDW,
  352. "FMOVDX", LFCONV, AFMOVDX,
  353. "FMOVF", LFMOV, AFMOVF,
  354. "FMOVFD", LFCONV, AFMOVFD,
  355. "FMOVFW", LFCONV, AFMOVFW,
  356. "FMOVFX", LFCONV, AFMOVFX,
  357. "FMOVWD", LFCONV, AFMOVWD,
  358. "FMOVWF", LFCONV, AFMOVWF,
  359. "FMOVWX", LFCONV, AFMOVWX,
  360. "FMOVX", LFCONV, AFMOVX,
  361. "FMOVXD", LFCONV, AFMOVXD,
  362. "FMOVXF", LFCONV, AFMOVXF,
  363. "FMOVXW", LFCONV, AFMOVXW,
  364. "FMULD", LFADD, AFMULD,
  365. "FMULF", LFADD, AFMULF,
  366. "FMULX", LFADD, AFMULX,
  367. "FNEGD", LFCONV, AFNEGD,
  368. "FNEGF", LFCONV, AFNEGF,
  369. "FNEGX", LFCONV, AFNEGX,
  370. "FSQRTD", LFCONV, AFSQRTD,
  371. "FSQRTF", LFCONV, AFSQRTF,
  372. "FSQRTX", LFCONV, AFSQRTX,
  373. "FSUBD", LFADD, AFSUBD,
  374. "FSUBF", LFADD, AFSUBF,
  375. "FSUBX", LFADD, AFSUBX,
  376. "GLOBL", LTEXT, AGLOBL,
  377. "IFLUSH", LFLUSH, AIFLUSH,
  378. "JMPL", LJMPL, AJMPL,
  379. "JMP", LJMPL, AJMP,
  380. "MOD", LADDW, AMOD,
  381. "MODL", LADDW, AMODL,
  382. "MOVB", LMOVB, AMOVB,
  383. "MOVBU", LMOVB, AMOVBU,
  384. "MOVD", LMOVD, AMOVD,
  385. "MOVH", LMOVB, AMOVH,
  386. "MOVHU", LMOVB, AMOVHU,
  387. "MOVW", LMOVW, AMOVW,
  388. "MUL", LADDW, AMUL,
  389. "MULSCC", LADDW, AMULSCC,
  390. "NOP", LNOP, ANOP,
  391. "OR", LADDW, AOR,
  392. "ORCC", LADDW, AORCC,
  393. "ORN", LADDW, AORN,
  394. "ORNCC", LADDW, AORNCC,
  395. "RESTORE", LADDW, ARESTORE,
  396. "RETT", LRETT, ARETT,
  397. "RETURN", LRETRN, ARETURN,
  398. "SAVE", LADDW, ASAVE,
  399. "SLL", LADDW, ASLL,
  400. "SRA", LADDW, ASRA,
  401. "SRL", LADDW, ASRL,
  402. "SUB", LADDW, ASUB,
  403. "SUBCC", LADDW, ASUBCC,
  404. "SUBX", LADDW, ASUBX,
  405. "SUBXCC", LADDW, ASUBXCC,
  406. "SWAP", LSWAP, ASWAP,
  407. "TA", LTRAP, ATA,
  408. "TADDCC", LADDW, ATADDCC,
  409. "TADDCCTV", LADDW, ATADDCCTV,
  410. "TAS", LSWAP, ATAS,
  411. "TCC", LTRAP, ATCC,
  412. "TCS", LTRAP, ATCS,
  413. "TE", LTRAP, ATE,
  414. "TEXT", LTEXT, ATEXT,
  415. "TG", LTRAP, ATG,
  416. "TGE", LTRAP, ATGE,
  417. "TGU", LTRAP, ATGU,
  418. "TL", LTRAP, ATL,
  419. "TLE", LTRAP, ATLE,
  420. "TLEU", LTRAP, ATLEU,
  421. "TN", LTRAP, ATN,
  422. "TNE", LTRAP, ATNE,
  423. "TNEG", LTRAP, ATNEG,
  424. "TPOS", LTRAP, ATPOS,
  425. "TSUBCC", LADDW, ATSUBCC,
  426. "TSUBCCTV", LADDW, ATSUBCCTV,
  427. "TVC", LTRAP, ATVC,
  428. "TVS", LTRAP, ATVS,
  429. "UNIMP", LUNIMP, AUNIMP,
  430. "WORD", LUNIMP, AWORD,
  431. "XNOR", LADDW, AXNOR,
  432. "XNORCC", LADDW, AXNORCC,
  433. "XOR", LXORW, AXOR,
  434. "XORCC", LADDW, AXORCC,
  435. "SCHED", LSCHED, 0,
  436. "NOSCHED", LSCHED, 0x80,
  437. 0
  438. };
  439. void
  440. cinit(void)
  441. {
  442. Sym *s;
  443. int i;
  444. nullgen.sym = S;
  445. nullgen.offset = 0;
  446. nullgen.type = D_NONE;
  447. nullgen.name = D_NONE;
  448. nullgen.reg = NREG;
  449. nullgen.xreg = NREG;
  450. if(FPCHIP)
  451. nullgen.dval = 0;
  452. for(i=0; i<sizeof(nullgen.sval); i++)
  453. nullgen.sval[i] = 0;
  454. nerrors = 0;
  455. iostack = I;
  456. iofree = I;
  457. peekc = IGN;
  458. nhunk = 0;
  459. for(i=0; i<NHASH; i++)
  460. hash[i] = S;
  461. for(i=0; itab[i].name; i++) {
  462. s = slookup(itab[i].name);
  463. s->type = itab[i].type;
  464. s->value = itab[i].value;
  465. }
  466. pathname = allocn(pathname, 0, 100);
  467. if(mygetwd(pathname, 99) == 0) {
  468. pathname = allocn(pathname, 100, 900);
  469. if(mygetwd(pathname, 999) == 0)
  470. strcpy(pathname, "/???");
  471. }
  472. }
  473. void
  474. syminit(Sym *s)
  475. {
  476. s->type = LNAME;
  477. s->value = 0;
  478. }
  479. void
  480. cclean(void)
  481. {
  482. outcode(AEND, &nullgen, NREG, &nullgen);
  483. Bflush(&obuf);
  484. }
  485. void
  486. zname(char *n, int t, int s)
  487. {
  488. Bputc(&obuf, ANAME);
  489. Bputc(&obuf, t); /* type */
  490. Bputc(&obuf, s); /* sym */
  491. while(*n) {
  492. Bputc(&obuf, *n);
  493. n++;
  494. }
  495. Bputc(&obuf, 0);
  496. }
  497. void
  498. zaddr(Gen *a, int s)
  499. {
  500. int32_t l;
  501. int i;
  502. char *n;
  503. Ieee e;
  504. Bputc(&obuf, a->type);
  505. Bputc(&obuf, a->reg);
  506. Bputc(&obuf, s);
  507. Bputc(&obuf, a->name);
  508. switch(a->type) {
  509. default:
  510. print("unknown type %d\n", a->type);
  511. exits("arg");
  512. case D_NONE:
  513. case D_REG:
  514. case D_FREG:
  515. case D_CREG:
  516. case D_PREG:
  517. break;
  518. case D_OREG:
  519. case D_ASI:
  520. case D_CONST:
  521. case D_BRANCH:
  522. l = a->offset;
  523. Bputc(&obuf, l);
  524. Bputc(&obuf, l>>8);
  525. Bputc(&obuf, l>>16);
  526. Bputc(&obuf, l>>24);
  527. break;
  528. case D_SCONST:
  529. n = a->sval;
  530. for(i=0; i<NSNAME; i++) {
  531. Bputc(&obuf, *n);
  532. n++;
  533. }
  534. break;
  535. case D_FCONST:
  536. ieeedtod(&e, a->dval);
  537. Bputc(&obuf, e.l);
  538. Bputc(&obuf, e.l>>8);
  539. Bputc(&obuf, e.l>>16);
  540. Bputc(&obuf, e.l>>24);
  541. Bputc(&obuf, e.h);
  542. Bputc(&obuf, e.h>>8);
  543. Bputc(&obuf, e.h>>16);
  544. Bputc(&obuf, e.h>>24);
  545. break;
  546. }
  547. }
  548. void
  549. outcode(int a, Gen *g1, int reg, Gen *g2)
  550. {
  551. int sf, st, t;
  552. Sym *s;
  553. if(pass == 1)
  554. goto out;
  555. if(g1->xreg != NREG) {
  556. if(reg != NREG || g2->xreg != NREG)
  557. yyerror("bad addressing modes");
  558. reg = g1->xreg;
  559. } else
  560. if(g2->xreg != NREG) {
  561. if(reg != NREG)
  562. yyerror("bad addressing modes");
  563. reg = g2->xreg;
  564. }
  565. jackpot:
  566. sf = 0;
  567. s = g1->sym;
  568. while(s != S) {
  569. sf = s->sym;
  570. if(sf < 0 || sf >= NSYM)
  571. sf = 0;
  572. t = g1->name;
  573. if(h[sf].type == t)
  574. if(h[sf].sym == s)
  575. break;
  576. zname(s->name, t, sym);
  577. s->sym = sym;
  578. h[sym].sym = s;
  579. h[sym].type = t;
  580. sf = sym;
  581. sym++;
  582. if(sym >= NSYM)
  583. sym = 1;
  584. break;
  585. }
  586. st = 0;
  587. s = g2->sym;
  588. while(s != S) {
  589. st = s->sym;
  590. if(st < 0 || st >= NSYM)
  591. st = 0;
  592. t = g2->name;
  593. if(h[st].type == t)
  594. if(h[st].sym == s)
  595. break;
  596. zname(s->name, t, sym);
  597. s->sym = sym;
  598. h[sym].sym = s;
  599. h[sym].type = t;
  600. st = sym;
  601. sym++;
  602. if(sym >= NSYM)
  603. sym = 1;
  604. if(st == sf)
  605. goto jackpot;
  606. break;
  607. }
  608. Bputc(&obuf, a);
  609. Bputc(&obuf, reg|nosched);
  610. Bputc(&obuf, lineno);
  611. Bputc(&obuf, lineno>>8);
  612. Bputc(&obuf, lineno>>16);
  613. Bputc(&obuf, lineno>>24);
  614. zaddr(g1, sf);
  615. zaddr(g2, st);
  616. out:
  617. if(a != AGLOBL && a != ADATA)
  618. pc++;
  619. }
  620. void
  621. outhist(void)
  622. {
  623. Gen g;
  624. Hist *h;
  625. char *p, *q, *op, c;
  626. int n;
  627. g = nullgen;
  628. c = pathchar();
  629. for(h = hist; h != H; h = h->link) {
  630. p = h->name;
  631. op = 0;
  632. /* on windows skip drive specifier in pathname */
  633. if(systemtype(Windows) && p && p[1] == ':'){
  634. p += 2;
  635. c = *p;
  636. }
  637. if(p && p[0] != c && h->offset == 0 && pathname){
  638. /* on windows skip drive specifier in pathname */
  639. if(systemtype(Windows) && pathname[1] == ':') {
  640. op = p;
  641. p = pathname+2;
  642. c = *p;
  643. } else if(pathname[0] == c){
  644. op = p;
  645. p = pathname;
  646. }
  647. }
  648. while(p) {
  649. q = strchr(p, c);
  650. if(q) {
  651. n = q-p;
  652. if(n == 0){
  653. n = 1; /* leading "/" */
  654. *p = '/'; /* don't emit "\" on windows */
  655. }
  656. q++;
  657. } else {
  658. n = strlen(p);
  659. q = 0;
  660. }
  661. if(n) {
  662. Bputc(&obuf, ANAME);
  663. Bputc(&obuf, D_FILE); /* type */
  664. Bputc(&obuf, 1); /* sym */
  665. Bputc(&obuf, '<');
  666. Bwrite(&obuf, p, n);
  667. Bputc(&obuf, 0);
  668. }
  669. p = q;
  670. if(p == 0 && op) {
  671. p = op;
  672. op = 0;
  673. }
  674. }
  675. g.offset = h->offset;
  676. Bputc(&obuf, AHISTORY);
  677. Bputc(&obuf, 0);
  678. Bputc(&obuf, h->line);
  679. Bputc(&obuf, h->line>>8);
  680. Bputc(&obuf, h->line>>16);
  681. Bputc(&obuf, h->line>>24);
  682. zaddr(&nullgen, 0);
  683. zaddr(&g, 0);
  684. }
  685. }
  686. #include "../cc/lexbody"
  687. #include "../cc/macbody"
  688. #include "../cc/compat"