Karim BELABAS on Wed, 9 Sep 1998 15:56:31 +0200 (MET DST)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: a very cute bug


[Igor Schein <igor@txc.com> writes: ]
> Hi, I discovered the following bug ( a,b and c are undefined):
> ? printp(1/a+1/b+1/c)
>   ***   segmentation fault: bug in GP (please report).
> 
> At this point, gp has gone mad and gives segfault on
> any output, so one must exit.

GENtostring was not meant to be reentrant. It is now, since "prettyprint"
needs it (and it doesn't hurt in any case...).

Note: prettyprint format is _very_ buggy/ugly and badly needs to be
rewritten. For instance, after correcting the SEGV, one got:

(15:25) gp > printp(1/a+1/b+1/c)

(
 (
  1

-----

 (c)
 b + 1)

----------------------------

            (b)
 a + 1)

--------------------------------------------------------------------------------

(a)

I added a patch for that also so that it now appears as:

(15:43) gp > printp(1/a+1/b+1/c)

 ((((1 / (c)) b + 1) / (b)) a + 1)

-----------------------------------

                (a)

which is definitely not OK, but a bit more acceptable.

  Karim.


*** src/language/es.c.orig	Wed Sep  9 15:20:08 1998
--- src/language/es.c	Wed Sep  9 15:42:47 1998
***************
*** 12,18 ****
  static void texi(GEN g, long nosign);
  static void sori(GEN g);
  static char format;
! static long decimals, chmp;
  
  /* output a space or do nothing depending on original caller */
  static void (*sp)();
--- 12,18 ----
  static void texi(GEN g, long nosign);
  static void sori(GEN g);
  static char format;
! static long decimals, chmp, initial;
  
  /* output a space or do nothing depending on original caller */
  static void (*sp)();
***************
*** 438,452 ****
    char *string;
    ulong len,size;
  } outString;
! static outString OutStr;
  
  #define STEPSIZE 1024
  #define check_output_length(l) { \
!   const ulong s = OutStr.size; \
!   if (OutStr.len + l >= s) { \
      ulong t = s + l + STEPSIZE; \
!     OutStr.string = gprealloc(OutStr.string, t, s); \
!     OutStr.size = t; \
    } \
  }
  
--- 438,452 ----
    char *string;
    ulong len,size;
  } outString;
! static outString *OutStr;
  
  #define STEPSIZE 1024
  #define check_output_length(l) { \
!   const ulong s = OutStr->size; \
!   if (OutStr->len + l >= s) { \
      ulong t = s + l + STEPSIZE; \
!     OutStr->string = gprealloc(OutStr->string, t, s); \
!     OutStr->size = t; \
    } \
  }
  
***************
*** 454,460 ****
  outstr_putc(char c)
  {
    check_output_length(1);
!   OutStr.string[OutStr.len++] = c;
  }
  
  static void
--- 454,460 ----
  outstr_putc(char c)
  {
    check_output_length(1);
!   OutStr->string[OutStr->len++] = c;
  }
  
  static void
***************
*** 462,469 ****
  {
    long len=strlen(s);
    check_output_length(len);
!   strcpy(OutStr.string+OutStr.len,s);
!   OutStr.len += len;
  }
  
  static void
--- 462,469 ----
  {
    long len=strlen(s);
    check_output_length(len);
!   strcpy(OutStr->string+OutStr->len,s);
!   OutStr->len += len;
  }
  
  static void
***************
*** 484,496 ****
  GENtostr0(GEN x, void(*do_out)(GEN))
  {
    PariOUT *tmp = pariOut;
  
    if (typ(x) == t_STR) return pari_strdup(GSTR(x));
!   pariOut = &pariOut2Str;
!   OutStr.len = 0; OutStr.size=0; OutStr.string=NULL;
!   do_out(x); OutStr.string[OutStr.len] = 0;
  
!   pariOut = tmp; return OutStr.string;
  }
  
  char *
--- 484,497 ----
  GENtostr0(GEN x, void(*do_out)(GEN))
  {
    PariOUT *tmp = pariOut;
+   outString *tmps = OutStr, newStr;
  
    if (typ(x) == t_STR) return pari_strdup(GSTR(x));
!   pariOut = &pariOut2Str; OutStr = &newStr;
!   OutStr->len = 0; OutStr->size=0; OutStr->string=NULL;
!   do_out(x); OutStr->string[OutStr->len] = 0;
  
!   pariOut = tmp; OutStr = tmps; return newStr.string;
  }
  
  char *
***************
*** 1446,1456 ****
        pariputc(')'); break;
  
      case t_RFRAC: case t_RFRACN:
      {
!       char *v1 = GENtostr0((GEN)g[1], &outsor);
!       char *v2 = GENtostr0((GEN)g[2], &outsor);
!       long sd = 0, sn = 0, n = strlen(v1), d = strlen(v2);
        long wd = term_width();
  
        pariputc('\n');
        i = max(n,d)+2;
--- 1447,1461 ----
        pariputc(')'); break;
  
      case t_RFRAC: case t_RFRACN:
+     if (initial)
      {
!       char *v1, *v2;
!       long sd = 0, sn = 0, d,n;
        long wd = term_width();
+       
+       initial = 0;
+       v1 = GENtostr0((GEN)g[1], &sori); n = strlen(v1);
+       v2 = GENtostr0((GEN)g[2], &sori); d = strlen(v2);
  
        pariputc('\n');
        i = max(n,d)+2;
***************
*** 1469,1474 ****
--- 1474,1481 ----
        blancs(sd+1); pariputs(v2);
        pariputc('\n'); return;
      }
+     pariputc('('); sori((GEN)g[1]); pariputs(" / "); sori((GEN)g[2]); 
+     pariputc(')'); return;
  	
      case t_QFR: case t_QFI: pariputc('{');
        sori((GEN)g[1]); pariputs(", ");
***************
*** 1693,1699 ****
  sor(GEN g, char f, long d, long c)
  {
    long av=avma; sp = &wr_space;
!   format = f; decimals = d; chmp = c;
    sori(changevar(g,polvar)); avma = av;
  }
  
--- 1700,1706 ----
  sor(GEN g, char f, long d, long c)
  {
    long av=avma; sp = &wr_space;
!   format = f; decimals = d; chmp = c; initial = 1;
    sori(changevar(g,polvar)); avma = av;
  }
  
--
Karim Belabas                    email: Karim.Belabas@math.u-psud.fr
Dep. de Mathematiques, Bat. 425
Universite Paris-Sud             Tel: (00 33) 1 69 15 57 48
F-91405 Orsay (France)           Fax: (00 33) 1 69 15 60 19
--
PARI/GP Home Page: http://pari.home.ml.org