+/**
+ * プログラム名とラベルに対応するハッシュ値を返す
+ *
+ * @return ハッシュ値
+ *
+ * @param prog プログラム名
+ * @param label ラベル
+ */
+unsigned labelhash(const char *prog, const char *label);
+
+/**
+ * ラベルを比較した結果を返す。qsort内で使われる関数
+ *
+ * @return ラベルが同一の場合は0、異なる場合は0以外
+ *
+ * @param *a ラベルa
+ * @param *b ラベルb
+ */
+int compare_adr(const void *a, const void *b);
+
+/**
+ * @brief ラベル数
+ */
+static int labelcnt = 0;
+
+/**
+ * @brief ラベル表
+ */
+static LABELTAB *labels[LABELTABSIZE];
+
+/**
+ * @brief ラベルのエラー
+ */
+static CERR cerr_label[] = {
+ { 101, "label already defined" },
+ { 102, "label table is full" },
+ { 103, "label not found" },
+};
+
+HKEY *label_hashkey(const char *value) {
+ HKEY *key = NULL;
+
+ key = malloc_chk(sizeof(HKEY), "label_hashkey");
+ key->type = CHARS;
+ key->val.s = strdup_chk(value, "label_hashkey->value");
+ return key;
+}
+
+unsigned labelhash(const char *prog, const char *label)
+{
+ HKEY *keys[2] = {NULL};
+ int i = 0;
+ unsigned h = 0;
+
+ if(prog[0]) {
+ keys[i++] = label_hashkey(prog);
+ }
+ keys[i] = label_hashkey(label);
+ h = hash(i+1, keys, LABELTABSIZE);
+ for(int j = 0; j < i + 1; j++) {
+ FREE(keys[j]->val.s);
+ FREE(keys[j]);
+ }
+ return h;
+}
+
+int compare_adr(const void *a, const void *b)