YACASL2
label.c
Go to the documentation of this file.
1 #include "assemble.h"
2 
10 HKEY *label_hashkey(const char *value);
11 
20 unsigned labelhash(const char *prog, const char *label);
21 
30 int compare_adr(const void *a, const void *b);
31 
35 static int labelcnt = 0;
36 
41 
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で定義された関数群 */
85 {
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 
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 }
@ LABELTABSIZE
Definition: assemble.h:66
void addcerrlist(int cerrc, CERR cerrv[])
エラーリストを作成・追加する
Definition: cerr.c:13
void setcerr(int num, const char *str)
現在のエラーを設定する
Definition: cerr.c:45
#define FREE(ptr)
メモリを解放するマクロ
Definition: cmem.h:21
char * strdup_chk(const char *s, const char *tag)
malloc_chkを実行してメモリを確保し、コピーした文字列を返す
Definition: cmem.c:25
void * calloc_chk(size_t nmemb, size_t size, const char *tag)
領域の数とサイズを指定してメモリーを確保するcallocを実行する
Definition: cmem.c:14
#define ARRAYSIZE(array)
配列のサイズを返すマクロ
Definition: cmem.h:14
void * malloc_chk(size_t size, const char *tag)
mallocを実行し、0で初期化する
Definition: cmem.c:3
@ CHARS
Definition: hash.h:8
unsigned hash(int keyc, HKEY *keyv[], int tabsize)
ハッシュ値を取得する
Definition: hash.c:3
void addcerrlist_label()
ラベルのエラーをエラーリストに追加する
Definition: label.c:84
bool addlabel(const char *prog, const char *label, WORD adr)
プログラム名、ラベル、アドレスをラベル表に追加する
Definition: label.c:106
unsigned labelhash(const char *prog, const char *label)
Definition: label.c:60
void printlabel()
ラベル表を表示する
Definition: label.c:135
static LABELTAB * labels[LABELTABSIZE]
ラベル表
Definition: label.c:40
WORD getlabel(const char *prog, const char *label)
プログラム名とラベルに対応するアドレスをラベル表から検索する
Definition: label.c:89
int compare_adr(const void *a, const void *b)
Definition: label.c:78
static CERR cerr_label[]
ラベルのエラー
Definition: label.c:45
HKEY * label_hashkey(const char *value)
Definition: label.c:51
static int labelcnt
ラベル数
Definition: label.c:35
void freelabel()
ラベル表を解放する
Definition: label.c:158
エラーを表すデータ型
Definition: cerr.h:15
ラベル表を表すデータ型
Definition: assemble.h:57
LABELARRAY * label
Definition: assemble.h:59
struct _LABELTAB * next
Definition: assemble.h:58
ハッシュ共用体のデータ型
Definition: hash.h:15
char * s
Definition: hash.h:18
UTYPE type
Definition: hash.h:16
union HKEY::@3 val
ラベル配列を表すデータ型
Definition: assemble.h:48
char * prog
Definition: assemble.h:49
WORD adr
Definition: assemble.h:51
char * label
Definition: assemble.h:50
unsigned short WORD
16ビットの数値を表すデータ型
Definition: word.h:9