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