/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 2002-2011 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
/*
* properly nested xml tag parse implementation
* name=value args are treated as tag members
*
* for these exrta-xml extensions data is literal (no &element; expansions)
*
* <#INCLUDE#>file</>
* include file; the file name is the remainder of line
* with leading and trailing space ignored
*
* <#TABLE#>
* read table data from following lines in the current file
* data is split into header and data sections, each section
* terminated by a blank line or EOF
* the first line of the header section defines the table tag
* names and the data delimiter; only one delimiter is
* supported; <#INCLUDE#> may appear in the first section
* NOTE: the blank lines are non-negotiable
* for example:
*
* <!- external header and table -!>
* <#TABLE#>
* <#INCLUDE#>file</>
*
* <!- inline header external table -!>
* <#TABLE#>
* NAME:TYPE:VALUE
* zero or more comment lines ignored
* <#INCLUDE#>file</>
*
* <!- inline header and table -!>
* <#TABLE#>
* NAME:TYPE:VALUE
* zero or more comment lines ignored
*
* foo:integer:1
* bar:double:2.3
*
* <!- end of inline data -!>
*/
#define _TAG_PRIVATE_ \
#define _TAG_FRAME_PRIVATE_ \
#include <ast.h>
#include <tag.h>
#include <ccode.h>
#include <ctype.h>
#include <error.h>
struct Column_s
{
};
struct Hit_s
{
};
struct Include_s
{
long line;
char* file;
};
/*
* return the current tag stack context
*/
char*
{
char* s;
if (!fp)
return "";
return "<?>";
{
}
do
{
s = "out of space";
return s;
}
/*
* include file pop exception handler
*/
static int
{
switch (op)
{
case SF_CLOSING:
case SF_DPOP:
case SF_FINAL:
if (op != SF_CLOSING)
{
}
break;
}
return 0;
}
/*
* parse include file name and push on the input stack
*/
static int
{
char* file;
char* path;
while (isspace(*s))
s++;
file = s;
s -= 2;
else if (!isspace(*s))
break;
*(s + 1) = 0;
if (!*file)
{
return -1;
}
{
return -1;
}
{
return -1;
}
{
return -1;
}
error_info.line = 0;
{
if (sp)
return -1;
}
return 0;
}
/*
* file include builtin
*/
static int
{
register char* s;
{
return -1;
}
error_info.line++;
}
/*
* get next line with optional embedded <#INCLUDE#>
*/
static char*
{
register char* s;
*inc = 0;
for (;;)
{
{
break;
}
error_info.line++;
while (isspace(*s))
s++;
if (*s != '<')
return s;
{
}
break;
*inc = 1;
}
return 0;
}
/*
* table data builtin
*/
static int
{
register char* s;
register char* b;
Column_t* p;
int del;
int inc;
int ret;
int sep;
ret = -1;
{
error_info.line++;
goto done;
for (b = s; isalnum(*b); b++);
if (!(del = *b))
{
goto done;
}
if (b == s)
s++;
while (*s)
{
for (b = s; *s && *s != del; s++);
{
return -1;
}
if (*s)
*s++ = 0;
{
goto done;
}
if (end)
else
}
do
{
goto done;
if (!*s)
{
goto done;
break;
}
} while (!inc);
sep = 0;
do
{
if (!*s)
{
ret = 0;
goto done;
}
if (sep)
{
return -1;
return -1;
}
else
sep = 1;
{
for (b = s; *s && *s != del; s++);
if (*s)
*s++ = 0;
goto done;
goto done;
goto done;
}
if (p)
{
goto done;
}
if (*s)
{
goto done;
}
error_info.line++;
}
done:
{
}
return ret;
}
{
"#INCLUDE#", "Push a tag include file.",
0,(Tagbeg_f)include,0,0,
"#TABLE#", "Read delimited table data.",
0,
};
/*
* parse a nested tag
*/
static int
{
register int c;
register int item;
register int quote;
register long back;
register char* s;
register char* t;
register char* u;
long keep_first;
long keep_last;
char* v;
item = 0;
keep_first = keep_last = 0;
if (fp)
for (;;)
{
{
case EOF:
break;
case '<':
if (item == '&')
item = 0;
if (!item)
{
{
goto nospace;
u = s + keep_last;
*t = 0;
if (keep_first)
else
while (*s && isspace(*s))
s++;
return -1;
back = 0;
}
else
if (fp)
keep_first = keep_last = 0;
item = c;
attrs = 0;
quote = 0;
{
if (c == '!')
}
}
else
continue;
case '>':
{
item = 0;
goto nospace;
else if (*s == '/')
{
s++;
if (!fp)
return -1;
{
return -1;
}
fp = 0;
break;
}
else if (!tags)
{
return -1;
}
else
{
break;
{
break;
{
return -1;
}
return -1;
continue;
}
np = 0;
return -1;
else if (attrs)
{
/*UNDENT...*/
while (*(t = s))
{
while (*s && !isspace(*s) && *s != '=')
s++;
if (*s == '=')
{
*s++ = 0;
u = v = s;
c = 0;
while (*s)
{
if (*s == c)
{
c = 0;
s++;
}
else if (c)
*u++ = *s++;
else if (*s == '"')
c = *s++;
else if (isspace(*s))
{
*s++ = 0;
break;
}
else
*u++ = *s++;
}
*u = 0;
}
else
{
v = "1";
if (*s)
*s++ = 0;
}
break;
{
return -1;
}
return -1;
return -1;
return -1;
}
/*...INDENT*/
}
{
error_info.indent++;
}
{
error_info.indent--;
}
if (c)
return -1;
return -1;
}
}
else
continue;
case '"':
if (item == '<')
continue;
case '&':
if (!item)
{
item = c;
}
continue;
case ';':
if (item == '&')
{
item = 0;
if (*s == '#')
else
{
if (fp)
if (streq(s, "alert"))
c = CC_bel;
else if (streq(s, "amp"))
c = '&';
else if (streq(s, "backspace"))
c = '\b';
else if (streq(s, "escape"))
c = CC_esc;
else if (streq(s, "formfeed"))
c = '\f';
else if (streq(s, "lt"))
c = '<';
else if (streq(s, "gt"))
c = '>';
else if (streq(s, "newline"))
c = '\n';
else if (streq(s, "nul"))
c = 0;
else if (streq(s, "quot"))
c = '"';
else if (streq(s, "return"))
c = '\r';
else if (streq(s, "space"))
c = ' ';
else if (streq(s, "tab"))
c = '\t';
else if (streq(s, "vtab"))
c = CC_vt;
else
{
c = '?';
}
}
if (!keep_first)
continue;
}
else
continue;
case '\n':
error_info.line++;
/*FALLTHROUGH*/
case ' ':
case '\t':
case '\v':
case '=':
if (item == '&')
item = 0;
{
c = 0;
}
/*FALLTHROUGH*/
default:
continue;
}
break;
}
if (item)
{
return -1;
}
if (fp)
{
return -1;
}
return 0;
return -1;
}
/*
* open and parse nested tags in ip
*/
{
char* ofile;
int oline;
int r;
{
if (tag)
return 0;
}
if (r)
{
return 0;
}
return tag;
}
/*
* sync tagopen handle and return input stream
*/
{
}
/*
* close a tagopen handle
*/
int
{
if (!tag)
return -1;
return 0;
}
/*
* tagscan helper
*/
static int
scan(Tag_t* tag, Tagframe_t* fp, Tagscan_f visit, void* handle, register Tags_t* tags, Tagdisc_t* disc)
{
register int r;
unsigned int f;
{
f = 0;
{
{
f |= TAG_SCAN_rec|TAG_SCAN_rep;
break;
}
if (!f)
{
{
f |= TAG_SCAN_rep;
break;
}
if (!f)
{
{
return -1;
}
}
}
}
{
return r;
return r;
return r;
}
return r;
tags++;
}
return 0;
}
/*
* scan the tag tree
*/
int
{
int r;
{
return 0;
}
{
}
return r;
}
/*
* tagusage() helper
*/
static int
{
if (flags & TAG_SCAN_end)
{
return 0;
}
{
return -1;
}
if (flags & TAG_SCAN_beg)
return 0;
}
/*
* generate optget usage[] section in op
*/
int
{
}