1
2 #include "errors.h"
3
4 #include <Rinternals.h>
5
6 #include <string.h>
7
8 #define ERRORBUF_SIZE 4096
9 static char errorbuf[ERRORBUF_SIZE];
10
r_throw_error(const char * func,const char * filename,int line,const char * msg,...)11 SEXP r_throw_error(const char *func, const char *filename, int line,
12 const char *msg, ...) {
13 va_list args;
14 errorbuf[0] = '\0';
15 va_start(args, msg);
16 vsnprintf(errorbuf, ERRORBUF_SIZE, msg, args);
17 va_end (args);
18 error("%s @%s:%d (%s)", errorbuf, filename, line, func);
19 return R_NilValue;
20 }
21
22 #ifdef _WIN32
23
r_throw_system_error(const char * func,const char * filename,int line,DWORD errorcode,const char * sysmsg,const char * msg,...)24 SEXP r_throw_system_error(const char *func, const char *filename, int line,
25 DWORD errorcode, const char *sysmsg,
26 const char *msg, ...) {
27
28 va_list args;
29 LPVOID lpMsgBuf;
30 char *realsysmsg = sysmsg ? (char*) sysmsg : NULL;
31 char *failmsg = "Formatting the system message failed :(";
32
33 if (errorcode == -1) errorcode = GetLastError();
34
35 if (!realsysmsg) {
36 DWORD ret = FormatMessage(
37 FORMAT_MESSAGE_ALLOCATE_BUFFER |
38 FORMAT_MESSAGE_FROM_SYSTEM |
39 FORMAT_MESSAGE_IGNORE_INSERTS,
40 NULL,
41 errorcode,
42 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
43 (LPTSTR) &lpMsgBuf,
44 0, NULL);
45
46 if (ret == 0) {
47 realsysmsg = failmsg;
48 } else {
49 realsysmsg = R_alloc(1, strlen(lpMsgBuf) + 1);
50 strcpy(realsysmsg, lpMsgBuf);
51 LocalFree(lpMsgBuf);
52 }
53 }
54
55 errorbuf[0] = '\0';
56 va_start(args, msg);
57 vsnprintf(errorbuf, ERRORBUF_SIZE, msg, args);
58 va_end(args);
59 error("%s (system error %d, %s) @%s:%d (%s)", errorbuf, errorcode,
60 realsysmsg, filename, line, func);
61 return R_NilValue;
62 }
63
64 #endif
65
66 #ifdef _WIN32
r_throw_posix_error(const char * func,const char * filename,int line,int errorcode,const char * sysmsg,const char * msg,...)67 SEXP r_throw_posix_error(
68 #else
69 SEXP r_throw_system_error(
70 #endif
71 const char *func, const char *filename, int line,
72 int errorcode, const char *sysmsg,
73 const char *msg, ...) {
74 va_list args;
75 if (!sysmsg) sysmsg = strerror(errorcode);
76 errorbuf[0] = '\0';
77 va_start(args, msg);
78 vsnprintf(errorbuf, ERRORBUF_SIZE, msg, args);
79 va_end(args);
80 error("%s (system error %d, %s) @%s:%d (%s)", errorbuf, errorcode, sysmsg,
81 filename, line, func);
82 return R_NilValue;
83 }
84