ラベルの出力時、アドレス順に並べ替えるように仕様変更
[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     LABELTAB *np;
28     for(np = labels[labelhash(prog, label)]; np != NULL; np = np->next) {
29         if((prog == NULL || (np->prog != NULL && strcmp(prog, np->prog) == 0)) &&
30            strcmp(label, np->label) == 0)
31         {
32             return np->adr;
33         }
34     }
35     return 0xFFFF;
36 }
37
38 /* ラベルを表に追加する */
39 bool addlabel(const char *prog, const char *label, WORD adr)
40 {
41     LABELTAB *np;
42     unsigned hashval;
43     char *keys[2];
44     int i = 0;
45
46     if(getlabel(prog, label) != 0xFFFF) {
47         setcerr(101, label);    /* label already defined */
48         return false;
49     }
50     np = malloc(sizeof(*np));
51     if(np == NULL || (np->label = strdup(label)) == NULL ||
52        (prog != NULL && (np->prog = strdup(prog)) == NULL))
53     {
54         setcerr(102, NULL);    /* label table is full */
55         return false;
56     }
57     if(prog != NULL) {
58         keys[i++] = strdup(prog);
59     }
60     labelcnt++;
61     keys[i] = strdup(label);
62     hashval = labelhash(prog, label);
63     np->next = labels[hashval];
64     labels[hashval] = np;
65     np->adr = adr;
66     return true;
67 }
68
69 int compare_adr(const void *a, const void *b)
70 {
71     return (**(const LABELARRAY **)a).adr - (**(const LABELARRAY **)b).adr;
72 }
73
74 /* ラベル表を表示する */
75 void printlabel()
76 {
77     int i, asize = 0;
78     LABELTAB *np = malloc(sizeof(LABELTAB *));
79     LABELARRAY **ar = malloc(labelcnt * sizeof(LABELARRAY **));
80
81     for(i = 0; i < LABELTABSIZE; i++) {
82         for(np = labels[i]; np != NULL; np = np->next) {
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             asize++;
88         }
89     }
90     qsort(ar, asize, sizeof(*ar), compare_adr);
91     for(i = 0; i < asize; i++) {
92         if(ar[i]->prog != NULL) {
93             fprintf(stdout, "%s.", ar[i]->prog);
94         }
95         fprintf(stdout, "%s ---> #%04X\n", ar[i]->label, ar[i]->adr);
96     }
97 }
98
99 /* ラベル表を解放する */
100 void freelabel()
101 {
102     int i;
103     LABELTAB *np, *nq;
104     for(i = 0; i < LABELTABSIZE; i++) {
105         for(np = labels[i]; np != NULL; np = nq) {
106             nq = np->next;
107             free(np->prog);
108             free(np->label);
109             free(np);
110         }
111     }
112 }