1 /* $NetBSD: display.c,v 1.21 2009/01/18 21:34:32 apb 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>
40 static char sccsid
[] = "@(#)display.c 8.1 (Berkeley) 6/6/93";
42 __RCSID("$NetBSD: display.c,v 1.21 2009/01/18 21:34:32 apb Exp $");
47 #include <sys/param.h>
62 enum _vflag vflag
= FIRST
;
64 static off_t address
; /* address/offset in stream */
65 static off_t eaddress
; /* end address */
67 static inline void print(PR
*, u_char
*);
78 u_char savech
, *savebp
;
81 while ((bp
= get()) != NULL
)
82 for (fs
= fshead
, savebp
= bp
, saveaddress
= address
; fs
;
83 fs
= fs
->nextfs
, bp
= savebp
, address
= saveaddress
)
84 for (fu
= fs
->nextfu
; fu
; fu
= fu
->nextfu
) {
85 if (fu
->flags
&F_IGNORE
)
87 for (cnt
= fu
->reps
; cnt
; --cnt
)
88 for (pr
= fu
->nextpr
; pr
; address
+= pr
->bcnt
,
89 bp
+= pr
->bcnt
, pr
= pr
->nextpr
) {
90 if (eaddress
&& address
>= eaddress
&&
91 !(pr
->flags
& (F_TEXT
|F_BPAD
)))
93 if (cnt
== 1 && pr
->nospace
) {
94 savech
= *pr
->nospace
;
98 if (cnt
== 1 && pr
->nospace
)
99 *pr
->nospace
= savech
;
104 * If eaddress not set, error or file size was multiple of
105 * blocksize, and no partial block ever found.
112 for (pr
= endfu
->nextpr
; pr
; pr
= pr
->nextpr
)
115 (void)printf(pr
->fmt
, (int64_t)eaddress
);
118 (void)printf("%s", pr
->fmt
);
125 print(PR
*pr
, u_char
*bp
)
138 (void)printf(pr
->fmt
, (int64_t)address
);
141 (void)printf(pr
->fmt
, "");
147 (void)printf(pr
->fmt
, *bp
);
152 memmove(&f4
, bp
, sizeof(f4
));
153 (void)printf(pr
->fmt
, f4
);
156 memmove(&f8
, bp
, sizeof(f8
));
157 (void)printf(pr
->fmt
, f8
);
164 (void)printf(pr
->fmt
, (int64_t)*bp
);
167 memmove(&s2
, bp
, sizeof(s2
));
168 (void)printf(pr
->fmt
, (int64_t)s2
);
171 memmove(&s4
, bp
, sizeof(s4
));
172 (void)printf(pr
->fmt
, (int64_t)s4
);
175 memmove(&s8
, bp
, sizeof(s8
));
176 (void)printf(pr
->fmt
, (int64_t)s8
);
181 (void)printf(pr
->fmt
, isprint(*bp
) ? *bp
: '.');
184 (void)printf(pr
->fmt
, (char *)bp
);
187 (void)printf("%s", pr
->fmt
);
195 (void)printf(pr
->fmt
, (uint64_t)*bp
);
198 memmove(&u2
, bp
, sizeof(u2
));
199 (void)printf(pr
->fmt
, (uint64_t)u2
);
202 memmove(&u4
, bp
, sizeof(u4
));
203 (void)printf(pr
->fmt
, (uint64_t)u4
);
206 memmove(&u8
, bp
, sizeof(u8
));
207 (void)printf(pr
->fmt
, (uint64_t)u8
);
217 static const char *spec
= " -0+#";
221 * Remove all conversion flags; '-' is the only one valid
222 * with %s, and it's not useful here.
227 for (p1
= pr
->fmt
; *p1
!= '%'; ++p1
);
228 for (p2
= ++p1
; *p1
&& strchr(spec
, *p1
); ++p1
);
229 while ((*p2
++ = *p1
++) != '\0');
237 static int ateof
= 1;
238 static u_char
*curp
, *savp
;
244 curp
= ecalloc(blocksize
, 1);
245 savp
= ecalloc(blocksize
, 1);
250 address
+= blocksize
;
252 for (need
= blocksize
, nread
= 0;;) {
254 * if read the right number of bytes, or at EOF for one file,
255 * and no other files are available, zero-pad the rest of the
256 * block and set the end flag.
258 if (!length
|| (ateof
&& !next(NULL
))) {
259 if (need
== blocksize
)
261 if (!need
&& vflag
!= ALL
&&
262 !memcmp(curp
, savp
, nread
)) {
267 memset((char *)curp
+ nread
, 0, need
);
268 eaddress
= address
+ nread
;
271 n
= fread((char *)curp
+ nread
, sizeof(u_char
),
272 length
== -1 ? need
: MIN(length
, need
), stdin
);
275 warn("%s", _argv
[-1]);
283 if (vflag
== ALL
|| vflag
== FIRST
||
284 memcmp(curp
, savp
, blocksize
)) {
285 if (vflag
== DUP
|| vflag
== FIRST
)
292 address
+= blocksize
;
313 if (!(freopen(*_argv
, "r", stdin
))) {
326 doskip(statok
? *_argv
: "stdin", statok
);
336 doskip(const char *fname
, int statok
)
342 if (fstat(fileno(stdin
), &sb
))
343 err(1, "fstat %s", fname
);
344 if (S_ISREG(sb
.st_mode
) && skip
>= sb
.st_size
) {
345 address
+= sb
.st_size
;
350 if (S_ISREG(sb
.st_mode
)) {
351 if (fseek(stdin
, skip
, SEEK_SET
))
352 err(1, "fseek %s", fname
);
356 for (cnt
= 0; cnt
< skip
; ++cnt
)
357 if (getchar() == EOF
)