119 lines
2.2 KiB
C
119 lines
2.2 KiB
C
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#undef XX
|
|
#define XX(x) x,
|
|
|
|
static const int errno_numbers[] = {
|
|
#include "errnolist.h"
|
|
0};
|
|
|
|
static const int signal_numbers[] = {
|
|
#include "signallist.h"
|
|
0};
|
|
|
|
#undef XX
|
|
#define XX(x) #x "\n"
|
|
|
|
static const char errno_symbols[] =
|
|
#include "errnolist.h"
|
|
;
|
|
|
|
static const char signal_symbols[] =
|
|
#include "signallist.h"
|
|
;
|
|
|
|
static char buffer[16384];
|
|
|
|
static char *portable_strsignal(int number) {
|
|
char *str;
|
|
char *pos;
|
|
|
|
str = strsignal(number);
|
|
pos = str ? strchr(str, ':') : 0;
|
|
if (pos) {
|
|
*pos = 0;
|
|
}
|
|
return str;
|
|
}
|
|
|
|
static char *format_number(int number) {
|
|
static char numbuf[16];
|
|
|
|
snprintf(numbuf, sizeof(numbuf), "%d", number);
|
|
return numbuf;
|
|
}
|
|
|
|
static void whitespace_cleanup(char *str) {
|
|
char *ptr;
|
|
char *lim;
|
|
|
|
lim = strchr(str, 0);
|
|
while (lim > str) {
|
|
if (!isspace(lim[-1])) {
|
|
break;
|
|
}
|
|
*--lim = 0;
|
|
}
|
|
for (ptr = str; ptr < lim; ptr++) {
|
|
if (isspace(*ptr)) {
|
|
*ptr = ' ';
|
|
}
|
|
}
|
|
}
|
|
|
|
static const char *prepare(const int *numbers, char *(*tostring)(int)) {
|
|
char *str;
|
|
size_t len, i;
|
|
|
|
memset(buffer, 0, sizeof(buffer));
|
|
for (i = 0; numbers[i]; i++) {
|
|
str = tostring(numbers[i]);
|
|
if (!str) {
|
|
str = "";
|
|
}
|
|
whitespace_cleanup(str);
|
|
len = strlen(buffer);
|
|
snprintf(&buffer[len], sizeof(buffer) - len, "%s\n", str);
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
const char *codeset_symbols(const char *codeset) {
|
|
if (!strcmp(codeset, "errno")) {
|
|
return errno_symbols;
|
|
}
|
|
if (!strcmp(codeset, "signal")) {
|
|
return signal_symbols;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
const char *codeset_numbers(const char *codeset) {
|
|
if (!strcmp(codeset, "errno")) {
|
|
return prepare(errno_numbers, format_number);
|
|
}
|
|
if (!strcmp(codeset, "signal")) {
|
|
return prepare(signal_numbers, format_number);
|
|
}
|
|
return "";
|
|
}
|
|
|
|
const char *codeset_messages(const char *codeset) {
|
|
if (!strcmp(codeset, "errno")) {
|
|
return prepare(errno_numbers, strerror);
|
|
}
|
|
if (!strcmp(codeset, "signal")) {
|
|
return prepare(signal_numbers, portable_strsignal);
|
|
}
|
|
return "";
|
|
}
|
|
|
|
const char *codeset_list(void) {
|
|
return "errno\n"
|
|
"signal\n";
|
|
}
|