/* roff.c, conditional processing */ #include "nroff.h" /* conditional processing */ /* if processing */ #define MAXCOND 10 /* place to save last condition */ char curcond[MAXCOND]; int curcptr; cond(buf, cmd) char *buf; { int val = 0; int condi = TRUE; if(*buf == '!'){ buf++; condi = FALSE; } if(*buf == '\"' || *buf == '\'') val = stricmp(&buf); else switch(*buf){ case 'o': if(curpage & ODD) val = 1; buf++; break; case 'e': if( (curpage & ODD) == 0) val = 1; buf++; break; case 't': case 'n': /* neither leave as zero always */ buf++; break; default: val = eval(&buf); break; } val = (val > 0); /* get condition right */ if(!condi) val = !val; while(*buf == ' ') buf++; if(*buf == '\0') return; if(cmd == EI){ if(curcptr >= MAXCOND){ fprintf(stderr, "Condition stack overflow\n"); exit(5); } curcond[curcptr++] = val; } iskip(buf, val); } iskip(buf, val) char *buf; { int level; int c; while(*buf == ' ') buf++; if(*buf == '\0') return; if(val){ /* condition is true */ if(*buf == echar && buf[1] == '{'){ /* multipart text here */ /* * must shove this stuff into a diversion * until it gets to the current point */ redirect(buf+2); return; } /* shame this can't be redirected !! */ strcpy(inbuf, buf); /* cheat badly !!!!! */ if(CMD(inbuf[0])) command(inbuf); else text(inbuf); return; } /* condition fails */ if(*buf == echar && buf[1] == '{'){ buf += 2; /* multi line stuff !! */ level = 0; while(*buf){ if(*buf == echar){ buf++; if(*buf == '{') level++; else if(*buf == '}') if(--level < 0) return; } buf++; } while( (c = getm()) != EOF) if(c == echar){ if((c = getm()) == EOF) return; if(c == '{') level++; else if(c == '}') if(--level < 0) return; } } } /* * read input and put onto a diversion so that it can then be put * back onto the input !! it works !! */ redirect(buf) char *buf; { int level = 0; int c; struct source *mp; /* going for a redirect !! */ mp = (struct source *)mymalloc(sizeof(struct source), TRUE); mp->m_val = mymalloc(LINESIZE+1, FALSE); mp->m_eptr = mp->m_val + LINESIZE; mp->m_curp = mp->m_val; mp->m_last = curdiv; curdiv = mp; for(;c = *buf++;){ if(c == echar){ c = *buf++; if(c == '\0'){ PUT(echar); break; } if(c == '{') level++; else if(c == '}') if(--level < 0) goto got; PUT(echar); } PUT(c); } /* must force out a NL here otherwise we get problems */ PUTNL(); while( (c = getm()) != EOF){ if(c == echar){ if((c = getm()) == EOF){ PUT(echar); break; } if(c == '{') level++; else if(c == '}') if(--level < 0) break; PUT(echar); } PUT(c); } /* now have text read for reinput */ got:; curdiv = mp->m_last; *mp->m_curp = '\0'; /* take off output, put back onto input */ mp->m_last = curmacro; curmacro = mp; mp->m_curp = mp->m_val; } /* else processing */ econd(buf) char *buf; { if(curcptr <= 0) /* .if stack empty */ return; iskip(buf, !curcond[--curcptr]); /* reverse the sense */ } /* if string1 == string2 !! */ stricmp(ptr) char **ptr; { }