home *** CD-ROM | disk | FTP | other *** search
- /*
-
- NAME
- apr -- source print utility
-
- SYNOPSIS
- apr [ -FHbfhlnpst ] [ files ... ]
-
- DESCRIPTION
- Apr prints the named files on the stdout. If the file specification
- is '-' or no files were specified, the stdin is assumed. The
- listing is separated into pages with the fixed size (user can
- configure any desired page size). By default, plain pages will be
- produced, but this option allows to set up either header with file
- status data and footer with page numbers, or custom header/footer.
- Apr also recognizes text patterns as page-advance commands. This
- means that a new page will be forced whenever the program finds
- that pattern at the first column of the input line.
-
-
- OPTIONS
- -F <string> Use <string> as the message to be printed in the footer
- instead of the copyright. Note that this option is ignored if
- -s option is not used.
-
- -H <string> Use <string> as the message to be printed in the header
- instead of the file name and it's size. Note that this option
- is ignored if -s option is not used.
-
- -b <string> Program will force a new page each time when it finds
- <string> at the beginning of the input line. Default value of
- <string> is /**.
-
- -f <number> Set the bottom margin to <number> lines (default 2).
-
- -h <number> Set the top margin to <number> lines (default 0).
-
- -l <number> Set the line width to <number> characters (default 78).
-
- -n Use the form-feed character for new pages (default is newlines).
-
- -p <number> Set page length to <number> lines (default 72).
-
- -r Provide 6-digit line numbering.
-
- -s Enable headers and footers.
-
- -t <number> Set tab-size to <number> characters (default 4).
-
- FILES
-
- VARIABLES
-
- CAVEATS
-
- SEE ALSO
-
- REFERENCES
-
- REVISIONS
- 10/15/88 Andreo Curko, NightWingers: tested
- 11/14/88 Andreo Curko, NightWingers: documented
- 12/13/88 Tom Sagrak, NightWingers: revised for uploading
-
- COPYRIGHT
- Copyright (c) 1988 by NightWingers, Zagreb
-
- Tom Sagrak
- Draskoviceva 29
- YU-41000 ZAGREB
- Yugoslavia
-
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appears in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of NightWingers not be used
- in advertising or publicity pertaining to distribution of
- the software without specific, written prior permission.
- NightWingers makes no representations about the suitability of
- this software for any purpose. It is provided "as is"
- without express or implied warranty.
-
- If you find apr of value, and like to use it, a contribution of
- $ 5 or more would be appreciated.
-
- */
-
- #include <errno.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdio.h>
- #include <time.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #ifdef UNIX
- #include <sys/timeb.h>
- #endif
-
- #ifdef MSDOS
- #include <stdlib.h>
- #include <process.h>
- #include <io.h>
- #endif
-
- #define TRUE 1
- #define FALSE 0
- #define OUTPUT stdout
- #define NO_ERRS 0
- #define NP_ERR 1
- #define USAGE 1
-
- #ifdef UNIX
- extern int getopt();
- extern int optind;
- extern char *optarg;
- #endif
-
-
-
- /**/
- #ifdef MSDOS
- /*
- * name getopt - parse the command line options, System V style.
- *
- * synopsis int getopt(argc, argv, optionS);
- * int argc; no. of arguments in the command line
- * char *argv[]; argument vector
- * char *optionS; definition list of options
- * extern int optind; index of the next argument
- * extern char *optarg; current option's argument
- *
- * description Standard option syntax is:
- * option ::= SW [optLetter] [argLetter space* argument]
- * where
- * - SW is '-'
- * - there is no space before any optLetter or argLetter.
- * - opt/arg letters are alphabetic, not punctuation characters.
- * - optLetter, if present, must be matched in optionS.
- * - argLetters, if present, are found in optionS followed by ':'.
- * - argument is any white-space delimited string. Note that it
- * can include the SW character.
- * - upper and lower case letters are distinct.
- * returns (int) ch - current option if OK
- * - '?' if error in argument vector
- * - EOF when no more options
- *
- **/
-
- int optind = 1; /* index of which argument is next */
- char *optarg; /* pointer to argument of current option */
-
- static char *letP; /* remember next option char's location */
- static char SW = '-'; /* switch character */
-
- int
- getopt(argc,argv,optionS)
- int argc;
- char *argv[], *optionS;
- {
- unsigned char ch;
- char *optP;
-
- if (argc > optind) {
- if ((letP = argv[optind]) == NULL || *(letP++) != SW)
- goto gopEOF;
- if (*letP == SW) {
- optind++;
- goto gopEOF;
- }
- if ((ch = *(letP++)) == '\0') {
- optind++;
- goto gopEOF;
- }
- if (ch == ':' || (optP = strchr(optionS, ch)) == NULL) {
- optind++;
- goto gopError;
- }
- if (*(++optP) == ':') {
- optind++;
- if (*letP == '\0') {
- if (argc <= optind)
- goto gopError;
- letP = argv[optind++];
- }
- optarg = letP;
- letP = NULL;
- }
- else {
- optind++;
- letP = NULL;
- optarg = NULL;
- }
- return ch;
- }
- gopEOF:
- optarg = letP = NULL;
- return EOF;
-
- gopError:
- optarg = NULL;
- return ('?');
- }
- #endif
-
- /**/
- #define LINESIZE 512
- #define OPTDEFS "p:l:t:b:h:f:F:H:nsr" /* program options */
-
- static struct stat statbuf; /* buffer for a stat info */
- static FILE *input; /* current input stream */
- static char globline[LINESIZE], /* global buffer for input line */
- cbrk[] = "/\**", /* default page-break string */
- *brkstring, /* default page-advance string */
- *foottext, /* pointer to footer message */
- *nofile = "(stdin)",/* if no filename specified */
- *filename, /* name of file currently printed */
- *filetime, /* it's time of the last modification */
- brkbuf[24], /* buffer for a page-break string */
- footbuf[60], /* buffer for a footer message */
- headbuf[60]; /* buffer for a header message */
- static int tabsize = 4, /* de~r}i}i~fault tab width */
- brklen = 3, /* length of page-advance string */
- footlen = 30, /* length of the footer message */
- lines_per_page = 72,/* physical page length in lines */
- header_margin = 0, /* default values for header and */
- footer_margin = 2, /* footer margin */
- no_ff = TRUE, /* use <LF> instead of <FF> */
- line_number = 0, /* line counter */
- do_lnum = FALSE, /* if set lines will be numbered */
- A_status = FALSE, /* if set status lines will be ON */
- footmessage = FALSE,/* if set user defines footer text */
- headmessage = FALSE,/* if set user defines header text */
- linesize = 78, /* default paper width in chars */
- paperwidth, /* info for header() and footer() */
- ln_cnt, /* line number in a single input line */
- page_no; /* current page number in a stream */
- static long flsize; /* it's size in bytes */
-
- static char *copywr = "(C) NightWingers 1988";
-
- /**/
- #ifdef MSDOS
-
- static void
- usage()
- {
- fprintf(stderr,"Apr Source Print Utility Version 2.0\n");
- fprintf(stderr,"Copyright (C) NightWingers 1988. All rights reserved.\n");
- fprintf(stderr,"usage: apr [options] [file ...]\n");
- fprintf(stderr,"options: -FHbfhlnpst\n");
- fprintf(stderr," F <string> - redefine footer message (only with -s option)\n");
- fprintf(stderr," H <string> - redefine header message (only with -s option)\n");
- fprintf(stderr," b <string> - redefine page-break string (/\**)\n");
- fprintf(stderr," f <number> - bottom margin in lines (2)\n");
- fprintf(stderr," h <number> - top margin in lines (0)\n");
- fprintf(stderr," l <number> - paper width in characters (78)\n");
- fprintf(stderr," n - use <FF> instead of <nl> for new page (<nl>)\n");
- fprintf(stderr," p <number> - paper size in lines (72)\n");
- fprintf(stderr," r - include line numbers (NO)\n");
- fprintf(stderr," s - output with status (NO)\n");
- fprintf(stderr," t <number> - tab distance in characters (4)\n");
- fprintf(stderr,"example: apr -s -F \"Acct. procs\" -t 8 -h 4 *.awk | lpr");
- exit(USAGE);
- }
-
- #else
-
- static void
- usage()
- {
- fprintf(stderr,"usage: apr [-FHbfhlnpst] [file ...]\n");
- exit(USAGE);
- }
-
- #endif
-
- /**
- *
- * name header
- *
- * synopsis void header();
- *
- * description
- *
- * return -*-
- *
- **/
-
- static void
- header()
- {
- int i = header_margin;
- int g;
-
- while (i--)
- fputc('\n',OUTPUT);
- if (A_status) {
- if (headmessage) {
- g = paperwidth - (strlen(headbuf) + 24);
- fprintf(OUTPUT,"%-s",headbuf);
- }
- else {
- g = (paperwidth - (strlen(filename) + 6 + 24)) >> 1;
- fprintf(OUTPUT,"%-s",filename);
- for (i=0; i<g; i++)
- fputc(' ',OUTPUT);
- if (flsize)
- fprintf(OUTPUT,"%-6ld",flsize);
- else
- fprintf(OUTPUT,"%6s"," ");
- }
- for (i=0; i<g; i++)
- fputc(' ',OUTPUT);
- fprintf(OUTPUT,"%-s",filetime);
- for (i = 0;i < paperwidth;i++)
- fputc('_',OUTPUT);
- fprintf(OUTPUT,"\n\n");
- }
- ln_cnt = lines_per_page - header_margin - footer_margin;
- }
-
- /**
- *
- * name footer
- *
- * synopsis void footer();
- *
- * description
- *
- * return -*-
- *
- **/
-
- static void
- footer()
- {
- int i = footer_margin;
- int j;
- char page_no_str[6];
-
- while (ln_cnt > 0) {
- fputc('\n',OUTPUT);
- ln_cnt--;
- }
- if (A_status) {
- fputc('\n',OUTPUT);
- for (j = 0;j < paperwidth;j++)
- fputc('_',OUTPUT);
- fprintf(OUTPUT,"\n%s", foottext);
- for (j = 0; j < paperwidth-(footlen+5);j++)
- fputc(' ',OUTPUT);
- sprintf(page_no_str,"[%d]",page_no);
- fprintf(OUTPUT,"%5s\n",page_no_str);
- }
- if (no_ff) {
- while (i--)
- fputc('\n',OUTPUT);
- }
- else
- fputc('\f',OUTPUT);
- page_no++;
- }
-
- /**
- *
- * name put_ln
- *
- * synopsis void put_ln(line, lin_cnt);
- * char *line;
- * int lin_cnt;
- *
- * description
- *
- * return -*-
- *
- **/
-
- static void
- put_ln(line, lin_cnt)
- char *line;
- int lin_cnt;
- {
- char c;
- register i,j;
-
- for(i=0;i<lin_cnt;i++) {
- if(ln_cnt <= 0)
- header();
- if (do_lnum) {
- if (i == 0) {
- line_number++;
- fprintf(OUTPUT,"%-6d: ",line_number);
- }
- else
- fprintf(OUTPUT," : ");
- }
- for(j=0;j<linesize && *line;j++) {
- c = *line++;
- fputc(c,OUTPUT);
- }
- if (c != '\n')
- fputc('\n',OUTPUT);
- ln_cnt--;
- if(ln_cnt <= 0)
- footer();
- }
- }
-
- /**
- *
- * name do_ln
- *
- * synopsis void do_ln(line);
- * char *line;
- *
- * description
- *
- * return -*-
- *
- **/
-
- static void
- do_ln(line)
- char *line;
- {
- static char buf[512];
- static char *p;
- int cnt = 1;
-
- p = buf;
- if ( ! strncmp(brkstring,line,brklen)) {
- if (ln_cnt > 0)
- footer();
- }
- while(*line) {
- if(*line == '\t') {
- do{
- *p++ = ' ';
- } while(cnt++ % tabsize != 0);
- ++line;
- }
- else {
- ++cnt;
- *p++ = *line++;
- }
- }
- *p = '\0';
- cnt = strlen(buf);
- put_ln(buf, 1 + cnt/(linesize+1));
- }
-
- static void
- do_file()
- {
- char *l;
- page_no = 1;
- ln_cnt = line_number = 0;
- while((l = fgets(globline, LINESIZE, input)) != NULL)
- do_ln(l);
- footer();
- }
-
- /**/
- void
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int ch;
- int pom;
-
- brkstring = cbrk;
- while ((ch = getopt(argc,argv,OPTDEFS)) != EOF ) {
- switch(ch) {
- case 'l':
- pom = atoi(optarg);
- if (pom >= 40 && pom <= 255)
- linesize = pom;
- break;
- case 't':
- pom = atoi(optarg);
- if (pom > 0 && pom <= 20)
- tabsize = pom;
- break;
- case 'p':
- pom = atoi(optarg);
- if (pom >= 20) {
- if (A_status)
- lines_per_page = pom - 6;
- else
- lines_per_page = pom;
- }
- break;
- case 'h':
- pom = atoi(optarg);
- if (pom >= 0 && pom <= 20)
- header_margin = pom;
- break;
- case 'f':
- pom = atoi(optarg);
- if (pom >= 0 && pom <= 20)
- footer_margin = pom;
- break;
- case 'n':
- no_ff = FALSE;
- break;
- case 'r':
- do_lnum = TRUE;
- break;
- case 's':
- if (! A_status)
- lines_per_page -= 6;
- A_status = TRUE;
- break;
- case 'b':
- strcpy(brkbuf, optarg);
- brkstring = brkbuf;
- brklen = strlen(brkstring);
- break;
- case 'F':
- strcpy(footbuf, optarg);
- footmessage = TRUE;
- break;
- case 'H':
- strcpy(headbuf, optarg);
- headmessage = TRUE;
- break;
- case '?':
- usage();
- break;
- }
- }
- paperwidth = linesize;
- if (do_lnum)
- linesize -= 10;
- if (footmessage) {
- footlen = strlen(footbuf);
- foottext = footbuf;
- }
- else {
- foottext = copywr;
- }
- if (optind == argc) { /* stdin */
- filename = nofile;
- time(&flsize);
- filetime = ctime(&flsize);
- flsize = 0L;
- input = stdin;
- do_file();
- }
- else {
- for(; optind<argc; ++optind) {
- filename = argv[optind];
- if (stat(argv[optind], &statbuf) == EOF) {
- perror(argv[optind]);
- exit(ENOENT);
- }
- if (!(statbuf.st_mode & 0x8000)) {
- fprintf(stderr,"%s: not an ordinary file\n",filename);
- exit(NP_ERR);
- }
- flsize = statbuf.st_size;
- filetime = ctime(&(statbuf.st_mtime));
- if((input = fopen(argv[optind], "r")) == NULL) {
- perror(argv[optind]);
- exit(EACCES);
- }
- do_file();
- }
- }
- exit(NO_ERRS);
- }