19075Srrh #ifndef lint 2*9094Srrh static char sccsid[] = "@(#)deroff.c 4.3 (Berkeley) 82/11/06"; 39075Srrh #endif not lint 49075Srrh 5*9094Srrh #include <stdio.h> 69075Srrh 7*9094Srrh /* 8*9094Srrh * Deroff command -- strip troff, eqn, and Tbl sequences from 9*9094Srrh * a file. Has two flags argument, -w, to cause output one word per line 10*9094Srrh * rather than in the original format. 11*9094Srrh * -mm (or -ms) causes the corresponding macro's to be interpreted 12*9094Srrh * so that just sentences are output 13*9094Srrh * -ml also gets rid of lists. 14*9094Srrh * Deroff follows .so and .nx commands, removes contents of macro 15*9094Srrh * definitions, equations (both .EQ ... .EN and $...$), 16*9094Srrh * Tbl command sequences, and Troff backslash constructions. 17*9094Srrh * 18*9094Srrh * All input is through the Cget macro; 19*9094Srrh * the most recently read character is in c. 20*9094Srrh * 21*9094Srrh * Modified by Robert Henry to process -me and -man macros. 22*9094Srrh */ 239075Srrh 24*9094Srrh #define Cget ( (c=getc(infile)) == EOF ? eof() : ((c==ldelim)&&(filesp==files) ? skeqn() : c) ) 25*9094Srrh #define C1get ( (c=getc(infile)) == EOF ? eof() : c) 269075Srrh 27*9094Srrh #ifdef DEBUG 28*9094Srrh # define C _C() 29*9094Srrh # define C1 _C1() 30*9094Srrh #else not DEBUG 31*9094Srrh # define C Cget 32*9094Srrh # define C1 C1get 33*9094Srrh #endif not DEBUG 349075Srrh 359075Srrh #define SKIP while(C != '\n') 369075Srrh #define SKIP_TO_COM SKIP; SKIP; pc=c; while(C != '.' || pc != '\n' || C > 'Z')pc=c 379075Srrh 38*9094Srrh #define YES 1 39*9094Srrh #define NO 0 40*9094Srrh #define MS 0 /* -ms */ 41*9094Srrh #define MM 1 /* -mm */ 42*9094Srrh #define ME 2 /* -me */ 43*9094Srrh #define MA 3 /* -man */ 449075Srrh 45*9094Srrh #ifdef DEBUG 46*9094Srrh char *mactab[] = {"-ms", "-mm", "-me", "-ma"}; 47*9094Srrh #endif DEBUG 48*9094Srrh 49*9094Srrh #define ONE 1 50*9094Srrh #define TWO 2 51*9094Srrh 529075Srrh #define NOCHAR -2 539075Srrh #define SPECIAL 0 549075Srrh #define APOS 1 559079Srrh #define PUNCT 2 569079Srrh #define DIGIT 3 579079Srrh #define LETTER 4 589075Srrh 59*9094Srrh int wordflag; 60*9094Srrh int msflag; /* processing a source written using a mac package */ 61*9094Srrh int mac; /* which package */ 62*9094Srrh int disp; 63*9094Srrh int parag; 64*9094Srrh int inmacro; 65*9094Srrh int intable; 66*9094Srrh int keepblock; /* keep blocks of text; normally false when msflag */ 679075Srrh 689079Srrh char chars[128]; /* SPECIAL, PUNCT, APOS, DIGIT, or LETTER */ 699075Srrh 709075Srrh char line[512]; 719075Srrh char *lp; 729075Srrh 739075Srrh int c; 749075Srrh int pc; 75*9094Srrh int ldelim; 76*9094Srrh int rdelim; 779075Srrh 789075Srrh 799075Srrh int argc; 809075Srrh char **argv; 819075Srrh 829075Srrh char fname[50]; 839075Srrh FILE *files[15]; 849075Srrh FILE **filesp; 859075Srrh FILE *infile; 86*9094Srrh FILE *opn(); 87*9094Srrh /* 88*9094Srrh * Flags for matching conditions other than 89*9094Srrh * the macro name 90*9094Srrh */ 91*9094Srrh #define NONE 0 92*9094Srrh #define FNEST 1 /* no nested files */ 93*9094Srrh #define NOMAC 2 /* no macro */ 94*9094Srrh #define MAC 3 /* macro */ 95*9094Srrh #define PARAG 4 /* in a paragraph */ 96*9094Srrh #define MSF 5 /* msflag is on */ 97*9094Srrh #define NBLK 6 /* set if no blocks to be kept */ 989075Srrh 99*9094Srrh /* 100*9094Srrh * Return codes from macro minions, determine where to jump, 101*9094Srrh * how to repeat/reprocess text 102*9094Srrh */ 103*9094Srrh #define COMX 1 /* goto comx */ 104*9094Srrh #define COM 2 /* goto com */ 105*9094Srrh 1069075Srrh main(ac, av) 1079075Srrh int ac; 1089075Srrh char **av; 1099075Srrh { 1109079Srrh register int i; 111*9094Srrh int errflg = 0; 112*9094Srrh register optchar; 1139079Srrh FILE *opn(); 114*9094Srrh int kflag = NO; 115*9094Srrh char *p; 1169075Srrh 117*9094Srrh wordflag = NO; 118*9094Srrh msflag = NO; 119*9094Srrh mac = ME; 120*9094Srrh disp = NO; 121*9094Srrh parag = NO; 122*9094Srrh inmacro = NO; 123*9094Srrh intable = NO; 124*9094Srrh ldelim = NOCHAR; 125*9094Srrh rdelim = NOCHAR; 126*9094Srrh keepblock = YES; 127*9094Srrh 128*9094Srrh for(argc = ac - 1, argv = av + 1; 129*9094Srrh ( (argc > 0) 130*9094Srrh && (argv[0][0] == '-') 131*9094Srrh && (argv[0][1] != '\0') ); 132*9094Srrh --argc, ++argv 133*9094Srrh ){ 134*9094Srrh for(p = argv[0]+1; *p; ++p) { 135*9094Srrh switch(*p) { 136*9094Srrh case 'p': 137*9094Srrh parag=YES; 138*9094Srrh break; 139*9094Srrh case 'k': 140*9094Srrh kflag = YES; 141*9094Srrh break; 142*9094Srrh case 'w': 143*9094Srrh wordflag = YES; 144*9094Srrh kflag = YES; 145*9094Srrh break; 146*9094Srrh case 'm': 147*9094Srrh msflag = YES; 148*9094Srrh keepblock = NO; 149*9094Srrh switch(p[1]){ 150*9094Srrh case 'm': mac = MM; p++; break; 151*9094Srrh case 's': mac = MS; p++; break; 152*9094Srrh case 'e': mac = ME; p++; break; 153*9094Srrh case 'a': mac = MA; p++; break; 154*9094Srrh case 'l': disp = YES; p++; break; 155*9094Srrh default: errflg++; break; 156*9094Srrh } 157*9094Srrh break; 158*9094Srrh default: 159*9094Srrh errflg++; 160*9094Srrh } 161*9094Srrh } 1629075Srrh } 163*9094Srrh 164*9094Srrh if (kflag) 165*9094Srrh keepblock = YES; 1669079Srrh if (errflg) 167*9094Srrh fatal("usage: deroff [ -w ] [ -k] [ -m (a e m s l) ] [ file ] ... \n", 168*9094Srrh (char *) NULL); 169*9094Srrh 170*9094Srrh #ifdef DEBUG 171*9094Srrh printf("msflag = %d, mac = %s, keepblock = %d, disp = %d\n", 172*9094Srrh msflag, mactab[mac], keepblock, disp); 173*9094Srrh #endif DEBUG 174*9094Srrh if (argc == 0){ 1759079Srrh infile = stdin; 176*9094Srrh } else { 177*9094Srrh infile = opn(argv[0]); 178*9094Srrh --argc; 179*9094Srrh ++argv; 180*9094Srrh } 181*9094Srrh 182*9094Srrh 1839079Srrh files[0] = infile; 1849079Srrh filesp = &files[0]; 1859075Srrh 1869079Srrh for(i='a'; i<='z' ; ++i) 1879079Srrh chars[i] = LETTER; 1889079Srrh for(i='A'; i<='Z'; ++i) 1899079Srrh chars[i] = LETTER; 1909079Srrh for(i='0'; i<='9'; ++i) 1919079Srrh chars[i] = DIGIT; 1929079Srrh chars['\''] = APOS; 1939079Srrh chars['&'] = APOS; 1949079Srrh chars['.'] = PUNCT; 1959079Srrh chars[','] = PUNCT; 1969079Srrh chars[';'] = PUNCT; 1979079Srrh chars['?'] = PUNCT; 1989079Srrh chars[':'] = PUNCT; 1999079Srrh work(); 2009079Srrh } 2019079Srrh char *calloc(); 2029075Srrh 2039075Srrh skeqn() 2049075Srrh { 2059079Srrh while((c = getc(infile)) != rdelim) 2069079Srrh if(c == EOF) 2079079Srrh c = eof(); 2089079Srrh else if(c == '"') 2099079Srrh while( (c = getc(infile)) != '"') 2109079Srrh if(c == EOF) 2119075Srrh c = eof(); 2129079Srrh else if(c == '\\') 2139079Srrh if((c = getc(infile)) == EOF) 2149079Srrh c = eof(); 2159079Srrh if(msflag)return(c='x'); 2169079Srrh return(c = ' '); 2179075Srrh } 2189075Srrh 2199075Srrh FILE *opn(p) 2209075Srrh register char *p; 2219075Srrh { 2229079Srrh FILE *fd; 2239075Srrh 2249079Srrh if( (fd = fopen(p, "r")) == NULL) 2259079Srrh fatal("Cannot open file %s\n", p); 2269075Srrh 2279079Srrh return(fd); 2289075Srrh } 2299075Srrh 2309075Srrh eof() 2319075Srrh { 2329079Srrh if(infile != stdin) 2339079Srrh fclose(infile); 2349079Srrh if(filesp > files) 2359079Srrh infile = *--filesp; 236*9094Srrh else if (argc > 0) { 237*9094Srrh infile = opn(argv[0]); 238*9094Srrh --argc; 239*9094Srrh ++argv; 240*9094Srrh } else 2419079Srrh exit(0); 2429079Srrh return(C); 2439075Srrh } 2449075Srrh 2459075Srrh getfname() 2469075Srrh { 2479079Srrh register char *p; 2489079Srrh struct chain { 2499079Srrh struct chain *nextp; 2509079Srrh char *datap; 2519079Srrh } *chainblock; 2529079Srrh register struct chain *q; 2539079Srrh static struct chain *namechain = NULL; 2549079Srrh char *copys(); 2559075Srrh 2569079Srrh while(C == ' ') ; 2579075Srrh 2589079Srrh for(p = fname ; (*p=c)!= '\n' && c!=' ' && c!='\t' && c!='\\' ; ++p) 2599079Srrh C; 2609079Srrh *p = '\0'; 2619079Srrh while(c != '\n') 2629079Srrh C; 2639075Srrh 2649079Srrh /* see if this name has already been used */ 2659075Srrh 2669079Srrh for(q = namechain ; q; q = q->nextp) 2679079Srrh if( ! strcmp(fname, q->datap)) 2689075Srrh { 2699079Srrh fname[0] = '\0'; 2709079Srrh return; 2719075Srrh } 2729075Srrh 2739079Srrh q = (struct chain *) calloc(1, sizeof(*chainblock)); 2749079Srrh q->nextp = namechain; 2759079Srrh q->datap = copys(fname); 2769079Srrh namechain = q; 2779075Srrh } 2789075Srrh 2799075Srrh fatal(s,p) 2809075Srrh char *s, *p; 2819075Srrh { 2829079Srrh fprintf(stderr, "Deroff: "); 2839079Srrh fprintf(stderr, s, p); 2849079Srrh exit(1); 2859075Srrh } 2869079Srrh 287*9094Srrh /*ARGSUSED*/ 288*9094Srrh textline(str, const) 289*9094Srrh char *str; 290*9094Srrh int const; 291*9094Srrh { 292*9094Srrh if (wordflag) { 293*9094Srrh msputwords(0); 294*9094Srrh return; 295*9094Srrh } 296*9094Srrh puts(str); 297*9094Srrh } 298*9094Srrh 2999075Srrh work() 3009075Srrh { 3019079Srrh for( ;; ) 3029075Srrh { 303*9094Srrh C; 304*9094Srrh #ifdef FULLDEBUG 305*9094Srrh printf("Starting work with `%c'\n", c); 306*9094Srrh #endif FULLDEBUG 307*9094Srrh if(c == '.' || c == '\'') 3089079Srrh comline(); 3099079Srrh else 310*9094Srrh regline(textline, TWO); 3119075Srrh } 3129075Srrh } 3139075Srrh 314*9094Srrh regline(pfunc, const) 315*9094Srrh int (*pfunc)(); 316*9094Srrh int const; 3179075Srrh { 3189079Srrh line[0] = c; 3199079Srrh lp = line; 3209079Srrh for( ; ; ) 3219075Srrh { 322*9094Srrh if(c == '\\') { 3239079Srrh *lp = ' '; 3249079Srrh backsl(); 3259075Srrh } 326*9094Srrh if(c == '\n') 327*9094Srrh break; 328*9094Srrh if(intable && c=='T') { 3299079Srrh *++lp = C; 330*9094Srrh if(c=='{' || c=='}') { 3319079Srrh lp[-1] = ' '; 3329079Srrh *lp = C; 3339075Srrh } 334*9094Srrh } else { 335*9094Srrh *++lp = C; 3369075Srrh } 3379075Srrh } 3389075Srrh 3399079Srrh *lp = '\0'; 3409075Srrh 3419079Srrh if(line[0] != '\0') 342*9094Srrh (*pfunc)(line, const); 3439075Srrh } 3449075Srrh 3459075Srrh macro() 3469075Srrh { 3479079Srrh if(msflag){ 3489079Srrh do { 3499079Srrh SKIP; 3509079Srrh } while(C!='.' || C!='.' || C=='.'); /* look for .. */ 3519079Srrh if(c != '\n')SKIP; 3529079Srrh return; 3539079Srrh } 3549079Srrh SKIP; 3559079Srrh inmacro = YES; 3569075Srrh } 3579075Srrh 3589075Srrh tbl() 3599075Srrh { 3609079Srrh while(C != '.'); 3619079Srrh SKIP; 3629079Srrh intable = YES; 3639075Srrh } 3649075Srrh stbl() 3659075Srrh { 3669079Srrh while(C != '.'); 3679079Srrh SKIP_TO_COM; 3689079Srrh if(c != 'T' || C != 'E'){ 3699079Srrh SKIP; 3709079Srrh pc=c; 3719079Srrh while(C != '.' || pc != '\n' || C != 'T' || C != 'E')pc=c; 3729079Srrh } 3739075Srrh } 3749075Srrh 3759075Srrh eqn() 3769075Srrh { 3779079Srrh register int c1, c2; 3789079Srrh register int dflg; 3799079Srrh char last; 3809075Srrh 3819079Srrh last=0; 3829079Srrh dflg = 1; 3839079Srrh SKIP; 3849075Srrh 3859079Srrh for( ;;) 3869075Srrh { 3879079Srrh if(C1 == '.' || c == '\'') 3889075Srrh { 3899079Srrh while(C1==' ' || c=='\t') 3909079Srrh ; 3919079Srrh if(c=='E' && C1=='N') 3929075Srrh { 3939079Srrh SKIP; 3949079Srrh if(msflag && dflg){ 3959079Srrh putchar('x'); 3969079Srrh putchar(' '); 3979079Srrh if(last){ 3989079Srrh putchar(last); 3999079Srrh putchar('\n'); 4009079Srrh } 4019079Srrh } 4029079Srrh return; 4039075Srrh } 4049075Srrh } 4059079Srrh else if(c == 'd') /* look for delim */ 4069075Srrh { 4079079Srrh if(C1=='e' && C1=='l') 4089079Srrh if( C1=='i' && C1=='m') 4099075Srrh { 4109079Srrh while(C1 == ' '); 4119079Srrh if((c1=c)=='\n' || (c2=C1)=='\n' 4129079Srrh || (c1=='o' && c2=='f' && C1=='f') ) 4139079Srrh { 4149079Srrh ldelim = NOCHAR; 4159079Srrh rdelim = NOCHAR; 4169079Srrh } 4179079Srrh else { 4189079Srrh ldelim = c1; 4199079Srrh rdelim = c2; 4209079Srrh } 4219075Srrh } 4229075Srrh dflg = 0; 4239075Srrh } 4249075Srrh 4259079Srrh if(c != '\n') while(C1 != '\n'){ 4269079Srrh if(chars[c] == PUNCT)last = c; 4279079Srrh else if(c != ' ')last = 0; 4289079Srrh } 4299075Srrh } 4309075Srrh } 4319075Srrh 4329075Srrh backsl() /* skip over a complete backslash construction */ 4339075Srrh { 4349079Srrh int bdelim; 4359075Srrh 4369079Srrh sw: 4379079Srrh switch(C) 4389075Srrh { 4399075Srrh case '"': 4409075Srrh SKIP; 4419075Srrh return; 4429075Srrh case 's': 4439075Srrh if(C == '\\') backsl(); 4449075Srrh else { 4459075Srrh while(C>='0' && c<='9') ; 4469075Srrh ungetc(c,infile); 4479075Srrh c = '0'; 4489079Srrh } 4499075Srrh --lp; 4509075Srrh return; 4519075Srrh 4529075Srrh case 'f': 4539075Srrh case 'n': 4549075Srrh case '*': 4559075Srrh if(C != '(') 4569075Srrh return; 4579075Srrh 4589075Srrh case '(': 4599079Srrh if(msflag){ 4609079Srrh if(C == 'e'){ 4619079Srrh if(C == 'm'){ 4629079Srrh *lp = '-'; 4639079Srrh return; 4649079Srrh } 4659079Srrh } 4669079Srrh else if(c != '\n')C; 4679079Srrh return; 4689079Srrh } 4699075Srrh if(C != '\n') C; 4709075Srrh return; 4719075Srrh 4729075Srrh case '$': 4739075Srrh C; /* discard argument number */ 4749075Srrh return; 4759075Srrh 4769075Srrh case 'b': 4779075Srrh case 'x': 4789075Srrh case 'v': 4799075Srrh case 'h': 4809075Srrh case 'w': 4819075Srrh case 'o': 4829075Srrh case 'l': 4839075Srrh case 'L': 4849075Srrh if( (bdelim=C) == '\n') 4859075Srrh return; 4869075Srrh while(C!='\n' && c!=bdelim) 4879075Srrh if(c == '\\') backsl(); 4889075Srrh return; 4899075Srrh 4909075Srrh case '\\': 4919075Srrh if(inmacro) 4929075Srrh goto sw; 4939075Srrh default: 4949075Srrh return; 4959075Srrh } 4969075Srrh } 4979075Srrh 4989075Srrh char *copys(s) 4999075Srrh register char *s; 5009075Srrh { 5019079Srrh register char *t, *t0; 5029075Srrh 5039079Srrh if( (t0 = t = calloc( (unsigned)(strlen(s)+1), sizeof(*t) ) ) == NULL) 5049079Srrh fatal("Cannot allocate memory", (char *) NULL); 5059075Srrh 5069079Srrh while( *t++ = *s++ ) 5079079Srrh ; 5089079Srrh return(t0); 5099075Srrh } 510*9094Srrh 511*9094Srrh sce() 512*9094Srrh { 5139079Srrh register char *ap; 5149079Srrh register int n, i; 5159079Srrh char a[10]; 5169075Srrh for(ap=a;C != '\n';ap++){ 5179075Srrh *ap = c; 5189075Srrh if(ap == &a[9]){ 5199075Srrh SKIP; 5209075Srrh ap=a; 5219075Srrh break; 5229075Srrh } 5239075Srrh } 5249075Srrh if(ap != a)n = atoi(a); 5259075Srrh else n = 1; 5269075Srrh for(i=0;i<n;){ 5279075Srrh if(C == '.'){ 5289075Srrh if(C == 'c'){ 5299075Srrh if(C == 'e'){ 5309075Srrh while(C == ' '); 5319079Srrh if(c == '0'){ 5329079Srrh SKIP; 5339079Srrh break; 5349079Srrh } 5359075Srrh else SKIP; 5369075Srrh } 5379075Srrh else SKIP; 5389075Srrh } 5399079Srrh else if(c == 'P' || C == 'P'){ 5409079Srrh if(c != '\n')SKIP; 5419079Srrh break; 5429079Srrh } 5439079Srrh else if(c != '\n')SKIP; 5449075Srrh } 5459075Srrh else { 5469075Srrh SKIP; 5479075Srrh i++; 5489075Srrh } 5499075Srrh } 5509075Srrh } 551*9094Srrh 5529079Srrh refer(c1) 5539079Srrh { 5549079Srrh register int c2; 5559079Srrh if(c1 != '\n') 5569079Srrh SKIP; 5579079Srrh while(1){ 5589079Srrh if(C != '.') 5599079Srrh SKIP; 5609079Srrh else { 5619079Srrh if(C != ']') 5629079Srrh SKIP; 5639079Srrh else { 5649079Srrh while(C != '\n') 5659079Srrh c2=c; 5669079Srrh if(chars[c2] == PUNCT)putchar(c2); 5679079Srrh return; 5689079Srrh } 5699079Srrh } 5709079Srrh } 5719079Srrh } 572*9094Srrh 573*9094Srrh inpic() 574*9094Srrh { 5759079Srrh register int c1; 5769079Srrh register char *p1; 5779079Srrh SKIP; 5789079Srrh p1 = line; 5799079Srrh c = '\n'; 5809079Srrh while(1){ 5819079Srrh c1 = c; 5829079Srrh if(C == '.' && c1 == '\n'){ 5839079Srrh if(C != 'P'){ 5849079Srrh if(c == '\n')continue; 5859079Srrh else { SKIP; c='\n'; continue;} 5869079Srrh } 5879079Srrh if(C != 'E'){ 5889079Srrh if(c == '\n')continue; 5899079Srrh else { SKIP; c='\n';continue; } 5909079Srrh } 5919079Srrh SKIP; 5929079Srrh return; 5939079Srrh } 5949079Srrh else if(c == '\"'){ 5959079Srrh while(C != '\"'){ 5969079Srrh if(c == '\\'){ 5979079Srrh if(C == '\"')continue; 5989079Srrh ungetc(c,infile); 5999079Srrh backsl(); 6009079Srrh } 6019079Srrh else *p1++ = c; 6029079Srrh } 6039079Srrh *p1++ = ' '; 6049079Srrh } 6059079Srrh else if(c == '\n' && p1 != line){ 6069079Srrh *p1 = '\0'; 607*9094Srrh if(wordflag)msputwords(NO); 6089079Srrh else { 6099079Srrh puts(line); 6109079Srrh putchar('\n'); 6119079Srrh } 6129079Srrh p1 = line; 6139079Srrh } 6149079Srrh } 6159079Srrh } 616*9094Srrh 617*9094Srrh #ifdef DEBUG 618*9094Srrh _C1() 619*9094Srrh { 620*9094Srrh return(C1get); 621*9094Srrh } 622*9094Srrh _C() 623*9094Srrh { 624*9094Srrh return(Cget); 625*9094Srrh } 626*9094Srrh #endif DEBUG 627*9094Srrh 628*9094Srrh /* 629*9094Srrh * Macro processing 630*9094Srrh * 631*9094Srrh * Macro table definitions 632*9094Srrh */ 633*9094Srrh #define reg register 634*9094Srrh typedef int pacmac; /* compressed macro name */ 635*9094Srrh int argconcat = 0; /* concat arguments together (-me only) */ 636*9094Srrh 637*9094Srrh #define tomac(c1, c2) ((((c1) & 0xFF) << 8) | ((c2) & 0xFF)) 638*9094Srrh #define frommac(src, c1, c2) (((c1)=((src)>>8)&0xFF),((c2) =(src)&0xFF)) 639*9094Srrh 640*9094Srrh struct mactab{ 641*9094Srrh int condition; 642*9094Srrh pacmac macname; 643*9094Srrh int (*func)(); 644*9094Srrh }; 645*9094Srrh struct mactab troffmactab[]; 646*9094Srrh struct mactab ppmactab[]; 647*9094Srrh struct mactab msmactab[]; 648*9094Srrh struct mactab mmmactab[]; 649*9094Srrh struct mactab memactab[]; 650*9094Srrh struct mactab manmactab[]; 651*9094Srrh /* 652*9094Srrh * macro table initialization 653*9094Srrh */ 654*9094Srrh #define M(cond, c1, c2, func) {cond, tomac(c1, c2), func} 655*9094Srrh 656*9094Srrh /* 657*9094Srrh * Put out a macro line, using ms and mm conventions. 658*9094Srrh */ 659*9094Srrh msputmac(s, const) 660*9094Srrh register char *s; 661*9094Srrh int const; 662*9094Srrh { 663*9094Srrh register char *t; 664*9094Srrh register found; 665*9094Srrh int last; 666*9094Srrh found = 0; 667*9094Srrh 668*9094Srrh if (wordflag) { 669*9094Srrh msputwords(YES); 670*9094Srrh return; 671*9094Srrh } 672*9094Srrh while(*s) 673*9094Srrh { 674*9094Srrh while(*s==' ' || *s=='\t') 675*9094Srrh putchar(*s++); 676*9094Srrh for(t = s ; *t!=' ' && *t!='\t' && *t!='\0' ; ++t) 677*9094Srrh ; 678*9094Srrh if(*s == '\"')s++; 679*9094Srrh if(t>s+const && chars[ s[0] ]==LETTER && chars[ s[1] ]==LETTER){ 680*9094Srrh while(s < t) 681*9094Srrh if(*s == '\"')s++; 682*9094Srrh else 683*9094Srrh putchar(*s++); 684*9094Srrh last = *(t-1); 685*9094Srrh found++; 686*9094Srrh } 687*9094Srrh else if(found && chars[ s[0] ] == PUNCT && s[1] == '\0') 688*9094Srrh putchar(*s++); 689*9094Srrh else{ 690*9094Srrh last = *(t-1); 691*9094Srrh s = t; 692*9094Srrh } 693*9094Srrh } 694*9094Srrh putchar('\n'); 695*9094Srrh if(msflag && chars[last] == PUNCT){ 696*9094Srrh putchar(last); 697*9094Srrh putchar('\n'); 698*9094Srrh } 699*9094Srrh } 700*9094Srrh /* 701*9094Srrh * put out words (for the -w option) with ms and mm conventions 702*9094Srrh */ 703*9094Srrh msputwords(macline) 704*9094Srrh int macline; /* is this is a macro line */ 705*9094Srrh { 706*9094Srrh register char *p, *p1; 707*9094Srrh int i, nlet; 708*9094Srrh 709*9094Srrh for(p1 = line ; ;) { 710*9094Srrh /* 711*9094Srrh * skip initial specials ampersands and apostrophes 712*9094Srrh */ 713*9094Srrh while( chars[*p1] < DIGIT) 714*9094Srrh if(*p1++ == '\0') return; 715*9094Srrh nlet = 0; 716*9094Srrh for(p = p1 ; (i=chars[*p]) != SPECIAL ; ++p) 717*9094Srrh if(i == LETTER) ++nlet; 718*9094Srrh 719*9094Srrh if ( (macline && nlet > 1) 720*9094Srrh || (!macline && nlet > 2 721*9094Srrh && chars[p1[0]] == LETTER 722*9094Srrh && chars[p1[1]] == LETTER) ) 723*9094Srrh { 724*9094Srrh /* 725*9094Srrh * delete trailing ampersands and apostrophes 726*9094Srrh */ 727*9094Srrh while( (p[-1]=='\'') 728*9094Srrh || (p[-1]=='&') 729*9094Srrh || (chars[p[-1]] == PUNCT) ){ 730*9094Srrh --p; 731*9094Srrh } 732*9094Srrh while(p1 < p) 733*9094Srrh putchar(*p1++); 734*9094Srrh putchar('\n'); 735*9094Srrh } else { 736*9094Srrh p1 = p; 737*9094Srrh } 738*9094Srrh } 739*9094Srrh } 740*9094Srrh /* 741*9094Srrh * put out a macro using the me conventions 742*9094Srrh */ 743*9094Srrh #define SKIPBLANK(cp) while(*cp == ' ' || *cp == '\t') { cp++; } 744*9094Srrh #define SKIPNONBLANK(cp) while(*cp !=' ' && *cp !='\cp' && *cp !='\0') { cp++; } 745*9094Srrh 746*9094Srrh meputmac(cp, const) 747*9094Srrh reg char *cp; 748*9094Srrh int const; 749*9094Srrh { 750*9094Srrh reg char *np; 751*9094Srrh int found; 752*9094Srrh int argno; 753*9094Srrh int last; 754*9094Srrh int inquote; 755*9094Srrh 756*9094Srrh if (wordflag) { 757*9094Srrh meputwords(YES); 758*9094Srrh return; 759*9094Srrh } 760*9094Srrh for (argno = 0; *cp; argno++){ 761*9094Srrh SKIPBLANK(cp); 762*9094Srrh inquote = (*cp == '"'); 763*9094Srrh if (inquote) 764*9094Srrh cp++; 765*9094Srrh for (np = cp; *np; np++){ 766*9094Srrh switch(*np){ 767*9094Srrh case '\n': 768*9094Srrh case '\0': break; 769*9094Srrh case '\t': 770*9094Srrh case ' ': if (inquote) { 771*9094Srrh continue; 772*9094Srrh } else { 773*9094Srrh goto endarg; 774*9094Srrh } 775*9094Srrh case '"': if(inquote && np[1] == '"'){ 776*9094Srrh strcpy(np, np + 1); 777*9094Srrh np++; 778*9094Srrh continue; 779*9094Srrh } else { 780*9094Srrh *np = ' '; /* bye bye " */ 781*9094Srrh goto endarg; 782*9094Srrh } 783*9094Srrh default: continue; 784*9094Srrh } 785*9094Srrh } 786*9094Srrh endarg: ; 787*9094Srrh /* 788*9094Srrh * cp points at the first char in the arg 789*9094Srrh * np points one beyond the last char in the arg 790*9094Srrh */ 791*9094Srrh if ((argconcat == 0) || (argconcat != argno)) { 792*9094Srrh putchar(' '); 793*9094Srrh } 794*9094Srrh #ifdef FULLDEBUG 795*9094Srrh { 796*9094Srrh char *p; 797*9094Srrh printf("[%d,%d: ", argno, np - cp); 798*9094Srrh for (p = cp; p < np; p++) { 799*9094Srrh putchar(*p); 800*9094Srrh } 801*9094Srrh printf("]"); 802*9094Srrh } 803*9094Srrh #endif FULLDEBUG 804*9094Srrh /* 805*9094Srrh * Determine if the argument merits being printed 806*9094Srrh * 807*9094Srrh * const is the cut off point below which something 808*9094Srrh * is not a word. 809*9094Srrh */ 810*9094Srrh if ( ( (np - cp) > const) 811*9094Srrh && ( inquote 812*9094Srrh || (chars[cp[0]] == LETTER)) ){ 813*9094Srrh for (cp = cp; cp < np; cp++){ 814*9094Srrh putchar(*cp); 815*9094Srrh } 816*9094Srrh last = np[-1]; 817*9094Srrh found++; 818*9094Srrh } else 819*9094Srrh if(found && (np - cp == 1) && chars[*cp] == PUNCT){ 820*9094Srrh putchar(*cp); 821*9094Srrh } else { 822*9094Srrh last = np[-1]; 823*9094Srrh } 824*9094Srrh cp = np; 825*9094Srrh } 826*9094Srrh if(msflag && chars[last] == PUNCT) 827*9094Srrh putchar(last); 828*9094Srrh putchar('\n'); 829*9094Srrh } 830*9094Srrh /* 831*9094Srrh * put out words (for the -w option) with ms and mm conventions 832*9094Srrh */ 833*9094Srrh meputwords(macline) 834*9094Srrh int macline; 835*9094Srrh { 836*9094Srrh msputwords(macline); 837*9094Srrh } 838*9094Srrh /* 839*9094Srrh * 840*9094Srrh * Skip over a nested set of macros 841*9094Srrh * 842*9094Srrh * Possible arguments to noblock are: 843*9094Srrh * 844*9094Srrh * fi end of unfilled text 845*9094Srrh * PE pic ending 846*9094Srrh * DE display ending 847*9094Srrh * 848*9094Srrh * for ms and mm only: 849*9094Srrh * KE keep ending 850*9094Srrh * 851*9094Srrh * NE undocumented match to NS (for mm?) 852*9094Srrh * LE mm only: matches RL or *L (for lists) 853*9094Srrh * 854*9094Srrh * for me: 855*9094Srrh * ([lqbzcdf] 856*9094Srrh */ 857*9094Srrh 858*9094Srrh noblock(a1, a2) 859*9094Srrh char a1, a2; 860*9094Srrh { 861*9094Srrh register int c1,c2; 862*9094Srrh register int eqnf; 863*9094Srrh int lct; 864*9094Srrh lct = 0; 865*9094Srrh eqnf = 1; 866*9094Srrh SKIP; 867*9094Srrh while(1){ 868*9094Srrh while(C != '.') 869*9094Srrh if(c == '\n') 870*9094Srrh continue; 871*9094Srrh else 872*9094Srrh SKIP; 873*9094Srrh if((c1=C) == '\n') 874*9094Srrh continue; 875*9094Srrh if((c2=C) == '\n') 876*9094Srrh continue; 877*9094Srrh if(c1==a1 && c2 == a2){ 878*9094Srrh SKIP; 879*9094Srrh if(lct != 0){ 880*9094Srrh lct--; 881*9094Srrh continue; 882*9094Srrh } 883*9094Srrh if(eqnf) 884*9094Srrh putchar('.'); 885*9094Srrh putchar('\n'); 886*9094Srrh return; 887*9094Srrh } else if(a1 == 'L' && c2 == 'L'){ 888*9094Srrh lct++; 889*9094Srrh SKIP; 890*9094Srrh } 891*9094Srrh /* 892*9094Srrh * equations (EQ) nested within a display 893*9094Srrh */ 894*9094Srrh else if(c1 == 'E' && c2 == 'Q'){ 895*9094Srrh if ( (mac == ME && a1 == ')') 896*9094Srrh || (mac != ME && a1 == 'D') ) { 897*9094Srrh eqn(); 898*9094Srrh eqnf=0; 899*9094Srrh } 900*9094Srrh } 901*9094Srrh /* 902*9094Srrh * turning on filling is done by the paragraphing 903*9094Srrh * macros 904*9094Srrh */ 905*9094Srrh else if(a1 == 'f') { /* .fi */ 906*9094Srrh if ( (mac == ME && (c2 == 'h' || c2 == 'p')) 907*9094Srrh ||(mac != ME && (c1 == 'P' || c2 == 'P')) ) { 908*9094Srrh SKIP; 909*9094Srrh return; 910*9094Srrh } 911*9094Srrh } else { 912*9094Srrh SKIP; 913*9094Srrh } 914*9094Srrh } 915*9094Srrh } 916*9094Srrh 917*9094Srrh EQ() 918*9094Srrh { 919*9094Srrh eqn(); 920*9094Srrh return(0); 921*9094Srrh } 922*9094Srrh domacro() 923*9094Srrh { 924*9094Srrh macro(); 925*9094Srrh return(0); 926*9094Srrh } 927*9094Srrh PS() 928*9094Srrh { 929*9094Srrh if (!msflag) { 930*9094Srrh inpic(); 931*9094Srrh } else { 932*9094Srrh noblock('P', 'E'); 933*9094Srrh } 934*9094Srrh return(0); 935*9094Srrh } 936*9094Srrh 937*9094Srrh skip() 938*9094Srrh { 939*9094Srrh SKIP; 940*9094Srrh return(0); 941*9094Srrh } 942*9094Srrh 943*9094Srrh intbl() 944*9094Srrh { 945*9094Srrh if(msflag){ 946*9094Srrh stbl(); 947*9094Srrh } 948*9094Srrh else tbl(); 949*9094Srrh return(0); 950*9094Srrh } 951*9094Srrh 952*9094Srrh outtbl(){ intable = NO; } 953*9094Srrh 954*9094Srrh so() 955*9094Srrh { 956*9094Srrh getfname(); 957*9094Srrh if( fname[0] ) 958*9094Srrh infile = *++filesp = opn( fname ); 959*9094Srrh return(0); 960*9094Srrh } 961*9094Srrh nx() 962*9094Srrh { 963*9094Srrh getfname(); 964*9094Srrh if(fname[0] == '\0') exit(0); 965*9094Srrh if(infile != stdin) 966*9094Srrh fclose(infile); 967*9094Srrh infile = *filesp = opn(fname); 968*9094Srrh return(0); 969*9094Srrh } 970*9094Srrh skiptocom(){ SKIP_TO_COM; return(COMX); } 971*9094Srrh 972*9094Srrh PP(c12) 973*9094Srrh pacmac c12; 974*9094Srrh { 975*9094Srrh int c1, c2; 976*9094Srrh 977*9094Srrh frommac(c12, c1, c2); 978*9094Srrh printf(".%c%c",c1,c2); 979*9094Srrh while(C != '\n')putchar(c); 980*9094Srrh putchar('\n'); 981*9094Srrh return(0); 982*9094Srrh } 983*9094Srrh AU() 984*9094Srrh { 985*9094Srrh if(mac==MM) { 986*9094Srrh return(0); 987*9094Srrh } else { 988*9094Srrh SKIP_TO_COM; 989*9094Srrh return(COMX); 990*9094Srrh } 991*9094Srrh } 992*9094Srrh 993*9094Srrh SH(c12) 994*9094Srrh pacmac c12; 995*9094Srrh { 996*9094Srrh int c1, c2; 997*9094Srrh 998*9094Srrh frommac(c12, c1, c2); 999*9094Srrh 1000*9094Srrh if(parag){ 1001*9094Srrh printf(".%c%c",c1,c2); 1002*9094Srrh while(C != '\n')putchar(c); 1003*9094Srrh putchar(c); 1004*9094Srrh putchar('!'); 1005*9094Srrh while(1){ 1006*9094Srrh while(C != '\n')putchar(c); 1007*9094Srrh putchar('\n'); 1008*9094Srrh if(C == '.') 1009*9094Srrh return(COM); 1010*9094Srrh putchar('!'); 1011*9094Srrh putchar(c); 1012*9094Srrh } 1013*9094Srrh /*NOTREACHED*/ 1014*9094Srrh } else { 1015*9094Srrh SKIP_TO_COM; 1016*9094Srrh return(COMX); 1017*9094Srrh } 1018*9094Srrh } 1019*9094Srrh 1020*9094Srrh UX() 1021*9094Srrh { 1022*9094Srrh if(wordflag) 1023*9094Srrh printf("UNIX\n"); 1024*9094Srrh else 1025*9094Srrh printf("UNIX "); 1026*9094Srrh return(0); 1027*9094Srrh } 1028*9094Srrh 1029*9094Srrh MMHU(c12) 1030*9094Srrh pacmac c12; 1031*9094Srrh { 1032*9094Srrh int c1, c2; 1033*9094Srrh 1034*9094Srrh frommac(c12, c1, c2); 1035*9094Srrh if(parag){ 1036*9094Srrh printf(".%c%c",c1,c2); 1037*9094Srrh while(C != '\n')putchar(c); 1038*9094Srrh putchar('\n'); 1039*9094Srrh } else { 1040*9094Srrh SKIP; 1041*9094Srrh } 1042*9094Srrh return(0); 1043*9094Srrh } 1044*9094Srrh 1045*9094Srrh mesnblock(c12) 1046*9094Srrh pacmac c12; 1047*9094Srrh { 1048*9094Srrh int c1, c2; 1049*9094Srrh 1050*9094Srrh frommac(c12, c1, c2); 1051*9094Srrh noblock(')',c2); 1052*9094Srrh return(0); 1053*9094Srrh } 1054*9094Srrh mssnblock(c12) 1055*9094Srrh pacmac c12; 1056*9094Srrh { 1057*9094Srrh int c1, c2; 1058*9094Srrh 1059*9094Srrh frommac(c12, c1, c2); 1060*9094Srrh noblock(c1,'E'); 1061*9094Srrh return(0); 1062*9094Srrh } 1063*9094Srrh nf() 1064*9094Srrh { 1065*9094Srrh noblock('f','i'); 1066*9094Srrh return(0); 1067*9094Srrh } 1068*9094Srrh 1069*9094Srrh ce() 1070*9094Srrh { 1071*9094Srrh sce(); 1072*9094Srrh return(0); 1073*9094Srrh } 1074*9094Srrh 1075*9094Srrh meip(c12) 1076*9094Srrh pacmac c12; 1077*9094Srrh { 1078*9094Srrh if(parag) 1079*9094Srrh mepp(c12); 1080*9094Srrh else if (wordflag) /* save the tag */ 1081*9094Srrh regline(meputmac, ONE); 1082*9094Srrh else { 1083*9094Srrh SKIP; 1084*9094Srrh } 1085*9094Srrh return(0); 1086*9094Srrh } 1087*9094Srrh /* 1088*9094Srrh * only called for -me .pp or .sh, when parag is on 1089*9094Srrh */ 1090*9094Srrh mepp(c12) 1091*9094Srrh pacmac c12; 1092*9094Srrh { 1093*9094Srrh PP(c12); /* eats the line */ 1094*9094Srrh return(0); 1095*9094Srrh } 1096*9094Srrh /* 1097*9094Srrh * Start of a section heading; output the section name if doing words 1098*9094Srrh */ 1099*9094Srrh mesh(c12) 1100*9094Srrh pacmac c12; 1101*9094Srrh { 1102*9094Srrh if (parag) 1103*9094Srrh mepp(c12); 1104*9094Srrh else if (wordflag) 1105*9094Srrh defcomline(c12); 1106*9094Srrh else { 1107*9094Srrh SKIP; 1108*9094Srrh } 1109*9094Srrh return(0); 1110*9094Srrh } 1111*9094Srrh /* 1112*9094Srrh * process a font setting 1113*9094Srrh */ 1114*9094Srrh mefont(c12) 1115*9094Srrh pacmac c12; 1116*9094Srrh { 1117*9094Srrh argconcat = 1; 1118*9094Srrh defcomline(c12); 1119*9094Srrh argconcat = 0; 1120*9094Srrh return(0); 1121*9094Srrh } 1122*9094Srrh manfont(c12) 1123*9094Srrh pacmac c12; 1124*9094Srrh { 1125*9094Srrh return(mefont(c12)); 1126*9094Srrh } 1127*9094Srrh manpp(c12) 1128*9094Srrh pacmac c12; 1129*9094Srrh { 1130*9094Srrh return(mepp(c12)); 1131*9094Srrh } 1132*9094Srrh 1133*9094Srrh defcomline(c12) 1134*9094Srrh pacmac c12; 1135*9094Srrh { 1136*9094Srrh int c1, c2; 1137*9094Srrh 1138*9094Srrh frommac(c12, c1, c2); 1139*9094Srrh if(msflag && mac==MM && c2=='L'){ 1140*9094Srrh if(disp || c1 == 'R') { 1141*9094Srrh noblock('L','E'); 1142*9094Srrh } else { 1143*9094Srrh SKIP; 1144*9094Srrh putchar('.'); 1145*9094Srrh } 1146*9094Srrh } 1147*9094Srrh else if(c1=='.' && c2=='.'){ 1148*9094Srrh if(msflag){ 1149*9094Srrh SKIP; 1150*9094Srrh return; 1151*9094Srrh } 1152*9094Srrh while(C == '.') 1153*9094Srrh /*VOID*/; 1154*9094Srrh } 1155*9094Srrh ++inmacro; 1156*9094Srrh /* 1157*9094Srrh * Process the arguments to the macro 1158*9094Srrh */ 1159*9094Srrh switch(mac){ 1160*9094Srrh default: 1161*9094Srrh case MM: 1162*9094Srrh case MS: 1163*9094Srrh if(c1 <= 'Z' && msflag) 1164*9094Srrh regline(msputmac, ONE); 1165*9094Srrh else 1166*9094Srrh regline(msputmac, TWO); 1167*9094Srrh break; 1168*9094Srrh case ME: 1169*9094Srrh regline(meputmac, ONE); 1170*9094Srrh break; 1171*9094Srrh } 1172*9094Srrh --inmacro; 1173*9094Srrh } 1174*9094Srrh 1175*9094Srrh comline() 1176*9094Srrh { 1177*9094Srrh reg int c1; 1178*9094Srrh reg int c2; 1179*9094Srrh pacmac c12; 1180*9094Srrh reg int mid; 1181*9094Srrh int lb, ub; 1182*9094Srrh int hit; 1183*9094Srrh static int tabsize = 0; 1184*9094Srrh static struct mactab *mactab = (struct mactab *)0; 1185*9094Srrh reg struct mactab *mp; 1186*9094Srrh 1187*9094Srrh if (mactab == 0){ 1188*9094Srrh buildtab(&mactab, &tabsize); 1189*9094Srrh } 1190*9094Srrh com: 1191*9094Srrh while(C==' ' || c=='\t') 1192*9094Srrh ; 1193*9094Srrh comx: 1194*9094Srrh if( (c1=c) == '\n') 1195*9094Srrh return; 1196*9094Srrh c2 = C; 1197*9094Srrh if(c1=='.' && c2 !='.') 1198*9094Srrh inmacro = NO; 1199*9094Srrh if(msflag && c1 == '['){ 1200*9094Srrh refer(c2); 1201*9094Srrh return; 1202*9094Srrh } 1203*9094Srrh if(parag && mac==MM && c1 == 'P' && c2 == '\n'){ 1204*9094Srrh printf(".P\n"); 1205*9094Srrh return; 1206*9094Srrh } 1207*9094Srrh if(c2 == '\n') 1208*9094Srrh return; 1209*9094Srrh /* 1210*9094Srrh * Single letter macro 1211*9094Srrh */ 1212*9094Srrh if (mac == ME && (c2 == ' ' || c2 == '\t') ) 1213*9094Srrh c2 = ' '; 1214*9094Srrh c12 = tomac(c1, c2); 1215*9094Srrh /* 1216*9094Srrh * binary search through the table of macros 1217*9094Srrh */ 1218*9094Srrh lb = 0; 1219*9094Srrh ub = tabsize - 1; 1220*9094Srrh while(lb <= ub){ 1221*9094Srrh mid = (ub + lb) / 2; 1222*9094Srrh mp = &mactab[mid]; 1223*9094Srrh if (mp->macname < c12) 1224*9094Srrh lb = mid + 1; 1225*9094Srrh else if (mp->macname > c12) 1226*9094Srrh ub = mid - 1; 1227*9094Srrh else { 1228*9094Srrh hit = 1; 1229*9094Srrh #ifdef FULLDEBUG 1230*9094Srrh printf("preliminary hit macro %c%c ", c1, c2); 1231*9094Srrh #endif FULLDEBUG 1232*9094Srrh switch(mp->condition){ 1233*9094Srrh case NONE: hit = YES; break; 1234*9094Srrh case FNEST: hit = (filesp == files); break; 1235*9094Srrh case NOMAC: hit = !inmacro; break; 1236*9094Srrh case MAC: hit = inmacro; break; 1237*9094Srrh case PARAG: hit = parag; break; 1238*9094Srrh case NBLK: hit = !keepblock; break; 1239*9094Srrh default: hit = 0; 1240*9094Srrh } 1241*9094Srrh if (hit) { 1242*9094Srrh #ifdef FULLDEBUG 1243*9094Srrh printf("MATCH\n"); 1244*9094Srrh #endif FULLDEBUG 1245*9094Srrh switch( (*(mp->func))(c12) ) { 1246*9094Srrh default: return; 1247*9094Srrh case COMX: goto comx; 1248*9094Srrh case COM: goto com; 1249*9094Srrh } 1250*9094Srrh } 1251*9094Srrh #ifdef FULLDEBUG 1252*9094Srrh printf("FAIL\n"); 1253*9094Srrh #endif FULLDEBUG 1254*9094Srrh break; 1255*9094Srrh } 1256*9094Srrh } 1257*9094Srrh defcomline(c12); 1258*9094Srrh } 1259*9094Srrh 1260*9094Srrh int macsort(p1, p2) 1261*9094Srrh struct mactab *p1, *p2; 1262*9094Srrh { 1263*9094Srrh return(p1->macname - p2->macname); 1264*9094Srrh } 1265*9094Srrh 1266*9094Srrh int sizetab(mp) 1267*9094Srrh reg struct mactab *mp; 1268*9094Srrh { 1269*9094Srrh reg int i; 1270*9094Srrh i = 0; 1271*9094Srrh if (mp){ 1272*9094Srrh for (; mp->macname; mp++, i++) 1273*9094Srrh /*VOID*/ ; 1274*9094Srrh } 1275*9094Srrh return(i); 1276*9094Srrh } 1277*9094Srrh 1278*9094Srrh struct mactab *macfill(dst, src) 1279*9094Srrh reg struct mactab *dst; 1280*9094Srrh reg struct mactab *src; 1281*9094Srrh { 1282*9094Srrh if (src) { 1283*9094Srrh while(src->macname){ 1284*9094Srrh *dst++ = *src++; 1285*9094Srrh } 1286*9094Srrh } 1287*9094Srrh return(dst); 1288*9094Srrh } 1289*9094Srrh 1290*9094Srrh buildtab(r_back, r_size) 1291*9094Srrh struct mactab **r_back; 1292*9094Srrh int *r_size; 1293*9094Srrh { 1294*9094Srrh int size; 1295*9094Srrh 1296*9094Srrh struct mactab *p, *p1, *p2; 1297*9094Srrh struct mactab *back; 1298*9094Srrh 1299*9094Srrh size = sizetab(troffmactab); 1300*9094Srrh size += sizetab(ppmactab); 1301*9094Srrh p1 = p2 = (struct mactab *)0; 1302*9094Srrh if (msflag){ 1303*9094Srrh switch(mac){ 1304*9094Srrh case ME: p1 = memactab; break; 1305*9094Srrh case MM: p1 = msmactab; 1306*9094Srrh p2 = mmmactab; break; 1307*9094Srrh 1308*9094Srrh case MS: p1 = msmactab; break; 1309*9094Srrh case MA: p1 = manmactab; break; 1310*9094Srrh default: break; 1311*9094Srrh } 1312*9094Srrh } 1313*9094Srrh size += sizetab(p1); 1314*9094Srrh size += sizetab(p2); 1315*9094Srrh back = (struct mactab *)calloc(size+2, sizeof(struct mactab)); 1316*9094Srrh 1317*9094Srrh p = macfill(back, troffmactab); 1318*9094Srrh p = macfill(p, ppmactab); 1319*9094Srrh p = macfill(p, p1); 1320*9094Srrh p = macfill(p, p2); 1321*9094Srrh 1322*9094Srrh qsort(back, size, sizeof(struct mactab), macsort); 1323*9094Srrh *r_size = size; 1324*9094Srrh *r_back = back; 1325*9094Srrh } 1326*9094Srrh 1327*9094Srrh /* 1328*9094Srrh * troff commands 1329*9094Srrh */ 1330*9094Srrh struct mactab troffmactab[] = { 1331*9094Srrh M(NONE, '\\','"', skip), /* comment */ 1332*9094Srrh M(NOMAC, 'd','e', domacro), /* define */ 1333*9094Srrh M(NOMAC, 'i','g', domacro), /* ignore till .. */ 1334*9094Srrh M(NOMAC, 'a','m', domacro), /* append macro */ 1335*9094Srrh M(NBLK, 'n','f', nf), /* filled */ 1336*9094Srrh M(NBLK, 'c','e', ce), /* centered */ 1337*9094Srrh 1338*9094Srrh M(NONE, 's','o', so), /* source a file */ 1339*9094Srrh M(NONE, 'n','x', nx), /* go to next file */ 1340*9094Srrh 1341*9094Srrh M(NONE, 't','m', skip), /* print string on tty */ 1342*9094Srrh M(NONE, 'h','w', skip), /* exception hyphen words */ 1343*9094Srrh M(NONE, 0,0, 0) 1344*9094Srrh }; 1345*9094Srrh /* 1346*9094Srrh * Preprocessor output 1347*9094Srrh */ 1348*9094Srrh struct mactab ppmactab[] = { 1349*9094Srrh M(FNEST, 'E','Q', EQ), /* equation starting */ 1350*9094Srrh M(FNEST, 'T','S', intbl), /* table starting */ 1351*9094Srrh M(FNEST, 'T','C', intbl), /* alternative table? */ 1352*9094Srrh M(FNEST, 'T','&', intbl), /* table reformatting */ 1353*9094Srrh M(NONE, 'T','E', outtbl),/* table ending */ 1354*9094Srrh M(NONE, 'P','S', PS), /* picture starting */ 1355*9094Srrh M(NONE, 0,0, 0) 1356*9094Srrh }; 1357*9094Srrh /* 1358*9094Srrh * Particular to ms and mm 1359*9094Srrh */ 1360*9094Srrh struct mactab msmactab[] = { 1361*9094Srrh M(NONE, 'T','L', skiptocom), /* title follows */ 1362*9094Srrh M(NONE, 'F','S', skiptocom), /* start footnote */ 1363*9094Srrh M(NONE, 'O','K', skiptocom), /* Other kws */ 1364*9094Srrh 1365*9094Srrh M(NONE, 'N','R', skip), /* undocumented */ 1366*9094Srrh M(NONE, 'N','D', skip), /* use supplied date */ 1367*9094Srrh 1368*9094Srrh M(PARAG, 'P','P', PP), /* begin parag */ 1369*9094Srrh M(PARAG, 'I','P', PP), /* begin indent parag, tag x */ 1370*9094Srrh M(PARAG, 'L','P', PP), /* left blocked parag */ 1371*9094Srrh 1372*9094Srrh M(NONE, 'A','U', AU), /* author */ 1373*9094Srrh M(NONE, 'A','I', AU), /* authors institution */ 1374*9094Srrh 1375*9094Srrh M(NONE, 'S','H', SH), /* section heading */ 1376*9094Srrh M(NONE, 'S','N', SH), /* undocumented */ 1377*9094Srrh M(NONE, 'U','X', UX), /* unix */ 1378*9094Srrh 1379*9094Srrh M(NBLK, 'D','S', mssnblock), /* start display text */ 1380*9094Srrh M(NBLK, 'K','S', mssnblock), /* start keep */ 1381*9094Srrh M(NBLK, 'K','F', mssnblock), /* start float keep */ 1382*9094Srrh M(NONE, 0,0, 0) 1383*9094Srrh }; 1384*9094Srrh 1385*9094Srrh struct mactab mmmactab[] = { 1386*9094Srrh M(NONE, 'H',' ', MMHU), /* -mm ? */ 1387*9094Srrh M(NONE, 'H','U', MMHU), /* -mm ? */ 1388*9094Srrh M(PARAG, 'P',' ', PP), /* paragraph for -mm */ 1389*9094Srrh M(NBLK, 'N','S', mssnblock), /* undocumented */ 1390*9094Srrh M(NONE, 0,0, 0) 1391*9094Srrh }; 1392*9094Srrh 1393*9094Srrh struct mactab memactab[] = { 1394*9094Srrh M(PARAG, 'p','p', mepp), 1395*9094Srrh M(PARAG, 'l','p', mepp), 1396*9094Srrh M(PARAG, 'n','p', mepp), 1397*9094Srrh M(NONE, 'i','p', meip), 1398*9094Srrh 1399*9094Srrh M(NONE, 's','h', mesh), 1400*9094Srrh M(NONE, 'u','h', mesh), 1401*9094Srrh 1402*9094Srrh M(NBLK, '(','l', mesnblock), 1403*9094Srrh M(NBLK, '(','q', mesnblock), 1404*9094Srrh M(NBLK, '(','b', mesnblock), 1405*9094Srrh M(NBLK, '(','z', mesnblock), 1406*9094Srrh M(NBLK, '(','c', mesnblock), 1407*9094Srrh 1408*9094Srrh M(NBLK, '(','d', mesnblock), 1409*9094Srrh M(NBLK, '(','f', mesnblock), 1410*9094Srrh M(NBLK, '(','x', mesnblock), 1411*9094Srrh 1412*9094Srrh M(NONE, 'r',' ', mefont), 1413*9094Srrh M(NONE, 'i',' ', mefont), 1414*9094Srrh M(NONE, 'b',' ', mefont), 1415*9094Srrh M(NONE, 'u',' ', mefont), 1416*9094Srrh M(NONE, 'q',' ', mefont), 1417*9094Srrh M(NONE, 'r','b', mefont), 1418*9094Srrh M(NONE, 'b','i', mefont), 1419*9094Srrh M(NONE, 'b','x', mefont), 1420*9094Srrh M(NONE, 0,0, 0) 1421*9094Srrh }; 1422*9094Srrh 1423*9094Srrh 1424*9094Srrh struct mactab manmactab[] = { 1425*9094Srrh M(PARAG, 'B','I', manfont), 1426*9094Srrh M(PARAG, 'B','R', manfont), 1427*9094Srrh M(PARAG, 'I','B', manfont), 1428*9094Srrh M(PARAG, 'I','R', manfont), 1429*9094Srrh M(PARAG, 'R','B', manfont), 1430*9094Srrh M(PARAG, 'R','I', manfont), 1431*9094Srrh 1432*9094Srrh M(PARAG, 'P','P', manpp), 1433*9094Srrh M(PARAG, 'L','P', manpp), 1434*9094Srrh M(PARAG, 'H','P', manpp), 1435*9094Srrh M(NONE, 0,0, 0) 1436*9094Srrh }; 1437