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