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

📄 asn_tabulate.c

📁 ASN.1语法解析代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (!(ctbp->flags & ASN_FALSE_FLAG)) return ptbp;
    return last_false(table, ctbp);
    }
syntax("in last_false()");
return (struct name_table *)0;       /* just to keep lint happy */
}

static void massage_table(struct name_table *table)
{
/**
Function: Completes the table by filling in the full paths for all names
Procedure:
1. Clean up DEFINED BYs whose TABLEs had not been defined at the time the
       DEFINED BY was encountered (and flag pointer items) , thus:
   FOR each item in table
	IF its name indicates a pointer, set pointer flag
	IF it's not a DEFINED BY, continue
        IF it has parent which is a definer
    	    Find the TABLE which is a child of the definer
            Make it a child of the defined
    	    Remove the definer as a parent of the defined
2. FOR each name in table that has no parent AND is not a pointer
        Mark it generation 0 and count it
   IF no name in table has no parent, do loop test
3. Starting at generation 0, FOR successive generations WHILE have another
	generation
4.	FOR each parent in that generation
	    Find a map of the parent for this generation
5.	    FOR each child in the table
                Find a pointer to that parent
		IF none OR the child already has a map indicating a later
		    generation, continue in the FOR
		Prefix its path with its parent's path
		Set its generation to current generation + 1
		Note another generation to be done
6. FOR each name in table
	IF it is a derived TABLE
	    Look through its parents
                IF parent is a definer, set table's tag thus:
                    IF parent has a tag, to parent's tag
    		    ELSE (definer is not a universal), to grandparent's tag
                ELSE set the position of its defined parent to that of the
                    table (to make the header file entry come out right)
            Sort the parents in order of precedence
	ELSE IF it's a POINTER OR an OF item
	    IF it has any children that are false
		Trace them down (only 1 child each) to the last false one
		Mark that with the POINTER or OF flags of the main item
	    IF it's a POINTER and pointee's generation is younger than pointer's
		Make the pointee a child of the pointer (for export, if needed)
	IF item in table is FALSE
            Find its lowest false descendant
            Give all the false ancestors of that (only) descendant
		the type and tag(if they have none) of that descendant
   FOR each name in table
	IF it is a basic TABLE
            Set table's tag to parent's and parent's position to table's
7. For each generation up to the last
        Scan the table for items of that generation marked for export that
            have children not so marked and mark them for export.
**/
struct name_table *ptbp, *ctbp, *lftbp;
int curr_parent, generation, last, lth;
char *func = "massage_table";
struct parent *pparentp, *cparentp;
								/* step 1 */
for (ctbp = table; ctbp->name; ctbp++)
    {
    if (*ctbp->name == '_') ctbp->flags |= ASN_POINTER_FLAG;
    if (!(ctbp->flags & ASN_DEFINED_FLAG)) continue;
		    /* ctbp is a defined item */
    for(cparentp = &ctbp->parent; cparentp && cparentp->index >= 0;
        cparentp = cparentp->next)
	{
	ptbp = &((struct name_table *)name_area.area)[cparentp->index];
	if (!(ptbp->flags & ASN_DEFINER_FLAG)) continue;
                /* ptbp is the (only) definer item */
		/* cparentp is the item in the defined pointing to definer */
	for (lftbp = table; lftbp->name; lftbp++)
	    {
	    if (!(lftbp->flags & ASN_TABLE_FLAG)) continue;
	            /* lftbp is a table item */
    	    for (pparentp = &lftbp->parent; pparentp &&
                pparentp->index != cparentp->index; pparentp = pparentp->next);
			/* pparentp (if any) points to definer item */
	    if (pparentp) break;
	    }
	if (!lftbp->name)
	    {
	    cat(classname, ptbp->name);
            warn(19, ptbp->name);
	    continue;
	    }
      	         /* lftbp is the (only) TABLE child of definer */
	add_child(lftbp->name, (ctbp - table), 0, -1, 0);
        if (cparentp == &ctbp->parent)
	    {
	    if ((pparentp = cparentp->next))
		{
		*cparentp = *pparentp;
		free(pparentp);
		}
	    else fatal(24, func);
	    }
        else
	    {       /* find the one before, pparentp */
    	    for (pparentp = &ctbp->parent; pparentp && pparentp->next !=
    	        cparentp; pparentp = pparentp->next);
    	    if (!pparentp) fatal(24, func);
    	    pparentp->next = cparentp->next;
    	    free(cparentp);
    	    cparentp = pparentp;
	    }
	break;
	}
    }
							   /* step 2 */
for(ctbp = table, generation = 0; ctbp->name; ctbp++)
    {
    for(cparentp = &ctbp->parent; cparentp && cparentp->index >= 0;
	cparentp = cparentp->next)
	{
	ptbp = &((struct name_table *)name_area.area)[cparentp->index];
	if (!(ptbp->flags & ASN_POINTER_FLAG)) break;
	}
    if (!cparentp || cparentp->index < 0)
        {
        ctbp->generation = 0;
	generation++;
	}
    }
if (!generation && loop_test(table, table, 0))
    fatal(13, (char *)0);
								/* step 3 */
for(generation = last = 0; generation <= last; generation++)
    {
    for(ptbp = table; ptbp->name; ptbp++)                       /* step 4 */
	{
	if (ptbp->generation != generation) continue;
	curr_parent = ptbp - table;
        for(pparentp = &ptbp->parent, lth = 0; pparentp;
	    pparentp = pparentp->next)
	    {
	    if (pparentp->map_lth == generation) break;
	    }
								/* step 5 */
	for(ctbp = table; ctbp->name; ctbp++)
	    {
	    for(cparentp = &ctbp->parent; cparentp; cparentp = cparentp->next)
	        {
		if (cparentp->index != curr_parent) continue;
    	        if (generation > 31 && loop_test(table, ptbp, 0))
                    fatal(13, (char *)0);
                if (((pparentp->map_lth + 2) >> 4) > (cparentp->map_lth >> 4))
    	            {
                    if (!(cparentp->mymap = recalloc(cparentp->mymap,
                        cparentp->map_lth, ((pparentp->map_lth + 17) & ~0xF))))
                        fatal(7, (char *)0);;
    	            }
                cparentp->mymap[pparentp->map_lth] =
                    cparentp->mymap[cparentp->map_lth - 1];
                strncpy(cparentp->mymap, pparentp->mymap, pparentp->map_lth);
                cparentp->map_lth = pparentp->map_lth + 1;
    	        if ((last = generation + 1) > ctbp->generation)
                     ctbp->generation = last;
	        }
	    }
	}
    }
for(ctbp = table; ctbp->name; ctbp++)				/* step 6 */
    {
    if ((ctbp->flags & ASN_TABLE_FLAG) && ctbp->pos < real_start)
	{
        for(cparentp = &ctbp->parent, lth = 0; cparentp;
    	    cparentp = cparentp->next)
    	    {
    	    if (cparentp->index < 0) continue;
    	    ptbp = &table[cparentp->index];
    	    if ((ptbp->flags & ASN_DEFINER_FLAG))
		{
		if (ptbp->type != 0xFFFFFFFF) ctbp->type = ptbp->type;
                else ctbp->type = table[ptbp->parent.index].type;
		if (lth++) fatal(25, ctbp->name);
		}
    	    else if ((ptbp->flags & ASN_DEFINED_FLAG)) ptbp->pos = ctbp->pos;
    	    }
        sort_defineds(ctbp);;
        }
    else if ((ctbp->flags & (ASN_OF_FLAG | ASN_POINTER_FLAG)))
	{
	curr_parent = (ctbp - table);
	for (ptbp = table; ptbp->name; ptbp++)
	    {
	    for(pparentp = &ptbp->parent; pparentp; pparentp = pparentp->next)
		{
		if (pparentp->index != curr_parent) continue;
		if ((ptbp->flags & ASN_FALSE_FLAG))
		    last_false(table, ptbp)->flags |=
                    ((ctbp->flags & (ASN_OF_FLAG | ASN_POINTER_FLAG)));
		}
	    }
	if (*ctbp->name == '_' &&
	    find_name(&ctbp->name[1])->generation <= ctbp->generation)
	    add_child(&ctbp->name[1], curr_parent, 0, -1,
            (ctbp->flags & ASN_EXPORT_FLAG));
	}
    if ((ctbp->flags & ASN_FALSE_FLAG))
	{
	curr_parent = ((lftbp = last_false(table, ctbp)) - table);
	for (ptbp = table; ptbp->name; ptbp++)
	    {
            for (pparentp = &ptbp->parent; pparentp &&
                pparentp->index != curr_parent; pparentp = pparentp->next);
	    if (pparentp) break;
	    }
	  /* ptbp is child of lftbp, i.e. the non-false item */
	if (!ptbp->name) fatal(5, lftbp->name);
	set_false(table, ptbp);
	}
    }
for(ctbp = table; ctbp->name; ctbp++)
    {
    if ((ctbp->flags & ASN_TABLE_FLAG) && ctbp->pos >= real_start)
	{
    	ptbp = &table[ctbp->parent.index];
    	ctbp->type = ptbp->type;
	ptbp->pos = ctbp->pos;
	}
    }
							        /* step 7 */
for(generation = 0; generation <= last; generation++)
    {
    for(ptbp = table; ptbp->name; ptbp++)
	{
	if (ptbp->generation == generation &&
            (ptbp->flags & (ASN_EXPORT_FLAG | ASN_SUB_EXPORT_FLAG)))
	    {
	    curr_parent = ptbp - table;
	    for(ctbp = table; ctbp->name; ctbp++)
		{
                for(cparentp = &ctbp->parent, lth = 0; cparentp;
            	    cparentp = cparentp->next)
            	    {
            	    if (cparentp->index != curr_parent) continue;
		    ctbp->flags |= ASN_SUB_EXPORT_FLAG;
		    if (*ctbp->name == '_')
			find_name(&ctbp->name[1])->flags |= ASN_SUB_EXPORT_FLAG;
		    }
		}
	    }
	}
    }
}

static void mk_table_child(int fd, int parent, int offset, int option)
{
/*
Procedure:
1. Add this as a child of the current parent with the DEFINED flag and the, if
        it is in option, the OPTIONAL flag
2. IF the defining object name isn't in the object table OR it
         appears more than once, fatal error
3. IF there's a table item that is a child of the defining object
        Make that table item also a child of this defined object
   ELSE make this defined object a child of the definer (this will be sorted out
        at the end when the table has been defined
*/
int child;
struct name_table *ntbp, *entbp, *tntbp;
struct parent *parentp;
if (parent < 0) return;
child = add_child(defined_by, parent, offset, (ulong)ASN_CHOICE,     /* step 1 */
    (ASN_DEFINED_FLAG | (option & ASN_OPTIONAL_FLAG)));
if (!(ntbp = find_definer(fd, definer, parent)) || !ntbp->name)
    {
    warn(19, definer);
    return;
    }
tntbp = (struct name_table *)name_area.area;
parent = ntbp - tntbp;
for (entbp = &tntbp[name_area.next]; tntbp < entbp; tntbp++)  /* step 3 */
    {
    if (!(tntbp->flags & ASN_TABLE_FLAG)) continue;
    for(parentp = &tntbp->parent; parentp && parentp->index != parent;
	parentp = parentp->next);
    if (parentp) break;
    }
if (tntbp < entbp)
    {
    add_child(tntbp->name, child, 0, (ulong)-1, 0);
    ntbp  = &((struct name_table *)name_area.area)[child];
    ntbp->pos = tntbp->pos;
    }
else add_child(defined_by, parent, offset, (ulong)ASN_CHOICE, ASN_DEFINED_FLAG);
}

void set_false(struct name_table *table, struct name_table *ctbp)
{
/**
Function: Sets the type of all parents of this item which are flagged FALSE
    to this item's type.  It is recursive
Inputs: pointer to start of table
	pointer to this item in the table
**/
struct parent *pparentp;
struct name_table *ptbp;
for (pparentp = &ctbp->parent; pparentp; pparentp = pparentp->next)
    {
    if (pparentp->index >= 0 &&
        ((ptbp = &table[pparentp->index])->flags & ASN_FALSE_FLAG))
	{
	ptbp->type = ctbp->type;
	if (ptbp->tag == 0xFFFFFFFF) ptbp->tag = ctbp->tag;
	set_false(table, ptbp);
	}
    }
}

static void copy_parent(struct parent *to, struct parent *from)
{
to->index = from->index;
to->map_lth = from->map_lth;
to->mymap = from->mymap;
}

static void sort_defineds(struct name_table *ntbp)
{
struct parent tparent, *parentp, *nparentp, *pparentp;
do
    {
    for (nparentp = (parentp = &ntbp->parent)->next;
        nparentp && strcmp(parentp->mymap, nparentp->mymap) <= 0;
        pparentp = parentp, nparentp = (parentp = parentp->next)->next);
    if (nparentp)
	{
	if (parentp == &ntbp->parent)
	    {
	    copy_parent(&tparent, parentp);
	    copy_parent(parentp, nparentp);
	    copy_parent(nparentp, &tparent);
	    }
	else
	    {
	    pparentp->next = nparentp;
	    parentp->next =  nparentp->next;
	    nparentp->next = parentp;
	    }
	}
    }
while(nparentp);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -