summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--INSTALL2
-rw-r--r--Makefile11
-rw-r--r--Makefile.depend6
-rw-r--r--compat_isblank.c33
-rw-r--r--compat_mkdtemp.c61
-rw-r--r--compat_vasprintf.c52
-rwxr-xr-xconfigure19
-rw-r--r--test-isblank.c7
-rw-r--r--test-mkdtemp.c12
-rw-r--r--test-vasprintf.c45
10 files changed, 247 insertions, 1 deletions
diff --git a/INSTALL b/INSTALL
index 2b0a8291..dc0f6b0e 100644
--- a/INSTALL
+++ b/INSTALL
@@ -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,
diff --git a/Makefile b/Makefile
index 4a802a12..9da02ead 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/configure b/configure
index 772f43e5..0a2fae40 100755
--- a/configure
+++ b/configure
@@ -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);
+}