commit 7f076e8069ca1b09cc099f67ba6671f9248c6071 Author: Lassi Kortela Date: Sun May 12 00:02:51 2024 +0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0250c46 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +codesets.chibi.c +*.so +*.dylib +*.o* diff --git a/build-chibi.sh b/build-chibi.sh new file mode 100755 index 0000000..47b328f --- /dev/null +++ b/build-chibi.sh @@ -0,0 +1,15 @@ +#!/bin/sh +set -eu +cd "$(dirname "$0")" +echo "Entering directory '$PWD'" +chibi=$(pkg-config --cflags --libs chibi-scheme) +soext=.so +case $(uname) in +Darwin) + soext=.dylib + ;; +esac +set -x +chibi-ffi codesets.chibi.stub +cc -std=c99 -Wall -Wextra -Wno-unused-parameter \ + $chibi -fPIC -shared -o codesets.chibi$soext codesets.chibi.c glue.c diff --git a/build-gambit.sh b/build-gambit.sh new file mode 100755 index 0000000..7122010 --- /dev/null +++ b/build-gambit.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -eu +cd "$(dirname "$0")" +echo "Entering directory '$PWD'" +set -x +gsc-script -cc-options glue.c codesets.sld diff --git a/codesets.chibi.stub b/codesets.chibi.stub new file mode 100644 index 0000000..b510a27 --- /dev/null +++ b/codesets.chibi.stub @@ -0,0 +1,13 @@ +(c-declare "#include \"glue.h\"") + +(define-c (const string) (%codeset-list "codeset_list") + ()) + +(define-c (const string) (%codeset-numbers "codeset_numbers") + ((const string))) + +(define-c (const string) (%codeset-symbols "codeset_symbols") + ((const string))) + +(define-c (const string) (%codeset-messages "codeset_messages") + ((const string))) diff --git a/codesets.gambit.scm b/codesets.gambit.scm new file mode 100644 index 0000000..e1af66f --- /dev/null +++ b/codesets.gambit.scm @@ -0,0 +1,13 @@ +(c-declare "#include \"glue.h\"") + +(define %codeset-list + (c-lambda () nonnull-char-string "codeset_list")) + +(define %codeset-numbers + (c-lambda (nonnull-char-string) nonnull-char-string "codeset_numbers")) + +(define %codeset-symbols + (c-lambda (nonnull-char-string) nonnull-char-string "codeset_symbols")) + +(define %codeset-messages + (c-lambda (nonnull-char-string) nonnull-char-string "codeset_messages")) diff --git a/codesets.sld b/codesets.sld new file mode 100644 index 0000000..547368c --- /dev/null +++ b/codesets.sld @@ -0,0 +1,34 @@ +(define-library (codesets) + (export codeset-alist) + (cond-expand + (chibi + (import (scheme base)) + (include-shared "codesets.chibi")) + (gambit + (import (gambit)) + (include "codesets.gambit.scm"))) + (begin + + (define (split string) + (let loop ((list '()) (a 0) (b 0)) + (cond ((= a (string-length string)) + (reverse list)) + ((char=? #\newline (string-ref string b)) + (loop (cons (string-copy string a b) list) + (+ b 1) + (+ b 1))) + (else + (loop list a (+ b 1)))))) + + (define (grovel-codeset codeset) + (define (append-map f a b c) (apply append (map f a b c))) + (cons (string->symbol codeset) + (list->vector + (append-map + list + (map string->number (split (%codeset-numbers codeset))) + (map string->symbol (split (%codeset-symbols codeset))) + (split (%codeset-messages codeset)))))) + + (define codeset-alist + (map grovel-codeset (split (%codeset-list)))))) diff --git a/errnolist.h b/errnolist.h new file mode 100644 index 0000000..c396f51 --- /dev/null +++ b/errnolist.h @@ -0,0 +1,453 @@ +#ifdef E2BIG + XX(E2BIG) +#endif +#ifdef EACCES + XX(EACCES) +#endif +#ifdef EADDRINUSE + XX(EADDRINUSE) +#endif +#ifdef EADDRNOTAVAIL + XX(EADDRNOTAVAIL) +#endif +#ifdef EADV + XX(EADV) +#endif +#ifdef EAFNOSUPPORT + XX(EAFNOSUPPORT) +#endif +#ifdef EAGAIN + XX(EAGAIN) +#endif +#ifdef EALREADY + XX(EALREADY) +#endif +#ifdef EAUTH + XX(EAUTH) +#endif +#ifdef EBADE + XX(EBADE) +#endif +#ifdef EBADF + XX(EBADF) +#endif +#ifdef EBADFD + XX(EBADFD) +#endif +#ifdef EBADMSG + XX(EBADMSG) +#endif +#ifdef EBADR + XX(EBADR) +#endif +#ifdef EBADRPC + XX(EBADRPC) +#endif +#ifdef EBADRQC + XX(EBADRQC) +#endif +#ifdef EBADSLT + XX(EBADSLT) +#endif +#ifdef EBFONT + XX(EBFONT) +#endif +#ifdef EBUSY + XX(EBUSY) +#endif +#ifdef ECANCELED + XX(ECANCELED) +#endif +#ifdef ECAPMODE + XX(ECAPMODE) +#endif +#ifdef ECHILD + XX(ECHILD) +#endif +#ifdef ECHRNG + XX(ECHRNG) +#endif +#ifdef ECOMM + XX(ECOMM) +#endif +#ifdef ECONNABORTED + XX(ECONNABORTED) +#endif +#ifdef ECONNREFUSED + XX(ECONNREFUSED) +#endif +#ifdef ECONNRESET + XX(ECONNRESET) +#endif +#ifdef EDEADLK + XX(EDEADLK) +#endif +#ifdef EDEADLOCK + XX(EDEADLOCK) +#endif +#ifdef EDESTADDRREQ + XX(EDESTADDRREQ) +#endif +#ifdef EDOM + XX(EDOM) +#endif +#ifdef EDOOFUS + XX(EDOOFUS) +#endif +#ifdef EDOTDOT + XX(EDOTDOT) +#endif +#ifdef EDQUOT + XX(EDQUOT) +#endif +#ifdef EEXIST + XX(EEXIST) +#endif +#ifdef EFAULT + XX(EFAULT) +#endif +#ifdef EFBIG + XX(EFBIG) +#endif +#ifdef EFTYPE + XX(EFTYPE) +#endif +#ifdef EHOSTDOWN + XX(EHOSTDOWN) +#endif +#ifdef EHOSTUNREACH + XX(EHOSTUNREACH) +#endif +#ifdef EHWPOISON + XX(EHWPOISON) +#endif +#ifdef EIDRM + XX(EIDRM) +#endif +#ifdef EILSEQ + XX(EILSEQ) +#endif +#ifdef EINPROGRESS + XX(EINPROGRESS) +#endif +#ifdef EINTR + XX(EINTR) +#endif +#ifdef EINVAL + XX(EINVAL) +#endif +#ifdef EIO + XX(EIO) +#endif +#ifdef EIPSEC + XX(EIPSEC) +#endif +#ifdef EISCONN + XX(EISCONN) +#endif +#ifdef EISDIR + XX(EISDIR) +#endif +#ifdef EISNAM + XX(EISNAM) +#endif +#ifdef EKEYEXPIRED + XX(EKEYEXPIRED) +#endif +#ifdef EKEYREJECTED + XX(EKEYREJECTED) +#endif +#ifdef EKEYREVOKED + XX(EKEYREVOKED) +#endif +#ifdef EL2HLT + XX(EL2HLT) +#endif +#ifdef EL2NSYNC + XX(EL2NSYNC) +#endif +#ifdef EL3HLT + XX(EL3HLT) +#endif +#ifdef EL3RST + XX(EL3RST) +#endif +#ifdef ELAST + XX(ELAST) +#endif +#ifdef ELIBACC + XX(ELIBACC) +#endif +#ifdef ELIBBAD + XX(ELIBBAD) +#endif +#ifdef ELIBEXEC + XX(ELIBEXEC) +#endif +#ifdef ELIBMAX + XX(ELIBMAX) +#endif +#ifdef ELIBSCN + XX(ELIBSCN) +#endif +#ifdef ELNRNG + XX(ELNRNG) +#endif +#ifdef ELOCKUNMAPPED + XX(ELOCKUNMAPPED) +#endif +#ifdef ELOOP + XX(ELOOP) +#endif +#ifdef EMEDIUMTYPE + XX(EMEDIUMTYPE) +#endif +#ifdef EMFILE + XX(EMFILE) +#endif +#ifdef EMLINK + XX(EMLINK) +#endif +#ifdef EMSGSIZE + XX(EMSGSIZE) +#endif +#ifdef EMULTIHOP + XX(EMULTIHOP) +#endif +#ifdef ENAMETOOLONG + XX(ENAMETOOLONG) +#endif +#ifdef ENAVAIL + XX(ENAVAIL) +#endif +#ifdef ENEEDAUTH + XX(ENEEDAUTH) +#endif +#ifdef ENETDOWN + XX(ENETDOWN) +#endif +#ifdef ENETRESET + XX(ENETRESET) +#endif +#ifdef ENETUNREACH + XX(ENETUNREACH) +#endif +#ifdef ENFILE + XX(ENFILE) +#endif +#ifdef ENOANO + XX(ENOANO) +#endif +#ifdef ENOATTR + XX(ENOATTR) +#endif +#ifdef ENOBUFS + XX(ENOBUFS) +#endif +#ifdef ENOCSI + XX(ENOCSI) +#endif +#ifdef ENODATA + XX(ENODATA) +#endif +#ifdef ENODEV + XX(ENODEV) +#endif +#ifdef ENOENT + XX(ENOENT) +#endif +#ifdef ENOEXEC + XX(ENOEXEC) +#endif +#ifdef ENOKEY + XX(ENOKEY) +#endif +#ifdef ENOLCK + XX(ENOLCK) +#endif +#ifdef ENOLINK + XX(ENOLINK) +#endif +#ifdef ENOMEDIUM + XX(ENOMEDIUM) +#endif +#ifdef ENOMEM + XX(ENOMEM) +#endif +#ifdef ENOMSG + XX(ENOMSG) +#endif +#ifdef ENONET + XX(ENONET) +#endif +#ifdef ENOPKG + XX(ENOPKG) +#endif +#ifdef ENOPROTOOPT + XX(ENOPROTOOPT) +#endif +#ifdef ENOSPC + XX(ENOSPC) +#endif +#ifdef ENOSR + XX(ENOSR) +#endif +#ifdef ENOSTR + XX(ENOSTR) +#endif +#ifdef ENOSYS + XX(ENOSYS) +#endif +#ifdef ENOTACTIVE + XX(ENOTACTIVE) +#endif +#ifdef ENOTBLK + XX(ENOTBLK) +#endif +#ifdef ENOTCAPABLE + XX(ENOTCAPABLE) +#endif +#ifdef ENOTCONN + XX(ENOTCONN) +#endif +#ifdef ENOTDIR + XX(ENOTDIR) +#endif +#ifdef ENOTEMPTY + XX(ENOTEMPTY) +#endif +#ifdef ENOTNAM + XX(ENOTNAM) +#endif +#ifdef ENOTRECOVERABLE + XX(ENOTRECOVERABLE) +#endif +#ifdef ENOTSOCK + XX(ENOTSOCK) +#endif +#ifdef ENOTSUP + XX(ENOTSUP) +#endif +#ifdef ENOTTY + XX(ENOTTY) +#endif +#ifdef ENOTUNIQ + XX(ENOTUNIQ) +#endif +#ifdef ENXIO + XX(ENXIO) +#endif +#ifdef EOPNOTSUPP + XX(EOPNOTSUPP) +#endif +#ifdef EOVERFLOW + XX(EOVERFLOW) +#endif +#ifdef EOWNERDEAD + XX(EOWNERDEAD) +#endif +#ifdef EPERM + XX(EPERM) +#endif +#ifdef EPFNOSUPPORT + XX(EPFNOSUPPORT) +#endif +#ifdef EPIPE + XX(EPIPE) +#endif +#ifdef EPROCLIM + XX(EPROCLIM) +#endif +#ifdef EPROCUNAVAIL + XX(EPROCUNAVAIL) +#endif +#ifdef EPROGMISMATCH + XX(EPROGMISMATCH) +#endif +#ifdef EPROGUNAVAIL + XX(EPROGUNAVAIL) +#endif +#ifdef EPROTO + XX(EPROTO) +#endif +#ifdef EPROTONOSUPPORT + XX(EPROTONOSUPPORT) +#endif +#ifdef EPROTOTYPE + XX(EPROTOTYPE) +#endif +#ifdef ERANGE + XX(ERANGE) +#endif +#ifdef EREMCHG + XX(EREMCHG) +#endif +#ifdef EREMOTE + XX(EREMOTE) +#endif +#ifdef EREMOTEIO + XX(EREMOTEIO) +#endif +#ifdef ERESTART + XX(ERESTART) +#endif +#ifdef ERFKILL + XX(ERFKILL) +#endif +#ifdef EROFS + XX(EROFS) +#endif +#ifdef ERPCMISMATCH + XX(ERPCMISMATCH) +#endif +#ifdef ESHUTDOWN + XX(ESHUTDOWN) +#endif +#ifdef ESOCKTNOSUPPORT + XX(ESOCKTNOSUPPORT) +#endif +#ifdef ESPIPE + XX(ESPIPE) +#endif +#ifdef ESRCH + XX(ESRCH) +#endif +#ifdef ESRMNT + XX(ESRMNT) +#endif +#ifdef ESTALE + XX(ESTALE) +#endif +#ifdef ESTRPIPE + XX(ESTRPIPE) +#endif +#ifdef ETIME + XX(ETIME) +#endif +#ifdef ETIMEDOUT + XX(ETIMEDOUT) +#endif +#ifdef ETOOMANYREFS + XX(ETOOMANYREFS) +#endif +#ifdef ETXTBSY + XX(ETXTBSY) +#endif +#ifdef EUCLEAN + XX(EUCLEAN) +#endif +#ifdef EUNATCH + XX(EUNATCH) +#endif +#ifdef EUSERS + XX(EUSERS) +#endif +#ifdef EWOULDBLOCK + XX(EWOULDBLOCK) +#endif +#ifdef EXDEV + XX(EXDEV) +#endif +#ifdef EXFULL + XX(EXFULL) +#endif diff --git a/errnolist.txt b/errnolist.txt new file mode 100644 index 0000000..a9d2573 --- /dev/null +++ b/errnolist.txt @@ -0,0 +1,151 @@ +E2BIG +EACCES +EADDRINUSE +EADDRNOTAVAIL +EADV +EAFNOSUPPORT +EAGAIN +EALREADY +EAUTH +EBADE +EBADF +EBADFD +EBADMSG +EBADR +EBADRPC +EBADRQC +EBADSLT +EBFONT +EBUSY +ECANCELED +ECAPMODE +ECHILD +ECHRNG +ECOMM +ECONNABORTED +ECONNREFUSED +ECONNRESET +EDEADLK +EDEADLOCK +EDESTADDRREQ +EDOM +EDOOFUS +EDOTDOT +EDQUOT +EEXIST +EFAULT +EFBIG +EFTYPE +EHOSTDOWN +EHOSTUNREACH +EHWPOISON +EIDRM +EILSEQ +EINPROGRESS +EINTR +EINVAL +EIO +EIPSEC +EISCONN +EISDIR +EISNAM +EKEYEXPIRED +EKEYREJECTED +EKEYREVOKED +EL2HLT +EL2NSYNC +EL3HLT +EL3RST +ELAST +ELIBACC +ELIBBAD +ELIBEXEC +ELIBMAX +ELIBSCN +ELNRNG +ELOCKUNMAPPED +ELOOP +EMEDIUMTYPE +EMFILE +EMLINK +EMSGSIZE +EMULTIHOP +ENAMETOOLONG +ENAVAIL +ENEEDAUTH +ENETDOWN +ENETRESET +ENETUNREACH +ENFILE +ENOANO +ENOATTR +ENOBUFS +ENOCSI +ENODATA +ENODEV +ENOENT +ENOEXEC +ENOKEY +ENOLCK +ENOLINK +ENOMEDIUM +ENOMEM +ENOMSG +ENONET +ENOPKG +ENOPROTOOPT +ENOSPC +ENOSR +ENOSTR +ENOSYS +ENOTACTIVE +ENOTBLK +ENOTCAPABLE +ENOTCONN +ENOTDIR +ENOTEMPTY +ENOTNAM +ENOTRECOVERABLE +ENOTSOCK +ENOTSUP +ENOTTY +ENOTUNIQ +ENXIO +EOPNOTSUPP +EOVERFLOW +EOWNERDEAD +EPERM +EPFNOSUPPORT +EPIPE +EPROCLIM +EPROCUNAVAIL +EPROGMISMATCH +EPROGUNAVAIL +EPROTO +EPROTONOSUPPORT +EPROTOTYPE +ERANGE +EREMCHG +EREMOTE +EREMOTEIO +ERESTART +ERFKILL +EROFS +ERPCMISMATCH +ESHUTDOWN +ESOCKTNOSUPPORT +ESPIPE +ESRCH +ESRMNT +ESTALE +ESTRPIPE +ETIME +ETIMEDOUT +ETOOMANYREFS +ETXTBSY +EUCLEAN +EUNATCH +EUSERS +EWOULDBLOCK +EXDEV +EXFULL diff --git a/generate.scm b/generate.scm new file mode 100644 index 0000000..745c9b6 --- /dev/null +++ b/generate.scm @@ -0,0 +1,35 @@ +(import (scheme base) + (scheme file) + (scheme read) + (scheme write)) + +(define disp + (lambda args + (for-each display args) + (newline))) + +(define (read-all) + (let loop ((xs '())) + (let ((x (read))) + (if (eof-object? x) + (reverse xs) + (loop (cons x xs)))))) + +(define (gen out in) + (let ((symbols (with-input-from-file in read-all))) + (with-output-to-file out + (lambda () + (for-each (lambda (symbol) + (disp "#ifdef " symbol) + (disp " XX(" symbol ")") + (disp "#endif")) + symbols))))) + +(define main + (lambda ignored + (gen "errnolist.h" + "errnolist.txt") + (gen "signallist.h" + "signallist.txt"))) + +(main) diff --git a/glue.c b/glue.c new file mode 100644 index 0000000..397d00a --- /dev/null +++ b/glue.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include + +#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"; +} diff --git a/glue.h b/glue.h new file mode 100644 index 0000000..f83d0ed --- /dev/null +++ b/glue.h @@ -0,0 +1,4 @@ +char *codeset_list(void); +char *codeset_numbers(const char *codeset); +char *codeset_symbols(const char *codeset); +char *codeset_messages(const char *codeset); diff --git a/signallist.h b/signallist.h new file mode 100644 index 0000000..0e3011b --- /dev/null +++ b/signallist.h @@ -0,0 +1,93 @@ +#ifdef SIGABRT + XX(SIGABRT) +#endif +#ifdef SIGALRM + XX(SIGALRM) +#endif +#ifdef SIGBUS + XX(SIGBUS) +#endif +#ifdef SIGCHLD + XX(SIGCHLD) +#endif +#ifdef SIGCONT + XX(SIGCONT) +#endif +#ifdef SIGEMT + XX(SIGEMT) +#endif +#ifdef SIGFPE + XX(SIGFPE) +#endif +#ifdef SIGHUP + XX(SIGHUP) +#endif +#ifdef SIGILL + XX(SIGILL) +#endif +#ifdef SIGINFO + XX(SIGINFO) +#endif +#ifdef SIGINT + XX(SIGINT) +#endif +#ifdef SIGIO + XX(SIGIO) +#endif +#ifdef SIGKILL + XX(SIGKILL) +#endif +#ifdef SIGPIPE + XX(SIGPIPE) +#endif +#ifdef SIGPROF + XX(SIGPROF) +#endif +#ifdef SIGQUIT + XX(SIGQUIT) +#endif +#ifdef SIGSEGV + XX(SIGSEGV) +#endif +#ifdef SIGSTOP + XX(SIGSTOP) +#endif +#ifdef SIGSYS + XX(SIGSYS) +#endif +#ifdef SIGTERM + XX(SIGTERM) +#endif +#ifdef SIGTRAP + XX(SIGTRAP) +#endif +#ifdef SIGTSTP + XX(SIGTSTP) +#endif +#ifdef SIGTTIN + XX(SIGTTIN) +#endif +#ifdef SIGTTOU + XX(SIGTTOU) +#endif +#ifdef SIGURG + XX(SIGURG) +#endif +#ifdef SIGUSR1 + XX(SIGUSR1) +#endif +#ifdef SIGUSR2 + XX(SIGUSR2) +#endif +#ifdef SIGVTALRM + XX(SIGVTALRM) +#endif +#ifdef SIGWINCH + XX(SIGWINCH) +#endif +#ifdef SIGXCPU + XX(SIGXCPU) +#endif +#ifdef SIGXFSZ + XX(SIGXFSZ) +#endif diff --git a/signallist.txt b/signallist.txt new file mode 100644 index 0000000..ea8bbc5 --- /dev/null +++ b/signallist.txt @@ -0,0 +1,31 @@ +SIGABRT +SIGALRM +SIGBUS +SIGCHLD +SIGCONT +SIGEMT +SIGFPE +SIGHUP +SIGILL +SIGINFO +SIGINT +SIGIO +SIGKILL +SIGPIPE +SIGPROF +SIGQUIT +SIGSEGV +SIGSTOP +SIGSYS +SIGTERM +SIGTRAP +SIGTSTP +SIGTTIN +SIGTTOU +SIGURG +SIGUSR1 +SIGUSR2 +SIGVTALRM +SIGWINCH +SIGXCPU +SIGXFSZ