/* roff.c, when processing */ #include "nroff.h" setwhen(buf) char *buf; { char name[2]; char *ttl; int pos; struct when *wp; int fbot; struct when *xwp; pos = eval(&buf); while(*buf == ' ') buf++; if(*buf == '\0'){ /* delete when on this line */ if(pos < 0) /* pos is relative to bottom */ pos = pos - bottom; for(wp = whens ; wp ; wp = wp->w_next) if(wp->w_lno == pos) break; if(wp == 0) /* no when on this line */ return; if(wp == whens) whens = wp->w_next; else { xwp = whens; for(; xwp->w_next != wp ; xwp = xwp->w_next); xwp->w_next = wp->w_next; } myfree( (char *)wp); return; } ttl = name; for(;*buf && *buf != ' '; buf++) if(ttl < name + 2) *ttl++ = *buf; if(ttl == name + 1) *ttl = '\0'; wp = (struct when *)mymalloc(sizeof(struct when), TRUE); wp->w_next = whens; whens = wp; wp->w_name[0] = name[0]; wp->w_name[1] = name[1]; wp->w_lno = pos; } /* change the position of the when signal */ chwhen(buf) char *buf; { char name[2]; char *ttl; struct when *wp; struct when *xwp; if(*buf == '\0') /* no name !! */ return; ttl = name; for(;*buf && *buf != ' '; buf++) if(ttl < name + 2) *ttl++ = *buf; if(ttl == name + 1) *ttl = '\0'; for(wp = whens ; wp ; wp = wp->w_next) if(wp->w_name[0] == name[0] && wp->w_name[1] == name[1]) break; if(wp == 0) /* not found */ return; while(*buf == ' ') buf++; /* * first zap old when value */ if(wp == whens) whens = wp->w_next; else { for(xwp = whens ; xwp->w_next != wp ; xwp = xwp->w_next); xwp->w_next = wp->w_next; } if(*buf == '\0'){ /* no value delete */ myfree((char *)wp); return; } wp->w_lno = eval(&buf); wp->w_next = whens; whens = wp; } spring(lno) { char name[2]; struct source *mp; int i; int cmd; struct when *wp; int fbot = lno - bottom; /* negative value to the bottom */ for(wp = whens ; wp ; wp = wp->w_next) if(wp->w_lno == lno || (wp->w_lno < 0 && wp->w_lno == fbot)) break; if(wp == 0) /* no when on this line */ return(0); for(mp = macros ; mp ; mp = mp->m_next) if(wp->w_name[0] == mp->m_name[0] && wp->w_name[1] == mp->m_name[1]) break; if(mp == 0) /* macro not found */ return(sprcmd(wp->w_name)); if(mp->m_last != 0) /* got a macro which has sprung already */ return(0); mp->m_last = curmacro; /* invoke the macro */ curmacro = mp; curmacro->m_curp = mp->m_val; for(i = 0 ; i < mp->m_nargs ; i++) if(mp->m_args[i] != 0){ myfree(mp->m_args[i]); mp->m_args[i] = 0; } mp->m_nargs = 0; return(1); } /* * is this a command that has to be sprung ?? */ sprcmd(name) char *name; { struct cm *cp; struct source *mp; char *p; for(cp = cmd ; cp->se ; cp++) if(cp->se[0] == *name && cp->se[1] == name[1]) break; if(cp->se == 0) /* not a command */ return(0); /* hand craft !! */ mp = (struct source *)mymalloc(sizeof(struct source), TRUE); mp->m_val = mymalloc(1+2+1+1, FALSE); /* .bp\n\0 */ mp->m_curp = mp->m_val; p = mp->m_val; *p++ = cmdchar1; /* horrible !! */ *p++ = cp->se[0]; if(*p = cp->se[1]) p++; *p++ = '\n'; *p = 0; mp->m_last = curmacro; curmacro = mp; return(1); } /* * little function to find out where the next trap is after * a lineno, if no when is found then value is to end of page * in a diversion, value is huge */ towhen(lno) { struct when *wp; int lowbound; int val; int fbot; lowbound = bottom; /* also works for diversions */ fbot = lno - bottom; /* negative to the bottom */ for(wp = whens ; wp ; wp = wp->w_next){ if(wp->w_lno >= 0){ if(lno <= wp->w_lno){ if(wp->w_lno < lowbound) lowbound = wp->w_lno; } } else if(fbot <= wp->w_lno){ if(bottom + wp->w_lno < lowbound) lowbound = bottom + wp->w_lno; } } return(lowbound - lno); }