abcscnuk@csun.UUCP (Naoto Kimura) (04/20/87)
Here's a program I have found to be quite useful if you happen to want to print a file on a line printer that uses carriage control characters in column 1. It's also useful if your printer doesn't allow the char-backspace-char sequences to generate overstrike. Of course, you won't get overstrike by using this program, but the overstrike stuff will be visible when you print it. If you happen to have a printer that allows you to print overstrike by sending CR without LF between lines, this program should help, since it will separate out the char-backspace-char into multiple lines, which then you can put a CR between to get overstrike. Although I am not finished with writing this program (I haven't gotten around to writing the code that takes out blank lines at the end of a page, or the code to take multiple blank lines and condense it to a series of triple-space and double-space control chars), but what I have now should still come in handy. For those unfamiliar with carriage control characters, they are characters found in column 1 ( or 0 if you happen to prefer numbering from 0 ) that are used by a printer to control spacing of lines. Here is a list of the carriage control characters: 1 form feed SP single space 0 double space - triple space + overstrike I should warn you about a really silly thing I've done in this program, which I used to trick getopt into doing something that it normally doesn't do, like accept something like -l66w80 and parse it as - l 66 w 80, instead of - l 66w80. What I've done will most likely not work with all implementations of getopt. I've marked that part of the code with the comment /* kludgy stuff */ . If you can think of a better way, without writing another implementation of getopt, please inform me. --- cut here -------- cut here -------- cut here -------- cut here --- #include <stdio.h> #include <ctype.h> #include <bool.h> #define SH_TRUE 1 #define SH_FALSE 0 #define NEWPAGE '1' #define OVRSTRK '+' #define SNG_SPC ' ' #define DBL_SPC '0' #define TRP_SPC '-' #define TABLENGTH 8 #define PAGELENGTH 66 char *pname; int tablength = TABLENGTH, pglength = PAGELENGTH, cctrl; usage() { fprintf(stderr,"usage: %s [-t#] [ file1 [ file2 .. filen ] ]\n", pname); fprintf(stderr,"\t-t# -- tabstops at multiples of #\n"); exit(SH_FALSE); } main(argc,argv) int argc; char **argv; { extern char *optarg; extern int optind, opterr; FILE *f; int errflg = FALSE, tmp, c; char *sp; pname=*argv; while ( (c=getopt(argc,argv,"l:t:")) != EOF ) switch(c) { case 'l': errflg=(errflg || sscanf(optarg,"%d",&tmp)!=1 || tmp<0); if (! errflg) { pglength = tmp; while(isdigit(*optarg)) /* kludgy stuff */ optarg++; if (*optarg != '\0') { /* kludgy stuff */ argv[--optind] = optarg - 1; argv[optind][0] = '-'; } } break; case 't': errflg=(errflg || sscanf(optarg,"%d",&tmp)!=1 || tmp<0); if (! errflg) { tablength = tmp; while(isdigit(*optarg)) /* kludgy stuff */ optarg++; if (*optarg != '\0') { /* kludgy stuff */ argv[--optind] = optarg - 1; argv[optind][0] = '-'; } } break; default: errflg = TRUE; break; } argc -= optind; argv = &(argv[optind]); if (errflg) usage(); if (argc==0) { cctrl = NEWPAGE; mkcc(stdin); } else { while (argc--) { if ((f=fopen(*argv,"r")) == NULL) { fprintf(stderr,"%s: cannot open file \"%s\".\n",pname,*argv); exit(SH_FALSE); } else { cctrl = NEWPAGE; mkcc(f); fclose(f); } argv++; } } exit(SH_TRUE); } /********************************************************************** * * * * * * **********************************************************************/ #define max(x,y) ((x)>(y) ? (x) : (y)) #define BUFCOLS 2048 #define BUFROWS 16 static char buffer[BUFROWS][BUFCOLS]; static int lines, width[BUFROWS], bufc, bufr[BUFCOLS], buftouched; mkcc(f) FILE *f; { int c; initbuf(); while ((c=getc(f))!= EOF) { buftouched = TRUE; switch(c) { case '\r' : printout(); cctrl = OVRSTRK; break; case '\f' : printout(); cctrl = NEWPAGE; break; case '\n' : printout(); cctrl = SNG_SPC; break; case '\b' : bufc--; break; case ' ' : bufc++; break; case '\t' : if (tablength > 0) bufc += tablength - (bufc % tablength); break; default: if isprint(c) { buffer[bufr[bufc]][bufc]=c; width[bufr[bufc]] =max(width[bufr[bufc]],bufc+1); bufr[bufc]++; lines=max(lines,bufr[bufc]); bufc++; } else { fprintf(stderr, "%s: can't handle control characters.\n", pname); exit(SH_FALSE); } break; } } printout(); } printout() { int i, j; if (buftouched) { putchar(cctrl); for (i=0; i<lines; i++) { if (i) printf("\n%c",OVRSTRK); for (j=0; j<width[i]; j++) if (i<bufr[j]) putchar(buffer[i][j]); else putchar(' '); } initbuf(); putchar('\n'); } } initbuf() { for (bufc=0; bufc<BUFCOLS; bufc++) bufr[bufc] = 0; for (lines=0; lines<BUFROWS; lines++) width[lines] = 0; bufc = 0; lines = 0; buftouched = FALSE; } --- cut here -------- cut here -------- cut here -------- cut here --- Naoto Kimura //-n-\\ (csun!abcscnuk) _____---=======---_____ ====____\ /.. ..\ /____==== // ---\__O__/--- \\ Enterprise... Surrender or we'll \_\ /_/ send back your *&^$% tribbles !!!