/***********************************************************************
* *
* 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
/*
* flat method
*
* Glenn Fowler
* AT&T Research
*/
static const char usage[] =
"[+DESCRIPTION?The \bdss\b flat method schema is the name of an XML file "
"\b$PATH\b.]"
"[b!:binary?Enable the fixed binary record field optimization.]"
"[e:emptyspace?Write empty field values as one \bspace\b character.]"
"[h:header?Print a C header for schema member access on the standard"
" output and exit. The \bFLAT\b(\adata\a) macro returns a pointer"
" to the flat record \bstruct\b given the \bDssrecord_t\b pointer"
" \adata\a. This macro cannot be evaluated in a declaration"
" assignment. The member names are prefixed by \ashema\a_ to"
" avoid C identifier conflicts.]"
"[o:offsets?Print the name, offset, size, number of elements and type"
" of each member, one per line, on the standard output, and exit."
" Scalar fields have 0 elements.]"
"[p:prototype?Print a prototype flat record with the field data replaced by"
" the field name on the standard output and exit.]"
"[s:struct?Print the fixed width record schema C \bstruct\b on the standard"
" output and exit.]"
"[T:test?Enable implementation-specific tests and tracing.]#[mask]"
"[+TAGS?The supported tags are:]{"
;
#include <dsslib.h>
#include <ccode.h>
#include <magicid.h>
#include <regex.h>
struct Value_s
{
const char* name;
long value;
};
{
};
struct Flatten_s
{
};
{
};
{
};
{
};
{
};
{
};
{
};
{
};
{
};
{
};
{
int nfields;
int binary;
int code;
int continuator;
int delimiter;
int emptyspace;
int escape;
int force;
int list;
int prototype;
int quotebegin;
int quoteend;
int sufficient;
int swap;
int terminator;
int variable;
char* valbuf;
unsigned char* e2a;
struct
{
int fixed;
} truncate;
};
#define SWAP_be 0
/*
* lazy flat field retrieval
*/
static Cxoperand_t*
{
register Member_t* w;
register Member_t* p;
register Member_t* y;
register Field_t* f;
register unsigned char* s;
register unsigned char* t;
register unsigned char* u;
register unsigned char* e;
register unsigned char* h;
unsigned char* g;
unsigned char* m;
Record_t* b;
Cxoperand_t* v;
Key_t* k;
Cxoperand_t a;
int c;
int d;
int q;
int x;
size_t n;
return &nullret;
{
{
{
goto empty;
{
r = b;
}
}
else if (b->buf)
r = b;
}
{
s = (unsigned char*)r->cur;
{
y = w;
y--;
}
else
{
}
{
f = p->field;
if (d >= 0)
{
if (f->width)
{
goto empty;
}
{
for (t = s; t < e && *t != d; t++);
n = t - s;
t++;
}
else
{
if ((s + 1) >= e || *s != q)
{
n = 1;
q = -1;
}
else
{
s++;
n = 0;
}
for (u = t = s; t < e; t++)
{
if ((c = *t) == x)
{
if (++t >= e)
{
(*r->dss->disc->errorf)(r->dss, r->dss->disc, 2, "%sinvalid escape", cxlocation(r->cx, r->record), p->field->variable.name);
goto empty;
}
c = *t;
}
else if (n)
{
if (c == d || c == flat->terminator)
break;
if (c == q)
{
n = 0;
continue;
}
}
else if (c == q)
{
if (x >= 0 || (t + 1) >= e || *(t + 1) != c)
{
n = 1;
continue;
}
t++;
}
if (u < t)
{
/*
* modify a copy of the input record image
*/
{
s = h + (s - (unsigned char*)r->buf);
t = h + (t - (unsigned char*)r->buf);
u = h + (u - (unsigned char*)r->buf);
e = h + r->siz;
r->buf = (char*)h;
}
*u = c;
}
u++;
}
if (!n)
{
(*r->dss->disc->errorf)(r->dss, r->dss->disc, 2, "%s%s: unterminated quote", cxlocation(r->cx, r->record), p->field->variable.name);
goto empty;
}
n = u - s;
t++;
}
if (d == '\n' && n > 0 && *(s + n - 1) == '\r')
n--;
while (t < e && *t == d)
t++;
}
else
{
if (f->width)
{
goto empty;
}
n = e - s;
else
t = s + n;
}
p->siz = n;
s = t;
}
goto empty;
r->cur = (char*)s;
}
goto empty;
{
{
s = (unsigned char*)r->cur;
while (s < e)
{
t = s;
for (;;)
{
for (; s < e && *s != d; s++);
break;
for (h = s; h < e && *h == d; h++);
if (h >= e)
break;
{
break;
}
s = h;
}
if (t > u && s > t)
{
{
while (t < s && isspace(*++t));
for (u = s++; u > t && isspace(*(u - 1)); u--);
do
{
{
p->siz = u - t;
break;
}
} while (k = k->next);
if (p == w)
break;
continue;
}
(*r->dss->disc->errorf)(r->dss, r->dss->disc, 2, "%s%-.*s: unknown key", cxlocation(r->cx, r->record), t - u, u);
}
for (t = s++; t > u && isspace(*(t - 1)); t--);
}
r->cur = (char*)s;
{
{
w->off = 0;
goto found;
}
goto empty;
}
}
}
{
goto empty;
{
(*r->dss->disc->errorf)(r->dss, r->dss->disc, 1, "%s%s: variable field width %d exceeds fixed maximum %d -- maximum assumed", cxlocation(r->cx, r->record), w->field->variable.name, n, w->field->physical.format.width);
}
else
{
w->siz = n;
else
{
{
(++y)->off = n;
break;
}
}
}
}
if ((*w->field->physical.type->internalf)(r->cx, w->field->physical.type, NiL, &w->field->physical.format, &w->ret, (char*)s, w->siz, r->cx->rm, r->cx->disc) < 0)
{
{
}
else
}
if (w->ret.type->generic[x]->base == w->field->physical.type || w->ret.type->generic[x]->base == w->field->physical.type->base)
{
break;
}
}
return &w->ret;
}
/*
* lazy flat field retrieval for aligned binary data
*/
static Cxoperand_t*
{
register char* s;
{
{
break;
break;
break;
#if _typ_int64_t
break;
#endif
break;
break;
break;
#if _typ_int64_t
break;
#endif
break;
break;
#ifdef _ast_flt12_t
break;
#endif
#ifdef _ast_flt16_t
break;
#endif
default:
w->ret.value.string.size = (s = memchr(w->ret.value.string.data = r->buf + w->off, 0, w->siz)) ? (s - (r->buf + w->off)) : w->siz;
else
break;
}
}
return &w->ret;
}
/*
* flat identf
*/
static int
{
register unsigned char* s;
register unsigned char* e;
int i;
int swap;
unsigned long num;
return 1;
{
if (n < sizeof(Magicid_t))
return 0;
return 0;
if (swap)
{
}
return 0;
return 0;
return 0;
while (s < e)
if (*s++)
return 0;
{
(*disc->errorf)(NiL, disc, 2, "%s: data size %d does not match schema size %d", file->path, magicid->size, flat->fixed);
return -1;
}
{
(*disc->errorf)(NiL, disc, 2, "%s: data version %s is newer than schema version %s", file->path, fmtversion(magicid->size), fmtversion(flat->fixed));
return -1;
}
return 1;
}
return 0;
{
{
return 1;
}
}
else
{
while (i-- > 0)
{
num >>= 8;
}
{
return 1;
}
}
return 0;
}
/*
*/
static ssize_t
{
register char* b;
register char* s;
register char* e;
register ssize_t n;
if (!z->width)
return z->reserve;
s = b + z->offset;
switch (z->type)
{
case 'a':
break;
case 'b':
break;
case 'd':
n = 0;
for (e = s + z->width; s < e; s++)
n = n * 100 + 10 * (*(unsigned char*)s >> 4) + (*s & 0xf);
if (z->base & 1)
n /= 10;
break;
case 'e':
break;
case 'l':
break;
case 'm':
break;
}
if (z->add)
return n;
}
/*
* flat readf
*/
static int
{
register char* s;
register ssize_t i;
size_t j;
size_t k;
size_t m;
Field_t* f;
Field_t* p;
for (;;)
{
if (!++r->serial)
{
r->serial = 1;
r->copy = 0;
for (i = 0; i < r->nfields; i++)
{
/*
* if the first record doesn't have a terminator
* then we ignore the terminator for all records;
* only string fields are checked
*/
{
for (k = 0;; k++)
{
if (k >= j)
{
break;
}
if (k >= m)
{
if (f = f->next)
else
{
if (s[k] != flat->terminator)
break;
}
}
break;
}
}
else
if (flat->terminator >= 0)
{
{
return -1;
}
k = 0;
{
while (k < m)
}
}
else
{
}
}
}
if (flat->terminator >= 0)
{
if (flat->continuator >= 0)
{
break;
{
for (;;)
{
goto eof;
{
break;
}
}
}
}
else
{
break;
}
{
k = r->nfields;
{
(*disc->errorf)(NiL, disc, 2, "%sinvalid record length %d -- record ignored", cxlocation(r->cx, record), i);
continue;
}
{
p = f;
while (p = p->next)
}
else
k = r->nfields;
}
r->index = 0;
}
{
break;
if (!(s = (char*)sfreserve(file->io, i, flat->variable)) && (!flat->variable || !(i = sfvalue(file->io)) || !(s = (char*)sfreserve(file->io, i, flat->variable))))
break;
}
else
{
(*disc->errorf)(NiL, disc, 2, "%snon-unique terminator record read not implemented", cxlocation(r->cx, record));
return -1;
}
r->siz = i;
{
for (j = 0; j < r->nfields; j++)
{
}
}
return 1;
}
eof:
(*disc->errorf)(NiL, disc, 2, "%slast record truncated (%ld/%ld)", cxlocation(r->cx, record), (long)sfvalue(file->io), (long)flat->fixed);
return 0;
}
/*
* flat writef
*/
static int
{
register Field_t* f;
register int i;
register unsigned char* s;
Cxoperand_t* v;
ssize_t n;
unsigned char* b;
unsigned char* e;
int q;
for (i = 0; i < r->nfields; i++)
{
v = (*f->flatgetf)(r, i);
while ((n = (*f->physical.type->externalf)(r->cx, f->physical.type, NiL, &f->physical.format, &v->value, flat->valbuf, flat->valsiz, r->cx->disc)) > flat->valsiz)
{
n = roundof(n, 32);
{
return -1;
}
}
if (n < 0)
return -1;
else if (n > 0)
{
if ((f->physical.format.flags & (CX_STRING|CX_BUFFER)) && f->physical.format.delimiter >= 0 && (f->physical.format.escape >= 0 || f->physical.format.quotebegin >= 0))
{
{
q = 1;
}
else
q = 0;
if (*s == f->physical.format.delimiter || *s == f->physical.format.escape || *s == f->physical.format.quotebegin || *s == f->physical.format.quoteend)
{
{
}
{
if (q)
continue;
q = 1;
}
else
{
if (!q)
{
q = 1;
}
}
b = s + 1;
}
{
q = 0;
}
if (q)
}
else
}
}
return 0;
}
/*
* skip file sections in s
*/
static int
{
register size_t i;
register char* t;
register char* u;
int code;
for (; s; s = s->next)
{
i = s->count;
do
{
if (s->delimiter >= 0)
{
goto eof;
}
else if (s->size > 0)
{
goto eof;
}
else
break;
{
if (code != REG_NOMATCH)
{
{
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%s: %s: regular expression: %s", file->path, section, buf);
}
return -1;
}
break;
}
} while (!i || --i);
}
return 0;
eof:
return -1;
}
static int
{
register unsigned char* a = (unsigned char*)va;
register unsigned char* b = (unsigned char*)vb;
register int c;
register int d;
while (!(d = (c = *a++) - (int)*b++))
if (!(t ? t[c] : c))
return 0;
return (!*(b - 1) && !(t ? t[c] : c)) ? 0 : d;
}
/*
* allocate and initialize a Table_t
*/
static Table_t*
{
register Table_t* t;
{
return 0;
}
{
return 0;
}
t->span = -1;
return t;
}
static Cxexpr_t*
{
void* pop;
return 0;
return expr;
}
/*
* final dictionary table initialization
*/
static int
{
register char* s;
register Key_t* k;
register Key_t* q;
register int i;
if (!tab->identified)
{
for (i = 0; i <= UCHAR_MAX; i++)
{
if (isalpha(i) || i == '_')
}
}
for (q = k; q; q = q->next)
{
{
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%s: %s: %s: cannot compile key qualification expression", q->field->variable.name, q->name, q->qualification);
return -1;
}
s = q->name;
while (*++s)
}
return 0;
}
/*
* allocate and initialize a Record_t
*/
static Record_t*
recinit(register Flat_t* flat, Dssfile_t* file, Record_t* b, Table_t* t, Field_t* fields, size_t n, size_t i, Dssdisc_t* disc)
{
register Field_t* f;
register Record_t* r;
register Key_t* k;
if (!fields)
return 0;
if (!n)
break;
{
return 0;
}
r->offset = i;
r->serial--;
r->nfields = n + i;
r->kfields = n + i + 1;
if (t && !t->qualified)
{
t->qualified = 1;
if (k->next && !k->qualification)
error(1, "%s: %s: field key is ambiguous -- qualification required", k->field->variable.name, k->name);
}
off = 0;
{
if (f->structure.members && !f->record && !(f->record = recinit(flat, file, r, f->table, f->next, 0, i + 1, disc)))
return 0;
{
r->kfields = i;
}
if (level == 1)
{
{
{
{
}
{
}
}
off++;
}
}
}
if (r->kfields <= r->nfields && (!(r->table = t) && !(r->table = tabinit(flat, disc)) || tabcomp(flat, r->table, disc)))
return 0;
return r;
}
/*
* flat fopenf
*/
static int
{
size_t i;
{
#if 0
if (file->ident)
goto noswap;
#endif
#if 0
{
char* s;
}
#endif
{
return -1;
}
return -1;
}
if (!(file->data = flat->root.record = recinit(flat, file, NiL, flat->root.table, flat->fields, flat->nfields, 0, disc)))
return -1;
{
goto noswap;
{
{
}
i -= sizeof(magicid);
}
else
{
else
{
union
{
#if _typ_int64_t
#endif
} num;
{
case 1:
break;
case 2:
break;
case 4:
break;
#if _typ_int64_t
case 8:
break;
#endif
}
}
}
while (i-- > 0)
{
return -1;
}
}
return 0;
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%s: binary record data swap not implemented yet", file->path);
return -1;
}
/*
* flat fclosef
*/
static int
{
return -1;
return 0;
}
{
"flat",
"flat format (2010-11-10)",
CXH,
0,
0,
0,
0
};
static int
op_get(Cx_t* cx, Cxinstruction_t* pc, Cxoperand_t* r, Cxoperand_t* a, Cxoperand_t* b, void* data, Cxdisc_t* disc)
{
#if __APPLE__
Cxoperand_t* x;
#else
#endif
return 0;
}
{
};
static int
{
{
return -1;
}
return 0;
}
static int
{
{
return -1;
}
return 0;
}
static int
{
{
return -1;
}
return 0;
}
static int
{
return -1;
return 0;
}
static int
{
return 0;
}
static int
{
char* s;
Cxtype_t* t;
if (!*s)
t = (Cxtype_t*)"number";
{
return -1;
}
{
}
{
if (streq(s, "string"))
else if (streq(s, "buffer"))
}
else
return 0;
}
static int
{
return 0;
}
static int
{
else
return 0;
}
static int
{
return 0;
}
static int
{
return 0;
}
static int
{
return 0;
}
static int
{
else
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
static int
{
char* e;
{
if (*e)
{
return -1;
}
}
{
return -1;
}
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
static int
{
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
static int
{
{
return -1;
}
return 0;
}
static int
{
return 0;
}
static int
{
char* e;
{
if (*e)
{
return -1;
}
}
{
return -1;
}
return 0;
}
{
"SIZE", "Fixed array size or variable size field name.",
0,0,flat_array_size_dat,0,
"PHYSICAL", "Physical (file representation) details; the"
" remaining tags may appear inside <PHYSICAL>."
" Outside of <PHYSICAL> the tags provide logical"
" (print representation) details. Logical details"
" are used as physical defaults.",
"DELIMITER", "Array value delimiter character.",
0,0,flat_array_delimiter_dat,0,
0
};
static Tags_t*
{
if (name)
{
if (!flat->lastfield->physical.array && !(flat->lastfield->physical.array = newof(0, Cxarray_t, 1, 0)))
{
return 0;
}
}
return &tags_array[2];
}
static int
{
return 0;
}
static Tags_t*
{
if (name)
{
if (!flat->lastfield->variable.array && !(flat->lastfield->variable.array = newof(0, Cxarray_t, 1, 0)))
{
return 0;
}
}
return &tags_array[0];
}
static Key_t*
{
{
return 0;
}
else
{
{
if (!old->qualification)
error(1, "%s: %s: field key is ambiguous -- qualification required", old->field->variable.name, key->name);
}
}
return key;
}
static int
{
{
return -1;
}
return -1;
return 0;
}
static int
{
{
return -1;
}
{
return -1;
}
return 0;
}
static int
{
register int c;
register int d;
register char* t;
char* e;
regclass_t f;
char m;
while (c = *s++)
{
if (*s == '[')
{
switch (*(s + 1))
{
case ':':
if (f = regclass(s + 1, &e))
{
s = (const char*)e;
for (c = 0; c <= UCHAR_MAX; c++)
if ((*f)(c))
continue;
}
return -1;
case '.':
case '=':
{
s = (const char*)e;
continue;
}
return -1;
}
}
if (*s == '-' && (d = *(s + 1)))
{
s += 2;
if (c == 'A' && d == 'Z')
t = "BCDEFGHIJKLMNOPQRSTUVWXYZ";
else if (c == 'a' && d == 'z')
t = "bcdefghijklmnopqrstuvwxyz";
else if (c == '0' && d == '9')
t = "123456789";
else
{
while (++c <= d)
continue;
}
while (c = *t++)
}
}
return 0;
}
static Table_t*
{
Field_t* p;
if (!p->table)
return p->table;
}
static int
{
}
static int
{
}
static int
{
return 0;
}
static int
{
return 0;
}
{
"NAME", "Key name.",
0,0,flat_field_key_name_dat,0,
"QUALIFICATION","Key qualification expression; the key is active"
" for the current record when the expression evaluates"
" non-zero. Used to disambiguate conflicting key"
" names. Why design data with conflicts?",
"ID1", "Characters that may appear anywhere in key names,"
" interpreted as the contents of an RE character"
" class. The default is \b[:alpha:]_\b.",
0,0,flat_field_key_id1_dat,0,
"ID2", "Characters that may appear after the first character"
" in key names, interpreted as the contents of an RE"
" character class. The default is"
" \b[:alnum:]_.,-\b.",
0,0,flat_field_key_id2_dat,0,
"SPAN", "The value is the key assignment character. If set"
" then key values may span the field separator"
" character up to the end of record or the next"
" \akey\a\aspan\a\avalue\a. Such data is fraught with"
" ambiguities. One must suppose that it never occurred"
" to the writers that the data would someday be read.",
0,0,flat_field_key_span_dat,0,
"UNKNOWN", "Span unknown but otherwise syntactically correct"
" keys.",
0,0,flat_field_key_unknown_dat,0,
0
};
static Tags_t*
{
if (name && !((Field_t*)flat->lastfield->structure.parent)->table && !(((Field_t*)flat->lastfield->structure.parent)->table = tabinit(flat, (Dssdisc_t*)disc)))
return 0;
return &tags_key[0];
}
static int
{
}
{
"NAME", "Field name.",
0,0,flat_field_name_dat,0,
"DESCRIPTION", "Field description.",
0,0,flat_field_description_dat,0,
"PHYSICAL", "Physical (file representation) details; the"
" remaining tags may appear inside <PHYSICAL>."
" Outside of <PHYSICAL> the tags provide logical"
" (print representation) details. Logical details"
" are used as physical defaults.",
"MAP", "Field value map;"
" either a map reference name or a map definition.",
"TYPE", "Field type. The intrinsic types are number and"
" string. Other types are defined in optional"
" method and schema libraries.",
0,0,flat_field_type_dat,0,
"DETAILS", "An optional type-specific comma-separated string"
" of name=value pairs.",
0,0,flat_field_details_dat,0,
"DELIMITER", "Field delimiter character.",
0,0,flat_field_delimiter_dat,0,
"MULTIPLE", "Multiple adjacent delimiters are equivalent to one.",
0,0,flat_field_multiple_dat,0,
0,0,flat_field_escape_dat,0,
"QUOTE", "Field quote begin and end character.",
0,0,flat_field_quotebegin_dat,0,
"QUOTEBEGIN", "Field quote begin character.",
0,0,flat_field_quotebegin_dat,0,
"QUOTEEND", "Field quote end character.",
0,0,flat_field_quoteend_dat,0,
"QUOTEALL", "Field quotes are the first and last characetrs.",
0,0,flat_field_quoteall_dat,0,
"CODESET", "Field codeset name; one of { native ascii ebcdic }.",
0,0,flat_field_codeset_dat,0,
"FIXEDPOINT", "Fixed point width.",
0,0,flat_field_fixedpoint_dat,0,
"WIDTH", "Field fixed width in bytes.",
0,0,flat_field_width_dat,0,
"REMAINDER", "Field is variable length up to the end of record.",
0,0,flat_field_remainder_dat,0,
"BASE", "Numeric field representation base.",
0,0,flat_field_base_dat,0,
"FILL", "Fixed width field fill character.",
0,0,flat_field_fill_dat,0,
"KEY", "name=value keyed field details. Keyed fields are"
" optional and may appear in any order after the"
" positional fields. All unknown keys and invalid"
" key data are passed to the key named \b*\b; if there"
" is no \b*\b key or if \b--verbose\b is on then an"
" error message is emitted for each occurrence. If"
" \b<SPAN>\b and \b<UNKNOWN>\b are enabled then"
" key messages are disabled.",
"CONSTRAINT", "Field value constraints. Constraints, when"
" enabled, are applied to each record as it is read.",
"ARRAY", "Array info.",
0,flat_array_beg,0,0,
"FIELD", "Field structure.",
0
};
static Tags_t*
{
if (name)
return &tags_flat_field[3];
}
static int
{
return 0;
}
static Tags_t*
{
Field_t* f;
Field_t* p;
Field_t* t;
if (name)
{
{
return 0;
}
{
}
else
{
{
else
}
else
{
}
}
else
}
return &tags_flat_field[0];
}
static int
{
{
return -1;
}
return 0;
}
static int
{
{
case 'a':
case 'b':
case 'd':
case 'e':
case 'l':
case 'm':
break;
default:
return -1;
}
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
{
"TYPE", "Size field physical type. The types are:"
" ascii - ascii text digits,"
" be_t - big endian binary,"
" ebcdic - ebcdic text digits,"
" le_t - little endian binary,"
" magic - binary with same byte order as the"
" header magic number.",
0,0,flat_size_type_dat,0,
"WIDTH", "Size field width in bytes.",
0,0,flat_size_width_dat,0,
"OFFSET", "Size field offset in bytes.",
0,0,flat_size_offset_dat,0,
"BASE", "Size field field representation base.",
0,0,flat_size_base_dat,0,
"SIZE", "Size field total width in bytes, <WIDTH>+<OFFSET>"
" by default. A + prefix specifies that the size"
" field total width must be added to the computed"
" size to determine the record length.",
0,0,flat_size_width_dat,0,
"FIXED", "Fixed record size.",
0,0,flat_size_fixed_dat,0,
0
};
static Tags_t*
{
Size_t* z;
if (name)
{
{
return 0;
}
if (*name == 'B')
else
}
return &tags_flat_size[0];
}
static int
{
if (z->size)
{
z->fixed = 0;
}
if (z->type == 'e')
{
{
return -1;
}
}
return 0;
}
static int
{
char* e;
if (*e && (*e != '*' || *(e + 1)))
{
return -1;
}
return 0;
}
static int
{
return 0;
}
static int
{
int code;
{
return -1;
}
{
{
}
return -1;
}
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
{
"COUNT", "Number of delimiters, patterns or sized blocks.",
0,0,flat_section_count_dat,0,
"DELIMITER", "Delimiter character.",
0,0,flat_section_delimiter_dat,0,
"PATTERN", "Regular expression; ignored if"
" delimiter or size specified.",
0,0,flat_section_pattern_dat,0,
"SIZE", "Fixed size in bytes.",
0,0,flat_section_size_dat,0,
0
};
static Tags_t*
{
Section_t* s;
if (name)
{
{
return 0;
}
s->count = 1;
s->delimiter = -1;
if (!flat->lastheader)
else
}
return &tags_flat_section[0];
}
static Tags_t*
{
Section_t* s;
if (name)
{
{
return 0;
}
s->count = 1;
s->delimiter = -1;
if (!flat->lasttrailer)
else
}
return &tags_flat_section[0];
}
static int
{
{
return -1;
}
return 0;
}
static int
{
{
return -1;
}
return 0;
}
static int
{
{
return -1;
}
return 0;
}
static int
{
register Library_t* p;
{
return -1;
}
if (!flat->lastlibrary)
else
return 0;
}
static int
{
{
return -1;
}
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
{
"none", SWAP_none,
"native", SWAP_native,
"be", SWAP_be,
"le", SWAP_le,
};
static int
{
register Value_t* v;
char* e;
{
break;
}
{
if (*e)
{
return -1;
}
}
return 0;
}
static int
{
char* e;
if (*e)
{
return -1;
}
return 0;
}
{
"STRING", "Magic string value.",
0,0,flat_magic_string_dat,0,
"NUMBER", "Magic number value.",
0,0,flat_magic_number_dat,0,
0,0,flat_magic_size_dat,0,
"SIZE", "Magic header size in bytes. If omitted then an AST"
"magic header is assumed.",
0,0,flat_magic_size_dat,0,
"SWAP", "Magic header binary field swap operation:"
" native - native byte order (default),"
" be - big endian swap,"
" le - little endian swap,"
" 1|2|4 - swap OR of 1:bytes 2:shorts 4:ints.",
0,0,flat_magic_swap_dat,0,
"VERSION", "Magic version stamp, either YYYYMMDD or 0xWWXXYYZZ.",
0,0,flat_magic_version_dat,0,
0
};
static Tags_t*
{
{
return 0;
}
return &tags_flat_magic[0];
}
static int
{
{
{
(*disc->errorf)(NiL, disc, 2, "magic header size %u is smaller than string/number length %u", flat->magic->size, flat->magic->length);
return -1;
}
if (!flat->magic->string && (flat->magic->length > 4 || (flat->magic->length & (flat->magic->length - 1))))
{
(*disc->errorf)(NiL, disc, 2, "magic number length %u must be a power of 2 less than or equal to 4", flat->magic->length);
return -1;
}
}
return 0;
}
static int
{
register Value_t* v;
char* e;
{
break;
}
{
if (*e)
{
return -1;
}
}
return 0;
}
static int
{
{
return -1;
}
return 0;
}
static int
{
return 0;
}
static int
{
return 0;
}
static int
{
return 0;
}
static int
{
return 0;
}
static int
{
return 0;
}
static int
{
else
return 0;
}
static int
{
else
return 0;
}
static int
{
{
return -1;
}
return 0;
}
static int
{
return 0;
}
{
"ID1", "Characters that may appear anywhere in key names,"
" interpreted as the contents of an RE character"
" class. The default is \b[:alpha:]_\b.",
0,0,flat_field_key_id1_dat,0,
"ID2", "Characters that may appear after the first character"
" in key names, interpreted as the contents of an RE"
" character class. The default is"
" \b[:alnum:]_.,-\b.",
0,0,flat_field_key_id2_dat,0,
"SPAN", "The value is the key assignment character. If set"
" then key values may span the field separator"
" character up to the end of record or the next"
" \akey\a\aspan\a\avalue\a. Such data is frought with"
" ambiguities. One must suppose that it never occurred"
" to the writers that the data would someday be read.",
0,0,flat_field_key_span_dat,0,
"UNKNOWN", "Span unknown but otherwise syntactically correct"
" keys.",
0,0,flat_field_key_unknown_dat,0,
0
};
static Tags_t*
{
return &tags_flat_physical_key[0];
}
{
"SWAP", "Binary record field swap operation:"
" none - don't swap (default),"
" native - swap to match the magic header NUMBER,"
" be - big endian swap,"
" le - little endian swap,"
" 1|2|4 - swap OR of 1:bytes 2:shorts 4:ints.",
0,0,flat_physical_swap_dat,0,
"DELIMITER", "Default field delimiter and continuation replacement"
" character.",
0,0,flat_physical_delimiter_dat,0,
0,0,flat_physical_escape_dat,0,
"QUOTE", "Default field quote begin and end character.",
0,0,flat_physical_quotebegin_dat,0,
"QUOTEBEGIN", "Default field quote begin character.",
0,0,flat_physical_quotebegin_dat,0,
"QUOTEEND", "Default field quote end character.",
0,0,flat_physical_quoteend_dat,0,
"QUOTEALL", "Field quotes are the first and last characetrs.",
0,0,flat_physical_quoteall_dat,0,
"MULTIPLE", "Multiple adjacent delimiters are equivalent to one.",
0,0,flat_physical_multiple_dat,0,
"CODESET", "Default records codeset name; one of { native ascii ebcdic }.",
0,0,flat_physical_codeset_dat,0,
"CONTINUE", "Terminator continuation (escape) character.",
0,0,flat_physical_continue_dat,0,
"TERMINATOR", "Default record termination character.",
0,0,flat_physical_terminator_dat,0,
"KEY", "Default field key attributes.",
0,flat_physical_key_beg,0,0,
};
static Tags_t*
{
return &tags_flat_physical[0];
}
{
"NAME", "Schema name.",
0,0,flat_name_dat,0,
"DESCRIPTION", "Schema description.",
0,0,flat_description_dat,0,
"IDENT", "Schema ident string.",
0,0,0,0,
" more than one library may be specified.",
0,0,flat_library_dat,0,
"MAGIC", "File magic number (identification header)"
" section definitions.",
"PRINT", "Default {print} query format.",
0,0,flat_print_dat,0,
"COMPRESS", "Preferred compression method; compression is applied"
" by the {compress} query.",
0,0,flat_compress_dat,0,
"HEADER", "File header section definitions.",
0,flat_header_beg,0,0,
"TRAILER", "File trailer section definitions.",
0,flat_trailer_beg,0,0,
"BLOCK", "Block size definitions.",
"RECORD", "Record size definitions; same as <BLOCK>.",
"PHYSICAL", "Default physical record and field attributes.",
0,flat_physical_beg,0,0,
"FIELD", "Schema field list.",
0
};
static Tags_t*
{
return &tags_flat[0];
}
{
"FLAT", "Flat method schema.",
0,flat_beg,0,0,
"MAP", "Field value map;"
" either a map reference name or a map definition.",
"METHOD", "Method name; must be flat.",
0,0,0,0,
0
};
/*
* outal rententive support
*/
static int
{
while (cur-- > 0)
return nxt;
}
/*
* fill in type and format defaults
*/
static void
{
register char* s;
format->flags |= type->format.flags & (CX_BINARY|CX_UNSIGNED|CX_INTEGER|CX_FLOAT|CX_STRING|CX_BUFFER);
{
else if (cxisstring(type))
else if (cxisbuffer(type))
else
{
{
s = details;
*s++ = '%';
*s++ = 'l';
*s++ = 'l';
{
default:
{
*s++ = '.';
*s++ = '.';
break;
}
/*FALLTHROUGH*/
case 0:
case 10:
break;
case 8:
*s++ = 'o';
break;
case 16:
*s++ = 'x';
break;
}
*s = 0;
}
}
}
}
/*
* methf
*/
extern Dsslib_t dss_lib_flat;
static Dssmeth_t*
flatmeth(const char* name, const char* options, const char* schema, Dssdisc_t* disc, Dssmeth_t* meth)
{
register Library_t* p;
register Field_t* f;
Field_t* g;
char* s;
ssize_t n;
int i;
int errors;
int fixed;
{
return 0;
}
flat->delimiter = flat->escape = flat->quotebegin = flat->quoteend = flat->terminator = flat->continuator = -1;
sp = 0;
if (options)
{
goto drop;
goto drop;
goto drop;
sp = 0;
for (;;)
{
{
case 'b':
continue;
case 'e':
continue;
case 'h':
case 'o':
case 's':
continue;
case 'p':
continue;
case 'T':
continue;
case '?':
goto drop;
case ':':
goto drop;
}
break;
}
}
{
return 0;
goto drop;
sp = 0;
goto invalid;
}
return 0;
for (i = 0; i < elementsof(local_callouts); i++)
return 0;
{
return 0;
{
return 0;
}
if (f->variable.array && (s = (char*)f->variable.array->variable) && !(f->variable.array->variable = (Cxvariable_t*)dtmatch(flat->meth.cx->variables, s)))
{
return 0;
}
{
return 0;
}
f->physical.format.flags |= f->variable.format.flags & (CX_BINARY|CX_UNSIGNED|CX_INTEGER|CX_FLOAT|CX_STRING|CX_BUFFER|CX_NUL);
{
}
}
if (flat->terminator < 0)
{
return 0;
}
errors = 0;
fixed = 1;
{
{
{
f->structref = 1;
continue;
}
errors++;
}
{
#if 0
/*OK*/;
#endif
continue;
}
{
}
{
if (f->width)
}
else
fixed = 0;
}
if (errors)
return 0;
{
return 0;
}
{
{
{
{
g = f;
while (g = g->next)
if (n > 0)
{
(*disc->errorf)(NiL, disc, 1, "%s: maximum variable field size shortened from %d to %d to comply with fixed record size %d", f->variable.name, f->physical.format.width, n, flat->record->reserve);
}
break;
}
}
}
}
else if (!fixed)
{
}
drop:
if (sp)
return 0;
}
/*
* openf
*/
static int
{
register Field_t* f;
register Cxvariable_t* v;
char* a;
char* s;
char* p;
char* t;
char* u;
int offset;
int fixed;
int pad;
int m;
int n;
if (flat)
{
{
{
}
}
{
case 'h':
{
return -1;
}
p = a;
*a++ = isalnum(*s) ? *s : '_';
*a++ = 0;
if (!isalpha(*p))
*p = '_';
t = a;
*a++ = 0;
if (islower(*t))
*t = toupper(*t);
u = a;
for (s = p; *s; s++)
*a = 0;
{
continue;
{
}
else
if (f->variable.description)
{
}
else
{
sfprintf(sfstdout, "((*_%s_record_->getf)(_%s_record_,%d)->%s.size)\n", p, p, f->variable.index, a);
}
}
break;
case 'o':
{
return -1;
}
/* HERE: under construction */
offset = 0;
pad = 0;
{
{
continue;
}
a = p = s = "";
m = 1;
n = 0;
{
{
}
else
p = "*";
}
{
}
{
else
}
else
{
else
{
}
{
s = "(MISALIGNED) ";
(*disc->errorf)(NiL, disc, 1, "%s: field size %u offset %u is not aligned", f->variable.name, f->physical.format.width, offset);
}
}
{
offset += 1;
tmp[1] = 0;
}
{
v = &f->variable;
if (v->structure)
{
if (v->array)
{
{
}
else
}
else
}
}
}
{
(*disc->errorf)(NiL, disc, 1, "%s: record has %u unused pad byte%s", flat->meth.name, fixed, fixed == 1 ? "" : "s");
}
break;
case 's':
{
return -1;
}
{
break;
}
offset = 0;
pad = 0;
{
{
continue;
}
a = p = s = "";
m = 1;
n = 0;
{
{
}
else
p = "*";
}
else
{
}
{
else
}
else
{
else
{
}
{
s = "(MISALIGNED) ";
(*disc->errorf)(NiL, disc, 1, "%s: field size %u offset %u is not aligned", f->variable.name, f->physical.format.width, offset);
}
}
if (*s || f->variable.description)
{
}
else
{
offset += 1;
tmp[1] = 0;
}
{
v = &f->variable;
if (v->structure)
{
if (v->array)
{
{
}
else
}
else
}
}
}
{
(*disc->errorf)(NiL, disc, 1, "%s: record has %u unused pad byte%s", flat->meth.name, fixed, fixed == 1 ? "" : "s");
}
sfprintf(sfstdout, "/* sizeof(struct _%s_%s_s)==%u */\n", flat->basemeth->name, flat->meth.name, offset);
break;
}
exit(0);
{
offset = 0;
{
if ((f->variable.format.flags & CX_BINARY) && ((offset % f->physical.format.width) || (f->physical.format.width & (f->physical.format.width - 1)) || f->physical.format.width > 8) || f->width)
break;
}
if (!f && !(offset % 8))
}
{
return -1;
}
}
return 0;
}
{
"flat",
CXH,
0,
0,
0,
0,
0,
0,
0,
};
static const char flatten_usage[] =
"[-1ls5P?\n@(#)$Id: dss flatten query (AT&T Research) 2005-05-09 $\n]"
"[+PLUGIN?\findex\f]"
"[+DESCRIPTION?Flatten input data to match flat method \bschema\b.]"
"[e:emptyspace?Write empty field values as one \bspace\b character.]"
"\n"
"\nschema\n"
"\n"
;
/*
* get source field value
*/
static Cxvalue_t*
{
{
return &nullval;
{
return &nullval;
}
}
else
{
return &nullval;
}
}
/*
* flattenget() with cxnum2str()
*/
static Cxvalue_t*
{
{
return &nullval;
}
return val;
}
/*
* flattenget() with cxstr2num()
*/
static Cxvalue_t*
{
Cxunsigned_t u;
{
return &nullval;
}
return val;
}
/*
* get nullval field value
*/
static Cxvalue_t*
{
return &nullval;
}
/*
* flatten query begin
*/
static int
{
int emptyspace = 0;
char* schema;
Field_t* f;
Field_t* g;
int offset;
int fixed;
for (;;)
{
{
case 'e':
emptyspace = 1;
continue;
case '?':
continue;
case ':':
continue;
}
break;
}
return -1;
{
return -1;
}
{
if (vm)
return -1;
}
#if _HUH_2010_05_28
#endif
{
goto bad;
}
if (!flatten->cx->getf && !(flatten->cx->getf = cxcallout(flatten->cx, CX_GET, flatten->cx->state->type_void, flatten->cx->state->type_void, flatten->cx->disc)))
{
goto bad;
}
offset = 0;
{
f->flattengetf = flattenget;
{
f->flattengetf = flattennull;
(*disc->errorf)(NiL, disc, 1, "%s: field not in source record -- default value will be output", f->variable.name);
}
{
f->flattengetf = flattenstr2num;
f->flattengetf = flattennum2str;
}
if ((g = (Field_t*)dtmatch(cx->variables, f->variable.name)) && g->physical.format.code != f->physical.format.code && g->physical.format.code == CC_NATIVE)
{
(*disc->errorf)(NiL, disc, 2, "%s: field size %u offset %u is not aligned", f->variable.name, f->physical.format.width, offset);
goto bad;
}
}
{
(*disc->errorf)(NiL, disc, 2, "%s: record has %u unused pad byte%s", flatten->dss->meth->name, offset, offset == 1 ? "" : "s");
goto bad;
}
goto bad;
return 0;
bad:
return -1;
}
/*
* flatten query action
*/
static int
{
register Field_t* f;
register unsigned char* s;
Cxvalue_t* v;
unsigned char* b;
unsigned char* e;
ssize_t n;
int q;
{
while ((n = (*f->physical.type->externalf)(flatten->cx, f->physical.type, NiL, &f->physical.format, v, flatten->flat->valbuf, flatten->flat->valsiz, disc)) > flatten->flat->valsiz)
{
n = roundof(n, 32);
{
return -1;
}
}
if (n < 0)
return -1;
else if (n > 0)
{
if (f->pam)
if ((f->physical.format.flags & (CX_STRING|CX_BUFFER)) && f->physical.format.delimiter >= 0 && (f->physical.format.escape >= 0 || f->physical.format.quotebegin >= 0))
{
{
q = 1;
}
else
q = 0;
if (*s == f->physical.format.delimiter || *s == f->physical.format.escape || *s == f->physical.format.quotebegin || *s == f->physical.format.quoteend)
{
{
}
{
if (q)
continue;
q = 1;
}
else
{
if (!q)
{
q = 1;
}
}
b = s + 1;
}
{
q = 0;
}
if (q)
}
else
}
}
return 0;
}
/*
* flatten query end
*/
static int
{
int r;
if (!flatten)
return -1;
r = 0;
r = -1;
r = -1;
return r;
}
{
{ "flatten", "query to flatten input data to flat schema format",
{0}
};
{
"flat",
"flat method"
"[-1ls5Pp0?\n@(#)$Id: dss flat method (AT&T Research) 2011-08-19 $\n]"
CXH,
0,
&method,
0,
0,
0,
0,
&queries[0],
};