📄 asn_constr.c
字号:
Print line to set tag
Clear tag and type
3. IF there's a subclass
Find out if it needs to be replaced
IF the subclass isn't in the table, error
IF there's a type in the table
'Or' that object's constructed bit into the tag
IF table has a tag
IF item has an explicit tag, warn
ELSE IF no tag so far
Set the expected tag (for checking the last tag list)
IF table tag is primitive AND item is explicit
Use that as tag (any constructed or implicit
item will set its own tag)
IF there's no type, use type from table
ELSE IF there's no subtype, use the subtype from the table
IF explicit, 'Or' constructed into the tag
IF the expected tag matches anything in the last_tag list
Print warning
IF no expected tag so far, use the tag, or, if no tag so far
Use the type as the expected tag
IF this item is optional OR (parenttype is CHOICE AND there's no
defined_by) OR parenttype is SET
Add the expected tag to last_tag list
ELSE clear last_tag list
Print the item with all options
IF there's a default, print that stuff
Copy name to prevname
4. IF token does not indicate the last item, finish the item
ELSE IF not in COMPONENTS OF
IF it's not imported, print the finale
IF table flag is set
Set state to INDEFINITION
IF doing defineds
IF at the last one, setstate to GLOBAL
ELSE bump up the name
ELSE (just did basic table) FOR each parent of basic table
Find the path from definer to definee
Print the whole constructor
Set up to do first defined item
Go back to start of table
Clear previous name
Free the list of last tags
IF not in state IN_DEFINITION, finish the definition
ELSE finish item
ELSE return 0
Return 1
**/
struct name_table *ntbp, *ctbp, *ptbp;
struct parent *parentp;
ulong tag_tb;
char *c;
static int thisdefined;
if (*defined_by)
{
ntbp = find_name(defined_by);
if (!(c = find_child(defined_by))) syntax(defined_w);
type = ASN_ANY | ASN_CONSTRUCTED;
}
if (((explicit & 1) || type == ASN_CHOICE || type == ASN_ANY) && tag >= 0 &&
!(flags & ASN_ENUM_FLAG)) option |= ASN_EXPLICIT_FLAG;
if (tag < 0 && type < ASN_CONSTRUCTED) tag = type;
else if (type == (ASN_ANY | ASN_CONSTRUCTED) && tag >= 0 &&
tag < ASN_CONSTRUCTED)
fprintf(outstr, tag_xw, itemname, ".", tag);
else if ((explicit & 1) && !(flags & ASN_ENUM_FLAG)) tag |= ASN_CONSTRUCTED;
else if (type >= 0) tag |= (type & ASN_CONSTRUCTED);
if ((flags & ASN_ENUM_FLAG)) option |= ASN_ENUM_FLAG;
/* step 2 */
if (curr_pos <= real_start);
else if ((flags & (ASN_TABLE_FLAG | ASN_DEFINED_FLAG)) == ASN_TABLE_FLAG)
{
if (type < 0 && !*subclass && !optional_def()) syntax(itemname);
if (type < 0) c = itemname;
else c = find_class(type);
fprintf(outstr, table_write, numstring, strlen(numstring) / 4);
/* chars are in form '\123' */
if (*token == ',') fprintf(outstr, table_item);
}
else if (type != ASN_FUNCTION)
{
if (!*itemname)
{
if (type >= 0) c = &find_class(type)[3];
else if (!*subclass) c = "no_item";
else c = subclass;
cat(itemname, c);
}
*itemname |= 0x20;
if ((flags & ASN_ENUM_FLAG))
{
fprintf(outstr, "%s._tag = %ld;\n", itemname, tag);
tag = type = -1;
}
/* step 3 */
tag_tb = -1;
if (*subclass && find_type(subclass) == ASN_NOTYPE)
{
if (!(ntbp = replace_name((*subclass != '_')? subclass:
&subclass[1]))) syntax(subclass);
if (ntbp->type != -1)
tag |= (ntbp->type & ASN_CONSTRUCTED);
if (ntbp->tag != -1)
{
if (tag > ASN_APPL_SPEC && (explicit & 1) && tag != ASN_CHOICE)
warn(15, (char *)tag);
else if (tag < 0)
{
tag_tb = ntbp->tag;
if (!(ntbp->tag & ASN_CONSTRUCTED) && (explicit & 1))
tag = ntbp->tag;
}
}
if (ntbp->generation < classgeneration)
{
add_child(subclass, (find_name(classname) -
(struct name_table *)name_area.area), 0, (long)-1, 0);
loop_test((struct name_table *)name_area.area, ntbp, 0);
}
if (type < 0) type = ntbp->type;
else if (subtype < 0) subtype = ntbp->type;
if ((explicit & 1)) tag |= ASN_CONSTRUCTED;
if (!max && ntbp->type != -1 && ntbp->type < ASN_CONSTRUCTED &&
(max = ntbp->max)) min = ntbp->min;
}
if (tag_tb == -1)
{
if (tag == -1) tag_tb = type;
else tag_tb = tag;
}
checkq(lasttagqp, tag_tb);
if ((option & ASN_OPTIONAL_FLAG) || (parenttype == ASN_CHOICE &&
!defined_by) || parenttype == ASN_SET) addq(&lasttagqp, tag_tb);
else if (lasttagqp) freeq(&lasttagqp);
print_item(itemname, prevname, tag, (option & ~ASN_TABLE_FLAG), max, min);
if (*defaultname && *defaultname != '{')
{
if (type != ASN_BOOLEAN)
fprintf(outstr, "%s.%s._flags |= ASN_DEFAULT_FLAG;\n", itemname,
defaultname);
else fprintf(outstr, "%s._default = 0x%x;\n", itemname,
(!strcmp(defaultname, "FALSE"))? 0: 0xFF);
}
strcpy(prevname, itemname);
}
/* step 4 */
if (*token != '}') end_item(); /* not last */
else if (state != SUB_ITEM) /* last, but not in components */
{
if (curr_pos > real_start) fprintf(outstr, finale);
if ((flags & ASN_TABLE_FLAG))
{
state = IN_DEFINITION;
if (flags & ASN_DEFINED_FLAG)
{
if (thisdefined++ >= numdefineds) state = GLOBAL;
else (classname[strlen(classname) - 1])++;
}
else
{
for (ctbp = find_name(classname), parentp = &ctbp->parent;
parentp; parentp = parentp->next)
{
if (parentp->index < 0) continue;
ptbp = &((struct name_table *)name_area.area)[parentp->index];
find_path(path, ptbp->name);
fprintf(outstr, derived_table, ptbp->name, ptbp->name, path,
strlen(path) + 1);
}
flags |= ASN_DEFINED_FLAG;
thisdefined = 1;
strcat(classname, "Defined");
}
if (state != GLOBAL) lseek(fd, tablepos, 0);
}
*prevname = 0;
if (lasttagqp) freeq(&lasttagqp);
parenttype = -1;
if (state != IN_DEFINITION) end_definition();
else end_item();
}
else return 0; /* last of components */
return 1;
}
static void addq(struct tagq **tagqp, long tmp)
{
struct tagq *tqp;
if (!*tagqp) *tagqp = tqp = (struct tagq *)calloc(sizeof(struct tagq), 1);
else
{
for (tqp = *tagqp ; tqp->next; tqp = tqp->next);
tqp->next = (struct tagq *)calloc(sizeof(struct tagq), 1);
tqp = tqp->next;
}
tqp->tag = tmp;
}
static void checkq(struct tagq *tagqp, long tmp)
{
for ( ; tagqp ; tagqp = tagqp->next)
{
if (tagqp->tag == tmp) break;
if (tagqp->tag >= ASN_APPL_SPEC || tmp > ASN_APPL_SPEC) continue;
if (tagqp->tag == ASN_ANY || tmp == ASN_ANY ||
tagqp->tag == ASN_CHOICE || tmp == ASN_CHOICE) break;
}
if (tagqp) warn(23, itemname);
}
static void find_path(char *path, char *tablenamep)
{
struct name_table *ntbp, *ptbp;
struct parent *parentp, *definerp, *definedp;
char *a, *b, *c;
int upcount;
definerp = definedp = (struct parent *)0;
ntbp = find_name(tablenamep);
for (parentp = &ntbp->parent; parentp && !definerp; parentp = parentp->next)
{
ptbp = (struct name_table *)&name_area.area[parentp->index *
sizeof(*ptbp)];
if ((ptbp->flags & ASN_DEFINER_FLAG)) definerp = &ptbp->parent;
}
if (!definerp) fatal(11, tablenamep);
for (parentp = &ntbp->parent, a = path; parentp; parentp = parentp->next)
{
ptbp = (struct name_table *)&name_area.area[parentp->index *
sizeof(*ptbp)];
if ((ptbp->flags & ASN_DEFINED_FLAG))
{
definedp = &ptbp->parent;
if (a > path) *a++ = ' ';
for (b = definerp->mymap, c = definedp->mymap; *b == *c; b++, c++);
for (upcount = &definerp->mymap[definerp->map_lth - 1] - b;
upcount--; *a++ = '-');
for(*a++ = *c++ - *b++ + '0'; *c; *a++ = *c++);
*a = 0;
}
}
}
static void freeq(struct tagq **tagqpp)
{
struct tagq *tqp, *ntqp;
for (tqp = *tagqpp; tqp; tqp = ntqp)
{
ntqp = tqp->next;
free((char *)tqp);
}
*tagqpp = (struct tagq *)0;
}
static int optional_def()
{
/**
Function: Determines if the defined item in a table can be absent
Inputs: Classname
Outputs:
0 if may not be absent
1 if may be
Procedure:
1. Find the name table entry for the table
Search each of its parents
IF the defined object is not OPTIONAL, return 0
Return 1
**/
struct name_table *ptbp, *ttbp = find_name(classname);
struct parent *parentp;
for (parentp = &ttbp->parent; parentp; parentp = parentp->next)
{
ptbp = &((struct name_table *)name_area.area)[parentp->index];
if ((ptbp->flags & ASN_DEFINED_FLAG) && !(ptbp->flags & ASN_OPTIONAL_FLAG))
return 0;
}
return 1;
}
static int print_flag(int option, char *string, int val)
{
fprintf(outstr, string);
if ((option &= ~val)) fprintf(outstr, " | ");
return option;
}
static void print_item(char *name, char *prevname, long tag, int option,
int max, int min)
{
/**
Procedure:
**/
char *b, *c;
c = dot;
b = "&";
if (!prevname || !*prevname) fprintf(outstr, first_item, b, name);
else fprintf(outstr, later_item, prevname, c, b, name);
fprintf(outstr, any_item, name, c);
if (tag > 0 && !find_class(tag)) fprintf(outstr, tag_xw, name, dot, tag);
if (max) fprintf(outstr, boundset, name, min, name, max);
option = set_options(option, name, c);
}
void print_of(int dup, int type)
{
char *c;
if (type > 0 && type < ASN_CONSTRUCTED && !(flags & ASN_ENUM_FLAG))
c = find_class(type);
else c = classname;
if ((dup & ASN_DUPED_FLAG)) fprintf(outstr, dup_func, classname, c, c);
if ((dup & ASN_DUPED_FLAG) && (type <= 0 || type >= ASN_CONSTRUCTED ||
(flags & ASN_ENUM_FLAG)))
fprintf(outstr, index_op, classname, classname, classname, classname);
}
static int set_options(int option, char *name, char *c)
{
if (option)
{
fprintf(outstr, "%s%s_flags |= (", name, c);
if ((option & ASN_OPTIONAL_FLAG)) option = print_flag(option,
"ASN_OPTIONAL_FLAG", ASN_OPTIONAL_FLAG);
if ((option & ASN_OF_FLAG)) option = print_flag(option,
"ASN_OF_FLAG", ASN_OF_FLAG);
if ((option & ASN_DEFAULT_FLAG)) option = print_flag(option,
"ASN_DEFAULT_FLAG", ASN_DEFAULT_FLAG);
if ((option & ASN_EXPLICIT_FLAG)) option = print_flag(option,
"ASN_EXPLICIT_FLAG", ASN_EXPLICIT_FLAG);
if ((option & ASN_ENUM_FLAG)) option = print_flag(option,
"ASN_ENUM_FLAG", ASN_ENUM_FLAG);
if ((option & ASN_POINTER_FLAG)) option = print_flag(option,
"ASN_POINTER_FLAG", ASN_POINTER_FLAG);
fprintf(outstr, ");\n");
}
return 0;
}
static void set_dup(char *classname, long tag)
{
if (tag == type)
fprintf(outstr, type_tag_w, "", "", "", "", find_define(tag));
else
{
if (tag > 0) fprintf(outstr, tag_xw, "", "", tag);
fprintf(outstr, type_xw, type);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -