diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2020-04-18 15:28:21 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2020-04-19 00:32:26 -0400 |
commit | f70b803e39484a2eba362414545ba8afd027c9da (patch) | |
tree | 9fd89a070f272df3e0c47de821f6fbf38c914360 | |
parent | 59f7d29e2d707373ba1153337dca3279a2e3acc5 (diff) | |
download | spmc-f70b803e39484a2eba362414545ba8afd027c9da.tar.gz |
Add error handler
-rw-r--r-- | include/error_handler.h | 34 | ||||
-rw-r--r-- | include/spm.h | 1 | ||||
-rw-r--r-- | lib/error_handler.c | 27 | ||||
-rw-r--r-- | tests/test_error_handler_spm_strerror.c | 27 |
4 files changed, 89 insertions, 0 deletions
diff --git a/include/error_handler.h b/include/error_handler.h new file mode 100644 index 0000000..a731d28 --- /dev/null +++ b/include/error_handler.h @@ -0,0 +1,34 @@ +#ifndef SPM_ERROR_HANDLER_H +#define SPM_ERROR_HANDLER_H + +#define _SPM_ERR_BASE 0x8000 // SPM errors begin at 32768 +#define _SPM_ERR_MASK 0x7FFF // Support up to 32768 error strings (zero index) +#define _SPM_ERR(X) _SPM_ERR_BASE + X // Create an error code +#define SPM_ERR_CONFIRM(X) (X >= 0x8000) // Is X a SPM error code? (no=0, yes=!0) +#define SPM_ERR_INDEX(X) (_SPM_ERR_MASK & X) // get index of error string + +#define SPM_ERR_SUCCESS _SPM_ERR(0) // no error +#define SPM_ERR_ROOT_NO_RECORD _SPM_ERR(1) // "root" has no root record +#define SPM_ERR_ROOT_UNSAFE _SPM_ERR(2) // "root" at root, "/" +#define SPM_ERR_PKG_NOT_FOUND _SPM_ERR(3) // package not found +#define SPM_ERR_PKG_INVALID _SPM_ERR(4) // invalid package (wrong structure, missing data, etc) +#define SPM_ERR_PKG_CHECKSUM _SPM_ERR(5) // bad checksum +#define SPM_ERR_PKG_FETCH _SPM_ERR(6) // failed to download package + +extern int spmerrno; + +static const char *SPM_ERR_STRING[] = { + "Success", + "No root record", + "Dangerous root path", + "Package not found", + "Invalid package", + "Bad package checksum", + "Failed to fetch package", + NULL, +}; + +char *spm_strerror(int code); +void spm_perror(const char *msg); + +#endif //SPM_ERROR_HANDLER_H diff --git a/include/spm.h b/include/spm.h index 5931a94..b96554a 100644 --- a/include/spm.h +++ b/include/spm.h @@ -28,6 +28,7 @@ #endif #include "compat.h" +#include "error_handler.h" #include "package.h" #include "str.h" #include "strlist.h" diff --git a/lib/error_handler.c b/lib/error_handler.c new file mode 100644 index 0000000..baf56b4 --- /dev/null +++ b/lib/error_handler.c @@ -0,0 +1,27 @@ +#include "spm.h" + +int spmerrno = 0; +static char spmerrbuf[255]; + +/** + * + * @param code + * @return + */ +char *spm_strerror(int code) { + char *buf = spmerrbuf; + int is_spm_error = SPM_ERR_CONFIRM(code); + + memset(buf, '\0', sizeof(spmerrbuf)); + if (is_spm_error == 0) { + strcpy(buf, strerror(code)); + } else { + strcpy(buf, SPM_ERR_STRING[SPM_ERR_INDEX(code)]); + } + return buf; +} + +void spm_perror(const char *msg) { + fprintf(stderr, "%s: %s\n", msg ? msg : "", spm_strerror(spmerrno)); +} + diff --git a/tests/test_error_handler_spm_strerror.c b/tests/test_error_handler_spm_strerror.c new file mode 100644 index 0000000..f373a59 --- /dev/null +++ b/tests/test_error_handler_spm_strerror.c @@ -0,0 +1,27 @@ +#include "spm.h" +#include "framework.h" + +const char *testFmt = "translated error code '%d': returned '%s', expected '%s'\n"; +struct TestCase testCase[] = { + {.caseValue.signed_integer = 0, .truthValue.sptr = "Success", .arg[0].signed_integer = 0}, + {.caseValue.signed_integer = SPM_ERR_ROOT_NO_RECORD, .truthValue.sptr = "No root record", .arg[0].signed_integer = 0}, + {.caseValue.signed_integer = SPM_ERR_ROOT_UNSAFE, .truthValue.sptr = "Dangerous root path", .arg[0].signed_integer = 0}, + {.caseValue.signed_integer = ENOENT, .truthValue.sptr = "No such file or directory", .arg[0].signed_integer = ENOENT}, + {.caseValue.signed_integer = EPIPE, .truthValue.sptr = "Broken pipe", .arg[0].signed_integer = EPIPE}, + {.caseValue.signed_integer = -1, .truthValue.sptr = "Unknown error -1", .arg[0].signed_integer = 0}, +}; +size_t numCases = sizeof(testCase) / sizeof(struct TestCase); + +int main(int argc, char *argv[]) { + for (size_t i = 0; i < numCases; i++) { + // Mock global errno value to the value stored in the test case + errno = testCase[i].arg[0].signed_integer; + + // Get SPM error (or system error) + char *estr = spm_strerror(testCase[i].caseValue.signed_integer); + + // Assert error string matches error produced + myassert(strcmp(estr, testCase[i].truthValue.sptr) == 0, testFmt, testCase[i].caseValue.signed_integer, estr, testCase[i].truthValue.sptr); + } + return 0; +}
\ No newline at end of file |