changeset 348:7d7991f97acf

misc: be more barebone portable
author David Demelier <markand@malikania.fr>
date Tue, 19 Oct 2021 15:35:28 +0200
parents 0969931b98e4
children 99d9b6a7e3db
files CMakeLists.txt src/config.h.in src/libmlk-adventure/adventure/dialog/save.c src/libmlk-adventure/adventure/state/map.c src/libmlk-core/core/panic.h src/libmlk-core/core/sys.c src/libmlk-core/core/vfs-directory.c src/libmlk-core/core/vfs.c src/libmlk-core/core/zfile.c src/libmlk-port/CMakeLists.txt src/libmlk-port/port/basename.c src/libmlk-port/port/dirname.c src/libmlk-port/port/fmemopen.c src/libmlk-port/port/getopt.c src/libmlk-port/port/port.c src/libmlk-port/port/port.h src/libmlk-port/port/strlcat.c src/libmlk-port/port/strlcpy.c src/libmlk-rpg/rpg/map-file.c src/libmlk-rpg/rpg/save.c src/libmlk-rpg/rpg/tileset-file.c src/tools/bcc/main.c src/tools/map/main.c src/tools/tileset/main.c
diffstat 24 files changed, 522 insertions(+), 563 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Tue Oct 19 13:23:30 2021 +0200
+++ b/CMakeLists.txt	Tue Oct 19 15:35:28 2021 +0200
@@ -55,6 +55,12 @@
 find_package(SDL2 REQUIRED COMPONENTS image mixer ttf)
 find_package(Jansson REQUIRED)
 
+configure_file(
+	${molko_SOURCE_DIR}/src/config.h.in
+	${molko_BINARY_DIR}/src/config.h
+)
+include_directories(${molko_BINARY_DIR}/src)
+
 if (MLK_WITH_JS)
 	add_subdirectory(extern/libduktape)
 endif ()
@@ -106,3 +112,4 @@
 if (MLK_WITH_EXAMPLES)
 	add_subdirectory(examples)
 endif ()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/config.h.in	Tue Oct 19 15:35:28 2021 +0200
@@ -0,0 +1,30 @@
+/*
+ * config.h -- project configuration (from CMake)
+ *
+ * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or 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.
+ */
+
+#ifndef MLK_CONFIG_H
+#define MLK_CONFIG_H
+
+#cmakedefine MLK_WITH_NLS
+#cmakedefine MLK_WITH_ZSTD
+#cmakedefine MLK_WITH_JS
+
+#define MLK_PREFIX "@CMAKE_INSTALL_PREFIX@"
+#define MLK_BINDIR "@CMAKE_INSTALL_BINDIR@"
+#define MLK_DATADIR "@CMAKE_INSTaLL_DATADIR@"
+
+#endif /* !MLK_CONFIG_H */
--- a/src/libmlk-adventure/adventure/dialog/save.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-adventure/adventure/dialog/save.c	Tue Oct 19 15:35:28 2021 +0200
@@ -155,7 +155,7 @@
 	label.text = line;
 
 	/* TODO: Get map position. */
-	strlcpy(line, "World", sizeof (line));
+	port_strlcpy(line, "World", sizeof (line));
 	label_draw(&label);
 	
 	/* Last time. */
--- a/src/libmlk-adventure/adventure/state/map.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-adventure/adventure/state/map.c	Tue Oct 19 15:35:28 2021 +0200
@@ -135,7 +135,7 @@
 	self = alloc_new0(sizeof (*self));
 	self->origin_x = origin_x;
 	self->origin_y = origin_y;
-	strlcpy(self->name, name, sizeof (self->name));
+	port_strlcpy(self->name, name, sizeof (self->name));
 
 	self->state.data = self;
 	self->state.start = start;
--- a/src/libmlk-core/core/panic.h	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-core/core/panic.h	Tue Oct 19 15:35:28 2021 +0200
@@ -20,7 +20,6 @@
 #define MOLKO_CORE_PANIC_H
 
 #include <stdarg.h>
-#include <stdnoreturn.h>
 
 #include "core.h"
 
@@ -28,13 +27,13 @@
 
 CORE_BEGIN_DECLS
 
-noreturn void
+void
 panicf(const char *, ...);
 
-noreturn void
+void
 panicva(const char *, va_list);
 
-noreturn void
+void
 panic(void);
 
 CORE_END_DECLS
--- a/src/libmlk-core/core/sys.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-core/core/sys.c	Tue Oct 19 15:35:28 2021 +0200
@@ -27,8 +27,11 @@
 #if defined(_WIN32)
 #       include <shlwapi.h>
 #       include <windows.h>
+
+#       if !defined(S_ISDIR)
+#               define S_ISDIR(m) (m & _S_IFDIR)
+#       endif
 #else
-#       include <sys/stat.h>
 #       include <errno.h>
 #       include <string.h>
 #endif
@@ -102,7 +105,7 @@
 	/* Determine base executable path. */
 	if (!(base = SDL_GetBasePath())) {
 		if (absolute(whichdir))
-			strlcpy(ret, whichdir, sizeof (ret));
+			port_strlcpy(ret, whichdir, sizeof (ret));
 		else
 			snprintf(ret, sizeof (ret), "%s/%s", MLK_PREFIX, whichdir);
 	} else {
@@ -126,7 +129,7 @@
 		 *   from: /usr/local/bin
 		 *   to:   /usr/local
 		 */
-		strlcpy(path, base, sizeof (path));
+		port_strlcpy(path, base, sizeof (path));
 		SDL_free(base);
 
 		if ((binsect = strstr(path, MLK_BINDIR)))
@@ -148,10 +151,10 @@
 	char *pref;
 
 	if ((pref = SDL_GetPrefPath(info.organization, info.name))) {
-		strlcpy(path, pref, sizeof (path));
+		port_strlcpy(path, pref, sizeof (path));
 		SDL_free(pref);
 	} else
-		strlcpy(path, "./", sizeof (path));
+		port_strlcpy(path, "./", sizeof (path));
 
 	return path;
 }
@@ -174,7 +177,7 @@
 static inline void
 set_bindir(void)
 {
-	strlcpy(paths.bindir, system_directory(MLK_BINDIR), sizeof (paths.bindir));
+	port_strlcpy(paths.bindir, system_directory(MLK_BINDIR), sizeof (paths.bindir));
 }
 
 static void
@@ -192,11 +195,11 @@
 		snprintf(test, sizeof (test), "%ssrc/libmlk-data", base);
 
 		if (stat(test, &st) == 0 && S_ISDIR(st.st_mode)) {
-			strlcpy(paths.datadir, test, sizeof (paths.datadir));
+			port_strlcpy(paths.datadir, test, sizeof (paths.datadir));
 			normalize(paths.datadir);
 		}
 
-		free(base);
+		SDL_free(base);
 	}
 
 	/* Not found, use standard. */
@@ -208,7 +211,7 @@
 static inline void
 set_localedir(void)
 {
-	strlcpy(paths.localedir, system_directory(MLK_BINDIR), sizeof (paths.localedir));
+	port_strlcpy(paths.localedir, system_directory(MLK_BINDIR), sizeof (paths.localedir));
 }
 
 int
@@ -223,8 +226,8 @@
 	set_datadir();
 	set_localedir();
 
-	strlcpy(info.organization, organization, sizeof (info.organization));
-	strlcpy(info.name, name, sizeof (info.name));
+	port_strlcpy(info.organization, organization, sizeof (info.organization));
+	port_strlcpy(info.name, name, sizeof (info.name));
 
 	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
 		return errorf("%s", SDL_GetError());
@@ -263,7 +266,7 @@
 	char path[PATH_MAX], *p;
 
 	/* Copy the directory to normalize and iterate over '/'. */
-	strlcpy(path, directory, sizeof (path));
+	port_strlcpy(path, directory, sizeof (path));
 	normalize(path);
 
 #if defined(_WIN32)
--- a/src/libmlk-core/core/vfs-directory.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-core/core/vfs-directory.c	Tue Oct 19 15:35:28 2021 +0200
@@ -104,7 +104,7 @@
 	struct self *self;
 
 	self = alloc_new(sizeof (*self));
-	strlcpy(self->base, path, sizeof (self->base));
+	port_strlcpy(self->base, path, sizeof (self->base));
 
 	/* Remove terminator and switch to UNIX paths. */
 	normalize(self->base);
--- a/src/libmlk-core/core/vfs.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-core/core/vfs.c	Tue Oct 19 15:35:28 2021 +0200
@@ -19,6 +19,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 
 #include "buf.h"
--- a/src/libmlk-core/core/zfile.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-core/core/zfile.c	Tue Oct 19 15:35:28 2021 +0200
@@ -25,7 +25,10 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
+
+#if !defined(_WIN32)
+#       include <unistd.h>
+#endif
 
 /*
  * If not enabled, we still need to check if a file is in zstandard so we use
@@ -94,7 +97,7 @@
 		errno = EINVAL;
 		goto fail;
 	}
-	if (!(zf->fp = fmemopen(zf->data, datasz, "r")))
+	if (!(zf->fp = port_fmemopen(zf->data, datasz, "r")))
 		goto fail;
 
 	close(fd);
--- a/src/libmlk-port/CMakeLists.txt	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-port/CMakeLists.txt	Tue Oct 19 15:35:28 2021 +0200
@@ -18,49 +18,16 @@
 
 project(libmlk-port)
 
-include(CheckFunctionExists)
-include(CheckIncludeFile)
-include(CheckSymbolExists)
-include(CheckTypeSize)
-include(CheckLibraryExists)
-
-check_function_exists(strlcpy MLK_HAS_STRLCPY)
-check_function_exists(fmemopen MLK_HAS_FMEMOPEN)
-check_function_exists(basename MLK_HAS_BASENAME)
-check_function_exists(dirname MLK_HAS_DIRNAME)
-check_function_exists(getopt MLK_HAS_GETOPT)
-check_include_file(stdnoreturn.h MLK_HAS_STDNORETURN_H)
-check_include_file(libgen.h MLK_HAS_LIBGEN_H)
-check_include_file(unistd.h MLK_HAS_UNISTD_H)
-check_symbol_exists(PATH_MAX limits.h MLK_HAS_PATH_MAX)
-check_type_size(ssize_t MLK_HAS_SSIZE_T)
-check_library_exists(m fmin "" MLK_HAS_LIBM)
-
-if (NOT MLK_HAS_STDNORETURN_H)
-	file(WRITE ${CMAKE_BINARY_DIR}/stdnoreturn.h "#define noreturn\n")
-endif ()
-if (NOT MLK_HAS_LIBGEN_H)
-	file(TOUCH ${CMAKE_BINARY_DIR}/libgen.h)
-endif ()
-if (NOT MLK_HAS_UNISTD_H)
-	file(TOUCH ${CMAKE_BINARY_DIR}/unistd.h)
-endif ()
-
-configure_file(
-	${libmlk-port_SOURCE_DIR}/port/config.h.in
-	${libmlk-port_BINARY_DIR}/config.h
-)
-
 set(
 	SOURCES
-	${libmlk-port_SOURCE_DIR}/port/port.c
-	${libmlk-port_SOURCE_DIR}/port/port.h
+	${libmlk-port_SOURCE_DIR}/port/basename.c
+	${libmlk-port_SOURCE_DIR}/port/dirname.c
+	${libmlk-port_SOURCE_DIR}/port/fmemopen.c
+	${libmlk-port_SOURCE_DIR}/port/getopt.c
+	${libmlk-port_SOURCE_DIR}/port/strlcat.c
+	${libmlk-port_SOURCE_DIR}/port/strlcpy.c
 )
 
-if (MLK_HAS_LIBM)
-	list(APPEND LIBRARIES m)
-endif ()
-
 mlk_library(
 	NAME libmlk-port
 	SOURCES ${SOURCES}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libmlk-port/port/basename.c	Tue Oct 19 15:35:28 2021 +0200
@@ -0,0 +1,68 @@
+/*	$OpenBSD: basename.c,v 1.17 2020/10/20 19:30:14 naddy Exp $	*/
+
+/*
+ * Copyright (c) 1997, 2004 Todd C. Miller <millert@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 <errno.h>
+#include <limits.h>
+#include <string.h>
+
+#ifndef PATH_MAX
+#       define PATH_MAX 2048
+#endif
+
+char *
+port_basename(char *path)
+{
+	static char bname[PATH_MAX];
+	size_t len;
+	const char *endp, *startp;
+
+	/* Empty or NULL string gets treated as "." */
+	if (path == NULL || *path == '\0') {
+		bname[0] = '.';
+		bname[1] = '\0';
+		return (bname);
+	}
+
+	/* Strip any trailing slashes */
+	endp = path + strlen(path) - 1;
+	while (endp > path && *endp == '/')
+		endp--;
+
+	/* All slashes becomes "/" */
+	if (endp == path && *endp == '/') {
+		bname[0] = '/';
+		bname[1] = '\0';
+		return (bname);
+	}
+
+	/* Find the start of the base */
+	startp = endp;
+	while (startp > path && *(startp - 1) != '/')
+		startp--;
+
+	len = endp - startp + 1;
+	if (len >= sizeof(bname)) {
+#if defined(ENAMETOOLONG)
+		errno = ENAMETOOLONG;
+#endif
+		return (NULL);
+	}
+	memcpy(bname, startp, len);
+	bname[len] = '\0';
+	return (bname);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libmlk-port/port/dirname.c	Tue Oct 19 15:35:28 2021 +0200
@@ -0,0 +1,72 @@
+/*	$OpenBSD: dirname.c,v 1.17 2020/10/20 19:30:14 naddy Exp $	*/
+
+/*
+ * Copyright (c) 1997, 2004 Todd C. Miller <millert@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 <errno.h>
+#include <limits.h>
+#include <string.h>
+
+#ifndef PATH_MAX
+#       define PATH_MAX 2048
+#endif
+
+char *
+port_dirname(char *path)
+{
+	static char dname[PATH_MAX];
+	size_t len;
+	const char *endp;
+
+	/* Empty or NULL string gets treated as "." */
+	if (path == NULL || *path == '\0') {
+		dname[0] = '.';
+		dname[1] = '\0';
+		return (dname);
+	}
+
+	/* Strip any trailing slashes */
+	endp = path + strlen(path) - 1;
+	while (endp > path && *endp == '/')
+		endp--;
+
+	/* Find the start of the dir */
+	while (endp > path && *endp != '/')
+		endp--;
+
+	/* Either the dir is "/" or there are no slashes */
+	if (endp == path) {
+		dname[0] = *endp == '/' ? '/' : '.';
+		dname[1] = '\0';
+		return (dname);
+	} else {
+		/* Move forward past the separating slashes */
+		do {
+			endp--;
+		} while (endp > path && *endp == '/');
+	}
+
+	len = endp - path + 1;
+	if (len >= sizeof(dname)) {
+#if defined(ENAMETOOLONG)
+		errno = ENAMETOOLONG;
+#endif
+		return (NULL);
+	}
+	memcpy(dname, path, len);
+	dname[len] = '\0';
+	return (dname);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libmlk-port/port/fmemopen.c	Tue Oct 19 15:35:28 2021 +0200
@@ -0,0 +1,54 @@
+/*
+ * fmemopen.h -- fmemopen polyfill
+ *
+ * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or 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.
+ */
+
+#if defined(_WIN32)
+
+#include <stdio.h>
+#include <windows.h>
+
+FILE *
+port_fmemopen(void *buf, size_t size, const char *mode)
+{
+	char temppath[MAX_PATH + 1];
+	char filename[MAX_PATH + 1];
+	FILE *fp;
+
+	if (!GetTempPath(sizeof (temppath), temppath))
+		return NULL;
+	if (!GetTempFileName(temppath, "MLK", 0, filename))
+		return NULL;
+	if (!(fp = fopen(filename, "wb")))
+		return NULL;
+
+	fwrite(buf, size, 1, fp);
+	fclose(fp);
+
+	return fopen(filename, mode);
+}
+
+#else /* !_WIN32 */
+
+#include <stdio.h>
+
+FILE *
+port_fmemopen(void *buf, size_t len, const char *type)
+{
+	return fmemopen(buf, len, type);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libmlk-port/port/getopt.c	Tue Oct 19 15:35:28 2021 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1987, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int	port_opterr = 1,		/* if error message should be printed */
+	port_optind = 1,		/* index into parent argv vector */
+	port_optopt,			/* character checked for validity */
+	port_optreset;		/* reset getopt */
+char	*port_optarg;		/* argument associated with option */
+
+#define	BADCH	(int)'?'
+#define	BADARG	(int)':'
+#define	EMSG	""
+
+/*
+ * getopt --
+ *	Parse argc/argv argument vector.
+ */
+int
+port_getopt(int nargc, char * const *nargv, const char *ostr)
+{
+	static char *place = EMSG;		/* option letter processing */
+	char *oli;				/* option letter list index */
+
+	if (ostr == NULL)
+		return (-1);
+
+	if (port_optreset || !*place) {		/* update scanning pointer */
+		port_optreset = 0;
+		if (port_optind >= nargc || *(place = nargv[port_optind]) != '-') {
+			place = EMSG;
+			return (-1);
+		}
+		if (place[1] && *++place == '-') {	/* found "--" */
+			++port_optind;
+			place = EMSG;
+			return (-1);
+		}
+	}					/* option letter okay? */
+	if ((port_optopt = (int)*place++) == (int)':' ||
+	    !(oli = strchr(ostr, port_optopt))) {
+		/*
+		 * if the user didn't specify '-' as an option,
+		 * assume it means -1.
+		 */
+		if (port_optopt == (int)'-')
+			return (-1);
+		if (!*place)
+			++port_optind;
+		if (port_opterr && *ostr != ':')
+			(void)fprintf(stderr,
+			    "illegal option -- %c\n", port_optopt);
+		return (BADCH);
+	}
+	if (*++oli != ':') {			/* don't need argument */
+		port_optarg = NULL;
+		if (!*place)
+			++port_optind;
+	}
+	else {					/* need an argument */
+		if (*place)			/* no white space */
+			port_optarg = place;
+		else if (nargc <= ++port_optind) {	/* no arg */
+			place = EMSG;
+			if (*ostr == ':')
+				return (BADARG);
+			if (port_opterr)
+				(void)fprintf(stderr,
+				    "option requires an argument -- %c\n",
+				    port_optopt);
+			return (BADCH);
+		}
+		else				/* white space */
+			port_optarg = nargv[port_optind];
+		place = EMSG;
+		++port_optind;
+	}
+	return (port_optopt);			/* dump back option letter */
+}
--- a/src/libmlk-port/port/port.c	Tue Oct 19 13:23:30 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,414 +0,0 @@
-/*
- * port.c -- portability bits
- *
- * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or 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 <stdio.h>
-
-#include "port.h"
-
-int
-mlk_port_exists(void)
-{
-	/* ISO C forbids empty source file. */
-	return 1;
-}
-
-/* {{{ strlcpy (BSD extension, incoming in next POSIX). */
-
-#if !defined(MLK_HAS_STRLCPY)
-
-/*	$OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $	*/
-
-/*
- * Copyright (c) 1998, 2015 Todd C. Miller <millert@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.
- */
-
-/*
- * Copy string src to buffer dst of size dsize.  At most dsize-1
- * chars will be copied.  Always NUL terminates (unless dsize == 0).
- * Returns strlen(src); if retval >= dsize, truncation occurred.
- */
-size_t
-strlcpy(char *dst, const char *src, size_t dsize)
-{
-	const char *osrc = src;
-	size_t nleft = dsize;
-
-	/* Copy as many bytes as will fit. */
-	if (nleft != 0) {
-		while (--nleft != 0) {
-			if ((*dst++ = *src++) == '\0')
-				break;
-		}
-	}
-
-	/* Not enough room in dst, add NUL and traverse rest of src. */
-	if (nleft == 0) {
-		if (dsize != 0)
-			*dst = '\0';		/* NUL-terminate dst */
-		while (*src++)
-			;
-	}
-
-	return (src - osrc - 1);	/* count does not include NUL */
-}
-
-#endif /* !MLK_HAS_STRLCPY */
-
-/* }}} */
-
-/* {{{ fmemopen (POSIX). */
-
-#if !defined(MLK_HAS_FMEMOPEN)
-
-#if defined(_WIN32)
-
-/* https://github.com/Arryboom/fmemopen_windows */
-#include <stdio.h>
-#include <windows.h>
-#include <share.h>
-#include <io.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-FILE *
-fmemopen(void *buf, size_t len, const char *type)
-{
-	int fd;
-	FILE *fp;
-	char tp[MAX_PATH - 13];
-	char fn[MAX_PATH + 1];
-	int * pfd = &fd;
-	int retner = -1;
-	char tfname[] = "MemTF_";
-
-	if (!GetTempPathA(sizeof(tp), tp))
-		return NULL;
-	if (!GetTempFileNameA(tp, tfname, 0, fn))
-		return NULL;
-	retner = _sopen_s(pfd, fn, _O_CREAT | _O_SHORT_LIVED | _O_TEMPORARY | _O_RDWR | _O_BINARY | _O_NOINHERIT, _SH_DENYRW, _S_IREAD | _S_IWRITE);
-	if (retner != 0)
-		return NULL;
-	if (fd == -1)
-		return NULL;
-	fp = _fdopen(fd, "wb+");
-	if (!fp) {
-		_close(fd);
-		return NULL;
-	}
-
-	/*
-	 * File descriptors passed into _fdopen are owned by the returned FILE
-	 * stream.If _fdopen is successful, do not call _close on the file
-	 * descriptor. Calling fclose on the returned FILE * also closes the
-	 * file descriptor.
-	 */
-	fwrite(buf, len, 1, fp);
-	rewind(fp);
-
-	return fp;
-}
-
-#endif /* !_WIN32 */
-
-#endif /* !MLK_HAS_FMEMOPEN */
-
-/* }}} */
-
-/* {{{ basename (POSIX). */
-
-#if !defined(MLK_HAS_BASENAME)
-
-/*	$OpenBSD: basename.c,v 1.17 2020/10/20 19:30:14 naddy Exp $	*/
-
-/*
- * Copyright (c) 1997, 2004 Todd C. Miller <millert@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 <errno.h>
-#include <limits.h>
-#include <string.h>
-
-#ifndef PATH_MAX
-#       define PATH_MAX 2048
-#endif
-
-char *
-basename(char *path)
-{
-	static char bname[PATH_MAX];
-	size_t len;
-	const char *endp, *startp;
-
-	/* Empty or NULL string gets treated as "." */
-	if (path == NULL || *path == '\0') {
-		bname[0] = '.';
-		bname[1] = '\0';
-		return (bname);
-	}
-
-	/* Strip any trailing slashes */
-	endp = path + strlen(path) - 1;
-	while (endp > path && *endp == '/')
-		endp--;
-
-	/* All slashes becomes "/" */
-	if (endp == path && *endp == '/') {
-		bname[0] = '/';
-		bname[1] = '\0';
-		return (bname);
-	}
-
-	/* Find the start of the base */
-	startp = endp;
-	while (startp > path && *(startp - 1) != '/')
-		startp--;
-
-	len = endp - startp + 1;
-	if (len >= sizeof(bname)) {
-		errno = ENAMETOOLONG;
-		return (NULL);
-	}
-	memcpy(bname, startp, len);
-	bname[len] = '\0';
-	return (bname);
-}
-
-#endif /* !MLK_HAS_BASENAME */
-
-/* }}} */
-
-/* {{{ dirname (POSIX). */
-
-#if !defined(MLK_HAS_BASENAME)
-
-/*	$OpenBSD: dirname.c,v 1.17 2020/10/20 19:30:14 naddy Exp $	*/
-
-/*
- * Copyright (c) 1997, 2004 Todd C. Miller <millert@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 <errno.h>
-#include <limits.h>
-#include <string.h>
-
-#ifndef PATH_MAX
-#       define PATH_MAX 2048
-#endif
-
-char *
-dirname(char *path)
-{
-	static char dname[PATH_MAX];
-	size_t len;
-	const char *endp;
-
-	/* Empty or NULL string gets treated as "." */
-	if (path == NULL || *path == '\0') {
-		dname[0] = '.';
-		dname[1] = '\0';
-		return (dname);
-	}
-
-	/* Strip any trailing slashes */
-	endp = path + strlen(path) - 1;
-	while (endp > path && *endp == '/')
-		endp--;
-
-	/* Find the start of the dir */
-	while (endp > path && *endp != '/')
-		endp--;
-
-	/* Either the dir is "/" or there are no slashes */
-	if (endp == path) {
-		dname[0] = *endp == '/' ? '/' : '.';
-		dname[1] = '\0';
-		return (dname);
-	}
-	else {
-		/* Move forward past the separating slashes */
-		do {
-			endp--;
-		} while (endp > path && *endp == '/');
-	}
-
-	len = endp - path + 1;
-	if (len >= sizeof(dname)) {
-		errno = ENAMETOOLONG;
-		return (NULL);
-	}
-	memcpy(dname, path, len);
-	dname[len] = '\0';
-	return (dname);
-}
-
-#endif /* !MLK_HAS_DIRNAME */
-
-/* }}} */
-
-/* {{{ getopt (POSIX) */
-
-#if !defined(MLK_HAS_GETOPT)
-
-/*
- * Copyright (c) 1987, 1993, 1994
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int	opterr = 1,		/* if error message should be printed */
-	optind = 1,		/* index into parent argv vector */
-	optopt,			/* character checked for validity */
-	optreset;		/* reset getopt */
-char	*optarg;		/* argument associated with option */
-
-#define	BADCH	(int)'?'
-#define	BADARG	(int)':'
-#define	EMSG	""
-
-/*
- * getopt --
- *	Parse argc/argv argument vector.
- */
-int
-getopt(int nargc, char **nargv, const char *ostr)
-{
-	static char *place = EMSG;		/* option letter processing */
-	char *oli;				/* option letter list index */
-
-	if (ostr == NULL)
-		return (-1);
-
-	if (optreset || !*place) {		/* update scanning pointer */
-		optreset = 0;
-		if (optind >= nargc || *(place = nargv[optind]) != '-') {
-			place = EMSG;
-			return (-1);
-		}
-		if (place[1] && *++place == '-') {	/* found "--" */
-			++optind;
-			place = EMSG;
-			return (-1);
-		}
-	}					/* option letter okay? */
-	if ((optopt = (int)*place++) == (int)':' ||
-	    !(oli = strchr(ostr, optopt))) {
-		/*
-		 * if the user didn't specify '-' as an option,
-		 * assume it means -1.
-		 */
-		if (optopt == (int)'-')
-			return (-1);
-		if (!*place)
-			++optind;
-		if (opterr && *ostr != ':')
-			(void)fprintf(stderr,
-			    "illegal option -- %c\n", optopt);
-		return (BADCH);
-	}
-	if (*++oli != ':') {			/* don't need argument */
-		optarg = NULL;
-		if (!*place)
-			++optind;
-	}
-	else {					/* need an argument */
-		if (*place)			/* no white space */
-			optarg = place;
-		else if (nargc <= ++optind) {	/* no arg */
-			place = EMSG;
-			if (*ostr == ':')
-				return (BADARG);
-			if (opterr)
-				(void)fprintf(stderr,
-				    "option requires an argument -- %c\n",
-				    optopt);
-			return (BADCH);
-		}
-		else				/* white space */
-			optarg = nargv[optind];
-		place = EMSG;
-		++optind;
-	}
-	return (optopt);			/* dump back option letter */
-}
-
-#endif /* !MLK_HAS_GETOPT */
-
-/* }}} */
--- a/src/libmlk-port/port/port.h	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-port/port/port.h	Tue Oct 19 15:35:28 2021 +0200
@@ -19,80 +19,45 @@
 #ifndef MOLKO_PORT_H
 #define MOLKO_PORT_H
 
-#include "config.h"
-
-/* {{{ strlcpy (BSD extension, incoming in next POSIX). */
-
-#if !defined(MLK_HAS_STRLCPY)
-
-#include <stddef.h>
-
-size_t
-strlcpy(char *, const char *, size_t);
-
-#endif /* !MLK_HAS_STRLCPY */
-
-/* }}} */
-
-/* {{{ fmemopen (POSIX). */
-
-#if !defined(MLK_HAS_FMEMOPEN)
-
+#include <limits.h>
 #include <stdio.h>
 
-FILE *
-fmemopen(void *, size_t, const char *);
-
-#endif /* !MLK_HAS_FMEMOPEN */
-
-/* }}} */
-
-/* {{{ basename (POSIX). */
-
-#if !defined(MLK_HAS_BASENAME)
-
-char *
-basename(char *);
-
-#endif /* !MLK_HAS_BASENAME */
-
-/* }}} */
-
-/* {{{ dirname (POSIX). */
-
-#if !defined(MLK_HAS_BASENAME)
-
-char *
-dirname(char *);
-
-#endif /* !MLK_HAS_DIRNAME */
-
-/* }}} */
-
-/* {{{ getopt (POSIX) */
-
-#if !defined(MLK_HAS_GETOPT)
-
-extern int opterr;
-extern int optind;
-extern int optopt;
-extern char *optarg;
-
-int
-getopt(int, char **, const char *);
-
-#endif /* !MLK_HAS_GETOPT */
-
-/* }}} */
-
 /* PATH_MAX (defined in limits.h) (POSIX) */
-#if !defined(MLK_HAS_PATH_MAX)
+#if !defined(PATH_MAX)
 #       define PATH_MAX 2048
 #endif
 
-/* ssize_t (defined in sys/types.h) (POSIX) */
-#if !defined(MLK_HAS_SSIZE_T)
+/* (POSIX) */
+#if defined(_WIN32)
 typedef long long int ssize_t;
 #endif
 
+/* OpenBSD extension (in next POSIX version). */
+size_t
+port_strlcpy(char *, const char *, size_t);
+
+/* Same as strlcpy. */
+size_t
+port_strlcat(char *, const char *, size_t);
+
+/* POSIX. */
+FILE *
+port_fmemopen(void *, size_t, const char *);
+
+/* POSIX. */
+char *
+port_basename(char *);
+
+/* POSIX. */
+char *
+port_dirname(char *);
+
+extern int port_opterr;
+extern int port_optind;
+extern int port_optopt;
+extern char *port_optarg;
+
+int
+port_getopt(int, char **, const char *);
+
 #endif /* !MOLKO_PORT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libmlk-port/port/strlcat.c	Tue Oct 19 15:35:28 2021 +0200
@@ -0,0 +1,55 @@
+/*	$OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $	*/
+
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <millert@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 <stddef.h>
+#include <string.h>
+
+/*
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left).  At most dsize-1 characters
+ * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
+ */
+size_t
+port_strlcat(char *dst, const char *src, size_t dsize)
+{
+	const char *odst = dst;
+	const char *osrc = src;
+	size_t n = dsize;
+	size_t dlen;
+
+	/* Find the end of dst and adjust bytes left but don't go past end. */
+	while (n-- != 0 && *dst != '\0')
+		dst++;
+	dlen = dst - odst;
+	n = dsize - dlen;
+
+	if (n-- == 0)
+		return(dlen + strlen(src));
+	while (*src != '\0') {
+		if (n != 0) {
+			*dst++ = *src;
+			n--;
+		}
+		src++;
+	}
+	*dst = '\0';
+
+	return(dlen + (src - osrc));	/* count does not include NUL */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libmlk-port/port/strlcpy.c	Tue Oct 19 15:35:28 2021 +0200
@@ -0,0 +1,49 @@
+/*	$OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $	*/
+
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <millert@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 <stddef.h>
+
+/*
+ * Copy string src to buffer dst of size dsize.  At most dsize-1
+ * chars will be copied.  Always NUL terminates (unless dsize == 0).
+ * Returns strlen(src); if retval >= dsize, truncation occurred.
+ */
+size_t
+port_strlcpy(char *dst, const char *src, size_t dsize)
+{
+	const char *osrc = src;
+	size_t nleft = dsize;
+
+	/* Copy as many bytes as will fit. */
+	if (nleft != 0) {
+		while (--nleft != 0) {
+			if ((*dst++ = *src++) == '\0')
+				break;
+		}
+	}
+
+	/* Not enough room in dst, add NUL and traverse rest of src. */
+	if (nleft == 0) {
+		if (dsize != 0)
+			*dst = '\0';		/* NUL-terminate dst */
+		while (*src++)
+			;
+	}
+
+	return(src - osrc - 1);	/* count does not include NUL */
+}
--- a/src/libmlk-rpg/rpg/map-file.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-rpg/rpg/map-file.c	Tue Oct 19 15:35:28 2021 +0200
@@ -18,7 +18,6 @@
 
 #include <assert.h>
 #include <errno.h>
-#include <libgen.h>
 #include <limits.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -226,8 +225,8 @@
 	char line[1024];
 	char basedir[PATH_MAX];
 
-	strlcpy(basedir, path, sizeof (basedir));
-	strlcpy(ctx->basedir, dirname(basedir), sizeof (ctx->basedir));
+	port_strlcpy(basedir, path, sizeof (basedir));
+	port_strlcpy(ctx->basedir, port_dirname(basedir), sizeof (ctx->basedir));
 
 	while (fgets(line, sizeof (line), ctx->fp)) {
 		/* Remove \n if any */
--- a/src/libmlk-rpg/rpg/save.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-rpg/rpg/save.c	Tue Oct 19 15:35:28 2021 +0200
@@ -140,7 +140,7 @@
 			char *str = va_arg(ap, char *);
 			size_t max = va_arg(ap, size_t);
 
-			strlcpy(str, (const char *)sqlite3_column_text(stmt->handle, c++), max);
+			port_strlcpy(str, (const char *)sqlite3_column_text(stmt->handle, c++), max);
 			break;
 		}
 		case 't':
--- a/src/libmlk-rpg/rpg/tileset-file.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/libmlk-rpg/rpg/tileset-file.c	Tue Oct 19 15:35:28 2021 +0200
@@ -18,7 +18,6 @@
 
 #include <assert.h>
 #include <errno.h>
-#include <libgen.h>
 #include <limits.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -279,8 +278,8 @@
 	char line[1024];
 	char basedir[PATH_MAX];
 
-	strlcpy(basedir, path, sizeof (basedir));
-	strlcpy(ctx->basedir, dirname(basedir), sizeof (ctx->basedir));
+	port_strlcpy(basedir, path, sizeof (basedir));
+	port_strlcpy(ctx->basedir, port_dirname(basedir), sizeof (ctx->basedir));
 
 	while (fgets(line, sizeof (line), ctx->fp)) {
 		/* Remove \n if any */
--- a/src/tools/bcc/main.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/tools/bcc/main.c	Tue Oct 19 15:35:28 2021 +0200
@@ -21,9 +21,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdnoreturn.h>
 #include <string.h>
-#include <unistd.h>
 
 #include <port/port.h>
 
@@ -35,14 +33,14 @@
 static bool fstatic;
 static bool funsigned;
 
-noreturn static void
+static void
 usage(void)
 {
 	fprintf(stderr, "usage: bcc [-0csu] [-I tab-indent] [-i space-indent] input variable\n");
 	exit(1);
 }
 
-noreturn static void
+static void
 die(const char *fmt, ...)
 {
 	va_list ap;
@@ -141,7 +139,7 @@
 {
 	int ch;
 
-	while ((ch = getopt(argc, argv, "0cI:i:su")) != -1) {
+	while ((ch = port_getopt(argc, argv, "0cI:i:su")) != -1) {
 		switch (ch) {
 		case '0':
 			fnull = true;
@@ -151,11 +149,11 @@
 			break;
 		case 'I':
 			findentchar = '\t';
-			findent = atoi(optarg);
+			findent = atoi(port_optarg);
 			break;
 		case 'i':
 			findentchar = ' ';
-			findent = atoi(optarg);
+			findent = atoi(port_optarg);
 			break;
 		case 's':
 			fstatic = true;
@@ -168,8 +166,8 @@
 		}
 	}
 
-	argc -= optind;
-	argv += optind;
+	argc -= port_optind;
+	argv += port_optind;
 
 	if (argc < 2)
 		usage();
--- a/src/tools/map/main.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/tools/map/main.c	Tue Oct 19 15:35:28 2021 +0200
@@ -16,15 +16,12 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define _XOPEN_SOURCE 700
 #include <assert.h>
-#include <libgen.h>
 #include <limits.h>
 #include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdnoreturn.h>
 #include <string.h>
 
 #include <jansson.h>
@@ -230,7 +227,7 @@
 
 	/* We need to replace the .json extension to .tileset. */
 	snprintf(path, sizeof (path), "%s", json_string_value(source));
-	snprintf(filename, sizeof (filename), "%s", basename(path));
+	snprintf(filename, sizeof (filename), "%s", port_basename(path));
 
 	if (!(ext = strstr(filename, ".json")))
 		die("could not determine tileset extension");
--- a/src/tools/tileset/main.c	Tue Oct 19 13:23:30 2021 +0200
+++ b/src/tools/tileset/main.c	Tue Oct 19 15:35:28 2021 +0200
@@ -19,12 +19,11 @@
 #include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
-#include <stdnoreturn.h>
 #include <string.h>
 
 #include <jansson.h>
 
-static noreturn void
+static void
 die(const char *fmt, ...)
 {
 	assert(fmt);