]> git.proxmox.com Git - libgit2.git/blob - src/errors.c
error: Simplify giterr_detach
[libgit2.git] / src / errors.c
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 #include "common.h"
8 #include "global.h"
9 #include "posix.h"
10 #include "buffer.h"
11 #include <stdarg.h>
12
13 /********************************************
14 * New error handling
15 ********************************************/
16
17 static git_error g_git_oom_error = {
18 "Out of memory",
19 GITERR_NOMEMORY
20 };
21
22 static void set_error(int error_class, char *string)
23 {
24 git_error *error = &GIT_GLOBAL->error_t;
25
26 git__free(error->message);
27
28 error->message = string;
29 error->klass = error_class;
30
31 GIT_GLOBAL->last_error = error;
32 }
33
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, ...)
40 {
41 git_buf buf = GIT_BUF_INIT;
42 va_list arglist;
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;
47
48 va_start(arglist, string);
49 git_buf_vprintf(&buf, string, arglist);
50 va_end(arglist);
51
52 if (error_class == GITERR_OS) {
53 #ifdef GIT_WIN32
54 char * win32_error = git_win32_get_error_message(win32_error_code);
55 if (win32_error) {
56 git_buf_PUTS(&buf, ": ");
57 git_buf_puts(&buf, win32_error);
58 git__free(win32_error);
59
60 SetLastError(0);
61 }
62 else
63 #endif
64 if (error_code) {
65 git_buf_PUTS(&buf, ": ");
66 git_buf_puts(&buf, strerror(error_code));
67 }
68
69 if (error_code)
70 errno = 0;
71 }
72
73 if (!git_buf_oom(&buf))
74 set_error(error_class, git_buf_detach(&buf));
75 }
76
77 void giterr_set_str(int error_class, const char *string)
78 {
79 char *message;
80
81 assert(string);
82
83 message = git__strdup(string);
84
85 if (message)
86 set_error(error_class, message);
87 }
88
89 int giterr_set_regex(const regex_t *regex, int error_code)
90 {
91 char error_buf[1024];
92
93 assert(error_code);
94
95 regerror(error_code, regex, error_buf, sizeof(error_buf));
96 giterr_set_str(GITERR_REGEX, error_buf);
97
98 if (error_code == REG_NOMATCH)
99 return GIT_ENOTFOUND;
100
101 return GIT_EINVALIDSPEC;
102 }
103
104 void giterr_clear(void)
105 {
106 set_error(0, NULL);
107 GIT_GLOBAL->last_error = NULL;
108
109 errno = 0;
110 #ifdef GIT_WIN32
111 SetLastError(0);
112 #endif
113 }
114
115 int giterr_detach(git_error *cpy)
116 {
117 git_error *error = GIT_GLOBAL->last_error;
118
119 assert(cpy);
120
121 if (!error)
122 return -1;
123
124 cpy->message = error->message;
125 cpy->klass = error->klass;
126
127 error->message = NULL;
128 giterr_clear();
129
130 return 0;
131 }
132
133 const git_error *giterr_last(void)
134 {
135 return GIT_GLOBAL->last_error;
136 }