]> git.proxmox.com Git - libgit2.git/blob - src/errors.c
Merge branch 'development'
[libgit2.git] / src / errors.c
1 /*
2 * Copyright (C) 2009-2012 the libgit2 contributors
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
44 int unix_error_code = 0;
45
46 #ifdef GIT_WIN32
47 DWORD win32_error_code = 0;
48 #endif
49
50 if (error_class == GITERR_OS) {
51 unix_error_code = errno;
52 errno = 0;
53
54 #ifdef GIT_WIN32
55 win32_error_code = GetLastError();
56 SetLastError(0);
57 #endif
58 }
59
60 va_start(arglist, string);
61 git_buf_vprintf(&buf, string, arglist);
62 va_end(arglist);
63
64 /* automatically suffix strerror(errno) for GITERR_OS errors */
65 if (error_class == GITERR_OS) {
66
67 if (unix_error_code != 0) {
68 git_buf_PUTS(&buf, ": ");
69 git_buf_puts(&buf, strerror(unix_error_code));
70 }
71
72 #ifdef GIT_WIN32
73 else if (win32_error_code != 0) {
74 LPVOID lpMsgBuf = NULL;
75
76 FormatMessage(
77 FORMAT_MESSAGE_ALLOCATE_BUFFER |
78 FORMAT_MESSAGE_FROM_SYSTEM |
79 FORMAT_MESSAGE_IGNORE_INSERTS,
80 NULL, win32_error_code, 0, (LPTSTR) &lpMsgBuf, 0, NULL);
81
82 if (lpMsgBuf) {
83 git_buf_PUTS(&buf, ": ");
84 git_buf_puts(&buf, lpMsgBuf);
85 LocalFree(lpMsgBuf);
86 }
87 }
88 #endif
89 }
90
91 if (!git_buf_oom(&buf))
92 set_error(error_class, git_buf_detach(&buf));
93 }
94
95 void giterr_set_str(int error_class, const char *string)
96 {
97 char *message = git__strdup(string);
98
99 if (message)
100 set_error(error_class, message);
101 }
102
103 void giterr_set_regex(const regex_t *regex, int error_code)
104 {
105 char error_buf[1024];
106 regerror(error_code, regex, error_buf, sizeof(error_buf));
107 giterr_set_str(GITERR_REGEX, error_buf);
108 }
109
110 void giterr_clear(void)
111 {
112 GIT_GLOBAL->last_error = NULL;
113 }
114
115 const git_error *giterr_last(void)
116 {
117 return GIT_GLOBAL->last_error;
118 }
119