]> gitweb.ps.run Git - toc/blobdiff - antlr4-cpp-runtime-4.9.2-source/runtime/src/support/CPPUtils.cpp
add antlr source code and ReadMe
[toc] / antlr4-cpp-runtime-4.9.2-source / runtime / src / support / CPPUtils.cpp
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/support/CPPUtils.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/support/CPPUtils.cpp
new file mode 100644 (file)
index 0000000..86a3751
--- /dev/null
@@ -0,0 +1,248 @@
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#include "support/CPPUtils.h"
+
+namespace antlrcpp {
+
+  std::string join(std::vector<std::string> strings, const std::string &separator) {
+    std::string str;
+    bool firstItem = true;
+    for (std::string s : strings) {
+      if (!firstItem) {
+        str.append(separator);
+      }
+      firstItem = false;
+      str.append(s);
+    }
+    return str;
+  }
+
+  std::map<std::string, size_t> toMap(const std::vector<std::string> &keys) {
+    std::map<std::string, size_t> result;
+    for (size_t i = 0; i < keys.size(); ++i) {
+      result.insert({ keys[i], i });
+    }
+    return result;
+  }
+
+  std::string escapeWhitespace(std::string str, bool escapeSpaces) {
+    std::string result;
+    for (auto c : str) {
+      switch (c) {
+        case '\n':
+          result += "\\n";
+          break;
+
+        case '\r':
+          result += "\\r";
+          break;
+
+        case '\t':
+          result += "\\t";
+          break;
+
+        case ' ':
+          if (escapeSpaces) {
+            result += "\u00B7";
+            break;
+          }
+          // else fall through
+#ifndef _MSC_VER
+#if __has_cpp_attribute(clang::fallthrough)
+          [[clang::fallthrough]];
+#endif
+#endif
+
+        default:
+          result += c;
+      }
+    }
+
+    return result;
+  }
+
+  std::string toHexString(const int t) {
+    std::stringstream stream;
+    stream << std::uppercase << std::hex << t;
+    return stream.str();
+  }
+
+  std::string arrayToString(const std::vector<std::string> &data) {
+    std::string answer;
+    for (auto sub: data) {
+      answer += sub;
+    }
+    return answer;
+  }
+
+  std::string replaceString(const std::string &s, const std::string &from, const std::string &to) {
+    std::string::size_type p;
+    std::string ss, res;
+
+    ss = s;
+    p = ss.find(from);
+    while (p != std::string::npos) {
+      if (p > 0)
+        res.append(ss.substr(0, p)).append(to);
+      else
+        res.append(to);
+      ss = ss.substr(p + from.size());
+      p = ss.find(from);
+    }
+    res.append(ss);
+
+    return res;
+  }
+
+  std::vector<std::string> split(const std::string &s, const std::string &sep, int count) {
+    std::vector<std::string> parts;
+    std::string ss = s;
+
+    std::string::size_type p;
+
+    if (s.empty())
+      return parts;
+
+    if (count == 0)
+      count= -1;
+
+    p = ss.find(sep);
+    while (!ss.empty() && p != std::string::npos && (count < 0 || count > 0)) {
+      parts.push_back(ss.substr(0, p));
+      ss = ss.substr(p+sep.size());
+
+      --count;
+      p = ss.find(sep);
+    }
+    parts.push_back(ss);
+
+    return parts;
+  }
+
+  //--------------------------------------------------------------------------------------------------
+
+  // Debugging helper. Adds indentation to all lines in the given string.
+  std::string indent(const std::string &s, const std::string &indentation, bool includingFirst) {
+    std::vector<std::string> parts = split(s, "\n", -1);
+    for (size_t i = 0; i < parts.size(); ++i) {
+      if (i == 0 && !includingFirst)
+        continue;
+      parts[i].insert(0, indentation);
+    }
+
+    return join(parts, "\n");
+  }
+
+  //--------------------------------------------------------------------------------------------------
+
+  // Recursively get the error from a, possibly nested, exception.
+#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023026
+  // No nested exceptions before VS 2015.
+  template <typename T>
+  std::exception_ptr get_nested(const T &/*e*/) {
+    try {
+      return nullptr;
+    }
+    catch (const std::bad_cast &) {
+      return nullptr;
+    }
+  }
+#else
+  template <typename T>
+  std::exception_ptr get_nested(const T &e) {
+    try {
+      auto nested = dynamic_cast<const std::nested_exception&>(e);
+      return nested.nested_ptr();
+    }
+    catch (const std::bad_cast &) {
+      return nullptr;
+    }
+  }
+#endif
+
+  std::string what(std::exception_ptr eptr) {
+    if (!eptr) {
+      throw std::bad_exception();
+    }
+
+    std::string result;
+    std::size_t nestCount = 0;
+
+    next: {
+      try {
+        std::exception_ptr yeptr;
+        std::swap(eptr, yeptr);
+        std::rethrow_exception(yeptr);
+      }
+      catch (const std::exception &e) {
+        result += e.what();
+        eptr = get_nested(e);
+      }
+      catch (const std::string &e) {
+        result += e;
+      }
+      catch (const char *e) {
+        result += e;
+      }
+      catch (...) {
+        result += "cannot be determined";
+      }
+
+      if (eptr) {
+        result += " (";
+        ++nestCount;
+        goto next;
+      }
+    }
+
+    result += std::string(nestCount, ')');
+    return result;
+  }
+
+  //----------------- FinallyAction ------------------------------------------------------------------------------------
+
+  FinalAction finally(std::function<void ()> f) {
+    return FinalAction(f);
+  }
+
+  //----------------- SingleWriteMultipleRead --------------------------------------------------------------------------
+
+  void SingleWriteMultipleReadLock::readLock() {
+    std::unique_lock<std::mutex> lock(_mutex);
+    while (_waitingWriters != 0)
+      _readerGate.wait(lock);
+    ++_activeReaders;
+    lock.unlock();
+  }
+
+  void SingleWriteMultipleReadLock::readUnlock() {
+    std::unique_lock<std::mutex> lock(_mutex);
+    --_activeReaders;
+    lock.unlock();
+    _writerGate.notify_one();
+  }
+
+  void SingleWriteMultipleReadLock::writeLock() {
+    std::unique_lock<std::mutex> lock(_mutex);
+    ++_waitingWriters;
+    while (_activeReaders != 0 || _activeWriters != 0)
+      _writerGate.wait(lock);
+    ++_activeWriters;
+    lock.unlock();
+  }
+
+  void SingleWriteMultipleReadLock::writeUnlock() {
+    std::unique_lock<std::mutex> lock(_mutex);
+    --_waitingWriters;
+    --_activeWriters;
+    if (_waitingWriters > 0)
+      _writerGate.notify_one();
+    else
+      _readerGate.notify_all();
+    lock.unlock();
+  }
+
+} // namespace antlrcpp