summaryrefslogtreecommitdiff
path: root/features
diff options
context:
space:
mode:
Diffstat (limited to 'features')
-rw-r--r--features/_mkcfake.c3
-rw-r--r--features/err/err.c99
-rw-r--r--features/fgetln/fgetln.c70
-rw-r--r--features/mkc_err.h36
-rw-r--r--features/mkc_fgetln.h16
-rw-r--r--features/mkc_imp.f_RB.mk4
-rw-r--r--features/mkc_imp.f_SLIST.mk15
-rw-r--r--features/mkc_imp.f_err.mk29
-rw-r--r--features/mkc_imp.f_fgetln.mk13
-rw-r--r--features/mkc_imp.f_getline.mk4
-rw-r--r--features/mkc_imp.f_libdl.mk4
-rw-r--r--features/mkc_imp.f_libm.mk4
-rw-r--r--features/mkc_imp.f_progname.mk28
-rw-r--r--features/mkc_imp.f_strlcat.mk4
-rw-r--r--features/mkc_imp.f_strlcpy.mk4
-rw-r--r--features/mkc_imp.f_warn.mk29
-rw-r--r--features/mkc_progname.h26
-rw-r--r--features/mkc_warn.h36
-rw-r--r--features/progname/progname.c37
-rw-r--r--features/warn/warn.c95
20 files changed, 548 insertions, 8 deletions
diff --git a/features/_mkcfake.c b/features/_mkcfake.c
new file mode 100644
index 0000000..1afa530
--- /dev/null
+++ b/features/_mkcfake.c
@@ -0,0 +1,3 @@
+static void _mkcfake(void)
+{
+}
diff --git a/features/err/err.c b/features/err/err.c
new file mode 100644
index 0000000..411f810
--- /dev/null
+++ b/features/err/err.c
@@ -0,0 +1,99 @@
+/* $NetBSD: err.c,v 1.4 2004/08/23 03:32:12 jlam Exp $ */
+
+/*
+ * Copyright 1997-2000 Luke Mewburn <lukem@netbsd.org>.
+ * Copyright 2014 Aleksey Cheusov <vle@gmx.net>.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <mkc_progname.h>
+#include <mkc_err.h>
+
+#if !HAVE_FUNC3_ERR_ERR_H
+void err (int eval, const char *fmt, ...)
+{
+ va_list ap;
+ int sverrno;
+
+ sverrno = errno;
+ fprintf (stderr, "%s: ", getprogname ());
+ va_start (ap, fmt);
+ if (fmt != NULL) {
+ vfprintf (stderr, fmt, ap);
+ fprintf (stderr, ": ");
+ }
+ va_end (ap);
+ fprintf (stderr, "%s\n", strerror (sverrno));
+ exit (eval);
+}
+#endif
+
+#if !HAVE_FUNC3_ERRX_ERR_H
+void errx (int eval, const char *fmt, ...)
+{
+ va_list ap;
+
+ fprintf (stderr, "%s: ", getprogname ());
+ va_start (ap, fmt);
+ if (fmt != NULL)
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+ fprintf (stderr, "\n");
+ exit (eval);
+}
+#endif
+
+#if !HAVE_FUNC3_VERR_ERR_H
+void verr (int eval, const char *fmt, va_list ap)
+{
+ int sverrno;
+
+ sverrno = errno;
+ fprintf (stderr, "%s: ", getprogname ());
+ if (fmt != NULL) {
+ vfprintf (stderr, fmt, ap);
+ fprintf (stderr, ": ");
+ }
+ fprintf (stderr, "%s\n", strerror (sverrno));
+ exit (eval);
+}
+#endif
+
+#if !HAVE_FUNC3_VERRX_ERR_H
+void verrx (int eval, const char *fmt, va_list ap)
+{
+ fprintf (stderr, "%s: ", getprogname ());
+ if (fmt != NULL)
+ vfprintf (stderr, fmt, ap);
+ fprintf (stderr, "\n");
+ exit (eval);
+}
+#endif
diff --git a/features/fgetln/fgetln.c b/features/fgetln/fgetln.c
new file mode 100644
index 0000000..c600b06
--- /dev/null
+++ b/features/fgetln/fgetln.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2005 Hector Garcia Alvarez
+ * Copyright (c) 2005, 2008-2012 Guillem Jover <guillem@hadrons.org>
+ * Copyright (c) 2014 Aleksey Cheusov <vle@gmx.net>
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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 <string.h>
+
+#include <mkc_getline.h>
+#include <mkc_fgetln.h>
+
+struct filebuf {
+ FILE *fp;
+ char *buf;
+ size_t len;
+};
+
+#define FILEBUF_POOL_ITEMS 128
+
+static struct filebuf fb_pool [FILEBUF_POOL_ITEMS];
+static int fb_pool_cur;
+
+char * fgetln (FILE *stream, size_t *len)
+{
+ struct filebuf *fb;
+ ssize_t nread;
+
+ /* Try to diminish the possibility of several fgetln() calls being
+ * used on different streams, by using a pool of buffers per file. */
+ fb = &fb_pool [fb_pool_cur];
+ if (fb->fp != stream && fb->fp != NULL) {
+ fb_pool_cur++;
+ fb_pool_cur %= FILEBUF_POOL_ITEMS;
+ fb = &fb_pool [fb_pool_cur];
+ }
+ fb->fp = stream;
+
+ nread = getline (&fb->buf, &fb->len, stream);
+ /* Note: the getdelim/getline API ensures nread != 0. */
+ if (nread == -1) {
+ *len = 0;
+ return NULL;
+ } else {
+ *len = (size_t) nread;
+ return fb->buf;
+ }
+}
diff --git a/features/mkc_err.h b/features/mkc_err.h
new file mode 100644
index 0000000..16ee12f
--- /dev/null
+++ b/features/mkc_err.h
@@ -0,0 +1,36 @@
+/********************************************************************\
+ Copyright (c) 2014 by Aleksey Cheusov
+
+ See LICENSE file in the distribution.
+\********************************************************************/
+
+#ifndef _MKC_ERR_H_
+#define _MKC_ERR_H_
+
+#include <stdarg.h>
+
+#if HAVE_HEADER_ERR_H
+#include <err.h>
+#endif
+
+#ifdef MKC_ERR_IS_FINE
+
+#include <err.h>
+
+#else
+#if !HAVE_FUNC3_ERR_ERR_H
+void err (int, const char *, ...);
+#endif
+#if !HAVE_FUNC3_ERRX_ERR_H
+void errx (int, const char *, ...);
+#endif
+#if !HAVE_FUNC3_VERR_ERR_H
+void verr (int, const char *, va_list);
+#endif
+#if !HAVE_FUNC3_VERRX_ERR_H
+void verrx (int, const char *, va_list);
+#endif
+
+#endif /* MKC_ERR_IS_FINE */
+
+#endif // _MKC_ERR_H_
diff --git a/features/mkc_fgetln.h b/features/mkc_fgetln.h
new file mode 100644
index 0000000..4238478
--- /dev/null
+++ b/features/mkc_fgetln.h
@@ -0,0 +1,16 @@
+/********************************************************************\
+ Copyright (c) 2014 by Aleksey Cheusov
+
+ See LICENSE file in the distribution.
+\********************************************************************/
+
+#ifndef _MKC_FGETLN_H_
+#define _MKC_FGETLN_H_
+
+#include <stdio.h>
+
+#ifndef HAVE_FUNC3_FGETLN_STDIO_H
+char *fgetln (FILE *stream, size_t *len);
+#endif
+
+#endif // _MKC_FGETLN_H_
diff --git a/features/mkc_imp.f_RB.mk b/features/mkc_imp.f_RB.mk
index 57839ed..5661efd 100644
--- a/features/mkc_imp.f_RB.mk
+++ b/features/mkc_imp.f_RB.mk
@@ -2,6 +2,10 @@
#
# See LICENSE file in the distribution.
############################################################
+.ifndef _MKC_IMP_F_RB_MK
+_MKC_IMP_F_RB_MK := 1
MKC_CHECK_DEFINES += RB_ENTRY:sys/tree.h
MKC_CHECK_DEFINES += SPLAY_ENTRY:sys/tree.h
+
+.endif # _MKC_IMP_F_RB_MK
diff --git a/features/mkc_imp.f_SLIST.mk b/features/mkc_imp.f_SLIST.mk
index c00abc6..d5a1fc4 100644
--- a/features/mkc_imp.f_SLIST.mk
+++ b/features/mkc_imp.f_SLIST.mk
@@ -2,7 +2,10 @@
#
# See LICENSE file in the distribution.
############################################################
-.include <mkc.configure.mk>
+.ifndef _MKC_IMP_F_SYSQUEUE_MK
+_MKC_IMP_F_SYSQUEUE_MK := 1
+
+.include <mkc_imp.conf-cleanup.mk>
_macro = SLIST SIMPLEQ STAILQ LIST TAILQ TAILQ
@@ -11,10 +14,7 @@ MKC_CHECK_DEFINES += ${m}_ENTRY:sys/queue.h
_macro.${m} = 1
.endfor
-MKC_NOAUTO.orig := ${MKC_NOAUTO}
-MKC_NOAUTO = 1
-
-.include <mkc.configure.mk>
+.include <mkc_imp.conf-cleanup.mk>
.for f in ${MKC_FEATURES}
.if defined(_macro.${f}) && !${HAVE_DEFINE.${m}_ENTRY.sys/queue.h:U0}
@@ -30,8 +30,7 @@ CFLAGS+= -DMKC_SYS_QUEUE_IS_FINE=1
.undef _macro.${m}
.endfor
-MKC_NOAUTO := ${MKC_NOAUTO.orig}
-
.undef bad
.undef _macro
-.undef MKC_NOAUTO.orig
+
+.endif # _MKC_IMP_F_SYSQUEUE_MK
diff --git a/features/mkc_imp.f_err.mk b/features/mkc_imp.f_err.mk
new file mode 100644
index 0000000..d3b50e1
--- /dev/null
+++ b/features/mkc_imp.f_err.mk
@@ -0,0 +1,29 @@
+# Copyright (c) 2014 by Aleksey Cheusov
+#
+# See LICENSE file in the distribution.
+############################################################
+.ifndef _MKC_IMP_F_ERR_MK
+_MKC_IMP_F_ERR_MK := 1
+
+.include <mkc_imp.f_progname.mk>
+
+.include <mkc_imp.conf-cleanup.mk>
+
+MKC_CHECK_HEADERS += err.h
+MKC_CHECK_FUNCLIBS += err errx verr verrx
+MKC_CHECK_FUNCS3 += err:err.h errx:err.h verr:err.h verrx:err.h
+
+.include <mkc_imp.conf-cleanup.mk>
+
+.if ${HAVE_FUNCLIB.err:U0} && ${HAVE_FUNCLIB.errx:U0} && \
+ ${HAVE_FUNCLIB.verr:U0} && ${HAVE_FUNCLIB.verrx:U0} && \
+ ${HAVE_FUNC3.err.err_h:U0} && ${HAVE_FUNC3.errx.err_h:U0} && \
+ ${HAVE_FUNC3.verr.err_h:U0} && ${HAVE_FUNC3.verrx.err_h:U0}
+CFLAGS += -DMKC_ERR_IS_FINE
+.else
+MKC_SRCS += ${FEATURESDIR}/err/err.c
+.endif
+
+.include <mkc_imp.conf-final.mk>
+
+.endif #_MKC_IMP_F_ERR_MK
diff --git a/features/mkc_imp.f_fgetln.mk b/features/mkc_imp.f_fgetln.mk
new file mode 100644
index 0000000..07e408b
--- /dev/null
+++ b/features/mkc_imp.f_fgetln.mk
@@ -0,0 +1,13 @@
+# Copyright (c) 2014 by Aleksey Cheusov
+#
+# See LICENSE file in the distribution.
+.ifndef _MKC_IMP.F_FGETLN_MK
+_MKC_IMP.F_FGETLN_MK := 1
+
+.include <mkc_imp.f_getline.mk>
+
+MKC_SOURCE_FUNCLIBS += fgetln
+MKC_SOURCE_DIR.fgetln.c = ${FEATURESDIR}/fgetln
+MKC_CHECK_FUNCS3 += fgetln:stdio.h
+
+.endif # _MKC_IMP.F_FGETLN_MK
diff --git a/features/mkc_imp.f_getline.mk b/features/mkc_imp.f_getline.mk
index 50b3710..23dca91 100644
--- a/features/mkc_imp.f_getline.mk
+++ b/features/mkc_imp.f_getline.mk
@@ -1,7 +1,11 @@
# Copyright (c) 2014 by Aleksey Cheusov
#
# See LICENSE file in the distribution.
+.ifndef _MKC_IMP.F_GETLINE_MK
+_MKC_IMP.F_GETLINE_MK := 1
MKC_SOURCE_FUNCLIBS += getline
MKC_SOURCE_DIR.getline.c = ${FEATURESDIR}/getline
MKC_CHECK_FUNCS3 += getline:stdio.h
+
+.endif # _MKC_IMP.F_GETLINE_MK
diff --git a/features/mkc_imp.f_libdl.mk b/features/mkc_imp.f_libdl.mk
index 88833d9..fdee554 100644
--- a/features/mkc_imp.f_libdl.mk
+++ b/features/mkc_imp.f_libdl.mk
@@ -1,8 +1,12 @@
# Copyright (c) 2014 by Aleksey Cheusov
#
# See LICENSE file in the distribution.
+.ifndef _MKC_IMP_F_LIBDL_MK
+_MKC_IMP_F_LIBDL_MK := 1
MKC_COMMON_DEFINES += -D_GNU_SOURCE
MKC_REQUIRE_FUNCLIBS += dlopen:dl
MKC_REQUIRE_FUNCS2 += dlopen:dlfcn.h
+
+.endif # _MKC_IMP_F_LIBDL_MK
diff --git a/features/mkc_imp.f_libm.mk b/features/mkc_imp.f_libm.mk
index e7d9d0e..5134a02 100644
--- a/features/mkc_imp.f_libm.mk
+++ b/features/mkc_imp.f_libm.mk
@@ -1,5 +1,9 @@
# Copyright (c) 2014 by Aleksey Cheusov
#
# See LICENSE file in the distribution.
+.ifndef _MKC_IMP_F_LIBM_MK
+_MKC_IMP_F_LIBM_MK := 1
MKC_CHECK_FUNCLIBS += sqrt:m
+
+.endif #_MKC_IMP_F_LIBM_MK
diff --git a/features/mkc_imp.f_progname.mk b/features/mkc_imp.f_progname.mk
new file mode 100644
index 0000000..9df8119
--- /dev/null
+++ b/features/mkc_imp.f_progname.mk
@@ -0,0 +1,28 @@
+# Copyright (c) 2014 by Aleksey Cheusov
+#
+# See LICENSE file in the distribution.
+############################################################
+.ifndef _MKC_IMP.F_PROGNAME_MK
+_MKC_IMP.F_PROGNAME_MK := 1
+
+MKC_COMMON_DEFINES += -D_GNU_SOURCE
+
+MKC_CHECK_FUNCLIBS += getprogname setprogname
+MKC_CHECK_FUNCS0 += getprogname:stdlib.h getexecname:stdlib.h
+MKC_CHECK_FUNCS1 += setprogname:stdlib.h
+MKC_CHECK_VARS += program_invocation_short_name:errno.h
+
+.include <mkc_imp.conf-cleanup.mk>
+
+.if ${HAVE_FUNCLIB.getprogname:U0} && \
+ ${HAVE_FUNCLIB.setprogname:U0} && \
+ ${HAVE_FUNC0.getprogname.stdlib_h:U0} && \
+ ${HAVE_FUNC1.setprogname.stdlib_h:U0}
+CFLAGS += -DMKC_PROGNAME_IS_FINE
+.else
+MKC_SRCS += ${FEATURESDIR}/progname/progname.c
+.endif
+
+.include <mkc_imp.conf-final.mk>
+
+.endif # _MKC_IMP.F_PROGNAME_MK
diff --git a/features/mkc_imp.f_strlcat.mk b/features/mkc_imp.f_strlcat.mk
index 9f6afc5..5d7b35a 100644
--- a/features/mkc_imp.f_strlcat.mk
+++ b/features/mkc_imp.f_strlcat.mk
@@ -1,7 +1,11 @@
# Copyright (c) 2014 by Aleksey Cheusov
#
# See LICENSE file in the distribution.
+.ifndef _MKC_IMP_F_STRLCAT_MK
+_MKC_IMP_F_STRLCAT_MK := 1
MKC_SOURCE_FUNCLIBS += strlcat
MKC_SOURCE_DIR.strlcat.c = ${FEATURESDIR}/strlcat
MKC_CHECK_FUNCS3 += strlcat:string.h
+
+.endif # _MKC_IMP_F_STRLCAT_MK
diff --git a/features/mkc_imp.f_strlcpy.mk b/features/mkc_imp.f_strlcpy.mk
index 5c41db6..51759a2 100644
--- a/features/mkc_imp.f_strlcpy.mk
+++ b/features/mkc_imp.f_strlcpy.mk
@@ -1,7 +1,11 @@
# Copyright (c) 2014 by Aleksey Cheusov
#
# See LICENSE file in the distribution.
+.ifndef _MKC_IMP_F_STRLCPY_MK
+_MKC_IMP_F_STRLCPY_MK := 1
MKC_SOURCE_FUNCLIBS += strlcpy
MKC_SOURCE_DIR.strlcpy.c = ${FEATURESDIR}/strlcpy
MKC_CHECK_FUNCS3 += strlcpy:string.h
+
+.endif #_MKC_IMP_F_STRLCPY_MK
diff --git a/features/mkc_imp.f_warn.mk b/features/mkc_imp.f_warn.mk
new file mode 100644
index 0000000..c494d50
--- /dev/null
+++ b/features/mkc_imp.f_warn.mk
@@ -0,0 +1,29 @@
+# Copyright (c) 2014 by Aleksey Cheusov
+#
+# See LICENSE file in the distribution.
+############################################################
+.ifndef _MKC_IMP_F_WARN_MK
+_MKC_IMP_F_WARN_MK := 1
+
+.include <mkc_imp.f_progname.mk>
+
+.include <mkc_imp.conf-cleanup.mk>
+
+MKC_CHECK_HEADERS += err.h
+MKC_CHECK_FUNCLIBS += warn warnx vwarn vwarnx
+MKC_CHECK_FUNCS2 += warn:err.h warnx:err.h vwarn:err.h vwarnx:err.h
+
+.include <mkc_imp.conf-cleanup.mk>
+
+.if ${HAVE_FUNCLIB.warn:U0} && ${HAVE_FUNCLIB.warnx:U0} && \
+ ${HAVE_FUNCLIB.vwarn:U0} && ${HAVE_FUNCLIB.vwarnx:U0} && \
+ ${HAVE_FUNC2.warn.err_h:U0} && ${HAVE_FUNC2.warnx.err_h:U0} && \
+ ${HAVE_FUNC2.vwarn.err_h:U0} && ${HAVE_FUNC2.vwarnx.err_h:U0}
+CFLAGS += -DMKC_WARN_IS_FINE
+.else
+MKC_SRCS += ${FEATURESDIR}/warn/warn.c
+.endif
+
+.include <mkc_imp.conf-final.mk>
+
+.endif # _MKC_IMP_F_WARN_MK
diff --git a/features/mkc_progname.h b/features/mkc_progname.h
new file mode 100644
index 0000000..7925e60
--- /dev/null
+++ b/features/mkc_progname.h
@@ -0,0 +1,26 @@
+/********************************************************************\
+ Copyright (c) 2014 by Aleksey Cheusov
+
+ See LICENSE file in the distribution.
+\********************************************************************/
+
+#ifndef _MKC_PROGNAME_H_
+#define _MKC_PROGNAME_H_
+
+#ifdef MKC_PROGNAME_IS_FINE
+
+#include <stdlib.h>
+
+#else
+
+#if !HAVE_FUNC1_SETPROGNAME_STDLIB_H
+void setprogname (const char *progname);
+#endif
+
+#if !HAVE_FUNC0_GETPROGNAME_STDLIB_H
+const char * getprogname (void);
+#endif
+
+#endif /* MKC_PROGNAME_IS_FINE */
+
+#endif // _MKC_PROGNAME_H_
diff --git a/features/mkc_warn.h b/features/mkc_warn.h
new file mode 100644
index 0000000..3576032
--- /dev/null
+++ b/features/mkc_warn.h
@@ -0,0 +1,36 @@
+/********************************************************************\
+ Copyright (c) 2014 by Aleksey Cheusov
+
+ See LICENSE file in the distribution.
+\********************************************************************/
+
+#ifndef _MKC_WARN_H_
+#define _MKC_WARN_H_
+
+#include <stdarg.h>
+
+#if HAVE_HEADER_ERR_H
+#include <err.h>
+#endif
+
+#ifdef MKC_WARN_IS_FINE
+
+#include <err.h>
+
+#else
+#if !HAVE_FUNC2_WARN_ERR_H
+void warn (const char *, ...);
+#endif
+#if !HAVE_FUNC2_WARNX_ERR_H
+void warnx (const char *, ...);
+#endif
+#if !HAVE_FUNC2_VWARN_ERR_H
+void vwarn (const char *, va_list);
+#endif
+#if !HAVE_FUNC2_VWARNX_ERR_H
+void vwarnx (const char *, va_list);
+#endif
+
+#endif /* MKC_WARN_IS_FINE */
+
+#endif // _MKC_WARN_H_
diff --git a/features/progname/progname.c b/features/progname/progname.c
new file mode 100644
index 0000000..c025cfe
--- /dev/null
+++ b/features/progname/progname.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 by Aleksey Cheusov
+ * See LICENSE file in the distribution.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <mkc_progname.h>
+
+static const char *__prog = NULL;
+
+const char * getprogname (void)
+{
+ if (__prog)
+ return __prog;
+
+#ifdef HAVE_FUNC0_GETEXECNAME_STDLIB_H
+ /* SunOS */
+ setprogname (getexecname ());
+ return getprogname ();
+#elif defined(HAVE_VAR_PROGRAM_INVOCATION_SHORT_NAME_ERRNO_H)
+ return program_invocation_short_name;
+#else
+ return "<unset_progname>";
+#endif
+}
+
+void setprogname (const char *progname)
+{
+ const char *s = strrchr (progname, '/');
+ __prog = progname;
+
+ if (s)
+ __prog = s + 1;
+}
diff --git a/features/warn/warn.c b/features/warn/warn.c
new file mode 100644
index 0000000..8b39b48
--- /dev/null
+++ b/features/warn/warn.c
@@ -0,0 +1,95 @@
+/* $NetBSD: warn.c,v 1.4 2004/08/23 03:32:12 jlam Exp $ */
+
+/*
+ * Copyright 1997-2000 Luke Mewburn <lukem@netbsd.org>.
+ * Copyright 2014 Aleksey Cheusov <vle@gmx.net>.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <mkc_progname.h>
+#include <mkc_warn.h>
+
+#if !HAVE_FUNC2_WARN_ERR_H
+void warn (const char *fmt, ...)
+{
+ va_list ap;
+ int sverrno;
+
+ sverrno = errno;
+ fprintf (stderr, "%s: ", getprogname ());
+ va_start (ap, fmt);
+ if (fmt != NULL) {
+ vfprintf (stderr, fmt, ap);
+ fprintf (stderr, ": ");
+ }
+ va_end (ap);
+ fprintf (stderr, "%s\n", strerror (sverrno));
+}
+#endif
+
+#if !HAVE_FUNC2_WARNX_ERR_H
+void warnx (const char *fmt, ...)
+{
+ va_list ap;
+
+ fprintf (stderr, "%s: ", getprogname ());
+ va_start (ap, fmt);
+ if (fmt != NULL)
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+ fprintf (stderr, "\n");
+}
+#endif
+
+#if !HAVE_FUNC2_VWARN_ERR_H
+void vwarn (const char *fmt, va_list ap)
+{
+ int sverrno;
+
+ sverrno = errno;
+ fprintf (stderr, "%s: ", getprogname ());
+ if (fmt != NULL) {
+ vfprintf (stderr, fmt, ap);
+ fprintf (stderr, ": ");
+ }
+ fprintf (stderr, "%s\n", strerror (sverrno));
+}
+#endif
+
+#if !HAVE_FUNC2_VWARNX_ERR_H
+void vwarnx (const char *fmt, va_list ap)
+{
+ fprintf (stderr, "%s: ", getprogname ());
+ if (fmt != NULL)
+ vfprintf (stderr, fmt, ap);
+ fprintf (stderr, "\n");
+}
+#endif