5252 * 2011 March Better error handling by Florian Zumbiehl.
5353 * 2011 April Formatting by Bram Moolenaar
5454 * 08.06.2013 Little-endian hexdump (-e) and offset (-o) by Vadim Vygonets.
55+ * 11.01.2019 Add full 64/32 bit range to -o and output by Christer Jensen.
5556 *
5657 * (c) 1990-1998 by Juergen Weigert ([email protected] ) 5758 *
9091#include <stdlib.h>
9192#include <string.h> /* for strncmp() */
9293#include <ctype.h> /* for isalnum() */
94+ #include <limits.h>
9395#if __MWERKS__ && !defined(BEBOX )
9496# include <unix.h> /* for fdopen() on MAC */
9597#endif
@@ -204,7 +206,7 @@ static void xxdline __P((FILE *, char *, int));
204206
205207#define TRY_SEEK /* attempt to use lseek, or skip forward by reading */
206208#define COLS 256 /* change here, if you ever need more columns */
207- #define LLEN (12 + (9*COLS-1) + COLS + 2)
209+ #define LLEN ((2*(int)sizeof(unsigned long)) + 4 + (9*COLS-1) + COLS + 2)
208210
209211char hexxa [] = "0123456789abcdef0123456789ABCDEF" , * hexx = hexxa ;
210212
@@ -466,7 +468,8 @@ main(int argc, char *argv[])
466468 int ebcdic = 0 ;
467469 int octspergrp = -1 ; /* number of octets grouped in output */
468470 int grplen ; /* total chars per octet group */
469- long length = -1 , n = 0 , seekoff = 0 , displayoff = 0 ;
471+ long length = -1 , n = 0 , seekoff = 0 ;
472+ unsigned long displayoff = 0 ;
470473 static char l [LLEN + 1 ]; /* static because it may be too big for stack */
471474 char * pp ;
472475
@@ -536,13 +539,25 @@ main(int argc, char *argv[])
536539 }
537540 else if (!STRNCMP (pp , "-o" , 2 ))
538541 {
542+ int reloffset = 0 ;
543+ int negoffset = 0 ;
539544 if (pp [2 ] && STRNCMP ("ffset" , pp + 2 , 5 ))
540- displayoff = ( int ) strtol (pp + 2 , NULL , 0 );
545+ displayoff = strtoul (pp + 2 , NULL , 0 );
541546 else
542547 {
543548 if (!argv [2 ])
544549 exit_with_usage ();
545- displayoff = (int )strtol (argv [2 ], NULL , 0 );
550+
551+ if (argv [2 ][0 ] == '+' )
552+ reloffset ++ ;
553+ if (argv [2 ][reloffset ] == '-' )
554+ negoffset ++ ;
555+
556+ if (negoffset )
557+ displayoff = ULONG_MAX - strtoul (argv [2 ] + reloffset + negoffset , NULL , 0 ) + 1 ;
558+ else
559+ displayoff = strtoul (argv [2 ] + reloffset + negoffset , NULL , 0 );
560+
546561 argv ++ ;
547562 argc -- ;
548563 }
@@ -805,31 +820,32 @@ main(int argc, char *argv[])
805820 else /* hextype == HEX_BITS */
806821 grplen = 8 * octspergrp + 1 ;
807822
823+ int addrlen = 9 ;
808824 e = 0 ;
809825 while ((length < 0 || n < length ) && (e = getc (fp )) != EOF )
810826 {
811827 if (p == 0 )
812828 {
813- sprintf (l , "%08lx:" ,
814- ((unsigned long )(n + seekoff + displayoff )) & 0xffffffff );
815- for (c = 9 ; c < LLEN ; l [c ++ ] = ' ' );
829+ addrlen = sprintf (l , "%08lx:" ,
830+ ((unsigned long )(n + seekoff + displayoff )));
831+ for (c = addrlen ; c < LLEN ; l [c ++ ] = ' ' );
816832 }
817833 if (hextype == HEX_NORMAL )
818834 {
819- l [c = (10 + (grplen * p ) / octspergrp )] = hexx [(e >> 4 ) & 0xf ];
835+ l [c = (addrlen + 1 + (grplen * p ) / octspergrp )] = hexx [(e >> 4 ) & 0xf ];
820836 l [++ c ] = hexx [ e & 0xf ];
821837 }
822838 else if (hextype == HEX_LITTLEENDIAN )
823839 {
824840 int x = p ^ (octspergrp - 1 );
825- l [c = (10 + (grplen * x ) / octspergrp )] = hexx [(e >> 4 ) & 0xf ];
841+ l [c = (addrlen + 1 + (grplen * x ) / octspergrp )] = hexx [(e >> 4 ) & 0xf ];
826842 l [++ c ] = hexx [ e & 0xf ];
827843 }
828844 else /* hextype == HEX_BITS */
829845 {
830846 int i ;
831847
832- c = (10 + (grplen * p ) / octspergrp ) - 1 ;
848+ c = (addrlen + 1 + (grplen * p ) / octspergrp ) - 1 ;
833849 for (i = 7 ; i >= 0 ; i -- )
834850 l [++ c ] = (e & (1 << i )) ? '1' : '0' ;
835851 }
@@ -838,7 +854,7 @@ main(int argc, char *argv[])
838854 if (ebcdic )
839855 e = (e < 64 ) ? '.' : etoa64 [e - 64 ];
840856 /* When changing this update definition of LLEN above. */
841- l [12 + (grplen * cols - 1 )/octspergrp + p ] =
857+ l [addrlen + 3 + (grplen * cols - 1 )/octspergrp + p ] =
842858#ifdef __MVS__
843859 (e >= 64 )
844860#else
@@ -848,7 +864,7 @@ main(int argc, char *argv[])
848864 n ++ ;
849865 if (++ p == cols )
850866 {
851- l [c = (12 + (grplen * cols - 1 )/octspergrp + p )] = '\n' ; l [++ c ] = '\0' ;
867+ l [c = (addrlen + 3 + (grplen * cols - 1 )/octspergrp + p )] = '\n' ; l [++ c ] = '\0' ;
852868 xxdline (fpo , l , autoskip ? nonzero : 1 );
853869 nonzero = 0 ;
854870 p = 0 ;
@@ -858,7 +874,7 @@ main(int argc, char *argv[])
858874 die (2 );
859875 if (p )
860876 {
861- l [c = (12 + (grplen * cols - 1 )/octspergrp + p )] = '\n' ; l [++ c ] = '\0' ;
877+ l [c = (addrlen + 3 + (grplen * cols - 1 )/octspergrp + p )] = '\n' ; l [++ c ] = '\0' ;
862878 xxdline (fpo , l , 1 );
863879 }
864880 else if (autoskip )
0 commit comments