#include <ctype.h>
#include <stdio.h>
#include "asn-incl.h"
#include "asn1module.h"
#include "mem.h"
#include "snacc-util.h"
#include "oid.h"
#include "val-parser.h"
#define P_LOCALS\
char *startStr
#define SAVE_POS()\
startStr = *vStr;
#define RESTORE_POS()\
*vStr = startStr;
#define AT_EOF()\
(*vStr == eof)
#define FAIL()\
{\
if (*vStr > farthestPosG)\
farthestPosG = *vStr;\
RESTORE_POS();\
return FALSE;\
}
#define SUCCEED()\
return TRUE;
#define FATAL_ERR()\
parseValuesErrG = 1;
#define PRINT_ERR_LOC(m, vd)\
fprintf (stderr,"file \"%s\", line %d (or near): ", m->asn1SrcFileName, valLineNoG);
#define PRINT_VAL(vd)\
PrintValueDef (stderr, vd);
static ValueDefList *newValsG;
static int parseValuesErrG;
static unsigned long valLineNoG;
static char *farthestPosG;
char *StripComments PROTO ((char *asn1Str, int len));
Value *ParseValue PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char *valueNotation, int len));
Value *ParseValueInternal PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char **valueNotation, char *eof));
int ParseOidValue PROTO ((ModuleList *mods, Module *m, ValueDef *vd, Type *t, char **valueNotation, char *eof, Value **result));
void SkipWht PROTO ((char **vStr, char *eof));
int ParseIdentifier PROTO ((char **valueNotation, char *eof, char **result));
int ParseNum PROTO ((char **valueNotation, char *eof, char **result));
void AddNewValueDef PROTO ((ValueDefList *vdl, char *name, Value *value));
int
ParseValues PARAMS ((mods, m),
ModuleList *mods _AND_
Module *m)
{
ValueDef *v;
Value *pv;
newValsG = AsnListNew (sizeof (void*));
FOR_EACH_LIST_ELMT (v, m->valueDefs)
{
if (v->value->basicValue->choiceId == BASICVALUE_VALUENOTATION)
{
valLineNoG = v->value->lineNo;
pv = ParseValue (mods, m, v, v->value->type, v->value->basicValue->a.valueNotation->octs, v->value->basicValue->a.valueNotation->octetLen);
if (pv != NULL)
{
pv->lineNo = v->value->lineNo;
pv->type = v->value->type;
Free (v->value->basicValue->a.valueNotation->octs);
Free (v->value->basicValue->a.valueNotation);
Free (v->value->basicValue);
Free (v->value);
v->value = pv;
}
}
}
m->valueDefs = AsnListConcat (m->valueDefs, newValsG);
Free (newValsG);
return parseValuesErrG;
}
Value*
ParseValue PARAMS ((mods, m, vd, t, valueNotationStr, vnLen),
ModuleList *mods _AND_
Module *m _AND_
ValueDef *vd _AND_
Type *t _AND_
char *valueNotationStr _AND_
int vnLen)
{
char *vStr;
char *vStrOrig;
int vStrLen;
Value *retVal;
vStrOrig = vStr = StripComments (valueNotationStr, vnLen);
vStrLen = strlen (vStr);
retVal = ParseValueInternal (mods, m, vd, t, &vStr, (vStr + vStrLen));
free (vStrOrig);
return retVal;
}
Value*
ParseValueInternal PARAMS ((mods, m, vd, t, vStr, eof),
ModuleList *mods _AND_
Module *m _AND_
ValueDef *vd _AND_
Type *t _AND_
char **vStr _AND_
char *eof)
{
Type *dT;
Value *retVal;
int parseResult = FALSE;
dT = ParanoidGetType (t);
if (dT == NULL)
return NULL;
retVal = NULL;
switch (dT->basicType->choiceId)
{
case BASICTYPE_SEQUENCE:
case BASICTYPE_SET:
case BASICTYPE_CHOICE:
case BASICTYPE_SEQUENCEOF:
case BASICTYPE_SETOF:
break;
case BASICTYPE_SELECTION:
case BASICTYPE_COMPONENTSOF:
case BASICTYPE_ANYDEFINEDBY:
case BASICTYPE_UNKNOWN:
case BASICTYPE_ANY:
break;
case BASICTYPE_BOOLEAN:
break;
case BASICTYPE_INTEGER:
case BASICTYPE_ENUMERATED:
break;
case BASICTYPE_REAL:
break;
case BASICTYPE_BITSTRING:
break;
case BASICTYPE_NULL:
break;
case BASICTYPE_OCTETSTRING:
break;
case BASICTYPE_OID:
case BASICTYPE_MACROTYPE:
parseResult = ParseOidValue (mods, m, vd, t, vStr, eof, &retVal);
if (!parseResult)
FATAL_ERR();
break;
default:
break;
}
if (parseResult)
return retVal;
else
return NULL;
}
char*
StripComments PARAMS ((s, len),
char *s _AND_
int len)
{
char *cpy;
int sIndex, cpyIndex;
int inComment;
cpy = (char*)Malloc (len +1);
cpyIndex = 0;
for (sIndex = 0; sIndex < len; )
{
if ((s[sIndex] == '-') &&
((sIndex+1) < len) && (s[sIndex+1]== '-'))
{
for (sIndex += 2; sIndex < len; )
{
if ((s[sIndex] == '-') &&
((sIndex+1) < len) && (s[sIndex+1]== '-'))
{
sIndex += 2;
break;
}
else if (s[sIndex] == '\n')
{
sIndex++;
break;
}
else
sIndex++;
}
}
else
cpy[cpyIndex++] = s[sIndex++];
}
cpy[cpyIndex] == '\0';
return cpy;
}
int
ParseOidValue PARAMS ((mods, m, vd, t, vStr, eof, result),
ModuleList *mods _AND_
Module *m _AND_
ValueDef *vd _AND_
Type *t _AND_
char **vStr _AND_
char *eof _AND_
Value **result)
{
Value *newVal;
Type *newType;
Value *oidVal;
OID *parsedOid;
OID **nextOid;
char *id;
char *id2;
char *id3;
char *num;
int arcNum;
int namedNumVal;
P_LOCALS;
SAVE_POS();
if (AT_EOF())
{
PRINT_ERR_LOC (m, vd);
fprintf (stderr,"ERROR - expecting more data in OBJECT IDENTIFER value\n");
FAIL();
}
SkipWht (vStr, eof);
if (**vStr != '{')
{
PRINT_ERR_LOC (m, vd);
fprintf (stderr,"ERROR - OBJECT IDENTIFER values must begin with an \"{\".\n");
FAIL();
}
else
(*vStr)++;
SkipWht (vStr, eof);
parsedOid = NULL;
nextOid = &parsedOid;
while (**vStr != '}')
{
if (ParseIdentifier (vStr, eof, &id))
{
SkipWht (vStr, eof);
if (**vStr == '(')
{
(*vStr)++;
SkipWht (vStr, eof);
arcNum = NULL_OID_ARCNUM;
if (ParseIdentifier (vStr, eof, &id2))
{
id3 = NULL;
if (**vStr == '.')
{
(*vStr)++;
if (!ParseIdentifier (vStr, eof, &id3))
{
PRINT_ERR_LOC (m, vd);
fprintf (stderr,"ERROR - missing a module name after the \"%s.\" value reference", id2);
FAIL();
}
}
SkipWht (vStr, eof);
if (**vStr == ')')
(*vStr)++;
else
{
PRINT_ERR_LOC (m, vd);
fprintf (stderr,"ERROR - missing a closing \")\", after the \"%s\" value reference.\n", id2);
FAIL();
}
if (id3 != NULL)
{
SetupValue (&newVal, BASICVALUE_IMPORTVALUEREF,valLineNoG);
newVal->basicValue->a.importValueRef =
(ValueRef*)Malloc (sizeof (ValueRef));
newVal->basicValue->a.importValueRef->valueName = id2;
newVal->basicValue->a.importValueRef->moduleName = id3;
AddPrivateImportElmt (m, id2, id3, valLineNoG);
}
else
{
SetupValue (&newVal, BASICVALUE_LOCALVALUEREF,valLineNoG);
newVal->basicValue->a.localValueRef =
(ValueRef*)Malloc (sizeof (ValueRef));
newVal->basicValue->a.localValueRef->valueName = id2;
}
}
else if (ParseNum (vStr, eof, &num))
{
SkipWht (vStr, eof);
if (**vStr == ')')
(*vStr)++;
else
{
PRINT_ERR_LOC (m, vd);
fprintf (stderr,"ERROR - missing a closing \")\" after the \"%s (%s\".\n", id2, num);
Free (num);
FAIL();
}
arcNum = atoi (num);
Free (num);
newVal = NULL;
}
else
{
PRINT_ERR_LOC (m, vd);
fprintf (stderr,"ERROR - expecting either a value reference or number after the \"(\".\n");
FAIL();
}
*nextOid = (OID*) Malloc (sizeof (OID));
(*nextOid)->valueRef = newVal;
(*nextOid)->arcNum = arcNum;
nextOid = &(*nextOid)->next;
}
else
{
*nextOid = (OID*) Malloc (sizeof (OID));
(*nextOid)->arcNum = NULL_OID_ARCNUM;
arcNum = OidArcNameToNum (id);
if (arcNum != -1)
{
(*nextOid)->arcNum = arcNum;
}
else
{
SetupValue (&newVal, BASICVALUE_LOCALVALUEREF,valLineNoG);
newVal->basicValue->a.localValueRef =
(ValueRef*)Malloc (sizeof (ValueRef));
newVal->basicValue->a.localValueRef->valueName = id;
(*nextOid)->valueRef = newVal;
}
nextOid = &(*nextOid)->next;
}
}
else if (ParseNum (vStr, eof, &num))
{
*nextOid = (OID*) Malloc (sizeof (OID));
(*nextOid)->arcNum = atoi (num);
nextOid = &(*nextOid)->next;
Free (num);
}
else
{
PRINT_ERR_LOC (m, vd);
fprintf (stderr,"ERROR - bady formed arc number\n");
FAIL();
}
SkipWht (vStr, eof);
}
(*vStr)++;
SetupValue (&oidVal, BASICVALUE_LINKEDOID, valLineNoG);
oidVal->basicValue->a.linkedOid = parsedOid;
*result = oidVal;
SUCCEED();
}
void
SkipWht PARAMS ((vStr, eof),
char **vStr _AND_
char *eof)
{
while (!AT_EOF())
switch (**vStr)
{
case '\n':
case '\f':
case '\v':
case '\r': valLineNoG++;
case '\t':
case ' ':
case '\007':
case '\b':
(*vStr)++;
break;
default:
return;
}
}
int
ParseIdentifier PARAMS ((vStr, eof, result),
char **vStr _AND_
char *eof _AND_
char **result)
{
char *start;
int len;
P_LOCALS;
SAVE_POS();
if (AT_EOF())
FAIL();
start = *vStr;
if (!islower (**vStr))
FAIL();
(*vStr)++;
while (!AT_EOF())
{
if ((isalpha (**vStr)) || isdigit (**vStr) ||
((**vStr == '-') && !(*(*vStr - 1) == '-')))
(*vStr)++;
else
break;
}
if (*(*vStr - 1) == '-')
(*vStr)--;
len = *vStr - start;
*result = Malloc (len +1);
strncpy (*result, start, len);
(*result)[len] = '\0';
SUCCEED();
}
int
ParseNum PARAMS ((vStr, eof, result),
char **vStr _AND_
char *eof _AND_
char **result)
{
P_LOCALS;
char *start;
int len;
SAVE_POS();
if (AT_EOF())
FAIL();
start = *vStr;
while (!AT_EOF())
{
if (isdigit (**vStr))
(*vStr)++;
else
break;
}
len = *vStr - start;
if (len == 0)
FAIL();
*result = Malloc (len +1);
strncpy (*result, start, len);
(*result)[len] = '\0';
SUCCEED();
}
void
AddNewValueDef PARAMS ((vdl, name, value),
ValueDefList *vdl _AND_
char *name _AND_
Value *value)
{
ValueDef *vd;
ValueDef **tmpVd;
vd = (ValueDef*)Malloc (sizeof (ValueDef));
vd->definedName = name;
vd->value = value;
tmpVd = (ValueDef**)AsnListAppend (vdl);
*tmpVd = vd;
}