pr.c
来自「早期freebsd实现」· C语言 代码 · 共 1,805 行 · 第 1/3 页
C
1,805 行
/*- * Copyright (c) 1991 Keith Muller. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Keith Muller of the University of California, San Diego. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1993\n\ The Regents of the University of California. All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)pr.c 8.2 (Berkeley) 4/16/94";#endif /* not lint */#include <sys/types.h>#include <sys/time.h>#include <sys/stat.h>#include <ctype.h>#include <errno.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "pr.h"#include "extern.h"/* * pr: a printing and pagination filter. If multiple input files * are specified, each is read, formatted, and written to standard * output. By default, input is seperated into 66-line pages, each * with a header that includes the page number, date, time and the * files pathname. * * Complies with posix P1003.2/D11 *//* * parameter variables */int pgnm; /* starting page number */int clcnt; /* number of columns */int colwd; /* column data width - multiple columns */int across; /* mult col flag; write across page */int dspace; /* double space flag */char inchar; /* expand input char */int ingap; /* expand input gap */int formfeed; /* use formfeed as trailer */char *header; /* header name instead of file name */char ochar; /* contract output char */int ogap; /* contract output gap */int lines; /* number of lines per page */int merge; /* merge multiple files in output */char nmchar; /* line numbering append char */int nmwd; /* width of line number field */int offst; /* number of page offset spaces */int nodiag; /* do not report file open errors */char schar; /* text column separation character */int sflag; /* -s option for multiple columns */int nohead; /* do not write head and trailer */int pgwd; /* page width with multiple col output */char *timefrmt; /* time conversion string *//* * misc globals */FILE *err; /* error message file pointer */int addone; /* page length is odd with double space */int errcnt; /* error count on file processing */char digs[] = "0123456789"; /* page number translation map */intmain(argc, argv) int argc; char *argv[];{ int ret_val; if (signal(SIGINT, SIG_IGN) != SIG_IGN) (void)signal(SIGINT, terminate); ret_val = setup(argc, argv); if (!ret_val) { /* * select the output format based on options */ if (merge) ret_val = mulfile(argc, argv); else if (clcnt == 1) ret_val = onecol(argc, argv); else if (across) ret_val = horzcol(argc, argv); else ret_val = vertcol(argc, argv); } else usage(); flsh_errs(); if (errcnt || ret_val) exit(1); return(0);}/* * onecol: print files with only one column of output. * Line length is unlimited. */intonecol(argc, argv) int argc; char *argv[];{ register int cnt = -1; register int off; register int lrgln; register int linecnt; register int num; int lncnt; int pagecnt; int ips; int ops; int cps; char *obuf; char *lbuf; char *nbuf; char *hbuf; char *ohbuf; FILE *inf; char *fname; int mor; if (nmwd) num = nmwd + 1; else num = 0; off = num + offst; /* * allocate line buffer */ if ((obuf = malloc((unsigned)(LBUF + off)*sizeof(char))) == NULL) { mfail(); return(1); } /* * allocate header buffer */ if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) { mfail(); return(1); } ohbuf = hbuf + offst; nbuf = obuf + offst; lbuf = nbuf + num; if (num) nbuf[--num] = nmchar; if (offst) { (void)memset(obuf, (int)' ', offst); (void)memset(hbuf, (int)' ', offst); } /* * loop by file */ while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) { if (pgnm) { /* * skip to specified page */ if (inskip(inf, pgnm, lines)) continue; pagecnt = pgnm; } else pagecnt = 1; lncnt = 0; /* * loop by page */ for(;;) { linecnt = 0; lrgln = 0; ops = 0; ips = 0; cps = 0; /* * loop by line */ while (linecnt < lines) { /* * input next line */ if ((cnt = inln(inf,lbuf,LBUF,&cps,0,&mor)) < 0) break; if (!linecnt && !nohead && prhead(hbuf, fname, pagecnt)) return(1); /* * start of new line. */ if (!lrgln) { if (num) addnum(nbuf, num, ++lncnt); if (otln(obuf,cnt+off, &ips, &ops, mor)) return(1); } else if (otln(lbuf, cnt, &ips, &ops, mor)) return(1); /* * if line bigger than buffer, get more */ if (mor) { lrgln = 1; continue; } /* * whole line rcvd. reset tab proc. state */ ++linecnt; lrgln = 0; ops = 0; ips = 0; } /* * fill to end of page */ if (linecnt && prtail(lines-linecnt-lrgln, lrgln)) return(1); /* * On EOF go to next file */ if (cnt < 0) break; ++pagecnt; } if (inf != stdin) (void)fclose(inf); } if (eoptind < argc) return(1); return(0);}/* * vertcol: print files with more than one column of output down a page */intvertcol(argc, argv) int argc; char *argv[];{ register char *ptbf; register char **lstdat; register int i; register int j; register int cnt = -1; register int pln; register int *indy; int cvc; int *lindy; int lncnt; int stp; int pagecnt; int col = colwd + 1; int mxlen = pgwd + offst + 1; int mclcnt = clcnt - 1; struct vcol *vc; int mvc; int tvc; int cw = nmwd + 1; int fullcol; char *buf; char *hbuf; char *ohbuf; char *fname; FILE *inf; int ips = 0; int cps = 0; int ops = 0; int mor = 0; /* * allocate page buffer */ if ((buf = malloc((unsigned)lines*mxlen*sizeof(char))) == NULL) { mfail(); return(1); } /* * allocate page header */ if ((hbuf = malloc((unsigned)(HDBUF + offst)*sizeof(char))) == NULL) { mfail(); return(1); } ohbuf = hbuf + offst; if (offst) (void)memset(hbuf, (int)' ', offst); /* * col pointers when no headers */ mvc = lines * clcnt; if ((vc = (struct vcol *)malloc((unsigned)mvc*sizeof(struct vcol))) == NULL) { mfail(); return(1); } /* * pointer into page where last data per line is located */ if ((lstdat = (char **)malloc((unsigned)lines*sizeof(char *))) == NULL){ mfail(); return(1); } /* * fast index lookups to locate start of lines */ if ((indy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) { mfail(); return(1); } if ((lindy = (int *)malloc((unsigned)lines*sizeof(int))) == NULL) { mfail(); return(1); } if (nmwd) fullcol = col + cw; else fullcol = col; /* * initialize buffer lookup indexes and offset area */ for (j = 0; j < lines; ++j) { lindy[j] = j * mxlen; indy[j] = lindy[j] + offst; if (offst) { ptbf = buf + lindy[j]; (void)memset(ptbf, (int)' ', offst); ptbf += offst; } else ptbf = buf + indy[j]; lstdat[j] = ptbf; } /* * loop by file */ while ((inf = nxtfile(argc, argv, &fname, ohbuf, 0)) != NULL) { if (pgnm) { /* * skip to requested page */ if (inskip(inf, pgnm, lines)) continue; pagecnt = pgnm; } else pagecnt = 1; lncnt = 0; /* * loop by page */ for(;;) { /* * loop by column */ cvc = 0; for (i = 0; i < clcnt; ++i) { j = 0; /* * if last column, do not pad */ if (i == mclcnt) stp = 1; else stp = 0; /* * loop by line */ for(;;) { /* * is this first column */ if (!i) { ptbf = buf + indy[j]; lstdat[j] = ptbf; } else ptbf = lstdat[j]; vc[cvc].pt = ptbf; /* * add number */ if (nmwd) { addnum(ptbf, nmwd, ++lncnt); ptbf += nmwd; *ptbf++ = nmchar; } /* * input next line */ cnt = inln(inf,ptbf,colwd,&cps,1,&mor); vc[cvc++].cnt = cnt; if (cnt < 0) break; ptbf += cnt; /* * pad all but last column on page */ if (!stp) { /* * pad to end of column */ if (sflag) *ptbf++ = schar; else if ((pln = col-cnt) > 0) { (void)memset(ptbf, (int)' ',pln); ptbf += pln; } } /* * remember last char in line */ lstdat[j] = ptbf; if (++j >= lines) break; } if (cnt < 0) break; } /* * when -t (no header) is specified the spec requires * the min number of lines. The last page may not have * balanced length columns. To fix this we must reorder * the columns. This is a very slow technique so it is * only used under limited conditions. Without -t, the * balancing of text columns is unspecified. To NOT * balance the last page, add the global variable * nohead to the if statement below e.g. * * if ((cnt < 0) && nohead && cvc ...... */ --cvc; /* * check to see if last page needs to be reordered */ if ((cnt < 0) && cvc && ((mvc-cvc) >= clcnt)){ pln = cvc/clcnt; if (cvc % clcnt) ++pln; /* * print header */ if (!nohead && prhead(hbuf, fname, pagecnt)) return(1); for (i = 0; i < pln; ++i) { ips = 0; ops = 0; if (offst&& otln(buf,offst,&ips,&ops,1)) return(1); tvc = i; for (j = 0; j < clcnt; ++j) { /* * determine column length */ if (j == mclcnt) { /* * last column */ cnt = vc[tvc].cnt; if (nmwd) cnt += cw; } else if (sflag) { /* * single ch between */ cnt = vc[tvc].cnt + 1; if (nmwd) cnt += cw; } else cnt = fullcol; if (otln(vc[tvc].pt, cnt, &ips, &ops, 1)) return(1); tvc += pln; if (tvc >= cvc) break; } /* * terminate line */ if (otln(buf, 0, &ips, &ops, 0)) return(1); } /* * pad to end of page */ if (prtail((lines - pln), 0)) return(1); /* * done with output, go to next file */ break; } /* * determine how many lines to output */ if (i > 0) pln = lines; else pln = j; /* * print header */ if (pln && !nohead && prhead(hbuf, fname, pagecnt)) return(1); /* * output each line */ for (i = 0; i < pln; ++i) { ptbf = buf + lindy[i]; if ((j = lstdat[i] - ptbf) <= offst) break; if (otln(ptbf, j, &ips, &ops, 0)) return(1); } /* * pad to end of page */ if (pln && prtail((lines - pln), 0)) return(1); /* * if EOF go to next file */ if (cnt < 0) break; ++pagecnt; } if (inf != stdin) (void)fclose(inf); } if (eoptind < argc) return(1); return(0);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?