1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 *
32 * A few general purpose routines.
33 *
34 */
35
36
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include <ctype.h>
40 #include <fcntl.h>
41
42 #include "gen.h" /* a few general purpose definitions */
43 #include "ext.h" /* external variable declarations */
44
45
46 int nolist = 0; /* number of specified ranges */
47 int olist[50]; /* processing range pairs */
48
49
50
51 void
error(int kind,char * mesg,...)52 error(int kind, char *mesg, ...)
53 {
54
55
56 /*
57 *
58 * Called when we've run into some kind of program error. *mesg is printed using
59 * the control string arguments a?. We'll quit if we're not ignoring errors and
60 * kind is FATAL.
61 *
62 */
63
64
65 if ( mesg != NULL && *mesg != '\0' ) {
66 va_list ap;
67
68 fprintf(stderr, "%s: ", prog_name);
69 va_start(ap, mesg);
70 vfprintf(stderr, mesg, ap);
71 va_end(ap);
72 if ( lineno > 0 )
73 fprintf(stderr, " (line %d)", lineno);
74 if ( position > 0 )
75 fprintf(stderr, " (near byte %d)", position);
76 putc('\n', stderr);
77 } /* End if */
78
79 if ( kind == FATAL && ignore == OFF ) {
80 if ( temp_file != NULL )
81 unlink(temp_file);
82 exit(x_stat | 01);
83 } /* End if */
84
85 } /* End of error */
86
87
88 /*****************************************************************************/
89
90 /*****************************************************************************/
91
92
93 void
out_list(str)94 out_list(str)
95
96
97 char *str; /* process ranges in this string */
98
99
100 {
101
102
103 int start, stop; /* end points */
104
105
106 /*
107 *
108 * Called to get the processing ranges that were specified by using the -o option.
109 * The range syntax should be identical to the one used in nroff and troff.
110 *
111 */
112
113
114 while ( *str && nolist < sizeof(olist) - 2 ) {
115 start = stop = str_convert(&str, 0);
116
117 if ( *str == '-' && *str++ )
118 stop = str_convert(&str, 9999);
119
120 if ( start > stop )
121 error(FATAL, "illegal range %d-%d", start, stop);
122
123 olist[nolist++] = start;
124 olist[nolist++] = stop;
125
126 if ( *str != '\0' ) str++;
127
128 } /* End while */
129
130 olist[nolist] = 0;
131
132 } /* End of out_list */
133
134
135 /*****************************************************************************/
136
137
138 int
in_olist(num)139 in_olist(num)
140
141
142 int num; /* should we print this page? */
143
144
145 {
146
147
148 int i; /* just a loop index */
149
150
151 /*
152 *
153 * Returns ON if num represents a page that we're supposed to print. If no ranges
154 * were selected nolist will be 0 and we'll print everything.
155 *
156 */
157
158
159 if ( nolist == 0 ) /* everything's included */
160 return(ON);
161
162 for ( i = 0; i < nolist; i += 2 )
163 if ( num >= olist[i] && num <= olist[i+1] )
164 return(ON);
165
166 return(OFF);
167
168 } /* End of in_olist */
169
170
171 /*****************************************************************************/
172
173
174 int
cat(file)175 cat(file)
176
177
178 char *file; /* copy this file to stdout */
179
180
181 {
182
183
184 int fd_in; /* for the input */
185 int fd_out; /* and output files */
186 char buf[512]; /* buffer for reads and writes */
187 int count; /* number of bytes we just read */
188
189
190 /*
191 *
192 * Copies *file to stdout - mostly for the prologue. Returns FALSE if there was a
193 * problem and TRUE otherwise.
194 *
195 */
196
197
198 fflush(stdout);
199
200 if ( (fd_in = open(file, O_RDONLY)) == -1 )
201 return(FALSE);
202
203 fd_out = fileno(stdout);
204 while ( (count = read(fd_in, buf, sizeof(buf))) > 0 )
205 write(fd_out, buf, count);
206
207 close(fd_in);
208
209 return(TRUE);
210
211 } /* End of cat */
212
213
214 /*****************************************************************************/
215
216
217 int
str_convert(str,err)218 str_convert(str, err)
219
220
221 char **str; /* get next number from this string */
222 int err; /* value returned on error */
223
224
225 {
226
227
228 int i; /* just a loop index */
229
230
231 /*
232 *
233 * Gets the next integer from **str and returns its value to the caller. If **str
234 * isn't an integer err is returned. *str is updated after each digit is processed.
235 *
236 */
237
238
239 if ( ! isdigit(**str) ) /* something's wrong */
240 return(err);
241
242 for ( i = 0; isdigit(**str); *str += 1 )
243 i = 10 * i + **str - '0';
244
245 return(i);
246
247 } /* End of str_convert */
248
249
250 /*****************************************************************************/
251
252
253
254
interrupt(sig)255 void interrupt(sig)
256
257
258 int sig; /* signal that we caught */
259
260
261 {
262
263
264 /*
265 *
266 * Called when we get a signal that we're supposed to catch.
267 *
268 */
269
270
271 if ( temp_file != NULL )
272 unlink(temp_file);
273
274 exit(1);
275
276 } /* End of interrupt */
277
278
279 /*****************************************************************************/
280
281
282