root/src/label.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. label_hashkey
  2. labelhash
  3. compare_adr
  4. addcerrlist_label
  5. getlabel
  6. addlabel
  7. printlabel
  8. freelabel

   1 #include "assemble.h"
   2 
   3 /**
   4  * ラベルのハッシュ値をセットしたキーを返す
   5  *
   6  * @return ハッシュ値をセットしたキー
   7  *
   8  * @param value 値
   9  */
  10 HKEY *label_hashkey(const char *value);
  11 
  12 /**
  13  * プログラム名とラベルに対応するハッシュ値を返す
  14  *
  15  * @return ハッシュ値
  16  *
  17  * @param prog プログラム名
  18  * @param label ラベル
  19  */
  20 unsigned labelhash(const char *prog, const char *label);
  21 
  22 /**
  23  * ラベルを比較した結果を返す。qsort内で使われる関数
  24  *
  25  * @return ラベルが同一の場合は0、異なる場合は0以外
  26  *
  27  * @param *a ラベルa
  28  * @param *b ラベルb
  29  */
  30 int compare_adr(const void *a, const void *b);
  31 
  32 /**
  33  * @brief ラベル数
  34  */
  35 static int labelcnt = 0;
  36 
  37 /**
  38  * @brief ラベル表
  39  */
  40 static LABELTAB *labels[LABELTABSIZE];
  41 
  42 /**
  43  * @brief ラベルのエラー
  44  */
  45 static CERR cerr_label[] = {
  46     { 101, "label already defined" },
  47     { 102, "label table is full" },
  48     { 103, "label not found" },
  49 };
  50 
  51 HKEY *label_hashkey(const char *value) {
  52     HKEY *key = NULL;
  53 
  54     key = malloc_chk(sizeof(HKEY), "label_hashkey");
  55     key->type = CHARS;
  56     key->val.s = strdup_chk(value, "label_hashkey->value");
  57     return key;
  58 }
  59 
  60 unsigned labelhash(const char *prog, const char *label)
  61 {
  62     HKEY *keys[2] = {NULL};
  63     int i = 0;
  64     unsigned h = 0;
  65 
  66     if(prog[0]) {
  67         keys[i++] = label_hashkey(prog);
  68     }
  69     keys[i] = label_hashkey(label);
  70     h = hash(i+1, keys, LABELTABSIZE);
  71     for(int j = 0; j < i + 1; j++) {
  72         FREE(keys[j]->val.s);
  73         FREE(keys[j]);
  74     }
  75     return h;
  76 }
  77 
  78 int compare_adr(const void *a, const void *b)
  79 {
  80     return (**(LABELARRAY **)a).adr - (**(LABELARRAY **)b).adr;
  81 }
  82 
  83 /* assemble.hで定義された関数群 */
  84 void addcerrlist_label()
  85 {
  86     addcerrlist(ARRAYSIZE(cerr_label), cerr_label);
  87 }
  88 
  89 WORD getlabel(const char *prog, const char *label)
  90 {
  91     assert(prog != NULL && label != NULL);
  92     LABELTAB *p = NULL;
  93     LABELARRAY *l = NULL;
  94 
  95     for(p = labels[labelhash(prog, label)]; p != NULL; p = p->next) {
  96         l = p->label;
  97         if((!prog[0] || (strcmp(prog, l->prog) == 0)) &&
  98            strcmp(label, l->label) == 0)
  99         {
 100             return l->adr;
 101         }
 102     }
 103     return 0xFFFF;
 104 }
 105 
 106 bool addlabel(const char *prog, const char *label, WORD adr)
 107 {
 108     assert(label != NULL);
 109     LABELTAB *p = NULL;
 110     LABELARRAY *l = NULL;
 111     unsigned h = 0;
 112 
 113     /* 登録されたラベルを検索。すでに登録されている場合はエラー発生 */
 114     if(getlabel(prog, label) != 0xFFFF) {
 115         setcerr(101, label);    /* label already defined */
 116         return false;
 117     }
 118     /* メモリを確保 */
 119     p = malloc_chk(sizeof(LABELTAB), "labels.next");
 120     l = p->label = malloc_chk(sizeof(LABELARRAY), "labels.label");
 121     /* プログラム名を設定 */
 122     l->prog = strdup_chk(prog, "label.prog");
 123     /* ラベルを設定 */
 124     l->label = strdup_chk(label, "label.label");
 125     /* アドレスを設定 */
 126     l->adr = adr;
 127     /* ラベル数を設定 */
 128     labelcnt++;
 129     /* ハッシュ表へ追加 */
 130     p->next = labels[h = labelhash(prog, label)];
 131     labels[h] = p;
 132     return true;
 133 }
 134 
 135 void printlabel()
 136 {
 137     int s = 0;
 138     LABELTAB *p = NULL;
 139     LABELARRAY **l = {NULL};
 140 
 141     l = calloc_chk(labelcnt, sizeof(LABELARRAY **), "labels");
 142     for(int i = 0; i < LABELTABSIZE; i++) {
 143         for(p = labels[i]; p != NULL; p = p->next) {
 144             assert(p->label != NULL);
 145             l[s++] = p->label;
 146         }
 147     }
 148     qsort(l, s, sizeof(*l), compare_adr);
 149     for(int i = 0; i < s; i++) {
 150         if(l[i]->prog[0]) {
 151             fprintf(stdout, "%s.", l[i]->prog);
 152         }
 153         fprintf(stdout, "%s ---> #%04X\n", l[i]->label, l[i]->adr);
 154     }
 155     FREE(l);
 156 }
 157 
 158 void freelabel()
 159 {
 160     int i;
 161     LABELTAB *p = NULL;
 162     LABELTAB *q = NULL;
 163 
 164     for(i = 0; i < LABELTABSIZE; i++) {
 165         for(p = labels[i]; p != NULL; p = q) {
 166             q = p->next;
 167             FREE(p->label->prog);
 168             FREE(p->label->label);
 169             FREE(p->label);
 170             FREE(p);
 171         }
 172         labels[i] = NULL;
 173     }
 174 }

/* [<][>][^][v][top][bottom][index][help] */