aboutsummaryrefslogtreecommitdiff
path: root/stdio-common
diff options
context:
space:
mode:
Diffstat (limited to 'stdio-common')
-rw-r--r--stdio-common/Makefile11
-rw-r--r--stdio-common/errlist-compat.c1
-rw-r--r--stdio-common/errlist.c30
-rwxr-xr-xstdio-common/tst-errno-manual.py73
4 files changed, 101 insertions, 14 deletions
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index 1333203..73bf0da 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -85,6 +85,8 @@ generated += tst-printf-bz18872.c tst-printf-bz18872.mtrace \
tst-printf-bz25691.mtrace tst-printf-bz25691-mem.out
endif
+tests-special += $(objpfx)tst-errno-manual.out
+
include ../Rules
ifeq ($(run-built-tests),yes)
@@ -129,6 +131,15 @@ $(objpfx)tst-%-mem.out: $(objpfx)tst-%.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-$*.mtrace > $@; \
$(evaluate-test)
+errlist-h = $(firstword $(wildcard $(addsuffix /errlist.h,$(sysdirs) .)))
+
+$(objpfx)tst-errno-manual.out: tst-errno-manual.py \
+ $(errlist-h) \
+ $(..)manual/errno.texi
+ $(PYTHON) tst-errno-manual.py -m $(..)manual/errno.texi \
+ -e $(errlist-h) > $@; \
+ $(evaluate-test)
+
CFLAGS-vfprintf.c += -Wno-uninitialized
CFLAGS-vfwprintf.c += -Wno-uninitialized
diff --git a/stdio-common/errlist-compat.c b/stdio-common/errlist-compat.c
new file mode 100644
index 0000000..6e25b02
--- /dev/null
+++ b/stdio-common/errlist-compat.c
@@ -0,0 +1 @@
+/* Empty. */
diff --git a/stdio-common/errlist.c b/stdio-common/errlist.c
index 91fa789..df52356 100644
--- a/stdio-common/errlist.c
+++ b/stdio-common/errlist.c
@@ -15,22 +15,24 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <stdio.h>
+#include <errno.h>
+#include <libintl.h>
#include <array_length.h>
-#include <stddef.h>
-const char *const _sys_errlist[] =
+const char *const _sys_errlist_internal[] =
{
- "Error 0", /* 0 */
- "Argument out of function's domain", /* 1 = EDOM */
- "Result out of range", /* 2 = ERANGE */
- "Operation not implemented", /* 3 = ENOSYS */
- "Invalid argument", /* 4 = EINVAL */
- "Illegal seek", /* 5 = ESPIPE */
- "Bad file descriptor", /* 6 = EBADF */
- "Cannot allocate memory", /* 7 = ENOMEM */
- "Permission denied", /* 8 = EACCES */
- "Too many open files in system", /* 9 = ENFILE */
- "Too many open files", /* 10 = EMFILE */
+#define _S(n, str) [n] = str,
+#include <errlist.h>
+#undef _S
};
-const int _sys_nerr = array_length (_sys_errlist);
+const char *
+__get_errlist (int errnum)
+{
+ if (errnum >= 0 && errnum < array_length (_sys_errlist_internal))
+ return _sys_errlist_internal[errnum];
+ return NULL;
+}
+
+#include <errlist-compat.c>
diff --git a/stdio-common/tst-errno-manual.py b/stdio-common/tst-errno-manual.py
new file mode 100755
index 0000000..618120f
--- /dev/null
+++ b/stdio-common/tst-errno-manual.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python3
+# Check is all errno definitions at errlist.h documented in the manual.
+# Copyright (C) 2020 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <https://www.gnu.org/licenses/>.
+
+import argparse
+import sys
+import re
+
+RE_MANUAL = re.compile(
+ r'(?:^@errno){(\w+)')
+
+RE_ERRLIST = re.compile(
+ r'\(E[a-zA-Z0-9]+\)')
+
+PASS=0
+FAIL=1
+
+# Each manual entry is in the form:
+#
+# errno{EAGAIN, 35, Resource temporarily unavailable}
+def parse_manual(f):
+ errlist = [RE_MANUAL.findall(s) for s in f]
+ return map(lambda x : x[0], filter(None, errlist))
+
+# Each errlist entry is in the form:
+#
+# _S(ERR_MAP(EAGAIN), N_("Resource temporarily unavailable"))
+def parse_errlist(f):
+ errlist = [RE_ERRLIST.findall(s) for s in f]
+ # Each element is '[]' or '['(EAGAIN)']'
+ return map(lambda s : s[0][s[0].find('(')+1:s[0].find(')')],
+ filter(None, errlist))
+
+def check_errno_definitions(manual_fname, errlist_fname):
+ with open(manual_fname, 'r') as mfile, open(errlist_fname, 'r') as efile:
+ merr = parse_manual(mfile)
+ eerr = parse_errlist(efile)
+ diff = set(eerr).difference(merr)
+ if not diff:
+ sys.exit(PASS)
+ else:
+ print("Failure: the following value(s) are not in manual:",
+ ", ".join(str(e) for e in diff))
+ sys.exit(FAIL)
+
+def main():
+ parser = argparse.ArgumentParser(description='Generate errlist.h')
+ parser.add_argument('-m', dest='manual', metavar='FILE',
+ help='manual errno texi file')
+ parser.add_argument('-e', dest='errlist', metavar='FILE',
+ help='errlist with errno definitions')
+ args = parser.parse_args()
+
+ check_errno_definitions(args.manual, args.errlist)
+
+
+if __name__ == '__main__':
+ main()