File Coverage

deps/libgit2/src/libgit2/errors.c
Criterion Covered Total %
statement 60 105 57.1
branch 20 40 50.0
condition n/a
subroutine n/a
pod n/a
total 80 145 55.1


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 "threadstate.h"
11             #include "posix.h"
12             #include "str.h"
13             #include "libgit2.h"
14              
15             /********************************************
16             * New error handling
17             ********************************************/
18              
19             static git_error g_git_oom_error = {
20             "Out of memory",
21             GIT_ERROR_NOMEMORY
22             };
23              
24             static git_error g_git_uninitialized_error = {
25             "libgit2 has not been initialized; you must call git_libgit2_init",
26             GIT_ERROR_INVALID
27             };
28              
29 7006           static void set_error_from_buffer(int error_class)
30             {
31 7006           git_error *error = &GIT_THREADSTATE->error_t;
32 7006           git_str *buf = &GIT_THREADSTATE->error_buf;
33              
34 7006           error->message = buf->ptr;
35 7006           error->klass = error_class;
36              
37 7006           GIT_THREADSTATE->last_error = error;
38 7006           }
39              
40 2752           static void set_error(int error_class, char *string)
41             {
42 2752           git_str *buf = &GIT_THREADSTATE->error_buf;
43              
44 2752           git_str_clear(buf);
45 2752 50         if (string) {
46 0           git_str_puts(buf, string);
47 0           git__free(string);
48             }
49              
50 2752           set_error_from_buffer(error_class);
51 2752           }
52              
53 0           void git_error_set_oom(void)
54             {
55 0           GIT_THREADSTATE->last_error = &g_git_oom_error;
56 0           }
57              
58 4254           void git_error_set(int error_class, const char *fmt, ...)
59             {
60             va_list ap;
61              
62 4254           va_start(ap, fmt);
63 4254           git_error_vset(error_class, fmt, ap);
64 4254           va_end(ap);
65 4254           }
66              
67 4254           void git_error_vset(int error_class, const char *fmt, va_list ap)
68             {
69             #ifdef GIT_WIN32
70             DWORD win32_error_code = (error_class == GIT_ERROR_OS) ? GetLastError() : 0;
71             #endif
72 4254 100         int error_code = (error_class == GIT_ERROR_OS) ? errno : 0;
73 4254           git_str *buf = &GIT_THREADSTATE->error_buf;
74              
75 4254           git_str_clear(buf);
76 4254 50         if (fmt) {
77 4254           git_str_vprintf(buf, fmt, ap);
78 4254 100         if (error_class == GIT_ERROR_OS)
79 2008           git_str_PUTS(buf, ": ");
80             }
81              
82 4254 100         if (error_class == GIT_ERROR_OS) {
83             #ifdef GIT_WIN32
84             char * win32_error = git_win32_get_error_message(win32_error_code);
85             if (win32_error) {
86             git_str_puts(buf, win32_error);
87             git__free(win32_error);
88              
89             SetLastError(0);
90             }
91             else
92             #endif
93 2008 100         if (error_code)
94 1938           git_str_puts(buf, strerror(error_code));
95              
96 2008 100         if (error_code)
97 1938           errno = 0;
98             }
99              
100 4254 50         if (!git_str_oom(buf))
101 4254           set_error_from_buffer(error_class);
102 4254           }
103              
104 0           int git_error_set_str(int error_class, const char *string)
105             {
106 0           git_str *buf = &GIT_THREADSTATE->error_buf;
107              
108 0 0         GIT_ASSERT_ARG(string);
109              
110 0           git_str_clear(buf);
111 0           git_str_puts(buf, string);
112              
113 0 0         if (git_str_oom(buf))
114 0           return -1;
115              
116 0           set_error_from_buffer(error_class);
117 0           return 0;
118             }
119              
120 4569           void git_error_clear(void)
121             {
122 4569 100         if (GIT_THREADSTATE->last_error != NULL) {
123 2752           set_error(0, NULL);
124 2752           GIT_THREADSTATE->last_error = NULL;
125             }
126              
127 4569           errno = 0;
128             #ifdef GIT_WIN32
129             SetLastError(0);
130             #endif
131 4569           }
132              
133 67           const git_error *git_error_last(void)
134             {
135             /* If the library is not initialized, return a static error. */
136 67 50         if (!git_libgit2_init_count())
137 0           return &g_git_uninitialized_error;
138              
139 67           return GIT_THREADSTATE->last_error;
140             }
141              
142 2           int git_error_state_capture(git_error_state *state, int error_code)
143             {
144 2           git_error *error = GIT_THREADSTATE->last_error;
145 2           git_str *error_buf = &GIT_THREADSTATE->error_buf;
146              
147 2           memset(state, 0, sizeof(git_error_state));
148              
149 2 50         if (!error_code)
150 0           return 0;
151              
152 2           state->error_code = error_code;
153 2           state->oom = (error == &g_git_oom_error);
154              
155 2 50         if (error) {
156 0           state->error_msg.klass = error->klass;
157              
158 0 0         if (state->oom)
159 0           state->error_msg.message = g_git_oom_error.message;
160             else
161 0           state->error_msg.message = git_str_detach(error_buf);
162             }
163              
164 2           git_error_clear();
165 2           return error_code;
166             }
167              
168 2           int git_error_state_restore(git_error_state *state)
169             {
170 2           int ret = 0;
171              
172 2           git_error_clear();
173              
174 2 50         if (state && state->error_msg.message) {
    50          
175 0 0         if (state->oom)
176 0           git_error_set_oom();
177             else
178 0           set_error(state->error_msg.klass, state->error_msg.message);
179              
180 0           ret = state->error_code;
181 0           memset(state, 0, sizeof(git_error_state));
182             }
183              
184 2           return ret;
185             }
186              
187 0           void git_error_state_free(git_error_state *state)
188             {
189 0 0         if (!state)
190 0           return;
191              
192 0 0         if (!state->oom)
193 0           git__free(state->error_msg.message);
194              
195 0           memset(state, 0, sizeof(git_error_state));
196             }
197              
198 0           int git_error_system_last(void)
199             {
200             #ifdef GIT_WIN32
201             return GetLastError();
202             #else
203 0           return errno;
204             #endif
205             }
206              
207 0           void git_error_system_set(int code)
208             {
209             #ifdef GIT_WIN32
210             SetLastError(code);
211             #else
212 0           errno = code;
213             #endif
214 0           }
215              
216             /* Deprecated error values and functions */
217              
218             #ifndef GIT_DEPRECATE_HARD
219 22           const git_error *giterr_last(void)
220             {
221 22           return git_error_last();
222             }
223              
224 0           void giterr_clear(void)
225             {
226 0           git_error_clear();
227 0           }
228              
229 0           void giterr_set_str(int error_class, const char *string)
230             {
231 0           git_error_set_str(error_class, string);
232 0           }
233              
234 0           void giterr_set_oom(void)
235             {
236 0           git_error_set_oom();
237 0           }
238             #endif