cb.c 18 KB

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