Annotation of researchv10no/cmd/cfront/optcfront/tree_walk.c, revision 1.1.1.1

1.1       root        1: /* ident "@(#)ctrans:src/tree_walk.c   1.2" */
                      2: /* 
                      3:        tree_walk.c
                      4:        Utilities for tree-walking 
                      5: */
                      6: 
                      7: #include "cfront.h"
                      8: #include "tree_walk.h"
                      9: #include <stdarg.h>
                     10: #include "hash.h"
                     11: // #include <alloca.h>
                     12: // ************ need to add an explicit call of free
                     13: // ************ make it an ifdef
                     14: // ??? #include <streamdefs.h>
                     15: #include <malloc.h>
                     16: 
                     17: class walker {
                     18:     tree_walk_control control;
                     19:     Pnode orig_addr;
                     20:     Hash *nodes_seen_hash;
                     21:     int depth;
                     22:     int made_ht;
                     23:     tree_walk_tree * cur_tree;
                     24:   public:
                     25:     walker(tree_walk_control& c) ;
                     26:  
                     27:     ~walker () {
                     28:        if(made_ht) delete nodes_seen_hash;
                     29:     }
                     30:     tree_node_action walk (Pnode&);
                     31:     tree_node_action walk_ (Pnode& n) 
                     32:     {
                     33:        if(n) {
                     34:            int save_depth = depth;
                     35:            tree_walk_tree * save_cur_tree = cur_tree;
                     36: 
                     37:            depth ++;
                     38:            if(control.alloc_stack_bytes) {
                     39:                cur_tree = (tree_walk_tree *)
                     40:                    // alloca (control.alloc_stack_bytes + sizeof (tree_walk_tree));
                     41:                    malloc(control.alloc_stack_bytes + sizeof (tree_walk_tree));
                     42:                cur_tree->parent = save_cur_tree;
                     43:            }
                     44:            tree_node_action r = walk(n);
                     45:            depth = save_depth;
                     46:            return r;
                     47:        } else return tna_continue;
                     48:     }
                     49:        
                     50:     tree_node_action walk(Pgen& n) 
                     51:     { return walk_ ((struct node * &)n); };
                     52:     tree_node_action walk(Pvec& n) 
                     53:     { return walk_ ((struct node * &)n); };
                     54:     tree_node_action walk(Pptr& n) 
                     55:     { return walk_ ((struct node * &)n); };
                     56:     tree_node_action walk(Ptype& n) 
                     57:     { return walk_ ((struct node * &)n); };
                     58:     tree_node_action walk(Pfct& n) 
                     59:     { return walk_ ((struct node * &)n); };
                     60:     tree_node_action walk(Ptable& n) 
                     61:     { return walk_ ((struct node * &)n); };
                     62:     tree_node_action walk(Pbase& n) 
                     63:     { return walk_ ((struct node * &)n); };
                     64:     tree_node_action walk(Pname& n) 
                     65:     { return walk_ ((struct node * &)n); };
                     66:      tree_node_action walk(Pexpr& n) 
                     67:     { return walk_ ((struct node * &)n); };
                     68:     tree_node_action walk(Pstmt& n) 
                     69:     { return walk_ ((struct node * &)n); };
                     70:     tree_node_action walk(Pblock& n) 
                     71:     { return walk_ ((struct node * &)n); };
                     72:     tree_node_action walk(Penum& n) 
                     73:     { return walk_ ((struct node * &)n); };
                     74:     tree_node_action walk(Pclass& n) 
                     75:     { return walk_ ((struct node * &)n); };
                     76:     tree_node_action walk(Pvirt& n) 
                     77:     { return walk_ ((struct node * &)n); };
                     78:     tree_node_action walk(Plist& n) 
                     79:     { return walk_ ((struct node * &)n); };
                     80:     tree_node_action walk(Pin& n) 
                     81:     { return walk_ ((struct node * &)n); };
                     82:     tree_node_action walk(struct ia * & n) 
                     83:     { return walk_ ((struct node * &)n); };
                     84:     tree_node_action walk(Pbcl& n) 
                     85:     { return walk_ ((struct node * &)n); };
                     86:   private:
                     87:     int fetching () {  return (control.fetcher != null_tfp); } ;
                     88:     void free_fetched (void *);
                     89:     int fetch (void *, unsigned long, void *&);
                     90:     int fetch (void * a, unsigned long l, Pnode& p) 
                     91:     {
                     92:        int ret;
                     93:        void * t;               /* this is an output argument */
                     94:        ret = fetch(a,l,t);
                     95:        if(!ret) {
                     96:            p = Pnode(t);
                     97:        }
                     98:        return ret;
                     99:     };
                    100:     // void error (const char *,...); ?? at&t -- to get it up quick, line 155
                    101:     void error ( char *, unsigned long=0 );
                    102:     tree_node_action pre_act_on_node (Pnode node, node_class nc,
                    103:                                      Pnode node_copy, Pnode& replacement);
                    104:                                       
                    105:     tree_node_action a_gen (Pnode, Pgen, Pnode&);
                    106:     tree_node_action a_vec (Pnode, Pvec, Pnode&);
                    107:     tree_node_action a_ptr (Pnode, Pptr, Pnode&);
                    108:     tree_node_action a_fct (Pnode, Pfct, Pnode&);
                    109:     tree_node_action a_table (Pnode, Ptable, Pnode&);
                    110:     tree_node_action a_basetype (Pnode, Pbase, Pnode&);
                    111:     tree_node_action a_name(Pnode, Pname, Pnode&);
                    112:     tree_node_action a_expr (Pnode, Pexpr, Pnode&);
                    113:     tree_node_action a_stmt (Pnode, Pstmt, Pnode&);
                    114:     tree_node_action a_enumdef (Pnode, Penum, Pnode&);
                    115:     tree_node_action a_classdef (Pnode, Pclass, Pnode&);
                    116:     tree_node_action a_virt (Pnode, Pvirt, Pnode&);
                    117:     tree_node_action a_name_list (Pnode, Plist, Pnode&);
                    118:     tree_node_action a_iline (Pnode, Pin, Pnode&);
                    119:     tree_node_action a_ia (Pnode, struct ia *, Pnode&);
                    120:     tree_node_action a_baseclass (Pnode, Pbcl, Pnode&);
                    121:     tree_node_action a_expr_guts (Pexpr);
                    122: };
                    123: 
                    124: 
                    125: walker::walker(tree_walk_control& c) 
                    126: { control = c;
                    127:   made_ht = 0;
                    128:   if (c.nodes_seen_hash)
                    129:     nodes_seen_hash = c.nodes_seen_hash;
                    130:   else {
                    131:     nodes_seen_hash = new pointer_hash (100);
                    132:     made_ht = 1;
                    133:   }
                    134:   depth = 0;
                    135:   cur_tree = 0;
                    136: }
                    137: 
                    138: 
                    139: tree_node_action
                    140: walk_tree (tree_walk_control& c, Pnode& n)
                    141: {
                    142:     walker w (c);
                    143:     return w.walk(n);
                    144: }
                    145: 
                    146: 
                    147: /* error messages are of finite length, so no need to run
                    148:    around mallocing strings */
                    149: 
                    150: // void walker::error (const char * format, ...)
                    151: void walker::error (char *format, unsigned long v)
                    152: {
                    153:     va_list args;
                    154:     va_start(args, format);
                    155:     if(control.call_i_error) {
                    156:        char buf[1000];
                    157:        // vsprintf(buf, format, args);
                    158:         // vsprintf not universal: by inspection
                    159:         // all calls are currently of 1 or 0 arguments
                    160:        sprintf(buf, format, v);
                    161:        (*control.i_error)('i', buf);
                    162:     } else {
                    163:        vostream_printf (format, args, *control.error_stream);
                    164:        *control.error_stream << "\n";
                    165:        control.error_stream->flush();
                    166:     }
                    167:     va_end (args);
                    168: }
                    169: 
                    170: 
                    171: void
                    172: walker::free_fetched (void * addr)
                    173: {
                    174:     if (control.fetcher != null_tfp)   /* null indicates no cross-address-space */
                    175:        free ((char *)addr);    
                    176: }    
                    177: 
                    178: int
                    179: walker::fetch (void * addr, unsigned long length, void*& taddr)
                    180: {
                    181:     int err;
                    182: 
                    183:     if (control.fetcher == null_tfp) { 
                    184:        taddr = addr;
                    185:        return 0;
                    186:     } else {
                    187:        taddr = (void *)malloc ((unsigned int)length);
                    188:        if(taddr == 0) {
                    189:           error ("walker::fetch: failed to malloc %d bytes.", length);
                    190:           return 1;
                    191:        }
                    192: 
                    193:        err = (*control.fetcher) (control.callback_info, addr, length, 0, taddr);
                    194:        if(err) {
                    195:           error("walker::fetch: fetcher returned %d.", err);
                    196:           return 1;
                    197:        }
                    198:    }
                    199: }
                    200: 
                    201: /* ::walk is called with a node pointer and a reference to
                    202:    a replacement node pointer. When it returns,
                    203:    replacement will be set if the action procedure
                    204:    called on the node decided to copy it or replace it.
                    205:    There are two possible modularities. 
                    206:    In case there is cross-address-space action,
                    207:    ::walk can't call the action procedure until it has
                    208:    entered the case on node bases. Once it has,
                    209:    it calls the per-structure-type procedure,
                    210:    which calls the action proc. If the action 
                    211:    proc supplies a replacement, then that replacement
                    212:    will be returned up via the reference parameters to 
                    213:    the per-structure procedures.
                    214: 
                    215:    It the action procedure returns tna_continue,
                    216:    then the walk continues against the new copy of the node
                    217:    so that further replacements are reflected in the new copies.
                    218:    This prevents replacement from being meaningful cross-address-space,
                    219:    since the new copy will presumably be in the current 
                    220:    (and not the cross) address space. That is, if the node
                    221:    is replaced by the action proc, the pointers in the new 
                    222:    node will drive the subsequent tree walk. Usually one
                    223:    would just bitcopy, and then they would be replaced in turn.
                    224: */
                    225: 
                    226: tree_node_action
                    227: walker::walk (Pnode& top)
                    228: {
                    229:     Pnode replacement = 0;
                    230:     tree_node_action err;
                    231:     int class_err;
                    232:     node_class nclass;
                    233:     Pnode node = 0; /* assign to shut up compiler,
                    234:                       which dosen't recognize pass-by-reference as a set */
                    235: 
                    236:     orig_addr = top;
                    237: 
                    238:     if(fetching ()) {
                    239:        if(fetch((void *)top, sizeof (struct node), node))
                    240:            return tna_error;
                    241:     } else node = top;
                    242: 
                    243: /* This has a complete catalog of bases, rather than just a list
                    244:    of those associated with data structures. Its important
                    245:    to detect the errs.
                    246: */   
                    247: 
                    248:     nclass = classify_node (node, class_err);
                    249: 
                    250:     if(class_err) {
                    251:        error("walker::walk: unknown node type %d.", node->base);
                    252:        free_fetched ((void *)node);
                    253:        err = tna_error;
                    254:        goto Return;
                    255:     }
                    256:     
                    257:     switch(nclass)
                    258:     {
                    259:       default:
                    260:       case nc_unused:
                    261:        error("walker::walk: unused node type %d.", node->base);
                    262:        err = tna_error;
                    263:        goto Return;
                    264: 
                    265:       case nc_eof:
                    266:        break;
                    267: 
                    268:       case nc_virt:
                    269:        fetch((void *)top, sizeof (struct virt), node);
                    270:        err = a_virt(top, Pvirt (node), replacement);
                    271:        break;
                    272: 
                    273:       case nc_nlist:
                    274:        fetch((void *)top, sizeof (struct name_list), node);
                    275:        err = a_name_list(top, (struct name_list *)node, replacement);
                    276:        break;
                    277: 
                    278:       case nc_iline:
                    279:        fetch((void *)top, sizeof (struct iline), node);
                    280:        err = a_iline(top, (struct iline *)node, replacement);
                    281:        break;
                    282: 
                    283:       case nc_gen:
                    284:        fetch((void *)top, sizeof (struct gen), node);
                    285:        err = a_gen(top, Pgen (node), replacement);
                    286:        break;
                    287: 
                    288:       case nc_vec:
                    289:        fetch((void *)top, sizeof (struct vec), node);
                    290:        err = a_vec(top, Pvec(node), replacement);
                    291:        break;
                    292: 
                    293:       case nc_ptr:
                    294:        fetch((void *)top, sizeof (struct ptr), node);
                    295:        err = a_ptr(top, Pptr(node), replacement);
                    296:        break;
                    297: 
                    298:       case nc_fct:
                    299:        fetch((void *)top, sizeof (struct fct), node);
                    300:        err = a_fct(top, Pfct(node), replacement);
                    301:        break;
                    302: 
                    303:       case nc_table:
                    304:        fetch((void *)top, sizeof (struct table), node);
                    305:        err = a_table(top, Ptable(node), replacement);
                    306:        break;
                    307: 
                    308:       case nc_basetype:
                    309:        fetch((void *)top, sizeof (struct basetype), node);
                    310:        err = a_basetype(top, Pbase(node), replacement);
                    311:        break;
                    312: 
                    313:       case nc_name:
                    314:        fetch((void *)top, sizeof (struct name), node);
                    315:        err = a_name(top, Pname(node), replacement);
                    316:        break;
                    317: 
                    318:       case nc_expr:
                    319:        fetch((void *)top, sizeof (struct expr), node);
                    320:        err = a_expr(top, Pexpr(node), replacement);
                    321:        break;
                    322: 
                    323:       case nc_stmt:
                    324:        fetch((void *)top, sizeof (struct stmt), node);
                    325:        err = a_stmt(top, Pstmt(node), replacement);
                    326:        break;
                    327: 
                    328:       case nc_enumdef:
                    329:        fetch((void *)top, sizeof (struct enumdef), node);
                    330:        err = a_enumdef(top, Penum(node), replacement);
                    331:        break;
                    332: 
                    333:       case nc_classdef:
                    334:        fetch((void *)top, sizeof (struct classdef), node);
                    335:        err = a_classdef(top, Pclass(node), replacement);
                    336:        break;
                    337: 
                    338:       case nc_ia:
                    339:        fetch((void *)top, sizeof (struct ia), node);
                    340:        err = a_ia(top, (struct ia *)node, replacement);
                    341:        break;
                    342: 
                    343:       case nc_baseclass:
                    344:        fetch((void *)top, sizeof (struct basecl), node);
                    345:        err = a_baseclass(top, Pbcl(node), replacement);
                    346:        break;
                    347: 
                    348:     }
                    349: 
                    350:     if(replacement) {
                    351:        if (fetching ()) {
                    352:            error
                    353:                ("walker::walk: Attempt to replace tree in cross-address space mode.");
                    354:            err = tna_error;
                    355:        } 
                    356:        else top = replacement;
                    357:     }
                    358:        
                    359:     if (control.post_action_proc && err != tna_error) {
                    360:        tree_node_action post_err;
                    361:        Pnode& post_repl = node;
                    362: 
                    363:        (*control.post_action_proc) (post_repl, nclass, control.callback_info, post_err,
                    364:                                     depth, orig_addr, *cur_tree);
                    365:        if(post_err != tna_continue) err = post_err;
                    366:        if(post_repl != node) {
                    367:            if (fetching ()) {
                    368:                error
                    369:                    ("walker::walk: Attempt to replace tree in cross-address space mode.");
                    370:                err = tna_error;
                    371:            } 
                    372:            else top = post_repl;
                    373:        }
                    374:     }
                    375: 
                    376:     free_fetched((void *) node);
                    377: 
                    378: Return:
                    379:     return err;
                    380: }
                    381: 
                    382: /* This is called in pre-order for each node. Then
                    383:    post_act_on_node is called after whatever recursive
                    384:    processing ensues.
                    385:    
                    386:    This is called from each of the structure-specific procedures
                    387:    to give the action procedure an opportunity to act.
                    388:    It can return a replacement pointer and control
                    389:    whether to examine the insides of the node.
                    390:    */
                    391: 
                    392: tree_node_action 
                    393: walker::pre_act_on_node (Pnode node, node_class nc,
                    394:                       Pnode node_copy, Pnode& replacement)
                    395: {
                    396: /* If we have been here before, then we never proceed */
                    397: /* node_copy is != node when a fetcher is in use */
                    398: 
                    399:     int found;
                    400:     int old_node;
                    401:     tree_node_action action;
                    402:     Pnode new_node;
                    403:     int register_in_hash = 1;
                    404: 
                    405:     nodes_seen_hash->action((int)node, 0, Hash::probe, found, old_node);
                    406: 
                    407:     if(found) {
                    408:        new_node = Pnode(old_node);
                    409:        if(new_node != node) replacement = new_node;
                    410:        return tna_stop; /* no need to proceed */
                    411:     }
                    412: 
                    413:     /* OK, we don't know from a previous pass. Call our actor */
                    414: 
                    415:     new_node = fetching () && node_copy ? node_copy : node;
                    416: 
                    417:     (*control.action_proc)(new_node, nc, control.callback_info, action, 
                    418:                           depth, orig_addr, *cur_tree,
                    419:                           register_in_hash);
                    420: 
                    421:     if(action != tna_error && !fetching () && new_node != node) {
                    422:        replacement = new_node;
                    423:        if(register_in_hash)
                    424:            nodes_seen_hash->action((int)node, 
                    425:                                    (int)new_node, 
                    426:                                    Hash::insert, 0, 0);
                    427:     }
                    428:     else {
                    429:        if(register_in_hash)
                    430:            nodes_seen_hash->action((int)node, (int) node, Hash::insert, 0, 0);
                    431:     }
                    432:     return action;
                    433: }                         
                    434: 
                    435: tree_node_action walker::a_table(Pnode ta, Ptable t, Pnode& replacement) 
                    436: {
                    437:     /* no unions */
                    438: 
                    439:     tree_node_action action;
                    440:     action = pre_act_on_node(ta, nc_table, Pnode(t), replacement);
                    441:     if(action != tna_continue) return action;
                    442: 
                    443: /* -----------------------------*/
                    444: /* For Now, Never Walk a Table. */
                    445: 
                    446:     action = tna_stop; return action;
                    447: 
                    448: /* An array of pointers. 
                    449:  * The action procedure is responsible for allocating a new one
                    450:  * of those if it replaced and continued. 
                    451:  * *** end of comment
                    452: 
                    453:     if(!fetching () && replacement)
                    454:        t = Ptable(replacement);
                    455: 
                    456:     Pname * t_entries;
                    457: 
                    458:     if(fetching ()) {
                    459:        void * temp;
                    460:        fetch((void *)t->entries, t->size * sizeof(Pname), temp);
                    461:        t_entries = (Pname *)temp;
                    462:     }
                    463:     else t_entries = t->entries;
                    464: 
                    465:     for(int nx = 0; nx < t->size; nx ++) {
                    466:        action = walk(t_entries[nx]);
                    467:        if(action == tna_error) return action;
                    468:     }
                    469: 
                    470:     if(fetching ()) free_fetched ((void *)t_entries);
                    471:     
                    472:     Pnode n = Pnode(t->real_block);
                    473: 
                    474:     action = walk(t->real_block);
                    475:     if(action == tna_error) return action;
                    476:     
                    477:     action = walk(t->next);
                    478:     action = walk(t->t_name);
                    479:     return tna_continue;
                    480: */ // don't walk table
                    481: }
                    482: 
                    483: tree_node_action walker::a_enumdef (Pnode ta, Penum e, Pnode& replacement) 
                    484: {
                    485:     tree_node_action action = pre_act_on_node(ta, nc_enumdef, Pnode(e), replacement);
                    486: 
                    487:     action = walk(e->mem);
                    488:     if(action == tna_error) return action;
                    489: 
                    490:     action = walk(e->e_type);
                    491: 
                    492:     return tna_continue;
                    493: }    
                    494: 
                    495: tree_node_action walker::a_virt(Pnode ta, Pvirt v, Pnode& replacement) 
                    496: {
                    497:     /* no unions */
                    498: 
                    499:     int nx;
                    500:     tree_node_action action = pre_act_on_node(ta, nc_enumdef, Pnode(v), replacement);
                    501: 
                    502:     if(action != tna_continue) return action;
                    503: 
                    504:     if(!fetching () && replacement)
                    505:        v = Pvirt(replacement);
                    506: 
                    507: /* an array of velem structures. */
                    508: 
                    509:     velem * v_virt_init;
                    510: 
                    511:     if(fetching ()) {
                    512:        void * t;
                    513:        fetch((void *)v->virt_init, v->n_init * sizeof(velem), t);
                    514:        v_virt_init = (velem *)t;
                    515:     }
                    516:     else v_virt_init = v->virt_init;
                    517: 
                    518:     for(nx = 0; nx < v->n_init; nx ++) {
                    519:        action = walk(v_virt_init[nx].n);
                    520:        if(action == tna_error) return action;
                    521:     }
                    522: 
                    523:     if(fetching ()) free_fetched ((void *)v_virt_init);
                    524:     
                    525:     action = walk(v->vclass);
                    526:     
                    527:     return tna_continue;
                    528: }
                    529: 
                    530: tree_node_action walker::a_classdef(Pnode ta, Pclass c, Pnode& replacement) 
                    531: {
                    532: 
                    533:     tree_node_action action = pre_act_on_node(ta, nc_classdef, Pnode(c), replacement);
                    534: 
                    535:     if(action != tna_continue) return action;
                    536: 
                    537:     if(!fetching () && replacement)
                    538:        c = Pclass(replacement);
                    539: 
                    540:     action = walk(c->baselist);
                    541:     if(action == tna_error) return action;
                    542: 
                    543:     action=walk(c->mem_list);
                    544:     if(action == tna_error) return action;
                    545:     
                    546:     action=walk(c->memtbl);
                    547:     if(action == tna_error) return action;
                    548: 
                    549:     action=walk(c->friend_list);
                    550:     if(action == tna_error) return action;
                    551: 
                    552:     action=walk(c->pubdef);
                    553:     if(action == tna_error) return action;
                    554:     
                    555:     action=walk(c->tn_list);
                    556:     if(action == tna_error) return action;
                    557: 
                    558:     action=walk(c->in_class);
                    559:     if(action == tna_error) return action;
                    560: 
                    561:     action=walk(c->in_fct);
                    562:     if(action == tna_error) return action;
                    563: 
                    564:     action=walk(c->this_type);
                    565:     if(action == tna_error) return action;
                    566: 
                    567:     action=walk(c->virt_list);
                    568:     if(action == tna_error) return action;
                    569: 
                    570:     action=walk(c->c_ctor);
                    571:     if(action == tna_error) return action;
                    572:     action=walk(c->c_dtor);
                    573:     if(action == tna_error) return action;
                    574:     action=walk(c->c_itor);
                    575:     if(action == tna_error) return action;
                    576: 
                    577:     action=walk(c->conv);
                    578:     if(action == tna_error) return action;
                    579: 
                    580:     return tna_continue;
                    581: }
                    582: 
                    583: tree_node_action walker::a_basetype(Pnode ta, Pbase b, Pnode& replacement) 
                    584: {
                    585: 
                    586:     tree_node_action action = pre_act_on_node(ta, nc_basetype, Pnode(b), replacement);
                    587:     int derr;
                    588: 
                    589:     if(action != tna_continue) return action;
                    590: 
                    591:     if(!fetching () && replacement)
                    592:        b = Pbase(replacement);
                    593: 
                    594:     action = walk(b->b_name);
                    595:     if(action == tna_error) return action;
                    596: 
                    597:     action = walk(b->b_table);
                    598:     if(action == tna_error) return action;
                    599: 
                    600:     // action = walk(b->b_field);
                    601:     // if(action == tna_error) return action;
                    602: 
                    603:     action = walk(b->b_xname);
                    604:     if(action == tna_error) return action;
                    605: 
                    606:     switch(derr = b->discriminator(0)) {
                    607:       case 0: break;
                    608:       case 1:
                    609:        action = walk(b->b_fieldtype);
                    610:        if(action == tna_error) return action;
                    611:        break;
                    612:       case 2: break;
                    613:       default:
                    614:        error ("a_basetype: discrim error %d.", derr);
                    615:        return tna_error;
                    616:     }
                    617: 
                    618:     return tna_continue;
                    619: }
                    620: 
                    621: tree_node_action walker::a_fct(Pnode ta, Pfct f, Pnode& replacement) 
                    622: {
                    623: 
                    624:     tree_node_action action = pre_act_on_node(ta, nc_fct, Pnode(f), replacement);
                    625: 
                    626:     if(action != tna_continue) return action;
                    627: 
                    628:     if(!fetching () && replacement)
                    629:        f = Pfct(replacement);
                    630: 
                    631:     action = walk(f->returns);
                    632:     if(action == tna_error) return action;
                    633: 
                    634:     action = walk(f->argtype);
                    635:     if(action == tna_error) return action;
                    636: 
                    637:     action = walk(f->s_returns);
                    638:     if(action == tna_error) return action;
                    639: 
                    640:     action = walk(f->f_this);
                    641:     if(action == tna_error) return action;
                    642: 
                    643:     action = walk(f->memof);
                    644:     if(action == tna_error) return action;
                    645: 
                    646:     action = walk(f->body);
                    647:     if(action == tna_error) return action;
                    648: 
                    649:     action = walk(f->f_init);
                    650:     if(action == tna_error) return action;
                    651: 
                    652:     action = walk(f->f_expr);
                    653:     if(action == tna_error) return action;
                    654: 
                    655:     action = walk(f->last_expanded);
                    656:     if(action == tna_error) return action;
                    657: 
                    658:     action = walk(f->f_result);
                    659:     if(action == tna_error) return action;
                    660: 
                    661:     action = walk(f->f_args);
                    662:     if(action == tna_error) return action;
                    663: 
                    664:     return tna_continue;
                    665: }
                    666: 
                    667: tree_node_action walker::a_name_list(Pnode ta, Plist l, Pnode& replacement) 
                    668: {
                    669: 
                    670:     int cl_error;
                    671:     tree_node_action action = pre_act_on_node(ta, nc_nlist, Pnode(l), replacement);
                    672: 
                    673:     if(action == tna_stop) {
                    674:        if(!fetching () && replacement)
                    675:            l = Plist(replacement);
                    676:        cl_error = 0;
                    677:        if((classify_node(Pnode(l), cl_error) == nc_nlist) && !cl_error) {
                    678:            action = walk(l->l);
                    679:            if(action == tna_error) return action;
                    680:        }
                    681:     }
                    682: 
                    683:     if(action != tna_continue) return action;
                    684: 
                    685:     if(!fetching () && replacement)
                    686:        l = Plist(replacement);
                    687: 
                    688:     action = walk(l->f);
                    689:     if(action == tna_error) return action;
                    690: 
                    691:     action = walk(l->l);
                    692:     if(action == tna_error) return action;
                    693: 
                    694:     return tna_continue;
                    695: }
                    696: 
                    697: tree_node_action walker::a_gen(Pnode ta, Pgen g, Pnode& replacement) 
                    698: {
                    699: 
                    700:     tree_node_action action = pre_act_on_node(ta, nc_gen, Pnode(g), replacement);
                    701: 
                    702:     if(action != tna_continue) return action;
                    703: 
                    704:     if(!fetching () && replacement)
                    705:        g = Pgen(replacement);
                    706: 
                    707:     action = walk(g->fct_list);
                    708:     if(action == tna_error) return action;
                    709: 
                    710:     return tna_continue;
                    711: }
                    712: 
                    713: tree_node_action walker::a_vec(Pnode ta, Pvec v, Pnode& replacement) 
                    714: {
                    715: 
                    716:     tree_node_action action = pre_act_on_node(ta, nc_vec, Pnode(v), replacement);
                    717: 
                    718:     if(action != tna_continue) return action;
                    719: 
                    720:     if(!fetching () && replacement)
                    721:        v = Pvec(replacement);
                    722: 
                    723:     action = walk(v->typ);
                    724:     if(action == tna_error) return action;
                    725: 
                    726:     action = walk(v->dim);
                    727:     if(action == tna_error) return action;
                    728: 
                    729:     return tna_continue;
                    730: }
                    731: 
                    732: tree_node_action walker::a_ptr(Pnode ta, Pptr p, Pnode& replacement) 
                    733: {
                    734: 
                    735:     tree_node_action action = pre_act_on_node(ta, nc_ptr, Pnode(p), replacement);
                    736: 
                    737:     if(action != tna_continue) return action;
                    738: 
                    739:     if(!fetching () && replacement)
                    740:        p = Pptr(replacement);
                    741: 
                    742:     action = walk(p->typ);
                    743:     if(action == tna_error) return action;
                    744: 
                    745:     action = walk(p->memof);
                    746:     if(action == tna_error) return action;
                    747: 
                    748:     return tna_continue;
                    749: }
                    750: 
                    751: 
                    752: tree_node_action walker::a_expr_guts(Pexpr e)
                    753: {
                    754:     int derr;
                    755:     tree_node_action action;
                    756: 
                    757:     switch(derr = e->discriminator (0)) {
                    758:       case 1:
                    759:        action = walk(e->tp);
                    760:        if(action == tna_error) return action;
                    761:        break;
                    762:       case 0:
                    763:        break;
                    764:       default:
                    765:        error ("a_expr: discrim error %d on union 0.", derr);
                    766:        return tna_error;
                    767:     }
                    768: 
                    769:     switch(derr = e->discriminator (1)) {
                    770:       case 0:
                    771:        break;
                    772:       default:
                    773:        error ("a_expr: discrim error %d on union 1.", derr);
                    774:        return tna_error;
                    775:       case 1:
                    776:        action = walk(e->e1);
                    777:        if(action == tna_error) return action;
                    778:        break;
                    779:       case 2:
                    780:        break;
                    781:       case 3:
                    782:        break;
                    783:     }
                    784: 
                    785:     switch(derr = e->discriminator (2)) {
                    786:       case 0:
                    787:        break;
                    788:       default:
                    789:        error ("a_expr: discrim error %d on union 2.", derr);
                    790:        return tna_error;
                    791:       case 1:
                    792:        /* elists are special. e2 for an elist is a peer, not
                    793:           a child. */
                    794:        if(e->base != ELIST) {
                    795:            action = walk(e->e2);
                    796:            if(action == tna_error) return action;
                    797:        }
                    798:        break;
                    799:       case 2:
                    800:        break;
                    801:       case 3:
                    802:        break;
                    803:       case 4:
                    804:        action = walk(e->n_initializer);
                    805:        if(action == tna_error) return action;
                    806:        break;
                    807:     }
                    808:     
                    809:     switch(derr = e->discriminator (3)) {
                    810:       case 0:
                    811:        break;
                    812:       default:
                    813:        error ("a_expr: discrim error %d on union 3.", derr);
                    814:        return tna_error;
                    815:       case 1:
                    816:        action = walk(e->tp2);
                    817:        if(action == tna_error) return action;
                    818:        break;
                    819:       case 2:
                    820:        action = walk(e->fct_name);
                    821:        if(action == tna_error) return action;
                    822:        break;
                    823:       case 3:
                    824:        action = walk(e->cond);
                    825:        if(action == tna_error) return action;
                    826:        break;
                    827:       case 4:
                    828:        action = walk(e->mem);
                    829:        if(action == tna_error) return action;
                    830:        break;
                    831:       case 5:
                    832:        action = walk(e->as_type);
                    833:        if(action == tna_error) return action;
                    834:        break;
                    835:       case 6:
                    836:        action = walk(e->n_table);
                    837:        if(action == tna_error) return action;
                    838:        break;
                    839:       case 7:
                    840:        action = walk(e->il);
                    841:        if(action == tna_error) return action;
                    842:        break;
                    843:       case 8:
                    844:        action = walk(e->query_this);
                    845:        if(action == tna_error) return action;
                    846:        break;
                    847:     }
                    848:     return tna_continue;
                    849: }
                    850: 
                    851: 
                    852: tree_node_action walker::a_expr(Pnode ta, Pexpr e, Pnode& replacement) 
                    853: {
                    854:     tree_node_action action = pre_act_on_node(ta, nc_expr, Pnode(e), replacement);
                    855: 
                    856:     if(action == tna_stop) {
                    857:        if(!fetching () && replacement)
                    858:            e = Pexpr(replacement);
                    859:        /* ELIST implies that e2 is a peer, not a child */
                    860:        if(e->base == ELIST) {
                    861:            action = walk(e->e2);
                    862:            return action;
                    863:        }
                    864:     }
                    865:        
                    866:     if(action != tna_continue) return action;
                    867: 
                    868:     if(!fetching () && replacement)
                    869:        e = Pexpr(replacement);
                    870: 
                    871:     action = a_expr_guts(e);
                    872:     if (action == tna_error) return action;
                    873:     if(e->base == ELIST)
                    874:        action = walk(e->e2);
                    875:     return action;
                    876: }
                    877: 
                    878: tree_node_action walker::a_baseclass(Pnode ta, Pbcl b, Pnode& replacement) 
                    879: {
                    880:     tree_node_action action = pre_act_on_node(ta, nc_baseclass, Pnode(b), replacement);
                    881: 
                    882:     if(action != tna_continue) return action;
                    883: 
                    884:     if(!fetching () && replacement)
                    885:        b = Pbcl(replacement);
                    886: 
                    887:     action = walk(b->bclass);
                    888:     if(action == tna_error) return action;
                    889: 
                    890:     action = walk(b->init);
                    891:     if(action == tna_error) return action;
                    892: 
                    893:     action = walk(b->next);
                    894:     if(action == tna_error) return action;
                    895: 
                    896:     return tna_continue;
                    897: }
                    898: 
                    899: 
                    900: /* a name is also an expr. */
                    901:    
                    902: 
                    903: tree_node_action walker::a_name(Pnode ta, Pname n, Pnode& replacement) 
                    904: {
                    905:     int derr;
                    906:     int cl_error;
                    907:     tree_node_action action = pre_act_on_node(ta, nc_name, Pnode(n), replacement);
                    908: 
                    909:     /* n_list is a sibling, not a child. We always process it
                    910:        except in case of an error. */
                    911:     if(action == tna_stop) {
                    912:        cl_error = 0;
                    913:        if(!fetching () && replacement)
                    914:            n = Pname(replacement);
                    915:        if((classify_node(Pnode(n), cl_error) == nc_name) && !cl_error) {
                    916:            if(depth > 0 || !control.dont_chase_lists_top) {
                    917:                action = walk(n->n_list); 
                    918:                if(action == tna_error) return action;
                    919:            }
                    920:        }
                    921:        return tna_stop;
                    922:     }  
                    923: 
                    924:     if(action != tna_continue) return action;
                    925: 
                    926:     if(!fetching () && replacement)
                    927:        n = Pname(replacement);
                    928: 
                    929: /* We don't walk n_tbl_list. Its not part of the graph.
                    930:    */
                    931: 
                    932:     switch(derr = n->discriminator(0)) {
                    933:       case 0:
                    934:        break;
                    935:       case 1:
                    936:        action = walk(n->n_qualifier);
                    937:        if(action == tna_error) return action;
                    938:        break;
                    939:       case 2:
                    940:        action = walk(n->n_realscope);
                    941:        if(action == tna_error) return action;
                    942:        break;
                    943:       default:
                    944:        error ("a_name: discrim error %d on union 0.", derr);
                    945:        return tna_error;
                    946:     }
                    947: 
                    948:     action = a_expr_guts(Pexpr(n));
                    949:     if(action == tna_error) return action;
                    950: 
                    951:     if(depth > 0 || !control.dont_chase_lists_top) {
                    952:        action = walk(n->n_list);
                    953:        if(action == tna_error) return action;
                    954:     }
                    955:     
                    956:     return action;
                    957: }
                    958:     
                    959: /* --- NOTE: s_list should be deferred until AFTER the post-action
                    960:    procedure is called, if there is one. Since no one uses
                    961:    post-actions yet I haven't bothered to make this fix.
                    962:    --benson */
                    963: 
                    964: tree_node_action walker::a_stmt(Pnode ta, Pstmt s, Pnode& replacement) 
                    965: {
                    966:     int cl_error;
                    967:     int derr;
                    968:     tree_node_action action = pre_act_on_node(ta, nc_stmt, Pnode(s), replacement);
                    969: 
                    970:     if(action == tna_stop) {
                    971:        if(!fetching () && replacement)
                    972:            s = Pstmt(replacement);
                    973:        cl_error = 0;
                    974:        if((classify_node(Pnode(s), cl_error) == nc_stmt) && !cl_error) {
                    975:            /* s_list is not our subordinate, it is our peer */
                    976:            if(depth > 0 || !control.dont_chase_lists_top) {
                    977:                action = walk(s->s_list); /* continue walk of sibs */
                    978:                if (action == tna_error) return tna_error;
                    979:            }
                    980:        }
                    981:        return tna_stop;
                    982:     }
                    983: 
                    984:     if(action != tna_continue) return action;
                    985: 
                    986:     if(!fetching () && replacement)
                    987:        s = Pstmt(replacement);
                    988: 
                    989:     action = walk(s->s);
                    990:     if(action == tna_error) return action;
                    991: 
                    992:     action = walk(s->memtbl);
                    993:     if(action == tna_error) return action;
                    994: 
                    995:     switch(derr = s->discriminator(0)) {
                    996:       default:
                    997:        error ("a_stmt: discrim error %d on union 0.", derr);
                    998:        return tna_error;
                    999:       case 4:
                   1000:       case 0: break;
                   1001:       case 1:
                   1002:        action = walk(s->d);
                   1003:        if(action == tna_error) return action;
                   1004:        break;
                   1005:       case 2:
                   1006:        action = walk(s->e2);
                   1007:        if(action == tna_error) return action;
                   1008:        break;
                   1009:       case 3:
                   1010:        action = walk(s->has_default);
                   1011:        if(action == tna_error) return action;
                   1012:        break;
                   1013:       case 5:
                   1014:        action = walk(s->ret_tp);
                   1015:        if(action == tna_error) return action;
                   1016:        break;
                   1017:     }
                   1018: 
                   1019:     switch(derr = s->discriminator(1)) {
                   1020:       default:
                   1021:        error ("a_stmt: discrim error %d on union 1.", derr);
                   1022:        return tna_error;
                   1023:       case 2:
                   1024:       case 0: break;
                   1025:       case 1:
                   1026:        action = walk(s->e);
                   1027:        if(action == tna_error) return action;
                   1028:        break;
                   1029:       case 3:
                   1030:        action = walk(s->s2);
                   1031:        if(action == tna_error) return action;
                   1032:        break;
                   1033:     }
                   1034: 
                   1035:     switch(derr = s->discriminator(2)) {
                   1036:       default:
                   1037:        error ("a_stmt: discrim error %d on union 2.", derr);
                   1038:        return tna_error;
                   1039:       case 0: break;
                   1040:       case 1:
                   1041:        action = walk(s->for_init);
                   1042:        if(action == tna_error) return action;
                   1043:        break;
                   1044:       case 2:
                   1045:        action = walk(s->else_stmt);
                   1046:        if(action == tna_error) return action;
                   1047:        break;
                   1048:       case 3:
                   1049:        action = walk(s->case_list);
                   1050:        if(action == tna_error) return action;
                   1051:        break;
                   1052:     }
                   1053: 
                   1054:     if(depth > 0 || !control.dont_chase_lists_top) {
                   1055:        action = walk(s->s_list);
                   1056:        if(action == tna_error) return action;
                   1057:     }
                   1058: 
                   1059:     return tna_continue;
                   1060: }
                   1061: 
                   1062: tree_node_action walker::a_ia(Pnode ta, struct ia * ia, Pnode& replacement) 
                   1063: {
                   1064:     tree_node_action action = pre_act_on_node(ta, nc_ia, Pnode(ia), replacement);
                   1065: 
                   1066:     if(action != tna_continue) return action;
                   1067: 
                   1068:     if(!fetching () && replacement)
                   1069:        ia = (struct ia *)&replacement;
                   1070: 
                   1071:     action = walk(ia->local);
                   1072:     if(action == tna_error) return action;
                   1073: 
                   1074:     action = walk(ia->arg);
                   1075:     if(action == tna_error) return action;
                   1076:     
                   1077:     action = walk(ia->tp);
                   1078:     if(action == tna_error) return action;
                   1079: 
                   1080:     return tna_continue;
                   1081: }
                   1082: 
                   1083: tree_node_action walker::a_iline(Pnode ta, Pin iline, Pnode& replacement) 
                   1084: {
                   1085:     tree_node_action action = pre_act_on_node(ta, nc_iline, Pnode(iline), replacement);
                   1086: 
                   1087:     if(action != tna_continue) return action;
                   1088: 
                   1089:     if(!fetching () && replacement)
                   1090:        iline = Pin(replacement);
                   1091: 
                   1092:     action = walk(iline->fct_name);
                   1093:     if(action == tna_error) return action;
                   1094: 
                   1095:     action = walk(iline->i_next);
                   1096:     if(action == tna_error) return action;
                   1097:     
                   1098:     action = walk(iline->i_table);
                   1099:     if(action == tna_error) return action;
                   1100: 
                   1101:     action = walk(iline->i_args);
                   1102:     if(action == tna_error) return action;
                   1103: 
                   1104:     return tna_continue;
                   1105: }

unix.superglobalmegacorp.com

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