Merge branch 'master' of dragon:/home/dav/yacasl2
[YACASL2.git] / src / cerr.c
1 #include "cerr.h"
2
3 /* mallocを実行し、メモリを確保できない場合は */
4 /* エラーを出力して終了 */
5 void *malloc_chk(size_t size, char *tag)
6 {
7     void *p;
8
9     if((p = malloc(size)) == NULL) {
10         fprintf(stderr, "%s: cannot allocate memory\n", tag);
11         exit(-1);
12     }
13     return p;
14 }
15
16 /* malloc_chkを実行してメモリを確保してから、 */
17 /* コピーした文字列を返す */
18 char *strdup_chk(const char *s, char *tag)
19 {
20     assert(s != NULL);
21     char *t;
22
23     t = malloc_chk(strlen(s) + 1, tag);
24     strcpy(t, s);
25     return t;
26 }
27
28 /* 現在のエラー */
29 CERR *cerr;
30
31 /* エラーリスト */
32 CERRLIST *cerrlist;
33
34 /* エラーリストを作成・追加する */
35 bool addcerrlist(int newerrc, CERR newerrv[])
36 {
37     int i;
38     CERRLIST *p, *q;
39
40     assert(newerrc > 0 && newerrv != NULL);
41     if(cerrlist == NULL) {
42         p = cerrlist = malloc_chk(sizeof(CERRLIST), "cerrlist");
43     } else {
44         for(p = cerrlist; p != NULL; p = p->next) {
45             q = p;
46         }
47         p = q->next = malloc_chk(sizeof(CERRLIST), "cerrlist.next");
48     }
49     for(i = 0; i < newerrc; i++) {
50         p->cerr = &(newerrv[i]);
51         p->next = malloc_chk(sizeof(CERRLIST), "cerrlist.next");
52         q = p;
53         p = p->next;
54     }
55     q->next = NULL;
56     return true;
57 }
58
59 /* 現在のエラーを設定する */
60 void setcerr(int num, const char *str)
61 {
62     cerr->num = num;
63     cerr->msg = malloc_chk(CERRMSGSIZE + 1, "cerr.msg");
64     if(str != NULL && strlen(str) <= CERRSTRSIZE) {
65         sprintf(cerr->msg, "%s: %s", str, getcerrmsg(cerr->num));
66     } else {
67         strcpy(cerr->msg, getcerrmsg(cerr->num));
68     }
69 }
70
71 /* エラーリストから、エラー番号に対応するメッセージを返す */
72 char *getcerrmsg(int num)
73 {
74     CERRLIST *p;
75
76     for(p = cerrlist; p != NULL; p = p->next) {
77         if(num == p->cerr->num) {
78             return p->cerr->msg;
79         }
80     }
81     return "unknown error";
82 }
83
84 /* エラーリストと現在のエラーを解放する */
85 void freecerr()
86 {
87     CERRLIST *p = cerrlist, *q;
88
89     /* エラーリストを解放 */
90     while(p != NULL) {
91         q = p->next;
92         free(p);
93         p = q;
94     }
95     /* 現在のエラーを解放 */
96     free(cerr);
97 }