From 5ec2a80866136ee80f2a93e54ee2c33815e358b2 Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Wed, 28 Dec 2016 17:18:24 +1000 Subject: [PATCH] * error return codes * add a lot of #define's * add imdb_error() for converting error code to detailed description --- src/database.c | 41 +++++++++++++++++++++++++++++------------ src/database.h | 26 ++++++++++++++++---------- tests/database.c | 2 +- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/database.c b/src/database.c index 81812c7..c366d32 100644 --- a/src/database.c +++ b/src/database.c @@ -24,7 +24,7 @@ bytes = pread((db)->fd, (buf), (len), (off)); \ if (errno) { \ strncpy((db)->error, strerror(errno), sizeof(db->error)); \ - return -1; \ + return IMDB_ERR_SYSTEM; \ } #define DB_WRITE(db, buf, len, off) \ @@ -32,7 +32,7 @@ bytes = pwrite((db)->fd, (buf), (len), (off)); \ if (errno) { \ strncpy((db)->error, strerror(errno), sizeof(db->error)); \ - return -1; \ + return IMDB_ERR_SYSTEM; \ } const char *imdb_hdr_fmt = "IMDB v%02u, CAPS: %s;"; @@ -74,31 +74,31 @@ imdb_open(const char *path, int mode, int *error) { assert(error != NULL); if (stat(path, &st) < 0) { - *error = -1; + *error = IMDB_ERR_SYSTEM; return NULL; } if ((fd = open(path, (mode & IMDB_FLAG_WRITE) ? O_RDWR : O_RDONLY)) < 0) { - *error = -1; + *error = IMDB_ERR_SYSTEM; return NULL; } errno = 0; bytes = pread(fd, buf, IMDB_REC_LEN, 0); if (bytes < IMDB_REC_LEN) { - *error = errno ? -1 : -3; /* empty file, damaged database or IO error */ + *error = errno ? IMDB_ERR_SYSTEM : IMDB_ERR_CORRUPTDB; return NULL; } p = buf + 0; if (memcmp("IMDB", p, 4) != 0) { - *error = -3; /* Not a database file */ + *error = IMDB_ERR_CORRUPTDB; return NULL; } p = buf + 6; if (atoi(p) != IMDB_VERSION) { - *error = -4; /* Database version mismatch */ + *error = IMDB_ERR_WRONGVERS; return NULL; } @@ -114,7 +114,7 @@ imdb_open(const char *path, int mode, int *error) { /* all seems to be ok */ if ((db = calloc(1, sizeof(imdb_db_t))) == NULL) { - *error = -2; /* out of memory */ + *error = IMDB_ERR_OOM; return NULL; } @@ -146,6 +146,22 @@ imdb_close(imdb_db_t *db) close(db->fd); } +const char * +imdb_error(int error) { + if (error == IMDB_SUCCESS) { + return "success"; + } else if (error == IMDB_ERR_SYSTEM) { + return strerror(errno); + } else if (error == IMDB_ERR_OOM) { + return "can't allocate memory"; + } else if (error == IMDB_ERR_CORRUPTDB) { + return "database corrupted"; + } else if (error == IMDB_ERR_WRONGVERS) { + return "database version differs from library version"; + } + return "unknown error"; +} + int imdb_read_rec(imdb_db_t *db, imdb_rec_t *rec) { ssize_t bytes = 0; @@ -157,7 +173,7 @@ int imdb_read_rec(imdb_db_t *db, imdb_rec_t *rec) DB_READ(db, rec->data, IMDB_REC_LEN, rec->num * IMDB_REC_LEN); if (bytes != IMDB_REC_LEN) - return -1; + return errno ? IMDB_ERR_SYSTEM : 0; if (rec->data[0] != 0xFF) return 0; @@ -176,7 +192,7 @@ int imdb_write_rec(imdb_db_t *db, imdb_rec_t *rec) DB_WRITE(db, rec->data, IMDB_REC_LEN, rec->num * IMDB_REC_LEN); if (bytes != IMDB_REC_LEN) - return -1; + return IMDB_ERR_SYSTEM; return 1; } @@ -235,6 +251,7 @@ imdb_search(imdb_db_t * const db, unsigned char *p = NULL; float ratio_s = 0.0; /* source */ float ratio_t = 0.0; /* tested */ + int ret = 0; assert(db != NULL); assert(sample != NULL); @@ -248,9 +265,9 @@ imdb_search(imdb_db_t * const db, blk.start = 1; blk.records = blk_size; - if (imdb_read_rec(db, sample) < 1) { + if ((ret = imdb_read_rec(db, sample)) < 1) { strncpy(db->error, "Can't read source sample", sizeof(db->error)); - return -1; + return ret; } if (search->limit == 0) diff --git a/src/database.h b/src/database.h index 739bb9a..2257b75 100644 --- a/src/database.h +++ b/src/database.h @@ -13,6 +13,13 @@ #define IMDB_CAP_RATIO 1 << (8 + 2) /* 3 used, 5 reserved */ +#define IMDB_SUCCESS 0 +/* database errors */ +#define IMDB_ERR_SYSTEM -1 /* see errno for details */ +#define IMDB_ERR_OOM -2 /* can't allocate memory */ +#define IMDB_ERR_CORRUPTDB -3 /* empty or currupted database */ +#define IMDB_ERR_WRONGVERS -4 /* database version mismatch */ + typedef struct { int fd; int flags; @@ -92,8 +99,7 @@ typedef struct { } imdb_match_t; /** - * @return 1 on success, 0 if record not used - * and -1 if record number not exists, + * @returns 1 on success, 0 if record missing and <0 on error */ int imdb_read_rec (imdb_db_t *db, imdb_rec_t *rec); int imdb_write_rec(imdb_db_t *db, imdb_rec_t *rec); @@ -116,10 +122,7 @@ bool imdb_create(const char *path); * @param mode Database open modes. See IMDB_FLAG_* defines above * @param error Pointer to error code storage * @returns Pointer to database handle on success, NULL on error - * -1 -- system error, see @a errno for details - * -2 -- malloc() failed - * -3 -- damaged database - * -4 -- database version mismatch + * @note use @a imdb_error() to get error description */ imdb_db_t * imdb_open(const char *path, int mode, int *error); @@ -129,14 +132,17 @@ imdb_db_t * imdb_open(const char *path, int mode, int *error); */ void imdb_close(imdb_db_t *db); +/** + * @brief Get error desctiption by error code + * @param error Error code, see IMDB_ERR_* defines above + */ +const char * imdb_error(int code); + float ratio_from_rec_data(unsigned char * const data); /** - @returns: - -1 on error - 0 if nothing found - >0 if found some matches + @returns: >0 if found some matches, 0 if nothing found, <0 on error */ int imdb_search(imdb_db_t * const db, diff --git a/tests/database.c b/tests/database.c index a2efafd..b980a67 100644 --- a/tests/database.c +++ b/tests/database.c @@ -24,7 +24,7 @@ int main() rec[0].num = 1; err = imdb_read_rec(db, rec); - assert(err < 0); /* no such record */ + assert(err == 0); /* no such record */ memset(rec[0].data, 0xAA, IMDB_REC_LEN); memset(rec[0].data, 0xFF, 1); /* record is used */