790a29aca0be0f2a26bd61e249cf2a0376bd99c1
[YACASL2.git] / src / label.c
1 #include "casl2.h"
2 #include "assemble.h"
3
4 int labelcnt = 0;                    /* ラベル数 */
5 LABELTAB *labels[LABELTABSIZE];  /* ラベル表 */
6
7 /* プログラム名とラベルに対応するハッシュ値を返す */
8 unsigned labelhash(const char *prog, const char *label)
9 {
10     HKEY *keys[2];
11     int i = 0;
12     if(prog != NULL) {
13         keys[i] = malloc(sizeof(HKEY));
14         keys[i]->type = CHARS;
15         keys[i++]->val.s = strdup(prog);
16     }
17     keys[i] = malloc(sizeof(HKEY));
18     keys[i]->type = CHARS;
19     keys[i]->val.s = strdup(label);
20     /* ハッシュ値を返す */
21     return hash(i+1, keys, LABELTABSIZE);
22 }
23
24 /* ラベル表からアドレスを検索する */
25 WORD getlabel(const char *prog, const char *label)
26 {
27     assert(label != NULL);
28     LABELTAB *np;
29     for(np = labels[labelhash(prog, label)]; np != NULL; np = np->next) {
30         if((prog == NULL || (np->prog != NULL && strcmp(prog, np->prog) == 0)) &&
31            strcmp(label, np->label) == 0)
32         {
33             return np->adr;
34         }
35     }
36     return 0xFFFF;
37 }
38
39 /* プログラム名、ラベル、アドレスをラベル表に追加する */
40 bool addlabel(const char *prog, const char *label, WORD adr)
41 {
42     assert(label != NULL);
43     LABELTAB *np;
44     unsigned hashval;
45
46     /* 登録されたラベルを検索。すでに登録されている場合はエラー発生 */
47     if(getlabel(prog, label) != 0xFFFF) {
48         setcerr(101, label);    /* label already defined */
49         return false;
50     }
51     /* プログラム名、ラベル、アドレスを設定。メモリーを確保できない場合はエラー発生 */
52     if((np = malloc(sizeof(LABELTAB))) == NULL || (np->label = strdup(label)) == NULL ||
53        (prog != NULL && (np->prog = strdup(prog)) == NULL))
54     {
55         setcerr(102, NULL);    /* label table is full */
56         return false;
57     }
58     np->adr = adr;
59     /* ラベル数の設定 */
60     labelcnt++;
61     /* ハッシュ表の設定 */
62     hashval = labelhash(prog, label);
63     np->next = labels[hashval];
64     labels[hashval] = np;
65     return true;
66 }
67
68 int compare_adr(const void *a, const void *b)
69 {
70     return (**(LABELARRAY **)a).adr - (**(LABELARRAY **)b).adr;
71 }
72
73 /* ラベル表を表示する */
74 void printlabel()
75 {
76     int i, asize = 0;
77     LABELTAB *np;
78     LABELARRAY *ar[labelcnt];
79
80     for(i = 0; i < LABELTABSIZE; i++) {
81         for(np = labels[i]; np != NULL; np = np->next) {
82             assert(np->label != NULL);
83             ar[asize] = malloc(sizeof(LABELARRAY));
84             ar[asize]->prog = (np->prog == NULL ? NULL : strdup(np->prog));
85             ar[asize]->label = strdup(np->label);
86             ar[asize++]->adr = np->adr;
87         }
88     }
89     qsort(ar, asize, sizeof(*ar), compare_adr);
90     for(i = 0; i < asize; i++) {
91         if(ar[i]->prog != NULL) {
92             fprintf(stdout, "%s.", ar[i]->prog);
93         }
94         fprintf(stdout, "%s ---> #%04X\n", ar[i]->label, ar[i]->adr);
95     }
96 }
97
98 /* ラベル表を解放する */
99 void freelabel()
100 {
101     int i;
102     LABELTAB *np, *nq;
103     for(i = 0; i < LABELTABSIZE; i++) {
104         for(np = labels[i]; np != NULL; np = nq) {
105             nq = np->next;
106             if(np->prog != NULL) {
107                 free(np->prog);
108             }
109             free(np->label);
110             free(np);
111         }
112     }
113 }