cb.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  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. {
  55. int c, cc;
  56. struct keyw *lptr;
  57. char *pt;
  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. unget(cc);
  472. if (question == 1){
  473. question = 0;
  474. gotop(c);
  475. continue;
  476. }
  477. putch(c,NO);
  478. if(structlev)continue;
  479. if ((lptr = lookup(lastlook,p)) != 0){
  480. if (lptr->type == CASE)outs(clev->tabs - 1);
  481. }
  482. else {
  483. lbegin = 0;
  484. outs(clev->tabs);
  485. }
  486. getnl();
  487. OUTK;
  488. continue;
  489. case '/':
  490. if ((cc = getch()) == '/') {
  491. putch(c,NO);
  492. putch(cc,NO);
  493. cpp_comment(YES);
  494. OUT;
  495. lastlook = 0;
  496. continue;
  497. }
  498. else if (cc != '*') {
  499. unget(cc);
  500. gotop(c);
  501. continue;
  502. }
  503. putch(c,NO);
  504. putch(cc,NO);
  505. cc = comment(YES);
  506. if(getnl() == 1){
  507. if(cc == 0){
  508. OUT;
  509. }
  510. else {
  511. outs(0);
  512. Bputc(output, '\n');
  513. lbegin = 1;
  514. count = 0;
  515. }
  516. lastlook = 0;
  517. }
  518. continue;
  519. case '[':
  520. putch(c,NO);
  521. ct = 0;
  522. while((c = getch()) != ']' || ct > 0){
  523. if(c == Beof)error("]");
  524. putch(c,NO);
  525. if(c == '[')ct++;
  526. if(c == ']')ct--;
  527. }
  528. putch(c,NO);
  529. continue;
  530. case '#':
  531. putch(c,NO);
  532. while ((cc = getch()) != '\n'){
  533. if(cc == Beof)error("newline");
  534. if (cc == '\\'){
  535. putch(cc,NO);
  536. cc = getch();
  537. }
  538. putch(cc,NO);
  539. }
  540. putch(cc,NO);
  541. lbegin = 0;
  542. outs(clev->tabs);
  543. lbegin = 1;
  544. count = 0;
  545. continue;
  546. default:
  547. if (c == ','){
  548. opflag = 1;
  549. putch(c,YES);
  550. if (strict){
  551. if ((cc = getch()) != ' ')unget(cc);
  552. if(cc != '\n')putch(' ',YES);
  553. }
  554. }
  555. else if(isop(c))gotop(c);
  556. else {
  557. if(isalnum(c) && lastlook == 0)lastlook = p;
  558. if(isdigit(c)){
  559. putch(c,NO);
  560. while(isdigit(c=Bgetc(input))||c == '.')putch(c,NO);
  561. if(c == 'e'){
  562. putch(c,NO);
  563. c = Bgetc(input);
  564. putch(c, NO);
  565. while(isdigit(c=Bgetc(input)))putch(c,NO);
  566. }
  567. Bungetc(input);
  568. }
  569. else putch(c,NO);
  570. if(keyflag != DATADEF)opflag = 0;
  571. }
  572. }
  573. }
  574. }
  575. void
  576. gotif(void){
  577. outs(clev->tabs);
  578. if(++clev->iflev >= IFLEVEL-1){
  579. fprint(2,"too many levels of if %d\n",clev->iflev );
  580. clev->iflev = IFLEVEL-1;
  581. }
  582. clev->ifc[clev->iflev] = clev->tabs;
  583. clev->spdepth[clev->iflev] = clev->pdepth;
  584. }
  585. void
  586. gotelse(void){
  587. clev->tabs = clev->ifc[clev->iflev];
  588. clev->pdepth = clev->spdepth[clev->iflev];
  589. if(--(clev->iflev) < 0)clev->iflev = 0;
  590. }
  591. int
  592. checkif(char *pt)
  593. {
  594. struct keyw *lptr;
  595. int cc;
  596. if((lptr=lookup(pt,lastplace+1))!= 0){
  597. if(lptr->type == IF){
  598. if(strict)putch(' ',YES);
  599. copy(lptr->name);
  600. *pt='\0';
  601. lastplace = pt;
  602. if(strict){
  603. putch(lptr->punc,NO);
  604. eatallsp();
  605. }
  606. clev->tabs = clev->ifc[clev->iflev];
  607. clev->pdepth = clev->spdepth[clev->iflev];
  608. keyflag = KEYWORD;
  609. return(1);
  610. }
  611. }
  612. return(0);
  613. }
  614. void
  615. gotdo(void){
  616. if(++dolevel >= DOLEVEL-1){
  617. fprint(2,"too many levels of do %d\n",dolevel);
  618. dolevel = DOLEVEL-1;
  619. }
  620. dotabs[dolevel] = clev->tabs;
  621. docurly[dolevel] = YES;
  622. }
  623. void
  624. resetdo(void){
  625. if(docurly[dolevel] == NO)
  626. clev->pdepth = dopdepth[dolevel];
  627. if(--dolevel < 0)dolevel = 0;
  628. }
  629. void
  630. gottype(struct keyw *lptr)
  631. {
  632. char *pt;
  633. struct keyw *tlptr;
  634. int c;
  635. while(1){
  636. pt = getnext(1);
  637. if((tlptr=lookup(pt,lastplace+1))!=0){
  638. putch(' ',YES);
  639. copy(tlptr->name);
  640. *pt='\0';
  641. lastplace = pt;
  642. if(tlptr->type == STRUCT){
  643. putch(tlptr->punc,YES);
  644. gotstruct();
  645. break;
  646. }
  647. lptr=tlptr;
  648. continue;
  649. }
  650. else{
  651. putch(lptr->punc,NO);
  652. while((c=getch())== ' ' || c == '\t');
  653. unget(c);
  654. break;
  655. }
  656. }
  657. }
  658. void
  659. gotstruct(void){
  660. int c;
  661. int cc;
  662. char *pt;
  663. while((c=getch()) == ' ' || c == '\t')
  664. if(!strict)putch(c,NO);
  665. if(c == '{'){
  666. structlev++;
  667. unget(c);
  668. return;
  669. }
  670. if(isalpha(c)){
  671. putch(c,NO);
  672. while(isalnum(c=getch()))putch(c,NO);
  673. }
  674. unget(c);
  675. pt = getnext(1);
  676. if(*pt == '{')structlev++;
  677. if(strict){
  678. eatallsp();
  679. putch(' ',NO);
  680. }
  681. }
  682. void
  683. gotop(int c)
  684. {
  685. char optmp[OPLENGTH];
  686. char *op_ptr;
  687. struct op *s_op;
  688. char *a, *b;
  689. op_ptr = optmp;
  690. *op_ptr++ = c;
  691. while (isop(( *op_ptr = getch())))op_ptr++;
  692. if(!strict)unget(*op_ptr);
  693. else if (*op_ptr != ' ')unget( *op_ptr);
  694. *op_ptr = '\0';
  695. s_op = op;
  696. b = optmp;
  697. while ((a = s_op->name) != 0){
  698. op_ptr = b;
  699. while ((*op_ptr == *a) && (*op_ptr != '\0')){
  700. a++;
  701. op_ptr++;
  702. }
  703. if (*a == '\0'){
  704. keep(s_op);
  705. opflag = s_op->setop;
  706. if (*op_ptr != '\0'){
  707. b = op_ptr;
  708. s_op = op;
  709. continue;
  710. }
  711. else break;
  712. }
  713. else s_op++;
  714. }
  715. }
  716. void
  717. keep(struct op *o)
  718. {
  719. char *s;
  720. int ok;
  721. if(o->blanks == NEVER)ok = NO;
  722. else ok = YES;
  723. if (strict && ((o->blanks & ALWAYS)
  724. || ((opflag == 0 && o->blanks & SOMETIMES) && clev->tabs != 0)))
  725. putspace(' ',YES);
  726. for(s=o->name; *s != '\0'; s++){
  727. if(*(s+1) == '\0')putch(*s,ok);
  728. else
  729. putch(*s,NO);
  730. }
  731. if (strict && ((o->blanks & ALWAYS)
  732. || ((opflag == 0 && o->blanks & SOMETIMES) && clev->tabs != 0))) putch(' ',YES);
  733. }
  734. int
  735. getnl(void){
  736. int ch;
  737. char *savp;
  738. int gotcmt;
  739. gotcmt = 0;
  740. savp = p;
  741. while ((ch = getch()) == '\t' || ch == ' ')putch(ch,NO);
  742. if (ch == '/'){
  743. if ((ch = getch()) == '*'){
  744. putch('/',NO);
  745. putch('*',NO);
  746. comment(NO);
  747. ch = getch();
  748. gotcmt=1;
  749. }
  750. else if (ch == '/') {
  751. putch('/',NO);
  752. putch('/',NO);
  753. cpp_comment(NO);
  754. ch = getch();
  755. gotcmt = 1;
  756. }
  757. else {
  758. if(inswitch)*(++lastplace) = ch;
  759. else {
  760. inswitch = 1;
  761. *lastplace = ch;
  762. }
  763. unget('/');
  764. return(0);
  765. }
  766. }
  767. if(ch == '\n'){
  768. if(gotcmt == 0)p=savp;
  769. return(1);
  770. }
  771. unget(ch);
  772. return(0);
  773. }
  774. void
  775. ptabs(int n){
  776. int i;
  777. int num;
  778. if(n > maxtabs){
  779. if(!folded){
  780. Bprint(output, "/* code folded from here */\n");
  781. folded = 1;
  782. }
  783. num = n-maxtabs;
  784. }
  785. else {
  786. num = n;
  787. if(folded){
  788. folded = 0;
  789. Bprint(output, "/* unfolding */\n");
  790. }
  791. }
  792. for (i = 0; i < num; i++)Bputc(output, '\t');
  793. }
  794. void
  795. outs(int n){
  796. if (p > string){
  797. if (lbegin){
  798. ptabs(n);
  799. lbegin = 0;
  800. if (split == 1){
  801. split = 0;
  802. if (clev->tabs > 0)Bprint(output, "\t");
  803. }
  804. }
  805. *p = '\0';
  806. Bprint(output, "%s", string);
  807. lastlook = p = string;
  808. }
  809. else {
  810. if (lbegin != 0){
  811. lbegin = 0;
  812. split = 0;
  813. }
  814. }
  815. }
  816. void
  817. putch(char c,int ok)
  818. {
  819. int cc;
  820. if(p < &string[LINE-1]){
  821. if(count+TABLENG*clev->tabs >= maxleng && ok && !folded){
  822. if(c != ' ')*p++ = c;
  823. OUT;
  824. split = 1;
  825. if((cc=getch()) != '\n')unget(cc);
  826. }
  827. else {
  828. *p++ = c;
  829. count++;
  830. }
  831. }
  832. else {
  833. outs(clev->tabs);
  834. *p++ = c;
  835. count = 0;
  836. }
  837. }
  838. struct keyw *
  839. lookup(char *first, char *last)
  840. {
  841. struct keyw *ptr;
  842. char *cptr, *ckey, *k;
  843. if(first == last || first == 0)return(0);
  844. cptr = first;
  845. while (*cptr == ' ' || *cptr == '\t')cptr++;
  846. if(cptr >= last)return(0);
  847. ptr = key;
  848. while ((ckey = ptr->name) != 0){
  849. for (k = cptr; (*ckey == *k && *ckey != '\0'); k++, ckey++);
  850. if(*ckey=='\0' && (k==last|| (k<last && !isalnum(*k)))){
  851. opflag = 1;
  852. lastlook = 0;
  853. return(ptr);
  854. }
  855. ptr++;
  856. }
  857. return(0);
  858. }
  859. int
  860. comment(int ok)
  861. {
  862. int ch;
  863. int hitnl;
  864. hitnl = 0;
  865. while ((ch = getch()) != Beof){
  866. putch(ch, NO);
  867. if (ch == '*'){
  868. gotstar:
  869. if ((ch = getch()) == '/'){
  870. putch(ch,NO);
  871. return(hitnl);
  872. }
  873. putch(ch,NO);
  874. if (ch == '*')goto gotstar;
  875. }
  876. if (ch == '\n'){
  877. if(ok && !hitnl){
  878. outs(clev->tabs);
  879. }
  880. else {
  881. outs(0);
  882. }
  883. lbegin = 1;
  884. count = 0;
  885. hitnl = 1;
  886. }
  887. }
  888. return(hitnl);
  889. }
  890. int
  891. cpp_comment(int ok)
  892. {
  893. int ch;
  894. int hitnl;
  895. hitnl = 0;
  896. while ((ch = getch()) != -1) {
  897. if (ch == '\n') {
  898. if (ok && !hitnl)
  899. outs(clev->tabs);
  900. else
  901. outs(0);
  902. lbegin = 1;
  903. count = 0;
  904. hitnl = 1;
  905. break;
  906. }
  907. putch(ch, NO);
  908. }
  909. return hitnl;
  910. }
  911. void
  912. putspace(char ch, int ok)
  913. {
  914. if(p == string)putch(ch,ok);
  915. else if (*(p - 1) != ch) putch(ch,ok);
  916. }
  917. int
  918. getch(void){
  919. char c;
  920. if(inswitch){
  921. if(next != '\0'){
  922. c=next;
  923. next = '\0';
  924. return(c);
  925. }
  926. if(tptr <= lastplace){
  927. if(*tptr != '\0')return(*tptr++);
  928. else if(++tptr <= lastplace)return(*tptr++);
  929. }
  930. inswitch=0;
  931. lastplace = tptr = temp;
  932. }
  933. return(Bgetc(input));
  934. }
  935. void
  936. unget(char c)
  937. {
  938. if(inswitch){
  939. if(tptr != temp)
  940. *(--tptr) = c;
  941. else next = c;
  942. }
  943. else Bungetc(input);
  944. }
  945. char *
  946. getnext(int must){
  947. int c;
  948. char *beg;
  949. int prect,nlct;
  950. prect = nlct = 0;
  951. if(tptr > lastplace){
  952. tptr = lastplace = temp;
  953. err = 0;
  954. inswitch = 0;
  955. }
  956. tp = lastplace;
  957. if(inswitch && tptr <= lastplace)
  958. if (isalnum(*lastplace)||ispunct(*lastplace)||isop(*lastplace))return(lastplace);
  959. space:
  960. while(isspace(c=Bgetc(input)))puttmp(c,1);
  961. beg = tp;
  962. puttmp(c,1);
  963. if(c == '/'){
  964. if(puttmp(Bgetc(input),1) == '*'){
  965. cont:
  966. while((c=Bgetc(input)) != '*'){
  967. puttmp(c,0);
  968. if(must == 0 && c == '\n')
  969. if(nlct++ > 2)goto done;
  970. }
  971. puttmp(c,1);
  972. star:
  973. if(puttmp((c=Bgetc(input)),1) == '/'){
  974. beg = tp;
  975. puttmp((c=Bgetc(input)),1);
  976. }
  977. else if(c == '*')goto star;
  978. else goto cont;
  979. }
  980. else goto done;
  981. }
  982. if(isspace(c))goto space;
  983. if(c == '#' && tp > temp+1 && *(tp-2) == '\n'){
  984. if(prect++ > 2)goto done;
  985. while(puttmp((c=Bgetc(input)),1) != '\n')
  986. if(c == '\\')puttmp(Bgetc(input),1);
  987. goto space;
  988. }
  989. if(isalnum(c)){
  990. while(isalnum(c = Bgetc(input)))puttmp(c,1);
  991. Bungetc(input);
  992. }
  993. done:
  994. puttmp('\0',1);
  995. lastplace = tp-1;
  996. inswitch = 1;
  997. return(beg);
  998. }
  999. void
  1000. copy(char *s)
  1001. {
  1002. while(*s != '\0')putch(*s++,NO);
  1003. }
  1004. void
  1005. clearif(struct indent *cl)
  1006. {
  1007. int i;
  1008. for(i=0;i<IFLEVEL-1;i++)cl->ifc[i] = 0;
  1009. }
  1010. char
  1011. puttmp(char c, int keep)
  1012. {
  1013. if(tp < &temp[TEMP-120])
  1014. *tp++ = c;
  1015. else {
  1016. if(keep){
  1017. if(tp >= &temp[TEMP-1]){
  1018. fprint(2,"can't look past huge comment - quiting\n");
  1019. exits("boom");
  1020. }
  1021. *tp++ = c;
  1022. }
  1023. else if(err == 0){
  1024. err++;
  1025. fprint(2,"truncating long comment\n");
  1026. }
  1027. }
  1028. return(c);
  1029. }
  1030. void
  1031. error(char *s)
  1032. {
  1033. fprint(2,"saw EOF while looking for %s\n",s);
  1034. exits("boom");
  1035. }