1035 lines
18 KiB
C
1035 lines
18 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
#include <bio.h>
|
|
#include "cb.h"
|
|
#include "cbtype.h"
|
|
|
|
void
|
|
main(int argc, char *argv[])
|
|
{
|
|
Biobuf stdin, stdout;
|
|
|
|
while (--argc > 0 && (*++argv)[0] == '-'){
|
|
switch ((*argv)[1]){
|
|
case 's':
|
|
strict = 1;
|
|
continue;
|
|
case 'j':
|
|
join = 1;
|
|
continue;
|
|
case 'l':
|
|
if((*argv)[2] != '\0'){
|
|
maxleng = atoi( &((*argv)[2]) );
|
|
}
|
|
else{
|
|
maxleng = atoi(*++argv);
|
|
argc--;
|
|
}
|
|
maxtabs = maxleng/TABLENG - 2;
|
|
maxleng -= (maxleng + 5)/10;
|
|
continue;
|
|
default:
|
|
fprint(2, "cb: illegal option %c\n", *argv[1]);
|
|
exits("boom");
|
|
}
|
|
}
|
|
Binit(&stdout, 1, OWRITE);
|
|
output = &stdout;
|
|
if (argc <= 0){
|
|
Binit(&stdin, 0, OREAD);
|
|
input = &stdin;
|
|
work();
|
|
} else {
|
|
while (argc-- > 0){
|
|
if ((input = Bopen( *argv, OREAD)) == 0){
|
|
fprint(2, "cb: cannot open input file %s\n", *argv);
|
|
exits("boom");
|
|
}
|
|
work();
|
|
argv++;
|
|
}
|
|
}
|
|
exits(0);
|
|
}
|
|
void
|
|
work(void){
|
|
int c;
|
|
struct keyw *lptr;
|
|
char *pt;
|
|
int cc;
|
|
int ct;
|
|
|
|
while ((c = getch()) != Beof){
|
|
switch (c){
|
|
case '{':
|
|
if ((lptr = lookup(lastlook,p)) != 0){
|
|
if (lptr->type == ELSE)gotelse();
|
|
else if(lptr->type == DO)gotdo();
|
|
else if(lptr->type == STRUCT)structlev++;
|
|
}
|
|
if(++clev >= &ind[CLEVEL-1]){
|
|
fprint(2,"too many levels of curly brackets\n");
|
|
clev = &ind[CLEVEL-1];
|
|
}
|
|
clev->pdepth = 0;
|
|
clev->tabs = (clev-1)->tabs;
|
|
clearif(clev);
|
|
if(strict && clev->tabs > 0)
|
|
putspace(' ',NO);
|
|
putch(c,NO);
|
|
getnl();
|
|
if(keyflag == DATADEF){
|
|
OUT;
|
|
}
|
|
else {
|
|
OUTK;
|
|
}
|
|
clev->tabs++;
|
|
pt = getnext(0); /* to handle initialized structures */
|
|
if(*pt == '{'){ /* hide one level of {} */
|
|
while((c=getch()) != '{')
|
|
if(c == Beof)error("{");
|
|
putch(c,NO);
|
|
if(strict){
|
|
putch(' ',NO);
|
|
eatspace();
|
|
}
|
|
keyflag = SINIT;
|
|
}
|
|
continue;
|
|
case '}':
|
|
pt = getnext(0); /* to handle initialized structures */
|
|
if(*pt == ','){
|
|
if(strict){
|
|
putspace(' ',NO);
|
|
eatspace();
|
|
}
|
|
putch(c,NO);
|
|
putch(*pt,NO);
|
|
*pt = '\0';
|
|
ct = getnl();
|
|
pt = getnext(0);
|
|
if(*pt == '{'){
|
|
OUT;
|
|
while((cc = getch()) != '{')
|
|
if(cc == Beof)error("}");
|
|
putch(cc,NO);
|
|
if(strict){
|
|
putch(' ',NO);
|
|
eatspace();
|
|
}
|
|
getnext(0);
|
|
continue;
|
|
}
|
|
else if(strict || ct){
|
|
OUT;
|
|
}
|
|
continue;
|
|
}
|
|
else if(keyflag == SINIT && *pt == '}'){
|
|
if(strict)
|
|
putspace(' ',NO);
|
|
putch(c,NO);
|
|
getnl();
|
|
OUT;
|
|
keyflag = DATADEF;
|
|
*pt = '\0';
|
|
pt = getnext(0);
|
|
}
|
|
outs(clev->tabs);
|
|
if(--clev < ind)clev = ind;
|
|
ptabs(clev->tabs);
|
|
putch(c,NO);
|
|
lbegin = 0;
|
|
lptr=lookup(pt,lastplace+1);
|
|
c = *pt;
|
|
if(*pt == ';' || *pt == ','){
|
|
putch(*pt,NO);
|
|
*pt = '\0';
|
|
lastplace=pt;
|
|
}
|
|
ct = getnl();
|
|
if((dolevel && clev->tabs <= dotabs[dolevel]) || (structlev )
|
|
|| (lptr != 0 &&lptr->type == ELSE&& clev->pdepth == 0)){
|
|
if(c == ';'){
|
|
OUTK;
|
|
}
|
|
else if(strict || (lptr != 0 && lptr->type == ELSE && ct == 0)){
|
|
putspace(' ',NO);
|
|
eatspace();
|
|
}
|
|
else if(lptr != 0 && lptr->type == ELSE){
|
|
OUTK;
|
|
}
|
|
if(structlev){
|
|
structlev--;
|
|
keyflag = DATADEF;
|
|
}
|
|
}
|
|
else {
|
|
OUTK;
|
|
if(strict && clev->tabs == 0){
|
|
if((c=getch()) != '\n'){
|
|
Bputc(output, '\n');
|
|
Bputc(output, '\n');
|
|
unget(c);
|
|
}
|
|
else {
|
|
lineno++;
|
|
Bputc(output, '\n');
|
|
if((c=getch()) != '\n')unget(c);
|
|
else lineno++;
|
|
Bputc(output, '\n');
|
|
}
|
|
}
|
|
}
|
|
if(lptr != 0 && lptr->type == ELSE && clev->pdepth != 0){
|
|
UNBUMP;
|
|
}
|
|
if(lptr == 0 || lptr->type != ELSE){
|
|
clev->iflev = 0;
|
|
if(dolevel && docurly[dolevel] == NO && clev->tabs == dotabs[dolevel]+1)
|
|
clev->tabs--;
|
|
else if(clev->pdepth != 0){
|
|
UNBUMP;
|
|
}
|
|
}
|
|
continue;
|
|
case '(':
|
|
paren++;
|
|
if ((lptr = lookup(lastlook,p)) != 0){
|
|
if(!(lptr->type == TYPE || lptr->type == STRUCT))keyflag=KEYWORD;
|
|
if (strict){
|
|
putspace(lptr->punc,NO);
|
|
opflag = 1;
|
|
}
|
|
putch(c,NO);
|
|
if (lptr->type == IF)gotif();
|
|
}
|
|
else {
|
|
putch(c,NO);
|
|
lastlook = p;
|
|
opflag = 1;
|
|
}
|
|
continue;
|
|
case ')':
|
|
if(--paren < 0)paren = 0;
|
|
putch(c,NO);
|
|
if((lptr = lookup(lastlook,p)) != 0){
|
|
if(lptr->type == TYPE || lptr->type == STRUCT)
|
|
opflag = 1;
|
|
}
|
|
else if(keyflag == DATADEF)opflag = 1;
|
|
else opflag = 0;
|
|
outs(clev->tabs);
|
|
pt = getnext(1);
|
|
if ((ct = getnl()) == 1 && !strict){
|
|
if(dolevel && clev->tabs <= dotabs[dolevel])
|
|
resetdo();
|
|
if(clev->tabs > 0 && (paren != 0 || keyflag == 0)){
|
|
if(join){
|
|
eatspace();
|
|
putch(' ',YES);
|
|
continue;
|
|
} else {
|
|
OUT;
|
|
split = 1;
|
|
continue;
|
|
}
|
|
}
|
|
else if(clev->tabs > 0 && *pt != '{'){
|
|
BUMP;
|
|
}
|
|
OUTK;
|
|
}
|
|
else if(strict){
|
|
if(clev->tabs == 0){
|
|
if(*pt != ';' && *pt != ',' && *pt != '(' && *pt != '['){
|
|
OUTK;
|
|
}
|
|
}
|
|
else {
|
|
if(keyflag == KEYWORD && paren == 0){
|
|
if(dolevel && clev->tabs <= dotabs[dolevel]){
|
|
resetdo();
|
|
eatspace();
|
|
continue;
|
|
}
|
|
if(*pt != '{'){
|
|
BUMP;
|
|
OUTK;
|
|
}
|
|
else {
|
|
*pt='\0';
|
|
eatspace();
|
|
unget('{');
|
|
}
|
|
}
|
|
else if(ct){
|
|
if(paren){
|
|
if(join){
|
|
eatspace();
|
|
} else {
|
|
split = 1;
|
|
OUT;
|
|
}
|
|
}
|
|
else {
|
|
OUTK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(dolevel && clev->tabs <= dotabs[dolevel])
|
|
resetdo();
|
|
continue;
|
|
case ' ':
|
|
case '\t':
|
|
if ((lptr = lookup(lastlook,p)) != 0){
|
|
if(!(lptr->type==TYPE||lptr->type==STRUCT))
|
|
keyflag = KEYWORD;
|
|
else if(paren == 0)keyflag = DATADEF;
|
|
if(strict){
|
|
if(lptr->type != ELSE){
|
|
if(lptr->type == TYPE){
|
|
if(paren != 0)putch(' ',YES);
|
|
}
|
|
else
|
|
putch(lptr->punc,NO);
|
|
eatspace();
|
|
}
|
|
}
|
|
else putch(c,YES);
|
|
switch(lptr->type){
|
|
case CASE:
|
|
outs(clev->tabs-1);
|
|
continue;
|
|
case ELSE:
|
|
pt = getnext(1);
|
|
eatspace();
|
|
if((cc = getch()) == '\n' && !strict){
|
|
unget(cc);
|
|
}
|
|
else {
|
|
unget(cc);
|
|
if(checkif(pt))continue;
|
|
}
|
|
gotelse();
|
|
if(strict) unget(c);
|
|
if(getnl() == 1 && !strict){
|
|
OUTK;
|
|
if(*pt != '{'){
|
|
BUMP;
|
|
}
|
|
}
|
|
else if(strict){
|
|
if(*pt != '{'){
|
|
OUTK;
|
|
BUMP;
|
|
}
|
|
}
|
|
continue;
|
|
case IF:
|
|
gotif();
|
|
continue;
|
|
case DO:
|
|
gotdo();
|
|
pt = getnext(1);
|
|
if(*pt != '{'){
|
|
eatallsp();
|
|
OUTK;
|
|
docurly[dolevel] = NO;
|
|
dopdepth[dolevel] = clev->pdepth;
|
|
clev->pdepth = 0;
|
|
clev->tabs++;
|
|
}
|
|
continue;
|
|
case TYPE:
|
|
if(paren)continue;
|
|
if(!strict)continue;
|
|
gottype(lptr);
|
|
continue;
|
|
case STRUCT:
|
|
gotstruct();
|
|
continue;
|
|
}
|
|
}
|
|
else if (lbegin == 0 || p > string)
|
|
if(strict)
|
|
putch(c,NO);
|
|
else putch(c,YES);
|
|
continue;
|
|
case ';':
|
|
putch(c,NO);
|
|
if(paren != 0){
|
|
if(strict){
|
|
putch(' ',YES);
|
|
eatspace();
|
|
}
|
|
opflag = 1;
|
|
continue;
|
|
}
|
|
outs(clev->tabs);
|
|
pt = getnext(0);
|
|
lptr=lookup(pt,lastplace+1);
|
|
if(lptr == 0 || lptr->type != ELSE){
|
|
clev->iflev = 0;
|
|
if(clev->pdepth != 0){
|
|
UNBUMP;
|
|
}
|
|
if(dolevel && docurly[dolevel] == NO && clev->tabs <= dotabs[dolevel]+1)
|
|
clev->tabs--;
|
|
/*
|
|
else if(clev->pdepth != 0){
|
|
UNBUMP;
|
|
}
|
|
*/
|
|
}
|
|
getnl();
|
|
OUTK;
|
|
continue;
|
|
case '\n':
|
|
if ((lptr = lookup(lastlook,p)) != 0){
|
|
pt = getnext(1);
|
|
if (lptr->type == ELSE){
|
|
if(strict)
|
|
if(checkif(pt))continue;
|
|
gotelse();
|
|
OUTK;
|
|
if(*pt != '{'){
|
|
BUMP;
|
|
}
|
|
}
|
|
else if(lptr->type == DO){
|
|
OUTK;
|
|
gotdo();
|
|
if(*pt != '{'){
|
|
docurly[dolevel] = NO;
|
|
dopdepth[dolevel] = clev->pdepth;
|
|
clev->pdepth = 0;
|
|
clev->tabs++;
|
|
}
|
|
}
|
|
else {
|
|
OUTK;
|
|
if(lptr->type == STRUCT)gotstruct();
|
|
}
|
|
}
|
|
else if(p == string)Bputc(output, '\n');
|
|
else {
|
|
if(clev->tabs > 0 &&(paren != 0 || keyflag == 0)){
|
|
if(join){
|
|
putch(' ',YES);
|
|
eatspace();
|
|
continue;
|
|
} else {
|
|
OUT;
|
|
split = 1;
|
|
continue;
|
|
}
|
|
}
|
|
else if(keyflag == KEYWORD){
|
|
OUTK;
|
|
continue;
|
|
}
|
|
OUT;
|
|
}
|
|
continue;
|
|
case '"':
|
|
case '\'':
|
|
putch(c,NO);
|
|
while ((cc = getch()) != c){
|
|
if(cc == Beof)
|
|
error("\" or '");
|
|
putch(cc,NO);
|
|
if (cc == '\\'){
|
|
putch(getch(),NO);
|
|
}
|
|
if (cc == '\n'){
|
|
outs(clev->tabs);
|
|
lbegin = 1;
|
|
count = 0;
|
|
}
|
|
}
|
|
putch(cc,NO);
|
|
opflag=0;
|
|
if (getnl() == 1){
|
|
unget('\n');
|
|
}
|
|
continue;
|
|
case '\\':
|
|
putch(c,NO);
|
|
putch(getch(),NO);
|
|
continue;
|
|
case '?':
|
|
question = 1;
|
|
gotop(c);
|
|
continue;
|
|
case ':':
|
|
if (question == 1){
|
|
question = 0;
|
|
gotop(c);
|
|
continue;
|
|
}
|
|
putch(c,NO);
|
|
if(structlev)continue;
|
|
if ((lptr = lookup(lastlook,p)) != 0){
|
|
if (lptr->type == CASE)outs(clev->tabs - 1);
|
|
}
|
|
else {
|
|
lbegin = 0;
|
|
outs(clev->tabs);
|
|
}
|
|
getnl();
|
|
OUTK;
|
|
continue;
|
|
case '/':
|
|
if ((cc = getch()) == '/') {
|
|
putch(c,NO);
|
|
putch(cc,NO);
|
|
cpp_comment(YES);
|
|
OUT;
|
|
lastlook = 0;
|
|
continue;
|
|
}
|
|
else if (cc != '*') {
|
|
unget(cc);
|
|
gotop(c);
|
|
continue;
|
|
}
|
|
putch(c,NO);
|
|
putch(cc,NO);
|
|
cc = comment(YES);
|
|
if(getnl() == 1){
|
|
if(cc == 0){
|
|
OUT;
|
|
}
|
|
else {
|
|
outs(0);
|
|
Bputc(output, '\n');
|
|
lbegin = 1;
|
|
count = 0;
|
|
}
|
|
lastlook = 0;
|
|
}
|
|
continue;
|
|
case '[':
|
|
putch(c,NO);
|
|
ct = 0;
|
|
while((c = getch()) != ']' || ct > 0){
|
|
if(c == Beof)error("]");
|
|
putch(c,NO);
|
|
if(c == '[')ct++;
|
|
if(c == ']')ct--;
|
|
}
|
|
putch(c,NO);
|
|
continue;
|
|
case '#':
|
|
putch(c,NO);
|
|
while ((cc = getch()) != '\n'){
|
|
if(cc == Beof)error("newline");
|
|
if (cc == '\\'){
|
|
putch(cc,NO);
|
|
cc = getch();
|
|
}
|
|
putch(cc,NO);
|
|
}
|
|
putch(cc,NO);
|
|
lbegin = 0;
|
|
outs(clev->tabs);
|
|
lbegin = 1;
|
|
count = 0;
|
|
continue;
|
|
default:
|
|
if (c == ','){
|
|
opflag = 1;
|
|
putch(c,YES);
|
|
if (strict){
|
|
if ((cc = getch()) != ' ')unget(cc);
|
|
if(cc != '\n')putch(' ',YES);
|
|
}
|
|
}
|
|
else if(isop(c))gotop(c);
|
|
else {
|
|
if(isalnum(c) && lastlook == 0)lastlook = p;
|
|
if(isdigit(c)){
|
|
putch(c,NO);
|
|
while(isdigit(c=Bgetc(input))||c == '.')putch(c,NO);
|
|
if(c == 'e'){
|
|
putch(c,NO);
|
|
c = Bgetc(input);
|
|
putch(c, NO);
|
|
while(isdigit(c=Bgetc(input)))putch(c,NO);
|
|
}
|
|
Bungetc(input);
|
|
}
|
|
else putch(c,NO);
|
|
if(keyflag != DATADEF)opflag = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void
|
|
gotif(void){
|
|
outs(clev->tabs);
|
|
if(++clev->iflev >= IFLEVEL-1){
|
|
fprint(2,"too many levels of if %d\n",clev->iflev );
|
|
clev->iflev = IFLEVEL-1;
|
|
}
|
|
clev->ifc[clev->iflev] = clev->tabs;
|
|
clev->spdepth[clev->iflev] = clev->pdepth;
|
|
}
|
|
void
|
|
gotelse(void){
|
|
clev->tabs = clev->ifc[clev->iflev];
|
|
clev->pdepth = clev->spdepth[clev->iflev];
|
|
if(--(clev->iflev) < 0)clev->iflev = 0;
|
|
}
|
|
int
|
|
checkif(char *pt)
|
|
{
|
|
struct keyw *lptr;
|
|
int cc;
|
|
if((lptr=lookup(pt,lastplace+1))!= 0){
|
|
if(lptr->type == IF){
|
|
if(strict)putch(' ',YES);
|
|
copy(lptr->name);
|
|
*pt='\0';
|
|
lastplace = pt;
|
|
if(strict){
|
|
putch(lptr->punc,NO);
|
|
eatallsp();
|
|
}
|
|
clev->tabs = clev->ifc[clev->iflev];
|
|
clev->pdepth = clev->spdepth[clev->iflev];
|
|
keyflag = KEYWORD;
|
|
return(1);
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
void
|
|
gotdo(void){
|
|
if(++dolevel >= DOLEVEL-1){
|
|
fprint(2,"too many levels of do %d\n",dolevel);
|
|
dolevel = DOLEVEL-1;
|
|
}
|
|
dotabs[dolevel] = clev->tabs;
|
|
docurly[dolevel] = YES;
|
|
}
|
|
void
|
|
resetdo(void){
|
|
if(docurly[dolevel] == NO)
|
|
clev->pdepth = dopdepth[dolevel];
|
|
if(--dolevel < 0)dolevel = 0;
|
|
}
|
|
void
|
|
gottype(struct keyw *lptr)
|
|
{
|
|
char *pt;
|
|
struct keyw *tlptr;
|
|
int c;
|
|
while(1){
|
|
pt = getnext(1);
|
|
if((tlptr=lookup(pt,lastplace+1))!=0){
|
|
putch(' ',YES);
|
|
copy(tlptr->name);
|
|
*pt='\0';
|
|
lastplace = pt;
|
|
if(tlptr->type == STRUCT){
|
|
putch(tlptr->punc,YES);
|
|
gotstruct();
|
|
break;
|
|
}
|
|
lptr=tlptr;
|
|
continue;
|
|
}
|
|
else{
|
|
putch(lptr->punc,NO);
|
|
while((c=getch())== ' ' || c == '\t');
|
|
unget(c);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
void
|
|
gotstruct(void){
|
|
int c;
|
|
int cc;
|
|
char *pt;
|
|
while((c=getch()) == ' ' || c == '\t')
|
|
if(!strict)putch(c,NO);
|
|
if(c == '{'){
|
|
structlev++;
|
|
unget(c);
|
|
return;
|
|
}
|
|
if(isalpha(c)){
|
|
putch(c,NO);
|
|
while(isalnum(c=getch()))putch(c,NO);
|
|
}
|
|
unget(c);
|
|
pt = getnext(1);
|
|
if(*pt == '{')structlev++;
|
|
if(strict){
|
|
eatallsp();
|
|
putch(' ',NO);
|
|
}
|
|
}
|
|
void
|
|
gotop(int c)
|
|
{
|
|
char optmp[OPLENGTH];
|
|
char *op_ptr;
|
|
struct op *s_op;
|
|
char *a, *b;
|
|
op_ptr = optmp;
|
|
*op_ptr++ = c;
|
|
while (isop((uchar)( *op_ptr = getch())))op_ptr++;
|
|
if(!strict)unget(*op_ptr);
|
|
else if (*op_ptr != ' ')unget( *op_ptr);
|
|
*op_ptr = '\0';
|
|
s_op = op;
|
|
b = optmp;
|
|
while ((a = s_op->name) != 0){
|
|
op_ptr = b;
|
|
while ((*op_ptr == *a) && (*op_ptr != '\0')){
|
|
a++;
|
|
op_ptr++;
|
|
}
|
|
if (*a == '\0'){
|
|
keep(s_op);
|
|
opflag = s_op->setop;
|
|
if (*op_ptr != '\0'){
|
|
b = op_ptr;
|
|
s_op = op;
|
|
continue;
|
|
}
|
|
else break;
|
|
}
|
|
else s_op++;
|
|
}
|
|
}
|
|
void
|
|
keep(struct op *o)
|
|
{
|
|
char *s;
|
|
int ok;
|
|
if(o->blanks == NEVER)ok = NO;
|
|
else ok = YES;
|
|
if (strict && ((o->blanks & ALWAYS)
|
|
|| ((opflag == 0 && o->blanks & SOMETIMES) && clev->tabs != 0)))
|
|
putspace(' ',YES);
|
|
for(s=o->name; *s != '\0'; s++){
|
|
if(*(s+1) == '\0')putch(*s,ok);
|
|
else
|
|
putch(*s,NO);
|
|
}
|
|
if (strict && ((o->blanks & ALWAYS)
|
|
|| ((opflag == 0 && o->blanks & SOMETIMES) && clev->tabs != 0))) putch(' ',YES);
|
|
}
|
|
int
|
|
getnl(void){
|
|
int ch;
|
|
char *savp;
|
|
int gotcmt;
|
|
gotcmt = 0;
|
|
savp = p;
|
|
while ((ch = getch()) == '\t' || ch == ' ')putch(ch,NO);
|
|
if (ch == '/'){
|
|
if ((ch = getch()) == '*'){
|
|
putch('/',NO);
|
|
putch('*',NO);
|
|
comment(NO);
|
|
ch = getch();
|
|
gotcmt=1;
|
|
}
|
|
else if (ch == '/') {
|
|
putch('/',NO);
|
|
putch('/',NO);
|
|
cpp_comment(NO);
|
|
ch = getch();
|
|
gotcmt = 1;
|
|
}
|
|
else {
|
|
if(inswitch)*(++lastplace) = ch;
|
|
else {
|
|
inswitch = 1;
|
|
*lastplace = ch;
|
|
}
|
|
unget('/');
|
|
return(0);
|
|
}
|
|
}
|
|
if(ch == '\n'){
|
|
if(gotcmt == 0)p=savp;
|
|
return(1);
|
|
}
|
|
unget(ch);
|
|
return(0);
|
|
}
|
|
void
|
|
ptabs(int n){
|
|
int i;
|
|
int num;
|
|
if(n > maxtabs){
|
|
if(!folded){
|
|
Bprint(output, "/* code folded from here */\n");
|
|
folded = 1;
|
|
}
|
|
num = n-maxtabs;
|
|
}
|
|
else {
|
|
num = n;
|
|
if(folded){
|
|
folded = 0;
|
|
Bprint(output, "/* unfolding */\n");
|
|
}
|
|
}
|
|
for (i = 0; i < num; i++)Bputc(output, '\t');
|
|
}
|
|
void
|
|
outs(int n){
|
|
if (p > string){
|
|
if (lbegin){
|
|
ptabs(n);
|
|
lbegin = 0;
|
|
if (split == 1){
|
|
split = 0;
|
|
if (clev->tabs > 0)Bprint(output, " ");
|
|
}
|
|
}
|
|
*p = '\0';
|
|
Bprint(output, "%s", string);
|
|
lastlook = p = string;
|
|
}
|
|
else {
|
|
if (lbegin != 0){
|
|
lbegin = 0;
|
|
split = 0;
|
|
}
|
|
}
|
|
}
|
|
void
|
|
putch(char c,int ok)
|
|
{
|
|
int cc;
|
|
if(p < &string[LINE-1]){
|
|
if(count+TABLENG*clev->tabs >= maxleng && ok && !folded){
|
|
if(c != ' ')*p++ = c;
|
|
OUT;
|
|
split = 1;
|
|
if((cc=getch()) != '\n')unget(cc);
|
|
}
|
|
else {
|
|
*p++ = c;
|
|
count++;
|
|
}
|
|
}
|
|
else {
|
|
outs(clev->tabs);
|
|
*p++ = c;
|
|
count = 0;
|
|
}
|
|
}
|
|
struct keyw *
|
|
lookup(char *first, char *last)
|
|
{
|
|
struct keyw *ptr;
|
|
char *cptr, *ckey, *k;
|
|
|
|
if(first == last || first == 0)return(0);
|
|
cptr = first;
|
|
while (*cptr == ' ' || *cptr == '\t')cptr++;
|
|
if(cptr >= last)return(0);
|
|
ptr = key;
|
|
while ((ckey = ptr->name) != 0){
|
|
for (k = cptr; (*ckey == *k && *ckey != '\0'); k++, ckey++);
|
|
if(*ckey=='\0' && (k==last|| (k<last && !isalnum((uchar)*k)))){
|
|
opflag = 1;
|
|
lastlook = 0;
|
|
return(ptr);
|
|
}
|
|
ptr++;
|
|
}
|
|
return(0);
|
|
}
|
|
int
|
|
comment(int ok)
|
|
{
|
|
int ch;
|
|
int hitnl;
|
|
|
|
hitnl = 0;
|
|
while ((ch = getch()) != Beof){
|
|
putch(ch, NO);
|
|
if (ch == '*'){
|
|
gotstar:
|
|
if ((ch = getch()) == '/'){
|
|
putch(ch,NO);
|
|
return(hitnl);
|
|
}
|
|
putch(ch,NO);
|
|
if (ch == '*')goto gotstar;
|
|
}
|
|
if (ch == '\n'){
|
|
if(ok && !hitnl){
|
|
outs(clev->tabs);
|
|
}
|
|
else {
|
|
outs(0);
|
|
}
|
|
lbegin = 1;
|
|
count = 0;
|
|
hitnl = 1;
|
|
}
|
|
}
|
|
return(hitnl);
|
|
}
|
|
int
|
|
cpp_comment(int ok)
|
|
{
|
|
int ch;
|
|
int hitnl;
|
|
|
|
hitnl = 0;
|
|
while ((ch = getch()) != -1) {
|
|
if (ch == '\n') {
|
|
if (ok && !hitnl)
|
|
outs(clev->tabs);
|
|
else
|
|
outs(0);
|
|
lbegin = 1;
|
|
count = 0;
|
|
hitnl = 1;
|
|
break;
|
|
}
|
|
putch(ch, NO);
|
|
}
|
|
return hitnl;
|
|
}
|
|
void
|
|
putspace(char ch, int ok)
|
|
{
|
|
if(p == string)putch(ch,ok);
|
|
else if (*(p - 1) != ch) putch(ch,ok);
|
|
}
|
|
int
|
|
getch(void){
|
|
char c;
|
|
if(inswitch){
|
|
if(next != '\0'){
|
|
c=next;
|
|
next = '\0';
|
|
return(c);
|
|
}
|
|
if(tptr <= lastplace){
|
|
if(*tptr != '\0')return(*tptr++);
|
|
else if(++tptr <= lastplace)return(*tptr++);
|
|
}
|
|
inswitch=0;
|
|
lastplace = tptr = temp;
|
|
}
|
|
return(Bgetc(input));
|
|
}
|
|
void
|
|
unget(char c)
|
|
{
|
|
if(inswitch){
|
|
if(tptr != temp)
|
|
*(--tptr) = c;
|
|
else next = c;
|
|
}
|
|
else Bungetc(input);
|
|
}
|
|
char *
|
|
getnext(int must){
|
|
int c;
|
|
char *beg;
|
|
int prect,nlct;
|
|
prect = nlct = 0;
|
|
if(tptr > lastplace){
|
|
tptr = lastplace = temp;
|
|
err = 0;
|
|
inswitch = 0;
|
|
}
|
|
tp = lastplace;
|
|
if(inswitch && tptr <= lastplace)
|
|
if (isalnum((uchar)*lastplace)||ispunct((uchar)*lastplace)||isop((uchar)*lastplace))return(lastplace);
|
|
space:
|
|
while(isspace(c=Bgetc(input)))puttmp(c,1);
|
|
beg = tp;
|
|
puttmp(c,1);
|
|
if(c == '/'){
|
|
if(puttmp(Bgetc(input),1) == '*'){
|
|
cont:
|
|
while((c=Bgetc(input)) != '*'){
|
|
puttmp(c,0);
|
|
if(must == 0 && c == '\n')
|
|
if(nlct++ > 2)goto done;
|
|
}
|
|
puttmp(c,1);
|
|
star:
|
|
if(puttmp((c=Bgetc(input)),1) == '/'){
|
|
beg = tp;
|
|
puttmp((c=Bgetc(input)),1);
|
|
}
|
|
else if(c == '*')goto star;
|
|
else goto cont;
|
|
}
|
|
else goto done;
|
|
}
|
|
if(isspace(c))goto space;
|
|
if(c == '#' && tp > temp+1 && *(tp-2) == '\n'){
|
|
if(prect++ > 2)goto done;
|
|
while(puttmp((c=Bgetc(input)),1) != '\n')
|
|
if(c == '\\')puttmp(Bgetc(input),1);
|
|
goto space;
|
|
}
|
|
if(isalnum(c)){
|
|
while(isalnum(c = Bgetc(input)))puttmp(c,1);
|
|
Bungetc(input);
|
|
}
|
|
done:
|
|
puttmp('\0',1);
|
|
lastplace = tp-1;
|
|
inswitch = 1;
|
|
return(beg);
|
|
}
|
|
void
|
|
copy(char *s)
|
|
{
|
|
while(*s != '\0')putch(*s++,NO);
|
|
}
|
|
void
|
|
clearif(struct indent *cl)
|
|
{
|
|
int i;
|
|
for(i=0;i<IFLEVEL-1;i++)cl->ifc[i] = 0;
|
|
}
|
|
char
|
|
puttmp(char c, int keep)
|
|
{
|
|
if(tp < &temp[TEMP-120])
|
|
*tp++ = c;
|
|
else {
|
|
if(keep){
|
|
if(tp >= &temp[TEMP-1]){
|
|
fprint(2,"can't look past huge comment - quiting\n");
|
|
exits("boom");
|
|
}
|
|
*tp++ = c;
|
|
}
|
|
else if(err == 0){
|
|
err++;
|
|
fprint(2,"truncating long comment\n");
|
|
}
|
|
}
|
|
return(c);
|
|
}
|
|
void
|
|
error(char *s)
|
|
{
|
|
fprint(2,"saw EOF while looking for %s\n",s);
|
|
exits("boom");
|
|
}
|