2 * 2ooM: The Master of Orion II Reverse Engineering Project
3 * Utilities for out-of-band error propagation.
4 * Copyright (C) 2010 Nick Bowler
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 #define _(s) dgettext(PACKAGE, s)
31 #if !defined(LBX_ERROR_LIMIT)
32 # define LBX_ERROR_LIMIT 256
35 static unsigned error_base, error_tip;
36 static int error_ring[LBX_ERROR_LIMIT];
38 static const char **user_errors;
39 static unsigned user_error_count;
40 static unsigned user_error_max = 2;
42 int lbx_error_new(const char *str)
44 assert(user_error_count <= user_error_max);
45 if (!user_errors || user_error_count == user_error_max) {
46 size_t size = sizeof *user_errors * user_error_max * 2;
49 new = realloc(user_errors, size);
56 user_errors[user_error_count] = str;
57 return LBX_EUBASE + user_error_count++;
60 int lbx_error_raise(int code)
62 if (code == LBX_EOK) {
64 } else if (code >= LBX_EMAX && code < LBX_EUBASE
65 || code >= LBX_EUBASE + user_error_count) {
66 fprintf(stderr, "%s: invalid error code %d\n", __func__, code);
70 error_ring[error_tip++] = code;
71 error_tip %= LBX_ERROR_LIMIT;
73 if (error_tip == error_base) {
74 error_base = (error_base + 1) % LBX_ERROR_LIMIT;
81 static void getmsg(int error, const char **msg)
84 *msg = strerror(-error);
93 *msg = _("Bad magic number");
96 *msg = _("Invalid file format");
99 *msg = _("Specified item does not exist");
102 *msg = _("Memory allocation failed");
105 *msg = _("Unexpected end of file");
108 *msg = user_errors[error - LBX_EUBASE];
112 int lbx_error_peek(const char **msg)
114 int error = error_tip == error_base ? LBX_EOK : error_ring[error_base];
116 assert(error < LBX_EMAX || error >= LBX_EUBASE);
117 assert(error < LBX_EUBASE + user_error_count);
125 int lbx_error_get(const char **msg)
127 int error = lbx_error_peek(msg);
129 if (error != LBX_EOK)
130 error_base = (error_base + 1) % LBX_ERROR_LIMIT;