#include #include #include "segtab.h" struct segtabnode { int localseg; int destseg; long offset; struct segtabnode * left; struct segtabnode * right; /* * counts of how many are left or right, for use in reorganising * the tree */ int leftcount; int rightcount; }; /* * init_seglocations() * add_seglocation() * get_seglocation() * done_seglocation() * * functions used by write_output() to manipulate associations * between segment numbers and locations (which are built up on a per * module basis, but we only need one module at a time...) * * implementation: we build a binary tree. */ void init_seglocations(segtab * root) { *root = NULL; } void descend_tree_add(struct segtabnode * * node, int localseg, int destseg, long offset) { struct segtabnode * n; if (*node == NULL) { *node = malloc (sizeof (**node)); if (!*node) { fprintf(stderr, "segment table: out of memory\n"); exit(1); } (*node)->localseg = localseg; (*node)->offset = offset; (*node)->left = NULL; (*node)->leftcount = 0; (*node)->right = NULL; (*node)->rightcount = 0; (*node)->destseg = destseg; return; } if (localseg < (*node)->localseg) { (*node)->leftcount++; descend_tree_add(&(*node)->left, localseg, destseg, offset); if ((*node)->leftcount > (*node)->rightcount + 2) { n = * node; *node = n->left; n->left = (*node)->right; n->leftcount = (*node)->rightcount; (*node)->right = n; (*node)->rightcount = n->leftcount + n->rightcount + 1; } } else { (*node)->rightcount++; descend_tree_add(&(*node)->right, localseg, destseg, offset); if ((*node)->rightcount > (*node)->leftcount + 2) { n = * node; *node = n->right; n->right= (*node)->left; n->rightcount = (*node)->leftcount; (*node)->left = n; (*node)->leftcount = n->leftcount + n->rightcount + 1; } } } void add_seglocation(segtab * root, int localseg, int destseg, long offset) { descend_tree_add((struct segtabnode **) root, localseg, destseg, offset); } int get_seglocation(segtab * root, int localseg, int * destseg, long * offset) { struct segtabnode * n = (struct segtabnode *) *root; while (n && n->localseg != localseg) { if (localseg < n->localseg) n = n->left; else n = n->right; } if (n) { *destseg = n->destseg; *offset = n->offset; return 1; } else return 0; } void freenode(struct segtabnode * n) { if (!n) return; freenode (n->left); freenode (n->right); free(n); } void done_seglocations(segtab * root) { freenode(*root); *root = NULL; } #if 0 void printnode(int i, struct segtabnode * n) { if (!n) return; printnode(i + 1, n->left); printf ("%*s%d %d %ld\n", i, "", n->localseg, n->destseg, n->offset); printnode(i + 1, n->right); } void printtable() { printnode(0,root); } #endif