TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / external / android-emugl / host / tools / emugen / Parser.cpp
diff --git a/src/type3_AndroidCloud/anbox-master/external/android-emugl/host/tools/emugen/Parser.cpp b/src/type3_AndroidCloud/anbox-master/external/android-emugl/host/tools/emugen/Parser.cpp
new file mode 100644 (file)
index 0000000..0839f20
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+* Copyright 2014 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include "Parser.h"
+
+#include <vector>
+
+#define WHITESPACE " \t\n"
+
+// Parse the |input| string as a list of type-specific tokens.
+// This tokenizes the input, using whitespace as separators and '*' as
+// a single token too. On success, return true and sets |*out| to the
+// list of tokens. On failure, return false.
+//
+// Example: 'const char**foo' -> ['const', 'char', '*', '*', 'foo']
+//
+static bool parseTypeTokens(const std::string& input,
+                            std::vector<std::string>* out,
+                            std::string* error) {
+    out->clear();
+    size_t pos = 0U;
+
+    // Parse all tokens in the input, treat '*' as a single token.
+    // I.e.
+    for (;;) {
+        // skip leading whitespace.
+        pos = input.find_first_not_of(WHITESPACE, pos);
+        if (pos == std::string::npos) {
+            break;  // end of parse.
+        }
+
+        // If this is a star, ensure it follows a type name.
+        // otherwise treat it as part of the final type.
+        if (input[pos] == '*') {
+            out->push_back(std::string("*"));
+            pos += 1U;
+            continue;
+        }
+
+        // find end of type/token.
+        size_t end = input.find_first_of(WHITESPACE "*", pos);
+        if (end == std::string::npos) {
+            end = input.size();
+        }
+
+        std::string str = input.substr(pos, end - pos);
+        if (str.size() == 0) {
+            // Sanity check: should not happen.
+            if (error != NULL) {
+                *error = "Unexpected empty token !?";
+            }
+            return false;
+        }
+
+        out->push_back(str);
+        pos = end;
+    }
+
+    if (error != NULL) {
+        // Sanity check: require non-empty input
+        if (out->empty()) {
+            *error = "Empty parameter declaration!";
+            return false;
+        }
+
+        // Sanity check: There must be base type name before any '*'
+        for (size_t n = 0; n < out->size(); ++n) {
+            std::string& token = (*out)[n];
+            if (token == "*") {
+                *error = "Unexpected '*' before type name";
+                return false;
+            } else if (token != "const") {
+                break;
+            }
+        }
+    }
+
+    return true;
+}
+
+// Given |tokens|, an input vector of strings, join the first |count| items
+// into a normalized type string, and return it.
+static std::string buildTypeString(const std::vector<std::string>& tokens,
+                                   size_t count) {
+    std::string result;
+
+    for (size_t n = 0; n < count; ++n) {
+        const std::string& token = tokens[n];
+        if (n > 0 && token != "*") {
+            result.append(" ");
+        }
+        result.append(token);
+    }
+    return result;
+}
+
+
+std::string normalizeTypeDeclaration(const std::string& input) {
+    std::vector<std::string> tokens;
+    if (!parseTypeTokens(input, &tokens, NULL)) {
+        return "";
+    }
+    return buildTypeString(tokens, tokens.size());
+}
+
+bool parseTypeDeclaration(const std::string& input,
+                          std::string* typeName,
+                          std::string* error) {
+    // The type name can be made of several tokens, e.g. 'unsigned int'
+    // use an array to store them, and a count variable. Each item can be
+    // one of '*', 'const' or a type name component (e.g. 'struct', 'unsigned')
+    std::vector<std::string> tokens;
+
+    if (!parseTypeTokens(input, &tokens, error)) {
+        return false;
+    }
+
+    // Sanity check, there must be a least one non-special tokens.
+    size_t nonSpecialCount = 0;
+    for (size_t n = 0; n < tokens.size(); ++n) {
+        if (tokens[n] != "*" && tokens[n] != "const") {
+            nonSpecialCount++;
+        }
+    }
+    if (nonSpecialCount == 0) {
+        *error = "Missing type name";
+        return false;
+    }
+    // Build the type name from all tokens before it.
+    *typeName = buildTypeString(tokens, tokens.size());
+    return true;
+}
+
+
+bool parseParameterDeclaration(const std::string& param,
+                               std::string* typeName,
+                               std::string* variableName,
+                               std::string* error) {
+    std::vector<std::string> tokens;
+
+    if (!parseTypeTokens(param, &tokens, error)) {
+        return false;
+    }
+
+    // Sanity check, there must be a least two non-special tokens.
+    size_t nonSpecialCount = 0;
+    for (size_t n = 0; n < tokens.size(); ++n) {
+        if (tokens[n] != "*" && tokens[n] != "const") {
+            nonSpecialCount++;
+        }
+    }
+    if (nonSpecialCount == 0) {
+        *error = "Missing type name";
+        return false;
+    }
+    if (nonSpecialCount == 1) {
+        *error = "Missing variable name";
+        return false;
+    }
+
+    // Sanity check: variable name must not be followed by 'const' or '*'
+    const std::string& lastToken = tokens[tokens.size() - 1U];
+    if (lastToken == "*") {
+        *error = "Extra '*' after variable name";
+        return false;
+    }
+    if (lastToken == "const") {
+        *error = "Extra 'const' after variable name";
+        return false;
+    }
+
+    // Extract the variable name as the last token.
+    if (variableName) {
+        *variableName = lastToken;
+    }
+    // Build the type name from all tokens before it.
+    *typeName = buildTypeString(tokens, tokens.size() - 1U);
+    return true;
+}