36b33a4dce81b1db45ca5a34bf4867e431d16547
[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         p->next = malloc_chk(sizeof(CERRLIST), "cerrlist.next");
47         q = p;
48         p = p->next;
49     }
50     q->next = NULL;
51     return true;
52 }
53
54 /**
55  * 現在のエラーを設定する
56  */
57 void setcerr(int num, const char *str)
58 {
59     /* 現在のエラー番号を設定  */
60     cerr->num = num;
61     /* 現在のエラーメッセージを設定 */
62     cerr->msg = malloc_chk(CERRMSGSIZE + 1, "cerr.msg");
63     if(str != NULL && strlen(str) <= CERRSTRSIZE) {
64         sprintf(cerr->msg, "%s: %s", str, getcerrmsg(cerr->num));
65     } else {
66         strcpy(cerr->msg, getcerrmsg(cerr->num));
67     }
68 }
69
70 /**
71  * エラーリストから、エラー番号に対応するメッセージを返す
72  */
73 char *getcerrmsg(int num)
74 {
75     CERRLIST *p;
76
77     for(p = cerrlist; p != NULL; p = p->next) {
78         if(num == p->cerr->num) {
79             return p->cerr->msg;
80         }
81     }
82     return "unknown error";
83 }
84
85 /**
86  * エラーリストと現在のエラーを解放する
87  */
88 void freecerr()
89 {
90     CERRLIST *p = cerrlist, *q;
91
92     /* エラーリストを解放 */
93     while(p != NULL) {
94         q = p->next;
95         free_chk(p, "freecerr.p");
96         p = q;
97     }
98     /* 現在のエラーメッセージを解放 */
99     free_chk(cerr->msg, "cerr.msg");
100     /* 現在のエラーを解放 */
101     free_chk(cerr, "cerr");
102 }