ブランチ「label-local」をマージ
[YACASL2.git] / src / label.c
1 #include "casl2.h"
2 #include "assemble.h"
3
4 LABELTAB *labels[LABELTABSIZE];
5
6 /* プログラム名とラベルに対応するハッシュ値を返す */
7 unsigned labelhash(const char *prog, const char *label)
8 {
9     HKEY *keys[2];
10     int i = 0;
11     if(prog != NULL) {
12         keys[i] = malloc(sizeof(HKEY));
13         keys[i]->type = CHARS;
14         keys[i++]->val.s = strdup(prog);
15     }
16     keys[i] = malloc(sizeof(HKEY));
17     keys[i]->type = CHARS;
18     keys[i]->val.s = strdup(label);
19     /* ハッシュ値を返す */
20     return hash(i+1, keys, LABELTABSIZE);
21 }
22
23 /* ラベル表からアドレスを検索する */
24 WORD getlabel(const char *prog, const char *label)
25 {
26     LABELTAB *np;
27     for(np = labels[labelhash(prog, label)]; np != NULL; np = np->next) {
28         if((prog == NULL || (np->prog != NULL && strcmp(prog, np->prog) == 0)) &&
29            strcmp(label, np->label) == 0)
30         {
31             return np->adr;
32         }
33     }
34     return 0xFFFF;
35 }
36
37 /* ラベルを表に追加する */
38 bool addlabel(const char *prog, const char *label, WORD adr)
39 {
40     LABELTAB *np;
41     unsigned hashval;
42     char *keys[2];
43     int i = 0;
44
45     if(getlabel(prog, label) != 0xFFFF) {
46         setcerr(101, label);    /* label already defined */
47         return false;
48     }
49     np = (LABELTAB *) malloc(sizeof(*np));
50     if(np == NULL || (np->label = strdup(label)) == NULL ||
51        (prog != NULL && (np->prog = strdup(prog)) == NULL))
52     {
53         setcerr(102, NULL);    /* label table is full */
54         return false;
55     }
56     if(prog != NULL) {
57         keys[i++] = strdup(prog);
58     }
59     keys[i] = strdup(label);;
60     hashval = labelhash(prog, label);
61     np->next = labels[hashval];
62     labels[hashval] = np;
63     np->adr = adr;
64     return true;
65 }
66
67 /* ラベル表を表示する */
68 void printlabel()
69 {
70     int i;
71     LABELTAB *np;
72     for(i = 0; i < LABELTABSIZE; i++) {
73         for(np = labels[i]; np != NULL; np = np->next) {
74             if(np->prog == NULL) {
75                 fprintf(stdout, "%s ---> #%04X\n", np->label, np->adr);
76             } else {
77                 fprintf(stdout, "%s.%s ---> #%04X\n", np->prog, np->label, np->adr);
78             }
79         }
80     }
81 }
82
83 /* ラベル表を解放する */
84 void freelabel()
85 {
86     int i;
87     LABELTAB *np, *nq;
88     for(i = 0; i < LABELTABSIZE; i++) {
89         for(np = labels[i]; np != NULL; np = nq){
90             nq = np->next;
91             free(np->prog);
92             free(np->label);
93             free(np);
94         }
95     }
96 }