dssprintf.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 2002-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* dss printf implementation
*/
#include "dsshdr.h"
#include <ast_float.h>
struct Arg_s
{
char* details;
char* qb;
char* qe;
unsigned short type;
unsigned short fmt;
unsigned char flags;
};
struct Format_s
{
char* oformat;
char* nformat;
};
typedef struct Fmt_s
{
void* data;
int errors;
} Fmt_t;
typedef union
{
char** p;
char* s;
Sflong_t q;
long l;
int i;
short h;
char c;
double f;
} Value_t;
#define DSS_FORMAT_char 1
#define DSS_FORMAT_float 2
#define DSS_FORMAT_int 3
#define DSS_FORMAT_long 4
#define DSS_FORMAT_string 5
#define DSS_FORMAT_quote 0x01
/*
* sfio %! extension function
*/
static int
{
if (ap->expr && cxeval(fp->cx, ap->expr, fp->data, &ret) < 0 || cxcast(fp->cx, &ret, ap->variable, ap->cast, fp->data, ap->details))
{
return -1;
}
{
case DSS_FORMAT_char:
value->c = 0;
else
break;
case DSS_FORMAT_float:
break;
case DSS_FORMAT_int:
#if 0
/*
* this code is technically correct but overly
* complicates script portability between architectures
*/
value->i = 0;
else
break;
#endif
case DSS_FORMAT_long:
value->q = 0;
value->q = FLTMAX_INTMAX_MAX;
value->q = FLTMAX_INTMAX_MAX;
else
break;
case DSS_FORMAT_string:
ret.value.string.size = strlen(ret.value.string.data = fmtquote(ret.value.string.data, ap->qb, ap->qe, ret.value.string.size, ap->fmt));
break;
}
return 0;
}
/*
* printf
*/
int
{
register char* s;
register char* t;
register char* d;
register char* v;
register int n;
register int q;
int l;
int x;
char* f;
char* o;
char* w;
if (!cx)
if (!fp)
{
if (f = s = (char*)format)
{
d = 0;
l = 0;
n = 0;
q = 0;
w = 0;
for (;;)
{
switch (*s++)
{
case 0:
if (q)
{
return -1;
}
break;
case '%':
if (*s != '%')
{
q = 1;
n++;
f = s - 1;
}
continue;
case '(':
if (q == 1)
{
q++;
for (;;)
{
switch (*s++)
{
case 0:
s--;
break;
case '(':
q++;
continue;
case ')':
if (--q == 1)
break;
continue;
case ':':
if (*s == ':')
s++;
else if (!d)
d = s;
continue;
default:
continue;
}
break;
}
if (d)
{
l += s - d + 1;
d = 0;
}
}
continue;
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'o':
case 's':
case 'u':
case 'x':
if (q == 1)
q = 0;
continue;
default:
continue;
}
break;
}
if (!(fp = vmnewof(dss->vm, 0, Format_t, 1, (n - 1) * sizeof(Arg_t) + strlen(format) + 2 * n + l + 2)))
{
return -1;
}
q = 0;
d = 0;
l = 0;
for (;;)
{
switch (*t++ = *s++)
{
case 0:
*(t - 1) = '\n';
*t = 0;
break;
case '%':
if (*s == '%')
*t++ = *s++;
else
q = 1;
continue;
case '(':
if (q == 1)
{
q++;
t--;
x = 0;
v = s;
for (;;)
{
switch (*s++)
{
case 0:
return -1;
case '(':
if (!d)
x = 1;
q++;
continue;
case ')':
if (--q == 1)
break;
continue;
case ':':
if (*s == ':')
s++;
else if (!d && q == 2)
d = s;
continue;
case ',':
if (!d)
x = 1;
continue;
default:
x = 1;
continue;
}
break;
}
if (d)
*(d - 1) = 0;
*(s - 1) = 0;
if (*v)
{
if (x)
{
void* pop;
return -1;
return -1;
}
else if (cx->referencef)
{
Cxoperand_t a;
Cxoperand_t b;
Cxoperand_t r;
return -1;
}
return -1;
}
else if (d)
{
w = d;
d = 0;
}
}
continue;
case 'c':
if (q == 1)
{
goto set;
}
continue;
case 'd':
case 'o':
case 'u':
case 'x':
if (q == 1)
{
if (l > 1 || ap->variable && (ap->variable->format.width == 8 || ap->variable->type->format.width == 8))
{
n = *(t - 1);
*(t - 1) = 'l';
*t++ = 'l';
*t++ = n;
}
else
goto set;
}
continue;
case 'e':
case 'f':
case 'g':
if (q == 1)
{
goto set;
}
continue;
case 'h':
if (q == 1)
t--;
continue;
case 'l':
if (q == 1)
{
t--;
l++;
}
continue;
case 's':
if (q == 1)
{
set:
if (w)
{
w = 0;
continue;
}
{
{
*t = 0;
}
return -1;
}
l = 0;
q = 0;
{
while (*d)
{
o = 0;
v = d;
while (*d)
if (*d++ == ':')
{
*(o = d - 1) = 0;
break;
}
{
if (o)
*o = ':';
{
if (d == o)
d++;
}
}
{
while (*f++ = *v++);
}
else if (streq(v, "expand"))
{
continue;
}
{
v += 7;
while (*v)
{
if (*v == '|' || *v == ',')
{
v++;
continue;
}
{
break;
}
{
v += 4;
}
{
v += 4;
}
{
v += 4;
}
{
v += 4;
}
{
v += 4;
}
else
while (*v && *v != '|' && *v != ',')
v++;
}
continue;
}
else if (streq(v, "escape"))
{
if (v[5])
{
while (*f++ = *v++);
}
else
}
{
if (v[5])
{
while (*f++ = *v++);
}
else
}
else if (streq(v, "wide"))
else
{
if (*d)
*(d - 1) = ':';
d = v;
break;
}
}
while (*f++ = *d++);
d = 0;
}
if (ap->variable && !ap->edit && cxisstring(ap->variable->type) && ap->variable->format.map && ap->variable->format.map->part && ap->variable->format.map->part->edit)
ap++;
}
continue;
case 'L':
if (q == 1)
{
t--;
l += 2;
}
continue;
default:
continue;
}
break;
}
}
else
{
n = q = 0;
{
for (vp = (Cxvariable_t*)dtfirst(dss->meth->cx->fields); vp; vp = (Cxvariable_t*)dtnext(dss->meth->cx->fields, vp), n++)
q = l;
}
{
q = l;
}
q += 2;
{
return -1;
}
*s++ = '\n';
vp = dss->meth->cx->fields ? (Cxvariable_t*)dtfirst(dss->meth->cx->fields) : dss->meth->data ? (Cxvariable_t*)dss->meth->data : 0;
if (vp)
for (;;)
{
{
if (!vp)
break;
}
break;
{
ap++;
}
else
vp++;
}
*s = 0;
}
if (!sp)
return 0;
}
}