home *** CD-ROM | disk | FTP | other *** search
- /* print.c
-
-
- simple print file utility for less by: Bob Leivian
-
- print -nh^ld#99|99t9wp:<string> file1 {-nh...}file2 file3 ...
-
- this is designed to be called from the less with the
- expanded list of files to print with a option list
- */
-
- #include <stdio.h>
- #include <ctype.h>
- long Open();
- #define MODE_OLDFILE 1005L
- #define MODE_NEWFILE 1006L
- long std_out;
- extern char prog_name[];
-
- /* this can be set with options */
- int numbers = 0;
- int headers = 0;
- int control = 0;
- int prefix = 0;
- int lines_per_page = 0;
- int chars_per_line = 0;
- int tab_stops = 0;
-
- long printer = 0;
-
-
- start_print(my_argc, my_argv)
- int my_argc;
- char *my_argv[];
- {
- int i;
- char *p;
- char name[30];
- char theprefix [30];
- char c;
-
- if (printer == 0) {
- printer = Open("PRT:", MODE_NEWFILE);
- if (!printer) exit(27);
- }
-
- while (my_argv[1]) {
- /* process options if any */
- while (*my_argv[1] == '-') {
- p = (char *) &*my_argv[1];
-
- p++; /* point to the option chars */
- do {
- switch (*p) {
- case ' ':
- case '\0': /* ignore nulls and spaces */
- break;
-
- case 'p': case 'P': /* turn on proportional mode */
- Write(printer, "\x1b[2p", 3L);
- break;
-
- case 'c': case 'C': /* turn on compressed mode */
- Write(printer, "\x1b[4w", 4L);
- break;
-
- case 'u': case 'U': /* turn on uncompressed mode */
- Write(printer, "\x1b[3w", 4L);
- break;
-
- case 'l': case 'L': /* turn on letter quality mode */
- Write(printer, "\x1b[2\"z", 5L);
- break;
-
- case 'd': case 'D': /* turn on draft mode */
- Write(printer, "\x1b[1\"z", 5L);
- break;
-
- case ':': /* print control string first */
- strcpy(theprefix, ++p);
- prefix++;
- goto next; /* consume rest of option */
-
- case '^': /* print control chars as ^X */
- control++;
- break;
-
- case 't': case 'T': /* set tab stops */
- p++;
- if (isdigit(*p))
- tab_stops = *p - '0';
- else {
- tab_stops = 8;
- p--;
- }
- break;
-
- case '#': /* set lines per page */
- p++;
- lines_per_page = 0;
- while(isdigit(*p)) {
- lines_per_page *= 10;
- lines_per_page += (*p++ - '0');
- }
- p--;
- break;
-
- case '|': /* set chars per line */
- p++;
- chars_per_line = 0;
- while(isdigit(*p)) {
- chars_per_line *= 10;
- chars_per_line += (*p++ - '0');
- }
- p--;
- break;
-
- case 'n': case 'N': /* print line numbers */
- numbers++;
- break;
-
- case 'h': /* print a header */
- headers++;
- break;
-
- default:
- /* ignore invalid stuff for now */;
- }
- p++;
- } while (*p);
- next:
- my_argc--;
- my_argv++;
- }
-
- /* put out the control prefix if any */
- if (prefix) {
- p = theprefix;
- while(*p) {
- if (*p == '^') {
- p++;
- c = *p - '@';
- Write(printer, &c, 1L);
- } else
- Write(printer, *p, 1L);
- p++;
- }
-
- /* reset the prefix flag */
- prefix = 0;
- }
-
- /* now print the file */
- print_one_file(my_argv[1]);
- my_argv++;
- }
- Close(printer);
- printer = 0;
- }
-
- static char buf[1024]; /* Note! if called from WB we have */
- static char outbuf[1024+100]; /* very limited stack space */
-
- /* do the actual print for a file */
- print_one_file(name)
- char *name;
- {
- long in;
- long bytes, Read();
-
- register long outbytes;
- register char *p;
-
- int line;
- int page;
- int num_lines;
- int new_line;
- int chars;
-
- char line_buf[10];
- char ctl[4];
- int i;
-
- in = Open(name, MODE_OLDFILE);
-
- if (!in) {
- sprintf(buf, "unable to open: '%s'\f", name);
- Write(printer, buf, (long) strlen(buf));
- return;
- }
-
- line = 1;
- page = 1;
-
- /* print a file header if desired */
- if (headers) {
- sprintf(buf, "File: %s Page %d\n\n", name, page);
- Write(printer, buf, (long) strlen(buf));
- num_lines = 3;
- } else
- num_lines = 1;
-
- if (numbers || control || lines_per_page || chars_per_line) {
-
- outbytes = 0;
- if (numbers) {
- sprintf(outbuf, "%4d ", line);
- outbytes = strlen(outbuf);
- chars = outbytes;
- }
-
- /* now read the file a block at a time */
- while(bytes = Read(in, buf, 1024L)) {
- p = buf;
- if (bytes < 0) {
- sprintf(buf, "Error reading file: %s\n", name);
- Write(printer, buf, (long) sizeof(buf));
- return;
- }
-
- /* now write out this block */
- while(bytes) {
- /* check for control chars, if requested */
- if (control) {
- if ((*p < ' ')&&(*p != '\n')&&(*p != '\t')){
- /* print all other control chars in ^A format */
- outbuf[outbytes++] = '^';
- *p += '@';
- chars++;
- }
- }
-
- /* check for a new line */
- if ((*p == '\n')||(*p == '\f')) {
- /* newline, need a page break? */
- if (((*p == '\f') && (!control)) ||
- (lines_per_page && (num_lines >= lines_per_page))) {
-
- /* is this a user formfeed */
- if (*p == '\f') {
- sprintf(buf, "<form feed>\f");
- strcpy(&outbuf[outbytes], buf);
- outbytes += strlen(buf);
- line--;
- } else
- outbuf[outbytes++] = '\f';
-
- /* print a file header if desired */
- page++;
- if (headers) {
- sprintf(buf, "File: %s Page %d\n\n",
- name, page);
- strcpy(&outbuf[outbytes], buf);
- outbytes += strlen(buf);
- num_lines = 2;
- } else
- num_lines = 0;
- }
- line++;
- num_lines++;
- new_line = 1;
- } else
- new_line = 0;
-
- /* now put the character and account for it */
- chars++;
- bytes--;
- switch (*p) {
- case '\t':
- if (tab_stops) {
- if ((chars % tab_stops) == 0) {
- for(i=0; i < tab_stops; i++) {
- outbuf[outbytes++] = ' ';
- chars++;
- }
- } else
- while(chars % tab_stops) {
- outbuf[outbytes++] = ' ';
- chars++;
- }
- p++;
- } else {
- while(chars % 8) chars++;
- outbuf[outbytes++] = *p++;
- }
- break;
-
- case '\f': /* formfeeds are accounted for eariler */
- p++;
- break;
-
- case 8:
- chars--;
- outbuf[outbytes++] = *p++;
- break;
-
- default:
- outbuf[outbytes++] = *p++;
- }
-
- /* check for line overflow, if requested */
- if (chars_per_line && (chars >= chars_per_line)) {
- outbuf[outbytes++] = '\n';
- num_lines++;
- if (numbers) {
- strcpy(&outbuf[outbytes], " ");
- outbytes += 5;
- chars = 5;
- } else
- chars = 0;
- }
-
- /* now put out the line number if needed */
- if (new_line && numbers) {
- sprintf(&outbuf[outbytes], "%4d ", line);
- outbytes += 5;
- chars = 5;
- }
-
- /* dump the buffer if near full */
- if (outbytes >= 1000L) {
- Write(printer, outbuf, outbytes);
- outbytes = 0;
- }
- } /* while chars in this block */
- } /* while not EOF */
-
- /* flush last line */
- if (outbytes)
- Write(printer, outbuf, outbytes);
- } else {
- /* we can just pump out the data untouched */
- while(bytes = Read(in, buf, 1024L))
- if (bytes > 0)
- Write(printer, buf, bytes);
- else {
- sprintf(buf, "Error reading file");
- Write(printer, buf, (long) sizeof(buf));
- }
-
- }
- Write(printer, "\f", 1L);
- Close(in);
- in = 0;
- }
-
- set_up_print(name)
- char *name;
- {
- long save;
- extern long tty;
- extern char **av;
- extern int called_from_WB;
- extern long current_dir;
- char option_string[80];
- char numbuf[16];
- char c;
- int i;
- char buf[100];
- long result, Execute();
- int fake_argc;
- char *fake_argv[4];
-
- /*
- * print the current file
- */
-
- save = tty;
-
- /* first make sure we can get the printer */
- printer = Open("PRT:", MODE_NEWFILE);
- if (!printer) {
- error("can't access the printer at this time");
- } else {
-
- /* printer is avail so... */
- tty = Open("RAW:100/50/470/100/Less's print server", MODE_NEWFILE);
- if (!tty) {
- tty = save;
- Close(printer);
- printer = 0;
- error("Can't open window!");
- return;
- }
-
- ttputs("Print File: ");
- ttputs(name);
- ttputs("\nEnter the first letter of each option, if any\n");
- ttputs("For example 'nh#60|80t8^l', the options are...\n");
- so_enter();
- ttputs("numberedlines headers ^ctrl proportional \n");
- ttputs("letterquality draft wide uncompressed \n");
- ttputs("#<num> of rows, |<num> of columns, t<num> tabstop\n");
- so_exit();
- ttputs("\nOptions or 'q' to quit? ");
-
- /* get a responce */
- i = 0;
- while (c = ttgetc()) {
- if (c == 8) { /* backspace ? */
- if (i > 0) {
- i--;
- ttputc(c);
- }
- } else {
- if ((c < ' ') || (i > 32)) break;
- option_string[i++] = c;
- ttputc(c);
- }
- }
- option_string[i] = 0;
-
- if(toupper(option_string[0]) != 'Q') {
-
- if (called_from_WB) {
- /* I haven't figured out how to queue from WB */
- #ifndef WB_QUEUED
- if (option_string[0]) {
- sprintf(buf, "-%s", option_string);
- fake_argc = 3;
- fake_argv[1] = buf;
- fake_argv[2] = name;
- } else {
- fake_argc = 2;
- fake_argv[1] = name;
- }
- fake_argv[fake_argc] = NULL;
-
- ttputs("\nPrinting...\n");
- start_print(fake_argc, fake_argv);
- ttputs("Complete!\n");
- #else
- /* this should work but I can't figure out why not */
- sprintf(buf, "RUN %s -p %ld ", prog_name, current_dir);
-
- if (option_string[0]) {
- strcat(buf, "-");
- strcat(buf, option_string);
- strcat(buf, " ");
- }
- strcat(buf, name);
-
- /* give up the printer */
- Close(printer);
- printer = 0;
-
- /* and execute the job */
- std_out = Open("NIL:", MODE_OLDFILE);
- result = Execute(buf, 0L, std_out);
- if (result) {
- ttputs("\nJob queued\n");
- } else {
- sprintf(buf, "\nError on Execute: %ld", result);
- ttputs(buf);
- }
- #endif
- } else {
- /* from CLI, queue it to a copy of myself */
- sprintf(buf, "RUN %s -p ", prog_name);
-
- if (option_string[0]) {
- strcat(buf, "-");
- strcat(buf, option_string);
- strcat(buf, " ");
- }
- strcat(buf, name);
-
- /* give up the printer */
- Close(printer);
- printer = 0;
-
- /* and execute the job */
- result = Execute(buf, 0L, 0L);
- if (result) {
- ttputs("\nJob queued\n");
- } else {
- sprintf(buf, "\nError on Execute: %ld", result);
- ttputs(buf);
- }
- }
- } else {
- Close(printer);
- printer = 0;
- ttputs("\nPrint request canceled by user!\n");
- }
-
- Delay(100L);
- ttclose();
- tty = save;
- }
- }
-
-