>From a75ee13583401bbe96235ac3be7f354c2480f9f6 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 12 Sep 2026 23:40:38 -0400 Subject: [PATCH 06/18] switch langinfo and error strings over to new common table lookup use of new locale files is not hooked up yet; the new table lookup is performed for built-in C locale strings, but the old LCTRANS() system is still used for obtaining localized versions. errno numbers can vary by arch (only mips at present), but the keys used in the table need to be arch-agnostic, since locale files may be shared across archs. the common arch/generic numbering is adopted, with a translation table built conditionally for archs that don't match. for now, EDEADLK != L_EDEADLK is used as a proxy condition; it can be expanded or explicitly declared by the arch if needed for future archs. the error string functions all use a two-component path key, even though each file only uses a single value for the first path component. this is to avoid the need to cache a lot of individual table pointers in the in-memory locale representation. the top-level wrapping is largely "hard-coded" while the table level with the actual data is produced with the mdecl.h/mdata.h include machinery. for nl_langinfo, the table actually has multiple subtables, one for each category, requiring a non-trivial top-level table. --- src/errno/__strerror.h | 4 +- src/errno/l_errno.h | 134 +++++++++++++++++++++++++++++++++++++ src/errno/remap_errno.h | 133 ++++++++++++++++++++++++++++++++++++ src/errno/strerror.c | 65 +++++++++++------- src/locale/langinfo.c | 128 ++++++++++++++++++++++------------- src/locale/lc_messages.h | 4 ++ src/locale/lc_monetary.h | 1 + src/locale/lc_numeric.h | 2 + src/locale/lc_time.h | 52 ++++++++++++++ src/network/gai_strerror.c | 42 +++++++----- src/network/gai_strerror.h | 12 ++++ src/network/hstrerror.c | 34 +++++++--- src/network/hstrerror.h | 5 ++ src/regex/regerror.c | 50 +++++++------- src/regex/regerror.h | 15 +++++ 15 files changed, 556 insertions(+), 125 deletions(-) create mode 100644 src/errno/l_errno.h create mode 100644 src/errno/remap_errno.h create mode 100644 src/locale/lc_messages.h create mode 100644 src/locale/lc_monetary.h create mode 100644 src/locale/lc_numeric.h create mode 100644 src/locale/lc_time.h create mode 100644 src/network/gai_strerror.h create mode 100644 src/network/hstrerror.h create mode 100644 src/regex/regerror.h diff --git a/src/errno/__strerror.h b/src/errno/__strerror.h index 0398b5b6..2db8ea22 100644 --- a/src/errno/__strerror.h +++ b/src/errno/__strerror.h @@ -3,7 +3,9 @@ * with these messages, and then to define a lookup table translating * error codes to offsets of corresponding fields in the structure. */ -E(0, "No error information") +E(E_, "Unknown error") + +E(E0, "No error information") E(EILSEQ, "Illegal byte sequence") E(EDOM, "Domain error") diff --git a/src/errno/l_errno.h b/src/errno/l_errno.h new file mode 100644 index 00000000..4a319827 --- /dev/null +++ b/src/errno/l_errno.h @@ -0,0 +1,134 @@ +#define L_EPERM 1 +#define L_ENOENT 2 +#define L_ESRCH 3 +#define L_EINTR 4 +#define L_EIO 5 +#define L_ENXIO 6 +#define L_E2BIG 7 +#define L_ENOEXEC 8 +#define L_EBADF 9 +#define L_ECHILD 10 +#define L_EAGAIN 11 +#define L_ENOMEM 12 +#define L_EACCES 13 +#define L_EFAULT 14 +#define L_ENOTBLK 15 +#define L_EBUSY 16 +#define L_EEXIST 17 +#define L_EXDEV 18 +#define L_ENODEV 19 +#define L_ENOTDIR 20 +#define L_EISDIR 21 +#define L_EINVAL 22 +#define L_ENFILE 23 +#define L_EMFILE 24 +#define L_ENOTTY 25 +#define L_ETXTBSY 26 +#define L_EFBIG 27 +#define L_ENOSPC 28 +#define L_ESPIPE 29 +#define L_EROFS 30 +#define L_EMLINK 31 +#define L_EPIPE 32 +#define L_EDOM 33 +#define L_ERANGE 34 +#define L_EDEADLK 35 +#define L_ENAMETOOLONG 36 +#define L_ENOLCK 37 +#define L_ENOSYS 38 +#define L_ENOTEMPTY 39 +#define L_ELOOP 40 +#define L_EWOULDBLOCK 41 +#define L_ENOMSG 42 +#define L_EIDRM 43 +#define L_ECHRNG 44 +#define L_EL2NSYNC 45 +#define L_EL3HLT 46 +#define L_EL3RST 47 +#define L_ELNRNG 48 +#define L_EUNATCH 49 +#define L_ENOCSI 50 +#define L_EL2HLT 51 +#define L_EBADE 52 +#define L_EBADR 53 +#define L_EXFULL 54 +#define L_ENOANO 55 +#define L_EBADRQC 56 +#define L_EBADSLT 57 +#define L_EDEADLOCK 58 +#define L_EBFONT 59 +#define L_ENOSTR 60 +#define L_ENODATA 61 +#define L_ETIME 62 +#define L_ENOSR 63 +#define L_ENONET 64 +#define L_ENOPKG 65 +#define L_EREMOTE 66 +#define L_ENOLINK 67 +#define L_EADV 68 +#define L_ESRMNT 69 +#define L_ECOMM 70 +#define L_EPROTO 71 +#define L_EMULTIHOP 72 +#define L_EDOTDOT 73 +#define L_EBADMSG 74 +#define L_EOVERFLOW 75 +#define L_ENOTUNIQ 76 +#define L_EBADFD 77 +#define L_EREMCHG 78 +#define L_ELIBACC 79 +#define L_ELIBBAD 80 +#define L_ELIBSCN 81 +#define L_ELIBMAX 82 +#define L_ELIBEXEC 83 +#define L_EILSEQ 84 +#define L_ERESTART 85 +#define L_ESTRPIPE 86 +#define L_EUSERS 87 +#define L_ENOTSOCK 88 +#define L_EDESTADDRREQ 89 +#define L_EMSGSIZE 90 +#define L_EPROTOTYPE 91 +#define L_ENOPROTOOPT 92 +#define L_EPROTONOSUPPORT 93 +#define L_ESOCKTNOSUPPORT 94 +#define L_EOPNOTSUPP 95 +#define L_ENOTSUP 95 +#define L_EPFNOSUPPORT 96 +#define L_EAFNOSUPPORT 97 +#define L_EADDRINUSE 98 +#define L_EADDRNOTAVAIL 99 +#define L_ENETDOWN 100 +#define L_ENETUNREACH 101 +#define L_ENETRESET 102 +#define L_ECONNABORTED 103 +#define L_ECONNRESET 104 +#define L_ENOBUFS 105 +#define L_EISCONN 106 +#define L_ENOTCONN 107 +#define L_ESHUTDOWN 108 +#define L_ETOOMANYREFS 109 +#define L_ETIMEDOUT 110 +#define L_ECONNREFUSED 111 +#define L_EHOSTDOWN 112 +#define L_EHOSTUNREACH 113 +#define L_EALREADY 114 +#define L_EINPROGRESS 115 +#define L_ESTALE 116 +#define L_EUCLEAN 117 +#define L_ENOTNAM 118 +#define L_ENAVAIL 119 +#define L_EISNAM 120 +#define L_EREMOTEIO 121 +#define L_EDQUOT 122 +#define L_ENOMEDIUM 123 +#define L_EMEDIUMTYPE 124 +#define L_ECANCELED 125 +#define L_ENOKEY 126 +#define L_EKEYEXPIRED 127 +#define L_EKEYREVOKED 128 +#define L_EKEYREJECTED 129 +#define L_EOWNERDEAD 130 +#define L_ENOTRECOVERABLE 131 +#define L_ERFKILL 132 +#define L_EHWPOISON 133 diff --git a/src/errno/remap_errno.h b/src/errno/remap_errno.h new file mode 100644 index 00000000..21c13a13 --- /dev/null +++ b/src/errno/remap_errno.h @@ -0,0 +1,133 @@ +[EPERM] = L_EPERM, +[ENOENT] = L_ENOENT, +[ESRCH] = L_ESRCH, +[EINTR] = L_EINTR, +[EIO] = L_EIO, +[ENXIO] = L_ENXIO, +[E2BIG] = L_E2BIG, +[ENOEXEC] = L_ENOEXEC, +[EBADF] = L_EBADF, +[ECHILD] = L_ECHILD, +[EAGAIN] = L_EAGAIN, +[ENOMEM] = L_ENOMEM, +[EACCES] = L_EACCES, +[EFAULT] = L_EFAULT, +[ENOTBLK] = L_ENOTBLK, +[EBUSY] = L_EBUSY, +[EEXIST] = L_EEXIST, +[EXDEV] = L_EXDEV, +[ENODEV] = L_ENODEV, +[ENOTDIR] = L_ENOTDIR, +[EISDIR] = L_EISDIR, +[EINVAL] = L_EINVAL, +[ENFILE] = L_ENFILE, +[EMFILE] = L_EMFILE, +[ENOTTY] = L_ENOTTY, +[ETXTBSY] = L_ETXTBSY, +[EFBIG] = L_EFBIG, +[ENOSPC] = L_ENOSPC, +[ESPIPE] = L_ESPIPE, +[EROFS] = L_EROFS, +[EMLINK] = L_EMLINK, +[EPIPE] = L_EPIPE, +[EDOM] = L_EDOM, +[ERANGE] = L_ERANGE, +[EDEADLK] = L_EDEADLK, +[ENAMETOOLONG] = L_ENAMETOOLONG, +[ENOLCK] = L_ENOLCK, +[ENOSYS] = L_ENOSYS, +[ENOTEMPTY] = L_ENOTEMPTY, +[ELOOP] = L_ELOOP, +[EWOULDBLOCK] = L_EWOULDBLOCK, +[ENOMSG] = L_ENOMSG, +[EIDRM] = L_EIDRM, +[ECHRNG] = L_ECHRNG, +[EL2NSYNC] = L_EL2NSYNC, +[EL3HLT] = L_EL3HLT, +[EL3RST] = L_EL3RST, +[ELNRNG] = L_ELNRNG, +[EUNATCH] = L_EUNATCH, +[ENOCSI] = L_ENOCSI, +[EL2HLT] = L_EL2HLT, +[EBADE] = L_EBADE, +[EBADR] = L_EBADR, +[EXFULL] = L_EXFULL, +[ENOANO] = L_ENOANO, +[EBADRQC] = L_EBADRQC, +[EBADSLT] = L_EBADSLT, +[EDEADLOCK] = L_EDEADLOCK, +[EBFONT] = L_EBFONT, +[ENOSTR] = L_ENOSTR, +[ENODATA] = L_ENODATA, +[ETIME] = L_ETIME, +[ENOSR] = L_ENOSR, +[ENONET] = L_ENONET, +[ENOPKG] = L_ENOPKG, +[EREMOTE] = L_EREMOTE, +[ENOLINK] = L_ENOLINK, +[EADV] = L_EADV, +[ESRMNT] = L_ESRMNT, +[ECOMM] = L_ECOMM, +[EPROTO] = L_EPROTO, +[EMULTIHOP] = L_EMULTIHOP, +[EDOTDOT] = L_EDOTDOT, +[EBADMSG] = L_EBADMSG, +[EOVERFLOW] = L_EOVERFLOW, +[ENOTUNIQ] = L_ENOTUNIQ, +[EBADFD] = L_EBADFD, +[EREMCHG] = L_EREMCHG, +[ELIBACC] = L_ELIBACC, +[ELIBBAD] = L_ELIBBAD, +[ELIBSCN] = L_ELIBSCN, +[ELIBMAX] = L_ELIBMAX, +[ELIBEXEC] = L_ELIBEXEC, +[EILSEQ] = L_EILSEQ, +[ERESTART] = L_ERESTART, +[ESTRPIPE] = L_ESTRPIPE, +[EUSERS] = L_EUSERS, +[ENOTSOCK] = L_ENOTSOCK, +[EDESTADDRREQ] = L_EDESTADDRREQ, +[EMSGSIZE] = L_EMSGSIZE, +[EPROTOTYPE] = L_EPROTOTYPE, +[ENOPROTOOPT] = L_ENOPROTOOPT, +[EPROTONOSUPPORT] = L_EPROTONOSUPPORT, +[ESOCKTNOSUPPORT] = L_ESOCKTNOSUPPORT, +[EOPNOTSUPP] = L_EOPNOTSUPP, +[EPFNOSUPPORT] = L_EPFNOSUPPORT, +[EAFNOSUPPORT] = L_EAFNOSUPPORT, +[EADDRINUSE] = L_EADDRINUSE, +[EADDRNOTAVAIL] = L_EADDRNOTAVAIL, +[ENETDOWN] = L_ENETDOWN, +[ENETUNREACH] = L_ENETUNREACH, +[ENETRESET] = L_ENETRESET, +[ECONNABORTED] = L_ECONNABORTED, +[ECONNRESET] = L_ECONNRESET, +[ENOBUFS] = L_ENOBUFS, +[EISCONN] = L_EISCONN, +[ENOTCONN] = L_ENOTCONN, +[ESHUTDOWN] = L_ESHUTDOWN, +[ETOOMANYREFS] = L_ETOOMANYREFS, +[ETIMEDOUT] = L_ETIMEDOUT, +[ECONNREFUSED] = L_ECONNREFUSED, +[EHOSTDOWN] = L_EHOSTDOWN, +[EHOSTUNREACH] = L_EHOSTUNREACH, +[EALREADY] = L_EALREADY, +[EINPROGRESS] = L_EINPROGRESS, +[ESTALE] = L_ESTALE, +[EUCLEAN] = L_EUCLEAN, +[ENOTNAM] = L_ENOTNAM, +[ENAVAIL] = L_ENAVAIL, +[EISNAM] = L_EISNAM, +[EREMOTEIO] = L_EREMOTEIO, +[EDQUOT] = L_EDQUOT, +[ENOMEDIUM] = L_ENOMEDIUM, +[EMEDIUMTYPE] = L_EMEDIUMTYPE, +[ECANCELED] = L_ECANCELED, +[ENOKEY] = L_ENOKEY, +[EKEYEXPIRED] = L_EKEYEXPIRED, +[EKEYREVOKED] = L_EKEYREVOKED, +[EKEYREJECTED] = L_EKEYREJECTED, +[EOWNERDEAD] = L_EOWNERDEAD, +[ENOTRECOVERABLE] = L_ENOTRECOVERABLE, +[ERFKILL] = L_ERFKILL, +[EHWPOISON] = L_EHWPOISON, diff --git a/src/errno/strerror.c b/src/errno/strerror.c index 7f926432..ffa655d3 100644 --- a/src/errno/strerror.c +++ b/src/errno/strerror.c @@ -1,7 +1,26 @@ #include #include -#include #include "locale_impl.h" +#include "l_errno.h" + +#define E(x,y) M(L_ ## x,y) +enum { L_E0 = 0, L_E_ = -1 }; +#define M_TABLE "../errno/__strerror.h", strerror_data, -1 +#define ERRDOMAIN_ERRNO 0 + +static const struct { + unsigned char header[8]; + unsigned char offsets[4]; + struct { + #include "mdecl.h" + } errors; +} strerrors = { + .header = { 0,0,0,0,0,0,0,4-1, }, + .offsets = { [ERRDOMAIN_ERRNO] = 1, }, + .errors = { + #include "mdata.h" + }, +}; /* mips has one error code outside of the 8-bit range due to a * historical typo, so we just remap it. */ @@ -11,32 +30,32 @@ #define EDQUOT 109 #endif -static const struct errmsgstr_t { -#define E(n, s) char str##n[sizeof(s)]; -#include "__strerror.h" -#undef E -} errmsgstr = { -#define E(n, s) s, -#include "__strerror.h" -#undef E -}; - -static const unsigned short errmsgidx[] = { -#define E(n, s) [n] = offsetof(struct errmsgstr_t, str##n), -#include "__strerror.h" -#undef E -}; - -char *__strerror_l(int e, locale_t loc) +static int common_errno(int e) { - const char *s; +#if EDEADLK != L_EDEADLK + static unsigned char remap_errno[] = { + #include "remap_errno.h" + }; #ifdef EDQUOT_ORIG - if (e==EDQUOT) e=0; + if (e==EDQUOT) e=-1; else if (e==EDQUOT_ORIG) e=EDQUOT; #endif - if (e >= sizeof errmsgidx / sizeof *errmsgidx) e = 0; - s = (char *)&errmsgstr + errmsgidx[e]; - return (char *)LCTRANS(s, LC_MESSAGES, loc); + if (e >= sizeof remap_errno / sizeof *remap_errno) return -1; + return remap_errno[e]; +#else + return e; +#endif +} + +char *__strerror_l(int e, locale_t loc) +{ + e = common_errno(e); + static const int unknown[] = LPATH(ERRDOMAIN_ERRNO, -1); + const int path[] = LPATH(ERRDOMAIN_ERRNO, e); + const char *s = __loc_lookup((const void *)&strerrors, + 0 /* LMEMB(loc,LC_MESSAGES,errors) */, + path, unknown); + return (char *)LCTRANS_CUR(s); } char *strerror(int e) diff --git a/src/locale/langinfo.c b/src/locale/langinfo.c index 14773093..7d3bb015 100644 --- a/src/locale/langinfo.c +++ b/src/locale/langinfo.c @@ -1,66 +1,102 @@ +#define _GNU_SOURCE #include #include +#include #include "locale_impl.h" -static const char c_time[] = - "Sun\0" "Mon\0" "Tue\0" "Wed\0" "Thu\0" "Fri\0" "Sat\0" - "Sunday\0" "Monday\0" "Tuesday\0" "Wednesday\0" - "Thursday\0" "Friday\0" "Saturday\0" - "Jan\0" "Feb\0" "Mar\0" "Apr\0" "May\0" "Jun\0" - "Jul\0" "Aug\0" "Sep\0" "Oct\0" "Nov\0" "Dec\0" - "January\0" "February\0" "March\0" "April\0" - "May\0" "June\0" "July\0" "August\0" - "September\0" "October\0" "November\0" "December\0" - "AM\0" "PM\0" - "%a %b %e %T %Y\0" - "%m/%d/%y\0" - "%H:%M:%S\0" - "%I:%M:%S %p\0" - "\0" - "\0" - "%m/%d/%y\0" - "0123456789\0" - "%a %b %e %T %Y\0" - "%H:%M:%S"; +#define O(k,m) [2*(k)] = \ + (offsetof(struct langinfo_data, m)+1)>>8, \ + (offsetof(struct langinfo_data, m)+1)&0xff -static const char c_messages[] = "^[yY]\0" "^[nN]\0" "yes\0" "no"; -static const char c_numeric[] = ".\0" ""; +#define M_TABLE_TIME "../locale/lc_time.h", lc_time_data, LC_TIME<<16 +#define M_TABLE_MESSAGES "../locale/lc_messages.h", lc_messages_data, LC_MESSAGES<<16 +#define M_TABLE_MONETARY "../locale/lc_monetary.h", lc_monetary_data, LC_MONETARY<<16 +#define M_TABLE_NUMERIC "../locale/lc_numeric.h", lc_numeric_data, LC_NUMERIC<<16 + +static const struct { + unsigned char header[8]; + unsigned char offsets[12]; + struct langinfo_data { + int :0; + struct { + #define M_TABLE M_TABLE_TIME + #include "mdecl.h" + #undef M_TABLE + } lc_time; + int :0; + struct { + #define M_TABLE M_TABLE_MESSAGES + #include "mdecl.h" + #undef M_TABLE + } lc_messages; + int :0; + struct { + #define M_TABLE M_TABLE_MONETARY + #include "mdecl.h" + #undef M_TABLE + } lc_monetary; + int :0; + struct { + #define M_TABLE M_TABLE_NUMERIC + #include "mdecl.h" + #undef M_TABLE + } lc_numeric; + } data; +} c_langinfo = { + .header = { 0,0,0,0,0,1,0,6-1, }, + .offsets = { + O(LC_TIME, lc_time), + O(LC_MESSAGES, lc_messages), + O(LC_MONETARY, lc_monetary), + O(LC_NUMERIC, lc_numeric), + }, + .data = { + .lc_time = { + #define M_TABLE M_TABLE_TIME + #include "mdata.h" + #undef M_TABLE + }, + .lc_messages = { + #define M_TABLE M_TABLE_MESSAGES + #include "mdata.h" + #undef M_TABLE + }, + .lc_monetary = { + #define M_TABLE M_TABLE_MONETARY + #include "mdata.h" + #undef M_TABLE + }, + .lc_numeric = { + #define M_TABLE M_TABLE_NUMERIC + #include "mdata.h" + #undef M_TABLE + }, + }, +}; char *__nl_langinfo_l(nl_item item, locale_t loc) { int cat = item >> 16; int idx = item & 65535; - const char *str; + int path[] = { 2, cat, item }; + static const int unknown[] = { 2, -1, -1 }; if (item == CODESET) return loc->cat[LC_CTYPE] ? "UTF-8" : "ASCII"; + //if (item == RADIXCHAR && loc->cat[LC_NUMERIC]) + // return loc->cat[LC_NUMERIC]->lconv.decimal_point; /* _NL_LOCALE_NAME extension */ - if (idx == 65535 && cat < LC_ALL) + if (idx == 65535 && (unsigned)cat < LC_ALL) return loc->cat[cat] ? (char *)loc->cat[cat]->name : "C"; - - switch (cat) { - case LC_NUMERIC: - if (idx > 1) return ""; - str = c_numeric; - break; - case LC_TIME: - if (idx > 0x31) return ""; - str = c_time; - break; - case LC_MONETARY: - if (idx > 0) return ""; - str = ""; - break; - case LC_MESSAGES: - if (idx > 3) return ""; - str = c_messages; - break; - default: - return ""; - } - for (; idx; idx--, str++) for (; *str; str++); + const char *str = __loc_lookup((const void *)&c_langinfo, + 0 /* LMEMB(CURRENT_LOCALE,cat,langinfo) */, + path, unknown); + + if (!str) str = ""; + if (cat != LC_NUMERIC && *str) str = LCTRANS(str, cat, loc); + return (char *)str; } diff --git a/src/locale/lc_messages.h b/src/locale/lc_messages.h new file mode 100644 index 00000000..671ae0b7 --- /dev/null +++ b/src/locale/lc_messages.h @@ -0,0 +1,4 @@ +M(YESEXPR, "^[yY]\0") +M(NOEXPR, "^[nN]\0") +M(YESSTR, "yes") +M(NOSTR, "no") diff --git a/src/locale/lc_monetary.h b/src/locale/lc_monetary.h new file mode 100644 index 00000000..36a5cfd4 --- /dev/null +++ b/src/locale/lc_monetary.h @@ -0,0 +1 @@ +M(CRNCYSTR, "") diff --git a/src/locale/lc_numeric.h b/src/locale/lc_numeric.h new file mode 100644 index 00000000..e91c5a15 --- /dev/null +++ b/src/locale/lc_numeric.h @@ -0,0 +1,2 @@ +M(RADIXCHAR, ".") +M(THOUSEP, "") diff --git a/src/locale/lc_time.h b/src/locale/lc_time.h new file mode 100644 index 00000000..75fc524c --- /dev/null +++ b/src/locale/lc_time.h @@ -0,0 +1,52 @@ +M(ABDAY_1, "Sun") +M(ABDAY_2, "Mon") +M(ABDAY_3, "Tue") +M(ABDAY_4, "Wed") +M(ABDAY_5, "Thu") +M(ABDAY_6, "Fri") +M(ABDAY_7, "Sat") +M(DAY_1, "Sunday") +M(DAY_2, "Monday") +M(DAY_3, "Tuesday") +M(DAY_4, "Wednesday") +M(DAY_5, "Thursday") +M(DAY_6, "Friday") +M(DAY_7, "Saturday") + +M(ABMON_1, "Jan") +M(ABMON_2, "Feb") +M(ABMON_3, "Mar") +M(ABMON_4, "Apr") +M(ABMON_5, "May") +M(ABMON_6, "Jun") +M(ABMON_7, "Jul") +M(ABMON_8, "Aug") +M(ABMON_9, "Sep") +M(ABMON_10, "Oct") +M(ABMON_11, "Nov") +M(ABMON_12, "Dec") +M(MON_1, "January") +M(MON_2, "February") +M(MON_3, "March") +M(MON_4, "April") +M(MON_5, "May") +M(MON_6, "June") +M(MON_7, "July") +M(MON_8, "August") +M(MON_9, "September") +M(MON_10, "October") +M(MON_11, "November") +M(MON_12, "December") + +M(AM_STR, "AM") +M(PM_STR, "PM") + +M(D_T_FMT, "%a %b %e %T %Y") +M(D_FMT, "%m/%d/%y") +M(T_FMT, "%H:%M:%S") +M(T_FMT_AMPM, "%I:%M:%S %p") +M(ERA, "") +M(ERA_D_FMT, "") +M(ALT_DIGITS, "") +M(ERA_D_T_FMT, "") +M(ERA_T_FMT, "") diff --git a/src/network/gai_strerror.c b/src/network/gai_strerror.c index 78e49f92..93163507 100644 --- a/src/network/gai_strerror.c +++ b/src/network/gai_strerror.c @@ -1,26 +1,32 @@ #include +#include #include "locale_impl.h" -static const char msgs[] = - "Invalid flags\0" - "Name does not resolve\0" - "Try again\0" - "Non-recoverable error\0" - "Name has no usable address\0" - "Unrecognized address family or invalid length\0" - "Unrecognized socket type\0" - "Unrecognized service\0" - "Unknown error\0" - "Out of memory\0" - "System error\0" - "Overflow\0" - "\0Unknown error"; +enum { EAI__ = 1 }; +#define M_TABLE "../network/gai_strerror.h", gai_strerror_data, -12 +#define ERRDOMAIN_EAI 2 + +static const struct { + unsigned char header[8]; + unsigned char offsets[4]; + struct { + #include "mdecl.h" + } errors; +} gai_strerrors = { + .header = { 0,0,0,0,0,0,0,4-1, }, + .offsets = { [ERRDOMAIN_EAI] = 1 }, + .errors = { + #include "mdata.h" + }, +}; const char *gai_strerror(int e) { - const char *s; - unsigned ecode=e; - for (s=msgs, ecode++; ecode && *s; ecode++, s++) for (; *s; s++); - if (!*s) s++; + static const int unknown[] = LPATH(ERRDOMAIN_EAI, EAI__); + const int path[] = LPATH(ERRDOMAIN_EAI, e); + + const char *s = __loc_lookup((const void *)&gai_strerrors, + 0 /* LMEMB(CURRENT_LOCALE,LC_MESSAGES,errors) */, + path, unknown); return LCTRANS_CUR(s); } diff --git a/src/network/gai_strerror.h b/src/network/gai_strerror.h new file mode 100644 index 00000000..fe40522a --- /dev/null +++ b/src/network/gai_strerror.h @@ -0,0 +1,12 @@ +M(EAI_BADFLAGS,"Invalid flags") +M(EAI_NONAME,"Name does not resolve") +M(EAI_AGAIN,"Try again") +M(EAI_FAIL,"Non-recoverable error") +M(EAI_NODATA,"Name has no usable address") +M(EAI_FAMILY,"Unrecognized address family or invalid length") +M(EAI_SOCKTYPE,"Unrecognized socket type") +M(EAI_SERVICE,"Unrecognized service") +M(EAI_MEMORY,"Out of memory") +M(EAI_SYSTEM,"System error") +M(EAI_OVERFLOW,"Overflow") +M(EAI__,"Unknown error") diff --git a/src/network/hstrerror.c b/src/network/hstrerror.c index a17a8e0a..76537679 100644 --- a/src/network/hstrerror.c +++ b/src/network/hstrerror.c @@ -1,19 +1,33 @@ #define _GNU_SOURCE #include +#include #include "locale_impl.h" -static const char msgs[] = - "Host not found\0" - "Try again\0" - "Non-recoverable error\0" - "Address not available\0" - "\0Unknown error"; +enum { H_ = -1 }; +#define M_TABLE "../network/hstrerror.h", hstrerror_data, -1 +#define ERRDOMAIN_H 1 + +static const struct { + unsigned char header[8]; + unsigned char offsets[4]; + struct { + #include "mdecl.h" + } errors; +} hstrerrors = { + .header = { 0,0,0,0,0,0,0,4-1, }, + .offsets = { [ERRDOMAIN_H] = 1 }, + .errors = { + #include "mdata.h" + }, +}; const char *hstrerror(int e) { - const char *s; - unsigned ecode=e; - for (s=msgs, ecode--; ecode && *s; ecode--, s++) for (; *s; s++); - if (!*s) s++; + static const int unknown[] = LPATH(ERRDOMAIN_H, H_); + const int path[] = LPATH(ERRDOMAIN_H, e); + + const char *s = __loc_lookup((const void *)&hstrerrors, + 0 /* LMEMB(CURRENT_LOCALE,LC_MESSAGES,errors) */, + path, unknown); return LCTRANS_CUR(s); } diff --git a/src/network/hstrerror.h b/src/network/hstrerror.h new file mode 100644 index 00000000..7203e1a6 --- /dev/null +++ b/src/network/hstrerror.h @@ -0,0 +1,5 @@ +M(HOST_NOT_FOUND, "Host not found") +M(TRY_AGAIN, "Try again") +M(NO_RECOVERY, "Non-recoverable error") +M(NO_DATA, "Address not available") +M(H_, "Unknown error") diff --git a/src/regex/regerror.c b/src/regex/regerror.c index 5e35870f..e6de915c 100644 --- a/src/regex/regerror.c +++ b/src/regex/regerror.c @@ -1,38 +1,34 @@ -#include #include #include +#include #include "locale_impl.h" -/* Error message strings for error codes listed in `regex.h'. This list - needs to be in sync with the codes listed there, naturally. */ +enum { REG__ = -1 }; +#define M_TABLE "../regex/regerror.h", regerror_data, -1 +#define ERRDOMAIN_REG 3 -/* Converted to single string by Rich Felker to remove the need for - * data relocations at runtime, 27 Feb 2006. */ - -static const char messages[] = { - "No error\0" - "No match\0" - "Invalid regexp\0" - "Unknown collating element\0" - "Unknown character class name\0" - "Trailing backslash\0" - "Invalid back reference\0" - "Missing ']'\0" - "Missing ')'\0" - "Missing '}'\0" - "Invalid contents of {}\0" - "Invalid character range\0" - "Out of memory\0" - "Repetition not preceded by valid expression\0" - "\0Unknown error" +static const struct { + unsigned char header[8]; + unsigned char offsets[4]; + struct { + #include "mdecl.h" + } errors; +} regerrors = { + .header = { 0,0,0,0,0,0,0,4-1, }, + .offsets = { [ERRDOMAIN_REG] = 1 }, + .errors = { + #include "mdata.h" + }, }; -size_t regerror(int c, const regex_t *restrict preg, char *restrict buf, size_t size) +size_t regerror(int e, const regex_t *restrict preg, char *restrict buf, size_t size) { - const char *s; - unsigned e=c; - for (s=messages; e && *s; e--, s+=strlen(s)+1); - if (!*s) s++; + static const int unknown[] = LPATH(ERRDOMAIN_REG, REG__); + const int path[] = LPATH(ERRDOMAIN_REG, e); + + const char *s = __loc_lookup((const void *)®errors, + 0 /* LMEMB(CURRENT_LOCALE,LC_MESSAGES,errors) */, + path, unknown); s = LCTRANS_CUR(s); return 1+snprintf(buf, size, "%s", s); } diff --git a/src/regex/regerror.h b/src/regex/regerror.h new file mode 100644 index 00000000..a61c4f9d --- /dev/null +++ b/src/regex/regerror.h @@ -0,0 +1,15 @@ +M(REG_OK, "No error") +M(REG_NOMATCH, "No match") +M(REG_BADPAT, "Invalid regexp") +M(REG_ECOLLATE, "Unknown collating element") +M(REG_ECTYPE, "Unknown character class name") +M(REG_EESCAPE, "Trailing backslash") +M(REG_ESUBREG, "Invalid back reference") +M(REG_EBRACK, "Missing ']'") +M(REG_EPAREN, "Missing ')'") +M(REG_EBRACE, "Missing '}'") +M(REG_BADBR, "Invalid contents of {}") +M(REG_ERANGE, "Invalid character range") +M(REG_ESPACE, "Out of memory") +M(REG_BADRPT, "Repetition not preceded by valid expression") +M(REG__, "Unknown error") -- 2.21.0