cb.c 18 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  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 <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. #include "cb.h"
  13. #include "cbtype.h"
  14. static void
  15. usage(void)
  16. {
  17. fprint(2, "usage: cb [-sj] [-l width]\n");
  18. exits("usage");
  19. }
  20. void
  21. main(int argc, char *argv[])
  22. {
  23. Biobuf stdin, stdout;
  24. ARGBEGIN{
  25. case 'j':
  26. join = 1;
  27. break;
  28. case 'l':
  29. maxleng = atoi(EARGF(usage()));
  30. maxtabs = maxleng/TABLENG - 2;
  31. maxleng -= (maxleng + 5)/10;
  32. break;
  33. case 's':
  34. strict = 1;
  35. break;
  36. default:
  37. usage();
  38. }ARGEND
  39. Binit(&stdout, 1, OWRITE);
  40. output = &stdout;
  41. if (argc <= 0){
  42. Binit(&stdin, 0, OREAD);
  43. input = &stdin;
  44. work();
  45. Bterm(input);
  46. } else {
  47. while (argc-- > 0){
  48. if ((input = Bopen(*argv, OREAD)) == 0)
  49. sysfatal("can't open input file %s: %r", *argv);
  50. work();
  51. Bterm(input);
  52. argv++;
  53. }
  54. }
  55. exits(0);
  56. }
  57. void
  58. work(void)
  59. {
  60. int c, cc;
  61. struct keyw *lptr;
  62. char *pt;
  63. int ct;
  64. while ((c = getch()) != Beof){
  65. switch (c){
  66. case '{':
  67. if ((lptr = lookup(lastlook,p)) != 0){
  68. if (lptr->type == ELSE)gotelse();
  69. else if(lptr->type == DO)gotdo();
  70. else if(lptr->type == STRUCT)structlev++;
  71. }
  72. if(++clev >= &ind[CLEVEL-1]){
  73. fprint(2,"too many levels of curly brackets\n");
  74. clev = &ind[CLEVEL-1];
  75. }
  76. clev->pdepth = 0;
  77. clev->tabs = (clev-1)->tabs;
  78. clearif(clev);
  79. if(strict && clev->tabs > 0)
  80. putspace(' ',NO);
  81. putch(c,NO);
  82. getnl();
  83. if(keyflag == DATADEF){
  84. OUT;
  85. }
  86. else {
  87. OUTK;
  88. }
  89. clev->tabs++;
  90. pt = getnext(0); /* to handle initialized structures */
  91. if(*pt == '{'){ /* hide one level of {} */
  92. while((c=getch()) != '{')
  93. if(c == Beof)error("{");
  94. putch(c,NO);
  95. if(strict){
  96. putch(' ',NO);
  97. eatspace();
  98. }
  99. keyflag = SINIT;
  100. }
  101. continue;
  102. case '}':
  103. pt = getnext(0); /* to handle initialized structures */
  104. if(*pt == ','){
  105. if(strict){
  106. putspace(' ',NO);
  107. eatspace();
  108. }
  109. putch(c,NO);
  110. putch(*pt,NO);
  111. *pt = '\0';
  112. ct = getnl();
  113. pt = getnext(0);
  114. if(*pt == '{'){
  115. OUT;
  116. while((cc = getch()) != '{')
  117. if(cc == Beof)error("}");
  118. putch(cc,NO);
  119. if(strict){
  120. putch(' ',NO);
  121. eatspace();
  122. }
  123. getnext(0);
  124. continue;
  125. }
  126. else if(strict || ct){
  127. OUT;
  128. }
  129. continue;
  130. }
  131. else if(keyflag == SINIT && *pt == '}'){
  132. if(strict)
  133. putspace(' ',NO);
  134. putch(c,NO);
  135. getnl();
  136. OUT;
  137. keyflag = DATADEF;
  138. *pt = '\0';
  139. pt = getnext(0);
  140. }
  141. outs(clev->tabs);
  142. if(--clev < ind)clev = ind;
  143. ptabs(clev->tabs);
  144. putch(c,NO);
  145. lbegin = 0;
  146. lptr=lookup(pt,lastplace+1);
  147. c = *pt;
  148. if(*pt == ';' || *pt == ','){
  149. putch(*pt,NO);
  150. *pt = '\0';
  151. lastplace=pt;
  152. }
  153. ct = getnl();
  154. if((dolevel && clev->tabs <= dotabs[dolevel]) || (structlev )
  155. || (lptr != 0 &&lptr->type == ELSE&& clev->pdepth == 0)){
  156. if(c == ';'){
  157. OUTK;
  158. }
  159. else if(strict || (lptr != 0 && lptr->type == ELSE && ct == 0)){
  160. putspace(' ',NO);
  161. eatspace();
  162. }
  163. else if(lptr != 0 && lptr->type == ELSE){
  164. OUTK;
  165. }
  166. if(structlev){
  167. structlev--;
  168. keyflag = DATADEF;
  169. }
  170. }
  171. else {
  172. OUTK;
  173. if(strict && clev->tabs == 0){
  174. if((c=getch()) != '\n'){
  175. Bputc(output, '\n');
  176. Bputc(output, '\n');
  177. unget(c);
  178. }
  179. else {
  180. lineno++;
  181. Bputc(output, '\n');
  182. if((c=getch()) != '\n')unget(c);
  183. else lineno++;
  184. Bputc(output, '\n');
  185. }
  186. }
  187. }
  188. if(lptr != 0 && lptr->type == ELSE && clev->pdepth != 0){
  189. UNBUMP;
  190. }
  191. if(lptr == 0 || lptr->type != ELSE){
  192. clev->iflev = 0;
  193. if(dolevel && docurly[dolevel] == NO && clev->tabs == dotabs[dolevel]+1)
  194. clev->tabs--;
  195. else if(clev->pdepth != 0){
  196. UNBUMP;
  197. }
  198. }
  199. continue;
  200. case '(':
  201. paren++;
  202. if ((lptr = lookup(lastlook,p)) != 0){
  203. if(!(lptr->type == TYPE || lptr->type == STRUCT))keyflag=KEYWORD;
  204. if (strict){
  205. putspace(lptr->punc,NO);
  206. opflag = 1;
  207. }
  208. putch(c,NO);
  209. if (lptr->type == IF)gotif();
  210. }
  211. else {
  212. putch(c,NO);
  213. lastlook = p;
  214. opflag = 1;
  215. }
  216. continue;
  217. case ')':
  218. if(--paren < 0)paren = 0;
  219. putch(c,NO);
  220. if((lptr = lookup(lastlook,p)) != 0){
  221. if(lptr->type == TYPE || lptr->type == STRUCT)
  222. opflag = 1;
  223. }
  224. else if(keyflag == DATADEF)opflag = 1;
  225. else opflag = 0;
  226. outs(clev->tabs);
  227. pt = getnext(1);
  228. if ((ct = getnl()) == 1 && !strict){
  229. if(dolevel && clev->tabs <= dotabs[dolevel])
  230. resetdo();
  231. if(clev->tabs > 0 && (paren != 0 || keyflag == 0)){
  232. if(join){
  233. eatspace();
  234. putch(' ',YES);
  235. continue;
  236. } else {
  237. OUT;
  238. split = 1;
  239. continue;
  240. }
  241. }
  242. else if(clev->tabs > 0 && *pt != '{'){
  243. BUMP;
  244. }
  245. OUTK;
  246. }
  247. else if(strict){
  248. if(clev->tabs == 0){
  249. if(*pt != ';' && *pt != ',' && *pt != '(' && *pt != '['){
  250. OUTK;
  251. }
  252. }
  253. else {
  254. if(keyflag == KEYWORD && paren == 0){
  255. if(dolevel && clev->tabs <= dotabs[dolevel]){
  256. resetdo();
  257. eatspace();
  258. continue;
  259. }
  260. if(*pt != '{'){
  261. BUMP;
  262. OUTK;
  263. }
  264. else {
  265. *pt='\0';
  266. eatspace();
  267. unget('{');
  268. }
  269. }
  270. else if(ct){
  271. if(paren){
  272. if(join){
  273. eatspace();
  274. } else {
  275. split = 1;
  276. OUT;
  277. }
  278. }
  279. else {
  280. OUTK;
  281. }
  282. }
  283. }
  284. }
  285. else if(dolevel && clev->tabs <= dotabs[dolevel])
  286. resetdo();
  287. continue;
  288. case ' ':
  289. case '\t':
  290. if ((lptr = lookup(lastlook,p)) != 0){
  291. if(!(lptr->type==TYPE||lptr->type==STRUCT))
  292. keyflag = KEYWORD;
  293. else if(paren == 0)keyflag = DATADEF;
  294. if(strict){
  295. if(lptr->type != ELSE){
  296. if(lptr->type == TYPE){
  297. if(paren != 0)putch(' ',YES);
  298. }
  299. else
  300. putch(lptr->punc,NO);
  301. eatspace();
  302. }
  303. }
  304. else putch(c,YES);
  305. switch(lptr->type){
  306. case CASE:
  307. outs(clev->tabs-1);
  308. continue;
  309. case ELSE:
  310. pt = getnext(1);
  311. eatspace();
  312. if((cc = getch()) == '\n' && !strict){
  313. unget(cc);
  314. }
  315. else {
  316. unget(cc);
  317. if(checkif(pt))continue;
  318. }
  319. gotelse();
  320. if(strict) unget(c);
  321. if(getnl() == 1 && !strict){
  322. OUTK;
  323. if(*pt != '{'){
  324. BUMP;
  325. }
  326. }
  327. else if(strict){
  328. if(*pt != '{'){
  329. OUTK;
  330. BUMP;
  331. }
  332. }
  333. continue;
  334. case IF:
  335. gotif();
  336. continue;
  337. case DO:
  338. gotdo();
  339. pt = getnext(1);
  340. if(*pt != '{'){
  341. eatallsp();
  342. OUTK;
  343. docurly[dolevel] = NO;
  344. dopdepth[dolevel] = clev->pdepth;
  345. clev->pdepth = 0;
  346. clev->tabs++;
  347. }
  348. continue;
  349. case TYPE:
  350. if(paren)continue;
  351. if(!strict)continue;
  352. gottype(lptr);
  353. continue;
  354. case STRUCT:
  355. gotstruct();
  356. continue;
  357. }
  358. }
  359. else if (lbegin == 0 || p > string)
  360. if(strict)
  361. putch(c,NO);
  362. else putch(c,YES);
  363. continue;
  364. case ';':
  365. putch(c,NO);
  366. if(paren != 0){
  367. if(strict){
  368. putch(' ',YES);
  369. eatspace();
  370. }
  371. opflag = 1;
  372. continue;
  373. }
  374. outs(clev->tabs);
  375. pt = getnext(0);
  376. lptr=lookup(pt,lastplace+1);
  377. if(lptr == 0 || lptr->type != ELSE){
  378. clev->iflev = 0;
  379. if(clev->pdepth != 0){
  380. UNBUMP;
  381. }
  382. if(dolevel && docurly[dolevel] == NO && clev->tabs <= dotabs[dolevel]+1)
  383. clev->tabs--;
  384. /*
  385. else if(clev->pdepth != 0){
  386. UNBUMP;
  387. }
  388. */
  389. }
  390. getnl();
  391. OUTK;
  392. continue;
  393. case '\n':
  394. if ((lptr = lookup(lastlook,p)) != 0){
  395. pt = getnext(1);
  396. if (lptr->type == ELSE){
  397. if(strict)
  398. if(checkif(pt))continue;
  399. gotelse();
  400. OUTK;
  401. if(*pt != '{'){
  402. BUMP;
  403. }
  404. }
  405. else if(lptr->type == DO){
  406. OUTK;
  407. gotdo();
  408. if(*pt != '{'){
  409. docurly[dolevel] = NO;
  410. dopdepth[dolevel] = clev->pdepth;
  411. clev->pdepth = 0;
  412. clev->tabs++;
  413. }
  414. }
  415. else {
  416. OUTK;
  417. if(lptr->type == STRUCT)gotstruct();
  418. }
  419. }
  420. else if(p == string)Bputc(output, '\n');
  421. else {
  422. if(clev->tabs > 0 &&(paren != 0 || keyflag == 0)){
  423. if(join){
  424. putch(' ',YES);
  425. eatspace();
  426. continue;
  427. } else {
  428. OUT;
  429. split = 1;
  430. continue;
  431. }
  432. }
  433. else if(keyflag == KEYWORD){
  434. OUTK;
  435. continue;
  436. }
  437. OUT;
  438. }
  439. continue;
  440. case '"':
  441. case '\'':
  442. putch(c,NO);
  443. while ((cc = getch()) != c){
  444. if(cc == Beof)
  445. error("\" or '");
  446. putch(cc,NO);
  447. if (cc == '\\'){
  448. putch(getch(),NO);
  449. }
  450. if (cc == '\n'){
  451. outs(clev->tabs);
  452. lbegin = 1;
  453. count = 0;
  454. }
  455. }
  456. putch(cc,NO);
  457. opflag=0;
  458. if (getnl() == 1){
  459. unget('\n');
  460. }
  461. continue;
  462. case '\\':
  463. putch(c,NO);
  464. putch(getch(),NO);
  465. continue;
  466. case '?':
  467. question = 1;
  468. gotop(c);
  469. continue;
  470. case ':':
  471. if ((cc = getch()) == ':') {
  472. putch(c,NO);
  473. putch(cc,NO);
  474. continue;
  475. }
  476. unget(cc);
  477. if (question == 1){
  478. question = 0;
  479. gotop(c);
  480. continue;
  481. }
  482. putch(c,NO);
  483. if(structlev)continue;
  484. if ((lptr = lookup(lastlook,p)) != 0){
  485. if (lptr->type == CASE)outs(clev->tabs - 1);
  486. }
  487. else {
  488. lbegin = 0;
  489. outs(clev->tabs);
  490. }
  491. getnl();
  492. OUTK;
  493. continue;
  494. case '/':
  495. if ((cc = getch()) == '/') {
  496. putch(c,NO);
  497. putch(cc,NO);
  498. cpp_comment(YES);
  499. OUT;
  500. lastlook = 0;
  501. continue;
  502. }
  503. else if (cc != '*') {
  504. unget(cc);
  505. gotop(c);
  506. continue;
  507. }
  508. putch(c,NO);
  509. putch(cc,NO);
  510. cc = comment(YES);
  511. if(getnl() == 1){
  512. if(cc == 0){
  513. OUT;
  514. }
  515. else {
  516. outs(0);
  517. Bputc(output, '\n');
  518. lbegin = 1;
  519. count = 0;
  520. }
  521. lastlook = 0;
  522. }
  523. continue;
  524. case '[':
  525. putch(c,NO);
  526. ct = 0;
  527. while((c = getch()) != ']' || ct > 0){
  528. if(c == Beof)error("]");
  529. putch(c,NO);
  530. if(c == '[')ct++;
  531. if(c == ']')ct--;
  532. }
  533. putch(c,NO);
  534. continue;
  535. case '#':
  536. putch(c,NO);
  537. while ((cc = getch()) != '\n'){
  538. if(cc == Beof)error("newline");
  539. if (cc == '\\'){
  540. putch(cc,NO);
  541. cc = getch();
  542. }
  543. putch(cc,NO);
  544. }
  545. putch(cc,NO);
  546. lbegin = 0;
  547. outs(clev->tabs);
  548. lbegin = 1;
  549. count = 0;
  550. continue;
  551. default:
  552. if (c == ','){
  553. opflag = 1;
  554. putch(c,YES);
  555. if (strict){
  556. if ((cc = getch()) != ' ')unget(cc);
  557. if(cc != '\n')putch(' ',YES);
  558. }
  559. }
  560. else if(isop(c))gotop(c);
  561. else {
  562. if(isalnum(c) && lastlook == 0)lastlook = p;
  563. if(isdigit(c)){
  564. putch(c,NO);
  565. while(isdigit(c=Bgetc(input))||c == '.')putch(c,NO);
  566. if(c == 'e'){
  567. putch(c,NO);
  568. c = Bgetc(input);
  569. putch(c, NO);
  570. while(isdigit(c=Bgetc(input)))putch(c,NO);
  571. }
  572. Bungetc(input);
  573. }
  574. else putch(c,NO);
  575. if(keyflag != DATADEF)opflag = 0;
  576. }
  577. }
  578. }
  579. }
  580. void
  581. gotif(void){
  582. outs(clev->tabs);
  583. if(++clev->iflev >= IFLEVEL-1){
  584. fprint(2,"too many levels of if %d\n",clev->iflev );
  585. clev->iflev = IFLEVEL-1;
  586. }
  587. clev->ifc[clev->iflev] = clev->tabs;
  588. clev->spdepth[clev->iflev] = clev->pdepth;
  589. }
  590. void
  591. gotelse(void){
  592. clev->tabs = clev->ifc[clev->iflev];
  593. clev->pdepth = clev->spdepth[clev->iflev];
  594. if(--(clev->iflev) < 0)clev->iflev = 0;
  595. }
  596. int
  597. checkif(char *pt)
  598. {
  599. struct keyw *lptr;
  600. int cc;
  601. if((lptr=lookup(pt,lastplace+1))!= 0){
  602. if(lptr->type == IF){
  603. if(strict)putch(' ',YES);
  604. copy(lptr->name);
  605. *pt='\0';
  606. lastplace = pt;
  607. if(strict){
  608. putch(lptr->punc,NO);
  609. eatallsp();
  610. }
  611. clev->tabs = clev->ifc[clev->iflev];
  612. clev->pdepth = clev->spdepth[clev->iflev];
  613. keyflag = KEYWORD;
  614. return(1);
  615. }
  616. }
  617. return(0);
  618. }
  619. void
  620. gotdo(void){
  621. if(++dolevel >= DOLEVEL-1){
  622. fprint(2,"too many levels of do %d\n",dolevel);
  623. dolevel = DOLEVEL-1;
  624. }
  625. dotabs[dolevel] = clev->tabs;
  626. docurly[dolevel] = YES;
  627. }
  628. void
  629. resetdo(void){
  630. if(docurly[dolevel] == NO)
  631. clev->pdepth = dopdepth[dolevel];
  632. if(--dolevel < 0)dolevel = 0;
  633. }
  634. void
  635. gottype(struct keyw *lptr)
  636. {
  637. char *pt;
  638. struct keyw *tlptr;
  639. int c;
  640. while(1){
  641. pt = getnext(1);
  642. if((tlptr=lookup(pt,lastplace+1))!=0){
  643. putch(' ',YES);
  644. copy(tlptr->name);
  645. *pt='\0';
  646. lastplace = pt;
  647. if(tlptr->type == STRUCT){
  648. putch(tlptr->punc,YES);
  649. gotstruct();
  650. break;
  651. }
  652. lptr=tlptr;
  653. continue;
  654. }
  655. else{
  656. putch(lptr->punc,NO);
  657. while((c=getch())== ' ' || c == '\t');
  658. unget(c);
  659. break;
  660. }
  661. }
  662. }
  663. void
  664. gotstruct(void){
  665. int c;
  666. int cc;
  667. char *pt;
  668. while((c=getch()) == ' ' || c == '\t')
  669. if(!strict)putch(c,NO);
  670. if(c == '{'){
  671. structlev++;
  672. unget(c);
  673. return;
  674. }
  675. if(isalpha(c)){
  676. putch(c,NO);
  677. while(isalnum(c=getch()))putch(c,NO);
  678. }
  679. unget(c);
  680. pt = getnext(1);
  681. if(*pt == '{')structlev++;
  682. if(strict){
  683. eatallsp();
  684. putch(' ',NO);
  685. }
  686. }
  687. void
  688. gotop(int c)
  689. {
  690. char optmp[OPLENGTH];
  691. char *op_ptr;
  692. struct op *s_op;
  693. char *a, *b;
  694. op_ptr = optmp;
  695. *op_ptr++ = c;
  696. while (isop(( (uint8_t)(*op_ptr = getch()) )))op_ptr++;
  697. if(!strict)unget(*op_ptr);
  698. else if (*op_ptr != ' ')unget( *op_ptr);
  699. *op_ptr = '\0';
  700. s_op = op;
  701. b = optmp;
  702. while ((a = s_op->name) != 0){
  703. op_ptr = b;
  704. while ((*op_ptr == *a) && (*op_ptr != '\0')){
  705. a++;
  706. op_ptr++;
  707. }
  708. if (*a == '\0'){
  709. keep(s_op);
  710. opflag = s_op->setop;
  711. if (*op_ptr != '\0'){
  712. b = op_ptr;
  713. s_op = op;
  714. continue;
  715. }
  716. else break;
  717. }
  718. else s_op++;
  719. }
  720. }
  721. void
  722. keep(struct op *o)
  723. {
  724. char *s;
  725. int ok;
  726. if(o->blanks == NEVER)ok = NO;
  727. else ok = YES;
  728. if (strict && ((o->blanks & ALWAYS)
  729. || ((opflag == 0 && o->blanks & SOMETIMES) && clev->tabs != 0)))
  730. putspace(' ',YES);
  731. for(s=o->name; *s != '\0'; s++){
  732. if(*(s+1) == '\0')putch(*s,ok);
  733. else
  734. putch(*s,NO);
  735. }
  736. if (strict && ((o->blanks & ALWAYS)
  737. || ((opflag == 0 && o->blanks & SOMETIMES) && clev->tabs != 0))) putch(' ',YES);
  738. }
  739. int
  740. getnl(void){
  741. int ch;
  742. char *savp;
  743. int gotcmt;
  744. gotcmt = 0;
  745. savp = p;
  746. while ((ch = getch()) == '\t' || ch == ' ')putch(ch,NO);
  747. if (ch == '/'){
  748. if ((ch = getch()) == '*'){
  749. putch('/',NO);
  750. putch('*',NO);
  751. comment(NO);
  752. ch = getch();
  753. gotcmt=1;
  754. }
  755. else if (ch == '/') {
  756. putch('/',NO);
  757. putch('/',NO);
  758. cpp_comment(NO);
  759. ch = getch();
  760. gotcmt = 1;
  761. }
  762. else {
  763. if(inswitch)*(++lastplace) = ch;
  764. else {
  765. inswitch = 1;
  766. *lastplace = ch;
  767. }
  768. unget('/');
  769. return(0);
  770. }
  771. }
  772. if(ch == '\n'){
  773. if(gotcmt == 0)p=savp;
  774. return(1);
  775. }
  776. unget(ch);
  777. return(0);
  778. }
  779. void
  780. ptabs(int n){
  781. int i;
  782. int num;
  783. if(n > maxtabs){
  784. if(!folded){
  785. Bprint(output, "/* code folded from here */\n");
  786. folded = 1;
  787. }
  788. num = n-maxtabs;
  789. }
  790. else {
  791. num = n;
  792. if(folded){
  793. folded = 0;
  794. Bprint(output, "/* unfolding */\n");
  795. }
  796. }
  797. for (i = 0; i < num; i++)Bputc(output, '\t');
  798. }
  799. void
  800. outs(int n){
  801. if (p > string){
  802. if (lbegin){
  803. ptabs(n);
  804. lbegin = 0;
  805. if (split == 1){
  806. split = 0;
  807. if (clev->tabs > 0)Bprint(output, "\t");
  808. }
  809. }
  810. *p = '\0';
  811. Bprint(output, "%s", string);
  812. lastlook = p = string;
  813. }
  814. else {
  815. if (lbegin != 0){
  816. lbegin = 0;
  817. split = 0;
  818. }
  819. }
  820. }
  821. void
  822. putch(char c,int ok)
  823. {
  824. int cc;
  825. if(p < &string[LINE-1]){
  826. if(count+TABLENG*clev->tabs >= maxleng && ok && !folded){
  827. if(c != ' ')*p++ = c;
  828. OUT;
  829. split = 1;
  830. if((cc=getch()) != '\n')unget(cc);
  831. }
  832. else {
  833. *p++ = c;
  834. count++;
  835. }
  836. }
  837. else {
  838. outs(clev->tabs);
  839. *p++ = c;
  840. count = 0;
  841. }
  842. }
  843. struct keyw *
  844. lookup(char *first, char *last)
  845. {
  846. struct keyw *ptr;
  847. char *cptr, *ckey, *k;
  848. if(first == last || first == 0)return(0);
  849. cptr = first;
  850. while (*cptr == ' ' || *cptr == '\t')cptr++;
  851. if(cptr >= last)return(0);
  852. ptr = key;
  853. while ((ckey = ptr->name) != 0){
  854. for (k = cptr; (*ckey == *k && *ckey != '\0'); k++, ckey++);
  855. if(*ckey=='\0' && (k==last|| (k<last && !isalnum((uint8_t)*k)))){
  856. opflag = 1;
  857. lastlook = 0;
  858. return(ptr);
  859. }
  860. ptr++;
  861. }
  862. return(0);
  863. }
  864. int
  865. comment(int ok)
  866. {
  867. int ch;
  868. int hitnl;
  869. hitnl = 0;
  870. while ((ch = getch()) != Beof){
  871. putch(ch, NO);
  872. if (ch == '*'){
  873. gotstar:
  874. if ((ch = getch()) == '/'){
  875. putch(ch,NO);
  876. return(hitnl);
  877. }
  878. putch(ch,NO);
  879. if (ch == '*')goto gotstar;
  880. }
  881. if (ch == '\n'){
  882. if(ok && !hitnl){
  883. outs(clev->tabs);
  884. }
  885. else {
  886. outs(0);
  887. }
  888. lbegin = 1;
  889. count = 0;
  890. hitnl = 1;
  891. }
  892. }
  893. return(hitnl);
  894. }
  895. int
  896. cpp_comment(int ok)
  897. {
  898. int ch;
  899. int hitnl;
  900. hitnl = 0;
  901. while ((ch = getch()) != -1) {
  902. if (ch == '\n') {
  903. if (ok && !hitnl)
  904. outs(clev->tabs);
  905. else
  906. outs(0);
  907. lbegin = 1;
  908. count = 0;
  909. hitnl = 1;
  910. break;
  911. }
  912. putch(ch, NO);
  913. }
  914. return hitnl;
  915. }
  916. void
  917. putspace(char ch, int ok)
  918. {
  919. if(p == string)putch(ch,ok);
  920. else if (*(p - 1) != ch) putch(ch,ok);
  921. }
  922. int
  923. getch(void){
  924. char c;
  925. if(inswitch){
  926. if(next != '\0'){
  927. c=next;
  928. next = '\0';
  929. return(c);
  930. }
  931. if(tptr <= lastplace){
  932. if(*tptr != '\0')return(*tptr++);
  933. else if(++tptr <= lastplace)return(*tptr++);
  934. }
  935. inswitch=0;
  936. lastplace = tptr = temp;
  937. }
  938. return(Bgetc(input));
  939. }
  940. void
  941. unget(char c)
  942. {
  943. if(inswitch){
  944. if(tptr != temp)
  945. *(--tptr) = c;
  946. else next = c;
  947. }
  948. else Bungetc(input);
  949. }
  950. char *
  951. getnext(int must){
  952. int c;
  953. char *beg;
  954. int prect,nlct;
  955. prect = nlct = 0;
  956. if(tptr > lastplace){
  957. tptr = lastplace = temp;
  958. err = 0;
  959. inswitch = 0;
  960. }
  961. tp = lastplace;
  962. if(inswitch && tptr <= lastplace)
  963. if (isalnum((uint8_t)*lastplace)||ispunct((uint8_t)*lastplace)||isop((uint8_t)*lastplace))return(lastplace);
  964. space:
  965. while(isspace(c=Bgetc(input)))puttmp(c,1);
  966. beg = tp;
  967. puttmp(c,1);
  968. if(c == '/'){
  969. if(puttmp(Bgetc(input),1) == '*'){
  970. cont:
  971. while((c=Bgetc(input)) != '*'){
  972. puttmp(c,0);
  973. if(must == 0 && c == '\n')
  974. if(nlct++ > 2)goto done;
  975. }
  976. puttmp(c,1);
  977. star:
  978. if(puttmp((c=Bgetc(input)),1) == '/'){
  979. beg = tp;
  980. puttmp((c=Bgetc(input)),1);
  981. }
  982. else if(c == '*')goto star;
  983. else goto cont;
  984. }
  985. else goto done;
  986. }
  987. if(isspace(c))goto space;
  988. if(c == '#' && tp > temp+1 && *(tp-2) == '\n'){
  989. if(prect++ > 2)goto done;
  990. while(puttmp((c=Bgetc(input)),1) != '\n')
  991. if(c == '\\')puttmp(Bgetc(input),1);
  992. goto space;
  993. }
  994. if(isalnum(c)){
  995. while(isalnum(c = Bgetc(input)))puttmp(c,1);
  996. Bungetc(input);
  997. }
  998. done:
  999. puttmp('\0',1);
  1000. lastplace = tp-1;
  1001. inswitch = 1;
  1002. return(beg);
  1003. }
  1004. void
  1005. copy(char *s)
  1006. {
  1007. while(*s != '\0')putch(*s++,NO);
  1008. }
  1009. void
  1010. clearif(struct indent *cl)
  1011. {
  1012. int i;
  1013. for(i=0;i<IFLEVEL-1;i++)cl->ifc[i] = 0;
  1014. }
  1015. char
  1016. puttmp(char c, int keep)
  1017. {
  1018. if(tp < &temp[TEMP-120])
  1019. *tp++ = c;
  1020. else {
  1021. if(keep){
  1022. if(tp >= &temp[TEMP-1]){
  1023. fprint(2,"can't look past huge comment - quiting\n");
  1024. exits("boom");
  1025. }
  1026. *tp++ = c;
  1027. }
  1028. else if(err == 0){
  1029. err++;
  1030. fprint(2,"truncating long comment\n");
  1031. }
  1032. }
  1033. return(c);
  1034. }
  1035. void
  1036. error(char *s)
  1037. {
  1038. fprint(2,"saw EOF while looking for %s\n",s);
  1039. exits("boom");
  1040. }