]>
Commit | Line | Data |
---|---|---|
02f9e637 | 1 | /* |
359fc2d2 | 2 | * Copyright (C) the libgit2 contributors. All rights reserved. |
02f9e637 | 3 | * |
bb742ede VM |
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. | |
02f9e637 | 6 | */ |
eae0bfdc | 7 | |
ae234862 | 8 | #include "common.h" |
eae0bfdc | 9 | |
a15c550d | 10 | #include "global.h" |
60bc2d20 | 11 | #include "posix.h" |
22772166 | 12 | #include "buffer.h" |
02f9e637 | 13 | |
60bc2d20 VM |
14 | /******************************************** |
15 | * New error handling | |
16 | ********************************************/ | |
17 | ||
1a481123 VM |
18 | static git_error g_git_oom_error = { |
19 | "Out of memory", | |
20 | GITERR_NOMEMORY | |
21 | }; | |
22 | ||
f85fc367 | 23 | static void set_error_from_buffer(int error_class) |
22772166 VM |
24 | { |
25 | git_error *error = &GIT_GLOBAL->error_t; | |
f85fc367 | 26 | git_buf *buf = &GIT_GLOBAL->error_buf; |
22772166 | 27 | |
f85fc367 | 28 | error->message = buf->ptr; |
22772166 VM |
29 | error->klass = error_class; |
30 | ||
31 | GIT_GLOBAL->last_error = error; | |
32 | } | |
33 | ||
f85fc367 CMN |
34 | static void set_error(int error_class, char *string) |
35 | { | |
36 | git_buf *buf = &GIT_GLOBAL->error_buf; | |
37 | ||
38 | git_buf_clear(buf); | |
39 | if (string) { | |
40 | git_buf_puts(buf, string); | |
41 | git__free(string); | |
42 | } | |
43 | ||
44 | set_error_from_buffer(error_class); | |
45 | } | |
46 | ||
1a481123 VM |
47 | void giterr_set_oom(void) |
48 | { | |
49 | GIT_GLOBAL->last_error = &g_git_oom_error; | |
50 | } | |
51 | ||
52 | void giterr_set(int error_class, const char *string, ...) | |
60bc2d20 | 53 | { |
60bc2d20 | 54 | va_list arglist; |
3ae0aad7 RB |
55 | #ifdef GIT_WIN32 |
56 | DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0; | |
57 | #endif | |
58 | int error_code = (error_class == GITERR_OS) ? errno : 0; | |
f85fc367 | 59 | git_buf *buf = &GIT_GLOBAL->error_buf; |
60bc2d20 | 60 | |
f85fc367 | 61 | git_buf_clear(buf); |
e62f96de ET |
62 | if (string) { |
63 | va_start(arglist, string); | |
f85fc367 | 64 | git_buf_vprintf(buf, string, arglist); |
e62f96de ET |
65 | va_end(arglist); |
66 | ||
67 | if (error_class == GITERR_OS) | |
f85fc367 | 68 | git_buf_PUTS(buf, ": "); |
e62f96de | 69 | } |
60bc2d20 | 70 | |
dda708e7 | 71 | if (error_class == GITERR_OS) { |
e1de726c | 72 | #ifdef GIT_WIN32 |
c70455c7 SS |
73 | char * win32_error = git_win32_get_error_message(win32_error_code); |
74 | if (win32_error) { | |
f85fc367 | 75 | git_buf_puts(buf, win32_error); |
c70455c7 | 76 | git__free(win32_error); |
8f624a47 PK |
77 | |
78 | SetLastError(0); | |
e1de726c | 79 | } |
8f624a47 | 80 | else |
e1de726c | 81 | #endif |
e62f96de | 82 | if (error_code) |
f85fc367 | 83 | git_buf_puts(buf, strerror(error_code)); |
8f624a47 PK |
84 | |
85 | if (error_code) | |
86 | errno = 0; | |
ae9e29fd RB |
87 | } |
88 | ||
f85fc367 CMN |
89 | if (!git_buf_oom(buf)) |
90 | set_error_from_buffer(error_class); | |
dda708e7 VM |
91 | } |
92 | ||
93 | void giterr_set_str(int error_class, const char *string) | |
94 | { | |
f85fc367 | 95 | git_buf *buf = &GIT_GLOBAL->error_buf; |
1a628100 RB |
96 | |
97 | assert(string); | |
98 | ||
f85fc367 CMN |
99 | if (!string) |
100 | return; | |
dda708e7 | 101 | |
f85fc367 CMN |
102 | git_buf_clear(buf); |
103 | git_buf_puts(buf, string); | |
104 | if (!git_buf_oom(buf)) | |
105 | set_error_from_buffer(error_class); | |
60bc2d20 VM |
106 | } |
107 | ||
cc146626 | 108 | int giterr_set_regex(const regex_t *regex, int error_code) |
dda708e7 VM |
109 | { |
110 | char error_buf[1024]; | |
6c72035f PK |
111 | |
112 | assert(error_code); | |
113 | ||
dda708e7 VM |
114 | regerror(error_code, regex, error_buf, sizeof(error_buf)); |
115 | giterr_set_str(GITERR_REGEX, error_buf); | |
cc146626 | 116 | |
117 | if (error_code == REG_NOMATCH) | |
118 | return GIT_ENOTFOUND; | |
6c72035f PK |
119 | |
120 | return GIT_EINVALIDSPEC; | |
dda708e7 VM |
121 | } |
122 | ||
1a481123 | 123 | void giterr_clear(void) |
60bc2d20 | 124 | { |
96869a4e RB |
125 | if (GIT_GLOBAL->last_error != NULL) { |
126 | set_error(0, NULL); | |
127 | GIT_GLOBAL->last_error = NULL; | |
128 | } | |
97a17e4e RB |
129 | |
130 | errno = 0; | |
131 | #ifdef GIT_WIN32 | |
132 | SetLastError(0); | |
133 | #endif | |
60bc2d20 | 134 | } |
e3c47510 | 135 | |
ef4857c2 ET |
136 | const git_error *giterr_last(void) |
137 | { | |
138 | return GIT_GLOBAL->last_error; | |
139 | } | |
140 | ||
141 | int giterr_state_capture(git_error_state *state, int error_code) | |
d6c60169 | 142 | { |
d6c60169 | 143 | git_error *error = GIT_GLOBAL->last_error; |
ef4857c2 | 144 | git_buf *error_buf = &GIT_GLOBAL->error_buf; |
d6c60169 | 145 | |
ef4857c2 | 146 | memset(state, 0, sizeof(git_error_state)); |
d6c60169 | 147 | |
ef4857c2 ET |
148 | if (!error_code) |
149 | return 0; | |
150 | ||
151 | state->error_code = error_code; | |
152 | state->oom = (error == &g_git_oom_error); | |
d6c60169 | 153 | |
ef4857c2 ET |
154 | if (error) { |
155 | state->error_msg.klass = error->klass; | |
d6c60169 | 156 | |
ef4857c2 ET |
157 | if (state->oom) |
158 | state->error_msg.message = g_git_oom_error.message; | |
159 | else | |
160 | state->error_msg.message = git_buf_detach(error_buf); | |
0fcfb60d | 161 | } |
d6c60169 | 162 | |
ef4857c2 ET |
163 | giterr_clear(); |
164 | return error_code; | |
d6c60169 RB |
165 | } |
166 | ||
ef4857c2 | 167 | int giterr_state_restore(git_error_state *state) |
e3c47510 | 168 | { |
ef4857c2 | 169 | int ret = 0; |
96869a4e | 170 | |
ef4857c2 | 171 | giterr_clear(); |
96869a4e | 172 | |
ef4857c2 ET |
173 | if (state && state->error_msg.message) { |
174 | if (state->oom) | |
0fcfb60d | 175 | giterr_set_oom(); |
ef4857c2 | 176 | else |
0fcfb60d | 177 | set_error(state->error_msg.klass, state->error_msg.message); |
ef4857c2 ET |
178 | |
179 | ret = state->error_code; | |
180 | memset(state, 0, sizeof(git_error_state)); | |
0fcfb60d | 181 | } |
96869a4e | 182 | |
ef4857c2 ET |
183 | return ret; |
184 | } | |
185 | ||
186 | void giterr_state_free(git_error_state *state) | |
187 | { | |
188 | if (!state) | |
189 | return; | |
190 | ||
191 | if (!state->oom) | |
192 | git__free(state->error_msg.message); | |
193 | ||
194 | memset(state, 0, sizeof(git_error_state)); | |
96869a4e RB |
195 | } |
196 | ||
197 | int giterr_system_last(void) | |
198 | { | |
199 | #ifdef GIT_WIN32 | |
200 | return GetLastError(); | |
201 | #else | |
202 | return errno; | |
203 | #endif | |
204 | } | |
205 | ||
206 | void giterr_system_set(int code) | |
207 | { | |
208 | #ifdef GIT_WIN32 | |
209 | SetLastError(code); | |
210 | #else | |
211 | errno = code; | |
212 | #endif | |
213 | } |