Annotation of researchv10no/cmd/twig/walker.c1, revision 1.1.1.1

1.1       root        1: /*
                      2:  * The machine is laid out as a sequence of integers in the walker.
                      3:  * The form described above is only used inside the preprocessor.
                      4:  * Each machine state is one of the following sequence:
                      5:  *
                      6:  * TABLE <value_1><index_1>...<value_n><index_n> -1 [FAIL <fail_index>] -1
                      7:  * or
                      8:  * TABLE2 <value_1><index_1>...<value_n><index_n> -1 [FAIL <fail_index>] -1
                      9:  * or
                     10:  * ACCEPT <accept table index> -1
                     11:  *
                     12:  * The accept table is in the form:
                     13:  *
                     14:  * <tree index_1> ...<tree_index_m> -1
                     15:  *
                     16:  */
                     17: /* Keutzer - all "short int"'s have been changed to "short" for
                     18:    portability to UTS. */
                     19: #include "symbols.h"
                     20: /* Keutzer  1/88- _mtG now uses varargs for portability to SUN4 etc.*/
                     21: #include <varargs.h>
                     22: 
                     23: #ifndef FILE
                     24: #include <stdio.h>
                     25: #endif
                     26: #include <assert.h>
                     27: 
                     28: /* These constants must be the same as the ones in machine.c */
                     29: #define FASTLIM        0
                     30: #define TABLE  1
                     31: #define FAIL   2
                     32: #define ACCEPT 3
                     33: #define TABLE2 4
                     34: #define EOT    -1
                     35: 
                     36: /* special machine state */
                     37: #define HANG   -1
                     38: 
                     39: /* used by the evaluator to interpret path table */
                     40: #define        eSTOP   0
                     41: #define        ePOP    -1
                     42: #define eEVAL  -2
                     43: #define eNEXT  -3
                     44: #define ePUSH  -4
                     45: 
                     46: /* Tags that indicate the type of a value */
                     47: #define M_BRANCH 010000
                     48: #define M_NODE 0
                     49: #define M_LABEL 01000
                     50: #define MAX_NODE_VALUE 00777
                     51: #define MTAG_SHIFT 9
                     52: #define M_DETAG(x)     ((x)&~(M_BRANCH|M_LABEL|M_NODE))
                     53: 
                     54: /* predicates to tell whether a value x is of type NODE, BRANCH, or LABEL */
                     55: #define MI_NODE(x)     (((x)&(M_BRANCH|M_LABEL))==0)
                     56: #define MI_DEFINED(x)  ((x)!=-1)
                     57: #define MI_LABEL(x)    (((x)&M_LABEL)!=0)
                     58: #define MI_BRANCH(x)   (((x)&M_BRANCH)!=0)
                     59: 
                     60: /* build a tagged value */
                     61: #define MV_NODE(x)     (x)
                     62: #define MV_BRANCH(x)   ((x)|M_BRANCH)
                     63: #define MV_LABEL(x)    ((x)|M_LABEL)
                     64: 
                     65: /* limits */
                     66: /*
                     67:  * The depth of a pattern must be 7 or less.  Otherwise the type of he
                     68:  * partial mask in skeleton must be changed
                     69:  */
                     70: #define MAXDEPTH       7
                     71: 
                     72: /* modes */
                     73: #define xTOPDOWN       3
                     74: #define xABORT         2
                     75: #define xREWRITE       1
                     76: #define xDEFER         0
                     77: 
                     78: /* macros */
                     79: #define tDO(m) _do((m)->skel, (m), 1)
                     80: #define REWRITE        return(_m->cost = cost, xREWRITE)
                     81: #define TOPDOWN return(_m->cost = cost, xTOPDOWN)
                     82: #define ABORT return(xABORT)
                     83: 
                     84: /*
                     85:  * REORDER macro allows a knowledgeable user to change the order
                     86:  * of evaluation of the leaves.
                     87:  */
                     88: #ifndef REORDER
                     89: #define REORDER(list)  _evalleaves(list)
                     90: #endif
                     91: #define EVAL   REORDER(_ll)
                     92: 
                     93: #define mpush(s,m)     (m)->next = s, s = m
                     94: 
                     95: /* skeleton structure */
                     96: typedef struct skeleton skeleton;
                     97: typedef struct __match __match;
                     98: typedef struct __partial __partial;
                     99: typedef struct __hshcls        __hshcls;       /* a hashed closure entry */
                    100: typedef int labelset;                  /* a bit vector of labels */
                    101: 
                    102: struct __partial {
                    103:        unsigned char treeno;
                    104:        char bits;
                    105: };
                    106: 
                    107: struct __hshcls {
                    108:        __hshcls *next;
                    109:        labelset labels;
                    110:        int treecnt;            /* number of partial matches */
                    111:        __partial partial[MAXTREES];
                    112: };
                    113: 
                    114: struct skeleton {
                    115:        skeleton *sibling;
                    116:        skeleton *leftchild;            /* leftmost child */
                    117:        skeleton *rightchild;           /* rightmost child */
                    118:        NODEPTR root;
                    119:        NODEPTR parent;                 /* our parent */
                    120:        int nson;
                    121:        int treecnt;
                    122:        __match *succ[MAXLABELS];
                    123:        __partial *partial;
                    124:        __match *winner;
                    125:        COST mincost;
                    126: };
                    127: 
                    128: struct __match {
                    129:        __match **lleaves;      /* labelled leaves */
                    130:        skeleton *skel;         /* back pointer to associated skeleton node */
                    131:        COST cost;
                    132:        short tree;
                    133:        short mode;
                    134: };
                    135: 
                    136: struct freeb {
                    137:        struct freeb *next;
                    138: };
                    139: 
                    140: struct _mem {
                    141:         struct _mem *next;
                    142:         int size;       /* size of individual elements in bytes */
                    143:         int blkf;       /* blocking factor */
                    144:         int bsize;      /* block size */
                    145:         char *block;    /* block */
                    146:         int cnt;        /* count of free elem in block */
                    147:         char *freelist; /* free list */
                    148:         int totelem;    /* total number elements we have */
                    149:         int freecnt;    /* number of times mem_free was called */
                    150: };
                    151: 
                    152: /* turn this flag on if your machine has a fast byte string zero operation */
                    153: /*#define BZERO        1*/
                    154: int mtDebug = 0;
                    155: int treedebug = 0;
                    156: extern int _machstep();
                    157: extern short mtStart;
                    158: extern short mtTable[], mtAccept[], mtMap[], mtPaths[], mtPathStart[];
                    159: #ifdef LINE_XREF
                    160:        extern short mtLine[];
                    161: #endif
                    162: 
                    163: #ifndef MPBSIZE
                    164: #define MPBSIZE 8000
                    165: #endif
                    166: 
                    167: #ifdef ADDCOST
                    168: #define DEFAULT_COST sumleaves(_ll)
                    169: COST sumleaves(list) __match **list;
                    170: {COST cost;
                    171:  cost=ZEROCOST;
                    172:  for(; *list; list++)
                    173:    {ADDCOST((cost),(*list)->cost);
                    174:    }
                    175:  return cost;
                    176: }
                    177: #endif
                    178: 
                    179: extern NODEPTR mtGetNodes(), mtAction();
                    180: extern skeleton *_allocskel();
                    181: extern __match *_allocmatch();
                    182: extern __partial *_allocpartial();
                    183: 
                    184: __match *_mpblock[MPBSIZE], **_mpbtop;
                    185: 
                    186: __match **
                    187: _getleaves (mp, skp)
                    188:        register __match *mp; register skeleton *skp;
                    189: {
                    190:        skeleton *stack[MAXDEPTH];
                    191:        skeleton **stp = stack;
                    192:        register short *sip = &mtPaths[mtPathStart[mp->tree]];
                    193:        register __match **mmp = _mpbtop;
                    194:        __match **mmp2 = mmp;
                    195:        if((_mpbtop += *sip++ + 1) > &_mpblock[MPBSIZE]) {
                    196:                printf("Tree too large: make MPBSIZE larger.\n\
                    197: (i.e. cc -c -DMPBSIZE=%d walker.c)\n",MPBSIZE*2);
                    198:                assert(0);
                    199:        }
                    200: 
                    201:        for(;;)
                    202:                switch(*sip++) {
                    203:                case ePUSH:
                    204:                        *stp++ = skp;
                    205:                        skp = skp->leftchild;
                    206:                        break;
                    207: 
                    208:                case eNEXT:
                    209:                        skp = skp->sibling;
                    210:                        break;
                    211: 
                    212:                case eEVAL:
                    213:                        if ((mp = skp->succ[M_DETAG(*sip++)])==NULL) abort();
                    214:                        *mmp++ = mp;
                    215:                        break;
                    216: 
                    217:                case ePOP:
                    218:                        skp = *--stp;
                    219:                        break;
                    220: 
                    221:                case eSTOP:
                    222:                        *mmp = NULL;
                    223:                        return (mmp2);
                    224:                }
                    225: }
                    226: 
                    227: _evalleaves (mpp)
                    228:        register __match **mpp;
                    229: {
                    230:        for (; *mpp!=NULL; mpp++) {
                    231:                register __match *mp = *mpp;
                    232:                _do (mp->skel, mp, 1);
                    233:        }
                    234: }
                    235: 
                    236: 
                    237: _do(sp, winner, evalall)
                    238:        skeleton *sp; register __match *winner; int evalall;
                    239: {
                    240:        register __match **mpp;
                    241:        register skeleton *skel = winner->skel;
                    242:        if(winner==NULL) {
                    243:                _nowin(sp);
                    244:                return;
                    245:        }
                    246:        if(winner->mode==xDEFER || (evalall && winner->mode!=xTOPDOWN))
                    247:                REORDER(winner->lleaves);
                    248:        mtSetNodes (skel->parent, skel->nson,
                    249:                skel->root=mtAction (winner->tree, winner->lleaves, sp));
                    250: }
                    251: 
                    252: skeleton *
                    253: _walk(sp, ostate)
                    254:        register skeleton *sp;
                    255:        int ostate;
                    256: {
                    257:        int state, nstate, nson;
                    258:        register __partial *pp;
                    259:        register __match *mp, *mp2;
                    260:        register skeleton *nsp, *lastchild = NULL;
                    261:        NODEPTR son, root;
                    262: 
                    263:        root = sp->root;
                    264:        nson = 1; sp->mincost = INFINITY;
                    265:        state = _machstep (ostate, root, mtValue(root));
                    266: 
                    267:        while((son = mtGetNodes(root, nson))!=NULL) {
                    268:                nstate = _machstep (state, NULL, MV_BRANCH(nson));
                    269:                nsp = _allocskel();
                    270:                nsp->root = son;
                    271:                nsp->parent = root;
                    272:                nsp->nson = nson;
                    273:                _walk(nsp, nstate);
                    274:                if(COSTLESS(nsp->mincost,INFINITY)) {
                    275:                        assert (nsp->winner->mode==xREWRITE);
                    276:                        _do(nsp, nsp->winner, 0);
                    277:                        _freeskel(nsp);
                    278:                        continue;
                    279:                }
                    280:                _merge (sp, nsp);
                    281:                if (lastchild==NULL) sp->leftchild = nsp;
                    282:                else lastchild->sibling = nsp;
                    283:                lastchild = nsp;
                    284:                nson++;
                    285:        }
                    286: 
                    287:        for (pp = sp->partial; pp < &sp->partial[sp->treecnt]; pp++)
                    288:                if (pp->bits&01==1) {
                    289:                        mp = _allocmatch();
                    290:                        mp->tree = pp->treeno;
                    291:                        _addmatches (ostate, sp, mp);
                    292:                }
                    293:        if(son==NULL && nson==1)
                    294:                _closure (state, ostate, sp);
                    295: 
                    296:        sp->rightchild = lastchild;
                    297:        if (root==NULL) {
                    298:                COST c; __match *win; int i; nsp = sp->leftchild;
                    299:                c = INFINITY;
                    300:                win = NULL;
                    301:                for (i = 0; i < MAXLABELS; i++) {
                    302:                        mp = nsp->succ[i];
                    303:                        if (mp!=NULL && COSTLESS (mp->cost, c))
                    304:                                { c = mp->cost; win = mp; }
                    305:                }
                    306:                _do (nsp, win, 0);
                    307:        }
                    308:        return(sp);
                    309: }
                    310: 
                    311: /*
                    312:  * Convert the start state which has a large branching factor into
                    313:  * a index table.  This must be called before the matcher is used.
                    314:  */
                    315: static short _nodetab[MAXNDVAL], _labeltab[MAXLABELS];
                    316: _matchinit()
                    317: {
                    318:        short *sp;
                    319: /* Keutzer - this syntax doesn't work on UTS
                    320:        struct pair { short val, where } *pp; 
                    321: */
                    322:        struct pair { short val; short where; } *pp; 
                    323:        for (sp=_nodetab; sp < &_nodetab[MAXNDVAL]; sp++) *sp = HANG;
                    324:        for (sp=_labeltab; sp < &_labeltab[MAXLABELS]; sp++) *sp = HANG;
                    325:        sp = &mtTable[mtStart];
                    326:        assert (*sp==TABLE);
                    327:        for (pp = (struct pair *) ++sp; pp->val!=EOF; pp++) {
                    328:                if (MI_NODE(pp->val))
                    329:                        _nodetab[M_DETAG(pp->val)] = pp->where;
                    330:                else if (MI_LABEL(pp->val))
                    331:                        _labeltab[M_DETAG(pp->val)] = pp->where;
                    332:        }
                    333: }
                    334: 
                    335: int
                    336: _machstep(state, root, input)
                    337:        short state, input;
                    338:        NODEPTR root;
                    339: {
                    340:        register short *stp = &mtTable[state];
                    341:        int start = 0;
                    342:        if (state==HANG)
                    343:                return (input==(MV_BRANCH(1)) ? mtStart : HANG);
                    344: rescan:
                    345:        if (stp==&mtTable[mtStart]) {
                    346:                if (MI_NODE(input)) return(_nodetab[M_DETAG(input)]);
                    347:                if (MI_LABEL(input)) return(_labeltab[M_DETAG(input)]);
                    348:        }
                    349:        
                    350:        for(;;) {
                    351:                if(*stp==ACCEPT) stp += 2;
                    352: 
                    353:                if(*stp==TABLE) {
                    354:                        stp++;
                    355:                        while(*stp!=EOT) {
                    356:                                if(input==*stp) {
                    357:                                        return(*++stp);
                    358:                                }
                    359:                                stp += 2;
                    360:                        }
                    361:                        stp++;
                    362:                }
                    363:                if(*stp!=FAIL) {
                    364:                        if (start) return (HANG);
                    365:                        else { stp = &mtTable[mtStart]; start = 1;  goto rescan;}
                    366:                } else {
                    367:                        stp++;
                    368:                        stp = &mtTable[*stp];
                    369:                        goto rescan;
                    370:                }
                    371:        }
                    372: }
                    373: 
                    374: _addmatches(ostate, sp, np)
                    375:        int ostate;
                    376:        register skeleton *sp;
                    377:        register __match *np;
                    378: {
                    379:        int label;
                    380:        int state;
                    381:        register __match *mp;
                    382: 
                    383:         label = mtMap[np->tree];
                    384: 
                    385:        /*
                    386:         * this is a very poor substitute for good design of the DFA.
                    387:         * What we need is a special case that allows any label to be accepted
                    388:         * by the start state but we don't want the start state to recognize
                    389:         * them after a failure.
                    390:         */
                    391:        state = _machstep(ostate, NULL, MV_LABEL(label));
                    392:        if (ostate!=mtStart  && state==HANG) {
                    393:                _freematch(np);
                    394:                return;
                    395:        }
                    396: 
                    397:        np->lleaves = _getleaves (np, sp);
                    398:        np->skel = sp;
                    399:         if((np->mode = mtEvalCost(np, np->lleaves, sp))==xABORT)
                    400:        {
                    401:                _freematch(np);
                    402:                return;
                    403:        }
                    404: 
                    405: /*
                    406:        if(np->mode==xREWRITE && COSTLESS(np->cost, sp->mincost)) {
                    407:                sp->mincost = np->cost;
                    408:                sp->winner = np;
                    409:        }
                    410: */
                    411:        if ((mp = sp->succ[label])!=NULL) {
                    412:                if (!COSTLESS (np->cost, mp->cost))
                    413:                        { _freematch(np); return; }
                    414:                else _freematch(mp);
                    415:        }
                    416:        if(COSTLESS(np->cost,sp->mincost)) {
                    417:                if(np->mode==xREWRITE) {
                    418:                        sp->mincost = np->cost; sp->winner = np; }
                    419:                else { sp->mincost = INFINITY; sp->winner = NULL; }
                    420:        }
                    421:        sp->succ[label] = np;
                    422:        _closure(state, ostate, sp);
                    423: }
                    424: 
                    425: _closure(state, ostate, skp)
                    426:        int state, ostate;
                    427:        skeleton *skp;
                    428: {
                    429:        register struct ap { short tree, depth; } *ap;
                    430:        short *sp = &mtTable[state];
                    431:        register __match *mp;
                    432: 
                    433:        if(state==HANG || *sp!=ACCEPT) return(NULL);
                    434: 
                    435:        for(ap = (struct ap *) &mtAccept[*++sp]; ap->tree!=-1; ap++)
                    436:                if (ap->depth==0) {
                    437:                        mp = _allocmatch();     
                    438:                        mp->tree = ap->tree;
                    439:                        _addmatches (ostate, skp, mp);
                    440:                } else {
                    441:                        register __partial *pp, *lim = &skp->partial[skp->treecnt];
                    442:                        for(pp=skp->partial; pp < lim; pp++)
                    443:                                if(pp->treeno==ap->tree)
                    444:                                        break;
                    445:                        if(pp==lim) {
                    446:                                skp->treecnt++;
                    447:                                pp->treeno = ap->tree;
                    448:                                pp->bits = (1<<(ap->depth));
                    449:                        } else pp->bits |= (1<<(ap->depth));
                    450:                }
                    451: }
                    452: 
                    453: _merge (old, new)
                    454:        skeleton *old, *new;
                    455: {
                    456:        register __partial *op = old->partial, *np = new->partial;
                    457:        int nson = new->nson;
                    458:        register __partial *lim = np + new->treecnt;
                    459:        if (nson==1) {
                    460:                old->treecnt = new->treecnt;
                    461:                for(; np < lim; op++, np++) {
                    462:                        op->treeno = np->treeno;
                    463:                        op->bits = np->bits/2;
                    464:                }
                    465:        } else {
                    466:                __partial *newer = _allocpartial();
                    467:                register __partial *newerp = newer;
                    468:                register int cnt;
                    469:                lim = op+old->treecnt;
                    470:                for(cnt=new->treecnt; cnt-- ; np++) {
                    471:                        for(op = old->partial; op < lim; op++)
                    472:                                if (op->treeno == np->treeno) {
                    473:                                        newerp->treeno = op->treeno;
                    474:                                        newerp++->bits = op->bits & (np->bits/2);
                    475:                                        break;
                    476:                                }
                    477:                }
                    478:                _freepartial(old->partial);
                    479:                old->partial = newer;
                    480:                old->treecnt = newerp-newer;
                    481:        }
                    482: }
                    483:  
                    484: /* Save and Allocate Matches */
                    485: #define BLKF   100
                    486: __match *freep = NULL;
                    487: static int _count = 0;
                    488: static __match *_blockp = NULL;
                    489: #ifdef CHECKMEM
                    490: int x_matches, f_matches;
                    491: #endif
                    492: 
                    493: __match *
                    494: _allocmatch()
                    495: {
                    496:        __match *mp;
                    497: 
                    498:        if(freep!=NULL) {
                    499:                mp = freep;
                    500:                freep = ((__match *)((struct freeb *) freep)->next);
                    501: #ifdef CHECKMEM
                    502:                f_matches--;
                    503: #endif
                    504:        } else {
                    505:                if(_count==0) {
                    506:                        _blockp = (__match *) malloc (BLKF*sizeof (__match));
                    507:                        _count = BLKF;
                    508: #ifdef CHECKMEM
                    509:                        x_matches += BLKF;
                    510: #endif
                    511:                }
                    512:                mp = _blockp++;
                    513:                _count--;
                    514:        }
                    515:        return(mp);
                    516: }
                    517: 
                    518: _freematch(mp)
                    519:        __match *mp;
                    520: {
                    521:        ((struct freeb *) mp)->next = (struct freeb *) freep;
                    522:        freep = mp;
                    523: #ifdef CHECKMEM
                    524:        f_matches++;
                    525: #endif
                    526: }
                    527: 
                    528: static __partial *pfreep = NULL;
                    529: static int pcount = 0;
                    530: static __partial *pblock = NULL;
                    531: #ifdef CHECKMEM
                    532: static int x_partials, f_partials;
                    533: #endif
                    534: 
                    535: __partial *
                    536: _allocpartial()
                    537: {
                    538:        __partial *pp;
                    539:        if (pfreep!=NULL) {
                    540:                pp = pfreep;
                    541:                pfreep = *(__partial **) pp;
                    542: #ifdef CHECKMEM
                    543:                f_partials--;
                    544: #endif
                    545:        } else {
                    546:                if (pcount==0) {
                    547:                        pblock=(__partial *)malloc(BLKF*MAXTREES*sizeof(__partial));
                    548:                        pcount = BLKF;
                    549: #ifdef CHECKMEM
                    550:                        x_partials += BLKF;
                    551: #endif
                    552:                }
                    553:                pp = pblock;
                    554:                pblock += MAXTREES;
                    555:                pcount--;
                    556:        }
                    557:        return(pp);
                    558: }
                    559: 
                    560: _freepartial(pp)
                    561:        __partial *pp;
                    562: {
                    563:        * (__partial **)pp = pfreep;
                    564:        pfreep = pp;
                    565: #ifdef CHECKMEM
                    566:        f_partials++;
                    567: #endif
                    568: }
                    569: 
                    570: 
                    571: /* storage management */
                    572: static skeleton *sfreep = NULL;
                    573: static int scount = 0;
                    574: static skeleton * sblock = NULL;
                    575: 
                    576: skeleton *
                    577: _allocskel()
                    578: {
                    579:        skeleton *sp;
                    580:        int i;
                    581:        if(sfreep!=NULL) {
                    582:                sp = sfreep;
                    583:                sfreep = sp->sibling;
                    584:        } else {
                    585:                if(scount==0) {
                    586:                        sblock = (skeleton *) malloc (BLKF * sizeof (skeleton));
                    587:                        scount = BLKF;
                    588:                }
                    589:                sp = sblock++;
                    590:                scount--;
                    591:        }
                    592:        sp->sibling = NULL; sp->leftchild = NULL;
                    593:        for (i=0; i < MAXLABELS; sp->succ[i++] = NULL);
                    594:        sp->treecnt = 0;
                    595:        sp->partial = _allocpartial();
                    596:        return(sp);
                    597: }
                    598: 
                    599: _freeskel(sp)
                    600:        skeleton *sp;
                    601: {
                    602:        int i;
                    603:        __match *mp;
                    604:        if(sp==NULL) return;
                    605:        _freeskel (sp->leftchild);
                    606:        _freeskel (sp->sibling);
                    607:        _freepartial (sp->partial);
                    608:        for (i=0; i < MAXLABELS; i++)
                    609:                if ((mp = sp->succ[i])!=NULL) _freematch (mp);
                    610:        sp->sibling = sfreep;
                    611:        sfreep = sp;
                    612: }
                    613: 
                    614: _match()
                    615: {
                    616:        skeleton *sp;
                    617:        sp = _allocskel();
                    618:        sp->root = NULL;
                    619:        _mpbtop = _mpblock;
                    620:        _freeskel(_walk(sp, HANG));
                    621: #ifdef CHECKMEM
                    622:        if(f_matches+_count!=x_matches) {
                    623:                printf(";#m %d %d %d\n", f_matches, _count, x_matches);
                    624:                assert(0);
                    625:        }
                    626:        if(f_partials+pcount!=x_partials) {
                    627:                printf(";#p %d %d %d\n", f_partials, pcount, x_partials);
                    628:                assert(0);
                    629:        }
                    630: #endif
                    631: }
                    632: 
                    633: /* Keutzer  1/88- _mtG now uses varargs for portability to SUN4 etc.*/
                    634: NODEPTR _mtG(va_alist)
                    635: va_dcl
                    636: {
                    637:     NODEPTR root;
                    638:     int i=0;
                    639:     va_list p_var;
                    640:     va_start(p_var);
                    641:     root = va_arg(p_var,NODEPTR);
                    642:     while( (i = va_arg(p_var,int)) != -1){
                    643:         root = mtGetNodes(root, i);
                    644:     }
                    645:     va_end(p_var);
                    646:     return(root);
                    647: }
                    648: 
                    649: /* diagnostic routines */
                    650: #ifdef NOMARK
                    651: markIfNoMatch(skp,mark)
                    652:        skeleton *skp;
                    653:        int mark;
                    654: {}
                    655: #else
                    656: markIfNoMatch(skp,mark) skeleton *skp; int mark;
                    657: {skeleton *child; int i; int found=0;
                    658:  for(i=0; i<MAXLABELS; i++)
                    659:         if (skp->succ[i]) found=1;
                    660:  if (!found) skp->root->mark=mark;
                    661:  for(child=skp->leftchild; child; child=child->sibling)
                    662:        markIfNoMatch(child,mark);
                    663: }
                    664: #endif
                    665: 
                    666: _nowin(skp) skeleton *skp;
                    667: {
                    668:   markIfNoMatch(skp,1);
                    669:   printf("# No match was found for the nodes printed in lowercase\n");
                    670:   printTree(skp->root);
                    671:   markIfNoMatch(skp,0);
                    672: }

unix.superglobalmegacorp.com

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