⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn_pproc.c

📁 ASN.1语法解析代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
File:     asn_pproc.c
Contents: Functions to pre-process ASN.1 files 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_pproc_rcsid[]="$Header: /nfs/sub-rosa/u2/IOS_Project/ASN/Dev/rcs/cmd/asn_gen/asn_pproc.c,v 1.21 1995/09/25 22:10:11 gardiner Exp $";
char asn_pproc_id[] = "@(#)asn_pproc.c 282P";

#include "includes.h"
#include "asn_obj.h"
#include "asn_gen.h"

static struct import_table
    {
    char *name;
    struct import_item
	{
	struct import_item *next;
	char *module;
	} item;
    } *imtbp;   /* pointer to entry for imported file currently being read */

static struct import_table *add_import_item(struct import_table *, char *);

static void encr_xform(int, char *),
    free_imports(),
    get_exports(int),
    get_fnames(int),
    putout(FILE *, char *);

static int is_imported(char *),
    pre_proc_get_token(int, FILE *, char *),
    pre_proc_glob(int, FILE *, char *, char **, char *, int *, long *),
    pre_proc_def(int, FILE *, char *, char **, char *, int *, long),
    pre_proc_item(int, FILE *, char *, char **, char *, int *, int, long),
    was_imported(char *);

static FILE *make_substr();

static char encrypted_w[] = "ENCRYPTED", exports_w[] = "EXPORTS",
    signed_w[] = "SIGNED";

static struct name_area import_area =
    {"import_area", sizeof(struct import_table), 20, 4000 };

char tobesigned[] = "{\n    toBeSigned  %sToBeSigned,\n",
    tabledef[] =
"%sAlgorithmIdentifier ::= SEQUENCE {\n\
    algorithm OBJECT IDENTIFIER TABLE %s,\n\
    parameters ANY DEFINED BY algorithm OPTIONAL}\n\n",
    objtobesigned[] = "%sToBeSigned ::= SEQUENCE ",
    signedname[] = "Signed%s ",
    signeddef[] = "::= SEQUENCE {\n",
    tagclass[] = "    %s  SEQUENCE,\n",
    thatword[] = "    %s  %s,\n",
    algsig[] =
"    algorithm  %sAlgorithmIdentifier,\n\
    signature BIT STRING }\n\n",
    of_opener[] =  "%s ::= %s %s %s\n\n",
    sub_opener[] = "%s ::= %s {\n",
    signed_sub_opener[] = "%s ::= %s";

void pre_proc(int fd, FILE *str, int in_sub)
{
/**
Function: Preprocesses file fd to translate SIGNED macro and produce file str
Inputs: fd is file descriptor for ASN.1 file.  IF this is non-zero, we are in
	    an imported file
	str is the stream descriptor for the output
	locstate is used for recursiveness
Outputs: ASN.1 code written to 'str'
Procedure:
1. Starting with lots of things cleared, DO forever
        IF no token AND no more tokens, break out of DO
        Switch on locstate
2.    Case GLOBAL
	IF processing global state returns GLOBAL state, return
      Case IN_DEFINITION
	    IF processing the definition returns GLOBAL state
		Clean up a few variables
      Case IN_ITEM
	    IF in a sub-item AND pre-processing the items returns GLOBAL
		state, return
**/
char linebuf[2*BSIZE], *linend = linebuf, *elinebuf = &linebuf[sizeof(linebuf)];
int signflag,
    active;     /* -1= in main file, 0= in imported file but not imported class
		  1= in imported file in an imported class, no details needed
		  2=  "   "        "  "   "    "      " , but details needed */
ulong loctag;
long loctype, glob_type;
if (!in_sub) *classname = 0;
for (signflag = loctag = 0, active = glob_type = loctype = -1,
    *token = *linebuf = *itemname = 0; pre_proc_get_token(fd, str, linebuf); )
    {
    switch (state)
    	{
    case PRE_GLOBAL:
	if (!strcmp(token, equals)) syntax(definitions_w);
	if (!strcmp(token, definitions_w)) state = GLOBAL;
	else *token = 0;   /* discard up to DEFINITIONS */
	break;

    case GLOBAL:			
	if ((state = pre_proc_glob(fd, str, linebuf, &linend, elinebuf,
            &active, &glob_type)) == GLOBAL) return;
	break;

    case IN_DEFINITION:                                     /* got ::= */
	if ((state = pre_proc_def(fd, str, linebuf, &linend, elinebuf,
            &active, glob_type)) == GLOBAL)
	    {
            active = glob_type = loctype = -1;
	    fflush(str);
    	    *subclass = *classname = *(linend = linebuf) = 0;
	    }
	break;

    case IN_ITEM:
    case SUB_ITEM:
	if ((state = pre_proc_item(fd, str, linebuf, &linend, elinebuf,
            &active, in_sub, glob_type)) == GLOBAL && in_sub) return;
	glob_type = -1;
	break;

    default:
	fatal(4, (char *)state);
	}
    }
if (linend > linebuf) fprintf(str, "%s\n", linebuf);
if (!fd) free_imports();
}

static int pre_proc_get_token(int fd, FILE *str, char *linebuf)
{
static int loopcount;
if (!*token) loopcount = 0;
else if (loopcount++ > 20)
    {
    putout(str, linebuf);
    fflush(str);
    fatal(22, token);
    }
if (!*token && !get_token(fd, token, (char)0)) return 0;
return 1;
}

static int pre_proc_glob(int fd, FILE *str, char *linebuf, char **linendp,
    char *elinebuf, int *activep, long *glob_typep)
{
/**
1. DO
        IF token is '::='
    	    IF not in definitions class, set state to IN_DEFINITION
    	    ELSE IF not in an imported file
    	        Print token with RETURN
    	        Clear class name and token
2.      ELSE IF token is IMPORTS
    	    IF have already started, error
            Get all the file names
            IF at top level
                FOR each file in the import table
    	            Add the name to the i_names list
    	            Open the file for reading
    	            Call pre_proc with that fd (this may add to the import
    		        table)
    	            Close input file
            Put out an extra line end
3.      ELSE IF token is EXPORTS, put export items in export area
        ELSE IF token is BEGIN, do nothing
        ELSE IF token is a known tag, save its type
        ELSE IF token is a name defined to be a universal type
    	    IF haven't a class name, error
    	    Replace the token with the universal name
        ELSE IF token is a brace, error
        ELSE IF have no local classname AND token looks like one
    	    Copy token to local class name
        IF classname is upper case, append token to linebuf and clear token
   WHILE state is GLOBAL AND there's a next token
   Return state
**/
char *c, locclass[128];
int locstate, tmp;
struct name_table *ntbp;
do                                                          /* step 1 */
    {
    if (!strcmp(token, equals))
        {
        if (strcmp(classname, definitions_w)) state = IN_DEFINITION;
        else
            {
            if (!fd) fprintf(str, "%s ::=\n\n", linebuf);
	    *token = *classname = *(*linendp = linebuf) = 0;
	    }
        }
    else if (!strcmp(token, imports_w))                     /* step 2 */
        {
        cat(classname, token);
        if (real_start) syntax(token);
        *token = 0;
        get_fnames(fd);
        if (!fd)
	    {
            for(imtbp = (struct import_table *)import_area.area;
	        imtbp->name; imtbp++)
	        {
		if (!strcmp(imtbp->name, source)) continue;
	        if (add_include_name(imtbp->name))
		    {
    	            if ((tmp = find_file(imtbp->name)) < 0)
                        fatal(2, imtbp->name);
    	            printf("File %s\n", imtbp->name);
		    cat(locclass, classname);
		    locstate = state;
    	            pre_proc(tmp, str, 0);
    	            fflush(str);
    	            close(tmp);
		    state = locstate;
		    cat(classname, locclass);
		    *token = 0;
		    }
	        }
	    imtbp = (struct import_table *)0;
	    printf("Main file\n");
	    }
        if (*activep) putout(str, "\n");
        if (!fd) real_start = ftell(str);
        *classname = 0;
        }
    else if (!strcmp(token, exports_w))                     /* step 3 */
        {
        get_exports(fd);
        *locclass = *classname = *token = 0;
        }
    else if (!strcmp(token, begin_w)) *token = 0;
    else if ((tmp = find_type(token)) != ASN_NOTYPE)
        get_expected(fd, (*glob_typep = tmp), token);
    else if ((ntbp = find_name(token)) && ntbp->name && ntbp->type <
        ASN_APPL_SPEC)
        {
        if (!*classname)
	    {
	    cat(classname, token);
            fatal(17, token);
	    }
        c = cat(token, find_typestring(ntbp->type));
        if (ntbp->type == ASN_OBJ_ID) cat(c, " IDENTIFIER");
        else if (ntbp->type == ASN_BITSTRING || ntbp->type ==
            ASN_OCTETSTRING) cat(c, " STRING");
        ntbp->pos = -2;     /* so it won't appear in unused list */
        *glob_typep = ntbp->type;
        }
    else if (*token == '{' || *token == '}') syntax(token);
    else if (!*classname && *token >= 'A')
        {
        cat(classname, token);
        if (strcmp(token, definitions_w) && strcmp(token, implicit_w) &&
	    strcmp(token, explicit_w) && isreserved(token))
            syntax("invalid class");
        }
    if (fd && *classname > ' ') *activep = is_imported(classname);
    if (*classname <= 'Z' && *activep && *token && (*linendp > linebuf ||
        *token > ' ') &&
        (*linendp = cat(cat(*linendp, token),
        ((!token == '{')? "\n    ": " "))) >= elinebuf) syntax(linebuf);
    *token = 0;
    }
while (state == GLOBAL && pre_proc_get_token(fd, str, linebuf));
return state;
}

static int pre_proc_def(int fd, FILE *str, char *linebuf, char **linendp,
    char *elinebuf, int *activep, long glob_type)
{
/**
1. DO
        IF token is ENCRYPTED, call encrypted transformation
        IF token is SIGNED
            Set signed flag
            Get next token to put out
        ELSE IF token is TABLE
            IF signed flag set
    	        Get table name
    	        Clear token
2.      ELSE IF token is '{' OR OF
    	    IF (it's an OF OR is imported) AND linebuf has data
                Put linebuf out
    	    IF token is OF
    	        IF active, put out OF
    	        IF next token is not a universal type
    		    IF active, put out token
    		    Clear token
    	            Set state to GLOBAL
    	        ELSE
    		    IF next token is '{'
    		        Make a synthetic name
    		        IF active
                            Print that with a line end
    		            IF details needed, print sub_opener with
    			        synthetic name and universal type name
    		        Clear token
    	            Set state to GLOBAL
    	    ELSE IF in an imported file
    	        Print token
    	        Skip to next '}'
    	    IF active AND not imported
    	        IF linebuf has data AND not a glob_type
    		    Put out the linebuf
                IF signed flag is set
                    Put out tobesigned lines
                    IF have a table, put out tabledef lines
                    Put out objtobesigned line
            IF state isn't GLOBAL, set state to IN_ITEM
3.      ELSE IF token is open parenthesis or bracket, bump count
        ELSE IF token is close parenthesis or bracket
    	    IF decrementing count goes < 0, error
        ELSE IF token is numeric
            Add object to ub table
    	    Clear linebuf
        ELSE IF token is alphabetic but not a reserved word
    	    IF have subclass OR type, i.e. definition is complete
    	        Set state to GLOBAL
    	        IF type is universal constructed, error
    	    ELSE set subclass from token
4.      IF classname is upper case
    	    IF just switched to GLOBAL state
    	        IF active
    		    IF in an imported file AND token is capital letter
    		        Add token as an imported item so it will be
    			    included as child of this 'false' item
                        Print 1 or 2 blank lines
    	        Clear assorted variables to enter global state, BUT keep
    		    token, since it starts the next definition
    	    ELSE
                IF active,
    		    Append token to linebuf
    		    IF item is a choice, set active to 2 to force getting
    		        contents of item
        ELSE throw away the token
   WHILE state is IN_DEFINITION AND there's another token
   Return state
**/
int loctype, signflag, tmp, brackets, parens;
char *c, table[128];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -