1 /* $NetBSD: display.c,v 1.20 2006/08/26 18:17:42 christos Exp $ */
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #if HAVE_NBTOOL_CONFIG_H
33 #include "nbtool_config.h"
36 #include <sys/cdefs.h>
39 static char sccsid
[] = "@(#)display.c 8.1 (Berkeley) 6/6/93";
41 __RCSID("$NetBSD: display.c,v 1.20 2006/08/26 18:17:42 christos Exp $");
45 #include <sys/param.h>
60 enum _vflag vflag
= FIRST
;
62 static off_t address
; /* address/offset in stream */
63 static off_t eaddress
; /* end address */
65 static inline void print(PR
*, u_char
*);
76 u_char savech
, *savebp
;
79 while ((bp
= get()) != NULL
)
80 for (fs
= fshead
, savebp
= bp
, saveaddress
= address
; fs
;
81 fs
= fs
->nextfs
, bp
= savebp
, address
= saveaddress
)
82 for (fu
= fs
->nextfu
; fu
; fu
= fu
->nextfu
) {
83 if (fu
->flags
&F_IGNORE
)
85 for (cnt
= fu
->reps
; cnt
; --cnt
)
86 for (pr
= fu
->nextpr
; pr
; address
+= pr
->bcnt
,
87 bp
+= pr
->bcnt
, pr
= pr
->nextpr
) {
88 if (eaddress
&& address
>= eaddress
&&
89 !(pr
->flags
& (F_TEXT
|F_BPAD
)))
91 if (cnt
== 1 && pr
->nospace
) {
92 savech
= *pr
->nospace
;
96 if (cnt
== 1 && pr
->nospace
)
97 *pr
->nospace
= savech
;
102 * If eaddress not set, error or file size was multiple of
103 * blocksize, and no partial block ever found.
110 for (pr
= endfu
->nextpr
; pr
; pr
= pr
->nextpr
)
113 (void)printf(pr
->fmt
, (int64_t)eaddress
);
116 (void)printf("%s", pr
->fmt
);
123 print(PR
*pr
, u_char
*bp
)
136 (void)printf(pr
->fmt
, (int64_t)address
);
139 (void)printf(pr
->fmt
, "");
145 (void)printf(pr
->fmt
, *bp
);
150 memmove(&f4
, bp
, sizeof(f4
));
151 (void)printf(pr
->fmt
, f4
);
154 memmove(&f8
, bp
, sizeof(f8
));
155 (void)printf(pr
->fmt
, f8
);
162 (void)printf(pr
->fmt
, (int64_t)*bp
);
165 memmove(&s2
, bp
, sizeof(s2
));
166 (void)printf(pr
->fmt
, (int64_t)s2
);
169 memmove(&s4
, bp
, sizeof(s4
));
170 (void)printf(pr
->fmt
, (int64_t)s4
);
173 memmove(&s8
, bp
, sizeof(s8
));
174 (void)printf(pr
->fmt
, (int64_t)s8
);
179 (void)printf(pr
->fmt
, isprint(*bp
) ? *bp
: '.');
182 (void)printf(pr
->fmt
, (char *)bp
);
185 (void)printf("%s", pr
->fmt
);
193 (void)printf(pr
->fmt
, (uint64_t)*bp
);
196 memmove(&u2
, bp
, sizeof(u2
));
197 (void)printf(pr
->fmt
, (uint64_t)u2
);
200 memmove(&u4
, bp
, sizeof(u4
));
201 (void)printf(pr
->fmt
, (uint64_t)u4
);
204 memmove(&u8
, bp
, sizeof(u8
));
205 (void)printf(pr
->fmt
, (uint64_t)u8
);
215 static const char *spec
= " -0+#";
219 * Remove all conversion flags; '-' is the only one valid
220 * with %s, and it's not useful here.
225 for (p1
= pr
->fmt
; *p1
!= '%'; ++p1
);
226 for (p2
= ++p1
; *p1
&& strchr(spec
, *p1
); ++p1
);
227 while ((*p2
++ = *p1
++) != '\0');
235 static int ateof
= 1;
236 static u_char
*curp
, *savp
;
242 curp
= ecalloc(blocksize
, 1);
243 savp
= ecalloc(blocksize
, 1);
248 address
+= blocksize
;
250 for (need
= blocksize
, nread
= 0;;) {
252 * if read the right number of bytes, or at EOF for one file,
253 * and no other files are available, zero-pad the rest of the
254 * block and set the end flag.
256 if (!length
|| (ateof
&& !next(NULL
))) {
257 if (need
== blocksize
)
259 if (!need
&& vflag
!= ALL
&&
260 !memcmp(curp
, savp
, nread
)) {
265 memset((char *)curp
+ nread
, 0, need
);
266 eaddress
= address
+ nread
;
269 n
= fread((char *)curp
+ nread
, sizeof(u_char
),
270 length
== -1 ? need
: MIN(length
, need
), stdin
);
273 warn("%s", _argv
[-1]);
281 if (vflag
== ALL
|| vflag
== FIRST
||
282 memcmp(curp
, savp
, blocksize
)) {
283 if (vflag
== DUP
|| vflag
== FIRST
)
290 address
+= blocksize
;
311 if (!(freopen(*_argv
, "r", stdin
))) {
324 doskip(statok
? *_argv
: "stdin", statok
);
334 doskip(const char *fname
, int statok
)
340 if (fstat(fileno(stdin
), &sb
))
341 err(1, "fstat %s", fname
);
342 if (S_ISREG(sb
.st_mode
) && skip
>= sb
.st_size
) {
343 address
+= sb
.st_size
;
348 if (S_ISREG(sb
.st_mode
)) {
349 if (fseek(stdin
, skip
, SEEK_SET
))
350 err(1, "fseek %s", fname
);
354 for (cnt
= 0; cnt
< skip
; ++cnt
)
355 if (getchar() == EOF
)