/***********************************************************************
* *
* 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
/*
* C expression library
*
* common Cxformat_t type attribute parse
*
* Glenn Fowler
* AT&T Research
*/
#include "cxlib.h"
#include <ccode.h>
typedef struct Attribute_s
{
const char* name;
short flags;
short width;
short base;
short code;
} Attribute_t;
#define S(s) s,(sizeof(s)-1)
{
S("ascii"), 0, 0, 0, CC_ASCII,
S("ebcdic"), 0, 0, 0, CC_EBCDIC,
S("ebcdic_e"), 0, 0, 0, CC_EBCDIC_E,
S("ebcdic_i"), 0, 0, 0, CC_EBCDIC_I,
S("ebcdic_o"), 0, 0, 0, CC_EBCDIC_O,
S("native"), 0, 0, 0, CC_NATIVE,
};
/*
* parse attributes from s into f and return the type
* p!=0 set to the first char after the type or to the
* first unrecognized attribute if type==0
*/
{
register Attribute_t* a;
register const char* t;
char* e;
const char* b;
int n;
b = s;
for (;;)
{
while (*s == ':' || isspace(*s))
s++;
if (!*s)
break;
{
s = (const char*)e;
}
{
t = s + 5;
switch (*t++)
{
case 'a':
case 'A':
n = CC_ASCII;
break;
case 'e':
case 'E':
n = CC_EBCDIC_E;
break;
case 'i':
case 'I':
n = CC_EBCDIC_I;
break;
case 'o':
case 'O':
n = CC_EBCDIC_O;
break;
case 'n':
case 'N':
n = CC_NATIVE;
break;
default:
if (p)
*p = (char*)s;
return 0;
}
if (*t == '2')
t++;
switch (*t++)
{
case 'a':
case 'A':
break;
case 'e':
case 'E':
n = CCOP(n, CC_EBCDIC_E);
break;
case 'i':
case 'I':
n = CCOP(n, CC_EBCDIC_I);
break;
case 'o':
case 'O':
n = CCOP(n, CC_EBCDIC_O);
break;
case 'n':
case 'N':
break;
case ':':
break;
default:
if (p)
*p = (char*)s;
return 0;
}
s = t;
}
{
s = (const char*)e;
}
else
{
for (t = s; *t && *t != ':' && !isspace(*t); t++);
for (a = attributes;; a++)
{
goto last;
{
if (a->flags)
if (a->width)
if (a->base)
if (a->code >= 0)
break;
}
}
s = t;
}
}
last:
{
if (p)
*p = (char*)s;
}
else
{
if (*t)
{
if ((t - s) >= sizeof(buf))
{
if (p)
*p = (char*)s;
return 0;
}
buf[t - s] = 0;
e = buf;
}
else
e = (char*)s;
s = t;
else if (s != b)
if (p)
*p = (char*)s;
}
f->base = 0;
return type;
}