cb.c 18 KB

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