/* roff.c, macro processing */ #include "nroff.h" extern char extrabuf[]; /* define a macro */ setmdef(buf, cmd) char *buf; { struct source *mp; char name[2]; char *ttl; struct cm *getcmd(); struct cm *cp; int l; if(*buf == '\0') return; for(ttl = name ; *buf && *buf != ' ';buf++) if(ttl < name + 2) *ttl++ = *buf; if(ttl == name + 1) name[1] = '\0'; for(mp = macros ; mp ; mp = mp->m_next) if(mp->m_name[0] == name[0] && mp->m_name[1] == name[1]) break; if(mp == 0){ /* not found */ mp = (struct source *)mymalloc(sizeof(struct source), TRUE); mp->m_name[0] = name[0]; mp->m_name[1] = name[1]; mp->m_next = macros; macros = mp; } /* redefining an old one (appending ) */ if(cmd != AM){ if(mp->m_val) myfree(mp->m_val); mp->m_val = 0; } if(mp->m_val == 0){ mp->m_val = mymalloc(LINESIZE+1, FALSE); mp->m_eptr = mp->m_val + LINESIZE; mp->m_curp = mp->m_val; } else { l = strlen(mp->m_val); ttl = mymalloc(l + LINESIZE + 1, FALSE); strcpy(ttl, mp->m_val); myfree(mp->m_val); mp->m_val = ttl; mp->m_curp = mp->m_val + l; mp->m_eptr = mp->m_curp + LINESIZE; } mp->m_last = curdiv; curdiv = mp; while(ngets(extrabuf, TRUE)){ if(CMD(extrabuf[0])){ cp = getcmd(extrabuf); if(cp != 0) /* unknown command */ if(cp->sev == EN) /* finish definition */ break; } /* must add to macro definition */ for(ttl = extrabuf ; *ttl ; ttl++) PUT(*ttl); PUTNL(); } *mp->m_curp = '\0'; curdiv = mp->m_last; mp->m_last = 0; } setmargs(mp, buf) struct source *mp; char *buf; { int i; int c; char *ttl; /* first free all old arguments (if any) */ 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; /* reset current args */ for(;;mp->m_nargs++){ /* now collect arguments */ while(*buf == ' ') buf++; if(*buf == '\0') break; if(*buf == '"') c = *buf++; else c = ' '; ttl = buf; while(*buf != '\0' && *buf != c) buf++; if(*buf == c) *buf++ = '\0'; c = strlen(ttl); mp->m_args[mp->m_nargs] = mymalloc(c+1, FALSE); strcpy(mp->m_args[mp->m_nargs], ttl); } } setsource(buf) char *buf; { FILE *fp; struct source *mp; char *ttl; int c; if(*buf == '\0') return; if(*buf == '"') c = *buf++; else c = ' '; ttl = buf; while(*buf && *buf != c) buf++; *buf = '\0'; /* * now check current so level */ if(nsources++ >= MAXSOURCE){ fprintf(stderr, "Out of .so stack space\n"); exit(1); } if( (fp = fopen(ttl, "r")) == NULL){ fprintf(stderr, "Cannot open .so '%s'\n", ttl); exit(2); } mp = (struct source *)mymalloc(sizeof(struct source), TRUE); mp->m_val = mymalloc(LINESIZE+1, TRUE); mp->m_curp = mp->m_val; mp->m_fp = fp; mp->m_last = curmacro; curmacro = mp; } /* call the end macro */ doemacro(name) char *name; { struct source *mp; for(mp = macros ; mp ; mp = mp->m_next) if(mp->m_name[0] == name[0] && mp->m_name[1] == name[1]) break; if(mp == 0) /* not found */ return; mp->m_last = curmacro; curmacro = mp; mp->m_curp = mp->m_val; }