diff options
-rw-r--r-- | INSTALL | 2 | ||||
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | Makefile.depend | 6 | ||||
-rw-r--r-- | compat_isblank.c | 33 | ||||
-rw-r--r-- | compat_mkdtemp.c | 61 | ||||
-rw-r--r-- | compat_vasprintf.c | 52 | ||||
-rwxr-xr-x | configure | 19 | ||||
-rw-r--r-- | test-isblank.c | 7 | ||||
-rw-r--r-- | test-mkdtemp.c | 12 | ||||
-rw-r--r-- | test-vasprintf.c | 45 |
10 files changed, 247 insertions, 1 deletions
@@ -42,6 +42,8 @@ generates. If anything looks wrong or different from what you wish, read the file "configure.local.example", create and edit a file "configure.local", and re-run "./configure" until the result seems right to you. +On Solaris 10 and earlier, you may have to run "ksh ./configure" +because the native /bin/sh lacks some POSIX features. 3. Run "make". Any POSIX-compatible make, in particular both BSD make and GNU make, @@ -23,6 +23,8 @@ TESTSRCS = test-dirent-namlen.c \ test-fgetln.c \ test-fts.c \ test-getsubopt.c \ + test-isblank.c \ + test-mkdtemp.c \ test-mmap.c \ test-ohash.c \ test-reallocarray.c \ @@ -34,6 +36,7 @@ TESTSRCS = test-dirent-namlen.c \ test-strptime.c \ test-strsep.c \ test-strtonum.c \ + test-vasprintf.c \ test-wchar.c SRCS = att.c \ @@ -42,6 +45,8 @@ SRCS = att.c \ compat_fgetln.c \ compat_fts.c \ compat_getsubopt.c \ + compat_isblank.c \ + compat_mkdtemp.c \ compat_ohash.c \ compat_reallocarray.c \ compat_sqlite3_errstr.c \ @@ -50,6 +55,7 @@ SRCS = att.c \ compat_strlcpy.c \ compat_strsep.c \ compat_strtonum.c \ + compat_vasprintf.c \ demandoc.c \ eqn.c \ eqn_html.c \ @@ -187,6 +193,8 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \ COMPAT_OBJS = compat_fgetln.o \ compat_fts.o \ compat_getsubopt.o \ + compat_isblank.o \ + compat_mkdtemp.o \ compat_ohash.o \ compat_reallocarray.o \ compat_sqlite3_errstr.o \ @@ -194,7 +202,8 @@ COMPAT_OBJS = compat_fgetln.o \ compat_strlcat.o \ compat_strlcpy.o \ compat_strsep.o \ - compat_strtonum.o + compat_strtonum.o \ + compat_vasprintf.o MANDOC_HTML_OBJS = eqn_html.o \ html.o \ diff --git a/Makefile.depend b/Makefile.depend index 54af8bce..54b85bb8 100644 --- a/Makefile.depend +++ b/Makefile.depend @@ -4,6 +4,8 @@ chars.o: chars.c config.h mandoc.h mandoc_aux.h libmandoc.h chars.in compat_fgetln.o: compat_fgetln.c config.h compat_fts.o: compat_fts.c config.h compat_fts.h compat_getsubopt.o: compat_getsubopt.c config.h +compat_isblank.o: compat_isblank.c config.h +compat_mkdtemp.o: compat_mkdtemp.c config.h compat_ohash.o: compat_ohash.c config.h compat_ohash.h compat_reallocarray.o: compat_reallocarray.c config.h compat_sqlite3_errstr.o: compat_sqlite3_errstr.c config.h @@ -12,6 +14,7 @@ compat_strlcat.o: compat_strlcat.c config.h compat_strlcpy.o: compat_strlcpy.c config.h compat_strsep.o: compat_strsep.c config.h compat_strtonum.o: compat_strtonum.c config.h +compat_vasprintf.o: compat_vasprintf.c config.h demandoc.o: demandoc.c config.h man.h mdoc.h mandoc.h eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h @@ -60,6 +63,8 @@ test-dirent-namlen.o: test-dirent-namlen.c test-fgetln.o: test-fgetln.c test-fts.o: test-fts.c test-getsubopt.o: test-getsubopt.c +test-isblank.o: test-isblank.c +test-mkdtemp.o: test-mkdtemp.c test-mmap.o: test-mmap.c test-ohash.o: test-ohash.c test-reallocarray.o: test-reallocarray.c @@ -71,4 +76,5 @@ test-strlcpy.o: test-strlcpy.c test-strptime.o: test-strptime.c test-strsep.o: test-strsep.c test-strtonum.o: test-strtonum.c +test-vasprintf.o: test-vasprintf.c test-wchar.o: test-wchar.c diff --git a/compat_isblank.c b/compat_isblank.c new file mode 100644 index 00000000..af8bdce8 --- /dev/null +++ b/compat_isblank.c @@ -0,0 +1,33 @@ +#include "config.h" + +#if HAVE_ISBLANK + +int dummy; + +#else + +/* $Id$ */ +/* + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +int +isblank(int c) +{ + + return(c == ' ' || c == '\t'); +} + +#endif diff --git a/compat_mkdtemp.c b/compat_mkdtemp.c new file mode 100644 index 00000000..d12fa87a --- /dev/null +++ b/compat_mkdtemp.c @@ -0,0 +1,61 @@ +#include "config.h" + +#if HAVE_MKDTEMP + +int dummy; + +#else + +/* $Id$ */ +/* + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * The algorithm of this function is inspired by OpenBSD mkdtemp(3) + * by Theo de Raadt and Todd Miller, but the code differs. + */ + +#include <sys/stat.h> +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +char * +mkdtemp(char *path) +{ + char *start, *cp; + unsigned int tries; + + start = strchr(path, '\0'); + while (start > path && start[-1] == 'X') + start--; + + for (tries = INT_MAX; tries; tries--) { + if (mktemp(path) == NULL) { + errno = EEXIST; + return(NULL); + } + if (mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR) == 0) + return(path); + if (errno != EEXIST) + return(NULL); + for (cp = start; *cp != '\0'; cp++) + *cp = 'X'; + } + errno = EEXIST; + return(NULL); +} + +#endif diff --git a/compat_vasprintf.c b/compat_vasprintf.c new file mode 100644 index 00000000..10113aaa --- /dev/null +++ b/compat_vasprintf.c @@ -0,0 +1,52 @@ +#include "config.h" + +#if HAVE_VASPRINTF + +int dummy; + +#else + +/* $Id$ */ +/* + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * This fallback implementation is not efficient: + * It does the formatting twice. + * Short of fiddling with the unknown internals of the system's + * printf(3) or completely reimplementing printf(3), i can't think + * of another portable solution. + */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +int +vasprintf(char **ret, const char *format, va_list ap) +{ + char buf[2]; + int sz; + + if ((sz = vsnprintf(buf, sizeof(buf), format, ap)) != -1 && + (*ret = malloc(sz + 1)) != NULL) { + if (vsnprintf(*ret, sz + 1, format, ap) == sz) + return(sz); + free(*ret); + } + *ret = NULL; + return(-1); +} + +#endif @@ -45,6 +45,8 @@ HAVE_DIRENT_NAMLEN= HAVE_FGETLN= HAVE_FTS= HAVE_GETSUBOPT= +HAVE_ISBLANK= +HAVE_MKDTEMP= HAVE_MMAP= HAVE_REALLOCARRAY= HAVE_STRCASESTR= @@ -53,6 +55,7 @@ HAVE_STRLCPY= HAVE_STRPTIME= HAVE_STRSEP= HAVE_STRTONUM= +HAVE_VASPRINTF= HAVE_WCHAR= HAVE_SQLITE3= @@ -167,6 +170,8 @@ runtest dirent-namlen DIRENT_NAMLEN || true runtest fgetln FGETLN || true runtest fts FTS || true runtest getsubopt GETSUBOPT || true +runtest isblank ISBLANK || true +runtest mkdtemp MKDTEMP || true runtest mmap MMAP || true runtest reallocarray REALLOCARRAY || true runtest strcasestr STRCASESTR || true @@ -175,6 +180,7 @@ runtest strlcpy STRLCPY || true runtest strptime STRPTIME || true runtest strsep STRSEP || true runtest strtonum STRTONUM || true +runtest vasprintf VASPRINTF || true runtest wchar WCHAR || true # --- sqlite3 --- @@ -268,6 +274,7 @@ __HEREDOC__ [ ${HAVE_FGETLN} -eq 0 -o ${HAVE_REALLOCARRAY} -eq 0 -o \ ${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 ] \ && echo "#include <sys/types.h>" +[ ${HAVE_VASPRINTF} -eq 0 ] && echo "#include <stdarg.h>" [ ${HAVE_FGETLN} -eq 0 ] && echo "#include <stdio.h>" echo @@ -279,6 +286,8 @@ cat << __HEREDOC__ #define HAVE_FGETLN ${HAVE_FGETLN} #define HAVE_FTS ${HAVE_FTS} #define HAVE_GETSUBOPT ${HAVE_GETSUBOPT} +#define HAVE_ISBLANK ${HAVE_ISBLANK} +#define HAVE_MKDTEMP ${HAVE_MKDTEMP} #define HAVE_MMAP ${HAVE_MMAP} #define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY} #define HAVE_STRCASESTR ${HAVE_STRCASESTR} @@ -287,6 +296,7 @@ cat << __HEREDOC__ #define HAVE_STRPTIME ${HAVE_STRPTIME} #define HAVE_STRSEP ${HAVE_STRSEP} #define HAVE_STRTONUM ${HAVE_STRTONUM} +#define HAVE_VASPRINTF ${HAVE_VASPRINTF} #define HAVE_WCHAR ${HAVE_WCHAR} #define HAVE_SQLITE3 ${HAVE_SQLITE3} #define HAVE_SQLITE3_ERRSTR ${HAVE_SQLITE3_ERRSTR} @@ -321,6 +331,12 @@ __HEREDOC__ [ ${HAVE_GETSUBOPT} -eq 0 ] && \ echo "extern int getsubopt(char **, char * const *, char **);" +[ ${HAVE_ISBLANK} -eq 0 ] && \ + echo "extern int isblank(int);" + +[ ${HAVE_MKDTEMP} -eq 0 ] && \ + echo "extern char *mkdtemp(char *);" + [ ${HAVE_REALLOCARRAY} -eq 0 ] && \ echo "extern void *reallocarray(void *, size_t, size_t);" @@ -342,6 +358,9 @@ __HEREDOC__ [ ${HAVE_STRTONUM} -eq 0 ] && \ echo "extern long long strtonum(const char *, long long, long long, const char **);" +[ ${HAVE_VASPRINTF} -eq 0 ] && \ + echo "extern int vasprintf(char **, const char *, va_list);" + echo echo "#endif /* MANDOC_CONFIG_H */" diff --git a/test-isblank.c b/test-isblank.c new file mode 100644 index 00000000..f91232ac --- /dev/null +++ b/test-isblank.c @@ -0,0 +1,7 @@ +#include <ctype.h> + +int +main(void) +{ + return(!isblank(' ') || !isblank('\t') || isblank('_')); +} diff --git a/test-mkdtemp.c b/test-mkdtemp.c new file mode 100644 index 00000000..8e1c46ca --- /dev/null +++ b/test-mkdtemp.c @@ -0,0 +1,12 @@ +#include <stdlib.h> +#include <unistd.h> + +int +main(void) +{ + char dirname[] = "/tmp/temp.XXXXXX"; + + if (mkdtemp(dirname) != dirname) + return(1); + return(rmdir(dirname) == -1); +} diff --git a/test-vasprintf.c b/test-vasprintf.c new file mode 100644 index 00000000..06fe5d61 --- /dev/null +++ b/test-vasprintf.c @@ -0,0 +1,45 @@ +/* $Id$ */ +/* + * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +int +testfunc(char **ret, const char *format, ...) +{ + va_list ap; + int irc; + + va_start(ap, format); + irc = vasprintf(ret, format, ap); + va_end(ap); + + return(irc); +} + +int +main(void) +{ + char *ret; + + if (testfunc(&ret, "%s.", "Text") != 5) + return(1); + if (strcmp(ret, "Text.")) + return(2); + return(0); +} |