Category : Tutorials + Patches
Archive   : INTER43D.ZIP
Filename : INTPRINT.C
Output of file : INTPRINT.C contained in archive : INTER43D.ZIP
/* INTPRINT.C by Ralf Brown. Donated to the Public Domain. */
/* Please do not remove my name from any copies or derivatives. */
/************************************************************************/
/* Program History: */
/* v1.00 4/23/89 initial public release */
/* with 4/30/89 list */
/* v1.10 5/21/89 added -I and -f */
/* v1.11 1/6/90 fixed #endif's for compilers which don't handle */
/* labels */
/* v1.20 6/8/90 added -r */
/* v1.30 7/14/90 added -b, tables now stay aligned on odd indents */
/* v1.40 10/6/90 added -B based on changes by Naoto Kimura, -w */
/* v1.40a 5/6/91 HP LaserJet II support by Russ Herman */
/* v1.41 7/9/91 HP PCL support by P.J.Farley III */
/* v2.00 9/1/91 modular printer definitions */
/* printing multipart interrupt list */
/* v2.01 2/9/92 fixed summary entry for non-numeric AX= and AH= */
/* smarter page breaks */
/* v2.02 2/18/92 bugfix & isxdigit suggested by Aaron West */
/* v2.10 3/14/92 updated to handle extra flags in headings */
/* v2.11 5/23/92 bugfix pointed out by Joe White */
/* v2.20 6/12/92 added -F based on code by Richard Brittain */
/* added -H and Panasonic printer def by Lewis Paper */
/* v2.21 10/14/92 fixed error in -H/-r interaction */
/* updated for new 'Bitmask of' section */
/* v2.22 2/15/93 exclude Index: by default, -x to force inclusion */
/* changed 'Bitmask of' to 'Bitfields for' */
/* v2.23 5/24/93 fix to allow INT/AL= to appear correctly in summary*/
/* v2.24 7/15/93 -k and infinite-length pages by Bent Lynggaard */
/* v3.00 6/4/94 -T, -V, and multi-file break section skipping */
/* major speedups; checked for BC++3.1 compatibility */
/* v3.01 6/11/94 bugfix: crashed with -l0 -L1 on lines >=80 chars */
/************************************************************************/
/* Recompiling: */
/* Turbo C / Borland C++ */
/* tcc -mt -lt -O -a -Z -p -k- intprint */
/* bcc -mt -lt -a -O1agim -p intprint.c */
/************************************************************************/
#include
#include
#include
#include
#include
#include
#define VERSION "3.01"
/***********************************************/
/* portability definitions */
#define _other_ /* assume no system-specific match */
/*--------------------------------------------------*/
/* first system: MS-DOS with Turbo/Borland C */
#ifdef __TURBOC__
# define PROTOTYPES
# include
# include
int _Cdecl isatty(int handle) ;
/* definitions to reduce size of executable */
unsigned int _Cdecl _stklen = 1024 ;
#define close _close
#define read _read
#define write _write
void _Cdecl _setenvp(void) {} /* don't need environment--don't include it */
void *_Cdecl malloc(size_t size) { return sbrk(size) ; }
void _Cdecl free(void *var) { (void)var ; }
/* since our free() doesn't do anything, macro it out of existence */
#define free(p)
#ifdef __BORLANDC__
void _Cdecl _setupio(void) {}
#pragma warn -eff
#endif
#undef _other_
#endif /* __TURBOC__ */
#ifdef __MSDOS__
# define LINE_TERMINATOR '\n'
#endif
/*--------------------------------------------------*/
/* Gnu C compiler */
#ifdef __GNUC__
#define PROTOTYPES
#define NEED_ITOA
#define NEED_ULTOA
#define NEED_STRUPR
#define NEED_STRNICMP
#undef _other_
#endif /* __GNUC__ */
/*--------------------------------------------------*/
/* generic Unix definitions */
#ifdef unix
# include
# include
extern int isatty(int) ;
# define LINE_TERMINATOR '\n'
#endif
/*--------------------------------------------------*/
/* any other system */
#ifdef _other_
/* unknown compiler/system, so set configuration #defines */
#if 0 /* set to 1 if compiler supports ANSI-style prototypes, 0 otherwise */
#define PROTOTYPES
#endif
#if 1 /* set to 0 if library contains strnicmp(), 1 otherwise */
#define NEED_STRNICMP
#endif
#if 1 /* set to 0 if library contains isxdigit(), 1 otherwise */
#define NEED_ISXDIGIT
#endif
#if 1 /* set to 0 if library contains strupr(), 1 otherwise */
#define NEED_STRUPR
#endif
#if 1 /* set to 0 if library contains three-arg itoa(), 1 otherwise */
#define NEED_ITOA
#endif
#if 1 /* set to 0 if library contains three-arg ultoa(), 1 otherwise */
#define NEED_ULTOA
#endif
/* the last character of the line termination sequence, i.e. '\n' for CRLF */
/* and LF, '\r' if your system uses CR or LFCR */
#define LINE_TERMINATOR '\n'
#endif /* _other_ */
/*--------------------------------------------------*/
/* catchall for macros which might not be defined */
#ifndef O_BINARY
# define O_BINARY 0
#endif
#ifndef _Cdecl
# define _Cdecl
#endif
/***********************************************/
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE !FALSE
#endif
/***********************************************/
#define MAXLINE 82 /* at most 80 chars per line (plus CR and newline) */
#define MAXPAGE 200 /* at most 200 lines per page */
#define lengthof(x) (sizeof(x)/sizeof(x[0]))
#define divider_line(line) (line[0] == '-' && memcmp(line+1,"-------",7) == 0)
#ifdef __MSDOS__
#define start_of_entry(s) (((int*)s)[0]==(256*'N'+'I')&&((int*)s)[1]==(256*' '+'T'))
#define index_line(l) \
(((int*)l)[0]==(256*'n'+'I')&&((int*)l)[1]==(256*'e'+'d')&& \
((int*)l)[2]==(256*':'+'x'))
#else
#define start_of_entry(s) (memcmp(s,"INT ",4) == 0)
#define index_line(line) (line[0] == 'I' && memcmp(line+1,"ndex:",5) == 0)
#endif
#define section_start(line) is_keyword(line,section_start_keys,lengthof(section_start_keys))
#define start_of_table(line) (is_keyword(line,table_start_keys,lengthof(table_start_keys)))
#define section_file_start(s) (s[0] == '-' && memcmp(s+1,"-------!---Section",18) == 0)
/***********************************************/
/* replacement file I/O function macros */
/***********************************************/
typedef struct
{
int fd ;
int buf_maxsize ;
char *buf ;
unsigned long bufoffset ;
int bufsize ;
int bufpos ;
int write ; /* file is output file if nonzero */
} IP_FILE ;
#define ip_putc(c,fp) \
((fp)->buf[fp->bufpos++]=(c),\
((fp)->bufpos>=(fp)->buf_maxsize&&ip_flush(fp)==-1)?-1:0)
/* output the indicated counted string to the given file */
#define ip_putcstr(s,fp) ip_write((s)->str,(s)->len,fp)
/* output the given string literal to the indicated file */
#define ip_putlit(s,fp) ip_write((s),sizeof(s)-1,fp)
/* output the given string variable to the indicated file */
#define ip_puts(s, fp) ip_write(s,strlen(s),fp)
#ifdef __MSDOS__
#define newline(fp) ip_write("\r\n",2,fp)
#else
#define newline(fp) ip_putc('\n',fp)
#endif
/***********************************************/
typedef struct /* a counted string */
{
int len ; /* the string's length */
char *str ; /* the actual contents of the string */
} cstr ;
#define CSTR(s) { sizeof(s)-1, (s) } /* for defining a counted string literal */
#define cstrlen(s) ((s)->len) /* how long is the counted string? */
typedef struct
{
char *name ; /* for selecting the appropriate printer */
cstr init1, init2 ; /* initialization strings */
cstr marginl, marginc, marginr ; /* margins: duplex even, non-duplex, duplex odd */
cstr duplex_on ; /* turn on duplex mode */
cstr term1, term2 ; /* cleanup strings */
cstr bold_on, bold_off ; /* boldface on/off */
int indent ; /* how many extra spaces to indent */
int lines_per_page ; /* how many lines to print on each page */
int page_length ; /* how many lines on each page */
int page_width ; /* how many printable columns per line? */
#ifdef PROTOTYPES
void (*put_line)(IP_FILE *,int) ;/* function to call to print out divider line */
void (*set_typeface)(IP_FILE *,char *) ;
#else
void (*put_line)() ; /* function to call to print out divider line */
void (*set_typeface)() ;
#endif /* PROTOTYPES */
int *flag ; /* flag to set when using this printer definition */
} PRINTER_DEF ;
typedef struct filter_list
{
struct filter_list *next ;
char str[1] ; /* will allocate enough for actual string */
} FILT_LIST ;
typedef struct
{
int part ;
int first_on_page ; /* TRUE if a new entry starts at the top of the page */
char desc[24] ;
int len ;
} HEADER ;
typedef struct
{
/* char *name ;*/
char name[14] ;
int length ;
} KEYWORDS ;
/***********************************************/
#ifdef PROTOTYPES
void usage(void) ;
void fatal(char *msg) ;
void warning(char *msg) ;
int unwanted_section(char *buf) ;
IP_FILE *ip_fdopen(int fd,char *buf,int bufsiz, int maxsiz, int write) ;
IP_FILE *ip_open_write(char *name, int trunc, char *buf, int bufsiz) ;
IP_FILE *ip_open_read(char *name, char *buf, int bufsiz) ;
int ip_close(IP_FILE *fp) ;
unsigned long ip_fgets(char *buf, int max, IP_FILE *fp) ;
int ip_write(char *buf, int count, IP_FILE *fp) ;
int ip_flush(IP_FILE *fp) ;
void get_raw_line(char *buf) ;
void get_line(char *buf) ;
void indent_to(int where,IP_FILE *fp) ;
void put_line(IP_FILE *fp, int len) ;
void HPPCL_put_line(IP_FILE *fp, int len) ;
void HPPCL_set_typeface(IP_FILE *fp,char *typeface) ;
int is_keyword(char *s, KEYWORDS *keys, unsigned int numkeys) ;
void output_line(char *line,IP_FILE *fp) ;
void fill_buffer(int lines, int lines_per_page) ;
int find_page_break(int lines) ;
int summarize(int line, int pages_printed) ;
void start_format(char *line) ;
void write_summary_header(IP_FILE *fp, char *title, int offsets, int tables) ;
void show_offset(int line,IP_FILE *fp) ;
void add_table(int i) ;
FILT_LIST *add_filter_info(FILT_LIST *list,char *str) ;
void build_filter_lists(char *file) ;
int make_description(char *desc,int line) ;
char *determine_heading(int last) ;
void print_buffer(int last,int body_lines,int lines_per_page,int total_lines,
int use_FF) ;
void select_printer(char *name) ;
void display_printers(void) ;
static void reset_printer_and_close(IP_FILE *fp) ;
int _Cdecl main(int argc, char **argv) ;
#else
void put_line() ;
void HPPCL_put_line() ;
void HPPCL_set_typeface() ;
void show_offset() ;
#endif /* PROTOTYPES */
/***********************************************/
/* I/O buffers */
/***********************************************/
char stderr_buf[256] ;
char filter_buf[256] ;
char infile_buf[8192] ;
char outfile_buf[8192] ;
char summary_buf[4096] ;
char formats_buf[3072] ;
char tables_buf[3072] ;
/***********************************************/
IP_FILE *err ;
IP_FILE *infile ;
IP_FILE *outfile ;
char *input_file ;
int input_file_namelen ;
char buffer[MAXPAGE][MAXLINE] ;
unsigned long line_offsets[MAXPAGE] ;
char num[6] ;
int need_summary ;
char summary_line[2*MAXLINE] ;
int summary_line_len ;
int pages_printed = 0 ;
int page_width = 0 ; /* page width in characters, 0 = use prtdef */
int indent = 0 ; /* number of columns to indent lines */
char *indent_string = NULL ; /* what to add at start of line to indent */
int indent_len = 0 ; /* length of indent_string */
int widow_length = 8 ; /* number of lines to scan for good place to break */
int page_numbers = FALSE ; /* add page numbers to bottom of page? */
int multi_file = FALSE ; /* printing multipart interrupt list? */
int out_of_files = FALSE ; /* hit end of last file for multipart printing? */
int do_summary = FALSE ; /* create a one-line-per-call summary? */
int do_tables = FALSE ; /* create a one-line-per-table index? */
int do_formats = FALSE ; /* create a separate file with data structures? */
int do_filter = FALSE ; /* using a filtering file? */
int do_headers = FALSE ; /* add page headings? */
int include_index_lines = FALSE ;
int IBM_chars = FALSE ; /* printer can handle IBM graphics characters */
int boldface = FALSE ; /* boldface titles and Return:/Notes: ? */
int printer_bold = FALSE ; /* boldface using printer control sequences? */
int echo_format = FALSE ;
int duplex = FALSE ;
int HPPCL_mode = FALSE ;
int show_offsets = FALSE ;
int keep_divider_lines = FALSE ;
IP_FILE *summary ;
IP_FILE *tables ;
IP_FILE *formats ;
PRINTER_DEF *printer = NULL ;
unsigned long current_line_offset = 0 ;
unsigned long offset_adjust = 0 ;
unsigned int first_page = 0 ;
unsigned int last_page = ~0 ;
int prev_table = 0 ;
FILT_LIST *includes = NULL ;
FILT_LIST *excludes = NULL ;
HEADER header_first = { 0, FALSE, "" } ;
HEADER header_last = { 0, FALSE, "" } ;
/***********************************************/
PRINTER_DEF printers[] =
{
{ "default",
CSTR(""), CSTR(""),
CSTR(""), CSTR(""), CSTR(""),
CSTR(""),
CSTR(""), CSTR(""),
CSTR(""), CSTR(""),
-1,
60,
0,
79,
put_line,
NULL,
NULL,
},
{ "Epson FX80, 12 cpi",
CSTR("\033M"), CSTR(""),
CSTR("\033l\004"), CSTR("\033l\007"), CSTR("\033l\014"),
CSTR(""),
CSTR("\033P"), CSTR("\033l\000"),
CSTR("\033E"), CSTR("\033F"),
0,
60,
0,
87, /* 96 - left margin - 1 right margin */
put_line,
NULL,
NULL,
},
{ "Panasonic KX-P1124i / 10 cpi Epson",
CSTR(""), CSTR(""),
CSTR(""), CSTR(""), CSTR(""),
CSTR(""),
CSTR(""), CSTR(""),
CSTR("\033E"), CSTR("\033F"),
-1,
60,
0,
79,
put_line,
NULL,
NULL,
},
{ "HP PCL",
CSTR("\033(8U"), CSTR(""),
CSTR("\033&a4c4L"), CSTR("\033&a8c8L"), CSTR("\033&a12c12L"),
CSTR("\033&l1S"),
CSTR("\033E"), CSTR(""),
CSTR("\033(s3B"), CSTR("\033(s0B"),
0,
69,
0,
87, /* 96 - left margin - 1 right margin */
HPPCL_put_line,
HPPCL_set_typeface,
&HPPCL_mode,
},
#define HPPCL_FONT_ON_A "\033(s0p12h10v0s0b"
/* HP PCL4/5 Font select: Roman-8;Upright12Pitch10PointMediumWeight */
#define HPPCL_FONT_ON_B "T\033&l6.8571C"
/* HP PCL4/5 Font select: End typeface select;VMI=7LPI: (48/7)-48th's inches*/
#define HPPCL_IBM_LN_A "\033&f0S\033*p-15Y\033*c"
/* HP PCL4/5 IBM Line: Push Pos;Up 15/720";Hor.Rule ???/300ths" long */
#define HPPCL_IBM_LN_B "a3b0P\033&f1S"
/* HP PCL4/5 IBM Line: 3/300ths" high,Print rule;Pop Position */
{ "LaserJet II",
CSTR("\033(10U"),CSTR(""),
CSTR("\033&a4c4L"), CSTR("\033&a8c8L"), CSTR("\033&a12c12L"),
CSTR(""),
CSTR("\033E"),CSTR(""),
CSTR("\033(s3B"),CSTR("\033(s0B"),
0,
54,
60,
79,
put_line,
NULL,
&IBM_chars,
},
} ;
#define NUM_PRINTERS lengthof(printers)
/***********************************************/
#define KEYWORD_ENTRY(s) { s, sizeof(s)-1 }
KEYWORDS section_start_keys[] =
{
KEYWORD_ENTRY("BUG:"),
KEYWORD_ENTRY("BUGS:"),
KEYWORD_ENTRY("Desc:"),
KEYWORD_ENTRY("Index:"),
KEYWORD_ENTRY("Note:"),
KEYWORD_ENTRY("Notes:"),
KEYWORD_ENTRY("Program:"),
KEYWORD_ENTRY("Range:"),
KEYWORD_ENTRY("Return:"),
KEYWORD_ENTRY("SeeAlso:"),
} ;
KEYWORDS table_start_keys[] =
{
KEYWORD_ENTRY("Bitfields "),
KEYWORD_ENTRY("Call "),
KEYWORD_ENTRY("Format "),
KEYWORD_ENTRY("Values "),
} ;
/***********************************************/
#ifdef isxdigit
#undef NEED_ISXDIGIT
#endif
#ifdef NEED_STRNICMP
#ifdef PROTOTYPES
int strnicmp(char *s1,char *s2,unsigned int len) ;
#endif
int strnicmp(s1,s2,len)
char *s1,*s2 ;
unsigned int len ;
{
char c1, c2 ;
while (*s1 && *s2 && len > 0)
{
len-- ;
c1 = (islower(*s1) ? toupper(*s1) : *s1) ;
c2 = (islower(*s2) ? toupper(*s2) : *s2) ;
if (c1 != c2 || len == 0) /* mismatch or substrings exhausted? */
return (c1 - c2) ;
s1++ ;
s2++ ;
}
return 0 ; /* strings match exactly on first 'len' characters */
}
#endif /* NEED_STRNICMP */
#ifdef NEED_STRUPR
#ifdef PROTOTYPES
char *strupr(char *s) ;
#endif
char *strupr(s)
char *s ;
{
char *orig_s = s ;
char c ;
if (s)
while (*s)
{
c = *s ;
*s++ = (islower(c) ? toupper(c) : c) ;
}
return orig_s ;
}
#endif /* NEED_STRUPR */
#ifdef NEED_ISXDIGIT
#ifdef PROTOTYPES
int isxdigit(int c) ;
#endif
int isxdigit(c)
int c ;
{
return isdigit(c) || (memchr("ABCDEFabcdef",c,12) != NULL) ;
}
#endif /* NEED_ISXDIGIT */
#ifdef NEED_ITOA
#ifdef PROTOTYPES
char *itoa(int num,char *buf,int radix) ;
#endif
char *itoa(num,buf,radix) /* not everybody has the same itoa() as TurboC */
int num ; /* minimal implementation */
char *buf ;
int radix ;
{
int count = 0 ;
int i ;
char tmp ;
do {
buf[count++] = "0123456789ABCDEF"[num % radix] ;
num /= radix ;
} while (num) ;
buf[count] = '\0' ;
if (count > 1)
for (i = 0 ; i < count / 2 ; i++)
{
tmp = buf[i] ;
buf[i] = buf[count-i-1] ;
buf[count-i-1] = tmp ;
}
return buf ;
}
#endif /* NEED_ITOA */
#ifdef NEED_ULTOA
#ifdef PROTOTYPES
char *ultoa(unsigned long num,char *buf,int radix) ;
#endif
char *ultoa(num,buf,radix) /* not everybody has the same ultoa() as TurboC */
unsigned long num ; /* minimal implementation */
char *buf ;
int radix ;
{
int count = 0 ;
int i ;
char tmp ;
do {
buf[count++] = "0123456789ABCDEF"[num % radix] ;
num /= radix ;
} while (num) ;
buf[count] = '\0' ;
if (count > 1)
for (i = 0 ; i < count / 2 ; i++)
{
tmp = buf[i] ;
buf[i] = buf[count-i-1] ;
buf[count-i-1] = tmp ;
}
return buf ;
}
#endif /* NEED_ULTOA */
/***********************************************/
void usage()
{
ip_putlit("\
Usage: intprint [options] intlist [>|>>]output\r\n\
Options:\r\n\
Filtering:\t-Ffile\tprint only entries matching filtering info in 'file'\r\n\
\t\t-k\tkeep original divider lines\r\n\
\t\t-rN:M\tprint only pages N through M\r\n\
\t\t-x\tinclude Index: lines in formatted output\r\n\
Formatting:\t-b\tboldface headings\t-B\tbold with control codes\r\n\
\t\t-d\t(duplex) print even/odd pages with different indents\r\n\
\t\t-e\t(elite) 96 chars/line\t-tN\tselect typeface N\r\n\
Pagination:\t-H\tadd page headers\t-iN\tindent N spaces\r\n\
\t\t-p\tnumber pages\t\t-nN\tN pages already printed\r\n\
\t\t-wN\twidow lines control\r\n\
\t\t-lN\tprint length\t\t-LN\ttotal page length\r\n\
\t\t\t(0 = infinite)\t(use linefeeds if > #lines printed)\r\n\
Printer:\t-I\tIBM graphics characters\r\n\
\t\t-Pname\tassume printer 'name'\t-P?\tlist printers\r\n\
Summaries:\t-ffile\tdata structure formats\t-sfile\tINT calls\r\n\
\t\t-Tfile\tlist tables\r\n\
Misc:\t\t-m\tprocess multiple parts\t-V\tmake INTERVUE summary\r\n\
"
,err) ;
ip_flush(err) ;
exit(1) ;
}
/***********************************************/
void fatal(msg)
char *msg ;
{
ip_putlit("UNRECOVERABLE ERROR:",err) ;
newline(err) ;
ip_puts(msg,err) ;
newline(err) ;
exit(1) ;
}
/***********************************************/
void warning(msg)
char *msg ;
{
ip_putlit("Warning: ",err) ;
ip_puts(msg,err) ;
newline(err) ;
}
/***********************************************/
IP_FILE *ip_fdopen(fd,buf,bufsiz,maxsiz,write)
int fd ;
char *buf ;
int bufsiz, maxsiz, write ;
{
IP_FILE *fp = (IP_FILE *)malloc(sizeof(IP_FILE)) ;
if (fp)
{
fp->fd = fd ;
fp->buf = buf ;
fp->bufsize = bufsiz ;
fp->buf_maxsize = maxsiz ;
fp->bufpos = 0 ;
fp->bufoffset = 0 ;
fp->write = write ;
}
return fp ;
}
/***********************************************/
IP_FILE *ip_open_write(name,trunc,buf,bufsiz)
char *name ;
char *buf ;
int trunc ;
int bufsiz ;
{
int fd ;
if (name && *name == '\0')
fd = 1 ; /* open stdout */
else
{
#ifdef __TURBOC__
if (trunc)
fd = _creat(name,0) ; /* create with no attribute bits sets */
else
fd = _open(name,O_WRONLY) ;
#else
if (trunc) trunc = O_TRUNC ;
fd = open(name,O_WRONLY|O_BINARY|O_CREAT|trunc,S_IREAD|S_IWRITE) ;
#endif
if (fd == -1)
return 0 ;
if (!trunc)
lseek(fd,0L,SEEK_END) ;
}
return ip_fdopen(fd,buf,bufsiz,bufsiz,1) ;
}
/***********************************************/
IP_FILE *ip_open_read(name,buf,bufsiz)
char *name ;
char *buf ;
int bufsiz ;
{
int fd, siz ;
#ifdef __TURBOC__
if ((fd = _open(name,O_RDONLY)) != -1)
#else
if ((fd = open(name,O_RDONLY | O_BINARY,0)) != -1)
#endif
{
siz = read(fd,buf,bufsiz) ;
if (siz == -1)
return 0 ;
return ip_fdopen(fd,buf,siz,bufsiz,0) ;
}
else
return 0 ;
}
/***********************************************/
int ip_flush(fp)
IP_FILE *fp ;
{
if (fp->write && fp->bufpos)
{
if (fp->bufpos > fp->buf_maxsize)
fp->bufpos = fp->buf_maxsize ;
if (write(fp->fd,fp->buf,fp->bufpos) == -1)
return -1 ;
fp->bufpos = 0 ;
}
return 0 ;
}
/***********************************************/
int ip_close(fp)
IP_FILE *fp ;
{
if (ip_flush(fp) == -1 || close(fp->fd) == -1)
return -1 ;
free(fp) ;
return 0 ;
}
/***********************************************/
unsigned long ip_fgets(buf, max, fp)
char *buf ;
int max ;
IP_FILE *fp ;
{
unsigned long line_offset = fp->bufoffset + fp->bufpos ;
char *end ;
int len ;
int new_bufpos ;
char *fpbuf = fp->buf ;
int bufpos = fp->bufpos ;
--max ;
if (bufpos + max < fp->bufsize)
{
end = (char *)memchr(fpbuf+bufpos,LINE_TERMINATOR,max) ;
if (end)
{
new_bufpos = (end-fpbuf) ;
len = new_bufpos++ - bufpos ;
/* eradicate rest of multi-character line terminator */
while (len > 0 && fpbuf[bufpos+len-1] <= ' ')
len-- ;
}
else
{
len = max ;
new_bufpos = bufpos + len ;
}
if (len)
memcpy(buf,fpbuf+bufpos,len) ;
buf[len] = '\0' ;
bufpos = new_bufpos ;
}
else
{
for (len = 1 ; len <= max ; len++)
{
*buf = fpbuf[bufpos++] ;
if (bufpos >= fp->bufsize)
{
if (fp->bufsize < fp->buf_maxsize)
{
fp->bufsize = bufpos = 0 ;
fpbuf[0] = '\0' ; /* dummy value to ensure empty string */
}
else
{
fp->bufoffset += fp->buf_maxsize ;
fp->bufsize = read(fp->fd,fpbuf,fp->buf_maxsize) ;
bufpos = 0 ;
}
if (fp->bufsize <= 0)
{
line_offset = (unsigned long)-1 ; /* signal end of file */
if (*buf != LINE_TERMINATOR)
*buf++ = LINE_TERMINATOR;
break ;
}
}
if (*buf == LINE_TERMINATOR)
break ;
else
buf++ ;
}
if (len > max) /* did we overflow before hitting EOL? */
*buf = '\0' ; /* if yes, plug in the terminator */
else
/* eradicate rest of multi-character line terminator */
while (len-- > 0 && *buf <= ' ')
*buf-- = '\0' ;
}
fp->bufpos = bufpos ;
return line_offset ;
}
/***********************************************/
int ip_write(buf, count, fp)
char *buf ;
int count ;
IP_FILE *fp ;
{
if (fp->bufpos + count < fp->buf_maxsize)
{
memcpy(fp->buf+fp->bufpos,buf,count) ;
fp->bufpos += count ;
}
else
while (count > 0)
{
int partial = fp->buf_maxsize - fp->bufpos ;
if (count < partial)
partial = count ;
memcpy(fp->buf+fp->bufpos,buf,partial) ;
buf += partial ;
fp->bufpos += partial ;
count -= partial ;
if (fp->bufpos >= fp->buf_maxsize && ip_flush(fp) == -1)
return -1 ;
}
return 0 ;
}
/***********************************************/
#define indent_line(fp) if(indent_string)ip_write(indent_string,indent_len,fp)
/***********************************************/
void indent_to(where,fp)
int where ;
IP_FILE *fp ;
{
where += indent ;
while (where >= 8)
{
ip_putc('\t',fp) ;
where -= 8 ;
}
if (where)
ip_write(" ",where,fp) ;
}
/***********************************************/
void put_line(fp,len)
IP_FILE *fp ;
int len ;
{
static char line[8] = { 196, 196, 196, 196, 196, 196, 196, 196 } ;
if (IBM_chars)
{
while (len >= 8)
{
ip_write(line,8,fp) ;
len -= 8 ;
}
if (len)
ip_write(line,len,fp) ;
}
else
{
while (len >= 8)
{
ip_write("--------",8,fp) ;
len -= 8 ;
}
if (len)
ip_write("--------",len,fp) ;
}
}
/***********************************************/
void HPPCL_put_line(fp,len)
IP_FILE *fp ;
int len ;
{
ip_putlit(HPPCL_IBM_LN_A,fp) ;
ip_puts(itoa((len * 25), num, 10),fp) ;
ip_putlit(HPPCL_IBM_LN_B,fp) ;
}
/***********************************************/
void HPPCL_set_typeface(fp,typeface)
IP_FILE *fp ;
char *typeface ;
{
ip_putlit(HPPCL_FONT_ON_A,fp) ;
if (typeface)
ip_puts(typeface,fp) ;
else
ip_putlit("8",fp) ;
ip_putlit(HPPCL_FONT_ON_B,fp) ;
}
/***********************************************/
int is_keyword(s,keys,numkeys)
char *s ;
KEYWORDS *keys ;
unsigned int numkeys ;
{
register int cmp ;
register unsigned int i ;
KEYWORDS *currkey ;
int firstchar = *s ;
do {
i = numkeys / 2 ;
currkey = &keys[i] ;
cmp = (firstchar - currkey->name[0]) ;
if (cmp == 0)
cmp = memcmp(s,currkey->name,currkey->length) ;
if (cmp < 0)
numkeys = i ;
else if (cmp > 0)
{
keys = currkey+1 ;
numkeys -= i+1 ;
}
else
return TRUE ;
} while (numkeys) ;
return FALSE ;
}
/***********************************************/
void output_line(line,fp)
char *line ;
IP_FILE *fp ;
{
if (*line)
{
int pos = 0 ;
int len = strlen(line) ;
indent_line(fp) ;
if (boldface)
{
if (start_of_entry(line) || start_of_table(line))
{
if (printer_bold)
{
ip_putcstr(&printer->bold_on,fp) ;
ip_write(line,len,fp) ;
ip_putcstr(&printer->bold_off,fp) ;
newline(fp) ;
return ;
}
else
{
ip_write(line,len,fp) ;
ip_putc('\r',fp) ;
indent_line(fp) ;
}
}
else if (section_start(line))
{
pos = (char *)memchr(line,':',len) - line ;
if (printer_bold)
{
ip_putcstr(&printer->bold_on,fp) ;
ip_write(line,pos,fp) ;
ip_putcstr(&printer->bold_off,fp) ;
line += pos ; /* adjust because no longer at left edge */
}
else
{
ip_write(line,pos,fp) ;
ip_putc('\r',fp) ;
indent_line(fp) ;
}
}
} /* boldface */
if (indent & 7) /* indenting by other than a multiple of 8 ? */
{
while (*line)
{
if (*line == '\t')
{
ip_write(" ",8-(pos&7),fp) ;
pos = 0 ; /* absolute column doesn't matter, only mod 8 */
}
else
{
ip_putc(*line,fp) ;
pos++ ;
}
line++ ;
}
}
else
ip_write(line,len,fp) ;
}
newline(fp) ;
}
/***********************************************/
void get_raw_line(buf)
char *buf ;
{
IP_FILE *in ;
buf[0] = '\0' ;
if (out_of_files)
return ;
current_line_offset = ip_fgets(buf,MAXLINE,infile) ;
if (current_line_offset == (unsigned long)-1)
if (multi_file)
{
offset_adjust += lseek(infile->fd,0L,SEEK_END) ;
input_file[input_file_namelen-1]++ ;
ip_close(infile) ;
if ((in = ip_open_read(input_file,infile_buf,sizeof(infile_buf)))
!= NULL)
{
infile = in ;
current_line_offset = ip_fgets(buf,MAXLINE,infile) ;
}
else
{
out_of_files = TRUE ;
return ;
}
}
else
out_of_files = TRUE ;
}
/***********************************************/
int unwanted_section(buf)
char *buf ;
{
int found ;
char str[MAXLINE] ;
FILT_LIST *p ;
if (start_of_entry(buf)) /* is it an interrupt entry? */
{
strcpy(str,buf) ;
(void) strupr(str) ;
/* section is unwanted if *any* exclude string matches */
for (p = excludes ; p ; p = p->next)
{
if (p->str && strstr(str, p->str) != NULL)
return TRUE ;
}
/* if still wanted, set to TRUE if *no* include string matches */
found = FALSE ;
for (p = includes ; p ; p = p->next)
{
if (p->str && strstr(str, p->str) != NULL)
{
found = TRUE ;
break ;
}
}
if (!found)
return TRUE ;
}
return FALSE ;
}
/***********************************************/
void get_line(buf)
char *buf ;
{
static char next_line[MAXLINE] ;
static int readahead = FALSE ;
/* get the next line from the file, skipping unwanted entries */
if (readahead)
{
strcpy(buf,next_line) ;
readahead = FALSE ;
}
else
{
do {
get_raw_line(buf) ;
} while (!include_index_lines && index_line(buf)) ;
if (section_file_start(buf))
do {
get_raw_line(buf) ;
} while (buf[0] && !divider_line(buf)) ;
if (do_filter)
{
/* if we read a divider line while filtering, we have to look ahead */
strcpy(next_line,buf);
while (next_line[0] && divider_line(next_line))
{
strcpy(buf,next_line) ; /* we may be returning the divider */
get_raw_line(next_line) ;
if (unwanted_section(next_line))
{
while (!divider_line(next_line))
get_raw_line(next_line) ;
}
else /* section is wanted, so return divider and then next line */
readahead = TRUE ;
}
}
}
}
/***********************************************/
void fill_buffer(lines,lines_per_page)
int lines, lines_per_page ;
{
int i ;
/* copy remainder, if any, from last page to top of current page */
if (lines)
for (i = lines ; i < lines_per_page ; i++)
{
strcpy(buffer[i-lines], buffer[i]) ;
line_offsets[i-lines] = line_offsets[i] ;
}
else
lines = lines_per_page ;
for (i = lines_per_page - lines ; i < lines_per_page ; i++)
{
get_line(buffer[i]) ;
line_offsets[i] = current_line_offset + offset_adjust ;
}
}
/***********************************************/
int find_page_break(lines)
int lines ;
{
int i ;
char *buf ;
for (i = 0 ; i < widow_length ; i++)
{
buf = buffer[lines-i-1] ;
if (buf[0] == '\0' || divider_line(buf))
return lines - i ;
else if (section_start(buf))
return lines - i - 1 ;
}
return lines ;
}
/***********************************************/
int summarize(line, pages_printed)
int line, pages_printed ;
{
char *s, reg ;
int i ;
int max_descrip ;
int len, numlen ;
s = buffer[line] ;
if (start_of_entry(s))
{
memcpy(summary_line," -- -- -- ",10) ;
summary_line[1] = s[4] ; /* output interrupt number */
summary_line[2] = s[5] ;
len = 4 ;
s = buffer[line+1] ;
while (*s && isspace(*s))
s++ ;
if (*s == 'A')
{
reg = s[1] ;
while (*s && *s != '=')
s++ ;
s++ ; /* skip the equal sign */
while (*s && isspace(*s))
s++ ; /* skip the space between equal sign and number */
if (isxdigit(*s) && isxdigit(s[1]))
{
if (reg == 'L')
len += 3 ;
summary_line[len++] = *s++ ;
summary_line[len++] = *s++ ;
if (reg == 'X')
{
len++ ;
summary_line[len++] = *s++ ;
summary_line[len] = *s ;
}
}
}
len = 10 ;
if (page_numbers)
{
itoa(pages_printed,num,10) ;
numlen = strlen(num) ;
for (i = numlen ; i < 3 ; i++)
summary_line[len++] = ' ' ;
memcpy(summary_line+len,num,numlen) ;
len += numlen ;
summary_line[len++] = ' ' ;
}
s = buffer[line] + 7 ; /* find function description */
if (*s && *s != '-') /* does the heading contain flags? */
{
while (*s && !isspace(*s))
summary_line[len++] = *s++ ;
summary_line[len++] = '>' ;
summary_line[len++] = ' ' ;
while (*s && *s != '-')
s++ ;
}
while (*s && !isspace(*s))
s++ ;
while (*s && isspace(*s))
s++ ;
max_descrip = (page_width > sizeof(summary_line)-1) ?
sizeof(summary_line)-1 : page_width ;
while (len < max_descrip && *s)
summary_line[len++] = *s++ ;
summary_line[len] = '\0' ;
summary_line_len = len ;
return 1 ;
}
else
return 0 ;
}
/***********************************************/
void start_format(line)
char *line ;
{
indent_line(formats) ;
(*printer->put_line)(formats,79) ;
newline(formats) ;
indent_line(formats) ;
ip_puts(summary_line,formats) ;
newline(formats) ;
indent_line(formats) ;
ip_putc('\t',formats) ;
ip_puts(line+10,formats) ;
newline(formats) ;
echo_format = TRUE ;
}
/***********************************************/
void show_offset(line,fp)
int line ;
IP_FILE *fp ;
{
char offset_string[12] ;
int len ;
ultoa(line_offsets[line],offset_string,16) ;
len = strlen(offset_string) ;
ip_write("00000000",8-len,fp) ;
ip_write(offset_string,len,fp) ;
}
/***********************************************/
void add_table(i)
int i ;
{
char firstchar ;
char num[6] ;
char *end ;
int len ;
int summary_width ;
char found = FALSE ;
prev_table++ ;
firstchar = buffer[i][0] ;
if (firstchar == 'C' || firstchar == 'V') /* Call.. or Values... ? */
{
if (i > 0 && buffer[i-1][0] == '(')
{
memcpy(num,buffer[i-1]+7,4) ;
num[4] = '\0' ;
len = 4 ;
found = TRUE ;
}
}
else if (firstchar == 'B' || firstchar == 'F') /* Bitfields.. or Format..? */
{
end = strrchr(buffer[i+1]+7,')') ; /* rule out Bit(s) as only match */
if (end)
{
memcpy(num,end-4,4) ;
num[4] = '\0' ;
len = 4 ;
found = TRUE ;
}
}
if (!found)
{
itoa(prev_table,num,10) ;
len = strlen(num) ;
}
indent_line(tables) ;
if (show_offsets)
show_offset(i,tables) ;
ip_write(" 0000",5-len,tables) ;
ip_write(num,len,tables);
if (page_numbers)
{
summary_width = 13 ;
while (summary_line[summary_width] != ' ')
summary_width++ ;
summary_width++ ; /* include the blank we found */
}
else
summary_width = 10 ;
ip_write(summary_line,summary_width,tables) ;
len = strlen(buffer[i])-1 ;
if (len > page_width - summary_width - 5)
len = page_width - summary_width - 5 ;
ip_write(buffer[i],len,tables) ;
newline(tables) ;
}
/***********************************************/
int make_description(desc,line)
char *desc ;
int line ;
{
char *start = desc ;
summarize(line,pages_printed) ;
memcpy(desc,"INT ", 4) ;
desc += 4 ;
*desc++ = summary_line[1] ;
*desc++ = summary_line[2] ;
if (summary_line[4] != '-')
{
memcpy(desc,", AH=", 5) ;
desc += 5 ;
*desc++ = summary_line[4] ;
*desc++ = summary_line[5] ;
}
if (summary_line[7] != '-')
{
memcpy(desc,", AL=", 5) ;
desc += 5 ;
*desc++ = summary_line[7] ;
*desc++ = summary_line[8] ;
}
*desc = '\0' ;
return (desc-start)+1 ;
}
/***********************************************/
char *determine_heading(last)
int last ;
{
int i ;
static char heading[MAXLINE] ;
char save[25] ;
char num[10] ;
/* ugly hack to keep the combination of -H and -T from showing wrong page */
/* numbers for tables--copy last summary line from previous page to safe */
/* place before processing current page, then restore it */
memcpy(save,summary_line,sizeof(save)) ;
if (start_of_entry(buffer[0]))
{
header_first.len = make_description(header_first.desc,0) ;
header_first.part = 1 ;
header_first.first_on_page = TRUE ;
}
else if (header_last.part == 0) /* very first entry? */
{
for (i = 0 ; i < last ; i++)
if (start_of_entry(buffer[i]))
{
header_first.len = make_description(header_first.desc,i) ;
header_first.part = 1 ;
header_first.first_on_page = TRUE ;
break ;
}
}
else
{
header_first.len = header_last.len ;
memcpy(header_first.desc,header_last.desc,header_last.len) ;
header_first.part = header_last.part + 1 ;
header_first.first_on_page = FALSE ;
}
/* assume entry spans entire page */
header_last.len = header_first.len ;
memcpy(header_last.desc,header_first.desc,header_first.len) ;
header_last.part = header_first.part ;
header_last.first_on_page = header_first.first_on_page ;
/* find last entry on page */
if (header_first.part > 0)
{
for (i = last-1 ; i > 0 ; i--)
if (start_of_entry(buffer[i]))
{
header_last.len = make_description(header_last.desc,i) ;
header_last.part = 1 ;
header_last.first_on_page = FALSE ;
break ;
}
memcpy(heading,header_first.desc,header_first.len) ;
if (header_first.part > 1)
{
strcat(heading," (Part ") ;
strcat(heading,itoa(header_first.part,num,10)) ;
strcat(heading,")") ;
}
if (memcmp(header_first.desc,header_last.desc,header_last.len) != 0 ||
header_first.part != header_last.part)
{
strcat(heading," to ") ;
strcat(heading,header_last.desc) ;
if (header_last.part > 1)
{
strcat(heading," (Part ") ;
strcat(heading,itoa(header_last.part,num,10)) ;
strcat(heading,")") ;
}
}
memcpy(summary_line,save,sizeof(save)) ;
return heading ;
}
else /* no headings yet */
{
memcpy(summary_line,save,sizeof(save)) ;
return NULL ;
}
}
/***********************************************/
void print_buffer(last,body_lines,lines_per_page,total_lines,use_FF)
int last, body_lines, lines_per_page, total_lines ;
int use_FF ;
{
int i, len ;
int headpos ;
int print_this_page = (pages_printed>=first_page && pages_printed<=last_page);
pages_printed++ ;
if (do_headers)
{
char *heading ;
if ((heading = determine_heading(last)) != NULL)
{
if (print_this_page)
{
len = strlen(heading) ;
headpos = 40-len/2 ;
indent_to(headpos,outfile) ;
if (boldface)
{
if (printer_bold)
{
ip_putcstr(&printer->bold_on,outfile) ;
ip_write(heading,len,outfile) ;
ip_putcstr(&printer->bold_off,outfile) ;
}
else
{
ip_write(heading,len,outfile) ;
ip_putc('\r',outfile) ;
indent_to(headpos,outfile) ;
ip_write(heading,len,outfile) ;
}
}
else
ip_write(heading,len,outfile) ;
}
}
newline(outfile) ;
newline(outfile) ;
}
for (i = 0 ; i < last ; i++)
{
if (print_this_page)
{
char *line = buffer[i] ;
if (*line)
{
if (!keep_divider_lines && divider_line(line))
{
indent_line(outfile) ;
(*printer->put_line)(outfile,79) ;
newline(outfile) ;
echo_format = FALSE ;
}
else
{
output_line(line, outfile) ;
if (echo_format)
output_line(line,formats) ;
}
}
else
{
newline(outfile) ;
echo_format = FALSE ;
}
}
/* need summary lines if doing summary, formats, or table index */
if (need_summary)
{
if (summarize(i,pages_printed) && do_summary && summary)
{
if (show_offsets)
show_offset(i,summary) ;
ip_write(summary_line,summary_line_len,summary) ;
newline(summary) ;
}
if (do_formats && memcmp(buffer[i],"Format ",7) == 0)
start_format(buffer[i]) ;
if (do_tables && start_of_table(buffer[i]))
add_table(i) ;
}
}
if (print_this_page)
{
if (page_numbers)
{
for (i = last ; i <= body_lines ; i++)
newline(outfile) ;
itoa(pages_printed, num, 10) ;
i = strlen(num) ;
if (!duplex)
indent_to(38-i/2,outfile) ;
else if (pages_printed & 1) /* odd-numbered page? */
indent_to(75-i/2,outfile) ;
else
indent_to(2,outfile) ;
ip_putlit("- ", outfile) ;
ip_write(num, i, outfile) ;
ip_putlit(" -", outfile) ;
newline(outfile) ;
}
if (use_FF)
ip_putc('\f',outfile) ;
else
for (i = page_numbers?lines_per_page:last ; i
if (duplex)
{
if (pages_printed & 1) /* next page even or odd? */
ip_putcstr(&printer->marginl, outfile) ; /* even page */
else
ip_putcstr(&printer->marginr, outfile) ; /* odd page */
}
}
}
/***********************************************/
void display_printers()
{
int i ;
ip_putlit("Valid printer names are:",err) ;
newline(err) ;
for (i = 0 ; i < NUM_PRINTERS ; i++)
{
ip_putc('\t',err) ;
ip_puts(printers[i].name,err) ;
newline(err) ;
}
ip_putlit("When entering the printer name, use either a dash or an",err) ;
newline(err) ;
ip_putlit("underscore in place of blanks. Case is ignored, and the",err) ;
newline(err) ;
ip_putlit("name may be abbreviated to the shortest unique prefix.",err) ;
newline(err) ;
exit(1) ;
}
/***********************************************/
void select_printer(name)
char *name ;
{
int i, len, prt = -1 ;
len = strlen(name) ;
for (i = 0 ; i < len ; i++) /* convert dashes and underscores to blanks */
if (name[i] == '-' || name[i] == '_')
name[i] = ' ' ;
for (i = 0 ; i < NUM_PRINTERS ; i++)
if (strnicmp(name,printers[i].name,len) == 0)
if (prt == -1)
prt = i ;
else
fatal("Ambiguous printer name! Use -P? to list printers.") ;
if (prt == -1)
fatal("Unknown printer name! Use -P? to list printers.") ;
else
printer = &printers[prt] ;
}
/***********************************************/
FILT_LIST *add_filter_info(list,str)
FILT_LIST *list ;
char *str ;
{
FILT_LIST *newfilt ;
int len = strlen(str)+1 ;
if ((newfilt = (FILT_LIST *)malloc(sizeof(struct filter_list)+len))
!= NULL)
{
newfilt->next = list ;
memcpy(newfilt->str,str,len) ;
strupr(newfilt->str) ;
}
else
fatal("out of memory") ;
return newfilt ;
}
/***********************************************/
void build_filter_lists(file)
char *file ;
{
IP_FILE *fp ;
char buf[MAXLINE] ;
int len ;
long result ;
if ((fp = ip_open_read(file,filter_buf,sizeof(filter_buf))) == NULL)
{
warning("unable to open filtering file, will print entire list.") ;
do_filter = FALSE ;
}
else /* OK, file is open, so start reading */
{
do {
buf[0] = '\0' ;
result = ip_fgets(buf, sizeof(buf), fp) ;
len = strlen(buf) ;
if (len > 1)
{
switch (buf[0])
{
case '+':
includes = add_filter_info(includes,buf+1) ;
break ;
case '-':
excludes = add_filter_info(excludes,buf+1) ;
break ;
case '#': /* comment lines */
default:
break ;
}
}
} while (result != -1) ;
ip_close(fp) ;
do_filter = TRUE ;
}
}
/***********************************************/
void write_summary_header(fp,title,show_offsets,show_table)
IP_FILE *fp ;
char *title ;
int show_offsets, show_table ;
{
/* set up the printer */
ip_putcstr(&printer->init1,fp) ;
ip_putcstr(&printer->init2,fp) ;
ip_putcstr(&printer->marginc,fp) ;
/* now start writing the actual header */
indent_to(show_offsets?8:0,fp) ;
ip_putlit("\t\t\t\t",fp) ;
ip_puts(title,fp) ;
newline(fp) ;
indent_to(show_offsets?8:0,fp) ;
ip_putlit("\t\t\t\t",fp) ;
(*printer->put_line)(fp,strlen(title)) ;
newline(fp) ;
newline(fp) ;
indent_line(fp) ;
if (show_offsets)
ip_putlit("Offset ", fp) ;
if (show_table)
ip_putlit("Tbl# ",fp) ;
ip_putlit("INT AH AL", fp) ;
if (page_numbers)
ip_putlit(" Page", fp) ;
ip_putlit("\t\t\tDescription", fp) ;
newline(fp) ;
indent_line(fp) ;
(*printer->put_line)(fp,page_width+(show_offsets?8:0)) ;
newline(fp) ;
}
/***********************************************/
static void reset_printer_and_close(fp)
IP_FILE *fp ;
{
ip_putcstr(&printer->term1,fp) ;
ip_putcstr(&printer->term2,fp) ;
ip_close(fp) ;
}
/***********************************************/
int _Cdecl main(argc,argv)
int argc ;
char *argv[] ;
{
int lines_per_page = -1 ;
int total_lines = -1 ;
int use_FF = TRUE ;
int last_line ;
int body_lines ;
char *typeface = NULL ;
char *summary_file = NULL ;
char *table_file = NULL ;
char *formats_file = NULL ;
char *filter_file = NULL ;
char *last_page_num ;
err = ip_fdopen(2,stderr_buf,sizeof(stderr_buf),sizeof(stderr_buf),1) ;
ip_putlit("INTPRINT v", err) ;
ip_putlit(VERSION, err) ;
ip_putlit(" by Ralf Brown and others. Donated to the Public Domain.",err) ;
newline(err) ;
ip_flush(err) ;
if (argc == 1 && isatty(0))
usage() ; /* give help if invoked with no args and keybd input */
while (argc >= 2 && argv[1][0] == '-')
{
switch (argv[1][1])
{
case 'B':
printer_bold = TRUE ;
/* fall through to -b */
case 'b':
boldface = TRUE ;
break ;
case 'd':
duplex = TRUE ;
break ;
case 'e':
indent = 8 ;
page_width = 87 ; /* 96 - indent - 1 right margin */
break ;
case 'f':
formats_file = argv[1]+2 ;
break ;
case 'F':
filter_file = argv[1]+2 ;
break ;
case 'H': /* page headers */
do_headers = TRUE ;
break ;
case 'i':
indent = atoi(argv[1]+2) ;
break ;
case 'I':
IBM_chars = TRUE ;
break ;
case 'k':
keep_divider_lines = TRUE ;
break ;
case 'l':
lines_per_page = atoi(argv[1]+2) ;
break ;
case 'L':
total_lines = atoi(argv[1]+2) ;
break ;
case 'm':
multi_file = TRUE ;
break ;
case 'n':
pages_printed = atoi(argv[1]+2) ;
break ;
case 'P':
if (argv[1][2] == '?')
display_printers() ;
else
select_printer(argv[1]+2) ;
break ;
case 'p':
page_numbers = TRUE ;
break ;
case 'r':
first_page = atoi(argv[1]+2) ;
last_page_num = strchr(argv[1]+2, ':') ;
last_page = last_page_num ? atoi(last_page_num+1) : 0 ;
if (last_page == 0)
last_page = ~0 ;
break ;
case 's':
summary_file = argv[1]+2 ;
break ;
case 't':
typeface = argv[1]+2 ;
break ;
case 'T':
table_file = argv[1]+2 ;
break ;
case 'V':
show_offsets = IBM_chars = TRUE ;
break ;
case 'w':
widow_length = atoi(argv[1]+2) ;
break ;
case 'x':
include_index_lines = TRUE ;
break ;
default:
usage() ;
}
argv++ ;
argc-- ;
}
if (printer == NULL)
select_printer("default") ;
/* apply any necessary overrides to parameters */
if (printer->indent != -1)
indent = printer->indent ;
if (lines_per_page < 0)
lines_per_page = printer->lines_per_page ;
if (total_lines <= 0)
total_lines = printer->page_length ;
if (page_width <= 0)
page_width = printer->page_width ;
if (show_offsets && page_width < 80)
page_width = 80 ;
if (printer->flag)
*(printer->flag) = TRUE ;
if (cstrlen(&printer->bold_on) == 0) /* control sequences for bold? */
printer_bold = FALSE ; /* if not, don't try to use them */
/* build the indent string */
if (indent)
{
char *t ;
int ind = indent ;
indent_len = indent/8 + indent%8 ;
t = indent_string = (char *)malloc(indent_len+1) ;
while (ind >= 8)
{
*t++ = '\t' ;
ind -= 8 ;
}
while (ind > 0)
{
*t++ = ' ' ;
ind-- ;
}
}
/* open the summary file, if any */
if (summary_file && *summary_file)
if ((summary = ip_open_write(summary_file,!pages_printed,summary_buf,
sizeof(summary_buf)))
!= NULL)
do_summary = TRUE ;
else
warning("unable to open summary file") ;
/* open the table index file, if any */
if (table_file && *table_file)
if ((tables = ip_open_write(table_file,!pages_printed,tables_buf,
sizeof(tables_buf)))
!= NULL)
do_tables = TRUE ;
else
warning("unable to open table index file") ;
/* open the data formats file, if any */
if (formats_file && *formats_file)
if ((formats = ip_open_write(formats_file,!pages_printed,formats_buf,
sizeof(formats_buf)))
!= NULL)
do_formats = TRUE ;
else
warning("unable to open formats file") ;
need_summary = (do_summary || do_formats || do_tables) ;
/* initialize filtering data, if specified */
if (filter_file && *filter_file)
build_filter_lists(filter_file) ;
if (total_lines <= lines_per_page)
{
total_lines = lines_per_page ;
use_FF = TRUE ;
}
else
use_FF = FALSE ;
if (argc == 2 || argc == 3)
{
input_file = argv[1] ;
input_file_namelen = strlen(input_file) ;
if ((infile = ip_open_read(input_file,infile_buf,sizeof(infile_buf))) == NULL)
fatal("unable to open input file") ;
if (argc == 3)
{
outfile = ip_open_write(argv[2],!pages_printed,outfile_buf,
sizeof(outfile_buf)) ;
if (outfile == NULL)
fatal("unable to open output file") ;
}
else
outfile = ip_open_write("",0,outfile_buf,sizeof(outfile_buf)) ;
}
else
usage() ;
if (lines_per_page > MAXPAGE)
{
ip_putlit("Surely you jest! I can't handle pages that long.",err) ;
newline(err) ;
newline(err) ;
usage() ;
}
else if (lines_per_page == 0) /* infinite page? */
{
widow_length = 0 ;
if (total_lines <= 0)
total_lines = MAXPAGE ;
lines_per_page = total_lines ;
use_FF = do_headers = page_numbers = FALSE ;
}
else
{
if (lines_per_page < 20)
{
ip_putlit("Surely your printer can handle at least 20 lines per page!",
err) ;
newline(err) ;
ip_putlit("Adjusting page length....",err) ;
newline(err) ;
lines_per_page = 20 ;
}
if (widow_length < 3 || widow_length > lines_per_page / 2)
{
ip_putlit("Widow lines (-w) must be set to at least 3 and at most one-half of the",err) ;
newline(err) ;
ip_putlit("page length. Using default of 8 lines.",err) ;
newline(err) ;
widow_length = 8 ;
}
}
/* set up the printer */
ip_putcstr(&printer->init1,outfile) ;
ip_putcstr(&printer->init2,outfile) ;
if (printer->set_typeface)
(*printer->set_typeface)(outfile,typeface) ;
if (duplex)
{
ip_putcstr(&printer->duplex_on,outfile) ;
if (pages_printed & 1) /* next page odd or even? */
ip_putcstr(&printer->marginl,outfile) ; /* even */
else
ip_putcstr(&printer->marginr,outfile) ; /* odd */
}
else
ip_putcstr(&printer->marginc,outfile) ; /* non-duplex, so center */
/* start the auxiliary files if this is the first part processed */
if (pages_printed == 0)
{
/* start the summary file */
if (do_summary)
write_summary_header(summary,"Interrupt Summary",show_offsets,FALSE) ;
/* start the table index file */
if (do_tables)
write_summary_header(tables,"Table Summary",show_offsets,TRUE) ;
/* start the data formats file */
if (do_formats)
write_summary_header(formats,"Data Structure Formats",FALSE,FALSE) ;
}
if (page_numbers)
body_lines = lines_per_page - 2 ;
else
body_lines = lines_per_page ;
if (do_headers)
body_lines -= 2 ;
last_line = 0 ;
while (!out_of_files)
{
fill_buffer(last_line,body_lines) ;
last_line = find_page_break(body_lines) ;
print_buffer(last_line,body_lines,lines_per_page,total_lines,use_FF) ;
}
if (last_line < body_lines)
{
int i ;
for (i = last_line ; i < body_lines ; i++)
{
strcpy(buffer[i-last_line], buffer[i]) ;
line_offsets[i-last_line] = line_offsets[i] ;
}
print_buffer(body_lines-last_line,body_lines,lines_per_page,total_lines,
use_FF) ;
}
ip_close(infile) ;
/* reset the printer */
reset_printer_and_close(outfile) ;
ip_puts(itoa(pages_printed, num, 10), err) ;
ip_putlit(" pages", err) ;
if (do_summary)
reset_printer_and_close(summary) ;
if (do_tables)
{
ip_putlit(", ", err) ;
ip_puts(itoa(prev_table, num, 10), err) ;
ip_putlit(" tables", err) ;
reset_printer_and_close(tables) ;
}
if (do_formats)
reset_printer_and_close(formats) ;
newline(err) ;
ip_close(err) ;
return 0 ;
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/