sources/format.cpp

changeset 1
4dd5bde4e777
child 5
146825d63b9a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sources/format.cpp	Wed Dec 10 19:17:00 2014 +0200
@@ -0,0 +1,107 @@
+/*
+	Copyright 2014 Teemu Piippo
+	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 copyright holder 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER
+	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 <cstdio>
+#include "format.h"
+
+//
+// Throws an error while formatting the string
+//
+static auto format_error (String fmtstr, const String errdescribe, int pos) -> void
+{
+	fmtstr.replace ("\n", " ");
+	fmtstr.replace ("\t", " ");
+	String errmsg ("With format string:\n" + fmtstr + "\n");
+
+	for (int x = 0; x < pos; ++x)
+		errmsg += "-";
+
+	errmsg += "^\n" + errdescribe;
+	// throw std::logic_error (errmsg.stdString());
+	std::fprintf (stderr, "%s", errmsg.chars());
+	std::exit (EXIT_FAILURE);
+}
+
+//
+// Main formatter algorithm autoion. Processes @fmtstr with @args and returns
+// the result.
+//
+auto format_args (const String& fmtstr, const Vector<String>& args) -> String
+{
+	String fmt = fmtstr;
+	int pos = 0;
+
+	while ((pos = fmt.find ("%", pos)) != -1)
+	{
+		if (fmt[pos + 1] == '%')
+		{
+			fmt.replace (pos, 2, "%");
+			pos++;
+			continue;
+		}
+
+		int ofs = 1;
+		char mod = '\0';
+
+		// handle modifiers
+		if (fmt[pos + ofs] == 's' or fmt[pos + ofs] == 'x' or fmt[pos + ofs] == 'd')
+		{
+			mod = fmt[pos + ofs];
+			ofs++;
+		}
+
+		if (fmt[pos + ofs] < '1' or fmt[pos + ofs] > '9')
+		{
+			format_error (fmtstr, "bad format string, expected non-zero digit with "
+				"optional modifier after '%%'", pos);
+		}
+
+		int i = fmt[pos + ofs] - '0';
+
+		if (i > args.size())
+			format_error (fmtstr, String ("Format argument #") + i + " used but not defined.", pos);
+
+		String replacement = args[i - 1];
+
+		switch (mod)
+		{
+		case 's': replacement = (replacement == "1") ? "" : "s";      break;
+		case 'd': replacement.sprintf ("%d", replacement[0]);         break;
+		case 'x': replacement.sprintf ("0x%x", replacement.to_int()); break;
+		default: break;
+		}
+
+		fmt.replace (pos, 1 + ofs, replacement);
+		pos += replacement.length();
+	}
+
+	return fmt;
+}
+

mercurial