1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
include <syserr.h>
include <error.h>
include <finfo.h>
include <time.h>
include <ttyset.h>
define WIDE_PAGE 100
define SZ_DDSTR 256
# LPRINT -- Print a file or files on the lineprinter. A one line header is
# printed at the top of each page, unless we are reading from the standard
# input. If printing multiple files, each file begins on a new page.
# TTYPUTLINE is used to output lines to the printer file, so that formfeeds,
# standout mode, etc., may be properly translated for the indicated device.
procedure t_lprint()
int out, list, map_cc
bool input_redirected, one_file
bool print_heading, auto_header
pointer sp, fname, device, label, lp, ddstr
pointer ttyodes()
bool streq(), clgetb()
int clpopni(), clplen(), envgets(), lpopen(), clgfil(), ttygets(), btoi()
string printer "printer"
errchk clgfil, lp_print_file
begin
call smark (sp)
call salloc (fname, SZ_FNAME, TY_CHAR)
call salloc (label, SZ_FNAME, TY_CHAR)
call salloc (device, SZ_FNAME, TY_CHAR)
call salloc (ddstr, SZ_DDSTR, TY_CHAR)
# Open list of files to be printed.
list = clpopni ("files")
one_file = (clplen (list) == 1)
# Get device name. Default is "printer", which means that the actual
# device name is given by the environment variable "printer".
call clgstr ("device", Memc[device], SZ_FNAME)
if (streq (Memc[device], printer))
if (envgets (printer, Memc[device], SZ_FNAME) <= 0) {
call clpcls (list)
call syserrs (SYS_ENVNF, printer)
}
# Map unknown control chars into printable sequences?
map_cc = btoi (clgetb ("map_cc"))
# If automatic pagination is selected, lprint will break pages and
# print headers only if the standard input is not redirected.
# Otherwise, pagination is disabled unless paginate=yes. The file
# name buffer is used as a temporary to hold the value string.
call clgstr ("paginate", Memc[fname], SZ_FNAME)
auto_header = streq (Memc[fname], "auto")
if (!auto_header)
print_heading = streq (Memc[fname], "yes")
# Open TTY descriptor and printer file. We deal only with character
# data, so open printer as a text file. Output the files to the line
# printer device.
lp = ttyodes (Memc[device])
if (ttygets (lp, "DD", Memc[ddstr], SZ_DDSTR) <= 0)
call error (1, "missing 'DD' parameter in termcap entry")
out = lpopen (Memc[ddstr], APPEND, TEXT_FILE)
while (clgfil (list, Memc[fname], SZ_FNAME) != EOF) {
# If only one file and it is the standard input (i.e., reading
# from a pipe), and if header printing is not explicitly enabled
# or disabled, do not break pages and print headers.
input_redirected = (one_file && streq (Memc[fname], "STDIN"))
if (auto_header)
print_heading = !input_redirected
# Get page header label string. File name is used unless reading
# from the standard input.
if (input_redirected)
call clgstr ("label", Memc[label], SZ_FNAME)
else
call strcpy (Memc[fname], Memc[label], SZ_FNAME)
# Output file, followed by a form feed.
iferr {
call lp_print_file (out, lp, Memc[fname], Memc[label], map_cc,
print_heading)
call flush (out)
} then
call erract (EA_WARN)
}
call close (out)
call clpcls (list)
call ttycdes (lp)
call sfree (sp)
end
# LP_PRINT_FILE -- Open and print the named text file on the output file,
# under control of the tty device descriptor LP. Print a header on each
# page if enabled, and formfeed at the end of the file. The number of lines
# per page is given by the tty descriptor.
procedure lp_print_file (out, lp, fname, label, map_cc, print_heading)
int out
pointer lp
char fname[ARB]
char label[ARB]
int map_cc
bool print_heading
bool one_tab_in, streq()
int pageno, lineno, maxlines, totlines, status, in
long fi[LEN_FINFO], time, clktime()
pointer sp, ip, lbuf, timebuf
int open(), getline(), finfo(), ttystati()
errchk salloc, finfo, cnvtime, open, ttystati, getline, ttyputline
begin
call smark (sp)
call salloc (lbuf, SZ_LINE+1, TY_CHAR)
call salloc (timebuf, SZ_TIME, TY_CHAR)
# Get time and date file was last modified.
if (print_heading) {
if (streq (fname, "STDIN"))
time = clktime (long(0))
else {
if (finfo (fname, fi) == ERR) {
call sprintf (Memc[lbuf], SZ_LINE, "%s '%s'\n")
call pargstr ("Cannot get info on file")
call pargstr (fname)
call error (1, Memc[lbuf])
} else
time = FI_MTIME(fi)
}
call cnvtime (time, Memc[timebuf], SZ_TIME)
}
in = open (fname, READ_ONLY, TEXT_FILE)
maxlines = ttystati (lp, TTY_NLINES)
# If printer page is very wide, set page in one tabstop from left
# margin.
one_tab_in = (ttystati (lp, TTY_NCOLS) > WIDE_PAGE)
if (one_tab_in) {
Memc[lbuf] = '\t'
ip = lbuf + 1
} else
ip = lbuf
# If printing header and breaking pages, allow for the 3 line header
# and a three line border at the bottom of the page.
if (print_heading)
maxlines = maxlines - 6
totlines = 0
status = OK
# Format and write each page of output. If headers are enabled,
# output formfeed and header between pages.
for (pageno=1; status != EOF; pageno=pageno+1) {
# Print header, if enabled. We assume that we are already
# positioned to the top of a page.
if (print_heading) {
call sprintf (Memc[ip], SZ_LINE, "%s %s Page %d\n\n\n")
call pargstr (Memc[timebuf])
call pargstr (label)
call pargi (pageno)
call ttyputline (out, lp, Memc[lbuf], map_cc)
totlines = totlines + 3
}
# Output one page of text. Each output line is processed by
# ttyputline to expand tabs, underline, etc.
for (lineno=1; lineno <= maxlines; lineno=lineno+1) {
status = getline (in, Memc[ip])
if (status == EOF)
break
if (Memc[ip] == '\f') {
call ttyputline (out, lp, "\f", map_cc)
call strcpy (Memc[ip+1], Memc[ip], SZ_LINE)
}
call ttyputline (out, lp, Memc[lbuf], map_cc)
totlines = totlines + 1
}
# Output formfeed, leaving printer positioned to top of page.
# Do not break pages if headers are disabled.
if (print_heading && totlines > 0)
call ttyputline (out, lp, "\f", map_cc)
}
call close (in)
call sfree (sp)
end
|