2 * 2ooM: The Master of Orion II Reverse Engineering Project
3 * Utilities for out-of-band error propagation.
4 * Copyright © 2010, 2013-2014 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/>.
31 // #define _(s) dgettext(PACKAGE, s)
34 #if !defined(LBX_ERROR_LIMIT)
35 # define LBX_ERROR_LIMIT 256
38 static unsigned error_base, error_tip;
39 static int error_ring[LBX_ERROR_LIMIT];
41 static const char **user_errors;
42 static int user_error_count, user_error_max = 2;
44 int lbx_error_new(const char *str)
46 assert(user_error_count >= 0 && user_error_count <= user_error_max);
48 if (!user_errors || user_error_count == user_error_max) {
52 if (user_error_max >= MIN((size_t)-1, INT_MAX)/2 - LBX_EUBASE)
54 if (2 * user_error_max >= (size_t)-1 / sizeof *user_errors)
57 size = 2 * user_error_max * sizeof *user_errors;
58 new = realloc(user_errors, size);
65 user_errors[user_error_count] = str;
66 return LBX_EUBASE + user_error_count++;
69 int lbx_error_raise(int code)
71 if (code == LBX_EOK) {
73 } else if (code >= 0 && ((code >= LBX_EMAX && code < LBX_EUBASE)
74 || code >= LBX_EUBASE + user_error_count)) {
75 fprintf(stderr, "%s: invalid error code %d\n", __func__, code);
79 error_ring[error_tip++] = code;
80 error_tip %= LBX_ERROR_LIMIT;
82 if (error_tip == error_base) {
83 error_base = (error_base + 1) % LBX_ERROR_LIMIT;
90 static void getmsg(int error, const char **msg)
93 *msg = strerror(-error);
102 *msg = _("Bad magic number");
105 *msg = _("Invalid file format");
108 *msg = _("Invalid argument");
111 *msg = _("Memory allocation failed");
114 *msg = _("Unexpected end of file");
117 *msg = user_errors[error - LBX_EUBASE];
121 int lbx_error_peek(const char **msg)
123 int error = error_tip == error_base ? LBX_EOK : error_ring[error_base];
125 assert(error < LBX_EMAX || error >= LBX_EUBASE);
126 assert(error < LBX_EUBASE + user_error_count);
134 int lbx_error_get(const char **msg)
136 int error = lbx_error_peek(msg);
138 if (error != LBX_EOK)
139 error_base = (error_base + 1) % LBX_ERROR_LIMIT;