]>
git.saurik.com Git - apple/shell_cmds.git/blob - hexdump/display.c
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 static char sccsid
[] = "@(#)display.c 8.1 (Berkeley) 6/6/93";
39 #include <sys/cdefs.h>
40 __FBSDID("$FreeBSD: src/usr.bin/hexdump/display.c,v 1.19 2004/07/11 01:11:12 tjr Exp $");
42 #include <sys/param.h>
54 enum _vflag vflag
= FIRST
;
56 static off_t address
; /* address/offset in stream */
57 static off_t eaddress
; /* end address */
59 static __inline
void print(PR
*, u_char
*);
70 u_char savech
=0, *savebp
;
73 for (fs
= fshead
, savebp
= bp
, saveaddress
= address
; fs
;
74 fs
= fs
->nextfs
, bp
= savebp
, address
= saveaddress
)
75 for (fu
= fs
->nextfu
; fu
; fu
= fu
->nextfu
) {
76 if (fu
->flags
&F_IGNORE
)
78 for (cnt
= fu
->reps
; cnt
; --cnt
)
79 for (pr
= fu
->nextpr
; pr
; address
+= pr
->bcnt
,
80 bp
+= pr
->bcnt
, pr
= pr
->nextpr
) {
81 if (eaddress
&& address
>= eaddress
&&
82 !(pr
->flags
& (F_TEXT
|F_BPAD
)))
84 if (cnt
== 1 && pr
->nospace
) {
85 savech
= *pr
->nospace
;
89 if (cnt
== 1 && pr
->nospace
)
90 *pr
->nospace
= savech
;
95 * If eaddress not set, error or file size was multiple of
96 * blocksize, and no partial block ever found.
104 for (pr
= endfu
->nextpr
; pr
; pr
= pr
->nextpr
)
107 (void)printf(pr
->fmt
, (quad_t
)eaddress
);
110 (void)printf("%s", pr
->fmt
);
119 print(PR
*pr
, u_char
*bp
)
133 (void)printf(pr
->fmt
, (quad_t
)address
);
136 (void)printf(pr
->fmt
, "");
139 conv_c(pr
, bp
, eaddress
? eaddress
- address
:
140 blocksize
- address
% blocksize
);
143 (void)printf(pr
->fmt
, *bp
);
148 bcopy(bp
, &f4
, sizeof(f4
));
149 (void)printf(pr
->fmt
, f4
);
152 bcopy(bp
, &f8
, sizeof(f8
));
153 (void)printf(pr
->fmt
, f8
);
156 if (pr
->bcnt
== sizeof(long double)) {
157 bcopy(bp
, &ldbl
, sizeof(ldbl
));
158 (void)printf(pr
->fmt
, ldbl
);
166 (void)printf(pr
->fmt
, (quad_t
)(signed char)*bp
);
169 bcopy(bp
, &s2
, sizeof(s2
));
170 (void)printf(pr
->fmt
, (quad_t
)s2
);
173 bcopy(bp
, &s4
, sizeof(s4
));
174 (void)printf(pr
->fmt
, (quad_t
)s4
);
177 bcopy(bp
, &s8
, sizeof(s8
));
178 (void)printf(pr
->fmt
, s8
);
183 (void)printf(pr
->fmt
, isprint(*bp
) && isascii(*bp
) ? *bp
: '.');
186 (void)printf(pr
->fmt
, (char *)bp
);
189 (void)printf("%s", pr
->fmt
);
197 (void)printf(pr
->fmt
, (u_quad_t
)*bp
);
200 bcopy(bp
, &u2
, sizeof(u2
));
201 (void)printf(pr
->fmt
, (u_quad_t
)u2
);
204 bcopy(bp
, &u4
, sizeof(u4
));
205 (void)printf(pr
->fmt
, (u_quad_t
)u4
);
208 bcopy(bp
, &u8
, sizeof(u8
));
209 (void)printf(pr
->fmt
, u8
);
219 static char const *spec
= " -0+#";
223 * Remove all conversion flags; '-' is the only one valid
224 * with %s, and it's not useful here.
229 for (p1
= pr
->fmt
; *p1
!= '%'; ++p1
);
230 for (p2
= ++p1
; *p1
&& index(spec
, *p1
); ++p1
);
231 while ((*p2
++ = *p1
++));
239 static int ateof
= 1;
240 static u_char
*curp
, *savp
;
247 if ((curp
= calloc(1, blocksize
)) == NULL
)
249 if ((savp
= calloc(1, blocksize
)) == NULL
)
255 address
+= blocksize
;
258 for (need
= blocksize
, nread
= 0;;) {
260 * if read the right number of bytes, or at EOF for one file,
261 * and no other files are available, zero-pad the rest of the
262 * block and set the end flag.
264 if (!length
|| (ateof
&& !next((char **)NULL
))) {
265 if (odmode
&& address
< skip
)
266 errx(1, "cannot skip past end of input");
267 if (need
== blocksize
)
268 return((u_char
*)NULL
);
270 * XXX bcmp() is not quite right in the presence
271 * of multibyte characters.
275 if (!need
&& vflag
!= ALL
&&
280 bcmp(curp
, savp
, nread
) == 0) {
283 return((u_char
*)NULL
);
285 bzero((char *)curp
+ nread
, need
);
286 eaddress
= address
+ nread
;
288 lseek(STDIN_FILENO
, ftell(stdin
), SEEK_SET
); /* rewind stdin for next process */
291 n
= fread((char *)curp
+ nread
, sizeof(u_char
),
292 length
== -1 ? need
: MIN(length
, need
), stdin
);
295 warn("%s", _argv
[-1]);
304 * XXX bcmp() is not quite right in the presence
305 * of multibyte characters.
307 if (vflag
== ALL
|| vflag
== FIRST
||
309 bcmp(curp
, savp
, blocksize
) != 0) {
310 if (vflag
== DUP
|| vflag
== FIRST
)
317 address
+= blocksize
;
327 peek(u_char
*buf
, size_t nbytes
)
332 if (length
!= -1 && nbytes
> length
)
335 while (nread
< nbytes
&& (c
= getchar()) != EOF
) {
359 if (!(freopen(*_argv
, "r", stdin
))) {
372 doskip(statok
? *_argv
: "stdin", statok
);
382 doskip(const char *fname
, int statok
)
388 if (fstat(fileno(stdin
), &sb
))
390 if (S_ISREG(sb
.st_mode
) && skip
>= sb
.st_size
) {
391 address
+= sb
.st_size
;
397 /* try to seek first; fall back on ESPIPE */
398 if (fseeko(stdin
, skip
, SEEK_SET
) == 0) {
399 #else /* !__APPLE__ */
400 if (S_ISREG(sb
.st_mode
)) {
401 if (fseeko(stdin
, skip
, SEEK_SET
))
403 #endif /* __APPLE__ */
410 #endif /* __APPLE__ */
411 for (cnt
= 0; cnt
< skip
; ++cnt
)
412 if (getchar() == EOF
)