+/**
+ * プログラム名とラベルに対応するハッシュ値を返す
+ *
+ * @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" },
+};
+
+unsigned labelhash(const char *prog, const char *label)
+{
+ HKEY *keys[2];
+ int i = 0, j;
+ unsigned h;
+
+ if(*prog != '\0') {
+ keys[i] = malloc_chk(sizeof(HKEY), "labelhash.key");
+ keys[i]->type = CHARS;
+ keys[i]->val.s = strdup_chk(prog, "labelhash.key.val");
+ i++;
+ }
+ keys[i] = malloc_chk(sizeof(HKEY), "labelhash.key");
+ keys[i]->type = CHARS;
+ keys[i]->val.s = strdup_chk(label, "labelhash.key.val");
+ h = hash(i+1, keys, LABELTABSIZE);
+ for(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)
+{
+ return (**(LABELARRAY **)a).adr - (**(LABELARRAY **)b).adr;
+}
+
+/* assemble.hで定義された関数群 */
+void addcerrlist_label()
+{
+ addcerrlist(ARRAYSIZE(cerr_label), cerr_label);
+}