24f620d9b19736a06cbc4dea57bda759b4eff66b
[YACASL2.git] / src / cerr.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #include <stdbool.h>
6 #include "cerr.h"
7
8 /**
9  * エラーの初期化
10  */
11 void cerr_init()
12 {
13     cerr = malloc_chk(sizeof(CERR), "cerr");
14     cerr->num = 0;
15 }
16
17 /**
18  * 現在のエラー
19  */
20 CERR *cerr;
21
22 /**
23  * エラーリスト
24  */
25 CERRLIST *cerrlist;
26
27 /**
28  * エラーリストを作成または追加する
29  */
30 bool addcerrlist(int newerrc, CERR newerrv[])
31 {
32     int i;
33     CERRLIST *p, *q;
34
35     assert(newerrc > 0 && newerrv != NULL);
36     if(cerrlist == NULL) {
37         p = cerrlist = malloc_chk(sizeof(CERRLIST), "cerrlist");
38     } else {
39         for(p = cerrlist; p != NULL; p = p->next) {
40             q = p;
41         }
42         p = q->next = malloc_chk(sizeof(CERRLIST), "cerrlist.next");
43     }
44     for(i = 0; i < newerrc; i++) {
45         p->cerr = &newerrv[i];
46         q = p;
47         p = p->next = malloc_chk(sizeof(CERRLIST), "cerrlist.next");
48     }
49     q->next = NULL;
50     return true;
51 }
52
53 /**
54  * エラーリストを表示する
55  */
56 void printcerrlist()
57 {
58     CERRLIST *p;
59
60     if(cerrlist == NULL) {
61         puts("error list is null.");
62     } else {
63         for(p = cerrlist; p != NULL; p = p->next) {
64             printf("%d: %s\n", p->cerr->num, p->cerr->msg);
65         }
66     }
67 }
68
69 /**
70  * 現在のエラーを設定する
71  */
72 void setcerr(int num, const char *str)
73 {
74     /* 現在のエラー番号を設定  */
75     cerr->num = num;
76     /* 現在のエラーメッセージを設定 */
77     cerr->msg = malloc_chk(CERRMSGSIZE + 1, "cerr.msg");
78     if(str != NULL && strlen(str) <= CERRSTRSIZE) {
79         sprintf(cerr->msg, "%s: %s", str, getcerrmsg(cerr->num));
80     } else {
81         strcpy(cerr->msg, getcerrmsg(cerr->num));
82     }
83 }
84
85 /**
86  * エラーリストから、エラー番号に対応するメッセージを返す
87  */
88 char *getcerrmsg(int num)
89 {
90     CERRLIST *p;
91     char *msg = "unknown error";
92
93     for(p = cerrlist; p != NULL; p = p->next) {
94         if(num == p->cerr->num) {
95             msg = p->cerr->msg;
96             break;
97         }
98     }
99     return msg;
100 }
101
102 /**
103  * エラーリストと現在のエラーを解放する
104  */
105 void freecerr()
106 {
107     CERRLIST *p = cerrlist, *q;
108
109     /* 現在のエラーメッセージを解放 */
110     free_chk(cerr->msg, "cerr.msg");
111     /* 現在のエラーを解放 */
112     free_chk(cerr, "cerr");
113     /* エラーリストを解放 */
114     for(p = cerrlist; p != NULL; p = q) {
115         q = p->next;
116         free_chk(p, "freecerr.p");
117     }
118 }