dhb (04/21/83)
#include <stdio.h> char *format_sccsid = "@(#) format.c: version 1.6"; char *format_rayssd = "@(#) format.c: Raytheon Submarine Signal Division"; char *format_author = "@(#) format.c: written by David H. Brierley"; /* In the following structure, type has the following meanings: 1 = mm macros 2 = ms macros 3 = me macros 4 = man macros 10 = eqn 11 = tbl 20 = .so 21 = .de */ struct s_tbl { char macro[20]; int type; }; /* the following strings are defined extermely large so that no matter */ /* how many arguments this program is given it will never blow up. */ char buffer[4096]; char macros[20] = ""; char nrflags[4096] = ""; char files[4096] = ""; char command[8192]; char tmp_holdfile[100]; char *index(); int flags = 0; #define EQN 001 #define TBL 002 #define COL 004 #define VU 010 int m_flags = 0; int M_flags = 0; #define MM 002 #define MS 004 #define ME 010 #define MAN 020 int fd_infile; int fd_stdin; int fd_holdfile; int check_flag = 0; int src_flag = 0; int file_count = 0; int i,j,k,l,m,n; /* The first macro entry in the following table MUST be in the */ /* position defined by FIRSTMAC. The beginning entries are */ /* reserved for .so, the tbl macros, and the eqn macros. */ #define FIRSTMAC 6 struct s_tbl srch_table[] = { ".EQ", 10, ".EN", 10, ".TS", 11, ".TE", 11, ".so", 20, ".de", 21, ".AF", 1, ".AL", 1, ".AS", 1, ".BL", 1, ".DF", 1, ".DL", 1, ".EC", 1, ".EF", 1, ".EH", 1, ".FD", 1, ".FG", 1, ".H", 1, ".HC", 1, ".HM", 1, ".HU", 1, ".HX", 1, ".HZ", 1, ".LB", 1, ".LC", 1, ".LE", 1, ".LI", 1, ".ML", 1, ".MT", 1, ".NE", 1, ".NS", 1, ".OF", 1, ".OH", 1, ".P", 1, ".PF", 1, ".PH", 1, ".PX", 1, ".RL", 1, ".SA", 1, ".SK", 1, ".SP", 1, ".TB", 1, ".TC", 1, ".TX", 1, ".VL", 1, ".AB", 2, ".AI", 2, ".AT", 2, ".B1", 2, ".B2", 2, ".BT", 2, ".BX", 2, ".CT", 2, ".DA", 2, ".EG", 2, ".HO", 2, ".IH", 2, ".IM", 2, ".KE", 2, ".KF", 2, ".KS", 2, ".LG", 2, ".MF", 2, ".MH", 2, ".MR", 2, ".NH", 2, ".NL", 2, ".PT", 2, ".PY", 2, ".QE", 2, ".QP", 2, ".QS", 2, ".RP", 2, ".TR", 2, ".UL", 2, ".UX", 2, ".WH", 2, ".(c", 3, ".(d", 3, ".(f", 3, ".(l", 3, ".(q", 3, ".(x", 3, ".(z", 3, ".)C", 3, ".)d", 3, ".)f", 3, ".)l", 3, ".)q", 3, ".)x", 3, ".)z", 3, ".++", 3, ".+c", 3, ".1c", 3, ".2c", 3, ".ac", 3, ".b", 3, ".ba", 3, ".bc", 3, ".bi", 3, ".bx", 3, ".ef", 3, ".eh", 3, ".fo", 3, ".hx", 3, ".he", 3, ".hl", 3, ".i", 3, ".ip", 3, ".lp", 3, ".lo", 3, ".np", 3, ".of", 3, ".oh", 3, ".pd", 3, ".pp", 3, ".r", 3, ".re", 3, ".sc", 3, ".sh", 3, ".sk", 3, ".sz", 3, ".th", 3, ".tp", 3, ".u", 3, ".uh", 3, ".xp", 3, ".BI", 4, ".BR", 4, ".DT", 4, ".HP", 4, ".IB", 4, ".IR", 4, ".PD", 4, ".RB", 4, ".RI", 4, "END", 0 }; main(argc,argv) int argc; char *argv[]; { if ( (strlen(argv[1]) == 2) && (strcmp(argv[1],"--") == 0) ) { check_flag = 1; argv++; argc--; } else { sprintf(tmp_holdfile,"/tmp/FORMAT%d",getpid()); if ((fd_holdfile = creat(tmp_holdfile,0666)) == -1) { fprintf(stderr,"Unable to create hold file\n"); exit(1); } } while(argc > 1) { if (check_flag) { flags = 0; m_flags = 0; M_flags = 0; } if (argv[1][0] == '-' && strlen(argv[1]) > 1) { if (strlen(argv[1]) == 2) { switch(argv[1][1]) { case 'v': flags |= VU; break; case 'c': flags |= COL; break; default: if (!check_flag) { strcat(nrflags,argv[1]); strcat(nrflags," "); } break; } } else { if (!check_flag) { strcat(nrflags,argv[1]); strcat(nrflags," "); } } argv++; argc--; continue; } find_pak(argv[1]); argv++; argc--; } if (check_flag) { exit(0); } dumpout(NULL); close(fd_holdfile); command[0] = '\0'; if (flags & EQN) { strcat(command,"neqn "); strcat(command,tmp_holdfile); strcat(command," | "); } if (flags & TBL) { strcat(command,"tbl "); if ( !(flags & EQN) ) { strcat(command,tmp_holdfile); } strcat(command," | "); } strcat(command,"nroff "); strcat(command,macros); strcat(command," "); strcat(command,nrflags); if ( !(flags & (TBL | EQN)) ) { strcat(command,tmp_holdfile); } else { strcat(command," -"); } if (flags & COL) { strcat(command," | col"); } if (flags & VU) { strcat(command," | vu"); } system(command); unlink(tmp_holdfile); } search(filename) char *filename; { struct s_tbl *table; char *ptr, *ptr2; char source[512]; int save_flag; int save_mflg; if (strlen(buffer) < 2) { dumpout(buffer); return; } for (table = srch_table; table->type != 0; table++) { if (strlen(buffer) < strlen(table->macro)) continue; if (strncmp(table->macro,buffer,strlen(table->macro)) != 0) continue; if (strlen(table->macro) != strlen(buffer)) if (buffer[strlen(table->macro)] != ' ') continue; switch(table->type) { case 1: dumpout(buffer); if (check_flag) double_check("-mm",filename); else strcpy(macros,"-mm"); m_flags |= MM; if (!check_flag) srch_table[FIRSTMAC].type = 0; return; case 2: dumpout(buffer); if (check_flag) double_check("-ms",filename); else strcpy(macros,"-ms"); m_flags |= MS; if (!check_flag) srch_table[FIRSTMAC].type = 0; return; case 3: dumpout(buffer); if (check_flag) double_check("-me",filename); else strcpy(macros,"-me"); m_flags |= ME; if (!check_flag) srch_table[FIRSTMAC].type = 0; return; case 4: dumpout(buffer); if (check_flag) double_check("-man",filename); else strcpy(macros,"-man"); m_flags |= MAN; if (!check_flag) srch_table[FIRSTMAC].type = 0; return; case 10: dumpout(buffer); flags |= EQN; return; case 11: dumpout(buffer); flags |= TBL; return; case 20: if ((ptr = index(buffer,' ')) == NULL) return; while(*ptr == ' ') ptr++; if ((ptr2 = index(ptr,' ')) != NULL) *ptr2 = '\0'; strcpy(source,ptr); if (check_flag) { save_flag = flags; save_mflg = m_flags; src_flag++; flags = 0; m_flags = 0; } find_pak(source); if (check_flag) { M_flags |= m_flags; flags = save_flag; m_flags = save_mflg; src_flag--; if (src_flag == 0) m_flags |= M_flags; } return; case 21: dumpout(buffer); if ((ptr = index(buffer,' ')) == NULL) return; while(*ptr == ' ') ptr++; if ((ptr2 = index(ptr,' ')) != NULL) *ptr2 = '\0'; for (table = srch_table; table->type!=0; table++) { if (strcmp(ptr,table->macro+1) == 0) { *(table->macro) = '+'; return; } } return; default: break; } } dumpout(buffer); } /*----------------------------------------------------------------------* * * * title: getline * * * * function: * * To read a line from a specified file descriptor. * * * * method of operation: * * The specified input is read until a carriage return is detected * * and passed back to the calling routine. * * If the file descriptor is not 0 (standard input), the * * file is read blocked, otherwise it is read unblocked. * * * *----------------------------------------------------------------------*/ #define BUFFSIZE 4096 #define BUFCOUNT 30 getline(fd,line) int fd; register char *line; { static char *buffer[BUFCOUNT]; static int buf_pos[BUFCOUNT]; static int buf_size[BUFCOUNT]; static int buf_max[BUFCOUNT]; static int init_flag = 1; register int i; register char *Buffer; register int Bufpos; register int *Bufsize; if (init_flag){ for (i=0; i<BUFCOUNT; i++){ buffer[i] = NULL; buf_pos[i] = BUFFSIZE; buf_size[i] = BUFFSIZE; } init_flag = 0; } if (fd >= BUFCOUNT){ printf("getline: file descriptor greater than max, fd=%d\n",fd); exit(1); } if (buffer[fd] == NULL){ if (fd == 0) buf_max[fd] = 1; else buf_max[fd] = BUFFSIZE; if ((buffer[fd] = (char *)malloc(buf_max[fd])) == NULL){ printf("getline: unable to allocate buffer space, "); printf("fd = %d\n",fd); perror("getline"); exit(1); } } i = 0; Bufpos = buf_pos[fd]; Bufsize = &buf_size[fd]; if (Bufpos < *Bufsize) Buffer = &buffer[fd][Bufpos]; while ( 1 ){ if (Bufpos >= *Bufsize){ *Bufsize = read(fd,buffer[fd],buf_max[fd]); Bufpos = 0; Buffer = buffer[fd]; if (*Bufsize == 0) break; } if (*Buffer == '\n') break; *line = *Buffer++; Bufpos++; line++; i++; } *line = '\0'; if ((i == 0) && (*Bufsize == 0) && (Bufpos == 0)) i = -1; buf_pos[fd] = ++Bufpos; return(i); } print_info(filename) char *filename; { int i; if (src_flag) printf("Sourced file "); else printf("File "); printf("%s requires ", (filename[0] == '-') ? "STANDARD INPUT" : filename); if (flags & TBL) { printf("tbl, "); } if (flags & EQN) { printf("eqn, "); } i = 0; if (m_flags & MM) { strcpy(macros,"-mm"); i++; } if (m_flags & MS) { strcpy(macros,"-ms"); i++; } if (m_flags & ME) { strcpy(macros,"-me"); i++; } if (m_flags & MAN) { strcpy(macros,"-man"); i++; } if (i == 0) { printf("unknown (or no) macro package\n"); } else { printf("%s macro package\n",macros); } if (i > 1) { printf("ERROR: file \"%s\" uses multiple macro packages:", (filename[0] == '-') ? "STANDARD INPUT" : filename); if (m_flags & MM) printf(" -mm"); if (m_flags & MS) printf(" -ms"); if (m_flags & ME) printf(" -me"); if (m_flags & MAN) printf(" -man"); printf("\n"); } fflush(stdout); } double_check(package,filename) char *package; char *filename; { if (macros[0] == '\0') return; if (strlen(package) == strlen(macros) && strcmp(package,macros) == 0) return; printf("ERROR: file \"%s\" conflicts with previous files\n", (filename[0] == '-') ? "STANDARD INPUT" : filename); printf("previous files used the %s macro package and\n",macros); printf("file \"%s\" uses the %s macro package\n", (filename[0] == '-') ? "STANDARD INPUT" : filename,package); } find_pak(filename) char *filename; { int fd_infile; if (filename[0] == '-'){ fd_infile = 0; } else { if ((fd_infile = open(filename,0)) == -1) { printf("Unable to open file %s\n",filename); perror("format"); return; } } while(getline(fd_infile,buffer) != -1) { if (buffer[0] != '.') { dumpout(buffer); continue; } search(filename); } close(fd_infile); if (check_flag) print_info(filename); } dumpout(buffer) char *buffer; { static char dumpbuff[8192]; static int buffpos = 0; register int n; register int size = buffpos; if (check_flag) return; if (buffer == NULL) { write(fd_holdfile,dumpbuff,buffpos); buffpos = 0; return; } n = strlen(buffer); strcpy(dumpbuff+size,buffer); dumpbuff[size + (n++)] = '\n'; dumpbuff[size + n] = '\0'; if ((size += n) > 4096) { write(fd_holdfile,dumpbuff,4096); strcpy(dumpbuff,dumpbuff+4096); size -= 4096; } buffpos = size; }