Annotation of 40BSD/cmd/struct/2.dfs.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #
                      3: /* depth-first search used to identify back edges, unreachable nodes;
                      4:        each node v entered by back edge replaced by
                      5:        LOOPVX ->ITERVX -> v,
                      6:        so that back edges entering v now enter the ITERVX,
                      7:        and other edges entering v now enter the LOOPVX.
                      8:        Nodes are numbered according to depth-first search:
                      9:                before numbering- ntobef[v] = i => node numbered v is i'th
                     10:                        node in order of first visit during the search;
                     11:                after numbering- ntoaft[v] = i => node numbered v is i'th
                     12:                        node visited in order of last visit during the search.
                     13:                        Also, in this case after[i] = v.
                     14: */
                     15: 
                     16: #include "def.h"
                     17: #include "2.def.h"
                     18: 
                     19: #define MAXINS 3       /* spacing needed between numbers generated during depth first search */
                     20: 
                     21: int *status;
                     22: int befcount, aftcount;
                     23: /* following defines used to mark back edges and nodes entered by back edges */
                     24: #define UNPROCESSED    0
                     25: #define STACKED        1
                     26: #define FINISHED       2
                     27: #define MARK(v)        {REACH(v) = 1; }        /* mark node v */
                     28: #define UNMARK(v)      {REACH(v) = 0; }
                     29: #define MARKED(v)      (REACH(v))
                     30: #define MKEDGE(e)      {if (e >= -1) e = -(e+3); }     /* mark edge e */
                     31: #define UNMKEDGE(e)    {if (e < -1) e = -(e+3); }
                     32: #define BACKEDGE(e)    (e < -1)
                     33: 
                     34: 
                     35: dfs(v)         /* depth first search */
                     36: VERT v;
                     37:        {
                     38:        int i; VERT w;
                     39:        accessnum = 0;
                     40:        status = challoc(sizeof(*status) * nodenum);
                     41:        for (w = 0; w < nodenum; ++w)
                     42:                {
                     43:                status[w] = UNPROCESSED;
                     44:                UNMARK(w);
                     45:                }
                     46:        search(v);
                     47:        chreach();
                     48:        chfree(status, sizeof(*status) * nodenum);
                     49:        addloop();
                     50:        after = challoc(sizeof(*after) * accessnum);
                     51:        for (i = 0; i < accessnum; ++i)
                     52:                after[i] = UNDEFINED;
                     53:        ntoaft = challoc(sizeof(*ntoaft) * nodenum);
                     54:        ntobef = challoc(sizeof(*ntobef) * nodenum);
                     55:        for (w = 0; w < nodenum; ++w)
                     56:                ntobef[w] = ntoaft[w] = UNDEFINED;
                     57:        befcount = 0;
                     58:        aftcount = 0;
                     59:        repsearch(v);
                     60:        }
                     61: 
                     62: 
                     63: search(v)
                     64:        /* using depth first search, mark back edges using MKEDGE, and nodes entered by back
                     65:        edges using MARK */
                     66: VERT v;
                     67:        {
                     68:        VERT adj; int i;
                     69:        status[v] = STACKED;
                     70:        for(i = 0; i < ARCNUM(v); ++i)
                     71:                {
                     72:                adj = ARC(v,i);
                     73:                if (!DEFINED(adj)) continue;
                     74:                else if (status[adj] == UNPROCESSED)
                     75:                        search(adj);
                     76:                else if (status[adj] == STACKED)
                     77:                        {
                     78:                        MARK(adj);              /* mark adj as entered by back edge */
                     79:                        MKEDGE(ARC(v,i));       /* mark edge ARC(v,i) as being back edge */
                     80:                        }
                     81:                }
                     82:        status[v] = FINISHED;
                     83:        ++accessnum;
                     84:        }
                     85: 
                     86: chreach()              /* look for unreachable nodes */
                     87:        {
                     88:        VERT v;
                     89:        LOGICAL unreach;
                     90:        unreach = FALSE;
                     91:        for (v = 0; v < nodenum; ++v)
                     92:                if (status[v] == UNPROCESSED && NTYPE(v) != FMTVX
                     93:                        && NTYPE(v) != STOPVX && NTYPE(v) != RETVX)
                     94:                        {
                     95:                        unreach = TRUE;
                     96:                        if (debug)
                     97:                                fprintf(stderr,"node %d unreachable\n",v);
                     98:                        }
                     99:        if (unreach)
                    100:                error(": unreachable statements - ","will be ignored","");
                    101:        }
                    102: 
                    103: 
                    104: addloop()      /* add LOOPVX, ITERVX at nodes entered by back edges, and adjust edges */
                    105:        {
                    106:        VERT v, adj;
                    107:        int j, oldnum;
                    108:        for (v = 0, oldnum = nodenum; v < oldnum; ++v)  /* insloop increases nodenum */
                    109:                if (MARKED(v))
                    110:                        {
                    111:                        UNMARK(v);      /* remove mark indicating v entered by back edge */
                    112:                        if (NTYPE(v) != ITERVX)                 /* DO loops already have ITERVX */
                    113:                                 insloop(v);  /* add LOOPVX, ITERVX since v entered by back edge*/
                    114:                        }
                    115:        /* arcs which used to enter v now enter LOOPVX; must make back edges enter ITERVX */
                    116:        for (v = 0; v < nodenum; ++v)
                    117:                for (j = 0; j < ARCNUM(v); ++j)
                    118:                        {
                    119:                        if (BACKEDGE(ARC(v,j)))
                    120:                                {
                    121:                                UNMKEDGE(ARC(v,j));             /* return edge to normal value */
                    122:                                adj = ARC(v,j);
                    123:                                if (NTYPE(adj) == ITERVX) continue;
                    124:                                ASSERT(NTYPE(adj) == LOOPVX,addloop);
                    125:                                ARC(v,j) = ARC(adj,0);  /* change arc to point to ITERVX */
                    126:                                ASSERT(NTYPE(ARC(v,j)) == ITERVX,addloop);
                    127:                                }
                    128:                        }
                    129:        }
                    130: 
                    131: insloop(v)             /* insert LOOPVX, ITERVX at node number v */
                    132: VERT v;
                    133:        {
                    134:        VERT loo, iter;
                    135:        loo = create(LOOPVX, 1);
                    136:        iter = create(ITERVX,1);
                    137:        accessnum += 2;
                    138:        /* want LOOPVX to take on node number v, so that arcs other than back arcs
                    139:                entering v will enter the LOOPVX automatically */
                    140:        exchange(&graph[v], &graph[loo]);
                    141:        exchange(&v, &loo);
                    142:        ARC(loo,0) = iter;
                    143:        ARC(iter,0) = v;
                    144:        FATH(iter) = UNDEFINED; /* will be defined later along with FATH for DOVX */
                    145:        }
                    146: 
                    147: exchange(p1,p2)                /* exchange values of p1,p2 */
                    148: int *p1,*p2;
                    149:        {
                    150:        int temp;
                    151:        temp = *p1;
                    152:        *p1 = *p2;
                    153:        *p2 = temp;
                    154:        }
                    155: 
                    156: 
                    157: repsearch(v)           /* repeat df search in order to fill in after, ntoaft, ntobef tables */
                    158: VERT v;
                    159:        {
                    160:        VERT adj; int i,temp;
                    161:        ntobef[v] = befcount;
                    162:        ++befcount;
                    163:        for(i = 0; i < ARCNUM(v); ++i)
                    164:                {
                    165:                adj = ARC(v,i);
                    166:                if (DEFINED(adj) && ntobef[adj] == UNDEFINED)
                    167:                        repsearch(adj);
                    168:                }
                    169:        ++aftcount;
                    170:        temp = accessnum - aftcount;
                    171:        after[temp] = v;
                    172:        ntoaft[v] = temp;
                    173:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.