Subject: [PATCH] maint: accommodate LP64 systems

From: Peter Rosin <[email-masked]>
Date: Fri, 26 Aug 2016 10:41:24 +0200

It is wrong to assume that pointers fit in long int.

* src/context.c (print_context_number_range): Use intptr_t and the
%PRIdPTR format when printing the lin type.
(print_unidiff_number_rande): Likewise.
* src/diff.h (translate_range): Likewise.
* src/diff3.c (output_diff3): Likewise.
(undotlines): Likewise.
(output_diff3_edscript): Likewise.
* src/ed.c (print_rcs_hunk): Likewise.
* src/side.c (print_sdiff_common_lines): Likewise.
(print_sdiff_hunk): Likewise.
* src/system.h: Likewise.
* src/ifdef.c (do_printf_spec): Likewise, but also make use of the
formats PRIoPTR, PRIxPTR and PRIXPTR.
---
 src/context.c | 12 ++++++------
 src/diff.h    |  2 +-
 src/diff3.c   | 37 +++++++++++++++++++------------------
 src/ed.c      |  8 +++++---
 src/ifdef.c   | 30 +++++++++++++++++++++++-------
 src/sdiff.c   | 16 ++++++++--------
 src/side.c    | 12 ++++++------
 src/system.h  |  2 +-
 src/util.c    | 23 ++++++++++++-----------
 9 files changed, 81 insertions(+), 61 deletions(-)

diff --git a/src/context.c b/src/context.c
index 1a92a60..4fcf0b8 100644
--- a/src/context.c
+++ b/src/context.c
@@ -126,7 +126,7 @@ print_context_script (struct change *script, bool unidiff)
 static void
 print_context_number_range (struct file_data const *file, lin a, lin b)
 {
-  long int trans_a, trans_b;
+  intptr_t trans_a, trans_b;
   translate_range (file, a, b, &trans_a, &trans_b);
 
   /* We can have B <= A in the case of a range of no lines.
@@ -139,9 +139,9 @@ print_context_number_range (struct file_data const *file, lin a, lin b)
      specification.  */
 
   if (trans_b <= trans_a)
-    fprintf (outfile, "%ld", trans_b);
+    fprintf (outfile, "%"PRIdPTR, trans_b);
   else
-    fprintf (outfile, "%ld,%ld", trans_a, trans_b);
+    fprintf (outfile, "%"PRIdPTR",%"PRIdPTR, trans_a, trans_b);
 }
 
 /* Print FUNCTION in a context header.  */
@@ -299,7 +299,7 @@ pr_context_hunk (struct change *hunk)
 static void
 print_unidiff_number_range (struct file_data const *file, lin a, lin b)
 {
-  long int trans_a, trans_b;
+  intptr_t trans_a, trans_b;
   translate_range (file, a, b, &trans_a, &trans_b);
 
   /* We can have B < A in the case of a range of no lines.
@@ -307,9 +307,9 @@ print_unidiff_number_range (struct file_data const *file, lin a, lin b)
      which is B.  It would be more logical to print A, but
      'patch' expects B in order to detect diffs against empty files.  */
   if (trans_b <= trans_a)
-    fprintf (outfile, trans_b < trans_a ? "%ld,0" : "%ld", trans_b);
+    fprintf (outfile, trans_b < trans_a ? "%"PRIdPTR",0" : "%"PRIdPTR, trans_b);
   else
-    fprintf (outfile, "%ld,%ld", trans_a, trans_b - trans_a + 1);
+    fprintf (outfile, "%"PRIdPTR",%"PRIdPTR, trans_a, trans_b - trans_a + 1);
 }
 
 /* Print a portion of an edit script in unidiff format.
diff --git a/src/diff.h b/src/diff.h
index 0983e7c..c4b236d 100644
--- a/src/diff.h
+++ b/src/diff.h
@@ -406,7 +406,7 @@ extern void print_script (struct change *, struct change * (*) (struct change *)
                           void (*) (struct change *));
 extern void setup_output (char const *, char const *, bool);
 extern void translate_range (struct file_data const *, lin, lin,
-                             long int *, long int *);
+                             intptr_t *, intptr_t *);
 
 enum color_context
 {
diff --git a/src/diff3.c b/src/diff3.c
index b80aeb3..eb4f729 100644
--- a/src/diff3.c
+++ b/src/diff3.c
@@ -1428,20 +1428,20 @@ output_diff3 (FILE *outputfile, struct diff3_block *diff,
 	  int realfile = mapping[i];
 	  lin lowt = D_LOWLINE (ptr, realfile);
 	  lin hight = D_HIGHLINE (ptr, realfile);
-	  long int llowt = lowt;
-	  long int lhight = hight;
+	  intptr_t llowt = lowt;
+	  intptr_t lhight = hight;
 
 	  fprintf (outputfile, "%d:", i + 1);
 	  switch (lowt - hight)
 	    {
 	    case 1:
-	      fprintf (outputfile, "%lda\n", llowt - 1);
+	      fprintf (outputfile, "%"PRIdPTR"a\n", llowt - 1);
 	      break;
 	    case 0:
-	      fprintf (outputfile, "%ldc\n", llowt);
+	      fprintf (outputfile, "%"PRIdPTR"c\n", llowt);
 	      break;
 	    default:
-	      fprintf (outputfile, "%ld,%ldc\n", llowt, lhight);
+	      fprintf (outputfile, "%"PRIdPTR",%"PRIdPTR"c\n", llowt, lhight);
 	      break;
 	    }
 
@@ -1495,19 +1495,20 @@ dotlines (FILE *outputfile, struct diff3_block *b, int filenum)
 
 /* Output to OUTPUTFILE a '.' line.  If LEADING_DOT is true, also
    output a command that removes initial '.'s starting with line START
-   and continuing for NUM lines.  (START is long int, not lin, for
-   convenience with printf %ld formats.)  */
+   and continuing for NUM lines.  (START is intptr_t, not lin, for
+   convenience with printf formats.)  */
 
 static void
-undotlines (FILE *outputfile, bool leading_dot, long int start, lin num)
+undotlines (FILE *outputfile, bool leading_dot, intptr_t start, lin num)
 {
   fputs (".\n", outputfile);
   if (leading_dot)
     {
       if (num == 1)
-	fprintf (outputfile, "%lds/^\\.//\n", start);
+        fprintf (outputfile, "%"PRIdPTR"s/^\\.//\n", start);
       else
-	fprintf (outputfile, "%ld,%lds/^\\.//\n", start, start + num - 1);
+        fprintf (outputfile, "%"PRIdPTR",%"PRIdPTR"s/^\\.//\n",
+                 start, start + num - 1);
     }
 }
 
@@ -1548,7 +1549,7 @@ output_diff3_edscript (FILE *outputfile, struct diff3_block *diff,
 	   ? DIFF_ALL
 	   : DIFF_1ST + rev_mapping[b->correspond - DIFF_1ST]);
 
-      long int low0, high0;
+      intptr_t low0, high0;
 
       /* If we aren't supposed to do this output block, skip it.  */
       switch (type)
@@ -1569,7 +1570,7 @@ output_diff3_edscript (FILE *outputfile, struct diff3_block *diff,
 
 	  /* Mark end of conflict.  */
 
-	  fprintf (outputfile, "%lda\n", high0);
+	  fprintf (outputfile, "%"PRIdPTR"a\n", high0);
 	  leading_dot = false;
 	  if (type == DIFF_ALL)
 	    {
@@ -1591,7 +1592,7 @@ output_diff3_edscript (FILE *outputfile, struct diff3_block *diff,
 
 	  /* Mark start of conflict.  */
 
-	  fprintf (outputfile, "%lda\n<<<<<<< %s\n", low0 - 1,
+	  fprintf (outputfile, "%"PRIdPTR"a\n<<<<<<< %s\n", low0 - 1,
 		   type == DIFF_ALL ? file0 : file1);
 	  leading_dot = false;
 	  if (type == DIFF_2ND)
@@ -1607,9 +1608,9 @@ output_diff3_edscript (FILE *outputfile, struct diff3_block *diff,
 	/* Write out a delete */
 	{
 	  if (low0 == high0)
-	    fprintf (outputfile, "%ldd\n", low0);
+	    fprintf (outputfile, "%"PRIdPTR"d\n", low0);
 	  else
-	    fprintf (outputfile, "%ld,%ldd\n", low0, high0);
+	    fprintf (outputfile, "%"PRIdPTR",%"PRIdPTR"d\n", low0, high0);
 	}
       else
 	/* Write out an add or change */
@@ -1617,13 +1618,13 @@ output_diff3_edscript (FILE *outputfile, struct diff3_block *diff,
 	  switch (high0 - low0)
 	    {
 	    case -1:
-	      fprintf (outputfile, "%lda\n", high0);
+	      fprintf (outputfile, "%"PRIdPTR"a\n", high0);
 	      break;
 	    case 0:
-	      fprintf (outputfile, "%ldc\n", high0);
+	      fprintf (outputfile, "%"PRIdPTR"c\n", high0);
 	      break;
 	    default:
-	      fprintf (outputfile, "%ld,%ldc\n", low0, high0);
+	      fprintf (outputfile, "%"PRIdPTR",%"PRIdPTR"c\n", low0, high0);
 	      break;
 	    }
 
diff --git a/src/ed.c b/src/ed.c
index 1fae2b8..14f9a43 100644
--- a/src/ed.c
+++ b/src/ed.c
@@ -144,7 +144,7 @@ static void
 print_rcs_hunk (struct change *hunk)
 {
   lin i, f0, l0, f1, l1;
-  long int tf0, tl0, tf1, tl1;
+  intptr_t tf0, tl0, tf1, tl1;
 
   /* Determine range of line numbers involved in each file.  */
   enum changes changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1);
@@ -159,14 +159,16 @@ print_rcs_hunk (struct change *hunk)
     {
       /* For deletion, print just the starting line number from file 0
 	 and the number of lines deleted.  */
-      fprintf (outfile, "d%ld %ld\n", tf0, tf0 <= tl0 ? tl0 - tf0 + 1 : 1);
+      fprintf (outfile, "d%"PRIdPTR" %"PRIdPTR"\n",
+               tf0, tf0 <= tl0 ? tl0 - tf0 + 1 : 1);
     }
 
   if (changes & NEW)
     {
       /* Take last-line-number from file 0 and # lines from file 1.  */
       translate_range (&files[1], f1, l1, &tf1, &tl1);
-      fprintf (outfile, "a%ld %ld\n", tl0, tf1 <= tl1 ? tl1 - tf1 + 1 : 1);
+      fprintf (outfile, "a%"PRIdPTR" %"PRIdPTR"\n",
+               tl0, tf1 <= tl1 ? tl1 - tf1 + 1 : 1);
 
       /* Print the inserted lines.  */
       for (i = f1; i <= l1; i++)
diff --git a/src/ifdef.c b/src/ifdef.c
index b8b084f..4a38404 100644
--- a/src/ifdef.c
+++ b/src/ifdef.c
@@ -358,19 +358,35 @@ do_printf_spec (FILE *out, char const *spec,
 	if (out)
 	  {
 	    /* For example, if the spec is "%3xn", use the printf
-	       format spec "%3lx".  Here the spec prefix is "%3".  */
-	    long int long_value = value;
+	       format spec "%3"PRIxPTR.  Here the spec prefix is "%3".  */
+	    intptr_t long_value = value;
 	    size_t spec_prefix_len = f - spec - 2;
+	    size_t max_format = MAX(strlen(PRIdPTR),
+	                        MAX(strlen(PRIoPTR),
+	                        MAX(strlen(PRIxPTR),
+	                            strlen(PRIXPTR))));
 #if HAVE_C_VARARRAYS
-	    char format[spec_prefix_len + 3];
+	    char format[spec_prefix_len + max_format + 1];
 #else
-	    char *format = xmalloc (spec_prefix_len + 3);
+	    char *format = xmalloc (spec_prefix_len + max_format + 1);
 #endif
 	    char *p = format + spec_prefix_len;
 	    memcpy (format, spec, spec_prefix_len);
-	    *p++ = 'l';
-	    *p++ = c;
-	    *p = '\0';
+	    switch (c)
+	      {
+	        case 'd':
+	          strcpy(p, PRIdPTR);
+	          break;
+	        case 'o':
+	          strcpy(p, PRIoPTR);
+	          break;
+	        case 'x':
+	          strcpy(p, PRIxPTR);
+	          break;
+	        case 'X':
+	          strcpy(p, PRIXPTR);
+	          break;
+	      }
 	    fprintf (out, format, long_value);
 #if ! HAVE_C_VARARRAYS
 	    free (format);
diff --git a/src/sdiff.c b/src/sdiff.c
index 22d6e5b..ed5b246 100644
--- a/src/sdiff.c
+++ b/src/sdiff.c
@@ -968,11 +968,11 @@ edit (struct line_filter *left, char const *lname, lin lline, lin llen,
 		if (llen)
 		  {
 		    if (llen == 1)
-		      fprintf (tmp, "--- %s %ld\n", lname, (long int) lline);
+		      fprintf (tmp, "--- %s %"PRIdPTR"\n", lname, (intptr_t) lline);
 		    else
-		      fprintf (tmp, "--- %s %ld,%ld\n", lname,
-			       (long int) lline,
-			       (long int) (lline + llen - 1));
+		      fprintf (tmp, "--- %s %"PRIdPTR",%"PRIdPTR"\n", lname,
+			       (intptr_t) lline,
+			       (intptr_t) (lline + llen - 1));
 		  }
 		/* Fall through.  */
 	      case '1': case 'b': case 'l':
@@ -990,11 +990,11 @@ edit (struct line_filter *left, char const *lname, lin lline, lin llen,
 		if (rlen)
 		  {
 		    if (rlen == 1)
-		      fprintf (tmp, "+++ %s %ld\n", rname, (long int) rline);
+		      fprintf (tmp, "+++ %s %"PRIdPTR"\n", rname, (intptr_t) rline);
 		    else
-		      fprintf (tmp, "+++ %s %ld,%ld\n", rname,
-			       (long int) rline,
-			       (long int) (rline + rlen - 1));
+		      fprintf (tmp, "+++ %s %"PRIdPTR",%"PRIdPTR"\n", rname,
+			       (intptr_t) rline,
+			       (intptr_t) (rline + rlen - 1));
 		  }
 		/* Fall through.  */
 	      case '2': case 'b': case 'r':
diff --git a/src/side.c b/src/side.c
index 2276385..f5f1027 100644
--- a/src/side.c
+++ b/src/side.c
@@ -260,9 +260,9 @@ print_sdiff_common_lines (lin limit0, lin limit1)
     {
       if (sdiff_merge_assist)
 	{
-	  long int len0 = limit0 - i0;
-	  long int len1 = limit1 - i1;
-	  fprintf (outfile, "i%ld,%ld\n", len0, len1);
+	  intptr_t len0 = limit0 - i0;
+	  intptr_t len1 = limit1 - i1;
+	  fprintf (outfile, "i%"PRIdPTR",%"PRIdPTR"\n", len0, len1);
 	}
 
       if (!left_column)
@@ -302,9 +302,9 @@ print_sdiff_hunk (struct change *hunk)
 
   if (sdiff_merge_assist)
     {
-      long int len0 = last0 - first0 + 1;
-      long int len1 = last1 - first1 + 1;
-      fprintf (outfile, "c%ld,%ld\n", len0, len1);
+      intptr_t len0 = last0 - first0 + 1;
+      intptr_t len1 = last1 - first1 + 1;
+      fprintf (outfile, "c%"PRIdPTR",%"PRIdPTR"\n", len0, len1);
     }
 
   /* Print "xxx  |  xxx " lines.  */
diff --git a/src/system.h b/src/system.h
index be1c0bd..70b8678 100644
--- a/src/system.h
+++ b/src/system.h
@@ -134,7 +134,7 @@ typedef ptrdiff_t lin;
 #define LIN_MAX PTRDIFF_MAX
 verify (TYPE_SIGNED (lin));
 verify (sizeof (ptrdiff_t) <= sizeof (lin));
-verify (sizeof (lin) <= sizeof (long int));
+verify (sizeof (lin) <= sizeof (intptr_t));
 
 /* Limit so that 2 * CONTEXT + 1 does not overflow.  */
 
diff --git a/src/util.c b/src/util.c
index 76872cb..f4e24e4 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1401,13 +1401,13 @@ translate_line_number (struct file_data const *file, lin i)
 }
 
 /* Translate a line number range.  This is always done for printing,
-   so for convenience translate to long int rather than lin, so that the
-   caller can use printf with "%ld" without casting.  */
+   so for convenience translate to intptr_t rather than lin, so that the
+   caller can use printf without casting.  */
 
 void
 translate_range (struct file_data const *file,
 		 lin a, lin b,
-		 long int *aptr, long int *bptr)
+		 intptr_t *aptr, intptr_t *bptr)
 {
   *aptr = translate_line_number (file, a - 1) + 1;
   *bptr = translate_line_number (file, b + 1) - 1;
@@ -1422,16 +1422,16 @@ translate_range (struct file_data const *file,
 void
 print_number_range (char sepchar, struct file_data *file, lin a, lin b)
 {
-  long int trans_a, trans_b;
+  intptr_t trans_a, trans_b;
   translate_range (file, a, b, &trans_a, &trans_b);
 
   /* Note: we can have B < A in the case of a range of no lines.
      In this case, we should print the line number before the range,
      which is B.  */
   if (trans_b > trans_a)
-    fprintf (outfile, "%ld%c%ld", trans_a, sepchar, trans_b);
+    fprintf (outfile, "%"PRIdPTR"%c%"PRIdPTR, trans_a, sepchar, trans_b);
   else
-    fprintf (outfile, "%ld", trans_b);
+    fprintf (outfile, "%"PRIdPTR, trans_b);
 }
 
 /* Look at a hunk of edit script and report the range of lines in each file
@@ -1565,11 +1565,12 @@ debug_script (struct change *sp)
 
   for (; sp; sp = sp->link)
     {
-      long int line0 = sp->line0;
-      long int line1 = sp->line1;
-      long int deleted = sp->deleted;
-      long int inserted = sp->inserted;
-      fprintf (stderr, "%3ld %3ld delete %ld insert %ld\n",
+      intptr_t line0 = sp->line0;
+      intptr_t line1 = sp->line1;
+      intptr_t deleted = sp->deleted;
+      intptr_t inserted = sp->inserted;
+      fprintf (stderr, "%3"PRIdPTR" %3"PRIdPTR" "
+	       "delete %"PRIdPTR" insert %"PRIdPTR"\n",
 	       line0, line1, deleted, inserted);
     }
 
-- 
2.8.3