/* An "author" of a "widget" w/o comments should be "sentenced to HARD LABOR" * * This one is an example - it took more time to comment and correct * * (then it probably would have taken to "code from scratch") * * his/her "fuzzy thoughts" plus messy code - FLAME OFF B.Eiben * * Warning: Only commented to the point I had to "understand" currently * * ************************************************************************ * Proposed usage (no code yet) * * C-source Beautifier * * Usage is: CB [-tx] infile [outfile] * * -tx x=indentation-atom length , x==0 =>2 ,-tx missing =>TAB* * outfile disk-output-file , default is terminal * * free standing comments are indented * * in-line comments are separated from code by one indent-atom* ************************************************************************ */ #include char tabstr[9] = { ' ',' ',' ',' ',' ',' ',' ',' ',0}; /* used (and modified) to indent */ int slevel[10]; int clevel = 0; int spflg[20][10]; int sind[20][10]; int siflev[10]; int sifflg[10]; int iflev = 0; int ifflg = -1; int level = 0; int ind[10] = { 0,0,0,0,0,0,0,0,0,0 }; int eflg = 0; int paren = 0; /* Level of parentheses */ int pflg[10] = { 0,0,0,0,0,0,0,0,0,0 }; char lchar; char pchar; int aflg = 0; int ct; int stabs[20][10]; int qflg = 0; char *wif[] = { "if",0}; char *welse[] = { "else",0}; char *wfor[] = { "for",0}; char *wds[] = { "case","default",0}; int j = 0; /* Warning Warning - for speed-reasons string[200] IS NOT GUARDED * * against over-flow - it "works" BUT is definitely NOT NICE * */ char string[200]; /* interim storage for text to be scanned */ char cc; int sflg = 1; /* 1== indent , 0== don't */ int peek = -1; /* -1==new char from source - otherwise "next char" */ int tabs = 0; /* count of indents */ int lastchar; /* "last" char */ int c; /* "current" char */ main(argc,argv) int argc; char *argv[]; { int n=2, flag=0; if(argc > 1){ /* in case of -tx set indent to x spaces */ if(argv[1][0]=='-'){ if(argv[1][1]=='t' || argv[1][1]=='T'){ n = atoi(&argv[1][2]); if(n==0) n=2; tabstr[(n>8)?8:n] = 0; } } } else { /* but if missing -tx set to TAB indent */ tabstr[0]= '\t'; tabstr[1]= 0; } while((c = getch()) != EOF){ switch(c){ case ' ': /* handle "white-space" */ case '\t': if(sflg == 0 || j > 0)string[j++] = c; if(lookup(welse) == 1){ /* as a terminator */ gotelse(); puts(); /* Dump so far */ continue; } continue; case '\n': /* EOL */ if((eflg = lookup(welse)) == 1)gotelse(); puts(); /* Dump so far */ printf("\n"); /* stuff CR */ sflg = 1; /* Indent on */ if(eflg == 1){ pflg[level]++; tabs++; } else if(pchar == lchar) aflg = 1; continue; case '{': /* Start of Block / terminator */ if(lookup(welse) == 1)gotelse(); siflev[clevel] = iflev; sifflg[clevel] = ifflg; iflev = ifflg = 0; clevel++; if(sflg == 1 && pflg[level] != 0){ pflg[level]--; tabs--; } string[j++] = c; puts(); /* Dump so far */ getnl(); /* Scan White Space and/or Comments */ puts(); /* Dump so far */ printf("\n"); /* Plus new-line - starting new indent */ tabs++; /* more indent */ sflg = 1; /* and indent on */ if(pflg[level] > 0){ ind[level] = 1; level++; slevel[level] = clevel; } continue; case '}': /* End of block */ clevel--; if((iflev = siflev[clevel]-1) < 0)iflev = 0; ifflg = sifflg[clevel]; if(pflg[level] >0 && ind[level] == 0){ tabs -= pflg[level]; pflg[level] = 0; } puts(); /* Dump so far */ tabs--; /* Decrease indentation */ ptabs(); /* indent directly */ if((peek = getch()) == ';'){ /* check for ; */ printf("%c;",c); /* get }; out */ peek = -1; /* peek is invalid */ } else printf("%c",c); /* Only } - so get } out */ getnl(); /* Scan White Space and/or comments */ puts(); /* Dump it */ printf("\n"); /* followed by CR */ sflg = 1; /* and enable indentation */ if(clevel < slevel[level])if(level > 0)level--; if(ind[level] != 0){ tabs -= pflg[level]; pflg[level] = 0; ind[level] = 0; } continue; case '"': case '\'': /* Check for " and/or ' */ string[j++] = c; /* save */ while((cc = getch()) != c){ string[j++] = cc; /* store anything til next " or ' */ if(cc == '\\'){ /* if \ */ string[j++] = getch(); /* store next one too */ } if(cc == '\n'){ /* if EOL */ puts(); /* Dump so far */ sflg = 1; /* Indentation ON */ } } string[j++] = cc; /* store */ if(getnl() == 1){ /* Check for White-Space or Comments */ lchar = cc; /* got nothing but EOL */ peek = '\n'; } continue; case ';': string[j++] = c; puts(); if(pflg[level] > 0 && ind[level] == 0){ tabs -= pflg[level]; pflg[level] = 0; } getnl(); /* Check for White-Space and Comments */ puts(); printf("\n"); /* plus CR */ sflg = 1; /* Indent ON */ if(iflev > 0) if(ifflg == 1){ iflev--; ifflg = 0; } else iflev = 0; continue; case '\\': /* Ckeck \ */ string[j++] = c; /* and save it */ string[j++] = getch(); /* save next one too */ continue; case '?': qflg = 1; string[j++] = c; continue; case ':': string[j++] = c; if(qflg == 1){ qflg = 0; continue; } if(lookup(wds) == 0){ sflg = 0; puts(); } else{ tabs--; puts(); tabs++; } if((peek = getch()) == ';'){ printf(";"); peek = -1; } getnl(); puts(); printf("\n"); sflg = 1; continue; case '/': /* Maybe Comment seen */ if((peek = getch()) != '*'){ string[j++] = c; /* No Comment - save / */ continue; /* and out of here */ } peek = -1; /* we'll stick it in later */ comment(); /* Scan for Comment */ continue; case ')': paren--; string[j++] = c; puts(); if(getnl() == 1){ peek = '\n'; if(paren != 0)aflg = 1; else if(tabs > 0){ pflg[level]++; tabs++; ind[level] = 0; } } continue; case '#': string[j++] = c; while((cc = getch()) != '\n')string[j++] = cc; string[j++] = cc; sflg = 0; puts(); sflg = 1; continue; case '(': string[j++] = c; paren++; if(lookup(wfor) == 1){ while((c = gets()) != ';'); ct=0; cont: while((c = gets()) != ')'){ if(c == '(') ct++; } if(ct != 0){ ct--; goto cont; } paren--; puts(); if(getnl() == 1){ peek = '\n'; pflg[level]++; tabs++; ind[level] = 0; } continue; } if(lookup(wif) == 1){ puts(); stabs[clevel][iflev] = tabs; spflg[clevel][iflev] = pflg[level]; sind[clevel][iflev] = ind[level]; iflev++; ifflg = 1; } continue; default: string[j++] = c; /* Any other char is saved */ if(c != ',')lchar = c; } } } ptabs(){ /* Print Indentation */ int i; for(i=0; i < tabs; i++)printf("%s",tabstr); } getch(){ if(peek < 0 && lastchar != ' ' && lastchar != '\t')pchar = lastchar; lastchar = (peek<0) ? getc(stdin):peek; peek = -1; return(lastchar); } puts(){ /* Indent (SFLG==1) and empty string-buffer */ if(j > 0){ if(sflg != 0){ ptabs(); if(aflg == 1){ if(tabs > 0)printf(" "); } } string[j] = '\0'; printf("%s",string); j = 0; } sflg = 0; aflg = 0; } lookup(tab) char *tab[]; { char r; int l,kk,k,i; if(j < 1)return(0); kk=0; while(r=string[kk] == ' '|| r == '\t')kk++; /* Skip leading White Space */ for(i=0; tab[i] != 0; i++){ l=0; for(k=kk;(r = tab[i][l++]) == string[k] && r != '\0';k++); if(r == '\0' && (string[k] < 'a' || string[k] > 'z' || k >= j))return(1); } return(0); } gets(){ char ch; beg: if((ch = string[j++] = getch()) == '\\'){ /* Check for \ */ string[j++] = getch(); /* and store */ goto beg; } if(ch == '\'' || ch == '"'){ /* Check for ' or " */ while((cc = string[j++] = getch()) != ch)if(cc == '\\')string[j++] = getch(); goto beg; } if(ch == '\n'){ puts(); aflg = 1; goto beg; } else return(ch); } gotelse(){ tabs = stabs[clevel][iflev]; pflg[level] = spflg[clevel][iflev]; ind[level] = sind[clevel][iflev]; ifflg = 1; } getnl(){ /* Scan over White Space and/or Comments */ while((peek = getch()) == '\t' || peek == ' '){ string[j++] = peek; peek = -1; } if((peek = getch()) == '/'){ peek = -1; if((peek = getch()) == '*'){ peek = -1; /* Found start of comment */ comment(); } else string[j++] = '/'; /* Store just / -not a comment */ } if((peek = getch()) == '\n'){ peek = -1; return(1); } return(0); } comment(){ flshwh(); /* Flush White Space before Comments */ rep: while((c = string[j++] = getch()) != '*') if(c == '\n'){ /* Check for EOL */ puts(); sflg = 1; } gotstar: if((c = string[j++] = getch()) != '/'){ if(c == '\n'){ /* Ckeck for EOL */ puts(); sflg = 1; } if(c == '*')goto gotstar; goto rep; } } flshwh() /* FLushes White-space before comments */ { char r; if (j >0 )j--; /* re-adjust pointer */ else { string[j++] = '/'; string[j++] = '*'; return; } /* Now walk back and "forget" white-space */ while(j >= 0 && ( ( r = string[j]) == ' ' || r == '\t' ))j--; if (j < 0 ) j = 0; /* Stay within bounds */ printf("%s",tabstr); /* use indent as separator */ string[j++] = '/'; string[j++] = '*'; }