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

📄 asn_constr.c

📁 ASN.1语法解析代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
File:     asn_constr.c
Contents: Functions to generate .c files as part of 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_constr_rcsid[]="$Header: /nfs/sub-rosa/u2/IOS_Project/ASN/Dev/rcs/cmd/asn_gen/asn_constr.c,v 1.17 1995/09/25 22:10:10 gardiner Exp $";
char asn_constr_id[] = "@(#)asn_constr.c 282P";

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

struct tagq
    {
    struct tagq *next;
    long tag;
    };

static void addq(struct tagq **, long),
    checkq(struct tagq *, long),
    constr_def(int, int *, int *, long*),
    find_path(char *, char *),
    freeq(struct tagq **),
    print_item(char *, char *, long, int, int, int),
    print_of(int, int),
    set_dup(char *classname, long tag);
static int constr_item(int, int, int, int),
    optional_def(), set_options(int, char *, char *);

static char dot[] = ".",
    opener[] =
"%s::%s()\n\
{\n",
    ptr_opener[] =
"%s *%s::operator->()\n{\nreturn (%s *)_ptr;\n}\n\n\
void %s::operator=(%s *objp)\n{\n_ptr = objp;\nobjp->_supra = this;\n\
objp->fill_upward((objp->_flags & ASN_FILLED_FLAG));\n}\n\n\
void %s::_point()\n{\nif (_ptr) clear();\n_ptr = (AsnObj *)new %s;\n\
_set_ptr();\n}\n\n",
    pointer_tag_xw[] = "_tag = 0x%X;\n\
_type = %s;\n\
ptr = 0;\n\
_flags |= ASN_POINTER_FLAG;\n",
    first_item[] = "_sub = (AsnObj *)%s%s;\n",
    any_item[] = "%s%s_supra = this;\n",
    later_item[] = "%s%s_next = (AsnObj *)%s%s;\n",
    table_opener[] =
"AsnObj *objp = objid;\n\
_tag = _type = %s;\n\
_flags |= ASN_TABLE_FLAG;\n\
_sub = objp;\n",
    table_item[] =
"objp->_next = &objp[1];\n\
objp++;\n",
    table_write[] = "objp->_valp = new UcharArray((const uchar *)\"%s\", %d);\n",
    derived_table[] = "%s::%s()\n{\n\
wherep = new UcharArray((uchar *)\"%s\", %d);\n}\n\n",
    pointer_type_tag_w[] = "_tag = _type = %s;\n\
_ptr = 0;\n\
_flags |= ASN_POINTER_FLAG;\n",
    type_tag_w[] = "%s%s_tag = %s%s_type = %s;\n",
    type_xw[] = "_type = 0x%X;\n",
    tag_xw[] = "%s%s_tag = 0x%X;\n",
    dup_func[] =
"AsnDup *%s::_dup()\n\
{\n\
%s *objp = new %s;\n\
_set_pointers(objp);\n\
return objp;\n\
}\n\n",
    index_op[] =
"%s& %s::operator[](int index)\n\
{\n\
%s *objp = (%s *)index_op(index);\n\
return *objp;\n\
}\n\n",
    boundset[] =       "%s._min = %d;\n%s._max = %d;\n",
    finale[] = "}\n\n";

struct tagq *lasttagqp = (struct tagq *)0;

void construct(int fd)
{
/*
Function: Creates constructors for the things defined an ASN.1 file.
Inputs: fd is file descriptor for ASN.1 file
	str is the stream descriptor for the output
Outputs: C code written to 'str'
Procedure:
1. WHILE have a next token
       Switch on state
2. Case GLOBAL
	IF reading global returns GLOBAL, return
   Case IN_DEFINITION
	IF token is not '{' (rerun of table) AND reading definition returns
	    less than 0, return
	IF STATE is not GLOBAL, construct definition
3. Case IN_ITEM
   Case SUB_ITEM
	Read the item
	IF token is '}' OR ',' (indicating the end of an item)
	    Construct the item
   Default: Exit with fatal message
4. Search name table for pointer items (starting with '_') that have no
	parent that's a passthrough, i.e. no definition
	Make a definition for any found
*/
char *c;
int did, tmp, classgeneration, numdefineds;
struct name_table *ntbp, *ptbp;
struct parent *parentp;
long parenttype = -1;
if (state != SUB_ITEM) end_definition();
else end_item();
for (lasttagqp = (struct tagq *)0, classgeneration = numdefineds = 0;
    get_token(fd, token, (char)0); )
    {
    switch (state)
    	{
    case GLOBAL:			
	if (read_global(fd) < 0) break;
	break;

    case IN_DEFINITION:                                     /* got ::= */
	if (*token != '{' && read_definition(fd, -1) < 0) return;
	if (state != GLOBAL) constr_def(fd, &classgeneration, &numdefineds,
            &parenttype);
    	break;
							    /* step 3 */
    case IN_ITEM:                                     /* got '{' */
    case SUB_ITEM:
	if (read_item(fd, -1, construct) < 0) return;
	if ((*token == ',' || *token == '}') &&        /* end of item */
	    !constr_item(fd, classgeneration, numdefineds, parenttype))
	    return;
	break;

    default:
	fatal(4, (char *)state);
	}
    }
for (ntbp = (struct name_table *)name_area.area; ntbp->name; ntbp++)
    {
    if (*(c = ntbp->name) != '_') continue;
    for (parentp = &ntbp->parent; parentp; parentp = parentp->next)
	{
	ptbp = &((struct name_table *)name_area.area)[parentp->index];
	if ((ptbp->flags & ASN_FALSE_FLAG)) break;
	}
    if (parentp) continue;
    cat(classname, c);
    if ((did = (test_dup(classname, &tmp) & ~ASN_OF_FLAG)))
        print_of(did, tmp);
    for (ptbp = (struct name_table *)name_area.area; ptbp->name &&
	strcmp(ptbp->name, &c[1]); ptbp++);
    fprintf(outstr, ptr_opener, &c[1], c, &c[1], c, &c[1], c, &c[1]);
    fprintf(outstr, opener, c, c);
    fprintf(outstr, pointer_type_tag_w, find_define(ptbp->type));
    fprintf(outstr, finale);
    }
}

static void constr_def(int fd, int *classgenerationp, int *numdefinedsp,
    long *parenttypep)
{
/**
1. IF token is '{' OR line end
        IF no tag, use type as tag
        Clear did and prevname
        IF token is { AND (type is BIT STRING OR INTEGER OR ENUMERATED)
            Set enumerated flag
        See if it needs dup stuff
        IF it's a primitive AND no enumerated flag, clear duped flag
        IF it needs dup for other than 'OF' AND it's not imported
    	    Print the OF stuff
        IF it's not imported AND (there's a '{' OR it's an OF OR it's a
    	    pointer)
    	    IF it's a pointer, print pointer opener
            Print opener C text
2. IF token is {
    Set parenttype to type
    IF it's not imported
        IF it's a defined item, print flag setting message
        Clear that flag
        IF it's a table
            Print table opener
            Get the path from the definer to the defined
        ELSE
            IF it needed a dup function, print dup stuff
            IF not universal tag, print tag msg
	    IF not derived from its type, print _type message
    Go to IN_ITEM state OR SUB_ITEM, depending on current state
3. ELSE  (line end)
    IF it's not a passthrough
        IF it needed a dup function, print dup stuff
        Make itemname out of subclass
        IF this is a pointer
	    IF it's part of an OF, print dup message
	    Print point, tag & type messages
        ELSE
            IF there's a subtype, use "array" as the itemname
            Print item with flags, except for OF flag
	    IF there's max, print min/max
	    IF there's a subclass AND its type is primitive
                Use that as the subtype
	    IF there's (now) a subtype
	        Print the tag & typemessage
	        IF there's a subclass AND this item has a max, set its bounds
        Print finale
    Clear classname
    Go to GLOBAL state
**/
char *c;
int did, tmp;
struct name_table *ntbp;
struct parent *parentp;
if (curr_pos <= real_start) curr_pos = lseek(fd, 0L, 1);
if (tag < 0) tag = type;
else if (type > 0) tag |= (type & ASN_CONSTRUCTED);
if (*token == '{' &&
    (type == ASN_BITSTRING || type == ASN_INTEGER ||
    type == ASN_ENUMERATED) && !(option & ASN_OF_FLAG))
    flags |= ASN_ENUM_FLAG;
did = test_dup(classname, &tmp);
if (type >= 0 && type < ASN_CONSTRUCTED && !(flags & ASN_ENUM_FLAG))
    did &= ~(ASN_DUPED_FLAG);
if ((did & ~(ASN_OF_FLAG)) &&
    curr_pos > real_start) print_of(did, tmp);
if (curr_pos > real_start &&
    (*token == '{' || (option & (ASN_OF_FLAG | ASN_POINTER_FLAG))))
    {
    if (option == ASN_POINTER_FLAG)
	{
        c = replace_name(classname)->name;
	fprintf(outstr, ptr_opener, &c[1], c, &c[1], c, &c[1], c, &c[1]);
	}
    else c = classname;
    fprintf(outstr, opener, c, c);
    }
							    /* step 2 */
if (*token == '{')
    {
    state = IN_ITEM;
    if ((type == ASN_BITSTRING || type == ASN_INTEGER ||
        type == ASN_ENUMERATED) && !(option & ASN_OF_FLAG))
        flags |= ASN_ENUM_FLAG;
    *parenttypep = type;
    if (curr_pos > real_start)
    	{
    	if ((flags & ASN_DEFINED_FLAG))
            fprintf(outstr, "_flags |= ASN_DEFINED_FLAG;\n");
    	else if ((flags & ASN_TABLE_FLAG))
            {
            ntbp = find_name(classname);
            fprintf(outstr, table_opener, find_define(ntbp->type));
	    ntbp = &((struct name_table *)name_area.area)[ntbp->parent.index];
	    for (parentp = &ntbp->parent, *numdefinedsp = 0; parentp->next;
                (*numdefinedsp)++, parentp = parentp->next);
            }
        else
            {
            if ((did & ASN_DUPED_FLAG)) set_dup(classname, tag);
            if (!did && tag >= ASN_APPL_SPEC && tag != ASN_CHOICE)
                fprintf(outstr, tag_xw, "", "", tag);
            }
        }
    if (type >= 0 && type < ASN_CONSTRUCTED && subtype < 0) subtype = type;
    *classgenerationp = find_name(classname)->generation;
    end_item();
    did = 0;
    }
					        /* step 3 */
else                /* no further definition */
    {
    if (curr_pos > real_start && (option & (ASN_OF_FLAG | ASN_POINTER_FLAG)))
        {
        if ((did & ASN_DUPED_FLAG)) set_dup(classname, tag);
        cat(itemname, subclass);
        if (*itemname != '_') *itemname |= 0x20;
        else itemname[1] |= 0x20;
        if (*subclass) ntbp = replace_name(subclass);
        else ntbp = 0;
        if (option == ASN_POINTER_FLAG)
	    {
	    ntbp = replace_name(&subclass[1]);
	    if (ntbp->type == ntbp->tag || ntbp->tag == 0xFFFFFFFF)
                fprintf(outstr, pointer_type_tag_w,
                    find_define(ntbp->type));
	    else fprintf(outstr, pointer_tag_xw, ntbp->tag,
                find_define(ntbp->type));
	    }
        else
            {
            if (subtype >= 0) cat(itemname, array_w);
            print_item((*itemname == '_')? &itemname[1]: itemname, prevname,
                (long)0,  (option & ~(ASN_OF_FLAG)), 0, 0);
            if (max) fprintf(outstr, "_min = %d;\n_max = %d;\n", min, max);
            if (ntbp && ntbp->type < ASN_CONSTRUCTED) subtype = ntbp->type;
            if (subtype >= 0)
	        {
                fprintf(outstr, type_tag_w, itemname, dot, itemname, dot,
                    find_define(subtype));
	        if (*subclass && ntbp->max) fprintf(outstr, boundset, itemname,
                    ntbp->min, itemname, ntbp->max);
	        }
	    }
        fprintf(outstr, finale);
        }
    end_definition();
    }
}

static int constr_item(int fd, int classgeneration, int numdefineds,
    int parenttype)
{
/**
1. IF it's a DEFINED BY
 	IF the definer has no child, syntax error
 	Set type to CONSTRUCTED ANY
 	Clear defined_by
   IF (explicit OR CHOICE OR ANY) AND have a tag AND not ENUM
 	Set explicit option
   IF no tag so far AND type is a universal primitive, use type as tag
   ELSE IF this item is explicitly tagged AND it;s not a subdefined
 	primitive, set the constructed bit in the tag
   ELSE IF have a type, then 'Or' the constructed bit of the type into the tag
   IF ENUM is set in flags, set it in option
2. IF it's an imported item, do nothing
   ELSE IF it's a table item
 	IF no type, use itemname
 	ELSE use class name
 	Print the table line
 	IF have a name, print line to create sub-item
 	IF it's not the last item, print about next item
   ELSE IF it's not a FUNCTION
 	IF there's no itemname, make one from type or subclass
        IF class is enumerated

⌨️ 快捷键说明

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