@@ -69,6 +69,11 @@ chapters.% top-menu.%: libc-texinfo.sh $(texis-path) Makefile
'$(chapters)' \
'$(appendices) $(licenses)'
+# Verify validity of texinfo sources against project rules.
+tests-special += \
+ $(objpfx)check-deftype.out \
+ $(objpfx)check-safety.out \
+ # tests-special
$(objpfx)libc.dvi $(objpfx)libc.pdf $(objpfx)libc.info: \
$(addprefix $(objpfx),$(libc-texi-generated))
@@ -83,10 +88,19 @@ $(objpfx)summary.texi: $(objpfx)stamp-summary ;
$(objpfx)stamp-summary: summary.pl $(filter-out $(objpfx)summary.texi, \
$(texis-path))
$(SHELL) ./check-safety.sh $(filter-out $(objpfx)%, $(texis-path))
+ $(SHELL) ./check-deftype.sh $(filter-out $(objpfx)%, $(texis-path))
LC_ALL=C $(PERL) $^ > $(objpfx)summary-tmp
$(move-if-change) $(objpfx)summary-tmp $(objpfx)summary.texi
touch $@
+$(objpfx)check-safety.out: check-safety.sh
+ $(SHELL) $< > $@ ; \
+ $(evaluate-test)
+
+$(objpfx)check-deftype.out: check-deftype.sh
+ $(SHELL) $< > $@ ; \
+ $(evaluate-test)
+
# Generate a file which can be added to the `dir' content to provide direct
# access to the documentation of the function, variables, and other
# definitions.
@@ -153,7 +167,8 @@ $(objpfx)%.pdf: %.texinfo
# Distribution.
minimal-dist = summary.pl texis.awk tsort.awk libc-texinfo.sh libc.texinfo \
- libm-err.texi stamp-libm-err check-safety.sh \
+ libm-err.texi stamp-libm-err check-safety.sh \
+ check-deftype.sh \
$(filter-out summary.texi, $(nonexamples)) \
$(patsubst %.c.texi,examples/%.c, $(examples))
new file mode 100644
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# Copyright 2024 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/>.
+
+# Check that the @deftypefun command is called with the expected
+# arguments and includes checking for common mistakes including
+# failure to include a space after the function name, or incorrect
+# quoting.
+
+success=:
+
+# If no arguments are given, take all *.texi files in the current directory.
+test $# != 0 || set *.texi
+
+# We search for all @deftypefun and @deftypefunx command uses.
+# Then we remove all of those that match our expectations.
+# A @deftypefun or @deftypefunx command takes 3 arguments:
+# - return type
+# - name
+# - arguments
+# This is different from @deftypefn which includes an additional
+# category which is implicit here.
+grep -n -r '^@deftypefun' "$@" |
+grep -v '^.*@deftypefunx\?'\
+' \({\?[a-zA-Z0-9_ *]*}\?\) \([a-zA-Z0-9_]*\) (.*)$' &&
+success=false
+
+# We search for all @deftypefn and @deftypefnx command uses.
+# We have 4 arguments in the command including the category.
+grep -n -r '^@deftypefn' "$@" |
+grep -v '^.*@deftypefnx\?'\
+' {\?[a-zA-Z ]*}\? \({\?[a-zA-Z0-9@{}_ *]*}\?\) \([a-zA-Z0-9_]*\) (.*)$' &&
+success=false
+
+$success
@@ -20,7 +20,7 @@ by @theglibc{}.
@c Need descriptions for all of these functions.
@subsection System V Semaphores
-@deftypefun int semctl (int @var{semid}, int @var{semnum}, int @var{cmd});
+@deftypefun int semctl (int @var{semid}, int @var{semnum}, int @var{cmd})
@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{/linux}}}
@c syscall(ipc) ok
@c
@@ -30,35 +30,35 @@ by @theglibc{}.
@c semid_ds.
@end deftypefun
-@deftypefun int semget (key_t @var{key}, int @var{nsems}, int @var{semflg});
+@deftypefun int semget (key_t @var{key}, int @var{nsems}, int @var{semflg})
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@c syscall(ipc) ok
@end deftypefun
-@deftypefun int semop (int @var{semid}, struct sembuf *@var{sops}, size_t @var{nsops});
+@deftypefun int semop (int @var{semid}, struct sembuf *@var{sops}, size_t @var{nsops})
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@c syscall(ipc) ok
@end deftypefun
-@deftypefun int semtimedop (int @var{semid}, struct sembuf *@var{sops}, size_t @var{nsops}, const struct timespec *@var{timeout});
+@deftypefun int semtimedop (int @var{semid}, struct sembuf *@var{sops}, size_t @var{nsops}, const struct timespec *@var{timeout})
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@c syscall(ipc) ok
@end deftypefun
@subsection POSIX Semaphores
-@deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value});
+@deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value})
@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
@c Does not atomically update sem_t therefore AC-unsafe
@c because it can leave sem_t partially initialized.
@end deftypefun
-@deftypefun int sem_destroy (sem_t *@var{sem});
+@deftypefun int sem_destroy (sem_t *@var{sem})
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@c Function does nothing and is therefore always safe.
@end deftypefun
-@deftypefun sem_t *sem_open (const char *@var{name}, int @var{oflag}, ...);
+@deftypefun {sem_t *} sem_open (const char *@var{name}, int @var{oflag}, ...)
@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acuinit{}}}
@c pthread_once asuinit
@c
@@ -67,7 +67,7 @@ by @theglibc{}.
@c shmfs on Linux.
@end deftypefun
-@deftypefun int sem_close (sem_t *@var{sem});
+@deftypefun int sem_close (sem_t *@var{sem})
@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
@c lll_lock asulock aculock
@c twalk mtsrace{:root}
@@ -77,13 +77,13 @@ by @theglibc{}.
@c are not updated atomically.
@end deftypefun
-@deftypefun int sem_unlink (const char *@var{name});
+@deftypefun int sem_unlink (const char *@var{name})
@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acucorrupt{}}}
@c pthread_once asuinit acucorrupt aculock
@c mempcpy acucorrupt
@end deftypefun
-@deftypefun int sem_wait (sem_t *@var{sem});
+@deftypefun int sem_wait (sem_t *@var{sem})
@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
@c atomic_fetch_add_relaxed (nwaiters) acucorrupt
@c
@@ -95,22 +95,22 @@ by @theglibc{}.
@c waiters count.
@end deftypefun
-@deftypefun int sem_timedwait (sem_t *@var{sem}, const struct timespec *@var{abstime});
+@deftypefun int sem_timedwait (sem_t *@var{sem}, const struct timespec *@var{abstime})
@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
@c Same safety issues as sem_wait.
@end deftypefun
-@deftypefun int sem_trywait (sem_t *@var{sem});
+@deftypefun int sem_trywait (sem_t *@var{sem})
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@c All atomic operations are safe in all contexts.
@end deftypefun
-@deftypefun int sem_post (sem_t *@var{sem});
+@deftypefun int sem_post (sem_t *@var{sem})
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@c Same safety as sem_trywait.
@end deftypefun
-@deftypefun int sem_getvalue (sem_t *@var{sem}, int *@var{sval});
+@deftypefun int sem_getvalue (sem_t *@var{sem}, int *@var{sval})
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@c Atomic write of a value is safe in all contexts.
@end deftypefun
@@ -4831,12 +4831,12 @@ of an IOCTL, see @ref{Out-of-Band Data}.
@manpagefunctionstub{poll,2}
@end deftypefun
-@deftypefun int epoll_create(int @var{size})
+@deftypefun int epoll_create (int @var{size})
@manpagefunctionstub{epoll_create,2}
@end deftypefun
-@deftypefun int epoll_wait(int @var{epfd}, struct epoll_event *@var{events}, int @var{maxevents}, int @var{timeout})
+@deftypefun int epoll_wait (int @var{epfd}, struct epoll_event *@var{events}, int @var{maxevents}, int @var{timeout})
@manpagefunctionstub{epoll_wait,2}
@end deftypefun
@@ -2935,7 +2935,7 @@ exceed the process' data storage limit.
@end deftypefun
-@deftypefun void *sbrk (ptrdiff_t @var{delta})
+@deftypefun {void *} sbrk (ptrdiff_t @var{delta})
@standards{BSD, unistd.h}
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@@ -2531,7 +2531,7 @@ store the result in which case @code{-1} is returned. This was
changed in order to comply with the @w{ISO C99} standard.
@end deftypefun
-@deftypefun dprintf (int @var{fd}, @var{template}, ...)
+@deftypefun int dprintf (int @var{fd}, @var{template}, ...)
@standards{POSIX, stdio.h}
@safety{@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}}
This function formats its arguments according to @var{template} and
@@ -592,7 +592,7 @@ destructor for the thread-specific data is not called during destruction, nor
is it called during thread exit.
@end deftypefun
-@deftypefun void *pthread_getspecific (pthread_key_t @var{key})
+@deftypefun {void *} pthread_getspecific (pthread_key_t @var{key})
@standards{POSIX, pthread.h}
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
@c pthread_getspecific ok
@@ -1829,7 +1829,7 @@ can be placed in the buffer @var{s} the return value is zero, with the
same problems indicated in the @code{strftime} documentation.
@end deftypefun
-@deftypefun {Deprecated function} {char *} asctime (const struct tm *@var{brokentime})
+@deftypefn {Deprecated function} {char *} asctime (const struct tm *@var{brokentime})
@standards{ISO, time.h}
@safety{@prelim{}@mtunsafe{@mtasurace{:asctime} @mtslocale{}}@asunsafe{}@acsafe{}}
@c asctime @mtasurace:asctime @mtslocale
@@ -1863,9 +1863,9 @@ string.)
@strong{Portability note:}
This obsolescent function is deprecated in C23.
Programs should instead use @code{strftime} or even @code{sprintf}.
-@end deftypefun
+@end deftypefn
-@deftypefun {Deprecated function} {char *} asctime_r (const struct tm *@var{brokentime}, char *@var{buffer})
+@deftypefn {Deprecated function} {char *} asctime_r (const struct tm *@var{brokentime}, char *@var{buffer})
@standards{???, time.h}
@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}}
@c asctime_r @mtslocale
@@ -1884,9 +1884,9 @@ it returns @code{NULL}.
@strong{Portability Note:}
POSIX.1-2024 removed this obsolescent function.
Programs should instead use @code{strftime} or even @code{sprintf}.
-@end deftypefun
+@end deftypefn
-@deftypefun {Deprecated function} {char *} ctime (const time_t *@var{time})
+@deftypefn {Deprecated function} {char *} ctime (const time_t *@var{time})
@standards{ISO, time.h}
@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtasurace{:asctime} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
@c ctime @mtasurace:tmbuf @mtasurace:asctime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
@@ -1909,9 +1909,9 @@ Calling @code{ctime} also sets the time zone state as if
@strong{Portability note:}
This obsolescent function is deprecated in C23.
Programs should instead use @code{strftime} or even @code{sprintf}.
-@end deftypefun
+@end deftypefn
-@deftypefun {Deprecated function} {char *} ctime_r (const time_t *@var{time}, char *@var{buffer})
+@deftypefn {Deprecated function} {char *} ctime_r (const time_t *@var{time}, char *@var{buffer})
@standards{???, time.h}
@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
@c ctime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
@@ -1935,7 +1935,7 @@ it returns @code{NULL}.
@strong{Portability Note:}
POSIX.1-2024 removed this obsolescent function.
Programs should instead use @code{strftime} or even @code{sprintf}.
-@end deftypefun
+@end deftypefn
@node Parsing Date and Time
@subsection Convert textual time and date information back