Logo Search packages:      
Sourcecode: ksh version File versions

tprintf.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1999-2007 AT&T Knowledge Ventures            *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                      by AT&T Knowledge Ventures                      *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                                                                      *
***********************************************************************/
#include    "sftest.h"

typedef struct _coord_
{     int   x;
      int   y;
} Coord_t;

Coord_t     Coord;

#if __STD_C
int coordprint(Sfio_t* f, Void_t* v, Sffmt_t* fe)
#else
int coordprint(f, v, fe)
Sfio_t*           f;
Void_t*           v;
Sffmt_t*    fe;
#endif
{
      char        type[128];
      Coord_t*    cp;
      char*       s;

      if(fe->fmt != 'c')
            return -1;

      cp = va_arg(fe->args,Coord_t*);
      memcpy(type,fe->t_str,fe->n_str); type[fe->n_str] = 0;
      s = *((char**)v) = sfprints(type,cp->x,cp->y);
      fe->fmt = 's';
      fe->size = strlen(s);
      fe->flags |= SFFMT_VALUE;
      return 0;
}

typedef union Value_u
{
      unsigned char     c;
      short       h;
      int         i;
      long        l;
      Sflong_t    ll;
      Sfdouble_t  ld;
      double            d;
      float       f;
      char        *s;
      int         *ip;
      char        **p;
} Value_t;

#if __STD_C
int nulprint(Sfio_t* f, Void_t* val, Sffmt_t* fe)
#else
int nulprint(f, val, fe)
Sfio_t*           f;
Void_t*           val;
Sffmt_t*    fe;
#endif
{
      if(fe->fmt == 'Z')
      {     fe->fmt = 'c';
            fe->size = -1;
            fe->base = -1;
            fe->flags &= ~SFFMT_LONG;
            fe->flags |= SFFMT_VALUE;
            ((Value_t*)val)->l = 0x04050607;
            ((Value_t*)val)->c = 0;
      }
      else if(fe->fmt == 'Y')
      {     fe->fmt = 'c';
            fe->size = -1;
            fe->base = ':';
            fe->flags &= ~SFFMT_LONG;
            fe->flags |= SFFMT_VALUE;
            ((Value_t*)val)->s = "abc";
      }
      return 0;
}

static int  OXcount;
static char*      OXstr = "abc";
#if __STD_C
int DOXSprint(Sfio_t* f, Void_t* v, Sffmt_t* fe)
#else
int DOXSprint(f, v, fe)
Sfio_t*           f;
Void_t*           v;
Sffmt_t*    fe;
#endif
{
      OXcount += 1;

      switch(fe->fmt)
      {
      case 'd' :
            *((int*)v) = 10;
            fe->flags |= SFFMT_VALUE;
            return 0;

      case 'O' :
            fe->fmt = 'o';
            *((int*)v) = 11;
            fe->flags |= SFFMT_VALUE;
            return 0;

      case 'X' :
            fe->fmt = 'x';
            *((int*)v) = 12;
            fe->flags |= SFFMT_VALUE;
            return 0;

      case 's':
            *((char**)v) = OXstr;
            fe->flags |= SFFMT_VALUE;
            return 0;
      }

      return 0;
}

#if __STD_C
int abprint(Sfio_t* f, Void_t* v, Sffmt_t* fe)
#else
int abprint(f, v, fe)
Sfio_t*           f;
Void_t*           v;
Sffmt_t*    fe;
#endif
{
      switch(fe->fmt)
      {
      case 'a' :
            fe->fmt = 'u';
            return 0;
      case 'b' :
            fe->fmt = 'd';
            return 0;
      case 'y' : /* test return value of extension function */
            fe->size = 10;
            fe->fmt = 's';
            return 0;
      case 'Y' : /* terminate format processing */
      default :
            return -1;
      }
}

#if __STD_C
int intarg(Sfio_t* f, Void_t* val, Sffmt_t* fe)
#else
int intarg(f, val, fe)
Sfio_t*           f;
Void_t*           val;
Sffmt_t*    fe;
#endif
{     static int  i = 1;
      *((int*)val) = i++;
      fe->flags |= SFFMT_VALUE;
      return 0;
}

#if __STD_C
int shortarg(Sfio_t* f, Void_t* val, Sffmt_t* fe)
#else
int shortarg(f, val, fe)
Sfio_t*           f;
Void_t*           val;
Sffmt_t*    fe;
#endif
{     static short      i = -2;

      *((short*)val) = i++;
      fe->size = sizeof(short);
      fe->flags |= SFFMT_VALUE;

      return 0;
}

#if __STD_C
int transarg(Sfio_t* f, Void_t* val, Sffmt_t* fe)
#else
int transarg(f, val, fe)
Sfio_t*           f;
Void_t*           val;
Sffmt_t*    fe;
#endif
{
      switch(fe->fmt)
      { case 'D' :
            fe->fmt = 'd'; return 0;
        case 'O' :
            fe->fmt = 'o'; return 0;
        case 'F' :
            fe->fmt = 'f'; return 0;
        case 'S' :
            fe->fmt = 's'; return 0;
        case 'C' :
            fe->fmt = 'c'; return 0;
        default : return -1;
      }
}

#if __STD_C
void stkprint(char* buf, int n, char* form, ...)
#else
void stkprint(buf,n,form,va_alist)
char* buf;
int   n;
char* form;
va_dcl
#endif
{     va_list     args;
      Sffmt_t     fe;
#if __STD_C
      va_start(args,form);
#else
      va_start(args);
#endif
      fe.form = form;
      va_copy(fe.args,args);
      fe.extf = NIL(Sffmtext_f);
      fe.eventf = NIL(Sffmtevent_f);
      sfsprintf(buf,n,"%! %d %d",&fe,3,4);
      va_end(args);
}

MAIN()
{
      char        buf1[1024], buf2[1024], *list[4], *s;
      double            x=0.0051, y;
      Sfdouble_t  lx, ly;
      int         i, j;
      long        k;
      Sffmt_t           fe;
      Sfio_t*           f;

      f = sfopen(NIL(Sfio_t*), tstfile(0), "w+");
      sfsetbuf(f,buf1,10);
      sfprintf(f,"%40s\n","0123456789");
      sfsprintf(buf2,sizeof(buf2),"%40s","0123456789");
      sfseek(f,(Sfoff_t)0,0);
      if(!(s = sfgetr(f,'\n',1)) )
            terror("Failed getting string\n");
      if(strcmp(s,buf2) != 0)
            terror("Failed formatting %%s\n");

      sfsprintf(buf1,sizeof(buf1),"%4d %4o %4x", 10, 11, 11);
      sfsprintf(buf2,sizeof(buf2),"%2$4d %1$4o %1$4x", 11, 10);
      if(strcmp(buf1,buf2) != 0)
            terror("Failed testing $position\n");

      sfsprintf(buf1,sizeof(buf1),"%d %1$d %.*d %1$d", 10, 5, 300);
      sfsprintf(buf2,sizeof(buf2),"%d %1$d %3$.*2$d %1$d", 10, 5, 300);
      if(strcmp(buf1,buf2) != 0)
            terror("Failed testing $position with precision\n");

      fe.version = SFIO_VERSION;
      fe.form = NIL(char*);
      fe.extf = DOXSprint;
      fe.eventf = NIL(Sffmtevent_f);

      sfsprintf(buf1,sizeof(buf1),"%4d %4o %4x %4o %4x %s", 10, 11, 12, 11, 10, "abc");
      sfsprintf(buf2,sizeof(buf2),"%!%2$4d %3$4O %4$4X %3$4O %2$4x %5$s", &fe);
      if(strcmp(buf1,buf2) != 0)
            terror("Failed testing $position2\n");
      if(OXcount != 4)
            terror("Failed OXprint called wrong number of times %d\n",OXcount);

      sfsprintf(buf1,sizeof(buf1),"%6.2f",x);
      if(strcmp(buf1,"  0.01") != 0)
            terror("%%f rounding wrong\n");

      fe.version = SFIO_VERSION;
      fe.form = NIL(char*);
      fe.extf = abprint;
      fe.eventf = NIL(Sffmtevent_f);
      sfsprintf(buf1,sizeof(buf1),"%%sX%%d%..4u %..4d9876543210",-1,-1);
      sfsprintf(buf2,sizeof(buf2),"%!%%sX%%d%..4a %..4b%y%Yxxx",
                  &fe, -1, -1, "9876543210yyyy" );
      if(strcmp(buf1,buf2) != 0)
            terror("%%!: Extension function failed1\n");

      fe.form = NIL(char*);
      fe.extf = intarg;
      sfsprintf(buf1,sizeof(buf1),"%d %d%",1,2);
      sfsprintf(buf2,sizeof(buf2),"%!%d %d%",&fe);
      if(strcmp(buf1,buf2) != 0)
            terror("%%!: Extension function failed2\n");

      fe.form = NIL(char*);
      sfsprintf(buf1,sizeof(buf1),"%d %d%%",3,4);
      sfsprintf(buf2,sizeof(buf2),"%!%d %d%%",&fe);
      if(strcmp(buf1,buf2) != 0)
            terror("%%!: Extension function failed3\n");

      fe.form = NIL(char*);
      fe.extf = shortarg;
      sfsprintf(buf1,sizeof(buf1),"%hu %ho %hi %hu %ho %hd", -2, -1, 0, 1, 2, 3);
      sfsprintf(buf2,sizeof(buf2),"%!%u %o %i %u %o %d",&fe);
      if(strcmp(buf1,buf2) != 0)
            terror("%%!: Extension function failed4\n");

      /* test extf translation */
      fe.form = NIL(char*);
      fe.extf = transarg;
      sfsprintf(buf1,sizeof(buf1),"%d %o %f %s %c", -1, -1, -1., "s", 'c');
      sfsprintf(buf2,sizeof(buf2),"%!%D %O %F %S %C",&fe, -1, -1, -1., "s", 'c');
      if(strcmp(buf1,buf2) != 0)
            terror("%%!: Extension function failed5\n");

      k = 1234567890;
      sfsprintf(buf1,sizeof(buf1),"%I*d",sizeof(k),k);
      if(strcmp(buf1,"1234567890") != 0)
            terror("%%I*d failed\n");

      Coord.x = 5;
      Coord.y = 7;
      sfsprintf(buf1,sizeof(buf1),"%d %d",Coord.x,Coord.y);

      fe.form = NIL(char*);
      fe.extf = coordprint;
      sfsprintf(buf2,sizeof(buf2),"%!%(%d %d)c",&fe,&Coord);
      if(strcmp(buf1,buf2) != 0)
            terror("%%()c `%s' != `%s'\n", buf1, buf2);

      fe.form = NIL(char*);
      fe.extf = nulprint;
      buf2[0] = buf2[1] = buf2[2] = buf2[3] = buf2[4] = 3;
      sfsprintf(buf2,sizeof(buf2),"%!\001%Z\002",&fe);
      if(buf2[0]!=1||buf2[1]!=0||buf2[2]!=2||buf2[3]!=0||buf2[4]!=3)
            terror("%%Z <1,0,2,0,3> != <%o,%o,%o,%o,%o>\n",
                  buf2[0], buf2[1], buf2[2], buf2[3], buf2[4]);

      fe.form = NIL(char*);
      fe.extf = nulprint;
      buf2[0] = buf2[1] = buf2[2] = buf2[3] = buf2[4] = 3;
      sfsprintf(buf2,sizeof(buf2),"%!%c%Z%c",&fe,1,2);
      if(buf2[0]!=1||buf2[1]!=0||buf2[2]!=2||buf2[3]!=0||buf2[4]!=3)
            terror("%%Z <1,0,2,0,3> != <%o,%o,%o,%o,%o>\n",
                  buf2[0], buf2[1], buf2[2], buf2[3], buf2[4]);

      fe.form = NIL(char*);
      fe.extf = nulprint;
      sfsprintf(buf2,sizeof(buf2),"%!%Y",&fe);
      if(strcmp(buf2,"a:b:c"))
            terror("%%Y a:b:c != %s\n", buf2);

      sfsprintf(buf1,sizeof(buf1),"%d %d %d %d",1,2,3,4);
      stkprint(buf2,sizeof(buf2),"%d %d",1,2);
      if(strcmp(buf1,buf2) != 0)
            terror("%%!: Stack function failed\n");

      sfsprintf(buf1,sizeof(buf1),"% +G",-1.2345);
      sfsprintf(buf2,sizeof(buf2),"-1.2345");
      if(strcmp(buf1,buf2) != 0)
            terror("Failed %% +G test\n");

      if(sizeof(int) == 4 &&  sizeof(short) == 2)
      {     char* s = sfprints("%hx",0xffffffff);
            if(!s || strcmp(s,"ffff") != 0)
                  terror("Failed %%hx test\n");

            s = sfprints("%I2x",0xffffffff);
            if(!s || strcmp(s,"ffff") != 0)
                  terror("Failed %%I2x test\n");
      }

      if(sizeof(int) == 4 &&  sizeof(char) == 1)
      {     char* s = sfprints("%hhx",0xffffffff);
            if(!s || strcmp(s,"ff") != 0)
                  terror("Failed %%hhx test\n");

            s = sfprints("%I1x",0xffffffff);
            if(!s || strcmp(s,"ff") != 0)
                  terror("Failed %%I1x test\n");
      }

      sfsprintf(buf1,sizeof(buf1),"%#..16d",-0xabc);
      if(strcmp(buf1,"-16#abc") != 0)
            terror("Failed %%..16d test\n");

      sfsprintf(buf1,sizeof(buf1),"%#..16lu",(long)0xc2c01576);
      if(strcmp(buf1,"16#c2c01576") != 0)
            terror("Failed %%..16u test\n");

      sfsprintf(buf1,sizeof(buf1),"%0#4o",077);
      if(strcmp(buf1,"0077") != 0)
            terror("Failed %%0#4o test\n");

      sfsprintf(buf1,sizeof(buf1),"%0#4x",0xc);
      if(strcmp(buf1,"0x000c") != 0)
            terror("Failed %%0#4x test\n");

      sfsprintf(buf1,sizeof(buf1),"%c%c%c",'a','b','c');
      if(strcmp(buf1,"abc") != 0)
            terror("Failed %%c test\n");

      sfsprintf(buf1,sizeof(buf1),"%.4c",'a');
      if(strcmp(buf1,"aaaa") != 0)
            terror("Failed %%.4c test\n");

      sfsprintf(buf1,sizeof(buf1),"%hd%c%hd%ld",(short)1,'1',(short)1,1L);
      if(strcmp(buf1,"1111") != 0)
            terror("Failed %%hd test\n");

      sfsprintf(buf1,sizeof(buf1),"%10.5E",(double)0.0000625);
      if(strcmp(buf1,"6.25000E-05") != 0)
            terror("Failed %%E test\n");

      sfsprintf(buf1,sizeof(buf1),"%10.5f",(double)0.0000625);
      if(strcmp(buf1,"   0.00006") != 0)
            terror("Failed %%f test\n");

      sfsprintf(buf1,sizeof(buf1),"%10.5G",(double)0.0000625);
      if(strcmp(buf1,"  6.25E-05") != 0)
            terror("Failed %%G test\n");

      list[0] = "0";
      list[1] = "1";
      list[2] = "2";
      list[3] = 0;
      sfsprintf(buf1,sizeof(buf1),"%..*s", ',', list);
      if(strcmp(buf1,"0,1,2") != 0)
            terror("Failed %%..*s test\n");

      sfsprintf(buf1,sizeof(buf1),"%.2.*c", ',', "012");
      if(strcmp(buf1,"00,11,22") != 0)
            terror("Failed %%..*c test\n");

      sfsprintf(buf1,sizeof(buf1),"A%.0dB", 0);
      if(strcmp(buf1,"AB") != 0)
            terror("Failed precision+0 test\n");

      sfsprintf(buf1,sizeof(buf1),"A%.0dB", 1);
      if(strcmp(buf1,"A1B") != 0)
            terror("Failed precision+1 test\n");

      sfsprintf(buf1,sizeof(buf1),"A%4.0dB", 12345);
      if(strcmp(buf1,"A12345B") != 0)
            terror("Failed exceeding width test\n");

      sfsprintf(buf1,sizeof(buf1),"A%3dB",33);
      if(strcmp(buf1,"A 33B") != 0)
            terror("Failed justification test\n");

      sfsprintf(buf1,sizeof(buf1),"A%04dB",-1);
      if(strcmp(buf1,"A-001B") != 0)
            terror("Failed zero filling test\n");

      sfsprintf(buf1,sizeof(buf1),"A%+04dB",1);
      if(strcmp(buf1,"A+001B") != 0)
            terror("Failed signed and zero-filled test\n");

      sfsprintf(buf1,sizeof(buf1),"A% .0dB", -1);
      if(strcmp(buf1,"A-1B") != 0)
            terror("Failed blank and precision test\n");

      sfsprintf(buf1,sizeof(buf1),"A%+ .0dB", 1);
      if(strcmp(buf1,"A+1B") != 0)
            terror("Failed +,blank and precision test\n");

      sfsprintf(buf1,sizeof(buf1),"A%010.2fB", 1.2);
      if(strcmp(buf1,"A0000001.20B") != 0)
            terror("Failed floating point and zero-filled test\n");

      sfsprintf(buf1,sizeof(buf1),"A%-010.2fB", 1.2);
      if(strcmp(buf1,"A1.20      B") != 0)
            terror("Failed floating point and left justification test\n");

      sfsprintf(buf1,sizeof(buf1),"A%-#XB", 0xab);
      if(strcmp(buf1,"A0XABB") != 0)
            terror("Failed %%-#X conversion test\n");

#if !_ast_intmax_long
      { Sflong_t  ll;
        char            buf[128];
        char*           s = sfprints("%#..16llu",~((Sflong_t)0));
        sfsscanf(s,"%lli", &ll);
        if(ll != (~((Sflong_t)0)) )
            terror("Failed inverting printf/scanf Sflong_t\n");

        s = sfprints("%#..18lld",~((Sflong_t)0));
        sfsscanf(s,"%lli", &ll);
        if(ll != (~((Sflong_t)0)) )
            terror("Failed inverting printf/scanf Sflong_t\n");

        s = sfprints("%#..lli",~((Sflong_t)0));
        sfsscanf(s,"%lli", &ll);
        if(ll != (~((Sflong_t)0)) )
            terror("Failed inverting printf/scanf Sflong_t\n");

        sfsprintf(buf,sizeof(buf), "%llu", (~((Sflong_t)0)/2) );
        s = sfprints("%Iu", (~((Sflong_t)0)/2) );
        if(strcmp(buf,s) != 0)
            terror("Failed conversion with I flag\n");

        if(sizeof(Sflong_t)*8 == 64)
        {   s = sfprints("%I64u",(~((Sflong_t)0)/2) );
            if(strcmp(buf,s) != 0)
                  terror("Failed conversion with I64 flag\n");
        }
      }
#endif

      i = (int)(~(~((unsigned int)0) >> 1));
      s = sfprints("%d",i);
      j = atoi(s);
      if(i != j)
            terror("Failed converting highbit\n");
      
      for(i = -10000; i < 10000; i += 123)
      {     s = sfprints("%d",i);
            j = atoi(s);
            if(j != i)
                  terror("Failed integer conversion\n");
      }

      /* test I flag for strings */
      { char      *ls[3];
        ls[0] = "0123456789";
        ls[1] = "abcdefghij";
        ls[2] = 0;
        s = sfprints("%I5..*s", 0, ls);
        if(strcmp(s, "01234abcde") != 0)
            terror("Failed I flag with %%s\n");
      }

      /* test justification */
      sfsprintf(buf1,sizeof(buf1),"%-10.5s","abcdefghij");
      sfsprintf(buf2,sizeof(buf2),"%*.5s",-10,"abcdefghij");
      if(strcmp(buf1,buf2) != 0)
            terror("Left-justification is wrong\n");

      sfsprintf(buf1,sizeof(buf1),"%10.5s","abcdefghij");
      sfsprintf(buf2,sizeof(buf2),"%*.5s",10,"abcdefghij");
      if(strcmp(buf1,buf2) != 0)
            terror("Justification is wrong\n");

      /* testing x/open compliant with respect to precision */
      sfsprintf(buf1, sizeof(buf1),
            "%.d %.hi %.lo %.f %.e %.g %.g %.g %.g %.g %.s %.d %.hi %.lo|",
            1345,
            1234,
            1234567890,
            321.7654321,
            321.7654321,
            -0.01,
            0.01,
            1e-5,
            1.4,
            -1.4,
            "test-string",
            0,
            0,
            0L);

      if(strcmp(buf1,"1345 1234 11145401322 322 3e+02 -0.01 0.01 1e-05 1 -1    |") )
            terror("Precision not set to zero as required after a dot");

      /* test %#c to print C-style characters */
      sfsprintf(buf1, sizeof(buf1), "%#.2c%#.2c", '\n', 255);
      if(strcmp(buf1, "\\n\\n\\377\\377") != 0)
            terror("%%#c formatting failed");

      /* test printing of signed integer of length 1 */
#if defined(__STDC__)
      {     signed char c = -1;
            sfsprintf(buf1, sizeof(buf1), "%I1d", c);
            if(strcmp(buf1, "-1") != 0)
                  terror("%%I1d formatting failed");
      }
#endif

      x = 0;
      y = 1;
      sfsprintf(buf1, sizeof(buf1), "%g %g %g", x/x, y/x, (-y)/x);
      if (strcmp(buf1, "nan inf -inf") != 0)
            terror("double NaN Inf error: %s", buf1);
      sfsprintf(buf1, sizeof(buf1), "%G %G %G", x/x, y/x, (-y)/x);
      if (strcmp(buf1, "NAN INF -INF") != 0)
            terror("double NaN Inf error: %s", buf1);
      sfsprintf(buf1, sizeof(buf1), "%05g %05g %05g", x/x, y/x, (-y)/x);
      if (strcmp(buf1, "  nan   inf  -inf") != 0)
            terror("double NaN Inf error: %s", buf1);
      lx = 0;
      ly = 1;
      sfsprintf(buf1, sizeof(buf1), "%Lg %Lg %Lg", lx/lx, ly/lx, (-ly)/lx);
      if (strcmp(buf1, "nan inf -inf") != 0)
            terror("Sfdbouble_t NaN Inf error: %s", buf1);

      /* test the sfaprints() function */
      if(sfaprints(&s, "%d", 123) != 4 || strcmp(s, "123") != 0)
            terror("sfaprints() failed");
      free(s);

      TSTEXIT(0);
}

Generated by  Doxygen 1.6.0   Back to index