📄 asn_hdr.c
字号:
/*****************************************************************************
File: asn_hdr.c
Contents: Functions to generate .h 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_hdr_rcsid[]="$Header: /nfs/sub-rosa/u2/IOS_Project/ASN/Dev/rcs/cmd/asn_gen/asn_hdr.c,v 1.16 1995/09/25 22:10:14 gardiner Exp $";
char asn_hdr_id[] = "@(#)asn_hdr.c 282P";
#include "includes.h"
#include "asn_obj.h"
#include "asn_gen.h"
static void print_end(int, int),
print_hdr(int),
print_item(char *, char *, long, int),
set_alt_subtype(struct name_table *, int);
static int hdr_def(int, int *, int *),
hdr_item(int, int, int);
static char *get_derivation(int, long);
static const char opener[] = "class %s : public %s\n {\n public:\n",
forward[] = "class %s;\n\n",
any_item[] = " %s %s;\n",
dup_point_func[] = "AsnObj *_%s%s();\n\n",
func_line[] = " %s;\n",
ptr_ops[] = " %s *operator->();\n void operator=(%s *);\
\n operator %s* () { return static_cast<%s*>(_ptr);}\
\n void _point();\n",
index_op[] = " AsnDup *_dup();\n %s& operator[](int index);\n",
constructor[] = " %s & operator=(const %s &frobj)\
\n { *((AsnObj *)this) = (AsnObj)frobj; return *this;}\
\n %s();\n",
table_line[] = " AsnObj objid[%d];\n",
typedef_line[] = "typedef %s %s;\n\n",
assign_num[] =
" int operator=(const long val) { return write(val); }\n\
operator long() { return *this; }\n",
assign_char[] =
" int operator=(const char *c) { return write((uchar *)c, strlen(c)); }\n\
int operator!=(const char *c) { return (*(AsnString *)this != c); }\n\
int operator==(const char *c) { return (*(AsnString *)this == c); }\n",
finale[] = " };\n\n";
void do_hdr(int fd, int flag)
{
/**
Function: Searches object table by generation and calls print_hdr for each
item
Inputs: fd is file descriptor for ASN.1 file
str is the stream descriptor for the output
Outputs: C header file written to 'str'
Procedure:
1. Find the latest generation in the object table
At the same time, print forward declarations
Starting at that generation, FOR each generation down to -1
FOR each item in the table
IF it's of another generation OR is ruled out by exports,
Continue in FOR
IF the name begins with '_'
Get its parent as the current pointer
IF its pointee is of an earlier generation
Print a forward declaration
IF it's not a passthrough
Print other stuff for it
Continue in FOR
ELSE IF it's an import OR is DEFINED OR is a DEFINER OR is an
'intermediate' table (i.e. not the real table)
Continue in FOR
ELSE use this pointer as the current pointer
Seek to its place in the input file
Print its header stuff
Decrement the generation
**/
struct name_table *ntbp, *entbp, *curr_ntbp;
int generation = -1, dup_ansr, tmp;
char *c;
for (ntbp = (struct name_table *)name_area.area,
entbp = &ntbp[name_area.next]; ntbp < entbp; ntbp++)
{
if (ntbp->generation > generation) generation = ntbp->generation;
if (ntbp->pos < real_start && flag && !(ntbp->flags & ASN_FALSE_FLAG) &&
ntbp->type >= ASN_CONSTRUCTED &&
*ntbp->name >= 'A' && *ntbp->name <= 'Z')
fprintf(outstr, forward, ntbp->name);
}
for ( ; generation >= -1; generation--)
{
for (ntbp = (struct name_table *)name_area.area; ntbp < entbp; ntbp++)
{
if (ntbp->generation != generation ||
(flag && !(ntbp->flags & flag)) ||
(!flag && (ntbp->flags & (ASN_EXPORT_FLAG | ASN_SUB_EXPORT_FLAG))))
continue;
end_definition();
cat(classname, ntbp->name);
if (*ntbp->name == '_')
{
if (find_name(&ntbp->name[1])->generation < generation)
fprintf(outstr, forward, &ntbp->name[1]);
curr_ntbp =
&((struct name_table *)name_area.area)[ntbp->parent.index];
if (!(curr_ntbp->flags & ASN_FALSE_FLAG))
{
if (((dup_ansr = test_dup(ntbp->name, &tmp)) & ASN_DUPED_FLAG))
c = "AsnPtrArray";
else c = "AsnPtr";
fprintf(outstr, opener, ntbp->name, c);
fprintf(outstr, ptr_ops, &ntbp->name[1], &ntbp->name[1],
&ntbp->name[1], &ntbp->name[1]);
print_end(dup_ansr, 1);
continue;
}
}
else if (ntbp->pos < real_start ||
(ntbp->flags & (ASN_DEFINER_FLAG | ASN_DEFINED_FLAG)) ||
((ntbp->flags & ASN_TABLE_FLAG) && ntbp->parent.index >= 0 &&
!(((struct name_table *)name_area.area)[ntbp->parent.index].flags &
ASN_TABLE_FLAG))) continue;
else if (ntbp->pos >= real_start &&
!(ntbp->flags & (ASN_TABLE_FLAG | ASN_ENUM_FLAG)) &&
((ntbp->flags & ASN_FALSE_FLAG) ||
(ntbp->type != -1 && ntbp->type < ASN_CONSTRUCTED)))
{
cat(itemname, classname);
curr_ntbp = replace_name(itemname);
if (curr_ntbp->type != 0xFFFFFFFF &&
curr_ntbp->type < ASN_CONSTRUCTED)
cat(itemname, find_class(curr_ntbp->type));
fprintf(outstr, typedef_line, itemname, classname);
continue;
}
else curr_ntbp = ntbp;
lseek(fd, curr_ntbp->pos, 0);
type = curr_ntbp->type;
state = IN_DEFINITION;
print_hdr(fd);
}
}
}
static void print_hdr(int fd)
{
/*
Function: Creates class definitions 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
state is the starting state
objname is the name of this object
Outputs: C header data written to 'outstr'
Procedure:
1. WHILE there is another token
Switch on state
2. Case IN_DEFINITION
IF read_definition returns -1 OR state is global, return
IF (token is '{' OR line end) AND making the definition returns 0
Return
3. Case IN_ITEM
Case SUB_ITEM
IF reading item returns -1, return
IF (token is '}' OR ',' (indicating the end of an item)) AND
making header item returns 0, return
Default: Exit with fatal message
*/
int dup_ansr, numdefineds;
for ( end_item(); get_token(fd, token, '('); )
{
switch (state)
{
case IN_DEFINITION:
if ((*token != '{' && read_definition(fd, -1) < 0) || state == GLOBAL)
return;
if ((*token == '{' || *token == '\n') &&
!hdr_def(fd, &numdefineds, &dup_ansr)) return;
break;
/* step 3 */
case IN_ITEM:
case SUB_ITEM:
if (read_item(fd, -1, print_hdr) < 0) return;
if ((*token == ',' || *token == '}') && /* end of item */
!hdr_item(fd, dup_ansr, numdefineds)) return;
break;
default:
fatal(4, (char *)state);
}
}
}
static int hdr_def(int fd, int *numdefinedsp, int *dup_ansrp)
{
/**
1. IF there's a subclass
IF there's no itemname, make one from subclass
IF the final name has a universal type AND it's not a primitive
that will have subs (i.e. ENUM)
use that as subtype
ELSE IF object has the DEFINED flag in table
Clear the TABLE option because this is the defined item
2. IF token is '{'
Set state to IN_ITEM
IF type is BIT STRING OR INTEGER, set enumerated flag
IF it's a TABLE, print opener with class "AsnTableObj"
ELSE
3. IF it will have a dup or point function, print them
Get type class name
IF no universal simple class OR ENUM flag is set
Print opener C text with classname and type class
IF had no '{'
IF a member of an OF
IF there's an explicit subclass
Make an itemname from it
IF there's a subtype
IF no subclass, use "array"
Give it the classname "AsnArray"
Clear the subtype
Print item with flags
IF item was an OF, print index operator stuff
ELSE IF it's a pointer, print pointer operations
ELSE
Make dummy name from classname
Print item with flags
Print lines for constructor and finale
IF had no '{', return 0
Clear assorted variables
Return 1
**/
struct name_table *ntbp;
char *c;
int tmp;
struct parent *parentp;
if (*subclass)
{
if (!*itemname)
{
cat(itemname, ((*subclass == '_')? &subclass[1]: subclass));
*itemname |= 0x20;
}
if ((ntbp = replace_name(subclass)) &&
ntbp->type != 0xFFFFFFFF && ntbp->type < ASN_CONSTRUCTED &&
!(ntbp->flags & ASN_ENUM_FLAG))
subtype = ntbp->type;
}
/* step 2 */
if (*token == '{')
{
state = IN_ITEM;
if ((type == ASN_BITSTRING || type == ASN_INTEGER ||
type == ASN_ENUMERATED) && !(option & ASN_OF_FLAG) &&
!(flags & ASN_TABLE_FLAG)) flags |= ASN_ENUM_FLAG;
}
if ((flags & (ASN_TABLE_FLAG | ASN_DEFINED_FLAG)) == ASN_TABLE_FLAG)
{ /* defined flag is turned on after printing table */
fprintf(outstr, opener, classname, "AsnTableObj");
classcount++;
ntbp = find_name(classname); /* then go up one generation */
ntbp = &((struct name_table *)name_area.area)[ntbp->parent.index];
for (parentp = &ntbp->parent, *numdefinedsp = 0; parentp->next;
(*numdefinedsp)++, parentp= parentp->next);
}
else
{
/* step 3 */
if ((flags & ASN_DEFINED_FLAG)) type = ASN_CHOICE;
*dup_ansrp = test_dup(classname, &tmp);
c = get_derivation(*dup_ansrp, type);
if (type >= 0 && type < ASN_CONSTRUCTED &&
!(flags & ASN_ENUM_FLAG))
/* now clear it for a primitive named something else
had to wait after get_derivation to force AsnArray */
*dup_ansrp &= ~(ASN_DUPED_FLAG);
if (type < 0 || type >= ASN_CONSTRUCTED || type == ASN_CHOICE ||
(flags & ASN_ENUM_FLAG))
{
fprintf(outstr, opener, classname, c);
/* c is "derived from" class */
classcount++;
if (state == IN_DEFINITION)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -