📄 asn_read.c
字号:
/*****************************************************************************
File: asn_read.c
Contents: Functions to parse ASN.1 as part of the ASN_GEN program.
System: ASN development.
Created:
Author: Charles W. Gardiner <gardiner@bbn.com>
Remarks:
COPYRIGHT 1995 BBN Systems and Technologies, A Division of Bolt Beranek and
Newman Inc.
150 CambridgePark Drive
Cambridge, Ma. 02140
617-873-4000
*****************************************************************************/
const char asn_read_rcsid[]="$Header: /nfs/sub-rosa/u2/IOS_Project/ASN/Dev/rcs/cmd/asn_gen/asn_read.c,v 1.8 1995/08/03 18:50:41 gardiner Exp $";
char asn_read_id[] = "@(#)asn_read.c 254P";
#include "includes.h"
#include "asn_obj.h"
#include "asn_gen.h"
static void append_subclasses(uchar *),
cvt_number(char *, char *),
do_components(int fd, void(*func)());
int read_global(int fd)
{
/**
Function: Reads file in global state
Inputs: File descriptor
Returns: IF reaches end of file, -1
ELSE 0
Procedure:
1. DO
IF token is '::='
Return IN_DEFINITION
ELSE IF token is DEFINITIONS
WHILE next token is not '::='
IF token is IMPLICIT, clear implicit flag for file
ELSE IF token is EXPLICIT, set explicit flag for file
ELSE IF token is not TAGS, error
ELSE IF haven't a classname, copy token into classname
2. WHILE have another token
Return -1
**/
do
{
if (!strcmp(token, equals))
{
max = min = 0;
state = IN_DEFINITION;
return 0;
}
else if (!strcmp(token, definitions_w))
{
while (get_token(fd, token, '(') && strcmp(token, equals))
{
if (!strcmp(token, implicit_w)) explicit = 0;
else if (!strcmp(token, explicit_w)) explicit = 3;
else if (strcmp(token, tags_w)) syntax(token);
}
}
else if (!*classname && *token >= 'A') strcpy(classname, token);
}
while (get_token(fd, token, '('));
return -1;
}
int read_definition(int fd, int parent)
{
/**
Function: General function to read a definition and fill in the appropriate
global variables
Inputs: file descriptor for input file
Outputs: Sets flags in option and in flags.
Fills in tag, type, min, max, and subclass
Sets state as follows:
IF definition is an upper bound, GLOBAL
ELSE IF '{' OR '\n' is found, IN_DEFINITION
Returns: IF end of file is reached, -1
ELSE 0
Procedure:
1. DO
IF token is CHOICE, set type of ASN_CHOICE
ELSE IF token is EMPTY, do nothing
ELSE IF token is OF, set OF bit in options and get the subclass name
ELSE IF token is SIZE, get sizes
ELSE IF token is TABLE, set table bit in flags and note file position
ELSE IF token is '[', get tag
ELSE IF token is '(', get min-max
ELSE IF token is numeric
Clear any line end
Set state to GLOBAL
ELSE IF token is a known type name
IF type is ENUMERATED, set enumerated flag
IF no type so far, use this one
ELSE IF OF flag set, set subtype to this type
ELSE 'Or' the constructed bit into the present type
ELSE IF (token begins with a capital letter OR *) AND
type is not -1, set subclass & options
IF no next token, return -1
WHILE state is IN_DEFINITION AND token is not '{' NOR '\n'
Return 0
**/
int tmp;
do
{
if (!strcmp(token, choice_w)) type = ASN_CHOICE;
else if (!strcmp(token, empty_w));
else if (!strcmp(token, of_w))
{
option |= ASN_OF_FLAG;
if (!get_token(fd, token, '(')) syntax(of_w);
if ((tmp = find_type(token)) != ASN_NOTYPE)
get_expected(fd, (subtype = tmp), token);
else if ((*token < 'A' || *token > 'Z') && *token != '*') syntax(token);
else option |= set_name_option(subclass, token);
}
else if (!strcmp(token, size_w)) get_size(fd, token, &min, &max, parent);
else if (!strcmp(token, table_w))
{
flags |= ASN_TABLE_FLAG;
tablepos = lseek(fd, 0L, 1);
}
else if (*token == '[') tag = get_tag(fd, token);
else if (*token == '(') get_paren(fd, token, &min, &max, parent);
else if (*token >= '0' && *token <= '9')
{
while(get_token(fd, token, '(') && *token != '\n');
state = GLOBAL;
return 0;
}
else if ((tmp = find_type(token)) != ASN_NOTYPE)
{
get_expected(fd, tmp, token);
if (tmp == ASN_ENUMERATED) flags |= ASN_ENUM_FLAG;
if (type < 0) type = tmp;
else if ((option & ASN_OF_FLAG)) subtype = tmp;
else if (tmp > 0) type |= (tmp & ASN_CONSTRUCTED);
}
else if (((*token >= 'A' && *token <= 'Z') || *token == '*') &&
type == -1) option |= set_name_option(subclass, token);
if (!get_token(fd, token, (char)0)) return -1;
}
while (state == IN_DEFINITION && *token != '{' && *token != '\n');
return 0;
}
int read_item(int fd, int parent, void(*func)())
{
/**
Function: General function to read an item and fill in appropriate global
variables
Input: File descriptor for input
Outputs: Sets option flags
Fills in tag, type, min, max, itemname, subclass, subtype,
defaultname and numstring
Procedure:
1. WHILE token is neither ',' NOR '}'
IF token is CHOICE, set constructed bit in type
ELSE IF token is COMPONENTS, do components stuff
ELSE IF token is DEFAULT, make defaultname and set default flag
ELSE IF token is DEFINED
IF next token isn't BY OR token after that isn't lower case
Syntax error
Make a name in defined_by
ELSE IF token is EMPTY, do nothing
ELSE IF token is EXPLICIT, set temporary explicit flag
ELSE IF token is FUNCTION
Set type
Get all tokens up to ')'
Append ';'
ELSE IF token is IMPLICIT, clear temporary explicit flag
ELSE IF token is OF, error
ELSE IF token is OPTIONAL, set OPTIONAL flag in options
ELSE IF token is SIZE, get min-max
ELSE IF token is TABLE
Get table name to skip it
Set table variable
ELSE IF token is TAGS, do nothing
ELSE IF token is '[', get tag
ELSE IF token is '('
IF enumerated flag set, get material for tag
ELSE Get min-max
ELSE IF token is a defined type
IF this is a table AND (there's a type OR a subclass already)
append token to alt_subclasses
ELSE IF have a subclass already, syntax error
ELSE IF have no type yet, use that
ELSE IF explicit tagging, set subtype
ELSE
'Or' the constructed bit into type
Get expected sequel to token, if any
ELSE IF token begins with a number
IF TABLE bit is set, convert number
ELSE IF enumerated flag is set
Put token into itemname prefixed with e
Set enumerated flag
ELSE IF name begins with a capital letter
IF this is a table item AND (there is already a subclass OR a type)
Append this to the alt_subclasses
ELSE IF there is already a subclass OR a type, syntax error
ELSE set the subclass and option from the token
ELSE IF name begins with a lower-case letter
IF no itemname so far, set token in itemname with options
IF no next token, return -1
Return 0
**/
char *c;
int tmp;
struct name_table *ntbp;
struct id_table *idp = (struct id_table *)0;
while (*token != ',' && *token != '}')
{
if (!strcmp(token, choice_w))
{
if (tag >= 0) tag |= ASN_CONSTRUCTED;
else if (type >= 0) type |= ASN_CONSTRUCTED;
else type = ASN_CONSTRUCTED;
}
else if (!strcmp(token, components_w)) do_components(fd, func);
else if (!strcmp(token, default_w))
{
option |= (ASN_OPTIONAL_FLAG | ASN_DEFAULT_FLAG);
get_token(fd, token, '(');
c = defaultname;
if (*token >= '0' && *token <= '9') *c++ = 'e';
else if (!strcmp(token, empty_w) || !strcmp(token, null_w) ||
(*token == '"' && token[1] == '"')) cat(token, "{");
strcpy(c, token);
}
else if (!strcmp(token, defined_w))
{
if (!get_token(fd, token, '(') || strcmp(token, "BY") ||
!get_token(fd, definer, '(') || (*definer < 'a' && *definer > 'z'))
syntax(defined_w);
mk_in_name(defined_by, itemname, classname);
if (type > 0) tag = type;
type = -1; /* cancel ANY or other universal primitive */
*inclass = 0;
}
else if (!strcmp(token, empty_w));
else if (!strcmp(token, explicit_w)) explicit |= 1;
else if (!strcmp(token, function_w))
{
type = ASN_FUNCTION;
if (!get_token(fd, token, (char)0)) fatal(19, (char *)0);
c = cat(itemname, token);
for (tmp = 4; tmp-- && get_token(fd, token, (char)0) && *token != '('; )
{
*c++ = ' ';
c = cat(c, token);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -