/* roff.c, system register handling */ #include "nroff.h" struct sreg { char S_name[2]; int *S_val; int (*S_getval)(); int (*S_rsetval)(); }; /* default reset value routine */ defrsval(sp, np) struct sreg *sp; struct nregs *np; { if(sp->S_val) *sp->S_val = np->n_value; } /* default get value routine */ defgval(sp, np) struct sreg *sp; struct nregs *np; { if(sp->S_val) np->n_value = *sp->S_val; else np->n_value = 0; } static Dgval(sp, np) /* number of arguments in current macro */ struct sreg *sp; struct nregs *np; { struct source *mp; for(mp = curmacro ; mp ; mp = mp->m_last) if(mp->m_name[0] != '\0'){ /* it really is a macro */ if(mp->m_type != AMACRO) continue; np->n_value = mp->m_nargs; return; } np->n_value = 0; } static int Arval = 1; /* always 1 in nroff */ static igval(sp, np) struct sreg *sp; struct nregs *np; { np->n_value = tival + inval; } static tgval(sp, np) struct sreg *sp; struct nregs *np; { np->n_value = towhen(lineno); } static zgval(sp, np) struct sreg *sp; struct nregs *np; { struct source *mp; int i; for(i = 0, mp = curdiv ; mp->m_last ; mp = mp->m_last, i++); np->n_value = i; } /* names of all system registers */ struct sreg sysrs[] = { '%', '\0', &curpage,defgval, defrsval, 'c', 't', 0, defgval, defrsval, 'd', 'l', &dlval, defgval, defrsval, 'd', 'n', 0, defgval, defrsval, 'd', 'w', 0, defgval, defrsval, 'd', 'y', 0, defgval, defrsval, 'h', 'p', 0, defgval, defrsval, 'l', 'n', 0, defgval, defrsval, 'm', 'o', 0, defgval, defrsval, 'n', 'l', 0, defgval, defrsval, 's', 'b', 0, defgval, defrsval, 's', 't', 0, defgval, defrsval, 'y', 'r', 0, defgval, defrsval, /* read only regs, if second char is '0', zap and set ro bit */ '$', '0', 0, Dgval, 0, 'A', '0', &Arval, defgval, 0, 'H', '0', 0, defgval, 0, 'T', '0', 0, defgval, 0,/* always zero */ 'V', '0', 0, defgval, 0, 'a', '0', 0, defgval, 0, 'c', '0', 0, defgval, 0, 'd', '0', 0, defgval, 0, 'f', '0', 0, defgval, 0, 'h', '0', 0, defgval, 0, 'i', '0', 0, igval, 0, 'l', '0', &rmval, defgval, 0, 'n', '0', 0, defgval, 0, 'o', '0', 0, defgval, 0, 'p', '0', &plval, defgval, 0, 's', '0', 0, defgval, 0, 't', '0', 0, tgval, 0, 'u', '0', &fill, defgval, 0, 'v', '0', &lsval, defgval, 0, 'w', '0', 0, defgval, 0, 'z', '0', 0, zgval, 0, }; #define SYSSIZ (sizeof(sysrs)/sizeof(sysrs[0])) static struct nregs stype[SYSSIZ]; /* define a new system register, with the normal values */ static newreg(np, name, ro) char *name; struct nregs *np; { np->n_name[0] = name[0]; np->n_name[1] = name[1]; np->n_status = NSYS|ro; np->n_digits = 1; np->n_form = '1'; np->n_next = numregs; numregs = np; } initsvals() /* define and set default values for all registers */ { struct sreg *sp; struct nregs *np; np = stype; for(sp = sysrs ; sp < sysrs + SYSSIZ ; sp++, np++){ if(sp->S_name[1] == '0'){ sp->S_name[1] = '\0'; newreg(np, sp->S_name, NRO); } else newreg(np, sp->S_name, 0); } } getsvals(np) /* set a system wide numeric register */ struct nregs *np; { struct sreg *sp; sp = &sysrs[np - stype]; if(sp->S_getval) (*sp->S_getval)(sp, np); } /* reset a changed system wide numeric register */ rsetsvals(np) struct nregs *np; { struct sreg *sp; sp = &sysrs[np - stype]; if(sp->S_rsetval) (*sp->S_rsetval)(sp, np); }