File Coverage

deps/libgit2/src/errors.c
Criterion Covered Total %
statement 59 106 55.6
branch 19 40 47.5
condition n/a
subroutine n/a
pod n/a
total 78 146 53.4


line stmt bran cond sub pod time code
1             /*
2             * Copyright (C) the libgit2 contributors. All rights reserved.
3             *
4             * This file is part of libgit2, distributed under the GNU GPL v2 with
5             * a Linking Exception. For full terms see the included COPYING file.
6             */
7              
8             #include "common.h"
9              
10             #include "global.h"
11             #include "posix.h"
12             #include "buffer.h"
13              
14             /********************************************
15             * New error handling
16             ********************************************/
17              
18             static git_error g_git_oom_error = {
19             "Out of memory",
20             GIT_ERROR_NOMEMORY
21             };
22              
23 6773           static void set_error_from_buffer(int error_class)
24             {
25 6773           git_error *error = &GIT_GLOBAL->error_t;
26 6773           git_buf *buf = &GIT_GLOBAL->error_buf;
27              
28 6773           error->message = buf->ptr;
29 6773           error->klass = error_class;
30              
31 6773           GIT_GLOBAL->last_error = error;
32 6773           }
33              
34 2290           static void set_error(int error_class, char *string)
35             {
36 2290           git_buf *buf = &GIT_GLOBAL->error_buf;
37              
38 2290           git_buf_clear(buf);
39 2290 50         if (string) {
40 0           git_buf_puts(buf, string);
41 0           git__free(string);
42             }
43              
44 2290           set_error_from_buffer(error_class);
45 2290           }
46              
47 0           void git_error_set_oom(void)
48             {
49 0           GIT_GLOBAL->last_error = &g_git_oom_error;
50 0           }
51              
52 4483           void git_error_set(int error_class, const char *fmt, ...)
53             {
54             va_list ap;
55              
56 4483           va_start(ap, fmt);
57 4483           git_error_vset(error_class, fmt, ap);
58 4483           va_end(ap);
59 4483           }
60              
61 4483           void git_error_vset(int error_class, const char *fmt, va_list ap)
62             {
63             #ifdef GIT_WIN32
64             DWORD win32_error_code = (error_class == GIT_ERROR_OS) ? GetLastError() : 0;
65             #endif
66 4483 100         int error_code = (error_class == GIT_ERROR_OS) ? errno : 0;
67 4483           git_buf *buf = &GIT_GLOBAL->error_buf;
68              
69 4483           git_buf_clear(buf);
70 4483 50         if (fmt) {
71 4483           git_buf_vprintf(buf, fmt, ap);
72 4483 100         if (error_class == GIT_ERROR_OS)
73 2300           git_buf_PUTS(buf, ": ");
74             }
75              
76 4483 100         if (error_class == GIT_ERROR_OS) {
77             #ifdef GIT_WIN32
78             char * win32_error = git_win32_get_error_message(win32_error_code);
79             if (win32_error) {
80             git_buf_puts(buf, win32_error);
81             git__free(win32_error);
82              
83             SetLastError(0);
84             }
85             else
86             #endif
87 2300 100         if (error_code)
88 2255           git_buf_puts(buf, strerror(error_code));
89              
90 2300 100         if (error_code)
91 2255           errno = 0;
92             }
93              
94 4483 50         if (!git_buf_oom(buf))
95 4483           set_error_from_buffer(error_class);
96 4483           }
97              
98 0           int git_error_set_str(int error_class, const char *string)
99             {
100 0           git_buf *buf = &GIT_GLOBAL->error_buf;
101              
102 0 0         assert(string);
103              
104 0 0         if (!string) {
105 0           git_error_set(GIT_ERROR_INVALID, "unspecified caller error");
106 0           return -1;
107             }
108              
109 0           git_buf_clear(buf);
110 0           git_buf_puts(buf, string);
111              
112 0 0         if (git_buf_oom(buf))
113 0           return -1;
114              
115 0           set_error_from_buffer(error_class);
116 0           return 0;
117             }
118              
119 3972           void git_error_clear(void)
120             {
121 3972 100         if (GIT_GLOBAL->last_error != NULL) {
122 2290           set_error(0, NULL);
123 2290           GIT_GLOBAL->last_error = NULL;
124             }
125              
126 3972           errno = 0;
127             #ifdef GIT_WIN32
128             SetLastError(0);
129             #endif
130 3972           }
131              
132 66           const git_error *git_error_last(void)
133             {
134 66           return GIT_GLOBAL->last_error;
135             }
136              
137 2           int git_error_state_capture(git_error_state *state, int error_code)
138             {
139 2           git_error *error = GIT_GLOBAL->last_error;
140 2           git_buf *error_buf = &GIT_GLOBAL->error_buf;
141              
142 2           memset(state, 0, sizeof(git_error_state));
143              
144 2 50         if (!error_code)
145 0           return 0;
146              
147 2           state->error_code = error_code;
148 2           state->oom = (error == &g_git_oom_error);
149              
150 2 50         if (error) {
151 0           state->error_msg.klass = error->klass;
152              
153 0 0         if (state->oom)
154 0           state->error_msg.message = g_git_oom_error.message;
155             else
156 0           state->error_msg.message = git_buf_detach(error_buf);
157             }
158              
159 2           git_error_clear();
160 2           return error_code;
161             }
162              
163 2           int git_error_state_restore(git_error_state *state)
164             {
165 2           int ret = 0;
166              
167 2           git_error_clear();
168              
169 2 50         if (state && state->error_msg.message) {
    50          
170 0 0         if (state->oom)
171 0           git_error_set_oom();
172             else
173 0           set_error(state->error_msg.klass, state->error_msg.message);
174              
175 0           ret = state->error_code;
176 0           memset(state, 0, sizeof(git_error_state));
177             }
178              
179 2           return ret;
180             }
181              
182 0           void git_error_state_free(git_error_state *state)
183             {
184 0 0         if (!state)
185 0           return;
186              
187 0 0         if (!state->oom)
188 0           git__free(state->error_msg.message);
189              
190 0           memset(state, 0, sizeof(git_error_state));
191             }
192              
193 0           int git_error_system_last(void)
194             {
195             #ifdef GIT_WIN32
196             return GetLastError();
197             #else
198 0           return errno;
199             #endif
200             }
201              
202 0           void git_error_system_set(int code)
203             {
204             #ifdef GIT_WIN32
205             SetLastError(code);
206             #else
207 0           errno = code;
208             #endif
209 0           }
210              
211             /* Deprecated error values and functions */
212              
213 21           const git_error *giterr_last(void)
214             {
215 21           return git_error_last();
216             }
217              
218 0           void giterr_clear(void)
219             {
220 0           git_error_clear();
221 0           }
222              
223 0           void giterr_set_str(int error_class, const char *string)
224             {
225 0           git_error_set_str(error_class, string);
226 0           }
227              
228 0           void giterr_set_oom(void)
229             {
230 0           git_error_set_oom();
231 0           }