📄 asn_tabulate.c
字号:
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 + -