?? asn_constr.c
字號:
/*****************************************************************************
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 + -