From b9f441e81e89728f284f61991e14748208817efd Mon Sep 17 00:00:00 2001
From: bruvzg <7645683+bruvzg@users.noreply.github.com>
Date: Tue, 11 Aug 2020 12:10:23 +0300
Subject: [Complex Text Layouts] Add third-party TextServer dependencies (ICU,
 HarfBuzz, Graphite).

---
 thirdparty/graphite/src/json.cpp | 147 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 147 insertions(+)
 create mode 100644 thirdparty/graphite/src/json.cpp

(limited to 'thirdparty/graphite/src/json.cpp')

diff --git a/thirdparty/graphite/src/json.cpp b/thirdparty/graphite/src/json.cpp
new file mode 100644
index 0000000000..25f2190f71
--- /dev/null
+++ b/thirdparty/graphite/src/json.cpp
@@ -0,0 +1,147 @@
+/*  GRAPHITE2 LICENSING
+
+    Copyright 2011, SIL International
+    All rights reserved.
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of 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
+    Lesser General Public License for more details.
+
+    You should also have received a copy of the GNU Lesser General Public
+    License along with this library in the file named "LICENSE".
+    If not, write to the Free Software Foundation, 51 Franklin Street,
+    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
+    internet at http://www.fsf.org/licenses/lgpl.html.
+
+Alternatively, the contents of this file may be used under the terms of the
+Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+License, as published by the Free Software Foundation, either version 2
+of the License or (at your option) any later version.
+*/
+// JSON debug logging
+// Author: Tim Eves
+
+#if !defined GRAPHITE2_NTRACING
+
+#include <cstdio>
+#include <limits>
+#include "inc/json.h"
+
+#if defined(_MSC_VER)
+#define FORMAT_INTMAX "%lli"
+#define FORMAT_UINTMAX "%llu"
+#else
+#define FORMAT_INTMAX "%ji"
+#define FORMAT_UINTMAX "%ju"
+#endif
+
+using namespace graphite2;
+
+namespace
+{
+    enum
+    {
+        seq = ',',
+        obj='}', member=':', empty_obj='{',
+        arr=']', empty_arr='['
+    };
+}
+
+const std::nullptr_t json::null = nullptr;
+
+inline
+void json::context(const char current) throw()
+{
+    fprintf(_stream, "%c", *_context);
+    indent();
+    *_context = current;
+}
+
+
+void json::indent(const int d) throw()
+{
+    if (*_context == member || (_flatten  && _flatten < _context))
+        fputc(' ', _stream);
+    else
+        fprintf(_stream,  "\n%*s",  4*int(_context - _contexts + d), "");
+}
+
+
+inline
+void json::push_context(const char prefix, const char suffix) throw()
+{
+    assert(_context - _contexts < ptrdiff_t(sizeof _contexts));
+
+    if (_context == _contexts)
+        *_context = suffix;
+    else
+        context(suffix);
+    *++_context = prefix;
+}
+
+
+void json::pop_context() throw()
+{
+    assert(_context > _contexts);
+
+    if (*_context == seq)   indent(-1);
+    else                    fputc(*_context, _stream);
+
+    fputc(*--_context, _stream);
+    if (_context == _contexts)  fputc('\n', _stream);
+    fflush(_stream);
+
+    if (_flatten >= _context)   _flatten = 0;
+    *_context = seq;
+}
+
+
+// These four functions cannot be inlined as pointers to these
+// functions are needed for operator << (_context_t) to work.
+void json::flat(json & j) throw()   { if (!j._flatten)  j._flatten = j._context; }
+void json::close(json & j) throw()  { j.pop_context(); }
+void json::object(json & j) throw() { j.push_context('{', '}'); }
+void json::array(json & j) throw()  { j.push_context('[', ']'); }
+void json::item(json & j) throw()
+{
+    while (j._context > j._contexts+1 && j._context[-1] != arr)
+        j.pop_context();
+}
+
+
+json & json::operator << (json::string s) throw()
+{
+    const char ctxt = _context[-1] == obj ? *_context == member ? seq : member : seq;
+    context(ctxt);
+    fprintf(_stream, "\"%s\"", s);
+    if (ctxt == member) fputc(' ', _stream);
+
+    return *this;
+}
+
+json & json::operator << (json::number f) throw()
+{
+    context(seq);
+    if (std::numeric_limits<json::number>::infinity() == f)
+        fputs("Infinity", _stream);
+    else if (-std::numeric_limits<json::number>::infinity() == f)
+        fputs("-Infinity", _stream);
+    else if (std::numeric_limits<json::number>::quiet_NaN() == f ||
+            std::numeric_limits<json::number>::signaling_NaN() == f)
+        fputs("NaN", _stream);
+    else
+        fprintf(_stream, "%g", f);
+    return *this;
+}
+json & json::operator << (json::integer d) throw()  { context(seq); fprintf(_stream, FORMAT_INTMAX, intmax_t(d)); return *this; }
+json & json::operator << (json::integer_u d) throw()  { context(seq); fprintf(_stream, FORMAT_UINTMAX, uintmax_t(d)); return *this; }
+json & json::operator << (json::boolean b) throw()  { context(seq); fputs(b ? "true" : "false", _stream); return *this; }
+json & json::operator << (std::nullptr_t)  throw()  { context(seq); fputs("null",_stream); return *this; }
+
+#endif
-- 
cgit v1.2.3