/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2010 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Research
*
* keyword printf support
*/
#include <ast.h>
#include <ccode.h>
#include <ctype.h>
#include <sfdisc.h>
#include <regex.h>
typedef struct
{
void* handle;
int invisible;
int level;
int version;
} Fmt_t;
typedef struct
{
char* next;
int delimiter;
int first;
} Field_t;
typedef union
{
char** p;
char* s;
Sflong_t q;
long l;
int i;
short h;
char c;
} Value_t;
static char*
{
register char* s;
register int n;
register int c;
register int lp;
register int rp;
char* b;
if (!f->delimiter)
return 0;
s = f->next;
if (f->first)
f->first = 0;
else if (restore)
*s = f->delimiter;
b = ++s;
for (;;)
{
if (!(c = *s++))
{
f->delimiter = 0;
break;
}
else if (c == CC_esc || c == '\\')
{
if (*s)
s++;
}
else if (c == lp)
n++;
else if (c == rp)
n--;
else if (n <= 0)
{
if (c == '(' && restore)
{
lp = '(';
rp = ')';
n = 1;
}
else if (c == '[' && restore)
{
lp = '[';
rp = ']';
n = 1;
}
else if (c == f->delimiter)
{
*(f->next = --s) = 0;
break;
}
}
}
return b;
}
/*
* sfio %! extension function
*/
static int
{
register char* v;
char* t;
char* b;
char* a = 0;
char* s = 0;
Sflong_t n = 0;
int h = 0;
int i = 0;
int x = 0;
int d;
Field_t f;
{
b = v;
for (;;)
{
switch (*v++)
{
case 0:
break;
case '(':
h++;
continue;
case ')':
h--;
continue;
case '=':
case ':':
case ',':
if (h <= 0)
{
a = v;
break;
}
continue;
default:
continue;
}
if (i = *--v)
{
*v = 0;
{
d = *(a + 4);
*(a + 4) = 0;
if (streq(a, "case"))
x = FMT_case;
else if (streq(a, "edit"))
x = FMT_edit;
*(a + 4) = d;
if (x)
a = 0;
}
}
break;
}
n = i;
if (i)
*v++ = i;
}
else
{
v = 0;
}
{
case 'c':
value->c = s ? *s : n;
break;
case 'd':
case 'i':
break;
case 'o':
case 'u':
case 'x':
break;
case 'p':
if (s)
break;
case 'q':
if (s)
{
}
else
{
value->q = n;
}
break;
case 's':
if (!s && (!h || !fp->tmp[1] && !(fp->tmp[1] = sfstropen()) || sfprintf(fp->tmp[1], "%I*d", sizeof(n), n) <= 0 || !(s = sfstruse(fp->tmp[1]))))
s = "";
if (x)
{
h = 0;
d = initfield(&f, v + 4);
switch (x)
{
case FMT_case:
{
if (strmatch(s, a))
{
if (!fp->tmp[0] && !(fp->tmp[0] = sfstropen()) || sfprintf(fp->tmp[0], "%!", &fmt) <= 0 || !(s = sfstruse(fp->tmp[0])))
s = "";
*(v - 1) = d;
if (f.delimiter)
*f.next = d;
h = 1;
break;
}
*(v - 1) = d;
}
break;
case FMT_edit:
for (x = 0; *f.next; x ^= 1)
{
else
break;
break;
if (!regexec(fp->re[x], s, elementsof(match), match, 0) && !regsubexec(fp->re[x], s, elementsof(match), match))
{
break;
}
}
h = 1;
break;
}
if (!h)
s = "";
}
value->s = s;
break;
case 'Z':
value->c = 0;
break;
case '\n':
value->s = "\n";
break;
case '.':
value->i = n;
break;
default:
if ((!fp->convert || !(value->s = (*fp->convert)(fp->handle, &fp->fmt, a, s, n))) && (!fp->tmp[0] && !(fp->tmp[0] = sfstropen()) || sfprintf(fp->tmp[0], "%%%c", fp->fmt.fmt) <= 0 || !(value->s = sfstruse(fp->tmp[0]))))
value->s = "";
break;
}
return 0;
}
/*
* this is the 20000308 interface with Sffmt_t* callback args
*/
int
sfkeyprintf(Sfio_t* sp, void* handle, const char* format, Sf_key_lookup_t lookup, Sf_key_convert_t convert)
{
register int i;
int r;
return r;
}
/*
* this is the original interface
*/
int
sfkeyprintf(Sfio_t* sp, void* handle, const char* format, Sf_key_lookup_t lookup, Sf_key_convert_t convert)
{
register int i;
int r;
return r;
}