11841Sroot #include <ctype.h> 21841Sroot #include <stdio.h> 31841Sroot #include <sys/types.h> 41841Sroot #include <sys/stat.h> 51841Sroot 61841Sroot /* 71841Sroot * Vfontedpr. 81841Sroot * 91841Sroot * Bill Joy, Apr. 1979. 10*1862Sroot * (made table driven - Dave Presotto 11/17/80) 11*1862Sroot * 121841Sroot */ 13*1862Sroot #define NOLANG -1 /* indicates no language chosen */ 14*1862Sroot #define C 0 15*1862Sroot #define PASCAL 1 16*1862Sroot #define MODEL 2 17*1862Sroot #define NLANG 3 /* total number of languages */ 18*1862Sroot 19*1862Sroot #define STRLEN 10 /* length of strings introducing things */ 20*1862Sroot #define PNAMELEN 40 /* length of a function/procedure name */ 21*1862Sroot 22*1862Sroot /* routines used by the different languages */ 23*1862Sroot 24*1862Sroot int cprbegin(); 25*1862Sroot int cprend(); 26*1862Sroot int pprbegin(); 27*1862Sroot int pprend(); 28*1862Sroot int mprbegin(); 29*1862Sroot int mprend(); 30*1862Sroot 31*1862Sroot /* keywords for the model language */ 32*1862Sroot 33*1862Sroot char *mkw[] = { 34*1862Sroot "abs", 35*1862Sroot "and", 36*1862Sroot "array", 37*1862Sroot "beginproc", 38*1862Sroot "boolean", 39*1862Sroot "by", 40*1862Sroot "case", 41*1862Sroot "cdnl", 42*1862Sroot "char", 43*1862Sroot "copied", 44*1862Sroot "dispose", 45*1862Sroot "div", 46*1862Sroot "do", 47*1862Sroot "dynamic", 48*1862Sroot "else", 49*1862Sroot "elsif", 50*1862Sroot "end", 51*1862Sroot "endproc", 52*1862Sroot "entry", 53*1862Sroot "external", 54*1862Sroot "f", 55*1862Sroot "FALSE", 56*1862Sroot "false", 57*1862Sroot "fi", 58*1862Sroot "file", 59*1862Sroot "for", 60*1862Sroot "formal", 61*1862Sroot "fortran", 62*1862Sroot "global", 63*1862Sroot "if", 64*1862Sroot "in", 65*1862Sroot "include", 66*1862Sroot "inline", 67*1862Sroot "is", 68*1862Sroot "lbnd", 69*1862Sroot "max", 70*1862Sroot "min", 71*1862Sroot "mod", 72*1862Sroot "new", 73*1862Sroot "NIL", 74*1862Sroot "nil", 75*1862Sroot "noresult", 76*1862Sroot "not", 77*1862Sroot "notin", 78*1862Sroot "od", 79*1862Sroot "of", 80*1862Sroot "or", 81*1862Sroot "procedure", 82*1862Sroot "public", 83*1862Sroot "read", 84*1862Sroot "readln", 85*1862Sroot "readonly", 86*1862Sroot "record", 87*1862Sroot "recursive", 88*1862Sroot "rem", 89*1862Sroot "rep", 90*1862Sroot "repeat", 91*1862Sroot "result", 92*1862Sroot "return", 93*1862Sroot "set", 94*1862Sroot "space", 95*1862Sroot "string", 96*1862Sroot "subscript", 97*1862Sroot "such", 98*1862Sroot "then", 99*1862Sroot "TRUE", 100*1862Sroot "true", 101*1862Sroot "type", 102*1862Sroot "ubnd", 103*1862Sroot "union", 104*1862Sroot "until", 105*1862Sroot "varies", 106*1862Sroot "while", 107*1862Sroot "width", 108*1862Sroot "write", 109*1862Sroot "writeln", 110*1862Sroot 0, 111*1862Sroot }; 112*1862Sroot 113*1862Sroot /* keywords for the pascal language */ 114*1862Sroot 115*1862Sroot char *pkw[] = { 116*1862Sroot "and", 117*1862Sroot "array", 118*1862Sroot "assert", 119*1862Sroot "begin", 120*1862Sroot "case", 121*1862Sroot "const", 122*1862Sroot "div", 123*1862Sroot "do", 124*1862Sroot "downto", 125*1862Sroot "else", 126*1862Sroot "end", 127*1862Sroot "file", 128*1862Sroot "for", 129*1862Sroot "forward", 130*1862Sroot "function", 131*1862Sroot "goto", 132*1862Sroot "if", 133*1862Sroot "in", 134*1862Sroot "label", 135*1862Sroot "mod", 136*1862Sroot "nil", 137*1862Sroot "not", 138*1862Sroot "of", 139*1862Sroot "or", 140*1862Sroot "packed", 141*1862Sroot "procedure", 142*1862Sroot "program", 143*1862Sroot "record", 144*1862Sroot "repeat", 145*1862Sroot "set", 146*1862Sroot "then", 147*1862Sroot "to", 148*1862Sroot "type", 149*1862Sroot "until", 150*1862Sroot "var", 151*1862Sroot "while", 152*1862Sroot "with", 153*1862Sroot "oct", 154*1862Sroot "hex", 155*1862Sroot "external", 156*1862Sroot 0, 157*1862Sroot }; 158*1862Sroot 159*1862Sroot /* keywords for the C language */ 160*1862Sroot 161*1862Sroot char *ckw[] = { 162*1862Sroot "asm", 163*1862Sroot "auto", 164*1862Sroot "break", 165*1862Sroot "case", 166*1862Sroot "char", 167*1862Sroot "continue", 168*1862Sroot "default", 169*1862Sroot "do", 170*1862Sroot "double", 171*1862Sroot "else", 172*1862Sroot "enum", 173*1862Sroot "extern", 174*1862Sroot "float", 175*1862Sroot "for", 176*1862Sroot "fortran", 177*1862Sroot "goto", 178*1862Sroot "if", 179*1862Sroot "int", 180*1862Sroot "long", 181*1862Sroot "register", 182*1862Sroot "return", 183*1862Sroot "short", 184*1862Sroot "sizeof", 185*1862Sroot "static", 186*1862Sroot "struct", 187*1862Sroot "switch", 188*1862Sroot "typedef", 189*1862Sroot "union", 190*1862Sroot "unsigned", 191*1862Sroot "while", 192*1862Sroot "#define", 193*1862Sroot "#else", 194*1862Sroot "#endif", 195*1862Sroot "#if", 196*1862Sroot "#ifdef", 197*1862Sroot "#ifndef", 198*1862Sroot "#include", 199*1862Sroot "#undef", 200*1862Sroot "#", 201*1862Sroot "define", 202*1862Sroot "else", 203*1862Sroot "endif", 204*1862Sroot "if", 205*1862Sroot "ifdef", 206*1862Sroot "ifndef", 207*1862Sroot "include", 208*1862Sroot "undef", 209*1862Sroot 0, 210*1862Sroot }; 211*1862Sroot 212*1862Sroot /* 213*1862Sroot * the following structure defines a language 214*1862Sroot */ 215*1862Sroot 216*1862Sroot struct langdef { 217*1862Sroot char *option; /* its option switch */ 218*1862Sroot char **kwd; /* address of its keyword table */ 219*1862Sroot int (*isproc)(); /* test for procedure begin */ 220*1862Sroot int (*ispend)(); /* test for procedure end */ 221*1862Sroot char *combeg; /* string introducing a comment */ 222*1862Sroot char *comend; /* string ending a comment */ 223*1862Sroot char *comout; /* string output in place of combeg string */ 224*1862Sroot char strdel; /* delimiter for string constant */ 225*1862Sroot char chrdel; /* delimiter for character constant */ 226*1862Sroot int onelncom; /* comments do not continue on next line */ 227*1862Sroot int onelnstr; /* string constants do not continue on next */ 228*1862Sroot }; 229*1862Sroot 230*1862Sroot struct langdef ld[] = { 231*1862Sroot /* the C language */ 232*1862Sroot "-c", 233*1862Sroot ckw, 234*1862Sroot cprbegin, 235*1862Sroot cprend, 236*1862Sroot "/*", 237*1862Sroot "*/", 238*1862Sroot "\\*(/*", 239*1862Sroot '"', 240*1862Sroot '\'', 241*1862Sroot 0, 242*1862Sroot 0, 243*1862Sroot 244*1862Sroot /* the pascal language */ 245*1862Sroot "-p", 246*1862Sroot pkw, 247*1862Sroot pprbegin, 248*1862Sroot pprend, 249*1862Sroot "{", 250*1862Sroot "}", 251*1862Sroot "{", 252*1862Sroot '\'', 253*1862Sroot 0, 254*1862Sroot 0, 255*1862Sroot 0, 256*1862Sroot 257*1862Sroot /* the model language */ 258*1862Sroot "-m", 259*1862Sroot mkw, 260*1862Sroot mprbegin, 261*1862Sroot mprend, 262*1862Sroot "$", 263*1862Sroot "$", 264*1862Sroot "$", 265*1862Sroot '"', 266*1862Sroot '\'', 267*1862Sroot 1, 268*1862Sroot 0 269*1862Sroot }; 270*1862Sroot 2711841Sroot char *ctime(); 2721841Sroot int incomm; 2731841Sroot int instr; 2741841Sroot int nokeyw; 2751841Sroot int index; 2761841Sroot int margin; 277*1862Sroot char *comcol; /* character position comment starts in */ 278*1862Sroot int language = NOLANG; /* the language indicator */ 279*1862Sroot char **keywds; /* keyword table address */ 280*1862Sroot int (*isprbeg)(); /* test for beginning of procedure */ 281*1862Sroot int (*isprend)(); /* test for end of procedure */ 282*1862Sroot char *cstart; /* start of comment string */ 283*1862Sroot char *cstop; /* end of comment string */ 284*1862Sroot char *cout; /* string to substitute for cstart */ 285*1862Sroot int lcstart; /* length of comment string starter */ 286*1862Sroot int lcstop; /* length of comment string terminator */ 287*1862Sroot char sdelim; /* string constant delimiter */ 288*1862Sroot char cdelim; /* character constant delimiter */ 289*1862Sroot int com1line; /* one line comments */ 290*1862Sroot int str1line; /* one line strings */ 291*1862Sroot char pname[PNAMELEN]; 2921841Sroot 293*1862Sroot #define ps(x) printf("%s", x) 294*1862Sroot 2951841Sroot main(argc, argv) 2961841Sroot int argc; 2971841Sroot char *argv[]; 2981841Sroot { 2991841Sroot int lineno; 3001841Sroot char *fname = ""; 3011841Sroot struct stat stbuf; 3021841Sroot char buf[BUFSIZ]; 3031841Sroot int needbp = 0; 3041841Sroot 3051841Sroot argc--, argv++; 3061841Sroot do { 3071841Sroot char *cp; 308*1862Sroot int i; 3091841Sroot 3101841Sroot if (argc > 0) { 3111841Sroot if (!strcmp(argv[0], "-h")) { 3121841Sroot if (argc == 1) { 3131841Sroot printf("'ds =H\n"); 3141841Sroot argc = 0; 3151841Sroot goto rest; 3161841Sroot } 3171841Sroot printf("'ds =H %s\n", argv[1]); 3181841Sroot argc -= 2; 3191841Sroot argv += 2; 3201841Sroot if (argc > 0) 3211841Sroot continue; 3221841Sroot goto rest; 3231841Sroot } 3241841Sroot if (!strcmp(argv[0], "-x")) { 3251841Sroot index++; 3261841Sroot argv[0] = "-n"; 3271841Sroot } 3281841Sroot if (!strcmp(argv[0], "-n")) { 3291841Sroot nokeyw++; 3301841Sroot argc--, argv++; 3311841Sroot continue; 3321841Sroot } 333*1862Sroot for (i = 0; i < NLANG; i++) 334*1862Sroot if (!strcmp(argv[0], ld[i].option)) { 335*1862Sroot language = i; 336*1862Sroot break; 337*1862Sroot } 338*1862Sroot if (i != NLANG) { 339*1862Sroot argc--, argv++; 340*1862Sroot continue; 341*1862Sroot } 3421841Sroot if (freopen(argv[0], "r", stdin) == NULL) { 3431841Sroot perror(argv[0]); 3441841Sroot exit(1); 3451841Sroot } 3461841Sroot if (index) 3471841Sroot printf("'ta 4i 4.25i 5.5iR\n'in .5i\n"); 3481841Sroot fname = argv[0]; 3491841Sroot argc--, argv++; 3501841Sroot } 3511841Sroot rest: 352*1862Sroot if (language == NOLANG) 353*1862Sroot language = C; /* C is the default */ 354*1862Sroot 355*1862Sroot /* initialize for the appropriate language */ 356*1862Sroot 357*1862Sroot keywds = ld[language].kwd; 358*1862Sroot isprbeg = ld[language].isproc; 359*1862Sroot isprend = ld[language].ispend; 360*1862Sroot cstart = ld[language].combeg; 361*1862Sroot cstop = ld[language].comend; 362*1862Sroot cout = ld[language].comout; 363*1862Sroot lcstart = strlen (cstart); 364*1862Sroot lcstop = strlen (cstop); 365*1862Sroot sdelim = ld[language].strdel; 366*1862Sroot cdelim = ld[language].chrdel; 367*1862Sroot com1line = ld[language].onelncom; 368*1862Sroot str1line = ld[language].onelnstr; 369*1862Sroot pname[0] = 0; 370*1862Sroot 371*1862Sroot /* initialize the program */ 372*1862Sroot 3731841Sroot incomm = 0; 3741841Sroot instr = 0; 3751841Sroot printf(".ds =F %s\n", fname); 3761841Sroot fstat(fileno(stdin), &stbuf); 3771841Sroot cp = ctime(&stbuf.st_mtime); 3781841Sroot cp[16] = '\0'; 3791841Sroot cp[24] = '\0'; 3801841Sroot printf(".ds =M %s %s\n", cp+4, cp+20); 3811841Sroot if (needbp) { 3821841Sroot needbp = 0; 3831841Sroot printf(".()\n"); 3841841Sroot printf(".bp\n"); 3851841Sroot } 3861841Sroot while (fgets(buf, sizeof buf, stdin) != NULL) { 3871841Sroot if (buf[0] == '\f') { 3881841Sroot printf(".bp\n"); 3891841Sroot continue; 3901841Sroot } 391*1862Sroot if (com1line && incomm) { 392*1862Sroot incomm = 0; 393*1862Sroot ps("\\c\n'-C\n"); 394*1862Sroot } 395*1862Sroot if (str1line) 396*1862Sroot instr = 0; 397*1862Sroot comcol = NULL; 3981841Sroot putScp(buf); 3991841Sroot if (buf[strlen(buf) - 2] != '\\') 4001841Sroot instr = 0; 4011841Sroot margin = 0; 4021841Sroot } 4031841Sroot needbp = 1; 4041841Sroot } while (argc > 0); 4051841Sroot exit(0); 4061841Sroot } 4071841Sroot 4081841Sroot #define isidchr(c) (isalnum(c) || (c) == '_') 4091841Sroot 4101841Sroot putScp(os) 4111841Sroot char *os; 4121841Sroot { 4131841Sroot register char *s = os; 4141841Sroot register int i; 4151841Sroot int xfld = 0; 4161841Sroot 417*1862Sroot if (nokeyw || incomm || instr) 4181841Sroot goto skip; 419*1862Sroot if ((*isprbeg)(s)) { 4201841Sroot ps("'FN "); 421*1862Sroot ps(pname); 4221841Sroot ps("\n"); 423*1862Sroot } else if ((*isprend)(s)) 4241841Sroot ps("'-F\n"); 4251841Sroot skip: 4261841Sroot while (*s) { 4271841Sroot if (index) { 4281841Sroot if (*s == ' ' || *s == '\t') { 4291841Sroot if (xfld == 0) 4301841Sroot printf(""); 4311841Sroot printf("\t"); 4321841Sroot xfld = 1; 4331841Sroot while (*s == ' ' || *s == '\t') 4341841Sroot s++; 4351841Sroot continue; 4361841Sroot } 4371841Sroot } 438*1862Sroot if (!nokeyw && !incomm && *s == sdelim) { 4391841Sroot if (instr) { 4401841Sroot if (s[-1] != '\\') 4411841Sroot instr = 0; 4421841Sroot } else 443*1862Sroot if (s[-1] != cdelim) 4441841Sroot instr = 1; 4451841Sroot } 446*1862Sroot if (incomm && comcol != s-1 && s - os >= lcstop && !strncmp(cstop, s - lcstop, lcstop)) { 4471841Sroot incomm = 0; 4481841Sroot ps("\\c\n'-C\n"); 449*1862Sroot } else if (!instr && !nokeyw && !incomm && !strncmp(cstart, s, lcstart)) { 450*1862Sroot comcol = s; 4511841Sroot incomm = 1; 4521841Sroot if (s != os) 4531841Sroot ps("\\c"); 4541841Sroot ps("\\c\n'+C\n"); 4551841Sroot margin = width(os, s); 456*1862Sroot ps(cout); 457*1862Sroot s += lcstart; 4581841Sroot continue; 4591841Sroot } 4601841Sroot if (*s == '\t') { 4611841Sroot while (*s == '\t') 4621841Sroot s++; 4631841Sroot i = tabs(os, s) - margin / 8; 4641841Sroot printf("\\h'|%dn'", i * 10 + 1 - margin % 8); 4651841Sroot continue; 4661841Sroot } 4671841Sroot /* 4681841Sroot if (*s == '-' && s[1] == '>') { 4691841Sroot s += 2; 4701841Sroot ps("\\(->"); 4711841Sroot continue; 4721841Sroot } 4731841Sroot */ 474*1862Sroot if (!incomm && !nokeyw && !instr && (*s == '#' || isalpha(*s)) && (s == os || !isidchr(s[-1]))) { 4751841Sroot i = iskw(s); 4761841Sroot if (i > 0) { 4771841Sroot ps("\\*(+K"); 4781841Sroot do 4791841Sroot putcp(*s++); 4801841Sroot while (--i > 0); 4811841Sroot ps("\\*(-K"); 4821841Sroot continue; 4831841Sroot } 4841841Sroot } 4851841Sroot putcp(*s++); 4861841Sroot } 4871841Sroot } 4881841Sroot 4891841Sroot tabs(s, os) 4901841Sroot char *s, *os; 4911841Sroot { 4921841Sroot 4931841Sroot return (width(s, os) / 8); 4941841Sroot } 4951841Sroot 4961841Sroot width(s, os) 4971841Sroot register char *s, *os; 4981841Sroot { 4991841Sroot register int i = 0; 5001841Sroot 5011841Sroot while (s < os) { 5021841Sroot if (*s == '\t') { 5031841Sroot i = (i + 8) &~ 7; 5041841Sroot s++; 5051841Sroot continue; 5061841Sroot } 5071841Sroot if (*s < ' ') 5081841Sroot i += 2; 5091841Sroot else 5101841Sroot i++; 5111841Sroot s++; 5121841Sroot } 5131841Sroot return (i); 5141841Sroot } 5151841Sroot 5161841Sroot putcp(c) 5171841Sroot register int c; 5181841Sroot { 5191841Sroot 5201841Sroot switch(c) { 5211841Sroot 5221841Sroot case '{': 5231841Sroot ps("\\*(+K{\\*(-K"); 5241841Sroot break; 5251841Sroot 5261841Sroot case '}': 5271841Sroot ps("\\*(+K}\\*(-K"); 5281841Sroot break; 5291841Sroot 5301841Sroot case '\\': 5311841Sroot ps("\\e"); 5321841Sroot break; 5331841Sroot 5341841Sroot case '_': 5351841Sroot ps("\\*_"); 5361841Sroot break; 5371841Sroot 5381841Sroot case '-': 5391841Sroot ps("\\*-"); 5401841Sroot break; 5411841Sroot 5421841Sroot case '`': 5431841Sroot ps("\\`"); 5441841Sroot break; 5451841Sroot 5461841Sroot case '\'': 5471841Sroot ps("\\'"); 5481841Sroot break; 5491841Sroot 5501841Sroot case '.': 5511841Sroot ps("\\&."); 5521841Sroot break; 5531841Sroot 5541841Sroot default: 5551841Sroot if (c < 040) 5561841Sroot putchar('^'), c |= '@'; 5571841Sroot case '\t': 5581841Sroot case '\n': 5591841Sroot putchar(c); 5601841Sroot } 5611841Sroot } 5621841Sroot 5631841Sroot iskw(s) 5641841Sroot register char *s; 5651841Sroot { 566*1862Sroot register char **ss = keywds; 5671841Sroot register int i = 1; 5681841Sroot register char *cp = s; 5691841Sroot 5701841Sroot while (++cp, isidchr(*cp)) 5711841Sroot i++; 5721841Sroot while (cp = *ss++) 5731841Sroot if (*s == *cp && !strncmp(s, cp, i) && !isidchr(cp[i])) 5741841Sroot return (i); 5751841Sroot return (0); 5761841Sroot } 577*1862Sroot 578*1862Sroot cprbegin(s) 579*1862Sroot register char *s; 580*1862Sroot { 581*1862Sroot register char *p; 582*1862Sroot 583*1862Sroot p = pname; 584*1862Sroot if ((*s == '_' || isalpha(*s)) && s[strlen(s) - 2] == ')') { 585*1862Sroot while (isidchr(*s)) 586*1862Sroot *p++ = *s++; 587*1862Sroot *p = 0; 588*1862Sroot return (1); 589*1862Sroot } 590*1862Sroot return (0); 591*1862Sroot } 592*1862Sroot 593*1862Sroot cprend(s) 594*1862Sroot register char *s; 595*1862Sroot { 596*1862Sroot if (!strcmp(s, "}\n")) 597*1862Sroot return (1); 598*1862Sroot else 599*1862Sroot return (0); 600*1862Sroot } 601*1862Sroot 602*1862Sroot pprbegin(s) 603*1862Sroot register char *s; 604*1862Sroot { 605*1862Sroot register char *p; 606*1862Sroot 607*1862Sroot p = pname; 608*1862Sroot while ((*s == ' ') || (*s == '\t')) 609*1862Sroot s++; 610*1862Sroot if (strncmp(s, "procedure", 9) == 0) 611*1862Sroot s += 9; 612*1862Sroot else if (strncmp(s, "function", 8) ==0) 613*1862Sroot s += 8; 614*1862Sroot else 615*1862Sroot return (0); 616*1862Sroot while ((*s == ' ') || (*s == '\t')) 617*1862Sroot s++; 618*1862Sroot while ((*s != ' ') && (*s != '\t') && (*s != '(') && (*s != ';')) 619*1862Sroot *p++ = *s++; 620*1862Sroot *p = 0; 621*1862Sroot return (1); 622*1862Sroot } 623*1862Sroot 624*1862Sroot pprend(s) 625*1862Sroot register char *s; 626*1862Sroot { 627*1862Sroot if (strncmp (s, "end", 3) == 0) 628*1862Sroot return (1); 629*1862Sroot else 630*1862Sroot return (0); 631*1862Sroot } 632*1862Sroot 633*1862Sroot mprbegin(s) 634*1862Sroot register char *s; 635*1862Sroot { 636*1862Sroot register char *p; 637*1862Sroot 638*1862Sroot p = pname; 639*1862Sroot if (strcmp(&s[strlen(s) - 10], "beginproc\n") == 0) { 640*1862Sroot 641*1862Sroot while ((*s == ' ') || (*s == '\t')) 642*1862Sroot s++; 643*1862Sroot 644*1862Sroot while (*s != ' ') 645*1862Sroot *p++ = *s++; 646*1862Sroot *p = 0; 647*1862Sroot return (1); 648*1862Sroot } else 649*1862Sroot return (0); 650*1862Sroot } 651*1862Sroot 652*1862Sroot mprend(s) 653*1862Sroot register char *s; 654*1862Sroot { 655*1862Sroot if (!strcmp(&s[strlen(s) - 9], "endproc;\n")) 656*1862Sroot return (1); 657*1862Sroot else 658*1862Sroot return (0); 659*1862Sroot } 660