segtab.c
上传用户:yuppie_zhu
上传日期:2007-01-08
资源大小:535k
文件大小:3k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "segtab.h"
  4. struct segtabnode {
  5.     int localseg;
  6.     int destseg;
  7.     long offset;
  8.     struct segtabnode * left;
  9.     struct segtabnode * right;
  10.     /* 
  11.      * counts of how many are left or right, for use in reorganising
  12.      * the tree
  13.      */
  14.     int leftcount;
  15.     int rightcount;
  16. };
  17. /*
  18.  * init_seglocations()
  19.  * add_seglocation()
  20.  * get_seglocation()
  21.  * done_seglocation()
  22.  *
  23.  * functions used by write_output() to manipulate associations
  24.  * between segment numbers and locations (which are built up on a per
  25.  * module basis, but we only need one module at a time...)
  26.  *
  27.  * implementation: we build a binary tree.
  28.  */
  29. void init_seglocations(segtab * root)
  30. {
  31.     *root = NULL;
  32. }
  33. void descend_tree_add(struct segtabnode * * node,
  34.       int localseg, int destseg, long offset)
  35. {
  36.     struct segtabnode * n;
  37.     if (*node == NULL) {
  38. *node = malloc (sizeof (**node));
  39. if (!*node) {
  40.     fprintf(stderr, "segment table: out of memoryn");
  41.     exit(1);
  42. }
  43. (*node)->localseg = localseg;
  44. (*node)->offset = offset;
  45. (*node)->left = NULL;
  46. (*node)->leftcount = 0;
  47. (*node)->right = NULL;
  48. (*node)->rightcount = 0;
  49. (*node)->destseg = destseg;
  50. return;
  51.     }
  52.     if (localseg < (*node)->localseg)
  53.     {
  54. (*node)->leftcount++;
  55. descend_tree_add(&(*node)->left, localseg, destseg, offset);
  56. if ((*node)->leftcount > (*node)->rightcount + 2) {
  57.     n = * node;
  58.     *node = n->left;
  59.     n->left = (*node)->right;
  60.     n->leftcount = (*node)->rightcount;
  61.     (*node)->right = n;
  62.     (*node)->rightcount = n->leftcount + n->rightcount + 1;
  63. }
  64.     }
  65.     else
  66.     {
  67. (*node)->rightcount++;
  68. descend_tree_add(&(*node)->right, localseg, destseg, offset);
  69. if ((*node)->rightcount > (*node)->leftcount + 2) {
  70.     n = * node;
  71.     *node = n->right;
  72.     n->right= (*node)->left;
  73.     n->rightcount = (*node)->leftcount;
  74.     (*node)->left = n;
  75.     (*node)->leftcount = n->leftcount + n->rightcount + 1;
  76. }
  77.     }
  78. }
  79. void add_seglocation(segtab * root, int localseg, int destseg, long offset)
  80. {
  81.     descend_tree_add((struct segtabnode **) root, localseg, destseg, offset);
  82. }
  83. int get_seglocation(segtab * root, int localseg, int * destseg, long * offset)
  84. {
  85.     struct segtabnode * n = (struct segtabnode *) *root;
  86.     
  87.     while (n && n->localseg != localseg)
  88.     {
  89. if (localseg < n->localseg) 
  90.     n = n->left;
  91. else
  92.     n = n->right;
  93.     }
  94.     if (n) {
  95. *destseg = n->destseg;
  96. *offset = n->offset;
  97. return 1;
  98.     }
  99.     else
  100. return 0;
  101. }
  102. void freenode(struct segtabnode * n)
  103. {
  104.     if (!n) return;
  105.     freenode (n->left);
  106.     freenode (n->right);
  107.     free(n);
  108. }
  109. void done_seglocations(segtab * root)
  110. {
  111.     freenode(*root);
  112.     *root = NULL;
  113. }
  114. #if 0
  115. void printnode(int i, struct segtabnode * n)
  116. {
  117.     if (!n) return;
  118.     printnode(i + 1, n->left);
  119.     printf ("%*s%d %d %ldn", i, "", n->localseg, n->destseg, n->offset);
  120.     printnode(i + 1, n->right);
  121. }
  122. void printtable()
  123. {
  124.     printnode(0,root);
  125. }
  126. #endif