/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1992-2010 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* pr
* Written by David Korn
* Mon Mar 30 15:07:41 EST 1992
*/
static const char usage[] =
"[-n?\n@(#)$Id: pr (AT&T Research) 2004-07-01 $\n]"
"[+NAME?pr - print files]"
"[+DESCRIPTION?\bpr\b formats and prints files to the standard output."
" If \afile\a is \b-\b or if no files are specified then the"
" standard input is read.]"
"[a:across?Print columns across rather than down; \b-\b\acolumns\a must be >1.]"
"[c:control?Print control characters in hat (^G) and octal form.]"
"[C:columns|cols?Print \acolumns\a columns of output. Can also be entered"
" as -\acolumns\a. May not be used with \b-m\b.]#[columns:=1]"
"[d:double-space?Double space the output.]"
"[e:expand?Expand \achar\a to \awidth\a.]:?[char[width]]:=\\t8]"
"[f:formfeed?Use formfeeds instead of newlines to separate pages with"
" a 3 line page header.]"
"[F:bigformfeed?Use formfeeds instead of newlines to separate pages with"
" a 5 line page header and trailer.]"
"[h:header?Use \aheader\a instead of the file name in header text.]:[header]"
"[i:replace?Replace spaces with \achar\as to tab \awidth\a.]:?"
" [char[width]]:=\\t8]"
"[j:join?Merge full lines.]"
"[l:lines?The page length in lines. 10 lines are reserved for the header"
" and trailer.]#[lines:=66]"
"[m:multiple?Print the input files one per column, truncating lines to fit.]"
"[n:number?Number lines with \adigits\a digits followed by \asep\a.]:?"
" [sep[digits]]:=\\t5]"
"[o:indent|margin|offset?Indent each line with \aindent\a spaces.]#[indent:=0]"
"[p:pause?Pause before printing each page if the output is to a terminal."
" \apr\a prinst a BEL on the terminal and reads one line of input"
" before continuing. (Not implemented.)]"
"[P:page?Start printing with page \apage\a. Can also be entered as +\apage\a.]"
" #[page:=1]"
"[r!:warn?Warn about unreadable input files.]"
"[s:separate?Separate columns with \astring\a.]:?[string]"
"[t|T!:headers?Generate headers and trailers and pass form feeds in the input"
" to the output.]"
"[w:width?The page width in characters.]#[width:=72]"
"[v:literal?Print control characters in C-style form.]"
"[X:test?Canonicalize output for testing.]"
"\n"
"\n[ file ... ]\n"
"\n"
"[+SEE ALSO?\bcat\b(1), \bfold\b(1), \bless\b(1), \bmore\b(1)]"
;
#include <cmd.h>
#include <ctype.h>
#include <ccode.h>
#include <ls.h>
#include <tm.h>
typedef struct _pr_
{
long pageno;
long pageskip;
long lineno;
int pagelen;
int offset;
int offlen;
int numwidth;
int columns;
int colno;
int width;
int flags;
int nopen;
int pageodd;
char **fieldlist;
char *fieldbuff;
char *fieldptr;
char **fieldlast;
char *header;
char *margin;
char *filename;
char *date;
struct
{
char *buf;
char *cur;
char *end;
unsigned char *map;
} control;
} Pr_t;
/*
* allocate and initialize pr global data
*/
{
return 0;
return pp;
}
/*
* print the page header
*/
{
return -1;
return 0;
}
/*
* print the page trailer
*/
{
{
if(n==0)
else
}
{
return -1;
}
else
{
return -1;
}
return 0;
}
/*
* fastest version, process a page at a time
*/
{
while(1)
{
break;
{
break;
}
}
}
/*
* write <space> space characters into output buffer using
* tab characters where appropriae.
* <col> is the number of columns until the next tab position
* The number of characters written is returned
*/
{
register int n=0;
{
/* changes spaces <pp->otab> */
{
return -1;
n++;
}
}
if(spaces>0)
return -1;
return n+=spaces;
}
/*
* Output one column which could be the complete line
* Do tab canonicalization if necessary
* <spaces> give the number of spaces that precede the field
* This routine returns the number of spaces at end of field
*/
{
register int omod=0;
{
{
goto skip;
}
while(1)
{
/* skip over regular characters */
{
{
break;
}
}
if(n==S_NL)
break;
return -1;
return 1;
size = 0;
skip:
{
if(n==S_SPACE)
n = 1;
else
size += n;
col += n;
}
if(n==S_NL)
{
/* delete trailing white-space */
return 0;
}
{
/* return spaces needed to complete field */
{
{
return 0;
}
}
else
return size;
}
size = 0;
}
}
return -1;
return 0;
}
/*
* print a line at a time
*/
{
register char *cp;
{
return 0;
}
{
{
line = 0;
return -1;
}
return -1;
{
else
}
}
return 0;
}
/*
* output page containing <n> fields
*/
{
{
return 0;
}
incr = 1;
else
while(1)
{
/* print out a line */
{
break;
}
break;
{
j=0;
if(j==0)
c = '\n';
else
c = ' ';
return -1;
{
else
old = 0;
}
}
break;
}
return 0;
}
/*
* This routine processes multi-column and merged files
* The data is put into in array and printed when the page fills.
*/
{
register int n=0, size;
do
{
{
nstream = 0;
}
while(1)
{
{
if(!skip)
}
{
if(fp)
{
{
break;
}
}
size=1;
}
else
break;
break;
{
nstream = 0;
}
}
if(skip>0)
{
skip--;
break;
}
}
while(cp);
return r;
}
static ssize_t
{
register char* s = (char*)buf;
register char* e = s + n;
register int c;
ssize_t z;
{
{
}
return z;
}
{
{
if (c > (e - s))
break;
while (c--)
}
else
{
if (c > 040 || c == 011 || c == 012)
else if ((e - s) < 2)
break;
else
{
*s++ = '^';
*s++ = hat[c];
}
}
}
return s - (char*)buf;
}
static ssize_t
{
register char* s = (char*)buf;
register char* e = s + n;
register char* t;
register int c;
ssize_t z;
{
{
}
return z;
}
{
{
if (c > (e - s))
break;
while (c--)
}
else
{
{
if (strlen(t) > (e - s))
{
break;
}
while (*s = *t++)
s++;
}
else
*s++ = c;
}
}
return s - (char*)buf;
}
int
{
register int n;
register char *cp;
for (;;)
{
{
case 0:
break;
case 'a':
continue;
case 'c':
continue;
case 'd':
continue;
case 'f':
continue;
case 'F':
continue;
case 'm':
continue;
case 'p':
continue;
case 'r':
continue;
case 't':
case 'T':
continue;
case 'C':
else
continue;
case 'h':
continue;
case 'w':
continue;
case 'l':
continue;
case 'o':
continue;
case 'P':
continue;
case 'n':
case 'i':
case 'e':
if(opt_info.arg && opt_info.arg==argv[opt_info.index-1] && (!(cp=argv[opt_info.index]) || *cp!='-'))
{
/* space allowed only if next argument
* begins with - */
}
if(n=='e')
else if(n=='i')
else
{
{
if(n=='e')
else if(n=='i')
else
}
{
if(n=='e')
else if(n=='i')
else
}
}
continue;
case 's':
if(opt_info.arg && opt_info.arg==argv[opt_info.index-1] && (!(cp=argv[opt_info.index]) || *cp!='-'))
{
/* space allowed only if next argument
* begins with - */
}
else
continue;
case 'v':
continue;
case 'X':
continue;
case ':':
break;
case '?':
break;
default:
continue;
}
break;
}
if(error_info.errors)
{
}
#if 0
#endif
{
{
}
else
{
#if 0
#else
#endif
}
}
{
/* pre-compute leading margin */
{
}
else
n = 0;
{
if(n-- > 0)
else
*cp = ' ';
}
}
argv++;
do
{
{
continue;
}
else
{
{
else
tmfmt(pp->date, DATESZ, "%b %e %H:%M %Y", fstat(sffileno(fp), &statb) ? (time_t*)0 : &statb.st_mtime);
}
{
n=1;
continue;
}
else
}
}
{
}
return error_info.errors != 0;
}