グローバル変数のリファクタリング
[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 /* callocを実行し、メモリを確保できない場合は */
17 /* エラーを出力して終了 */
18 void *calloc_chk(size_t nmemb, size_t size, char *tag)
19 {
20     void *p;
21
22     if((p = calloc(nmemb, size)) == NULL) {
23         fprintf(stderr, "%s: cannot allocate memory\n", tag);
24         exit(-1);
25     }
26     return p;
27 }
28
29 /* エラーの初期化 */
30 void cerr_init()
31 {
32     cerr = malloc_chk(sizeof(CERR), "cerr");
33     cerr->num = 0;
34 }
35
36 /* malloc_chkを実行してメモリを確保してから、 */
37 /* コピーした文字列を返す */
38 char *strdup_chk(const char *s, char *tag)
39 {
40     assert(s != NULL);
41     char *t;
42
43     t = malloc_chk(strlen(s) + 1, tag);
44     strcpy(t, s);
45     return t;
46 }
47
48 /* 現在のエラー */
49 CERR *cerr;
50
51 /* エラーリスト */
52 CERRLIST *cerrlist;
53
54 /* エラーリストを作成・追加する */
55 bool addcerrlist(int newerrc, CERR newerrv[])
56 {
57     int i;
58     CERRLIST *p, *q;
59
60     assert(newerrc > 0 && newerrv != NULL);
61     if(cerrlist == NULL) {
62         p = cerrlist = malloc_chk(sizeof(CERRLIST), "cerrlist");
63     } else {
64         for(p = cerrlist; p != NULL; p = p->next) {
65             q = p;
66         }
67         p = q->next = malloc_chk(sizeof(CERRLIST), "cerrlist.next");
68     }
69     for(i = 0; i < newerrc; i++) {
70         p->cerr = &(newerrv[i]);
71         p->next = malloc_chk(sizeof(CERRLIST), "cerrlist.next");
72         q = p;
73         p = p->next;
74     }
75     q->next = NULL;
76     return true;
77 }
78
79 /* 現在のエラーを設定する */
80 void setcerr(int num, const char *str)
81 {
82     cerr->num = num;
83     cerr->msg = malloc_chk(CERRMSGSIZE + 1, "cerr.msg");
84     if(str != NULL && strlen(str) <= CERRSTRSIZE) {
85         sprintf(cerr->msg, "%s: %s", str, getcerrmsg(cerr->num));
86     } else {
87         strcpy(cerr->msg, getcerrmsg(cerr->num));
88     }
89 }
90
91 /* エラーリストから、エラー番号に対応するメッセージを返す */
92 char *getcerrmsg(int num)
93 {
94     CERRLIST *p;
95
96     for(p = cerrlist; p != NULL; p = p->next) {
97         if(num == p->cerr->num) {
98             return p->cerr->msg;
99         }
100     }
101     return "unknown error";
102 }
103
104 /* エラーリストと現在のエラーを解放する */
105 void freecerr()
106 {
107     CERRLIST *p = cerrlist, *q;
108
109     /* エラーリストを解放 */
110     while(p != NULL) {
111         q = p->next;
112         free(p);
113         p = q;
114     }
115     /* 現在のエラーを解放 */
116     free(cerr);
117 }