blob: 3e7c54b4233c588f2744bb18b7c4fcbc2a2c55a5 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* xxd: my hexdump facility. jw
2 *
3 * 2.10.90 changed to word output
4 * 3.03.93 new indent style, dumb bug inserted and fixed.
5 * -c option, mls
6 * 26.04.94 better option parser, -ps, -l, -s added.
7 * 1.07.94 -r badly needs - as input file. Per default autoskip over
Bram Moolenaar82038d72007-05-10 17:15:45 +00008 * consecutive lines of zeroes, as unix od does.
Bram Moolenaar071d4272004-06-13 20:20:40 +00009 * -a shows them too.
10 * -i dump as c-style #include "file.h"
11 * 1.11.95 if "xxd -i" knows the filename, an 'unsigned char filename_bits[]'
12 * array is written in correct c-syntax.
13 * -s improved, now defaults to absolute seek, relative requires a '+'.
14 * -r improved, now -r -s -0x... is supported.
15 * change/suppress leading '\0' bytes.
16 * -l n improved: stops exactly after n bytes.
17 * -r improved, better handling of partial lines with trailing garbage.
18 * -r improved, now -r -p works again!
19 * -r improved, less flushing, much faster now! (that was silly)
20 * 3.04.96 Per repeated request of a single person: autoskip defaults to off.
21 * 15.05.96 -v added. They want to know the version.
22 * -a fixed, to show last line inf file ends in all zeros.
23 * -u added: Print upper case hex-letters, as preferred by unix bc.
24 * -h added to usage message. Usage message extended.
25 * Now using outfile if specified even in normal mode, aehem.
26 * No longer mixing of ints and longs. May help doze people.
27 * Added binify ioctl for same reason. (Enough Doze stress for 1996!)
28 * 16.05.96 -p improved, removed occasional superfluous linefeed.
29 * 20.05.96 -l 0 fixed. tried to read anyway.
30 * 21.05.96 -i fixed. now honours -u, and prepends __ to numeric filenames.
31 * compile -DWIN32 for NT or W95. George V. Reilly, * -v improved :-)
32 * support --gnuish-longhorn-options
33 * 25.05.96 MAC support added: CodeWarrior already uses ``outline'' in Types.h
34 * which is included by MacHeaders (Axel Kielhorn). Renamed to
35 * xxdline().
36 * 7.06.96 -i printed 'int' instead of 'char'. *blush*
37 * added Bram's OS2 ifdefs...
Bram Moolenaar4b96df52020-01-26 22:00:26 +010038 * 18.07.96 gcc -Wall @ SunOS4 is now silent.
Bram Moolenaar071d4272004-06-13 20:20:40 +000039 * Added osver for MSDOS/DJGPP/WIN32.
40 * 29.08.96 Added size_t to strncmp() for Amiga.
41 * 24.03.97 Windows NT support (Phil Hanna). Clean exit for Amiga WB (Bram)
42 * 02.04.97 Added -E option, to have EBCDIC translation instead of ASCII
Bram Moolenaar4317d9b2005-03-18 20:25:31 +000043 * (azc10@yahoo.com)
Bram Moolenaar071d4272004-06-13 20:20:40 +000044 * 22.05.97 added -g (group octets) option (jcook@namerica.kla.com).
45 * 23.09.98 nasty -p -r misfeature fixed: slightly wrong output, when -c was
46 * missing or wrong.
47 * 26.09.98 Fixed: 'xxd -i infile outfile' did not truncate outfile.
48 * 27.10.98 Fixed: -g option parser required blank.
49 * option -b added: 01000101 binary output in normal format.
50 * 16.05.00 Added VAXC changes by Stephen P. Wall
Bram Moolenaar82038d72007-05-10 17:15:45 +000051 * 16.05.00 Improved MMS file and merge for VMS by Zoltan Arpadffy
Bram Moolenaare0659a62011-04-01 19:14:40 +020052 * 2011 March Better error handling by Florian Zumbiehl.
53 * 2011 April Formatting by Bram Moolenaar
Bram Moolenaar4dcdf292015-03-05 17:51:15 +010054 * 08.06.2013 Little-endian hexdump (-e) and offset (-o) by Vadim Vygonets.
Bram Moolenaard8c56a02019-01-30 23:02:25 +010055 * 11.01.2019 Add full 64/32 bit range to -o and output by Christer Jensen.
Bram Moolenaar363d6142020-05-30 20:50:25 +020056 * 04.02.2020 Add -d for decimal offsets by Aapo Rantalainen
Erik Auerswaldc0a1d372022-01-14 11:58:48 +000057 * 14.01.2022 Disable extra newlines with -c0 -p by Erik Auerswald.
David Gow83e11802022-06-29 20:24:49 +010058 * 20.06.2022 Permit setting the variable names used by -i by David Gow
Christian Brabandt0ffa97e2023-08-31 21:03:02 +020059 * 31.08.2023 -R never/auto/always prints colored output
tristhaus85f45212023-10-06 19:51:13 +020060 * 06.10.2023 enable -r -b to reverse bit dumps
Igor Todorovski48a75f32024-01-09 21:05:48 +000061 * 12.01.2024 disable auto-conversion for z/OS (MVS)
Kuratius7062be12024-01-17 18:37:32 +010062 * 17.01.2024 use size_t instead of usigned int for code-generation (-i), #13876
Christian Brabandtfa8c9712024-01-25 20:50:49 +010063 * 25.01.2024 revert the previous patch (size_t instead of unsigned int)
Goffredo Baroncelli00221482024-02-10 13:31:06 +010064 * 10.02.2024 fix buffer-overflow when writing color output to buffer, #14003
Lennard Hofmann67797192024-05-10 14:17:26 +020065 * 10.05.2024 fix another buffer-overflow when writing colored output to buffer, #14738
Andre Chang15022722024-09-15 20:03:05 +020066 * 10.09.2024 Support -b and -i together, #15661
Aapo Rantalainenc73fc862024-10-19 15:54:57 +020067 * 19.10.2024 -e did add an extra space #15899
DungSaga4b9fa952024-11-11 22:19:50 +010068 * 11.11.2024 improve end-of-options argument parser #9285
sendittothenewts6e6aff02024-12-07 16:27:22 +010069 * 07.12.2024 fix overflow with xxd --autoskip and large sparse files #16175
Emanuel Krollmann6897f182025-06-15 16:24:09 +020070 * 15.06.2025 improve color code logic
Bram Moolenaar071d4272004-06-13 20:20:40 +000071 *
=?UTF-8?q?J=C3=BCrgen=20Weigert?=80b2ba32021-06-29 20:36:25 +020072 * (c) 1990-1998 by Juergen Weigert (jnweiger@gmail.com)
Bram Moolenaar071d4272004-06-13 20:20:40 +000073 *
Bram Moolenaar43fe3292015-08-04 17:29:07 +020074 * I hereby grant permission to distribute and use xxd
75 * under X11-MIT or GPL-2.0 (at the user's choice).
76 *
=?UTF-8?q?J=C3=BCrgen=20Weigert?=80b2ba32021-06-29 20:36:25 +020077 * Contributions by Bram Moolenaar et al.
Bram Moolenaar071d4272004-06-13 20:20:40 +000078 */
Bram Moolenaar362e1a32006-03-06 23:29:24 +000079
80/* Visual Studio 2005 has 'deprecated' many of the standard CRT functions */
81#if _MSC_VER >= 1400
82# define _CRT_SECURE_NO_DEPRECATE
83# define _CRT_NONSTDC_NO_DEPRECATE
84#endif
Bram Moolenaar6ef8f9e2019-03-02 07:15:28 +010085#if !defined(CYGWIN) && defined(__CYGWIN__)
Bram Moolenaardc40a2b2009-06-16 16:29:10 +000086# define CYGWIN
87#endif
Bram Moolenaar362e1a32006-03-06 23:29:24 +000088
Yegappan Lakshmananef089f52021-12-31 17:33:47 +000089#if (defined(__linux__) && !defined(__ANDROID__)) || defined(__CYGWIN__)
90# define _XOPEN_SOURCE 700 /* for fdopen() */
91#endif
92
Bram Moolenaar071d4272004-06-13 20:20:40 +000093#include <stdio.h>
94#ifdef VAXC
95# include <file.h>
96#else
97# include <fcntl.h>
98#endif
Bram Moolenaareae1b912019-05-09 15:12:55 +020099#if defined(WIN32) || defined(CYGWIN)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000100# include <io.h> /* for setmode() */
Ken Takatac4a40382023-10-25 21:17:35 +0200101#endif
102#ifdef WIN32
K.Takataf6fc2552023-09-01 18:41:04 +0200103# include <windows.h>
104#endif
105#ifdef UNIX
106# include <unistd.h>
Bram Moolenaar071d4272004-06-13 20:20:40 +0000107#endif
108#include <stdlib.h>
Keith Thompson184f71c2024-01-04 21:19:04 +0100109#include <string.h>
110#include <ctype.h>
Bram Moolenaard8c56a02019-01-30 23:02:25 +0100111#include <limits.h>
Bram Moolenaar071d4272004-06-13 20:20:40 +0000112#if __MWERKS__ && !defined(BEBOX)
113# include <unix.h> /* for fdopen() on MAC */
114#endif
115
Bram Moolenaar071d4272004-06-13 20:20:40 +0000116
117/* This corrects the problem of missing prototypes for certain functions
118 * in some GNU installations (e.g. SunOS 4.1.x).
119 * Darren Hiebert <darren@hmi.com> (sparc-sun-sunos4.1.3_U1/2.7.2.2)
120 */
121#if defined(__GNUC__) && defined(__STDC__)
122# ifndef __USE_FIXED_PROTOTYPES__
123# define __USE_FIXED_PROTOTYPES__
124# endif
125#endif
126
127#ifndef __USE_FIXED_PROTOTYPES__
128/*
129 * This is historic and works only if the compiler really has no prototypes:
130 *
131 * Include prototypes for Sun OS 4.x, when using an ANSI compiler.
132 * FILE is defined on OS 4.x, not on 5.x (Solaris).
133 * if __SVR4 is defined (some Solaris versions), don't include this.
134 */
135#if defined(sun) && defined(FILE) && !defined(__SVR4) && defined(__STDC__)
136# define __P(a) a
137/* excerpt from my sun_stdlib.h */
138extern int fprintf __P((FILE *, char *, ...));
139extern int fputs __P((char *, FILE *));
140extern int _flsbuf __P((unsigned char, FILE *));
141extern int _filbuf __P((FILE *));
142extern int fflush __P((FILE *));
143extern int fclose __P((FILE *));
144extern int fseek __P((FILE *, long, int));
145extern int rewind __P((FILE *));
146
147extern void perror __P((char *));
148# endif
149#endif
150
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200151char version[] = "xxd 2025-06-15 by Juergen Weigert et al.";
Bram Moolenaar071d4272004-06-13 20:20:40 +0000152#ifdef WIN32
153char osver[] = " (Win32)";
154#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000155char osver[] = "";
Bram Moolenaar071d4272004-06-13 20:20:40 +0000156#endif
157
Bram Moolenaara06ecab2016-07-16 14:47:36 +0200158#if defined(WIN32)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000159# define BIN_READ(yes) ((yes) ? "rb" : "rt")
160# define BIN_WRITE(yes) ((yes) ? "wb" : "wt")
161# define BIN_CREAT(yes) ((yes) ? (O_CREAT|O_BINARY) : O_CREAT)
162# define BIN_ASSIGN(fp, yes) setmode(fileno(fp), (yes) ? O_BINARY : O_TEXT)
Bram Moolenaar12033fb2005-12-16 21:49:31 +0000163# define PATH_SEP '\\'
164#elif defined(CYGWIN)
165# define BIN_READ(yes) ((yes) ? "rb" : "rt")
166# define BIN_WRITE(yes) ((yes) ? "wb" : "w")
167# define BIN_CREAT(yes) ((yes) ? (O_CREAT|O_BINARY) : O_CREAT)
168# define BIN_ASSIGN(fp, yes) ((yes) ? (void) setmode(fileno(fp), O_BINARY) : (void) (fp))
169# define PATH_SEP '/'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000170#else
171# ifdef VMS
172# define BIN_READ(dummy) "r"
173# define BIN_WRITE(dummy) "w"
174# define BIN_CREAT(dummy) O_CREAT
175# define BIN_ASSIGN(fp, dummy) fp
176# define PATH_SEP ']'
177# define FILE_SEP '.'
178# else
179# define BIN_READ(dummy) "r"
180# define BIN_WRITE(dummy) "w"
181# define BIN_CREAT(dummy) O_CREAT
182# define BIN_ASSIGN(fp, dummy) fp
183# define PATH_SEP '/'
184# endif
185#endif
186
187/* open has only to arguments on the Mac */
188#if __MWERKS__
189# define OPEN(name, mode, umask) open(name, mode)
190#else
191# define OPEN(name, mode, umask) open(name, mode, umask)
192#endif
193
194#ifdef AMIGA
195# define STRNCMP(s1, s2, l) strncmp(s1, s2, (size_t)l)
196#else
197# define STRNCMP(s1, s2, l) strncmp(s1, s2, l)
198#endif
199
200#ifndef __P
Bram Moolenaareae1b912019-05-09 15:12:55 +0200201# if defined(__STDC__) || defined(WIN32)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000202# define __P(a) a
203# else
204# define __P(a) ()
205# endif
206#endif
207
Bram Moolenaar071d4272004-06-13 20:20:40 +0000208#define TRY_SEEK /* attempt to use lseek, or skip forward by reading */
209#define COLS 256 /* change here, if you ever need more columns */
Goffredo Baroncelli00221482024-02-10 13:31:06 +0100210
211/*
212 * LLEN is the maximum length of a line; other than the visible characters
213 * we need to consider also the escape color sequence prologue/epilogue ,
Lennard Hofmann67797192024-05-10 14:17:26 +0200214 * (11 bytes for each character).
Goffredo Baroncelli00221482024-02-10 13:31:06 +0100215 */
Lennard Hofmann67797192024-05-10 14:17:26 +0200216#define LLEN \
217 (39 /* addr: ⌈log10(ULONG_MAX)⌉ if "-d" flag given. We assume ULONG_MAX = 2**128 */ \
218 + 2 /* ": " */ \
219 + 13 * COLS /* hex dump with colors */ \
220 + (COLS - 1) /* whitespace between groups if "-g1" option given and "-c" maxed out */ \
221 + 2 /* whitespace */ \
222 + 12 * COLS /* ASCII dump with colors */ \
223 + 2) /* "\n\0" */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000224
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200225/*
226 * LLEN_NO_COLOR is the maximum length of a line excluding the colors.
227 */
228#define LLEN_NO_COLOR \
229 (39 /* addr: ⌈log10(ULONG_MAX)⌉ if "-d" flag given. We assume ULONG_MAX = 2**128 */ \
230 + 2 /* ": " */ \
231 + 2 * COLS /* hex dump */ \
232 + (COLS - 1) /* whitespace between groups if "-g1" option given and "-c" maxed out */ \
233 + 2 /* whitespace */ \
234 + COLS /* ASCII dump */ \
235 + 2) /* "\n\0" */
236
Bram Moolenaar071d4272004-06-13 20:20:40 +0000237char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa;
238
239/* the different hextypes known by this program: */
Andre Chang15022722024-09-15 20:03:05 +0200240#define HEX_NORMAL 0x00 /* no flags set */
241#define HEX_POSTSCRIPT 0x01
242#define HEX_CINCLUDE 0x02
243#define HEX_BITS 0x04 /* not hex a dump, but bits: 01111001 */
244#define HEX_LITTLEENDIAN 0x08
Bram Moolenaar071d4272004-06-13 20:20:40 +0000245
Keith Thompson184f71c2024-01-04 21:19:04 +0100246#define CONDITIONAL_CAPITALIZE(c) (capitalize ? toupper((unsigned char)(c)) : (c))
Bram Moolenaar8b31a6f2018-04-03 12:17:25 +0200247
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200248#define COLOR_PROLOGUE(color) \
249l_colored[c++] = '\033'; \
250l_colored[c++] = '['; \
251l_colored[c++] = '1'; \
252l_colored[c++] = ';'; \
253l_colored[c++] = '3'; \
254l_colored[c++] = (color); \
255l_colored[c++] = 'm';
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200256
257#define COLOR_EPILOGUE \
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200258l_colored[c++] = '\033'; \
259l_colored[c++] = '['; \
260l_colored[c++] = '0'; \
261l_colored[c++] = 'm';
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200262#define COLOR_RED '1'
263#define COLOR_GREEN '2'
264#define COLOR_YELLOW '3'
265#define COLOR_BLUE '4'
266#define COLOR_WHITE '7'
267
Bram Moolenaare0659a62011-04-01 19:14:40 +0200268static char *pname;
269
270 static void
Bram Moolenaarb638a7b2016-01-30 21:29:58 +0100271exit_with_usage(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000272{
273 fprintf(stderr, "Usage:\n %s [options] [infile [outfile]]\n", pname);
274 fprintf(stderr, " or\n %s -r [-s [-]offset] [-c cols] [-ps] [infile [outfile]]\n", pname);
275 fprintf(stderr, "Options:\n");
276 fprintf(stderr, " -a toggle autoskip: A single '*' replaces nul-lines. Default off.\n");
Andre Chang15022722024-09-15 20:03:05 +0200277 fprintf(stderr, " -b binary digit dump (incompatible with -ps). Default hex.\n");
Bram Moolenaar8b31a6f2018-04-03 12:17:25 +0200278 fprintf(stderr, " -C capitalize variable names in C include file style (-i).\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000279 fprintf(stderr, " -c cols format <cols> octets per line. Default 16 (-i: 12, -ps: 30).\n");
280 fprintf(stderr, " -E show characters in EBCDIC. Default ASCII.\n");
Bram Moolenaar4dcdf292015-03-05 17:51:15 +0100281 fprintf(stderr, " -e little-endian dump (incompatible with -ps,-i,-r).\n");
Atsushi SUGAWARA34a36482021-10-17 16:09:08 +0100282 fprintf(stderr, " -g bytes number of octets per group in normal output. Default 2 (-e: 4).\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000283 fprintf(stderr, " -h print this summary.\n");
284 fprintf(stderr, " -i output in C include file style.\n");
285 fprintf(stderr, " -l len stop after <len> octets.\n");
David Gow83e11802022-06-29 20:24:49 +0100286 fprintf(stderr, " -n name set the variable name used in C include output (-i).\n");
Bram Moolenaar4dcdf292015-03-05 17:51:15 +0100287 fprintf(stderr, " -o off add <off> to the displayed file position.\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000288 fprintf(stderr, " -ps output in postscript plain hexdump style.\n");
289 fprintf(stderr, " -r reverse operation: convert (or patch) hexdump into binary.\n");
290 fprintf(stderr, " -r -s off revert with <off> added to file positions found in hexdump.\n");
Bram Moolenaar363d6142020-05-30 20:50:25 +0200291 fprintf(stderr, " -d show offset in decimal instead of hex.\n");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000292 fprintf(stderr, " -s %sseek start at <seek> bytes abs. %sinfile offset.\n",
293#ifdef TRY_SEEK
294 "[+][-]", "(or +: rel.) ");
295#else
296 "", "");
297#endif
298 fprintf(stderr, " -u use upper case hex letters.\n");
K.Takataf6fc2552023-09-01 18:41:04 +0200299 fprintf(stderr, " -R when colorize the output; <when> can be 'always', 'auto' or 'never'. Default: 'auto'.\n"),
Bram Moolenaar071d4272004-06-13 20:20:40 +0000300 fprintf(stderr, " -v show version: \"%s%s\".\n", version, osver);
301 exit(1);
302}
303
Bram Moolenaare0659a62011-04-01 19:14:40 +0200304 static void
DungSagaa2ffb432021-10-22 15:55:31 +0100305perror_exit(int ret)
Bram Moolenaare0659a62011-04-01 19:14:40 +0200306{
307 fprintf(stderr, "%s: ", pname);
308 perror(NULL);
309 exit(ret);
310}
311
DungSagaa2ffb432021-10-22 15:55:31 +0100312 static void
313error_exit(int ret, char *msg)
314{
315 fprintf(stderr, "%s: %s\n", pname, msg);
316 exit(ret);
317}
318
DungSagad1d8a592021-11-26 13:59:27 +0000319 static int
320getc_or_die(FILE *fpi)
Bram Moolenaar8af87bd2021-11-25 11:16:50 +0000321{
DungSagad1d8a592021-11-26 13:59:27 +0000322 int c = getc(fpi);
Bram Moolenaar8af87bd2021-11-25 11:16:50 +0000323 if (c == EOF && ferror(fpi))
324 perror_exit(2);
DungSagad1d8a592021-11-26 13:59:27 +0000325 return c;
Bram Moolenaar8af87bd2021-11-25 11:16:50 +0000326}
327
328 static void
Bram Moolenaar71b36202021-11-25 13:26:19 +0000329putc_or_die(int c, FILE *fpo)
Bram Moolenaar8af87bd2021-11-25 11:16:50 +0000330{
331 if (putc(c, fpo) == EOF)
332 perror_exit(3);
333}
334
335 static void
336fputs_or_die(char *s, FILE *fpo)
337{
338 if (fputs(s, fpo) == EOF)
339 perror_exit(3);
340}
341
DungSaga7e5503c2021-12-01 11:24:52 +0000342/* Use a macro to allow for different arguments. */
343#define FPRINTF_OR_DIE(args) if (fprintf args < 0) perror_exit(3)
Bram Moolenaar8af87bd2021-11-25 11:16:50 +0000344
345 static void
346fclose_or_die(FILE *fpi, FILE *fpo)
347{
348 if (fclose(fpo) != 0)
349 perror_exit(3);
350 if (fclose(fpi) != 0)
351 perror_exit(2);
352}
353
Bram Moolenaar071d4272004-06-13 20:20:40 +0000354/*
Bram Moolenaar786e05b2021-11-14 13:46:05 +0000355 * If "c" is a hex digit, return the value.
356 * Otherwise return -1.
357 */
358 static int
359parse_hex_digit(int c)
360{
361 return (c >= '0' && c <= '9') ? c - '0'
362 : (c >= 'a' && c <= 'f') ? c - 'a' + 10
363 : (c >= 'A' && c <= 'F') ? c - 'A' + 10
364 : -1;
365}
366
367/*
tristhaus85f45212023-10-06 19:51:13 +0200368 * If "c" is a bin digit, return the value.
369 * Otherwise return -1.
370 */
371 static int
372parse_bin_digit(int c)
373{
374 return (c >= '0' && c <= '1') ? c - '0'
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200375 : -1;
tristhaus85f45212023-10-06 19:51:13 +0200376}
377
378/*
Bram Moolenaar786e05b2021-11-14 13:46:05 +0000379 * Ignore text on "fpi" until end-of-line or end-of-file.
380 * Return the '\n' or EOF character.
381 * When an error is encountered exit with an error message.
382 */
383 static int
384skip_to_eol(FILE *fpi, int c)
385{
386 while (c != '\n' && c != EOF)
DungSagad1d8a592021-11-26 13:59:27 +0000387 c = getc_or_die(fpi);
Bram Moolenaar786e05b2021-11-14 13:46:05 +0000388 return c;
389}
390
391/*
Bram Moolenaar071d4272004-06-13 20:20:40 +0000392 * Max. cols binary characters are decoded from the input stream per line.
393 * Two adjacent garbage characters after evaluated data delimit valid data.
394 * Everything up to the next newline is discarded.
395 *
396 * The name is historic and came from 'undo type opt h'.
397 */
Bram Moolenaare0659a62011-04-01 19:14:40 +0200398 static int
Bram Moolenaarb638a7b2016-01-30 21:29:58 +0100399huntype(
400 FILE *fpi,
401 FILE *fpo,
Bram Moolenaarb638a7b2016-01-30 21:29:58 +0100402 int cols,
403 int hextype,
404 long base_off)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000405{
Christian Brabandt7879bc52023-10-08 20:36:44 +0200406 int c, ign_garb = 1, n1 = -1, n2 = 0, n3 = 0, p = cols, bt = 0, b = 0, bcnt = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000407 long have_off = 0, want_off = 0;
408
409 rewind(fpi);
410
411 while ((c = getc(fpi)) != EOF)
412 {
413 if (c == '\r') /* Doze style input file? */
414 continue;
415
Bram Moolenaar8a33e742010-02-17 18:28:41 +0100416 /* Allow multiple spaces. This doesn't work when there is normal text
417 * after the hex codes in the last line that looks like hex, thus only
418 * use it for PostScript format. */
419 if (hextype == HEX_POSTSCRIPT && (c == ' ' || c == '\n' || c == '\t'))
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000420 continue;
Bram Moolenaar899dddf2006-03-26 21:06:50 +0000421
tristhaus85f45212023-10-06 19:51:13 +0200422 if (hextype == HEX_NORMAL || hextype == HEX_POSTSCRIPT)
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200423 {
tristhaus85f45212023-10-06 19:51:13 +0200424 n3 = n2;
425 n2 = n1;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000426
tristhaus85f45212023-10-06 19:51:13 +0200427 n1 = parse_hex_digit(c);
428 if (n1 == -1 && ign_garb)
429 continue;
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200430 }
tristhaus85f45212023-10-06 19:51:13 +0200431 else /* HEX_BITS */
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200432 {
tristhaus85f45212023-10-06 19:51:13 +0200433 n1 = parse_hex_digit(c);
434 if (n1 == -1 && ign_garb)
435 continue;
436
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200437 bt = parse_bin_digit(c);
438 if (bt != -1)
439 {
440 b = ((b << 1) | bt);
441 ++bcnt;
442 }
443 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000444
445 ign_garb = 0;
446
tristhaus85f45212023-10-06 19:51:13 +0200447 if ((hextype != HEX_POSTSCRIPT) && (p >= cols))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000448 {
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200449 if (hextype == HEX_NORMAL)
450 {
tristhaus85f45212023-10-06 19:51:13 +0200451 if (n1 < 0)
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200452 {
453 p = 0;
454 continue;
455 }
tristhaus85f45212023-10-06 19:51:13 +0200456 want_off = (want_off << 4) | n1;
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200457 }
458 else /* HEX_BITS */
459 {
OldWorldOrdr1c140302023-10-25 20:57:30 +0200460 if (n1 < 0)
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200461 {
462 p = 0;
463 bcnt = 0;
464 continue;
465 }
OldWorldOrdr1c140302023-10-25 20:57:30 +0200466 want_off = (want_off << 4) | n1;
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200467 }
468 continue;
469 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000470
471 if (base_off + want_off != have_off)
472 {
Bram Moolenaare0659a62011-04-01 19:14:40 +0200473 if (fflush(fpo) != 0)
DungSagaa2ffb432021-10-22 15:55:31 +0100474 perror_exit(3);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000475#ifdef TRY_SEEK
Bram Moolenaar786e05b2021-11-14 13:46:05 +0000476 if (fseek(fpo, base_off + want_off - have_off, SEEK_CUR) >= 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000477 have_off = base_off + want_off;
478#endif
479 if (base_off + want_off < have_off)
DungSaga7e5503c2021-12-01 11:24:52 +0000480 error_exit(5, "Sorry, cannot seek backwards.");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000481 for (; have_off < base_off + want_off; have_off++)
Bram Moolenaar8af87bd2021-11-25 11:16:50 +0000482 putc_or_die(0, fpo);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000483 }
484
tristhaus85f45212023-10-06 19:51:13 +0200485 if (hextype == HEX_NORMAL || hextype == HEX_POSTSCRIPT)
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200486 {
487 if (n2 >= 0 && n1 >= 0)
488 {
489 putc_or_die((n2 << 4) | n1, fpo);
490 have_off++;
491 want_off++;
492 n1 = -1;
493 if (!hextype && (++p >= cols))
494 /* skip the rest of the line as garbage */
495 c = skip_to_eol(fpi, c);
496 }
497 else if (n1 < 0 && n2 < 0 && n3 < 0)
498 /* already stumbled into garbage, skip line, wait and see */
499 c = skip_to_eol(fpi, c);
500 }
tristhaus85f45212023-10-06 19:51:13 +0200501 else /* HEX_BITS */
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200502 {
503 if (bcnt == 8)
504 {
505 putc_or_die(b, fpo);
506 have_off++;
507 want_off++;
508 b = 0;
509 bcnt = 0;
510 if (++p >= cols)
511 /* skip the rest of the line as garbage */
512 c = skip_to_eol(fpi, c);
513 }
514 }
Bram Moolenaar786e05b2021-11-14 13:46:05 +0000515
DungSaga47810462021-10-22 12:55:42 +0100516 if (c == '\n')
517 {
tristhaus85f45212023-10-06 19:51:13 +0200518 if (hextype == HEX_NORMAL || hextype == HEX_BITS)
DungSaga47810462021-10-22 12:55:42 +0100519 want_off = 0;
520 p = cols;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000521 ign_garb = 1;
522 }
523 }
Bram Moolenaare0659a62011-04-01 19:14:40 +0200524 if (fflush(fpo) != 0)
DungSagaa2ffb432021-10-22 15:55:31 +0100525 perror_exit(3);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000526#ifdef TRY_SEEK
Bram Moolenaar786e05b2021-11-14 13:46:05 +0000527 fseek(fpo, 0L, SEEK_END);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000528#endif
Bram Moolenaar8af87bd2021-11-25 11:16:50 +0000529 fclose_or_die(fpi, fpo);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000530 return 0;
531}
532
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200533
Bram Moolenaar071d4272004-06-13 20:20:40 +0000534/*
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200535 * Print line l with given colors.
536 */
537 static void
538print_colored_line(FILE *fp, char *l, char *colors)
539{
540 static char l_colored[LLEN+1];
541
542 if (colors)
543 {
544 int c = 0;
545 if (colors[0])
546 {
547 COLOR_PROLOGUE(colors[0])
548 }
549 l_colored[c++] = l[0];
550 int i;
551 for (i = 1; l[i]; i++)
552 {
553 if (colors[i] != colors[i-1])
554 {
555 if (colors[i-1])
556 {
557 COLOR_EPILOGUE
558 }
559 if (colors[i])
560 {
561 COLOR_PROLOGUE(colors[i])
562 }
563 }
564 l_colored[c++] = l[i];
565 }
566
567 if (colors[i])
568 {
569 COLOR_EPILOGUE
570 }
571 l_colored[c++] = '\0';
572
573 fputs_or_die(l_colored, fp);
574 }
575 else
576 fputs_or_die(l, fp);
577}
578
579/*
580 * Print line l with given colors. If nz is false, xxdline regards the line as a line of
Bram Moolenaar071d4272004-06-13 20:20:40 +0000581 * zeroes. If there are three or more consecutive lines of zeroes,
582 * they are replaced by a single '*' character.
583 *
584 * If the output ends with more than two lines of zeroes, you
585 * should call xxdline again with l being the last line and nz
586 * negative. This ensures that the last line is shown even when
587 * it is all zeroes.
588 *
589 * If nz is always positive, lines are never suppressed.
590 */
Bram Moolenaare0659a62011-04-01 19:14:40 +0200591 static void
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200592xxdline(FILE *fp, char *l, char *colors, int nz)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000593{
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200594 static char z[LLEN_NO_COLOR+1];
595 static char z_colors[LLEN_NO_COLOR+1];
sendittothenewts6e6aff02024-12-07 16:27:22 +0100596 static signed char zero_seen = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000597
598 if (!nz && zero_seen == 1)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200599 {
600 strcpy(z, l);
601 memcpy(z_colors, colors, strlen(z));
602 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000603
604 if (nz || !zero_seen++)
605 {
606 if (nz)
607 {
608 if (nz < 0)
609 zero_seen--;
610 if (zero_seen == 2)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200611 print_colored_line(fp, z, z_colors);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000612 if (zero_seen > 2)
Bram Moolenaar8af87bd2021-11-25 11:16:50 +0000613 fputs_or_die("*\n", fp);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000614 }
615 if (nz >= 0 || zero_seen > 0)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200616 print_colored_line(fp, l, colors);
617
Bram Moolenaar071d4272004-06-13 20:20:40 +0000618 if (nz)
619 zero_seen = 0;
620 }
sendittothenewts6e6aff02024-12-07 16:27:22 +0100621
622 /* If zero_seen > 3, then its exact value doesn't matter, so long as it
623 * remains >3 and incrementing it will not cause overflow. */
624 if (zero_seen >= 0x7F)
625 zero_seen = 4;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000626}
627
628/* This is an EBCDIC to ASCII conversion table */
629/* from a proposed BTL standard April 16, 1979 */
630static unsigned char etoa64[] =
631{
632 0040,0240,0241,0242,0243,0244,0245,0246,
633 0247,0250,0325,0056,0074,0050,0053,0174,
634 0046,0251,0252,0253,0254,0255,0256,0257,
635 0260,0261,0041,0044,0052,0051,0073,0176,
636 0055,0057,0262,0263,0264,0265,0266,0267,
637 0270,0271,0313,0054,0045,0137,0076,0077,
638 0272,0273,0274,0275,0276,0277,0300,0301,
639 0302,0140,0072,0043,0100,0047,0075,0042,
640 0303,0141,0142,0143,0144,0145,0146,0147,
641 0150,0151,0304,0305,0306,0307,0310,0311,
642 0312,0152,0153,0154,0155,0156,0157,0160,
643 0161,0162,0136,0314,0315,0316,0317,0320,
644 0321,0345,0163,0164,0165,0166,0167,0170,
645 0171,0172,0322,0323,0324,0133,0326,0327,
646 0330,0331,0332,0333,0334,0335,0336,0337,
647 0340,0341,0342,0343,0344,0135,0346,0347,
648 0173,0101,0102,0103,0104,0105,0106,0107,
649 0110,0111,0350,0351,0352,0353,0354,0355,
650 0175,0112,0113,0114,0115,0116,0117,0120,
651 0121,0122,0356,0357,0360,0361,0362,0363,
652 0134,0237,0123,0124,0125,0126,0127,0130,
653 0131,0132,0364,0365,0366,0367,0370,0371,
654 0060,0061,0062,0063,0064,0065,0066,0067,
655 0070,0071,0372,0373,0374,0375,0376,0377
656};
657
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200658 static char
659get_color_char (int e, int ebcdic)
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200660{
661 if (ebcdic)
662 {
663 if ((e >= 75 && e <= 80) || (e >= 90 && e <= 97) ||
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200664 (e >= 107 && e <= 111) || (e >= 121 && e <= 127) ||
665 (e >= 129 && e <= 137) || (e >= 145 && e <= 154) ||
666 (e >= 162 && e <= 169) || (e >= 192 && e <= 201) ||
667 (e >= 208 && e <= 217) || (e >= 226 && e <= 233) ||
668 (e >= 240 && e <= 249) || (e == 189) || (e == 64) ||
669 (e == 173) || (e == 224) )
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200670 return COLOR_GREEN;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200671
672 else if (e == 37 || e == 13 || e == 5)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200673 return COLOR_YELLOW;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200674 else if (e == 0)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200675 return COLOR_WHITE;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200676 else if (e == 255)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200677 return COLOR_BLUE;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200678 else
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200679 return COLOR_RED;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200680 }
681 else /* ASCII */
682 {
Igor Todorovski48a75f32024-01-09 21:05:48 +0000683 #if defined(__MVS__) && __CHARSET_LIB == 0
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200684 if (e >= 64)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200685 return COLOR_GREEN;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200686 #else
687 if (e > 31 && e < 127)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200688 return COLOR_GREEN;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200689 #endif
690
691 else if (e == 9 || e == 10 || e == 13)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200692 return COLOR_YELLOW;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200693 else if (e == 0)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200694 return COLOR_WHITE;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200695 else if (e == 255)
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200696 return COLOR_BLUE;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200697 else
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200698 return COLOR_RED;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200699 }
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200700 return 0;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200701}
702
K.Takataf6fc2552023-09-01 18:41:04 +0200703 static int
704enable_color(void)
705{
706#ifdef WIN32
707 DWORD mode;
708 HANDLE out;
709
710 if (!isatty(1))
711 return 0;
712
713 out = GetStdHandle(STD_OUTPUT_HANDLE);
714 GetConsoleMode(out, &mode);
715 mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
716 return (int)SetConsoleMode(out, mode);
717#elif defined(UNIX)
718 return isatty(STDOUT_FILENO);
719#else
720 return 0;
721#endif
722}
723
Bram Moolenaare0659a62011-04-01 19:14:40 +0200724 int
Bram Moolenaarb638a7b2016-01-30 21:29:58 +0100725main(int argc, char *argv[])
Bram Moolenaar071d4272004-06-13 20:20:40 +0000726{
727 FILE *fp, *fpo;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200728 int c, e, p = 0, relseek = 1, negseek = 0, revert = 0, i, x;
Erik Auerswaldc0a1d372022-01-14 11:58:48 +0000729 int cols = 0, colsgiven = 0, nonzero = 0, autoskip = 0, hextype = HEX_NORMAL;
Bram Moolenaar363d6142020-05-30 20:50:25 +0200730 int capitalize = 0, decimal_offset = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000731 int ebcdic = 0;
732 int octspergrp = -1; /* number of octets grouped in output */
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200733 int grplen; /* total chars per octet group excluding colors */
Bram Moolenaard8c56a02019-01-30 23:02:25 +0100734 long length = -1, n = 0, seekoff = 0;
735 unsigned long displayoff = 0;
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200736 static char l[LLEN_NO_COLOR+1]; /* static because it may be too big for stack */
737 static char colors[LLEN_NO_COLOR+1]; /* color array */
Bram Moolenaare0659a62011-04-01 19:14:40 +0200738 char *pp;
David Gow83e11802022-06-29 20:24:49 +0100739 char *varname = NULL;
Bram Moolenaaraf703582019-01-31 11:00:42 +0100740 int addrlen = 9;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200741 int color = 0;
K.Takataf6fc2552023-09-01 18:41:04 +0200742 char *no_color;
Emanuel Krollmann6897f182025-06-15 16:24:09 +0200743 char cur_color = 0;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200744
K.Takataf6fc2552023-09-01 18:41:04 +0200745 no_color = getenv("NO_COLOR");
746 if (no_color == NULL || no_color[0] == '\0')
747 color = enable_color();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000748
749#ifdef AMIGA
750 /* This program doesn't work when started from the Workbench */
751 if (argc == 0)
752 exit(1);
753#endif
754
755 pname = argv[0];
756 for (pp = pname; *pp; )
757 if (*pp++ == PATH_SEP)
758 pname = pp;
759#ifdef FILE_SEP
760 for (pp = pname; *pp; pp++)
761 if (*pp == FILE_SEP)
762 {
763 *pp = '\0';
764 break;
765 }
766#endif
767
768 while (argc >= 2)
769 {
770 pp = argv[1] + (!STRNCMP(argv[1], "--", 2) && argv[1][2]);
771 if (!STRNCMP(pp, "-a", 2)) autoskip = 1 - autoskip;
Andre Chang15022722024-09-15 20:03:05 +0200772 else if (!STRNCMP(pp, "-b", 2)) hextype |= HEX_BITS;
773 else if (!STRNCMP(pp, "-e", 2)) hextype |= HEX_LITTLEENDIAN;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000774 else if (!STRNCMP(pp, "-u", 2)) hexx = hexxa + 16;
Andre Chang15022722024-09-15 20:03:05 +0200775 else if (!STRNCMP(pp, "-p", 2)) hextype |= HEX_POSTSCRIPT;
776 else if (!STRNCMP(pp, "-i", 2)) hextype |= HEX_CINCLUDE;
Bram Moolenaar8b31a6f2018-04-03 12:17:25 +0200777 else if (!STRNCMP(pp, "-C", 2)) capitalize = 1;
Bram Moolenaar363d6142020-05-30 20:50:25 +0200778 else if (!STRNCMP(pp, "-d", 2)) decimal_offset = 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000779 else if (!STRNCMP(pp, "-r", 2)) revert++;
780 else if (!STRNCMP(pp, "-E", 2)) ebcdic++;
781 else if (!STRNCMP(pp, "-v", 2))
782 {
783 fprintf(stderr, "%s%s\n", version, osver);
784 exit(0);
785 }
786 else if (!STRNCMP(pp, "-c", 2))
787 {
Bram Moolenaar970f5d32019-01-25 21:52:17 +0100788 if (pp[2] && !STRNCMP("apitalize", pp + 2, 9))
Bram Moolenaar79cf7c02018-04-03 14:21:16 +0200789 capitalize = 1;
Bram Moolenaar970f5d32019-01-25 21:52:17 +0100790 else if (pp[2] && STRNCMP("ols", pp + 2, 3))
Erik Auerswaldc0a1d372022-01-14 11:58:48 +0000791 {
792 colsgiven = 1;
793 cols = (int)strtol(pp + 2, NULL, 0);
794 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000795 else
796 {
797 if (!argv[2])
Bram Moolenaare0659a62011-04-01 19:14:40 +0200798 exit_with_usage();
Erik Auerswaldc0a1d372022-01-14 11:58:48 +0000799 colsgiven = 1;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000800 cols = (int)strtol(argv[2], NULL, 0);
801 argv++;
802 argc--;
803 }
804 }
805 else if (!STRNCMP(pp, "-g", 2))
806 {
Bram Moolenaar970f5d32019-01-25 21:52:17 +0100807 if (pp[2] && STRNCMP("roup", pp + 2, 4))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000808 octspergrp = (int)strtol(pp + 2, NULL, 0);
809 else
810 {
811 if (!argv[2])
Bram Moolenaare0659a62011-04-01 19:14:40 +0200812 exit_with_usage();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000813 octspergrp = (int)strtol(argv[2], NULL, 0);
814 argv++;
815 argc--;
816 }
817 }
Bram Moolenaar4dcdf292015-03-05 17:51:15 +0100818 else if (!STRNCMP(pp, "-o", 2))
819 {
Bram Moolenaard8c56a02019-01-30 23:02:25 +0100820 int reloffset = 0;
821 int negoffset = 0;
Bram Moolenaar4dcdf292015-03-05 17:51:15 +0100822 if (pp[2] && STRNCMP("ffset", pp + 2, 5))
Bram Moolenaard8c56a02019-01-30 23:02:25 +0100823 displayoff = strtoul(pp + 2, NULL, 0);
Bram Moolenaar4dcdf292015-03-05 17:51:15 +0100824 else
825 {
826 if (!argv[2])
827 exit_with_usage();
Bram Moolenaard8c56a02019-01-30 23:02:25 +0100828
829 if (argv[2][0] == '+')
830 reloffset++;
831 if (argv[2][reloffset] == '-')
832 negoffset++;
833
834 if (negoffset)
835 displayoff = ULONG_MAX - strtoul(argv[2] + reloffset+negoffset, NULL, 0) + 1;
836 else
837 displayoff = strtoul(argv[2] + reloffset+negoffset, NULL, 0);
838
Bram Moolenaar4dcdf292015-03-05 17:51:15 +0100839 argv++;
840 argc--;
841 }
842 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000843 else if (!STRNCMP(pp, "-s", 2))
844 {
845 relseek = 0;
846 negseek = 0;
847 if (pp[2] && STRNCMP("kip", pp+2, 3) && STRNCMP("eek", pp+2, 3))
848 {
849#ifdef TRY_SEEK
850 if (pp[2] == '+')
851 relseek++;
852 if (pp[2+relseek] == '-')
853 negseek++;
854#endif
855 seekoff = strtol(pp + 2+relseek+negseek, (char **)NULL, 0);
856 }
857 else
858 {
859 if (!argv[2])
Bram Moolenaare0659a62011-04-01 19:14:40 +0200860 exit_with_usage();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000861#ifdef TRY_SEEK
862 if (argv[2][0] == '+')
863 relseek++;
864 if (argv[2][relseek] == '-')
865 negseek++;
866#endif
867 seekoff = strtol(argv[2] + relseek+negseek, (char **)NULL, 0);
868 argv++;
869 argc--;
870 }
871 }
872 else if (!STRNCMP(pp, "-l", 2))
873 {
874 if (pp[2] && STRNCMP("en", pp + 2, 2))
875 length = strtol(pp + 2, (char **)NULL, 0);
876 else
877 {
878 if (!argv[2])
Bram Moolenaare0659a62011-04-01 19:14:40 +0200879 exit_with_usage();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000880 length = strtol(argv[2], (char **)NULL, 0);
881 argv++;
882 argc--;
883 }
884 }
David Gow83e11802022-06-29 20:24:49 +0100885 else if (!STRNCMP(pp, "-n", 2))
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200886 {
887 if (pp[2] && STRNCMP("ame", pp + 2, 3))
888 varname = pp + 2;
889 else
890 {
891 if (!argv[2])
892 exit_with_usage();
893 varname = argv[2];
894 argv++;
895 argc--;
896 }
897 }
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200898 else if (!STRNCMP(pp, "-R", 2))
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200899 {
K.Takataf6fc2552023-09-01 18:41:04 +0200900 char *pw = pp + 2;
901 if (!pw[0])
902 {
903 pw = argv[2];
904 argv++;
905 argc--;
906 }
907 if (!pw)
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200908 exit_with_usage();
K.Takataf6fc2552023-09-01 18:41:04 +0200909 if (!STRNCMP(pw, "always", 6))
910 {
911 (void)enable_color();
912 color = 1;
913 }
914 else if (!STRNCMP(pw, "never", 5))
Aapo Rantalainene2528ae2023-08-31 17:58:13 +0200915 color = 0;
K.Takataf6fc2552023-09-01 18:41:04 +0200916 else if (!STRNCMP(pw, "auto", 4))
K.Takata233f9562023-09-04 07:46:59 +0200917 color = enable_color();
K.Takataf6fc2552023-09-01 18:41:04 +0200918 else
919 exit_with_usage();
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200920 }
DungSaga4b9fa952024-11-11 22:19:50 +0100921 else if (!strcmp(argv[1], "--")) /* end of options */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000922 {
923 argv++;
924 argc--;
925 break;
926 }
927 else if (pp[0] == '-' && pp[1]) /* unknown option */
Bram Moolenaare0659a62011-04-01 19:14:40 +0200928 exit_with_usage();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000929 else
930 break; /* not an option */
931
932 argv++; /* advance to next argument */
933 argc--;
934 }
935
Andre Chang15022722024-09-15 20:03:05 +0200936 if (hextype != (HEX_CINCLUDE | HEX_BITS))
937 {
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +0200938 /* Allow at most one bit to be set in hextype */
939 if (hextype & (hextype - 1))
940 error_exit(1, "only one of -b, -e, -u, -p, -i can be used");
Andre Chang15022722024-09-15 20:03:05 +0200941 }
942
Erik Auerswaldc0a1d372022-01-14 11:58:48 +0000943 if (!colsgiven || (!cols && hextype != HEX_POSTSCRIPT))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000944 switch (hextype)
945 {
946 case HEX_POSTSCRIPT: cols = 30; break;
947 case HEX_CINCLUDE: cols = 12; break;
Andre Chang15022722024-09-15 20:03:05 +0200948 case HEX_CINCLUDE | HEX_BITS:
Bram Moolenaar071d4272004-06-13 20:20:40 +0000949 case HEX_BITS: cols = 6; break;
950 case HEX_NORMAL:
Bram Moolenaar4dcdf292015-03-05 17:51:15 +0100951 case HEX_LITTLEENDIAN:
Bram Moolenaar071d4272004-06-13 20:20:40 +0000952 default: cols = 16; break;
953 }
954
955 if (octspergrp < 0)
956 switch (hextype)
957 {
Andre Chang15022722024-09-15 20:03:05 +0200958 case HEX_CINCLUDE | HEX_BITS:
Bram Moolenaar071d4272004-06-13 20:20:40 +0000959 case HEX_BITS: octspergrp = 1; break;
960 case HEX_NORMAL: octspergrp = 2; break;
Bram Moolenaar4dcdf292015-03-05 17:51:15 +0100961 case HEX_LITTLEENDIAN: octspergrp = 4; break;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000962 case HEX_POSTSCRIPT:
963 case HEX_CINCLUDE:
964 default: octspergrp = 0; break;
965 }
966
Erik Auerswaldc0a1d372022-01-14 11:58:48 +0000967 if ((hextype == HEX_POSTSCRIPT && cols < 0) ||
968 (hextype != HEX_POSTSCRIPT && cols < 1) ||
969 ((hextype == HEX_NORMAL || hextype == HEX_BITS || hextype == HEX_LITTLEENDIAN)
Bram Moolenaare9c3bcd2007-12-03 20:32:43 +0000970 && (cols > COLS)))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000971 {
972 fprintf(stderr, "%s: invalid number of columns (max. %d).\n", pname, COLS);
973 exit(1);
974 }
975
Bram Moolenaar4dcdf292015-03-05 17:51:15 +0100976 if (octspergrp < 1 || octspergrp > cols)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000977 octspergrp = cols;
Bram Moolenaar4dcdf292015-03-05 17:51:15 +0100978 else if (hextype == HEX_LITTLEENDIAN && (octspergrp & (octspergrp-1)))
DungSagaa2ffb432021-10-22 15:55:31 +0100979 error_exit(1, "number of octets per group must be a power of 2 with -e.");
Bram Moolenaar071d4272004-06-13 20:20:40 +0000980
981 if (argc > 3)
Bram Moolenaare0659a62011-04-01 19:14:40 +0200982 exit_with_usage();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000983
984 if (argc == 1 || (argv[1][0] == '-' && !argv[1][1]))
985 BIN_ASSIGN(fp = stdin, !revert);
986 else
987 {
988 if ((fp = fopen(argv[1], BIN_READ(!revert))) == NULL)
989 {
990 fprintf(stderr,"%s: ", pname);
991 perror(argv[1]);
992 return 2;
993 }
994 }
995
996 if (argc < 3 || (argv[2][0] == '-' && !argv[2][1]))
997 BIN_ASSIGN(fpo = stdout, revert);
998 else
999 {
1000 int fd;
1001 int mode = revert ? O_WRONLY : (O_TRUNC|O_WRONLY);
1002
1003 if (((fd = OPEN(argv[2], mode | BIN_CREAT(revert), 0666)) < 0) ||
1004 (fpo = fdopen(fd, BIN_WRITE(revert))) == NULL)
1005 {
1006 fprintf(stderr, "%s: ", pname);
1007 perror(argv[2]);
1008 return 3;
1009 }
1010 rewind(fpo);
1011 }
Igor Todorovski48a75f32024-01-09 21:05:48 +00001012#ifdef __MVS__
1013 // Disable auto-conversion on input file descriptors
1014 __disableautocvt(fileno(fp));
1015#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00001016
1017 if (revert)
tristhaus85f45212023-10-06 19:51:13 +02001018 switch (hextype)
1019 {
1020 case HEX_NORMAL:
1021 case HEX_POSTSCRIPT:
1022 case HEX_BITS:
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001023 return huntype(fp, fpo, cols, hextype,
1024 negseek ? -seekoff : seekoff);
1025 break;
tristhaus85f45212023-10-06 19:51:13 +02001026 default:
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001027 error_exit(-1, "Sorry, cannot revert this type of hexdump");
tristhaus85f45212023-10-06 19:51:13 +02001028 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001029
1030 if (seekoff || negseek || !relseek)
1031 {
1032#ifdef TRY_SEEK
1033 if (relseek)
Bram Moolenaar786e05b2021-11-14 13:46:05 +00001034 e = fseek(fp, negseek ? -seekoff : seekoff, SEEK_CUR);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001035 else
Bram Moolenaar786e05b2021-11-14 13:46:05 +00001036 e = fseek(fp, negseek ? -seekoff : seekoff,
1037 negseek ? SEEK_END : SEEK_SET);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001038 if (e < 0 && negseek)
DungSaga7e5503c2021-12-01 11:24:52 +00001039 error_exit(4, "Sorry, cannot seek.");
Bram Moolenaar071d4272004-06-13 20:20:40 +00001040 if (e >= 0)
1041 seekoff = ftell(fp);
1042 else
1043#endif
1044 {
1045 long s = seekoff;
1046
1047 while (s--)
DungSaga7e5503c2021-12-01 11:24:52 +00001048 if (getc_or_die(fp) == EOF)
Bram Moolenaar10d77eb2011-04-02 14:44:55 +02001049 {
DungSaga7e5503c2021-12-01 11:24:52 +00001050 error_exit(4, "Sorry, cannot seek.");
Bram Moolenaar10d77eb2011-04-02 14:44:55 +02001051 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001052 }
1053 }
1054
Andre Chang15022722024-09-15 20:03:05 +02001055 if (hextype & HEX_CINCLUDE)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001056 {
David Gow83e11802022-06-29 20:24:49 +01001057 /* A user-set variable name overrides fp == stdin */
1058 if (varname == NULL && fp != stdin)
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001059 varname = argv[1];
David Gow83e11802022-06-29 20:24:49 +01001060
1061 if (varname != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001062 {
Keith Thompson184f71c2024-01-04 21:19:04 +01001063 FPRINTF_OR_DIE((fpo, "unsigned char %s", isdigit((unsigned char)varname[0]) ? "__" : ""));
David Gow83e11802022-06-29 20:24:49 +01001064 for (e = 0; (c = varname[e]) != 0; e++)
Keith Thompson184f71c2024-01-04 21:19:04 +01001065 putc_or_die(isalnum((unsigned char)c) ? CONDITIONAL_CAPITALIZE(c) : '_', fpo);
Bram Moolenaar8af87bd2021-11-25 11:16:50 +00001066 fputs_or_die("[] = {\n", fpo);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001067 }
1068
1069 p = 0;
DungSagad1d8a592021-11-26 13:59:27 +00001070 while ((length < 0 || p < length) && (c = getc_or_die(fp)) != EOF)
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001071 {
1072 if (hextype & HEX_BITS)
Andre Chang15022722024-09-15 20:03:05 +02001073 {
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001074 if (p == 0)
1075 fputs_or_die(" ", fpo);
1076 else if (p % cols == 0)
1077 fputs_or_die(",\n ", fpo);
1078 else
1079 fputs_or_die(", ", fpo);
Andre Chang15022722024-09-15 20:03:05 +02001080
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001081 FPRINTF_OR_DIE((fpo, "0b"));
1082 for (int j = 7; j >= 0; j--)
1083 putc_or_die((c & (1 << j)) ? '1' : '0', fpo);
1084 p++;
Andre Chang15022722024-09-15 20:03:05 +02001085 }
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001086 else
Andre Chang15022722024-09-15 20:03:05 +02001087 {
1088 FPRINTF_OR_DIE((fpo, (hexx == hexxa) ? "%s0x%02x" : "%s0X%02X",
DungSaga7e5503c2021-12-01 11:24:52 +00001089 (p % cols) ? ", " : (!p ? " " : ",\n "), c));
Andre Chang15022722024-09-15 20:03:05 +02001090 p++;
1091 }
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001092 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001093
Bram Moolenaar8af87bd2021-11-25 11:16:50 +00001094 if (p)
1095 fputs_or_die("\n", fpo);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001096
David Gow83e11802022-06-29 20:24:49 +01001097 if (varname != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001098 {
DungSagad1d8a592021-11-26 13:59:27 +00001099 fputs_or_die("};\n", fpo);
Christian Brabandtfa8c9712024-01-25 20:50:49 +01001100 FPRINTF_OR_DIE((fpo, "unsigned int %s", isdigit((unsigned char)varname[0]) ? "__" : ""));
David Gow83e11802022-06-29 20:24:49 +01001101 for (e = 0; (c = varname[e]) != 0; e++)
Keith Thompson184f71c2024-01-04 21:19:04 +01001102 putc_or_die(isalnum((unsigned char)c) ? CONDITIONAL_CAPITALIZE(c) : '_', fpo);
DungSaga7e5503c2021-12-01 11:24:52 +00001103 FPRINTF_OR_DIE((fpo, "_%s = %d;\n", capitalize ? "LEN" : "len", p));
Bram Moolenaar071d4272004-06-13 20:20:40 +00001104 }
1105
Bram Moolenaar8af87bd2021-11-25 11:16:50 +00001106 fclose_or_die(fp, fpo);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001107 return 0;
1108 }
1109
1110 if (hextype == HEX_POSTSCRIPT)
1111 {
1112 p = cols;
DungSagad1d8a592021-11-26 13:59:27 +00001113 while ((length < 0 || n < length) && (e = getc_or_die(fp)) != EOF)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001114 {
Bram Moolenaar8af87bd2021-11-25 11:16:50 +00001115 putc_or_die(hexx[(e >> 4) & 0xf], fpo);
1116 putc_or_die(hexx[e & 0xf], fpo);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001117 n++;
Erik Auerswaldc0a1d372022-01-14 11:58:48 +00001118 if (cols > 0 && !--p)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001119 {
Bram Moolenaar8af87bd2021-11-25 11:16:50 +00001120 putc_or_die('\n', fpo);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001121 p = cols;
1122 }
1123 }
Erik Auerswaldc0a1d372022-01-14 11:58:48 +00001124 if (cols == 0 || p < cols)
Bram Moolenaar8af87bd2021-11-25 11:16:50 +00001125 putc_or_die('\n', fpo);
1126 fclose_or_die(fp, fpo);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001127 return 0;
1128 }
1129
Bram Moolenaar4dcdf292015-03-05 17:51:15 +01001130 /* hextype: HEX_NORMAL or HEX_BITS or HEX_LITTLEENDIAN */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001131
Bram Moolenaar4dcdf292015-03-05 17:51:15 +01001132 if (hextype != HEX_BITS)
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001133 {
1134 grplen = octspergrp + octspergrp + 1; /* chars per octet group */
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001135 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001136 else /* hextype == HEX_BITS */
1137 grplen = 8 * octspergrp + 1;
1138
DungSagad1d8a592021-11-26 13:59:27 +00001139 while ((length < 0 || n < length) && (e = getc_or_die(fp)) != EOF)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001140 {
1141 if (p == 0)
1142 {
DungSaga581f41a2021-11-22 11:57:31 +00001143 addrlen = sprintf(l, decimal_offset ? "%08ld:" : "%08lx:",
Bram Moolenaar363d6142020-05-30 20:50:25 +02001144 ((unsigned long)(n + seekoff + displayoff)));
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001145 for (c = addrlen; c < LLEN_NO_COLOR; l[c++] = ' ')
Bram Moolenaar4390d872023-03-05 20:17:39 +00001146 ;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001147 }
DungSaga48608b42021-11-24 11:18:07 +00001148 x = hextype == HEX_LITTLEENDIAN ? p ^ (octspergrp-1) : p;
1149 c = addrlen + 1 + (grplen * x) / octspergrp;
DungSaga581f41a2021-11-22 11:57:31 +00001150 if (hextype == HEX_NORMAL || hextype == HEX_LITTLEENDIAN)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001151 {
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001152 if (color)
1153 {
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001154 cur_color = get_color_char(e, ebcdic);
1155 colors[c] = cur_color;
1156 colors[c+1] = cur_color;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001157 }
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001158
1159 l[c] = hexx[(e >> 4) & 0xf];
1160 l[++c] = hexx[e & 0xf];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001161 }
1162 else /* hextype == HEX_BITS */
1163 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00001164 for (i = 7; i >= 0; i--)
DungSaga48608b42021-11-24 11:18:07 +00001165 l[c++] = (e & (1 << i)) ? '1' : '0';
Bram Moolenaar071d4272004-06-13 20:20:40 +00001166 }
Bram Moolenaar085346f2018-02-24 18:30:55 +01001167 if (e)
1168 nonzero++;
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001169 /* When changing this update definition of LLEN and LLEN_NO_COLOR above. */
Bram Moolenaar4390d872023-03-05 20:17:39 +00001170 if (hextype == HEX_LITTLEENDIAN)
1171 /* last group will be fully used, round up */
1172 c = grplen * ((cols + octspergrp - 1) / octspergrp);
1173 else
1174 c = (grplen * cols - 1) / octspergrp;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001175
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001176
1177 if (ebcdic)
1178 e = (e < 64) ? '.' : etoa64[e-64];
1179
1180 if (hextype == HEX_LITTLEENDIAN)
1181 c -= 1;
1182
1183 c += addrlen + 3 + p;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001184 if (color)
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001185 {
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001186 colors[c] = cur_color;
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001187 }
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001188 l[c++] =
1189#if defined(__MVS__) && __CHARSET_LIB == 0
1190 (e >= 64)
1191#else
1192 (e > 31 && e < 127)
1193#endif
1194 ? e : '.';
1195 n++;
1196 if (++p == cols)
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001197 {
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001198 l[c++] = '\n';
1199 l[c] = '\0';
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001200
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001201 xxdline(fpo, l, color ? colors : NULL, autoskip ? nonzero : 1);
1202 memset(colors, 0, c);
1203 nonzero = 0;
1204 p = 0;
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001205 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00001206 }
1207 if (p)
1208 {
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001209 l[c++] = '\n';
1210 l[c] = '\0';
1211 if (color)
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001212 {
1213 x = p;
1214 if (hextype == HEX_LITTLEENDIAN)
1215 {
1216 int fill = octspergrp - (p % octspergrp);
1217 if (fill == octspergrp) fill = 0;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001218
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001219 c = addrlen + 1 + (grplen * (x - (octspergrp-fill))) / octspergrp;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001220
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001221 for (i = 0; i < fill;i++)
1222 {
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001223 colors[c] = COLOR_RED;
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001224 l[c++] = ' '; /* empty space */
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001225 x++;
1226 p++;
1227 }
1228 }
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001229
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001230 if (hextype != HEX_BITS)
1231 {
1232 c = addrlen + 1 + (grplen * x) / octspergrp;
1233 c += cols - p;
1234 c += (cols - p) / octspergrp;
Aapo Rantalainene2528ae2023-08-31 17:58:13 +02001235
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001236 for (i = cols - p; i > 0;i--)
1237 {
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001238 colors[c] = COLOR_RED;
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001239 l[c++] = ' '; /* empty space */
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001240 }
1241 }
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001242 xxdline(fpo, l, colors, 1);
Naruhiko Nishinoc2a90002025-05-04 20:05:47 +02001243 }
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001244 else
1245 xxdline(fpo, l, NULL, 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001246 }
1247 else if (autoskip)
Emanuel Krollmann6897f182025-06-15 16:24:09 +02001248 xxdline(fpo, l, color ? colors : NULL, -1); /* last chance to flush out suppressed lines */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001249
Bram Moolenaar8af87bd2021-11-25 11:16:50 +00001250 fclose_or_die(fp, fpo);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001251 return 0;
1252}
Bram Moolenaare0659a62011-04-01 19:14:40 +02001253
1254/* vi:set ts=8 sw=4 sts=2 cino+={2 cino+=n-2 : */