1 /*
2 * Copyright 2018 Jonathan Dieter <jdieter@gmail.com>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include <stdio.h>
28 #include <assert.h>
29 #include <string.h>
30 #include <stdarg.h>
31 #include <stdbool.h>
32 #include <zck.h>
33
34 #include "zck_private.h"
35
36 static const char *empty_error = "";
37
38 zckCtx zck_none = {0};
39
set_error_wf(zckCtx * zck,int fatal,const char * function,const char * format,...)40 void set_error_wf(zckCtx *zck, int fatal, const char *function,
41 const char *format, ...) {
42 va_list args;
43 int size = 0;
44 char *old_msg = NULL;
45 int old_size = 0;
46 assert(format != NULL);
47
48 if(zck == NULL)
49 zck = &zck_none;
50
51 zck->error_state = 1 + (fatal > 0 ? 1 : 0);
52 va_start(args, format);
53 size = vsnprintf(NULL, 0, format, args);
54 va_end(args);
55 va_start(args, format);
56 zck_log_v(function, ZCK_LOG_ERROR, format, args);
57 va_end(args);
58 if(size < 0)
59 return;
60 if(zck->msg != NULL) {
61 old_size = strlen(zck->msg);
62 old_msg = zck->msg;
63 }
64 if(old_msg)
65 zck->msg = zmalloc(size + old_size + 3);
66 else
67 zck->msg = zmalloc(size + 2);
68 va_start(args, format);
69 vsnprintf(zck->msg, size + 1, format, args);
70 va_end(args);
71 if(old_msg) {
72 snprintf(zck->msg + size, old_size + 3, ": %s", old_msg);
73 free(old_msg);
74 } else {
75 snprintf(zck->msg + size, 2, "\n");
76 }
77
78 }
79
zck_is_error(zckCtx * zck)80 int PUBLIC zck_is_error(zckCtx *zck) {
81 if(zck == NULL)
82 zck = &zck_none;
83
84 return zck->error_state;
85 }
86
zck_get_error(zckCtx * zck)87 const char PUBLIC *zck_get_error(zckCtx *zck) {
88 if(zck == NULL)
89 zck = &zck_none;
90
91 if(zck->msg == NULL)
92 return empty_error;
93 return zck->msg;
94 }
95
zck_clear_error(zckCtx * zck)96 bool PUBLIC zck_clear_error(zckCtx *zck) {
97 if(zck != NULL && zck->error_state > 1)
98 return false;
99
100 if(zck == NULL)
101 zck = &zck_none;
102
103 free(zck->msg);
104 zck->msg = NULL;
105 zck->error_state = 0;
106 return true;
107 }
108