📄 asn_gen.c
字号:
Set its tag and flags
Go to its last filled in parent structure (note: items may have been
addeas children by find_definer without a known offset)
IF need another parent structure, make one
Fill in parent index
IF offset is >= 0, put count of this subordinate into mymap
**/
struct parent *parentp;
struct name_table *ntbp;
int ansr;
if (parent < 0) return parent;
ansr = add_name(name, type, option);
ntbp = &((struct name_table *)name_area.area)[ansr];
if (ntbp->type == 0xFFFFFFFF) ntbp->type = type;
ntbp->flags |= option;
for(parentp = &ntbp->parent; parentp->index >= 0 && parentp->map_lth > 0 &&
parentp->next; parentp = parentp->next);
if (parentp->index >= 0 && parentp->map_lth > 0)
{
if (!(parentp->next =
(struct parent *)calloc(sizeof(struct parent), 1)))
fatal(7, (char *)0);
parentp = parentp->next;
}
parentp->index = parent;
if (offset >= 0)
{
parentp->map_lth = 1;
if (!(parentp->mymap = calloc(16, 1))) fatal(7, (char *)0);
*parentp->mymap = offset + '0';
}
return ansr;
}
struct id_table *add_id(char *name)
{
struct id_table *idp, *eidp;
for(idp = (struct id_table *)id_area.area, eidp = &idp[id_area.next];
idp < eidp && strcmp(idp->name, name); idp++);
if (idp < eidp) fatal(17, name);
idp = (struct id_table *)expand_area(&id_area);
if (!(idp->name = calloc((strlen(name) + 1), 1))) fatal(7, (char *)0);
cat(idp->name, name);
id_area.next++;
return idp;
}
int add_include_name(char *fname)
{
char *b, *c;
int lth, xlth = 0;
if (xport) xlth = strlen(xport);
for (c = fname; *c; c++);
lth = c - fname;
while (c > fname && *(--c) != '.');
if (c > fname) lth = c - fname;
if ((!i_names && !(i_names = calloc(lth + 3 + xlth, 1))) ||
!(i_names = realloc(i_names, (i_namesize + lth + 3 + xlth))))
fatal(7, (char *)0);
strncpy((b = &i_names[i_namesize]), fname, lth);
c = cat(cat(&b[lth], ((xport)? xport: "")),".h");
lth = (c - b) + 1;
for (c = i_names; c < b && strcmp(c, b); ) /* eliminate duplicates */
{
while(*c++);
}
if (c >= b) return (i_namesize += lth);
else return 0;
}
int add_name(char *name, long tag, int option)
{
struct name_table *ntbp;
if (!name_area.area) ntbp = (struct name_table *)expand_area(&name_area);
ntbp = find_name(name);
if (!ntbp->name)
{
ntbp = (struct name_table *)expand_area(&name_area);
ntbp->name = calloc(strlen(name) + 1, 1);
ntbp->pos = ntbp->generation = ntbp->parent.index = -1;
strcpy(ntbp->name, name);
ntbp->tag = ntbp->type = ntbp->subtype = -1;
name_area.next++;
}
if (ntbp->type == -1) ntbp->type = tag;
ntbp->flags |= option;
return (ntbp - (struct name_table *)name_area.area);
}
void add_ub(char *name, int val)
{
struct ub_table *ubp, *eubp;
for(ubp = (struct ub_table *)ub_area.area, eubp = &ubp[ub_area.next];
ubp < eubp && strcmp(ubp->name, name); ubp++);
if (ubp < eubp) fatal(17, name);
ubp = (struct ub_table *)expand_area(&ub_area);
if (!(ubp->name = calloc(strlen(name) + 1, 1))) fatal(7, (char *)0);
cat(ubp->name, name);
ubp->val = val;
ub_area.next++;
}
void bclr(char *from, int lth)
{
while(lth--) *from++ = 0;
}
char *cat (s1,s2)
char *s1, *s2;
{
while ((*s1 = *s2++)) s1++;
return s1;
}
void clear_globals()
{
end_definition();
state = GLOBAL,
explicit = 3;
}
char *expand_area(struct name_area *area)
{
if (area->next + 1 >= area->size)
{
if ((area->size + area->chunk) > area->limit) fatal(9, area->name);
if ((!area->size && !(area->area = calloc((area->size = area->chunk),
area->item))) ||
(area->size && !(area->area = recalloc(area->area,
area->size * area->item,
((area->size + area->chunk) * area->item))))) fatal(7, (char *)0);
area->size += area->chunk;
}
return &area->area[area->next * area->item];
}
void fatal(int err, char *param)
{
if (!*classname) cat(classname, "(null}");
warn(err, param);
if (err) print_tables();
exit(err);
}
char *find_child(char *name)
{
struct name_table *ctbp, *ptbp = find_name(name);
struct parent *cparentp;
int curr_parent;
for(ctbp = (struct name_table *)name_area.area, curr_parent = ptbp - ctbp;
ctbp->name; ctbp++)
{
for(cparentp = &ctbp->parent; cparentp && cparentp->index != curr_parent;
cparentp = cparentp->next);
if (cparentp) return ctbp->name;
}
return (char *)0;
}
char *find_class(tag)
ulong tag;
{
struct tag_table *tagtbp;
for (tagtbp = tag_table; tagtbp->classname && tagtbp->tag != tag; tagtbp++);
return tagtbp->classname;
}
char *find_define(tag)
ulong tag;
{
struct tag_table *tagtbp;
for (tagtbp = tag_table; tagtbp->classname && tagtbp->tag != tag; tagtbp++);
return tagtbp->define;
}
int find_file(char *name)
{
char *c, buf[120];
int fd;
if ((fd = open(name, O_RDONLY)) >= 0) return fd;
for (c = i_paths; c < &i_paths[i_pathsize]; )
{
cat(cat(cat(buf, c), "/"), name);
if ((fd = open(buf, O_RDONLY)) >= 0) return fd;
while (*c++);
}
return fd;
}
struct id_table *find_id(char *name)
{
struct id_table *idp, *eidp;
for(idp = (struct id_table *)id_area.area, eidp = &idp[id_area.next];
idp < eidp && strcmp(idp->name, name); idp++);
if (idp && !idp->name) idp = (struct id_table *)0;
return idp;
}
struct name_table *find_name(char *name)
{
struct name_table *ntbp, *entbp;
for(ntbp = (struct name_table *)name_area.area,
entbp = &((struct name_table *)name_area.area)[name_area.next];
ntbp < entbp && wdcmp(name, ntbp->name); ntbp++);
return ntbp;
}
ulong find_type(char *string)
{
struct tag_table *tagtbp;
for (tagtbp = tag_table; tagtbp->classname && strcmp(string, tagtbp->string);
tagtbp++);
return tagtbp->tag;
}
char *find_typestring(ulong tag)
{
struct tag_table *tagtbp;
for (tagtbp = tag_table; tagtbp->classname && tagtbp->tag != tag; tagtbp++);
return tagtbp->string;
}
int find_ub(char *name)
{
struct ub_table *ntbp;
if (!(ntbp = is_ub(name))) fatal(16, name);
return ntbp->val;
}
void get_expected(int fd, ulong tag, char *name)
{
char *string, token[80];
if (tag == ASN_BITSTRING || (tag == ASN_OCTETSTRING && *name != 'E'))
string = "STRING";
else if (tag == ASN_OBJ_ID) string = "IDENTIFIER";
else return;
if (!get_token(fd, token, '(')) syntax(find_typestring(tag));
if (strcmp(token, string)) fatal(6, token);
strcat(strcat(name, " "), string);
}
void get_paren(int fd, char *token, int *min, int *max, int parent)
{
if (!get_token(fd, token, (char)0)) syntax("(");
if (!strcmp(token, size_w)) get_size(fd, token, min, max, parent);
else if (!get_token(fd, token, '(')) fatal(20, ")");
}
void get_size(int fd, char *token, int *min, int *max, int parent)
{
/**
Function: Gets min and max size from input
Returns: Min and max. Also token contains the item from which max was derived
Inputs: fd is file descriptor for input
token is a buffer
min and max are self-explanatory
**/
char *c, savec;
if (!get_token(fd, token, (char)0)) fatal(20, "("); /* gets the opening '(' */
if (!get_token(fd, token, '(')) syntax("("); /* gets the min..max */
c = token;
if (*c >= '0' && *c <= '9')
{
for(*min = 0; *c >= '0' && *c <= '9'; *min = (*min * 10) + *c++ - '0');
}
else
{
while (*c > ' ' && *c != '.' && *c != ')') c++;
savec = *c;
*c = 0;
*min = find_ub(token);
*c = savec;
}
while (*c == '.') c++;
if (*c == ')') return;
if (!*c) c = token;
if (*c >= '0' && *c <= '9')
{
for (*max = 0; *c >= '0' && *c <= '9'; *max = (*max * 10) +
*c++ - '0');
}
else *max = find_ub(c);
if (*c > '9') add_child(c, parent, 0, (ulong)-1, 0);
if (!get_token(fd, token, '(') || /* gets the ')' */
*token != ')') fatal(20, ")");
}
long get_tag(int fd, char *token)
{
/**
Procedure:
1. IF no next token, exit with fatal message
IF token is APPLICATION OR PRIVATE
Set tag to application specific
IF no next token, exit with fatal message
ELSE set tag to content specific
Get number in token
2. Return tag
**/
long tag, tmp;
char *c;
if (!get_token(fd, token, '(')) syntax("[");
if (!strncmp(token, application_w, 11) || !strncmp(token, private_w, 7))
{
if (*token == 'A') tag = ASN_APPL_SPEC;
else tag = ASN_PRIV_SPEC;
if (!get_token(fd, token, '(')) fatal (20, "]");
}
else tag = ASN_CONT_SPEC;
for(c = token, tmp = 0; *c && *c != ']'; tmp = (tmp * 10) + *c++ - '0');
if (!*c) syntax(token);
if (tmp < 31) tag |= tmp;
else
{
tag |= 31;
if (tmp >= (1 << 14)) tag |= 0x808000 + (((tmp & 0x7F) << 24) +
((tmp & 0x3F80) << 9)
+ ((tmp & 0x1FC000) >> 6));
else if (tmp >= (1 << 7)) tag |= 0x8000 + (((tmp & 0x7F) << 16) +
((tmp & 0x3F80) << 1));
else tag |= (tmp < 8);
}
return tag;
}
static char comma = 0;
int get_token(int fd, char *buf, char skip)
{
/**
Procedure:
1. IF previously ended with comma, brace or line end
IF it was comma or brace, return that
IF next char is EOF or line end, return line end
2. WHILE next character is <= space
IF char is line end AND next char is line end, return 1
IF EOF, return zero
IF first non-white was skip char, skip over (nested) skip partners
3. IF got '[' OR comma OR '(' OR '{' OR partner, advance pointer
ELSE
DO
Read into buffer until whitespace OR comma OR '{' OR '}' OR
semicolon is hit
IF buffer starts with '--', read to line end
WHILE buffer starts with '--'
IF reached printable terminator OR line end
IF beyond start of buffer, save that in 'comma'
ELSE advance pointer beyond this initial terminator
ELSE IF previous char is ']', back up one
Terminate the string
Return length of string
**/
char *c = buf;
int lth, parens;
char partner = 0;
if (comma) /* step 1 */
{
*c++ = comma; /* might be ',' or '}' or '\n' */
comma = *c = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -