From 4420659effaee63e1a814e5aae1350f1924731ab Mon Sep 17 00:00:00 2001
From: Ben Longbons <b.r.longbons@gmail.com>
Date: Fri, 15 Nov 2013 21:52:11 -0800
Subject: Another step towards proper header ordering

---
 src/admin/ladmin.cpp                 |   2 +-
 src/char/char.cpp                    |   2 +-
 src/char/int_party.cpp               |   2 +-
 src/char/int_storage.cpp             |   2 +-
 src/char/inter.cpp                   |   2 +-
 src/common/const_array.hpp           |   2 +-
 src/common/core.hpp                  |   2 +-
 src/common/cxxstdio.hpp              | 263 ----------------------------------
 src/common/cxxstdio_test.cpp         |   3 -
 src/common/db.hpp                    |   2 +-
 src/common/dumb_ptr.hpp              |   2 +-
 src/common/extract.hpp               |   2 +-
 src/common/human_time_diff.hpp       |   2 +-
 src/common/ip.cpp                    |   2 +-
 src/common/ip.hpp                    |   2 +-
 src/common/ip_test.cpp               |   2 +-
 src/common/md5calc.cpp               |   2 +-
 src/common/md5calc.hpp               |   2 +-
 src/common/mmo.hpp                   |   2 +-
 src/common/nullpo.hpp                |   2 +-
 src/common/random.hpp                |   2 +-
 src/common/sanity.hpp                |  34 -----
 src/common/socket.cpp                |   2 +-
 src/common/socket.hpp                |   2 +-
 src/common/timer.cpp                 |   3 +-
 src/common/timer.hpp                 |   2 +-
 src/common/utils.cpp                 |   2 +-
 src/common/utils.hpp                 |   2 +-
 src/common/utils2.hpp                |   2 +-
 src/io/cxxstdio.cpp                  |   1 +
 src/io/cxxstdio.hpp                  | 264 +++++++++++++++++++++++++++++++++++
 src/io/fwd.hpp                       |   2 +-
 src/io/lock.cpp                      |   3 +-
 src/io/read.cpp                      |   2 +-
 src/io/read.hpp                      |   2 +-
 src/io/write.hpp                     |   2 +-
 src/login/login.cpp                  |   2 +-
 src/map/atcommand.cpp                |   2 +-
 src/map/battle.cpp                   |   2 +-
 src/map/chrif.cpp                    |   3 +-
 src/map/clif.cpp                     |   2 +-
 src/map/grfio.cpp                    |   2 +-
 src/map/intif.cpp                    |   3 +-
 src/map/itemdb.cpp                   |   2 +-
 src/map/magic-expr.cpp               |   3 +-
 src/map/magic-interpreter-base.cpp   |   3 +-
 src/map/magic-interpreter-lexer.lpp  |   2 +-
 src/map/magic-interpreter-parser.ypp |   3 +-
 src/map/magic-stmt.cpp               |   3 +-
 src/map/magic.cpp                    |   2 +-
 src/map/map.cpp                      |   2 +-
 src/map/map.hpp                      |   3 +-
 src/map/mob.cpp                      |   2 +-
 src/map/npc.cpp                      |   2 +-
 src/map/party.cpp                    |   3 +-
 src/map/path.cpp                     |   3 +-
 src/map/pc.cpp                       |   2 +-
 src/map/script.cpp                   |   2 +-
 src/map/skill-pools.cpp              |   2 +-
 src/map/skill.cpp                    |   2 +-
 src/map/tmw.cpp                      |   3 +-
 src/map/trade.cpp                    |   3 +-
 src/monitor/main.cpp                 |   2 +-
 src/sanity.hpp                       |  34 +++++
 src/strings/fwd.hpp                  |   2 +-
 src/strings/pair.hpp                 |   2 +-
 66 files changed, 371 insertions(+), 361 deletions(-)
 delete mode 100644 src/common/cxxstdio.hpp
 delete mode 100644 src/common/cxxstdio_test.cpp
 delete mode 100644 src/common/sanity.hpp
 create mode 100644 src/io/cxxstdio.cpp
 create mode 100644 src/io/cxxstdio.hpp
 create mode 100644 src/sanity.hpp

diff --git a/src/admin/ladmin.cpp b/src/admin/ladmin.cpp
index 023aeae..d41b74d 100644
--- a/src/admin/ladmin.cpp
+++ b/src/admin/ladmin.cpp
@@ -11,11 +11,11 @@
 #include "../strings/xstring.hpp"
 #include "../strings/vstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 #include "../io/write.hpp"
 
 #include "../common/core.hpp"
-#include "../common/cxxstdio.hpp"
 #include "../common/human_time_diff.hpp"
 #include "../common/md5calc.hpp"
 #include "../common/mmo.hpp"
diff --git a/src/char/char.cpp b/src/char/char.cpp
index a3b1a27..5c5179d 100644
--- a/src/char/char.cpp
+++ b/src/char/char.cpp
@@ -20,11 +20,11 @@
 #include "../strings/zstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/lock.hpp"
 #include "../io/read.hpp"
 
 #include "../common/core.hpp"
-#include "../common/cxxstdio.hpp"
 #include "../common/db.hpp"
 #include "../common/extract.hpp"
 #include "../common/human_time_diff.hpp"
diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp
index 41aa9c3..2972689 100644
--- a/src/char/int_party.cpp
+++ b/src/char/int_party.cpp
@@ -7,10 +7,10 @@
 #include "../strings/fstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/lock.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/db.hpp"
 #include "../common/extract.hpp"
 #include "../common/mmo.hpp"
diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp
index 304a792..4e52215 100644
--- a/src/char/int_storage.cpp
+++ b/src/char/int_storage.cpp
@@ -9,10 +9,10 @@
 #include "../strings/fstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/lock.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/db.hpp"
 #include "../common/extract.hpp"
 #include "../common/mmo.hpp"
diff --git a/src/char/inter.cpp b/src/char/inter.cpp
index 330ea66..38e6194 100644
--- a/src/char/inter.cpp
+++ b/src/char/inter.cpp
@@ -11,10 +11,10 @@
 #include "../strings/zstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/lock.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/db.hpp"
 #include "../common/extract.hpp"
 #include "../common/socket.hpp"
diff --git a/src/common/const_array.hpp b/src/common/const_array.hpp
index 314eccf..383a4e2 100644
--- a/src/common/const_array.hpp
+++ b/src/common/const_array.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "sanity.hpp"
+#include "../sanity.hpp"
 
 #include <cstring>
 
diff --git a/src/common/core.hpp b/src/common/core.hpp
index 1cbd0c2..11b04fd 100644
--- a/src/common/core.hpp
+++ b/src/common/core.hpp
@@ -1,7 +1,7 @@
 #ifndef CORE_HPP
 #define CORE_HPP
 
-#include "sanity.hpp"
+#include "../sanity.hpp"
 
 #include "../strings/fwd.hpp"
 
diff --git a/src/common/cxxstdio.hpp b/src/common/cxxstdio.hpp
deleted file mode 100644
index 1ae1be3..0000000
--- a/src/common/cxxstdio.hpp
+++ /dev/null
@@ -1,263 +0,0 @@
-#ifndef CXXSTDIO_HPP
-#define CXXSTDIO_HPP
-//    cxxstdio.hpp - pass C++ types through scanf/printf
-//
-//    Copyright © 2011-2013 Ben Longbons <b.r.longbons@gmail.com>
-//
-//    This file is part of The Mana World (Athena server)
-//
-//    This program is free software: you can redistribute it and/or modify
-//    it under the terms of the GNU General Public License as published by
-//    the Free Software Foundation, either version 3 of the License, or
-//    (at your option) any later version.
-//
-//    This program 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 General Public License for more details.
-//
-//    You should have received a copy of the GNU General Public License
-//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-#include "sanity.hpp"
-
-#include <cstdarg>
-#include <cstdio>
-
-#include "../io/fwd.hpp"
-
-#include "const_array.hpp"
-#include "utils2.hpp"
-
-
-namespace cxxstdio
-{
-    // other implementations of do_vprint or do_vscan are injected by ADL.
-    inline __attribute__((format(printf, 2, 0)))
-    int do_vprint(FILE *out, const char *fmt, va_list ap)
-    {
-        return vfprintf(out, fmt, ap);
-    }
-
-    inline __attribute__((format(scanf, 2, 0)))
-    int do_vscan(FILE *in, const char *fmt, va_list ap)
-    {
-        return vfscanf(in, fmt, ap);
-    }
-
-#if 0
-    inline __attribute__((format(scanf, 2, 0)))
-    int do_vscan(const char *in, const char *fmt, va_list ap)
-    {
-        return vsscanf(in, fmt, ap);
-    }
-#else
-    inline
-    int do_vscan(const char *, const char *, va_list) = delete;
-#endif
-
-    template<class T>
-    inline __attribute__((format(printf, 2, 3)))
-    int do_print(T&& t, const char *fmt, ...) throw()
-    {
-        int rv;
-        va_list ap;
-        va_start(ap, fmt);
-        rv = do_vprint(std::forward<T>(t), fmt, ap);
-        va_end(ap);
-        return rv;
-    }
-
-    template<class T>
-    inline __attribute__((format(scanf, 2, 3)))
-    int do_scan(T&& t, const char *fmt, ...) throw()
-    {
-        int rv;
-        va_list ap;
-        va_start(ap, fmt);
-        rv = do_vscan(std::forward<T>(t), fmt, ap);
-        va_end(ap);
-        return rv;
-    }
-
-
-    template<class T, typename=typename std::enable_if<!std::is_class<T>::value>::type>
-    typename remove_enum<T>::type decay_for_printf(T v)
-    {
-        typedef typename remove_enum<T>::type repr_type;
-        return repr_type(v);
-    }
-
-    template<class T, typename=decltype(decay_for_printf(std::declval<T&&>()))>
-    T&& convert_for_printf(T&& v)
-    {
-        return std::forward<T>(v);
-    }
-
-    template<class T, typename = typename std::enable_if<!std::is_enum<T>::value>::type>
-    T& convert_for_scanf(T& v)
-    {
-        return v;
-    }
-
-#if 0
-    template<class E>
-    constexpr
-    E get_enum_min_value(decltype(E::min_value))
-    {
-        return E::min_value;
-    }
-    template<class E>
-    constexpr
-    E get_enum_min_value(E def)
-    {
-        return def;
-    }
-
-    template<class E>
-    constexpr
-    E get_enum_max_value(decltype(E::max_value))
-    {
-        return E::max_value;
-    }
-    template<class E>
-    constexpr
-    E get_enum_max_value(E def)
-    {
-        return def;
-    }
-#else
-    template<class E>
-    constexpr
-    E get_enum_min_value(E)
-    {
-        return E::min_value;
-    }
-    template<class E>
-    constexpr
-    E get_enum_max_value(E)
-    {
-        return E::max_value;
-    }
-#endif
-
-    template<class E>
-    class EnumConverter
-    {
-        E& out;
-        typedef typename underlying_type<E>::type U;
-#if 0
-        constexpr static
-        U min_value = U(get_enum_min_value<E>(E(std::numeric_limits<U>::min())));
-        constexpr static
-        U max_value = U(get_enum_max_value<E>(E(std::numeric_limits<U>::max())));
-#else
-        constexpr static
-        U min_value = U(get_enum_min_value(E()));
-        constexpr static
-        U max_value = U(get_enum_max_value(E()));
-#endif
-        U mid;
-    public:
-        EnumConverter(E& e)
-        : out(e), mid(0)
-        {}
-        ~EnumConverter()
-        {
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wtype-limits"
-            if (min_value <= mid && mid <= max_value)
-#pragma GCC diagnostic pop
-                out = E(mid);
-        }
-        U *operator &()
-        {
-            return &mid;
-        }
-    };
-
-    template<class T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
-    EnumConverter<T> convert_for_scanf(T& v)
-    {
-        return v;
-    }
-
-    template<class Format>
-    class PrintFormatter
-    {
-    public:
-        template<class T, class... A>
-        static
-        int print(T&& t, A&&... a)
-        {
-            constexpr static
-            const char *print_format = Format::print_format();
-            return do_print(std::forward<T>(t), print_format,
-                    decay_for_printf(convert_for_printf(std::forward<A>(a)))...);
-        }
-    };
-
-    template<class Format>
-    class ScanFormatter
-    {
-    public:
-        template<class T, class... A>
-        static
-        int scan(T&& t, A&&... a)
-        {
-            constexpr static
-            const char *scan_format = Format::scan_format();
-            return do_scan(std::forward<T>(t), scan_format,
-                    &convert_for_scanf(*a)...);
-        }
-    };
-
-#define XPRINTF(out, fmt, ...)                                      \
-    (/*[&]() -> int*/                                                   \
-    {                                                               \
-        struct format_impl                                          \
-        {                                                           \
-            constexpr static                                        \
-            const char *print_format() { return fmt; }              \
-        };                                                          \
-        /*return*/ cxxstdio::PrintFormatter<format_impl>::print(out, ## __VA_ARGS__);   \
-    }/*()*/)
-
-#define XSCANF(out, fmt, ...)                                   \
-    (/*[&]() -> int*/                                               \
-    {                                                           \
-        struct format_impl                                      \
-        {                                                       \
-            constexpr static                                    \
-            const char *scan_format() { return fmt; }           \
-        };                                                      \
-        /*return*/ cxxstdio::ScanFormatter<format_impl>::scan(out, ## __VA_ARGS__);     \
-    }/*()*/)
-
-#define FPRINTF(file, fmt, ...)     XPRINTF(/*no_cast<FILE *>*/(file), fmt, ## __VA_ARGS__)
-#define FSCANF(file, fmt, ...)      XSCANF(no_cast<FILE *>(file), fmt, ## __VA_ARGS__)
-#define PRINTF(fmt, ...)            FPRINTF(stdout, fmt, ## __VA_ARGS__)
-#define SPRINTF(str, fmt, ...)      XPRINTF(base_cast<FString&>(str), fmt, ## __VA_ARGS__)
-#define SNPRINTF(str, n, fmt, ...)  XPRINTF(base_cast<VString<n-1>&>(str), fmt, ## __VA_ARGS__)
-#define SCANF(fmt, ...)             FSCANF(stdin, fmt, ## __VA_ARGS__)
-#define SSCANF(str, fmt, ...)       XSCANF(/*ZString or compatible*/str, fmt, ## __VA_ARGS__)
-
-#define STRPRINTF(fmt, ...)                     \
-    (/*[&]() -> FString*/                           \
-    {                                           \
-        FString _out_impl;                      \
-        SPRINTF(_out_impl, fmt, ## __VA_ARGS__);\
-        /*return*/ _out_impl;                       \
-    }/*()*/)
-
-#define STRNPRINTF(n, fmt, ...)                     \
-    (/*[&]() -> VString<n - 1>*/                        \
-    {                                               \
-        VString<n - 1> _out_impl;                   \
-        SNPRINTF(_out_impl, n, fmt, ## __VA_ARGS__);\
-        /*return*/ _out_impl;                           \
-    }/*()*/)
-
-} // namespace cxxstdio
-
-#endif // CXXSTDIO_HPP
diff --git a/src/common/cxxstdio_test.cpp b/src/common/cxxstdio_test.cpp
deleted file mode 100644
index 9b6eeb2..0000000
--- a/src/common/cxxstdio_test.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "cxxstdio.hpp"
-
-#include <gtest/gtest.h>
diff --git a/src/common/db.hpp b/src/common/db.hpp
index 927db22..0384f1c 100644
--- a/src/common/db.hpp
+++ b/src/common/db.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-# include "sanity.hpp"
+# include "../sanity.hpp"
 
 # include <map>
 # include <memory>
diff --git a/src/common/dumb_ptr.hpp b/src/common/dumb_ptr.hpp
index bcc9dda..1dba39d 100644
--- a/src/common/dumb_ptr.hpp
+++ b/src/common/dumb_ptr.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "sanity.hpp"
+#include "../sanity.hpp"
 
 #include <cstring>
 
diff --git a/src/common/extract.hpp b/src/common/extract.hpp
index dd0a8a3..4f90be4 100644
--- a/src/common/extract.hpp
+++ b/src/common/extract.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "sanity.hpp"
+#include "../sanity.hpp"
 
 #include <algorithm>
 
diff --git a/src/common/human_time_diff.hpp b/src/common/human_time_diff.hpp
index a937316..b8754b2 100644
--- a/src/common/human_time_diff.hpp
+++ b/src/common/human_time_diff.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "sanity.hpp"
+#include "../sanity.hpp"
 
 #include "../strings/xstring.hpp"
 
diff --git a/src/common/ip.cpp b/src/common/ip.cpp
index a1fdfda..146734a 100644
--- a/src/common/ip.cpp
+++ b/src/common/ip.cpp
@@ -21,7 +21,7 @@
 #include "../strings/xstring.hpp"
 #include "../strings/vstring.hpp"
 
-#include "cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
 
 #include "../poison.hpp"
 
diff --git a/src/common/ip.hpp b/src/common/ip.hpp
index cce6c2b..7e645bb 100644
--- a/src/common/ip.hpp
+++ b/src/common/ip.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "sanity.hpp"
+#include "../sanity.hpp"
 
 #include <netinet/in.h>
 
diff --git a/src/common/ip_test.cpp b/src/common/ip_test.cpp
index 64a537f..7ef1047 100644
--- a/src/common/ip_test.cpp
+++ b/src/common/ip_test.cpp
@@ -2,7 +2,7 @@
 
 #include <gtest/gtest.h>
 
-#include "cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
 
 #define CB(X) (std::integral_constant<bool, (X)>::value)
 TEST(ip4addr, cmp)
diff --git a/src/common/md5calc.cpp b/src/common/md5calc.cpp
index 70b0e1f..8d650fa 100644
--- a/src/common/md5calc.cpp
+++ b/src/common/md5calc.cpp
@@ -5,9 +5,9 @@
 #include "../strings/xstring.hpp"
 #include "../strings/vstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 
-#include "cxxstdio.hpp"
 #include "random.hpp"
 #include "utils.hpp"
 
diff --git a/src/common/md5calc.hpp b/src/common/md5calc.hpp
index 205c21a..479c1a9 100644
--- a/src/common/md5calc.hpp
+++ b/src/common/md5calc.hpp
@@ -1,7 +1,7 @@
 #ifndef MD5CALC_HPP
 #define MD5CALC_HPP
 
-#include "sanity.hpp"
+#include "../sanity.hpp"
 
 #include <netinet/in.h>
 
diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp
index cfc7b78..0f89c81 100644
--- a/src/common/mmo.hpp
+++ b/src/common/mmo.hpp
@@ -2,7 +2,7 @@
 #ifndef MMO_HPP
 #define MMO_HPP
 
-# include "sanity.hpp"
+# include "../sanity.hpp"
 
 # include "../strings/vstring.hpp"
 
diff --git a/src/common/nullpo.hpp b/src/common/nullpo.hpp
index 9eb9ea9..26aab20 100644
--- a/src/common/nullpo.hpp
+++ b/src/common/nullpo.hpp
@@ -21,7 +21,7 @@
 # define nullpo_ret(t) nullpo_retr(0, t)
 # define nullpo_retv(t) nullpo_retr(, t)
 
-# include "sanity.hpp"
+# include "../sanity.hpp"
 
 /// Used by macros in this header
 bool nullpo_chk(const char *file, int line, const char *func,
diff --git a/src/common/random.hpp b/src/common/random.hpp
index 44057ed..a694cce 100644
--- a/src/common/random.hpp
+++ b/src/common/random.hpp
@@ -3,7 +3,7 @@
 
 # include "random.t.hpp"
 
-# include "sanity.hpp"
+# include "../sanity.hpp"
 
 # include <random>
 
diff --git a/src/common/sanity.hpp b/src/common/sanity.hpp
deleted file mode 100644
index 3658f9f..0000000
--- a/src/common/sanity.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/// return wrappers for unexpected NULL pointers
-#ifndef SANITY_HPP
-#define SANITY_HPP
-
-# ifndef __cplusplus
-#  error "Please compile in C++ mode"
-# endif // __cplusplus
-
-# if __GNUC__ < 4
-#  error "Your compiler is absolutely ancient. You have no chance ..."
-# endif // __GNUC__ < 4
-
-/// Convert type assumptions to use the standard types here
-# include <cstdint>
-/// size_t, NULL
-# include <cstddef>
-
-# if __GNUC__ == 4
-// clang identifies as GCC 4.2, but is mostly okay.
-// Until a bug-free release of it happens, though, I won't recommend it.
-// (patched) clang 3.1 would be the requirement
-#  if __GNUC_MINOR__ < 6 && !defined(__clang__)
-#   error "Please upgrade to at least GCC 4.6"
-#  endif // __GNUC_MINOR__ < 6 && !defined(__clang__)
-# endif // __GNUC__ == 4
-
-# if not defined(__i386__) and not defined(__x86_64__)
-// Known platform dependencies:
-// endianness for the [RW]FIFO.* macros
-// possibly, some signal-handling
-#  error "Unsupported platform use x86 / amd64 only"
-# endif // not __i386__
-
-#endif // SANITY_HPP
diff --git a/src/common/socket.cpp b/src/common/socket.cpp
index c7e6ed2..b507cd8 100644
--- a/src/common/socket.cpp
+++ b/src/common/socket.cpp
@@ -12,7 +12,7 @@
 #include <cstring>
 #include <ctime>
 
-#include "cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
 //#include "mmo.hpp"
 #include "utils.hpp"
 
diff --git a/src/common/socket.hpp b/src/common/socket.hpp
index 1ff400a..8a2ee3a 100644
--- a/src/common/socket.hpp
+++ b/src/common/socket.hpp
@@ -1,7 +1,7 @@
 #ifndef SOCKET_HPP
 #define SOCKET_HPP
 
-# include "sanity.hpp"
+# include "../sanity.hpp"
 
 # include <netinet/in.h>
 
diff --git a/src/common/timer.cpp b/src/common/timer.cpp
index 17c6d80..ee62df2 100644
--- a/src/common/timer.cpp
+++ b/src/common/timer.cpp
@@ -10,7 +10,8 @@
 
 #include "../strings/zstring.hpp"
 
-#include "cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "utils.hpp"
 
 #include "../poison.hpp"
diff --git a/src/common/timer.hpp b/src/common/timer.hpp
index de867ab..a54cb36 100644
--- a/src/common/timer.hpp
+++ b/src/common/timer.hpp
@@ -3,7 +3,7 @@
 
 # include "timer.t.hpp"
 
-# include "sanity.hpp"
+# include "../sanity.hpp"
 
 # include "../strings/fwd.hpp"
 
diff --git a/src/common/utils.cpp b/src/common/utils.cpp
index 0f8a0af..7f9a7ee 100644
--- a/src/common/utils.cpp
+++ b/src/common/utils.cpp
@@ -9,9 +9,9 @@
 #include "../strings/zstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/write.hpp"
 
-#include "cxxstdio.hpp"
 #include "extract.hpp"
 
 #include "../poison.hpp"
diff --git a/src/common/utils.hpp b/src/common/utils.hpp
index 4171759..2d2e2d5 100644
--- a/src/common/utils.hpp
+++ b/src/common/utils.hpp
@@ -1,7 +1,7 @@
 #ifndef UTILS_HPP
 #define UTILS_HPP
 
-#include "sanity.hpp"
+#include "../sanity.hpp"
 
 #include <cstdio>
 #include <cstring>
diff --git a/src/common/utils2.hpp b/src/common/utils2.hpp
index adcb465..7dbd741 100644
--- a/src/common/utils2.hpp
+++ b/src/common/utils2.hpp
@@ -1,7 +1,7 @@
 #ifndef UTILS2_HPP
 #define UTILS2_HPP
 
-#include "sanity.hpp"
+#include "../sanity.hpp"
 
 #include <algorithm>
 #include <functional>
diff --git a/src/io/cxxstdio.cpp b/src/io/cxxstdio.cpp
new file mode 100644
index 0000000..47617cb
--- /dev/null
+++ b/src/io/cxxstdio.cpp
@@ -0,0 +1 @@
+#include "cxxstdio.hpp"
diff --git a/src/io/cxxstdio.hpp b/src/io/cxxstdio.hpp
new file mode 100644
index 0000000..0d0bdba
--- /dev/null
+++ b/src/io/cxxstdio.hpp
@@ -0,0 +1,264 @@
+#ifndef TMWA_IO_CXXSTDIO_HPP
+#define TMWA_IO_CXXSTDIO_HPP
+//    cxxstdio.hpp - pass C++ types through scanf/printf
+//
+//    Copyright © 2011-2013 Ben Longbons <b.r.longbons@gmail.com>
+//
+//    This file is part of The Mana World (Athena server)
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program 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 General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#include "../sanity.hpp"
+
+#include <cstdarg>
+#include <cstdio>
+
+// TODO get rid of these header order violations
+#include "../common/const_array.hpp"
+#include "../common/utils2.hpp"
+
+#include "fwd.hpp"
+
+
+namespace cxxstdio
+{
+    // other implementations of do_vprint or do_vscan are injected by ADL.
+    inline __attribute__((format(printf, 2, 0)))
+    int do_vprint(FILE *out, const char *fmt, va_list ap)
+    {
+        return vfprintf(out, fmt, ap);
+    }
+
+    inline __attribute__((format(scanf, 2, 0)))
+    int do_vscan(FILE *in, const char *fmt, va_list ap)
+    {
+        return vfscanf(in, fmt, ap);
+    }
+
+#if 0
+    inline __attribute__((format(scanf, 2, 0)))
+    int do_vscan(const char *in, const char *fmt, va_list ap)
+    {
+        return vsscanf(in, fmt, ap);
+    }
+#else
+    inline
+    int do_vscan(const char *, const char *, va_list) = delete;
+#endif
+
+    template<class T>
+    inline __attribute__((format(printf, 2, 3)))
+    int do_print(T&& t, const char *fmt, ...) throw()
+    {
+        int rv;
+        va_list ap;
+        va_start(ap, fmt);
+        rv = do_vprint(std::forward<T>(t), fmt, ap);
+        va_end(ap);
+        return rv;
+    }
+
+    template<class T>
+    inline __attribute__((format(scanf, 2, 3)))
+    int do_scan(T&& t, const char *fmt, ...) throw()
+    {
+        int rv;
+        va_list ap;
+        va_start(ap, fmt);
+        rv = do_vscan(std::forward<T>(t), fmt, ap);
+        va_end(ap);
+        return rv;
+    }
+
+
+    template<class T, typename=typename std::enable_if<!std::is_class<T>::value>::type>
+    typename remove_enum<T>::type decay_for_printf(T v)
+    {
+        typedef typename remove_enum<T>::type repr_type;
+        return repr_type(v);
+    }
+
+    template<class T, typename=decltype(decay_for_printf(std::declval<T&&>()))>
+    T&& convert_for_printf(T&& v)
+    {
+        return std::forward<T>(v);
+    }
+
+    template<class T, typename = typename std::enable_if<!std::is_enum<T>::value>::type>
+    T& convert_for_scanf(T& v)
+    {
+        return v;
+    }
+
+#if 0
+    template<class E>
+    constexpr
+    E get_enum_min_value(decltype(E::min_value))
+    {
+        return E::min_value;
+    }
+    template<class E>
+    constexpr
+    E get_enum_min_value(E def)
+    {
+        return def;
+    }
+
+    template<class E>
+    constexpr
+    E get_enum_max_value(decltype(E::max_value))
+    {
+        return E::max_value;
+    }
+    template<class E>
+    constexpr
+    E get_enum_max_value(E def)
+    {
+        return def;
+    }
+#else
+    template<class E>
+    constexpr
+    E get_enum_min_value(E)
+    {
+        return E::min_value;
+    }
+    template<class E>
+    constexpr
+    E get_enum_max_value(E)
+    {
+        return E::max_value;
+    }
+#endif
+
+    template<class E>
+    class EnumConverter
+    {
+        E& out;
+        typedef typename underlying_type<E>::type U;
+#if 0
+        constexpr static
+        U min_value = U(get_enum_min_value<E>(E(std::numeric_limits<U>::min())));
+        constexpr static
+        U max_value = U(get_enum_max_value<E>(E(std::numeric_limits<U>::max())));
+#else
+        constexpr static
+        U min_value = U(get_enum_min_value(E()));
+        constexpr static
+        U max_value = U(get_enum_max_value(E()));
+#endif
+        U mid;
+    public:
+        EnumConverter(E& e)
+        : out(e), mid(0)
+        {}
+        ~EnumConverter()
+        {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wtype-limits"
+            if (min_value <= mid && mid <= max_value)
+#pragma GCC diagnostic pop
+                out = E(mid);
+        }
+        U *operator &()
+        {
+            return &mid;
+        }
+    };
+
+    template<class T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
+    EnumConverter<T> convert_for_scanf(T& v)
+    {
+        return v;
+    }
+
+    template<class Format>
+    class PrintFormatter
+    {
+    public:
+        template<class T, class... A>
+        static
+        int print(T&& t, A&&... a)
+        {
+            constexpr static
+            const char *print_format = Format::print_format();
+            return do_print(std::forward<T>(t), print_format,
+                    decay_for_printf(convert_for_printf(std::forward<A>(a)))...);
+        }
+    };
+
+    template<class Format>
+    class ScanFormatter
+    {
+    public:
+        template<class T, class... A>
+        static
+        int scan(T&& t, A&&... a)
+        {
+            constexpr static
+            const char *scan_format = Format::scan_format();
+            return do_scan(std::forward<T>(t), scan_format,
+                    &convert_for_scanf(*a)...);
+        }
+    };
+
+#define XPRINTF(out, fmt, ...)                                      \
+    (/*[&]() -> int*/                                                   \
+    {                                                               \
+        struct format_impl                                          \
+        {                                                           \
+            constexpr static                                        \
+            const char *print_format() { return fmt; }              \
+        };                                                          \
+        /*return*/ cxxstdio::PrintFormatter<format_impl>::print(out, ## __VA_ARGS__);   \
+    }/*()*/)
+
+#define XSCANF(out, fmt, ...)                                   \
+    (/*[&]() -> int*/                                               \
+    {                                                           \
+        struct format_impl                                      \
+        {                                                       \
+            constexpr static                                    \
+            const char *scan_format() { return fmt; }           \
+        };                                                      \
+        /*return*/ cxxstdio::ScanFormatter<format_impl>::scan(out, ## __VA_ARGS__);     \
+    }/*()*/)
+
+#define FPRINTF(file, fmt, ...)     XPRINTF(/*no_cast<FILE *>*/(file), fmt, ## __VA_ARGS__)
+#define FSCANF(file, fmt, ...)      XSCANF(no_cast<FILE *>(file), fmt, ## __VA_ARGS__)
+#define PRINTF(fmt, ...)            FPRINTF(stdout, fmt, ## __VA_ARGS__)
+#define SPRINTF(str, fmt, ...)      XPRINTF(base_cast<FString&>(str), fmt, ## __VA_ARGS__)
+#define SNPRINTF(str, n, fmt, ...)  XPRINTF(base_cast<VString<n-1>&>(str), fmt, ## __VA_ARGS__)
+#define SCANF(fmt, ...)             FSCANF(stdin, fmt, ## __VA_ARGS__)
+#define SSCANF(str, fmt, ...)       XSCANF(/*ZString or compatible*/str, fmt, ## __VA_ARGS__)
+
+#define STRPRINTF(fmt, ...)                     \
+    (/*[&]() -> FString*/                           \
+    {                                           \
+        FString _out_impl;                      \
+        SPRINTF(_out_impl, fmt, ## __VA_ARGS__);\
+        /*return*/ _out_impl;                       \
+    }/*()*/)
+
+#define STRNPRINTF(n, fmt, ...)                     \
+    (/*[&]() -> VString<n - 1>*/                        \
+    {                                               \
+        VString<n - 1> _out_impl;                   \
+        SNPRINTF(_out_impl, n, fmt, ## __VA_ARGS__);\
+        /*return*/ _out_impl;                           \
+    }/*()*/)
+
+} // namespace cxxstdio
+
+#endif // TMWA_IO_CXXSTDIO_HPP
diff --git a/src/io/fwd.hpp b/src/io/fwd.hpp
index c68c437..9a980c5 100644
--- a/src/io/fwd.hpp
+++ b/src/io/fwd.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "../common/sanity.hpp"
+#include "../sanity.hpp"
 
 
 namespace io
diff --git a/src/io/lock.cpp b/src/io/lock.cpp
index 7ee4fbe..823b168 100644
--- a/src/io/lock.cpp
+++ b/src/io/lock.cpp
@@ -23,8 +23,7 @@
 
 #include "../strings/zstring.hpp"
 
-// TODO remove this violation of include order
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
 
 #include "../poison.hpp"
 
diff --git a/src/io/read.cpp b/src/io/read.cpp
index 11a0020..146ba81 100644
--- a/src/io/read.cpp
+++ b/src/io/read.cpp
@@ -25,7 +25,7 @@
 #include "../strings/mstring.hpp"
 #include "../strings/zstring.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
 
 #include "../poison.hpp"
 
diff --git a/src/io/read.hpp b/src/io/read.hpp
index d5b8c23..47fc055 100644
--- a/src/io/read.hpp
+++ b/src/io/read.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "../common/sanity.hpp"
+#include "../sanity.hpp"
 
 #include "../strings/fwd.hpp"
 
diff --git a/src/io/write.hpp b/src/io/write.hpp
index f0aa584..18e8209 100644
--- a/src/io/write.hpp
+++ b/src/io/write.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "../common/sanity.hpp"
+#include "../sanity.hpp"
 
 #include <cstdarg>
 
diff --git a/src/login/login.cpp b/src/login/login.cpp
index b93a698..bd466e1 100644
--- a/src/login/login.cpp
+++ b/src/login/login.cpp
@@ -20,11 +20,11 @@
 #include "../strings/xstring.hpp"
 #include "../strings/vstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/lock.hpp"
 #include "../io/read.hpp"
 
 #include "../common/core.hpp"
-#include "../common/cxxstdio.hpp"
 #include "../common/db.hpp"
 #include "../common/extract.hpp"
 #include "../common/human_time_diff.hpp"
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index 55596b3..5256121 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -10,11 +10,11 @@
 #include "../strings/xstring.hpp"
 #include "../strings/vstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 #include "../io/write.hpp"
 
 #include "../common/core.hpp"
-#include "../common/cxxstdio.hpp"
 #include "../common/extract.hpp"
 #include "../common/human_time_diff.hpp"
 #include "../common/mmo.hpp"
diff --git a/src/map/battle.cpp b/src/map/battle.cpp
index 457c37a..05bacd4 100644
--- a/src/map/battle.cpp
+++ b/src/map/battle.cpp
@@ -5,9 +5,9 @@
 #include "../strings/fstring.hpp"
 #include "../strings/zstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/nullpo.hpp"
 #include "../common/random.hpp"
 
diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp
index 8e62e4d..4afccb7 100644
--- a/src/map/chrif.cpp
+++ b/src/map/chrif.cpp
@@ -7,7 +7,8 @@
 #include "../strings/fstring.hpp"
 #include "../strings/zstring.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "../common/nullpo.hpp"
 #include "../common/socket.hpp"
 #include "../common/timer.hpp"
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index d4cedc6..5b7c21d 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -10,9 +10,9 @@
 #include "../strings/zstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/write.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/md5calc.hpp"
 #include "../common/random.hpp"
 #include "../common/nullpo.hpp"
diff --git a/src/map/grfio.cpp b/src/map/grfio.cpp
index c486cf4..c5a55f5 100644
--- a/src/map/grfio.cpp
+++ b/src/map/grfio.cpp
@@ -15,9 +15,9 @@
 #include "../strings/mstring.hpp"
 #include "../strings/fstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/extract.hpp"
 
 #include "../poison.hpp"
diff --git a/src/map/intif.cpp b/src/map/intif.cpp
index 18415d0..8673aef 100644
--- a/src/map/intif.cpp
+++ b/src/map/intif.cpp
@@ -7,7 +7,8 @@
 #include "../strings/zstring.hpp"
 #include "../strings/xstring.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "../common/nullpo.hpp"
 #include "../common/socket.hpp"
 
diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp
index 5a11aa1..313ff23 100644
--- a/src/map/itemdb.cpp
+++ b/src/map/itemdb.cpp
@@ -7,9 +7,9 @@
 #include "../strings/zstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/db.hpp"
 #include "../common/extract.hpp"
 #include "../common/nullpo.hpp"
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp
index b360cca..acdefc2 100644
--- a/src/map/magic-expr.cpp
+++ b/src/map/magic-expr.cpp
@@ -10,7 +10,8 @@
 #include "../strings/zstring.hpp"
 #include "../strings/vstring.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "../common/random.hpp"
 
 #include "battle.hpp"
diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp
index e86e86b..0ba145a 100644
--- a/src/map/magic-interpreter-base.cpp
+++ b/src/map/magic-interpreter-base.cpp
@@ -6,7 +6,8 @@
 #include "../strings/fstring.hpp"
 #include "../strings/xstring.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "../common/timer.hpp"
 
 #include "magic-expr.hpp"
diff --git a/src/map/magic-interpreter-lexer.lpp b/src/map/magic-interpreter-lexer.lpp
index b5a16b2..2b68acf 100644
--- a/src/map/magic-interpreter-lexer.lpp
+++ b/src/map/magic-interpreter-lexer.lpp
@@ -3,7 +3,7 @@
 #
 #include "magic-interpreter-parser.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
 
 #ifdef HEADING
 # error "what platform is this? please tell me who #defined HEADING"
diff --git a/src/map/magic-interpreter-parser.ypp b/src/map/magic-interpreter-parser.ypp
index 8a654cd..0657ade 100644
--- a/src/map/magic-interpreter-parser.ypp
+++ b/src/map/magic-interpreter-parser.ypp
@@ -13,8 +13,9 @@
 #include "../strings/fstring.hpp"
 #include "../strings/zstring.hpp"
 
+#include "../io/cxxstdio.hpp"
+
 #include "../common/const_array.hpp"
-#include "../common/cxxstdio.hpp"
 
 #include "itemdb.hpp"
 #include "magic-expr.hpp"
diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp
index a0e2b7c..682d9bc 100644
--- a/src/map/magic-stmt.cpp
+++ b/src/map/magic-stmt.cpp
@@ -4,7 +4,8 @@
 
 #include "../strings/zstring.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "../common/random2.hpp"
 #include "../common/timer.hpp"
 
diff --git a/src/map/magic.cpp b/src/map/magic.cpp
index 75a76ae..0602dfa 100644
--- a/src/map/magic.cpp
+++ b/src/map/magic.cpp
@@ -2,7 +2,7 @@
 
 #include "../strings/xstring.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
 
 #include "magic-interpreter.hpp"
 
diff --git a/src/map/map.cpp b/src/map/map.cpp
index d259451..137adff 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -15,11 +15,11 @@
 #include "../strings/xstring.hpp"
 #include "../strings/vstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/write.hpp"
 #include "../io/read.hpp"
 
 #include "../common/core.hpp"
-#include "../common/cxxstdio.hpp"
 #include "../common/db.hpp"
 #include "../common/extract.hpp"
 #include "../common/random2.hpp"
diff --git a/src/map/map.hpp b/src/map/map.hpp
index e1f8422..7eeaa8c 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -12,7 +12,8 @@
 #include "../strings/fstring.hpp"
 #include "../strings/vstring.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "../common/db.hpp"
 #include "../common/matrix.hpp"
 #include "../common/socket.hpp"
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index 34374a7..960c58e 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -11,9 +11,9 @@
 #include "../strings/fstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/extract.hpp"
 #include "../common/nullpo.hpp"
 #include "../common/random.hpp"
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index e6c7445..f5a1f21 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -12,9 +12,9 @@
 #include "../strings/zstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/db.hpp"
 #include "../common/extract.hpp"
 #include "../common/nullpo.hpp"
diff --git a/src/map/party.cpp b/src/map/party.cpp
index 0ba251f..9d7cae2 100644
--- a/src/map/party.cpp
+++ b/src/map/party.cpp
@@ -4,7 +4,8 @@
 
 #include "../strings/xstring.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "../common/db.hpp"
 #include "../common/nullpo.hpp"
 #include "../common/socket.hpp"
diff --git a/src/map/path.cpp b/src/map/path.cpp
index f7fffbe..d66640e 100644
--- a/src/map/path.cpp
+++ b/src/map/path.cpp
@@ -2,7 +2,8 @@
 
 #include <cassert>
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "../common/random.hpp"
 #include "../common/nullpo.hpp"
 
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 157046f..0b648d1 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -7,9 +7,9 @@
 #include "../strings/fstring.hpp"
 #include "../strings/zstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/nullpo.hpp"
 #include "../common/random.hpp"
 #include "../common/socket.hpp"
diff --git a/src/map/script.cpp b/src/map/script.cpp
index f7a87a5..f3635c4 100644
--- a/src/map/script.cpp
+++ b/src/map/script.cpp
@@ -12,10 +12,10 @@
 #include "../strings/zstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/lock.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/db.hpp"
 #include "../common/extract.hpp"
 #include "../common/intern-pool.hpp"
diff --git a/src/map/skill-pools.cpp b/src/map/skill-pools.cpp
index 2774922..31998f8 100644
--- a/src/map/skill-pools.cpp
+++ b/src/map/skill-pools.cpp
@@ -1,6 +1,6 @@
 #include "skill.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
 
 #include "battle.hpp"
 #include "pc.hpp"
diff --git a/src/map/skill.cpp b/src/map/skill.cpp
index 9187335..3fdd45d 100644
--- a/src/map/skill.cpp
+++ b/src/map/skill.cpp
@@ -9,9 +9,9 @@
 #include "../strings/fstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/extract.hpp"
 #include "../common/nullpo.hpp"
 #include "../common/random.hpp"
diff --git a/src/map/tmw.cpp b/src/map/tmw.cpp
index d4beef4..9841a75 100644
--- a/src/map/tmw.cpp
+++ b/src/map/tmw.cpp
@@ -7,7 +7,8 @@
 #include "../strings/zstring.hpp"
 #include "../strings/xstring.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "../common/nullpo.hpp"
 
 #include "atcommand.hpp"
diff --git a/src/map/trade.cpp b/src/map/trade.cpp
index 785a4da..7fc01ae 100644
--- a/src/map/trade.cpp
+++ b/src/map/trade.cpp
@@ -1,6 +1,7 @@
 #include "trade.hpp"
 
-#include "../common/cxxstdio.hpp"
+#include "../io/cxxstdio.hpp"
+
 #include "../common/nullpo.hpp"
 
 #include "battle.hpp"
diff --git a/src/monitor/main.cpp b/src/monitor/main.cpp
index b398b97..934e24f 100644
--- a/src/monitor/main.cpp
+++ b/src/monitor/main.cpp
@@ -19,9 +19,9 @@
 #include "../strings/zstring.hpp"
 #include "../strings/xstring.hpp"
 
+#include "../io/cxxstdio.hpp"
 #include "../io/read.hpp"
 
-#include "../common/cxxstdio.hpp"
 #include "../common/utils.hpp"
 
 #include "../poison.hpp"
diff --git a/src/sanity.hpp b/src/sanity.hpp
new file mode 100644
index 0000000..d4a8738
--- /dev/null
+++ b/src/sanity.hpp
@@ -0,0 +1,34 @@
+/// Keep spatulas out of the build environment
+#ifndef TMWA_SANITY_HPP
+#define TMWA_SANITY_HPP
+
+# ifndef __cplusplus
+#  error "Please compile in C++ mode"
+# endif // __cplusplus
+
+# if __GNUC__ < 4
+#  error "Your compiler is absolutely ancient. You have no chance ..."
+# endif // __GNUC__ < 4
+
+/// Convert type assumptions to use the standard types here
+# include <cstdint>
+/// size_t, NULL
+# include <cstddef>
+
+# if __GNUC__ == 4
+// clang identifies as GCC 4.2, but is mostly okay.
+// Until a bug-free release of it happens, though, I won't recommend it.
+// (patched) clang 3.1 would be the requirement
+#  if __GNUC_MINOR__ < 6 && !defined(__clang__)
+#   error "Please upgrade to at least GCC 4.6"
+#  endif // __GNUC_MINOR__ < 6 && !defined(__clang__)
+# endif // __GNUC__ == 4
+
+# if not defined(__i386__) and not defined(__x86_64__)
+// Known platform dependencies:
+// endianness for the [RW]FIFO.* macros
+// possibly, some signal-handling
+#  error "Unsupported platform, we use x86 / amd64 only"
+# endif // not __i386__
+
+#endif // TMWA_SANITY_HPP
diff --git a/src/strings/fwd.hpp b/src/strings/fwd.hpp
index 41abbbb..9d71b5f 100644
--- a/src/strings/fwd.hpp
+++ b/src/strings/fwd.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "../common/sanity.hpp"
+#include "../sanity.hpp"
 
 // It is a common mistake to assume that one string class for everything.
 // Because C++ and TMWA have a C legacy, there are a few more here
diff --git a/src/strings/pair.hpp b/src/strings/pair.hpp
index 88422be..2c0061a 100644
--- a/src/strings/pair.hpp
+++ b/src/strings/pair.hpp
@@ -19,7 +19,7 @@
 //    You should have received a copy of the GNU General Public License
 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-#include "../common/sanity.hpp"
+#include "../sanity.hpp"
 
 #include <cstring>
 
-- 
cgit v1.2.3-70-g09d2