Hi,

The standard expr(1) code in src/expr.c uses type 'int' to evaluate
integer expressions.  We needed it to be able to handle larger numbers
associated with the sizes of large files (bigger than 2 GB).

Since the configure scripts test for 'unsigned long long', I've modified
the code in expr.c to utilize that test and assume that if 'unsigned
long long' is available, then so too is 'long long', and the printf(3)
format to use is "%lld".  If unsigned long long is not available, then
the code explicitly uses 'long' and "%ld"; on a 64-bit platform, that
will most likely yield the same effect as using 'long long' on a 32-bit
platform.

I made basically trivial changes in lib/xalloc.h and src/sys2.h so that
the code compiles more nearly cleanly under GCC 3.0.4 on Solaris 7 with
the options '-Wall -Wmissing-prototypes -Wstrict-prototypes'.  I'm sure
that the changes in src/sys2.h are not complete - more default
prototypes could and should be provided.

I hope this patch helps.  Please let me know if you release a sh-utils
maintenance release with this patch (or something very similar) in
place.

Thanks for the code!

-- 
Jonathan Leffler                           #include <disclaimer.h>
STSM, Informix Database Engineering, IBM Data Management Solutions
Phone: +1 650-926-6921                          Tie-line: 630-6921
Email: [EMAIL PROTECTED] (RIP [EMAIL PROTECTED])
Notes ID: Jonathan Leffler/Menlo Park/IBM@IBMUS
Guardian of DBD::Informix v1.00.PC2 -- http://dbi.perl.org
            *=*=*=*=*=* THE END IS NIGH! *=*=*=*=*=*
Please use [EMAIL PROTECTED] because [EMAIL PROTECTED] will
not work from 2002-07-01.  Expect slower responses from 2002-02-18
because email will be sent to Notes and I can't use Lotus Notes as
fast as Unix email.  One day, this signature will shrink!
**************************
** Patch for src/expr.c **
**************************

--- src/expr.c.old      Sun Mar 28 19:12:16 1999
+++ src/expr.c  Fri Mar  1 14:45:03 2002
@@ -45,6 +45,14 @@
 #define NEW(type) ((type *) xmalloc (sizeof (type)))
 #define OLD(x) free ((char *) x)
 
+#ifdef HAVE_UNSIGNED_LONG_LONG
+typedef long long exprInt;
+#define PRINTF_EXPRINT_FORMAT "%lld"
+#else
+typedef long exprInt;
+#define PRINTF_EXPRINT_FORMAT "%ld"
+#endif /* HAVE_UNSIGNED_LONG_LONG */
+
 /* The kinds of value we can have.  */
 enum valtype
 {
@@ -59,7 +67,7 @@
   TYPE type;                   /* Which kind. */
   union
   {                            /* The value itself. */
-    int i;
+    exprInt i;
     char *s;
   } u;
 };
@@ -75,11 +83,11 @@
 /* The name this program was run with. */
 char *program_name;
 
-char *xstrdup ();
+extern char *xstrdup PARAMS ((const char *str));
 
 static VALUE *docolon PARAMS ((VALUE *sv, VALUE *pv));
 static VALUE *eval PARAMS ((void));
-static VALUE *int_value PARAMS ((int i));
+static VALUE *int_value PARAMS ((exprInt i));
 static VALUE *str_value PARAMS ((char *s));
 static int isstring PARAMS ((VALUE *v));
 static int nextarg PARAMS ((char *str));
@@ -94,7 +102,7 @@
 static void trace ();
 #endif
 
-void
+static void
 usage (int status)
 {
   if (status != 0)
@@ -194,7 +202,7 @@
 /* Return a VALUE for I.  */
 
 static VALUE *
-int_value (int i)
+int_value (exprInt i)
 {
   VALUE *v;
 
@@ -235,7 +243,7 @@
   switch (v->type)
     {
     case integer:
-      printf ("%d\n", v->u.i);
+      printf (PRINTF_EXPRINT_FORMAT "\n", v->u.i);
       break;
     case string:
       printf ("%s\n", v->u.s);
@@ -280,7 +288,7 @@
     {
     case integer:
       temp = xmalloc (4 * (sizeof (int) / sizeof (char)));
-      sprintf (temp, "%d", v->u.i);
+      sprintf (temp, PRINTF_EXPRINT_FORMAT, v->u.i);
       v->u.s = temp;
       v->type = string;
       break;
@@ -296,7 +304,7 @@
 static int
 toarith (VALUE *v)
 {
-  int i;
+  exprInt i;
   int neg;
   char *cp;
 
@@ -352,7 +360,7 @@
 
 #define cmpf(name, rel)                                \
 static                                         \
-int name (l, r) VALUE *l; VALUE *r;            \
+int name (VALUE *l, VALUE *r)                   \
 {                                              \
   if (isstring (l) || isstring (r))            \
     {                                          \
@@ -363,6 +371,7 @@
  else                                          \
    return l->u.i rel r->u.i;                   \
 }
+
  cmpf (less_than, <)
  cmpf (less_equal, <=)
  cmpf (equal, ==)
@@ -376,7 +385,7 @@
 
 #define arithf(name, op)                       \
 static                                         \
-int name (l, r) VALUE *l; VALUE *r;            \
+exprInt name (VALUE *l, VALUE *r)              \
 {                                              \
   if (!toarith (l) || !toarith (r))            \
     error (2, 0, _("non-numeric argument"));   \
@@ -384,12 +393,13 @@
 }
 
 #define arithdivf(name, op)                    \
-int name (l, r) VALUE *l; VALUE *r;            \
+static                                         \
+exprInt name (VALUE *l, VALUE *r)              \
 {                                              \
   if (!toarith (l) || !toarith (r))            \
     error (2, 0, _("non-numeric argument"));   \
   if (r->u.i == 0)                             \
-    error (2, 0, _("division by zero"));               \
+    error (2, 0, _("division by zero"));       \
   return l->u.i op r->u.i;                     \
 }
 
@@ -406,8 +416,7 @@
 /* Print evaluation trace and args remaining.  */
 
 static void
-trace (fxn)
-     char *fxn;
+trace (char *fxn)
 {
   char **a;
 
@@ -554,7 +563,7 @@
       tostring (l);
       tostring (r);
       v = int_value (strcspn (l->u.s, r->u.s) + 1);
-      if (v->u.i == (int) strlen (l->u.s) + 1)
+      if (v->u.i == (exprInt) strlen (l->u.s) + 1)
        v->u.i = 0;
       freev (l);
       freev (r);
@@ -568,7 +577,7 @@
       i2 = eval6 ();
       tostring (l);
       if (!toarith (i1) || !toarith (i2)
-         || i1->u.i > (int) strlen (l->u.s)
+         || i1->u.i > (exprInt) strlen (l->u.s)
          || i1->u.i <= 0 || i2->u.i <= 0)
        v = str_value ("");
       else
@@ -625,8 +634,8 @@
 {
   VALUE *l;
   VALUE *r;
-  int (*fxn) ();
-  int val;
+  exprInt (*fxn) (VALUE *l, VALUE *r);
+  exprInt val;
 
 #ifdef EVAL_TRACE
   trace ("eval4");
@@ -658,8 +667,8 @@
 {
   VALUE *l;
   VALUE *r;
-  int (*fxn) ();
-  int val;
+  exprInt (*fxn) (VALUE *l, VALUE *r);
+  exprInt val;
 
 #ifdef EVAL_TRACE
   trace ("eval3");
@@ -689,8 +698,8 @@
 {
   VALUE *l;
   VALUE *r;
-  int (*fxn) ();
-  int val;
+  int (*fxn) (VALUE *l, VALUE *r);
+  exprInt val;
 
 #ifdef EVAL_TRACE
   trace ("eval2");


**************************
** Patch for src/sys2.h **
**************************

--- src/sys2.h.old      Fri Jul 30 14:17:40 1999
+++ src/sys2.h  Fri Mar  1 14:45:20 2002
@@ -158,7 +158,7 @@
 #endif
 
 #ifndef HAVE_DECL_GETENV
-char *getenv ();
+char *getenv PARAMS((const char *));
 #endif
 
 #ifndef HAVE_DECL_LSEEK


****************************
** Patch for lib/xalloc.h **
****************************

--- lib/xalloc.h.old    Fri Jan  1 09:46:37 1999
+++ lib/xalloc.h        Fri Mar  1 14:44:49 2002
@@ -33,7 +33,7 @@
 
 /* If this pointer is non-zero, run the specified function upon each
    allocation failure.  It is initialized to zero. */
-extern void (*xalloc_fail_func) ();
+extern void (*xalloc_fail_func) PARAMS((void));
 
 /* If XALLOC_FAIL_FUNC is undefined or a function that returns, this
    message must be non-NULL.  It is translated via gettext.


Reply via email to