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

📄 asn_gen.c

📁 ASN.1语法解析代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   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 + -