changeset 15693:e00983850550 v8.1.0854

patch 8.1.0854: xxd does not work with more than 32 bit addresses commit https://github.com/vim/vim/commit/d8c56a0d29ccb53e12c6dec73b9a0e8a6dad99c2 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jan 30 23:02:25 2019 +0100 patch 8.1.0854: xxd does not work with more than 32 bit addresses Problem: xxd does not work with more than 32 bit addresses. Solution: Add support for 64 bit addresses. (Christer Jensen, closes https://github.com/vim/vim/issues/3791)
author Bram Moolenaar <Bram@vim.org>
date Wed, 30 Jan 2019 23:15:05 +0100
parents 62b5f69be0d4
children 1a8f97622760
files src/version.c src/xxd/xxd.c
diffstat 2 files changed, 31 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/version.c
+++ b/src/version.c
@@ -784,6 +784,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    854,
+/**/
     853,
 /**/
     852,
--- a/src/xxd/xxd.c
+++ b/src/xxd/xxd.c
@@ -52,6 +52,7 @@
  * 2011 March  Better error handling by Florian Zumbiehl.
  * 2011 April  Formatting by Bram Moolenaar
  * 08.06.2013  Little-endian hexdump (-e) and offset (-o) by Vadim Vygonets.
+ * 11.01.2019  Add full 64/32 bit range to -o and output by Christer Jensen.
  *
  * (c) 1990-1998 by Juergen Weigert (jnweiger@informatik.uni-erlangen.de)
  *
@@ -90,6 +91,7 @@
 #include <stdlib.h>
 #include <string.h>	/* for strncmp() */
 #include <ctype.h>	/* for isalnum() */
+#include <limits.h>
 #if __MWERKS__ && !defined(BEBOX)
 # include <unix.h>	/* for fdopen() on MAC */
 #endif
@@ -204,7 +206,7 @@ static void xxdline __P((FILE *, char *,
 
 #define TRY_SEEK	/* attempt to use lseek, or skip forward by reading */
 #define COLS 256	/* change here, if you ever need more columns */
-#define LLEN (12 + (9*COLS-1) + COLS + 2)
+#define LLEN ((2*(int)sizeof(unsigned long)) + 4 + (9*COLS-1) + COLS + 2)
 
 char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa;
 
@@ -466,7 +468,8 @@ main(int argc, char *argv[])
   int ebcdic = 0;
   int octspergrp = -1;	/* number of octets grouped in output */
   int grplen;		/* total chars per octet group */
-  long length = -1, n = 0, seekoff = 0, displayoff = 0;
+  long length = -1, n = 0, seekoff = 0;
+  unsigned long displayoff = 0;
   static char l[LLEN+1];  /* static because it may be too big for stack */
   char *pp;
 
@@ -536,13 +539,25 @@ main(int argc, char *argv[])
 	}
       else if (!STRNCMP(pp, "-o", 2))
 	{
+	  int reloffset = 0;
+	  int negoffset = 0;
 	  if (pp[2] && STRNCMP("ffset", pp + 2, 5))
-	    displayoff = (int)strtol(pp + 2, NULL, 0);
+	    displayoff = strtoul(pp + 2, NULL, 0);
 	  else
 	    {
 	      if (!argv[2])
 		exit_with_usage();
-	      displayoff = (int)strtol(argv[2], NULL, 0);
+
+	      if (argv[2][0] == '+')
+	       reloffset++;
+	     if (argv[2][reloffset] == '-')
+	       negoffset++;
+
+	     if (negoffset)
+	       displayoff = ULONG_MAX - strtoul(argv[2] + reloffset+negoffset, NULL, 0) + 1;
+	     else
+	       displayoff = strtoul(argv[2] + reloffset+negoffset, NULL, 0);
+
 	      argv++;
 	      argc--;
 	    }
@@ -805,31 +820,32 @@ main(int argc, char *argv[])
   else	/* hextype == HEX_BITS */
     grplen = 8 * octspergrp + 1;
 
+  int addrlen = 9;
   e = 0;
   while ((length < 0 || n < length) && (e = getc(fp)) != EOF)
     {
       if (p == 0)
 	{
-	  sprintf(l, "%08lx:",
-	    ((unsigned long)(n + seekoff + displayoff)) & 0xffffffff);
-	  for (c = 9; c < LLEN; l[c++] = ' ');
+	  addrlen = sprintf(l, "%08lx:",
+	    ((unsigned long)(n + seekoff + displayoff)));
+	  for (c = addrlen; c < LLEN; l[c++] = ' ');
 	}
       if (hextype == HEX_NORMAL)
 	{
-	  l[c = (10 + (grplen * p) / octspergrp)] = hexx[(e >> 4) & 0xf];
+	  l[c = (addrlen + 1 + (grplen * p) / octspergrp)] = hexx[(e >> 4) & 0xf];
 	  l[++c]				  = hexx[ e       & 0xf];
 	}
       else if (hextype == HEX_LITTLEENDIAN)
 	{
 	  int x = p ^ (octspergrp-1);
-	  l[c = (10 + (grplen * x) / octspergrp)] = hexx[(e >> 4) & 0xf];
+	  l[c = (addrlen + 1 + (grplen * x) / octspergrp)] = hexx[(e >> 4) & 0xf];
 	  l[++c]				  = hexx[ e       & 0xf];
 	}
       else /* hextype == HEX_BITS */
 	{
 	  int i;
 
-	  c = (10 + (grplen * p) / octspergrp) - 1;
+	  c = (addrlen + 1 + (grplen * p) / octspergrp) - 1;
 	  for (i = 7; i >= 0; i--)
 	    l[++c] = (e & (1 << i)) ? '1' : '0';
 	}
@@ -838,7 +854,7 @@ main(int argc, char *argv[])
       if (ebcdic)
 	e = (e < 64) ? '.' : etoa64[e-64];
       /* When changing this update definition of LLEN above. */
-      l[12 + (grplen * cols - 1)/octspergrp + p] =
+      l[addrlen + 3 + (grplen * cols - 1)/octspergrp + p] =
 #ifdef __MVS__
 	  (e >= 64)
 #else
@@ -848,7 +864,7 @@ main(int argc, char *argv[])
       n++;
       if (++p == cols)
 	{
-	  l[c = (12 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
+	  l[c = (addrlen + 3 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
 	  xxdline(fpo, l, autoskip ? nonzero : 1);
 	  nonzero = 0;
 	  p = 0;
@@ -858,7 +874,7 @@ main(int argc, char *argv[])
     die(2);
   if (p)
     {
-      l[c = (12 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
+      l[c = (addrlen + 3 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
       xxdline(fpo, l, 1);
     }
   else if (autoskip)