/*
 * Copyright (C) 2013 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.
 */

/* This program processes Renderscript function definitions described in spec files.
 * For each spec file provided on the command line, it generates a corresponding
 * Renderscript header (*.rsh) which is meant for inclusion in client scripts.
 *
 * This program also generates Junit test files to automatically test each of the
 * functions using randomly generated data.  We create two files for each function:
 * - a Renderscript file named Test{Function}.rs,
 * - a Junit file named Test{function}.java, which calls the above RS file.
 *
 * This program takes an optional -v parameter, the RS version to target the
 * test files for.  The header file will always contain all the functions.
 *
 * This program contains five main classes:
 * - SpecFile: Represents on spec file.
 * - Function: Each instance represents a function, like clamp.  Even though the
 *      spec file contains many entries for clamp, we'll only have one clamp instance.
 * - Specification: Defines one of the many variations of the function.  There's
 *      a one to one correspondance between Specification objects and entries in the
 *      spec file.  Strings that are parts of a Specification can include placeholders,
 *      which are "#1", "#2", "#3", and "#4".  We'll replace these by values before
 *      generating the files.
 * - Permutation: A concrete version of a specification, where all placeholders have
 *      been replaced by actual values.
 * - ParameterDefinition: A definition of a parameter of a concrete function.
 */

#include <math.h>
#include <stdio.h>
#include <cctype>
#include <cstdlib>
#include <fstream>
#include <functional>
#include <iomanip>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

namespace {

const char* AUTO_GENERATED_WARNING =
            "// Don't edit this file!  It is auto-generated by "
            "frameworks/rs/api/gen_runtime.\n\n";
const char* LEGAL_NOTICE =
            "/*\n"
            " * Copyright (C) 2014 The Android Open Source Project\n"
            " *\n"
            " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
            " * you may not use this file except in compliance with the License.\n"
            " * You may obtain a copy of the License at\n"
            " *\n"
            " *      http://www.apache.org/licenses/LICENSE-2.0\n"
            " *\n"
            " * Unless required by applicable law or agreed to in writing, software\n"
            " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
            " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
            " * See the License for the specific language governing permissions and\n"
            " * limitations under the License.\n"
            " */\n\n";

class Function;
class Specification;
class Permutation;
struct Type;

/* Information about a parameter to a function.  The values of all the fields should only be set by
 * parseParameterDefinition.
 */
struct ParameterDefinition {
    string rsType;        // The Renderscript type, e.g. "uint3"
    string rsBaseType;    // As above but without the number, e.g. "uint"
    string javaBaseType;  // The type we need to declare in Java, e.g. "unsigned int"
    string specType;      // The type found in the spec, e.g. "f16"
    bool isFloatType;     // True if it's a floating point value

    /* The number of entries in the vector.  It should be either "1", "2", "3", or "4".  It's also
     * "1" for scalars.
     */
    string mVectorSize;
    /* The space the vector takes in an array.  It's the same as the vector size, except for size
     * "3", where the width is "4".
     */
    string vectorWidth;

    string specName;       // e.g. x, as found in the spec file
    string variableName;   // e.g. inX, used both in .rs and .java
    string rsAllocName;    // e.g. gAllocInX
    string javaAllocName;  // e.g. inX
    string javaArrayName;  // e.g. arrayInX

    // If non empty, the mininum and maximum values to be used when generating the test data.
    string minValue;
    string maxValue;
    /* If non empty, contains the name of another parameter that should be smaller or equal to this
     * parameter, i.e.  value(smallerParameter) <= value(this).  This is used when testing clamp.
     */
    string smallerParameter;

    bool isOutParameter;       // True if this parameter returns data from the script.
    bool undefinedIfOutIsNan;  // If true, we don't validate if 'out' is NaN.

    int typeIndex;            // Index in the TYPES array.
    int compatibleTypeIndex;  // Index in TYPES for which the test data must also fit.

    /* Parse the parameter definition found in the spec file.  It will generate a name if none
     * are present in the file.  One of the two counts will be incremented, and potentially
     * used to generate unique names.  isReturn is true if we're processing the "return:"
     * definition.
     */
    void parseParameterDefinition(string s, bool isReturn, int* inputCount, int* outputCount);
};

// An entire spec file and the methods to process it.
class SpecFile {
public:
    explicit SpecFile(const string& specFileName) : mSpecFileName(specFileName) {}
    bool process(int versionOfTestFiles);

private:
    const string mSpecFileName;
    // The largest version number that we have found in all the specifications.
    int mLargestVersionNumber;

    map<string, Function*> mFunctionsMap;  // All the known functions.
    typedef map<string, Function*>::iterator FunctionsIterator;

    bool readSpecFile();
    Function* getFunction(const string& name);
    bool generateFiles(int versionOfTestFiles);
    bool writeAllFunctions(ofstream& headerFile, int versionOfTestFiles);
};

/* Represents a function, like "clamp".  Even though the spec file contains many entries for clamp,
 * we'll only have one clamp instance.
 */
class Function {
private:
    string mName;             // The lower case name, e.g. native_log
    string mCapitalizedName;  // The capitalized name, e.g. NativeLog
    string mTestName;         // e.g. TestNativeLog
    string mRelaxedTestName;  // e.g. TestNativeLogRelaxed

    vector<Specification*> mSpecifications;
    typedef vector<Specification*>::iterator SpecificationIterator;

    /* We keep track of the allocations generated in the .rs file and the argument classes defined
     * in the Java file, as we share these between the functions created for each specification.
     */
    set<string> mRsAllocationsGenerated;
    set<string> mJavaGeneratedArgumentClasses;

    string mJavaCallAllCheckMethods;  // Lines of Java code to invoke the check methods.

    ofstream mRsFile;    // The Renderscript test file we're generating.
    ofstream mJavaFile;  // The Jave test file we're generating.

    bool startRsFile();         // Open the mRsFile and writes its header.
    bool writeRelaxedRsFile();  // Write the entire relaxed rs test file (an include essentially)
    bool startJavaFile();       // Open the mJavaFile and writes the header.
    void finishJavaFile();      // Write the test method and closes the file.

public:
    explicit Function(const string& name);
    void addSpecification(Specification* spec) { mSpecifications.push_back(spec); }
    /* Write the .java and the two .rs test files.  versionOfTestFiles is used to restrict which API
     * to test.  Also writes the section of the header file.
     */
    bool writeFiles(ofstream& headerFile, int versionOfTestFiles);
    // Write an allocation and keep track of having it written, so it can be shared.
    void writeRsAllocationDefinition(const ParameterDefinition& param);
    // Write an argument class definiton and keep track of having it written, so it can be shared.
    void writeJavaArgumentClassDefinition(const string& className, const string& definition);
    // Add a call to mJavaCallAllCheckMethods to be used at the end of the file generation.
    void addJavaCheckCall(const string& call);
};

/* Defines one of the many variations of the function.  There's a one to one correspondance between
 * Specification objects and entries in the spec file.  Some of the strings that are parts of a
 * Specification can include placeholders, which are "#1", "#2", "#3", and "#4".  We'll replace
 * these by values before generating the files.
 */
class Specification {
private:
    /* The range of versions this specification applies to. 0 if there's no restriction, so an API
     * that became available at 9 and is still valid would have min:9 max:0.
     */
    int mMinVersion;
    int mMaxVersion;

    /* The name of the function without #n, e.g. convert.  As of this writing, it only differs for
     * convert.
     */
    string mCleanName;
    string mTest;  // How to test.  One of "scalar", "vector", "noverify", "limited", and "none".
    string mPrecisionLimit;  // Maximum precision required when checking output of this function.

    vector<vector<string> > mReplaceables;

    // The following fields may contain placeholders that will be replaced using the mReplaceables.

    // The name of this function, can include #, e.g. convert_#1_#2
    string mName;

    string mReturn;           // The return type
    vector<string> mComment;  // The comments to be included in the header
    vector<string> mInline;   // The inline code to be included in the header
    vector<string> mParam;    // One entry per parameter defined

    // Substitute the placeholders in the strings by the corresponding entries in mReplaceables.
    string expandString(string s, int i1, int i2, int i3, int i4) const;
    void expandStringVector(const vector<string>& in, int i1, int i2, int i3, int i4,
                            vector<string>* out) const;

public:
    Specification() {
        mMinVersion = 0;
        mMaxVersion = 0;
    }
    int getMinVersion() const { return mMinVersion; }
    int getMaxVersion() const { return mMaxVersion; }

    string getName(int i1, int i2, int i3, int i4) const {
        return expandString(mName, i1, i2, i3, i4);
    }
    string getReturn(int i1, int i2, int i3, int i4) const {
        return expandString(mReturn, i1, i2, i3, i4);
    }
    void getComments(int i1, int i2, int i3, int i4, vector<string>* comments) const {
        return expandStringVector(mComment, i1, i2, i3, i4, comments);
    }
    void getInlines(int i1, int i2, int i3, int i4, vector<string>* inlines) const {
        return expandStringVector(mInline, i1, i2, i3, i4, inlines);
    }
    void getParams(int i1, int i2, int i3, int i4, vector<string>* params) const {
        return expandStringVector(mParam, i1, i2, i3, i4, params);
    }
    string getTest() const { return mTest; }
    string getPrecisionLimit() const { return mPrecisionLimit; }
    string getCleanName() const { return mCleanName; }

    void writeFiles(ofstream& headerFile, ofstream& rsFile, ofstream& javaFile, Function* function,
                    int versionOfTestFiles);
    bool writeRelaxedRsFile() const;
    // Return true if this specification should be generated for this version.
    bool relevantForVersion(int versionOfTestFiles) const;

    static Specification* scanSpecification(FILE* in);
};

// A concrete version of a specification, where all placeholders have been replaced by actual
// values.
class Permutation {
private:
    Function* mFunction;
    Specification* mSpecification;

    // These are the expanded version of those found on Specification
    string mName;
    string mCleanName;
    string mTest;  // How to test.  One of "scalar", "vector", "noverify", "limited", and "none".
    string mPrecisionLimit;  // Maximum precision required when checking output of this function.
    vector<string> mInline;
    vector<string> mComment;

    // The inputs and outputs of the function.  This include the return type, if present.
    vector<ParameterDefinition*> mParams;
    // The index of the return value in mParams, -1 if the function is void.
    int mReturnIndex;
    // The index of the first input value in mParams, -1 if there's no input.
    int mFirstInputIndex;
    // The number of input and output parameters.
    int mInputCount;
    int mOutputCount;

    string mRsKernelName;
    string mJavaArgumentsClassName;
    string mJavaArgumentsNClassName;
    string mJavaVerifierComputeMethodName;
    string mJavaCheckMethodName;
    string mJavaVerifyMethodName;

    void writeHeaderSection(ofstream& file) const;

    void writeRsSection(ofstream& rs) const;

    void writeJavaSection(ofstream& file) const;
    void writeJavaArgumentClass(ofstream& file, bool scalar) const;
    void writeJavaCheckMethod(ofstream& file, bool generateCallToVerify) const;
    void writeJavaVerifyScalarMethod(ofstream& file) const;
    void writeJavaVerifyVectorMethod(ofstream& file) const;
    void writeJavaVerifyFunctionHeader(ofstream& file) const;
    void writeJavaInputAllocationDefinition(ofstream& file, const string& indent,
                                            const ParameterDefinition& param) const;
    void writeJavaOutputAllocationDefinition(ofstream& file, const string& indent,
                                             const ParameterDefinition& param) const;
    // Write code to create a random allocation for which the data must be compatible for two types.
    void writeJavaRandomCompatibleFloatAllocation(ofstream& file, const string& dataType,
                                                  const string& seed, char vectorSize,
                                                  const Type& compatibleType,
                                                  const Type& generatedType) const;
    void writeJavaRandomCompatibleIntegerAllocation(ofstream& file, const string& dataType,
                                                    const string& seed, char vectorSize,
                                                    const Type& compatibleType,
                                                    const Type& generatedType) const;
    void writeJavaCallToRs(ofstream& file, bool relaxed, bool generateCallToVerify) const;

    void writeJavaTestAndSetValid(ofstream& file, int indent, const ParameterDefinition& p,
                                  const string& argsIndex, const string& actualIndex) const;
    void writeJavaTestOneValue(ofstream& file, int indent, const ParameterDefinition& p,
                               const string& argsIndex, const string& actualIndex) const;
    void writeJavaAppendOutputToMessage(ofstream& file, int indent, const ParameterDefinition& p,
                                        const string& argsIndex, const string& actualIndex) const;
    void writeJavaAppendInputToMessage(ofstream& file, int indent, const ParameterDefinition& p,
                                       const string& actual) const;
    void writeJavaAppendNewLineToMessage(ofstream& file, int indent) const;
    void writeJavaAppendVariableToMessage(ofstream& file, int indent, const ParameterDefinition& p,
                                          const string& value) const;
    void writeJavaAppendFloatyVariableToMessage(ofstream& file, int indent,
                                                const string& value) const;
    void writeJavaVectorComparison(ofstream& file, int indent, const ParameterDefinition& p) const;
    void writeJavaAppendVectorInputToMessage(ofstream& file, int indent,
                                             const ParameterDefinition& p) const;
    void writeJavaAppendVectorOutputToMessage(ofstream& file, int indent,
                                              const ParameterDefinition& p) const;
    bool passByAddressToSet(const string& name) const;
    void convertToRsType(const string& name, string* dataType, char* vectorSize) const;

public:
    Permutation(Function* function, Specification* specification, int i1, int i2, int i3, int i4);
    void writeFiles(ofstream& headerFile, ofstream& rsFile, ofstream& javaFile,
                    int versionOfTestFiles);
#define DISABLE_LONG_AND_DOUBLE_TESTS
#ifdef DISABLE_LONG_AND_DOUBLE_TESTS
    bool hasLongOrDoubleParameter() const;
#endif
};

// Table of type equivalences
// TODO: We should just be pulling this from a shared header. Slang does exactly the same thing.

enum NumberKind { SIGNED_INTEGER, UNSIGNED_INTEGER, FLOATING_POINT };

struct Type {
    const char* specType;  // Name found in the .spec file
    string rsDataType;     // RS data type
    string cType;          // Type in a C file
    const char* javaType;  // Type in a Java file
    NumberKind kind;
    /* For integers, number of bits of the number, excluding the sign bit.
     * For floats, number of implied bits of the mantissa.
     */
    int significantBits;
    // For floats, number of bits of the exponent.  0 for integer types.
    int exponentBits;
};

const Type TYPES[] = {{"f16", "FLOAT_16", "half", "half", FLOATING_POINT, 11, 5},
                      {"f32", "FLOAT_32", "float", "float", FLOATING_POINT, 24, 8},
                      {"f64", "FLOAT_64", "double", "double", FLOATING_POINT, 53, 11},
                      {"i8", "SIGNED_8", "char", "byte", SIGNED_INTEGER, 7, 0},
                      {"u8", "UNSIGNED_8", "uchar", "byte", UNSIGNED_INTEGER, 8, 0},
                      {"i16", "SIGNED_16", "short", "short", SIGNED_INTEGER, 15, 0},
                      {"u16", "UNSIGNED_16", "ushort", "short", UNSIGNED_INTEGER, 16, 0},
                      {"i32", "SIGNED_32", "int", "int", SIGNED_INTEGER, 31, 0},
                      {"u32", "UNSIGNED_32", "uint", "int", UNSIGNED_INTEGER, 32, 0},
                      {"i64", "SIGNED_64", "long", "long", SIGNED_INTEGER, 63, 0},
                      {"u64", "UNSIGNED_64", "ulong", "long", UNSIGNED_INTEGER, 64, 0}};

const int NUM_TYPES = sizeof(TYPES) / sizeof(TYPES[0]);

// Returns the index in TYPES for the provided cType
int FindCType(const string& cType) {
    for (int i = 0; i < NUM_TYPES; i++) {
        if (cType == TYPES[i].cType) {
            return i;
        }
    }
    return -1;
}

// Capitalizes and removes underscores.  E.g. converts "native_log" to NativeLog.
string capitalize(const string& source) {
    int length = source.length();
    string result;
    bool capitalize = true;
    for (int s = 0; s < length; s++) {
        if (source[s] == '_') {
            capitalize = true;
        } else if (capitalize) {
            result += toupper(source[s]);
            capitalize = false;
        } else {
            result += source[s];
        }
    }
    return result;
}

string tab(int n) { return string(n * 4, ' '); }

// Returns a string that's an hexadecimal constant fo the hash of the string.
string hashString(const string& s) {
    long hash = 0;
    for (size_t i = 0; i < s.length(); i++) {
        hash = hash * 43 + s[i];
    }
    stringstream stream;
    stream << "0x" << std::hex << hash << "l";
    return stream.str();
}

// Removes the character from present. Returns true if the string contained the character.
static bool charRemoved(char c, string* s) {
    size_t p = s->find(c);
    if (p != string::npos) {
        s->erase(p, 1);
        return true;
    }
    return false;
}

// Return true if the string is already in the set.  Inserts it if not.
bool testAndSet(const string& flag, set<string>* set) {
    if (set->find(flag) == set->end()) {
        set->insert(flag);
        return false;
    }
    return true;
}

// Convert an int into a string.
string toString(int n) {
    char buf[100];
    snprintf(buf, sizeof(buf), "%d", n);
    return string(buf);
}

void trim(string* s, size_t start) {
    if (start > 0) {
        s->erase(0, start);
    }

    while (s->size() && (s->at(0) == ' ')) {
        s->erase(0, 1);
    }

    size_t p = s->find_first_of("\n\r");
    if (p != string::npos) {
        s->erase(p);
    }

    while ((s->size() > 0) && (s->at(s->size() - 1) == ' ')) {
        s->erase(s->size() - 1);
    }
}

string stringReplace(string s, string match, string rep) {
    while (1) {
        size_t p = s.find(match);
        if (p == string::npos) break;

        s.erase(p, match.size());
        s.insert(p, rep);
    }
    return s;
}

// Return the next line from the input file.
bool getNextLine(FILE* in, string* s) {
    s->clear();
    while (1) {
        int c = fgetc(in);
        if (c == EOF) return s->size() != 0;
        if (c == '\n') break;
        s->push_back((char)c);
    }
    return true;
}

void writeIfdef(ofstream& file, string filename, bool isStart) {
    string t = "__";
    t += filename;
    t += "__";

    for (size_t i = 2; i < t.size(); i++) {
        if (t[i] == '.') {
            t[i] = '_';
        }
    }

    if (isStart) {
        file << "#ifndef " << t << "\n";
        file << "#define " << t << "\n";
    } else {
        file << "#endif // " << t << "\n";
    }
}

void writeJavaArrayInitialization(ofstream& file, const ParameterDefinition& p) {
    file << tab(2) << p.javaBaseType << "[] " << p.javaArrayName << " = new " << p.javaBaseType
         << "[INPUTSIZE * " << p.vectorWidth << "];\n";
    file << tab(2) << p.javaAllocName << ".copyTo(" << p.javaArrayName << ");\n";
}

bool parseCommandLine(int argc, char* argv[], int* versionOfTestFiles,
                      vector<string>* specFileNames) {
    for (int i = 1; i < argc; i++) {
        if (argv[i][0] == '-') {
            if (argv[i][1] == 'v') {
                i++;
                if (i < argc) {
                    char* end;
                    *versionOfTestFiles = strtol(argv[i], &end, 10);
                    if (*end != '\0') {
                        printf("Can't parse the version number %s\n", argv[i]);
                        return false;
                    }
                } else {
                    printf("Missing version number after -v\n");
                    return false;
                }
            } else {
                printf("Unrecognized flag %s\n", argv[i]);
                return false;
            }
        } else {
            specFileNames->push_back(argv[i]);
        }
    }
    if (specFileNames->size() == 0) {
        printf("No spec file specified\n");
        return false;
    }
    return true;
}

/* Returns a double that should be able to be converted to an integer of size
 * numberOfIntegerBits.
 */
static double MaxDoubleForInteger(int numberOfIntegerBits, int mantissaSize) {
    /* Double has only 52 bits of precision (53 implied). So for longs, we want
     * to create smaller values to avoid a round up.  Same for floats and halfs.
     */
    int lowZeroBits = max(0, numberOfIntegerBits - mantissaSize);
    unsigned long l = (0xffffffffffffffff >> (64 - numberOfIntegerBits + lowZeroBits))
                      << lowZeroBits;
    return (double)l;
}

/* Parse a parameter definition.  It's of the form "type [*][name]".  The type
 * is required.  The name is optional.  The * indicates it's an output
 * parameter.  We also pass the indexed of this parameter in the definition, so
 * we can create names like in2, in3, etc. */
void ParameterDefinition::parseParameterDefinition(string s, bool isReturn, int* inputCount,
                                                   int* outputCount) {
    istringstream stream(s);
    string name, type, option;
    stream >> rsType;
    stream >> specName;
    stream >> option;

    // Determine if this is an output.
    isOutParameter = charRemoved('*', &rsType) || charRemoved('*', &specName) || isReturn;

    // Extract the vector size out of the type.
    int last = rsType.size() - 1;
    char lastChar = rsType[last];
    if (lastChar >= '0' && lastChar <= '9') {
        rsBaseType = rsType.substr(0, last);
        mVectorSize = lastChar;
    } else {
        rsBaseType = rsType;
        mVectorSize = "1";
    }
    if (mVectorSize == "3") {
        vectorWidth = "4";
    } else {
        vectorWidth = mVectorSize;
    }

    /* Create variable names to be used in the java and .rs files.  Because x and
     * y are reserved in .rs files, we prefix variable names with "in" or "out".
     */
    if (isOutParameter) {
        variableName = "out";
        if (!specName.empty()) {
            variableName += capitalize(specName);
        } else if (!isReturn) {
            variableName += toString(*outputCount);
        }
        (*outputCount)++;
    } else {
        variableName = "in";
        if (!specName.empty()) {
            variableName += capitalize(specName);
        } else if (*inputCount > 0) {
            variableName += toString(*inputCount);
        }
        (*inputCount)++;
    }
    rsAllocName = "gAlloc" + capitalize(variableName);
    javaAllocName = variableName;
    javaArrayName = "array" + capitalize(javaAllocName);

    // Process the option.
    undefinedIfOutIsNan = false;
    compatibleTypeIndex = -1;
    if (!option.empty()) {
        if (option.compare(0, 6, "range(") == 0) {
            size_t pComma = option.find(',');
            size_t pParen = option.find(')');
            if (pComma == string::npos || pParen == string::npos) {
                printf("Incorrect range %s\n", option.c_str());
            } else {
                minValue = option.substr(6, pComma - 6);
                maxValue = option.substr(pComma + 1, pParen - pComma - 1);
            }
        } else if (option.compare(0, 6, "above(") == 0) {
            size_t pParen = option.find(')');
            if (pParen == string::npos) {
                printf("Incorrect option %s\n", option.c_str());
            } else {
                smallerParameter = option.substr(6, pParen - 6);
            }
        } else if (option.compare(0, 11, "compatible(") == 0) {
            size_t pParen = option.find(')');
            if (pParen == string::npos) {
                printf("Incorrect option %s\n", option.c_str());
            } else {
                compatibleTypeIndex = FindCType(option.substr(11, pParen - 11));
            }
        } else if (option.compare(0, 11, "conditional") == 0) {
            undefinedIfOutIsNan = true;
        } else {
            printf("Unrecognized option %s\n", option.c_str());
        }
    }

    typeIndex = FindCType(rsBaseType);
    isFloatType = false;
    if (typeIndex < 0) {
        // TODO set a global flag when we encounter an error & abort
        printf("Error, could not find %s\n", rsBaseType.c_str());
    } else {
        javaBaseType = TYPES[typeIndex].javaType;
        specType = TYPES[typeIndex].specType;
        isFloatType = TYPES[typeIndex].exponentBits > 0;
    }
}

bool SpecFile::process(int versionOfTestFiles) {
    if (!readSpecFile()) {
        return false;
    }
    if (versionOfTestFiles == 0) {
        versionOfTestFiles = mLargestVersionNumber;
    }
    if (!generateFiles(versionOfTestFiles)) {
        return false;
    }
    printf("%s: %ld functions processed.\n", mSpecFileName.c_str(), mFunctionsMap.size());
    return true;
}

// Read the specification, adding the definitions to the global functions map.
bool SpecFile::readSpecFile() {
    FILE* specFile = fopen(mSpecFileName.c_str(), "rt");
    if (!specFile) {
        printf("Error opening input file: %s\n", mSpecFileName.c_str());
        return false;
    }

    mLargestVersionNumber = 0;
    while (1) {
        Specification* spec = Specification::scanSpecification(specFile);
        if (spec == NULL) {
            break;
        }
        getFunction(spec->getCleanName())->addSpecification(spec);
        int specMin = spec->getMinVersion();
        int specMax = spec->getMaxVersion();
        if (specMin && specMin > mLargestVersionNumber) {
            mLargestVersionNumber = specMin;
        }
        if (specMax && specMax > mLargestVersionNumber) {
            mLargestVersionNumber = specMax;
        }
    }

    fclose(specFile);
    return true;
}

bool SpecFile::generateFiles(int versionOfTestFiles) {
    printf("%s: Generating test files for version %d\n", mSpecFileName.c_str(), versionOfTestFiles);

    // The header file name should have the same base but with a ".rsh" extension.
    string headerFileName = mSpecFileName;
    size_t l = headerFileName.length();
    const char SPEC[] = ".spec";
    const int SPEC_SIZE = sizeof(SPEC) - 1;
    const int start = l - SPEC_SIZE;
    if (start >= 0 && headerFileName.compare(start, SPEC_SIZE, SPEC) == 0) {
        headerFileName.erase(start);
    }
    headerFileName += ".rsh";

    // Write the start of the header file.
    ofstream headerFile;
    headerFile.open(headerFileName.c_str(), ios::out | ios::trunc);
    if (!headerFile.is_open()) {
        printf("Error opening output file: %s\n", headerFileName.c_str());
        return false;
    }
    headerFile << LEGAL_NOTICE;
    headerFile << AUTO_GENERATED_WARNING;
    writeIfdef(headerFile, headerFileName, true);

    // Write the functions to the header and test files.
    bool success = writeAllFunctions(headerFile, versionOfTestFiles);

    // Finish the header file.
    writeIfdef(headerFile, headerFileName, false);
    headerFile.close();

    return success;
}

// Return the named function from the map.  Creates it if it's not there.
Function* SpecFile::getFunction(const string& name) {
    FunctionsIterator iter = mFunctionsMap.find(name);
    if (iter != mFunctionsMap.end()) {
        return iter->second;
    }
    Function* f = new Function(name);
    mFunctionsMap[name] = f;
    return f;
}

bool SpecFile::writeAllFunctions(ofstream& headerFile, int versionOfTestFiles) {
    bool success = true;
    for (FunctionsIterator iter = mFunctionsMap.begin(); iter != mFunctionsMap.end(); iter++) {
        Function* func = iter->second;
        if (!func->writeFiles(headerFile, versionOfTestFiles)) {
            success = false;
        }
    }
    return success;
}

Function::Function(const string& name) {
    mName = name;
    mCapitalizedName = capitalize(mName);
    mTestName = "Test" + mCapitalizedName;
    mRelaxedTestName = mTestName + "Relaxed";
}

bool Function::writeFiles(ofstream& headerFile, int versionOfTestFiles) {
    if (!startRsFile() || !startJavaFile() || !writeRelaxedRsFile()) {
        return false;
    }

    for (SpecificationIterator i = mSpecifications.begin(); i < mSpecifications.end(); i++) {
        (*i)->writeFiles(headerFile, mRsFile, mJavaFile, this, versionOfTestFiles);
    }

    finishJavaFile();
    // There's no work to wrap-up in the .rs file.

    mRsFile.close();
    mJavaFile.close();
    return true;
}

bool Function::startRsFile() {
    string fileName = mTestName + ".rs";
    mRsFile.open(fileName.c_str(), ios::out | ios::trunc);
    if (!mRsFile.is_open()) {
        printf("Error opening file: %s\n", fileName.c_str());
        return false;
    }
    mRsFile << LEGAL_NOTICE;
    mRsFile << "#pragma version(1)\n";
    mRsFile << "#pragma rs java_package_name(android.renderscript.cts)\n\n";
    mRsFile << AUTO_GENERATED_WARNING;
    return true;
}

// Write an allocation definition if not already emitted in the .rs file.
void Function::writeRsAllocationDefinition(const ParameterDefinition& param) {
    if (!testAndSet(param.rsAllocName, &mRsAllocationsGenerated)) {
        mRsFile << "rs_allocation " << param.rsAllocName << ";\n";
    }
}

// Write the entire *Relaxed.rs test file, as it only depends on the name.
bool Function::writeRelaxedRsFile() {
    string name = mRelaxedTestName + ".rs";
    FILE* file = fopen(name.c_str(), "wt");
    if (!file) {
        printf("Error opening file: %s\n", name.c_str());
        return false;
    }
    fputs(LEGAL_NOTICE, file);
    string s;
    s += "#include \"" + mTestName + ".rs\"\n";
    s += "#pragma rs_fp_relaxed\n";
    s += AUTO_GENERATED_WARNING;
    fputs(s.c_str(), file);
    fclose(file);
    return true;
}

bool Function::startJavaFile() {
    string fileName = mTestName + ".java";
    mJavaFile.open(fileName.c_str(), ios::out | ios::trunc);
    if (!mJavaFile.is_open()) {
        printf("Error opening file: %s\n", fileName.c_str());
        return false;
    }
    mJavaFile << LEGAL_NOTICE;
    mJavaFile << AUTO_GENERATED_WARNING;
    mJavaFile << "package android.renderscript.cts;\n\n";

    mJavaFile << "import android.renderscript.Allocation;\n";
    mJavaFile << "import android.renderscript.RSRuntimeException;\n";
    mJavaFile << "import android.renderscript.Element;\n\n";

    mJavaFile << "public class " << mTestName << " extends RSBaseCompute {\n\n";

    mJavaFile << tab(1) << "private ScriptC_" << mTestName << " script;\n";
    mJavaFile << tab(1) << "private ScriptC_" << mRelaxedTestName << " scriptRelaxed;\n\n";

    mJavaFile << tab(1) << "@Override\n";
    mJavaFile << tab(1) << "protected void setUp() throws Exception {\n";
    mJavaFile << tab(2) << "super.setUp();\n";
    mJavaFile << tab(2) << "script = new ScriptC_" << mTestName << "(mRS);\n";
    mJavaFile << tab(2) << "scriptRelaxed = new ScriptC_" << mRelaxedTestName << "(mRS);\n";
    mJavaFile << tab(1) << "}\n\n";
    return true;
}

void Function::writeJavaArgumentClassDefinition(const string& className, const string& definition) {
    if (!testAndSet(className, &mJavaGeneratedArgumentClasses)) {
        mJavaFile << definition;
    }
}

void Function::addJavaCheckCall(const string& call) {
    mJavaCallAllCheckMethods += tab(2) + call + "\n";
}

void Function::finishJavaFile() {
    mJavaFile << tab(1) << "public void test" << mCapitalizedName << "() {\n";
    mJavaFile << mJavaCallAllCheckMethods;
    mJavaFile << tab(1) << "}\n";
    mJavaFile << "}\n";
}

void Specification::expandStringVector(const vector<string>& in, int i1, int i2, int i3, int i4,
                                       vector<string>* out) const {
    out->clear();
    for (vector<string>::const_iterator iter = in.begin(); iter != in.end(); iter++) {
        out->push_back(expandString(*iter, i1, i2, i3, i4));
    }
}

Specification* Specification::scanSpecification(FILE* in) {
    Specification* spec = new Specification();
    spec->mTest = "scalar";  // default
    bool modeComment = false;
    bool modeInline = false;
    bool success = true;

    while (1) {
        string s;
        bool ret = getNextLine(in, &s);
        if (!ret) break;

        if (modeComment) {
            if (!s.size() || (s[0] == ' ')) {
                trim(&s, 0);
                spec->mComment.push_back(s);
                continue;
            } else {
                modeComment = false;
            }
        }

        if (modeInline) {
            if (!s.size() || (s[0] == ' ')) {
                trim(&s, 0);
                spec->mInline.push_back(s);
                continue;
            } else {
                modeInline = false;
            }
        }

        if (s[0] == '#') {
            continue;
        }

        if (s.compare(0, 5, "name:") == 0) {
            trim(&s, 5);
            spec->mName = s;
            // Some functions like convert have # part of the name.  Truncate at that point.
            size_t p = s.find('#');
            if (p != string::npos) {
                if (p > 0 && s[p - 1] == '_') {
                    p--;
                }
                s.erase(p);
            }
            spec->mCleanName = s;
            continue;
        }

        if (s.compare(0, 4, "arg:") == 0) {
            trim(&s, 4);
            spec->mParam.push_back(s);
            continue;
        }

        if (s.compare(0, 4, "ret:") == 0) {
            trim(&s, 4);
            spec->mReturn = s;
            continue;
        }

        if (s.compare(0, 5, "test:") == 0) {
            trim(&s, 5);
            if (s == "scalar" || s == "vector" || s == "noverify" || s == "none") {
                spec->mTest = s;
            } else if (s.compare(0, 7, "limited") == 0) {
                spec->mTest = "limited";
                if (s.compare(7, 1, "(") == 0) {
                    size_t pParen = s.find(')');
                    if (pParen == string::npos) {
                        printf("Incorrect test %s\n", s.c_str());
                    } else {
                        spec->mPrecisionLimit = s.substr(8, pParen - 8);
                    }
                }
            } else {
                printf("Error: Unrecognized test option: %s\n", s.c_str());
                success = false;
            }
            continue;
        }

        if (s.compare(0, 4, "end:") == 0) {
            if (success) {
                return spec;
            } else {
                delete spec;
                return NULL;
            }
        }

        if (s.compare(0, 8, "comment:") == 0) {
            modeComment = true;
            continue;
        }

        if (s.compare(0, 7, "inline:") == 0) {
            modeInline = true;
            continue;
        }

        if (s.compare(0, 8, "version:") == 0) {
            trim(&s, 8);
            sscanf(s.c_str(), "%i %i", &spec->mMinVersion, &spec->mMaxVersion);
            continue;
        }

        if (s.compare(0, 8, "start:") == 0) {
            continue;
        }

        if (s.compare(0, 2, "w:") == 0) {
            vector<string> t;
            if (s.find("1") != string::npos) {
                t.push_back("");
            }
            if (s.find("2") != string::npos) {
                t.push_back("2");
            }
            if (s.find("3") != string::npos) {
                t.push_back("3");
            }
            if (s.find("4") != string::npos) {
                t.push_back("4");
            }
            spec->mReplaceables.push_back(t);
            continue;
        }

        if (s.compare(0, 2, "t:") == 0) {
            vector<string> t;
            for (int i = 0; i < NUM_TYPES; i++) {
                if (s.find(TYPES[i].specType) != string::npos) {
                    t.push_back(TYPES[i].cType);
                }
            }
            spec->mReplaceables.push_back(t);
            continue;
        }

        if (s.size() == 0) {
            // eat empty line
            continue;
        }

        printf("Error, line:\n");
        printf("  %s\n", s.c_str());
    }

    delete spec;
    return NULL;
}

void Specification::writeFiles(ofstream& headerFile, ofstream& rsFile, ofstream& javaFile,
                               Function* function, int versionOfTestFiles) {
    int start[4];
    int end[4];
    for (int i = 0; i < 4; i++) {
        if (i < (int)mReplaceables.size()) {
            start[i] = 0;
            end[i] = mReplaceables[i].size();
        } else {
            start[i] = -1;
            end[i] = 0;
        }
    }
    for (int i4 = start[3]; i4 < end[3]; i4++) {
        for (int i3 = start[2]; i3 < end[2]; i3++) {
            for (int i2 = start[1]; i2 < end[1]; i2++) {
                for (int i1 = start[0]; i1 < end[0]; i1++) {
                    Permutation p(function, this, i1, i2, i3, i4);
                    p.writeFiles(headerFile, rsFile, javaFile, versionOfTestFiles);
                }
            }
        }
    }
}

bool Specification::relevantForVersion(int versionOfTestFiles) const {
    if (mMinVersion != 0 && mMinVersion > versionOfTestFiles) {
        return false;
    }
    if (mMaxVersion != 0 && mMaxVersion < versionOfTestFiles) {
        return false;
    }
    return true;
}

string Specification::expandString(string s, int i1, int i2, int i3, int i4) const {
    if (mReplaceables.size() > 0) {
        s = stringReplace(s, "#1", mReplaceables[0][i1]);
    }
    if (mReplaceables.size() > 1) {
        s = stringReplace(s, "#2", mReplaceables[1][i2]);
    }
    if (mReplaceables.size() > 2) {
        s = stringReplace(s, "#3", mReplaceables[2][i3]);
    }
    if (mReplaceables.size() > 3) {
        s = stringReplace(s, "#4", mReplaceables[3][i4]);
    }
    return s;
}

Permutation::Permutation(Function* func, Specification* spec, int i1, int i2, int i3, int i4)
    : mFunction(func),
      mSpecification(spec),
      mReturnIndex(-1),
      mFirstInputIndex(-1),
      mInputCount(0),
      mOutputCount(0) {
    // We expand the strings now to make capitalization easier.  The previous code preserved the #n
    // markers just before emitting, which made capitalization difficult.
    mName = spec->getName(i1, i2, i3, i4);
    mCleanName = spec->getCleanName();
    mTest = spec->getTest();
    mPrecisionLimit = spec->getPrecisionLimit();
    spec->getInlines(i1, i2, i3, i4, &mInline);
    spec->getComments(i1, i2, i3, i4, &mComment);

    vector<string> paramDefinitions;
    spec->getParams(i1, i2, i3, i4, &paramDefinitions);
    for (size_t i = 0; i < paramDefinitions.size(); i++) {
        ParameterDefinition* def = new ParameterDefinition();
        def->parseParameterDefinition(paramDefinitions[i], false, &mInputCount, &mOutputCount);
        if (!def->isOutParameter && mFirstInputIndex < 0) {
            mFirstInputIndex = mParams.size();
        }
        mParams.push_back(def);
    }

    const string s = spec->getReturn(i1, i2, i3, i4);
    if (!s.empty() && s != "void") {
        ParameterDefinition* def = new ParameterDefinition();
        // Adding "*" tells the parse method it's an output.
        def->parseParameterDefinition(s, true, &mInputCount, &mOutputCount);
        mReturnIndex = mParams.size();
        mParams.push_back(def);
    }

    mRsKernelName = "test" + capitalize(mName);
    mJavaArgumentsClassName = "Arguments";
    mJavaArgumentsNClassName = "Arguments";
    mJavaCheckMethodName = "check" + capitalize(mCleanName);
    mJavaVerifyMethodName = "verifyResults" + capitalize(mCleanName);
    for (int i = 0; i < (int)mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        mRsKernelName += capitalize(p.rsType);
        mJavaArgumentsClassName += capitalize(p.rsBaseType);
        mJavaArgumentsNClassName += capitalize(p.rsBaseType);
        if (p.mVectorSize != "1") {
            mJavaArgumentsNClassName += "N";
        }
        mJavaCheckMethodName += capitalize(p.rsType);
        mJavaVerifyMethodName += capitalize(p.rsType);
    }
    mJavaVerifierComputeMethodName = "compute" + capitalize(mCleanName);
}

#ifdef DISABLE_LONG_AND_DOUBLE_TESTS
// TODO Remove once we have long/double copyTo/copyFrom
bool Permutation::hasLongOrDoubleParameter() const {
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (p.javaBaseType == "long" || p.javaBaseType == "double") {
            return true;
        }
    }
    return false;
}
#endif

void Permutation::writeFiles(ofstream& headerFile, ofstream& rsFile, ofstream& javaFile,
                             int versionOfTestFiles) {
    writeHeaderSection(headerFile);
#ifdef DISABLE_LONG_AND_DOUBLE_TESTS
    if (hasLongOrDoubleParameter()) {
        printf("Warning: skipping a test for %s as we don't support long or double arguments (due "
               "to Allocation not supporting them).\n",
               mName.c_str());
        return;
    }
#endif
    if (mSpecification->relevantForVersion(versionOfTestFiles) && mTest != "none") {
        writeRsSection(rsFile);
        writeJavaSection(javaFile);
    }
}

void Permutation::writeHeaderSection(ofstream& file) const {
    int minVersion = mSpecification->getMinVersion();
    int maxVersion = mSpecification->getMaxVersion();
    bool hasVersion = minVersion || maxVersion;

    if (hasVersion) {
        if (maxVersion) {
            file << "#if (defined(RS_VERSION) && (RS_VERSION >= " << minVersion
                 << ") && (RS_VERSION <= " << maxVersion << "))\n";
        } else {
            file << "#if (defined(RS_VERSION) && (RS_VERSION >= " << minVersion << "))\n";
        }
    }

    file << "/*\n";
    for (size_t ct = 0; ct < mComment.size(); ct++) {
        if (!mComment[ct].empty()) {
            file << " * " << mComment[ct] << "\n";
        } else {
            file << " *\n";
        }
    }
    file << " *\n";
    if (minVersion || maxVersion) {
        if (maxVersion) {
            file << " * Suppored by API versions " << minVersion << " - " << maxVersion << "\n";
        } else {
            file << " * Supported by API versions " << minVersion << " and newer.\n";
        }
    }
    file << " */\n";
    if (mInline.size() > 0) {
        file << "static ";
    } else {
        file << "extern ";
    }
    if (mReturnIndex >= 0) {
        file << mParams[mReturnIndex]->rsType;
    } else {
        file << "void";
    }
    file << " __attribute__((";
    if (mOutputCount <= 1) {
        file << "const, ";
    }
    file << "overloadable))";
    file << mName;
    file << "(";
    bool needComma = false;
    for (int i = 0; i < (int)mParams.size(); i++) {
        if (i != mReturnIndex) {
            const ParameterDefinition& p = *mParams[i];
            if (needComma) {
                file << ", ";
            }
            file << p.rsType;
            if (p.isOutParameter) {
                file << "*";
            }
            if (!p.specName.empty()) {
                file << " " << p.specName;
            }
            needComma = true;
        }
    }
    if (mInline.size() > 0) {
        file << ") {\n";
        for (size_t ct = 0; ct < mInline.size(); ct++) {
            file << " " << mInline[ct].c_str() << "\n";
        }
        file << "}\n";
    } else {
        file << ");\n";
    }
    if (hasVersion) {
        file << "#endif\n";
    }
    file << "\n";
}

/* Write the section of the .rs file for this permutation.
 *
 * We communicate the extra input and output parameters via global allocations.
 * For example, if we have a function that takes three arguments, two for input
 * and one for output:
 *
 * start:
 * name: gamn
 * ret: float3
 * arg: float3 a
 * arg: int b
 * arg: float3 *c
 * end:
 *
 * We'll produce:
 *
 * rs_allocation gAllocInB;
 * rs_allocation gAllocOutC;
 *
 * float3 __attribute__((kernel)) test_gamn_float3_int_float3(float3 inA, unsigned int x) {
 *    int inB;
 *    float3 outC;
 *    float2 out;
 *    inB = rsGetElementAt_int(gAllocInB, x);
 *    out = gamn(a, in_b, &outC);
 *    rsSetElementAt_float4(gAllocOutC, &outC, x);
 *    return out;
 * }
 *
 * We avoid re-using x and y from the definition because these have reserved
 * meanings in a .rs file.
 */
void Permutation::writeRsSection(ofstream& rs) const {
    // Write the allocation declarations we'll need.
    for (int i = 0; i < (int)mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        // Don't need allocation for one input and one return value.
        if (i != mReturnIndex && i != mFirstInputIndex) {
            mFunction->writeRsAllocationDefinition(p);
        }
    }
    rs << "\n";

    // Write the function header.
    if (mReturnIndex >= 0) {
        rs << mParams[mReturnIndex]->rsType;
    } else {
        rs << "void";
    }
    rs << " __attribute__((kernel)) " << mRsKernelName;
    rs << "(";
    bool needComma = false;
    if (mFirstInputIndex >= 0) {
        rs << mParams[mFirstInputIndex]->rsType << " " << mParams[mFirstInputIndex]->variableName;
        needComma = true;
    }
    if (mOutputCount > 1 || mInputCount > 1) {
        if (needComma) {
            rs << ", ";
        }
        rs << "unsigned int x";
    }
    rs << ") {\n";

    // Write the local variable declarations and initializations.
    for (int i = 0; i < (int)mParams.size(); i++) {
        if (i == mFirstInputIndex || i == mReturnIndex) {
            continue;
        }
        const ParameterDefinition& p = *mParams[i];
        rs << tab(1) << p.rsType << " " << p.variableName;
        if (p.isOutParameter) {
            rs << " = 0;\n";
        } else {
            rs << " = rsGetElementAt_" << p.rsType << "(" << p.rsAllocName << ", x);\n";
        }
    }

    // Write the function call.
    if (mReturnIndex >= 0) {
        if (mOutputCount > 1) {
            rs << tab(1) << mParams[mReturnIndex]->rsType << " "
               << mParams[mReturnIndex]->variableName << " = ";
        } else {
            rs << tab(1) << "return ";
        }
    }
    rs << mName << "(";
    needComma = false;
    for (int i = 0; i < (int)mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (i == mReturnIndex) {
            continue;
        }
        if (needComma) {
            rs << ", ";
        }
        if (p.isOutParameter) {
            rs << "&";
        }
        rs << p.variableName;
        needComma = true;
    }
    rs << ");\n";

    if (mOutputCount > 1) {
        // Write setting the extra out parameters into the allocations.
        for (int i = 0; i < (int)mParams.size(); i++) {
            const ParameterDefinition& p = *mParams[i];
            if (p.isOutParameter && i != mReturnIndex) {
                rs << tab(1) << "rsSetElementAt_" << p.rsType << "(" << p.rsAllocName << ", ";
                if (passByAddressToSet(p.variableName)) {
                    rs << "&";
                }
                rs << p.variableName << ", x);\n";
            }
        }
        if (mReturnIndex >= 0) {
            rs << tab(1) << "return " << mParams[mReturnIndex]->variableName << ";\n";
        }
    }
    rs << "}\n";
}

bool Permutation::passByAddressToSet(const string& name) const {
    string s = name;
    int last = s.size() - 1;
    char lastChar = s[last];
    return lastChar >= '0' && lastChar <= '9';
}

void Permutation::writeJavaSection(ofstream& file) const {
    // By default, we test the results using item by item comparison.
    if (mTest == "scalar" || mTest == "limited") {
        writeJavaArgumentClass(file, true);
        writeJavaCheckMethod(file, true);
        writeJavaVerifyScalarMethod(file);
    } else if (mTest == "vector") {
        writeJavaArgumentClass(file, false);
        writeJavaCheckMethod(file, true);
        writeJavaVerifyVectorMethod(file);
    } else if (mTest == "noverify") {
        writeJavaCheckMethod(file, false);
    }

    // Register the check method to be called.  This code will be written at the end.
    mFunction->addJavaCheckCall(mJavaCheckMethodName + "();");
}

void Permutation::writeJavaArgumentClass(ofstream& file, bool scalar) const {
    string name;
    if (scalar) {
        name = mJavaArgumentsClassName;
    } else {
        name = mJavaArgumentsNClassName;
    }
    string s;
    s += tab(1) + "public class " + name + " {\n";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        s += tab(2) + "public ";
        if (p.isOutParameter && p.isFloatType) {
            s += "Floaty";
        } else {
            s += p.javaBaseType;
        }
        if (!scalar && p.mVectorSize != "1") {
            s += "[]";
        }
        s += " " + p.variableName + ";\n";
    }
    s += tab(1) + "}\n\n";

    mFunction->writeJavaArgumentClassDefinition(name, s);
}

void Permutation::writeJavaCheckMethod(ofstream& file, bool generateCallToVerify) const {
    file << tab(1) << "private void " << mJavaCheckMethodName << "() {\n";
    // Generate the input allocations and initialization.
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (!p.isOutParameter) {
            writeJavaInputAllocationDefinition(file, tab(2), p);
        }
    }
    // Enforce ordering if needed.
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (!p.isOutParameter && !p.smallerParameter.empty()) {
            string smallerAlloc = "in" + capitalize(p.smallerParameter);
            file << tab(2) << "enforceOrdering(" << smallerAlloc << ", " << p.javaAllocName
                 << ");\n";
        }
    }
    writeJavaCallToRs(file, false, generateCallToVerify);
    writeJavaCallToRs(file, true, generateCallToVerify);
    file << tab(1) << "}\n\n";
}

void Permutation::writeJavaInputAllocationDefinition(ofstream& file, const string& indent,
                                                     const ParameterDefinition& param) const {
    string dataType;
    char vectorSize;
    convertToRsType(param.rsType, &dataType, &vectorSize);

    string seed = hashString(mJavaCheckMethodName + param.javaAllocName);
    file << indent << "Allocation " << param.javaAllocName << " = ";
    if (param.compatibleTypeIndex >= 0) {
        if (TYPES[param.typeIndex].kind == FLOATING_POINT) {
            writeJavaRandomCompatibleFloatAllocation(file, dataType, seed, vectorSize,
                                                     TYPES[param.compatibleTypeIndex],
                                                     TYPES[param.typeIndex]);
        } else {
            writeJavaRandomCompatibleIntegerAllocation(file, dataType, seed, vectorSize,
                                                       TYPES[param.compatibleTypeIndex],
                                                       TYPES[param.typeIndex]);
        }
    } else if (!param.minValue.empty()) {
        if (TYPES[param.typeIndex].kind != FLOATING_POINT) {
            printf("range(,) is only supported for floating point\n");
        } else {
            file << "createRandomFloatAllocation(mRS, Element.DataType." << dataType << ", "
                 << vectorSize << ", " << seed << ", " << param.minValue << ", " << param.maxValue
                 << ")";
        }
    } else {
        file << "createRandomAllocation(mRS, Element.DataType." << dataType << ", " << vectorSize
             << ", " << seed << ", false)";  // TODO set to false only for native
    }
    file << ";\n";
}

void Permutation::writeJavaRandomCompatibleFloatAllocation(ofstream& file, const string& dataType,
                                                           const string& seed, char vectorSize,
                                                           const Type& compatibleType,
                                                           const Type& generatedType) const {
    file << "createRandomFloatAllocation"
         << "(mRS, Element.DataType." << dataType << ", " << vectorSize << ", " << seed << ", ";
    double minValue = 0.0;
    double maxValue = 0.0;
    switch (compatibleType.kind) {
        case FLOATING_POINT: {
            // We're generating floating point values.  We just worry about the exponent.
            // Subtract 1 for the exponent sign.
            int bits = min(compatibleType.exponentBits, generatedType.exponentBits) - 1;
            maxValue = ldexp(0.95, (1 << bits) - 1);
            minValue = -maxValue;
            break;
        }
        case UNSIGNED_INTEGER:
            maxValue = MaxDoubleForInteger(compatibleType.significantBits,
                                           generatedType.significantBits);
            minValue = 0.0;
            break;
        case SIGNED_INTEGER:
            maxValue = MaxDoubleForInteger(compatibleType.significantBits,
                                           generatedType.significantBits);
            minValue = -maxValue - 1.0;
            break;
    }
    file << scientific << std::setprecision(19);
    file << minValue << ", " << maxValue << ")";
    file.unsetf(ios_base::floatfield);
}

void Permutation::writeJavaRandomCompatibleIntegerAllocation(ofstream& file, const string& dataType,
                                                             const string& seed, char vectorSize,
                                                             const Type& compatibleType,
                                                             const Type& generatedType) const {
    file << "createRandomIntegerAllocation"
         << "(mRS, Element.DataType." << dataType << ", " << vectorSize << ", " << seed << ", ";

    if (compatibleType.kind == FLOATING_POINT) {
        // Currently, all floating points can take any number we generate.
        bool isSigned = generatedType.kind == SIGNED_INTEGER;
        file << (isSigned ? "true" : "false") << ", " << generatedType.significantBits;
    } else {
        bool isSigned =
                    compatibleType.kind == SIGNED_INTEGER && generatedType.kind == SIGNED_INTEGER;
        file << (isSigned ? "true" : "false") << ", "
             << min(compatibleType.significantBits, generatedType.significantBits);
    }
    file << ")";
}

void Permutation::writeJavaOutputAllocationDefinition(ofstream& file, const string& indent,
                                                      const ParameterDefinition& param) const {
    string dataType;
    char vectorSize;
    convertToRsType(param.rsType, &dataType, &vectorSize);
    file << indent << "Allocation " << param.javaAllocName << " = Allocation.createSized(mRS, "
         << "getElement(mRS, Element.DataType." << dataType << ", " << vectorSize
         << "), INPUTSIZE);\n";
}

// Converts float2 to FLOAT_32 and 2, etc.
void Permutation::convertToRsType(const string& name, string* dataType, char* vectorSize) const {
    string s = name;
    int last = s.size() - 1;
    char lastChar = s[last];
    if (lastChar >= '1' && lastChar <= '4') {
        s.erase(last);
        *vectorSize = lastChar;
    } else {
        *vectorSize = '1';
    }
    dataType->clear();
    for (int i = 0; i < NUM_TYPES; i++) {
        if (s == TYPES[i].cType) {
            *dataType = TYPES[i].rsDataType;
            break;
        }
    }
}

void Permutation::writeJavaVerifyScalarMethod(ofstream& file) const {
    writeJavaVerifyFunctionHeader(file);
    string vectorSize = "1";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        writeJavaArrayInitialization(file, p);
        if (p.mVectorSize != "1" && p.mVectorSize != vectorSize) {
            if (vectorSize == "1") {
                vectorSize = p.mVectorSize;
            } else {
                printf("Yikes, had vector %s and %s\n", vectorSize.c_str(), p.mVectorSize.c_str());
            }
        }
    }

    file << tab(2) << "for (int i = 0; i < INPUTSIZE; i++) {\n";
    file << tab(3) << "for (int j = 0; j < " << vectorSize << " ; j++) {\n";

    file << tab(4) << "// Extract the inputs.\n";
    file << tab(4) << mJavaArgumentsClassName << " args = new " << mJavaArgumentsClassName
         << "();\n";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (!p.isOutParameter) {
            file << tab(4) << "args." << p.variableName << " = " << p.javaArrayName << "[i";
            if (p.vectorWidth != "1") {
                file << " * " << p.vectorWidth << " + j";
            }
            file << "];\n";
        }
    }

    file << tab(4) << "// Figure out what the outputs should have been.\n";
    file << tab(4) << "Floaty.setRelaxed(relaxed);\n";
    file << tab(4) << "CoreMathVerifier." << mJavaVerifierComputeMethodName << "(args);\n";

    file << tab(4) << "// Figure out what the outputs should have been.\n";
    file << tab(4) << "boolean valid = true;\n";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (p.isOutParameter) {
            writeJavaTestAndSetValid(file, 4, p, "", "[i * " + p.vectorWidth + " + j]");
        }
    }

    file << tab(4) << "if (!valid) {\n";
    file << tab(5) << "StringBuilder message = new StringBuilder();\n";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (p.isOutParameter) {
            writeJavaAppendOutputToMessage(file, 5, p, "", "[i * " + p.vectorWidth + " + j]");
        } else {
            writeJavaAppendInputToMessage(file, 5, p, "args." + p.variableName);
        }
    }

    file << tab(5) << "assertTrue(\"Incorrect output for " << mJavaCheckMethodName << "\" +\n";
    file << tab(7) << "(relaxed ? \"_relaxed\" : \"\") + \":\\n\" + message.toString(), valid);\n";
    file << tab(4) << "}\n";
    file << tab(3) << "}\n";
    file << tab(2) << "}\n";
    file << tab(1) << "}\n\n";
}

void Permutation::writeJavaVerifyFunctionHeader(ofstream& file) const {
    file << tab(1) << "private void " << mJavaVerifyMethodName << "(";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        file << "Allocation " << p.javaAllocName << ", ";
    }
    file << "boolean relaxed) {\n";
}

void Permutation::writeJavaTestAndSetValid(ofstream& file, int indent, const ParameterDefinition& p,
                                           const string& argsIndex,
                                           const string& actualIndex) const {
    writeJavaTestOneValue(file, indent, p, argsIndex, actualIndex);
    file << tab(indent + 1) << "valid = false;\n";
    file << tab(indent) << "}\n";
}

void Permutation::writeJavaTestOneValue(ofstream& file, int indent, const ParameterDefinition& p,
                                        const string& argsIndex, const string& actualIndex) const {
    file << tab(indent) << "if (";
    if (p.isFloatType) {
        file << "!args." << p.variableName << argsIndex << ".couldBe(" << p.javaArrayName
             << actualIndex;
        if (!mPrecisionLimit.empty()) {
            file << ", " << mPrecisionLimit;
        }
        file << ")";
    } else {
        file << "args." << p.variableName << argsIndex << " != " << p.javaArrayName << actualIndex;
    }
    if (p.undefinedIfOutIsNan && mReturnIndex >= 0) {
        file << " && args." << mParams[mReturnIndex]->variableName << argsIndex << ".isNaN()";
    }
    file << ") {\n";
}

void Permutation::writeJavaAppendOutputToMessage(ofstream& file, int indent,
                                                 const ParameterDefinition& p,
                                                 const string& argsIndex,
                                                 const string& actualIndex) const {
    const string expected = "args." + p.variableName + argsIndex;
    const string actual = p.javaArrayName + actualIndex;
    file << tab(indent) << "message.append(\"Expected output " + p.variableName + ": \");\n";
    if (p.isFloatType) {
        writeJavaAppendFloatyVariableToMessage(file, indent, expected);
    } else {
        writeJavaAppendVariableToMessage(file, indent, p, expected);
    }
    writeJavaAppendNewLineToMessage(file, indent);
    file << tab(indent) << "message.append(\"Actual   output " + p.variableName + ": \");\n";
    writeJavaAppendVariableToMessage(file, indent, p, actual);

    writeJavaTestOneValue(file, indent, p, argsIndex, actualIndex);
    file << tab(indent + 1) << "message.append(\" FAIL\");\n";
    file << tab(indent) << "}\n";
    writeJavaAppendNewLineToMessage(file, indent);
}

void Permutation::writeJavaAppendInputToMessage(ofstream& file, int indent,
                                                const ParameterDefinition& p,
                                                const string& actual) const {
    file << tab(indent) << "message.append(\"Input " + p.variableName + ": \");\n";
    writeJavaAppendVariableToMessage(file, indent, p, actual);
    writeJavaAppendNewLineToMessage(file, indent);
}

void Permutation::writeJavaAppendNewLineToMessage(ofstream& file, int indent) const {
    file << tab(indent) << "message.append(\"\\n\");\n";
}

void Permutation::writeJavaAppendVariableToMessage(ofstream& file, int indent,
                                                   const ParameterDefinition& p,
                                                   const string& value) const {
    if (p.specType == "f16" || p.specType == "f32") {
        file << tab(indent) << "message.append(String.format(\"%14.8g %8x %15a\",\n";
        file << tab(indent + 2) << value << ", "
             << "Float.floatToRawIntBits(" << value << "), " << value << "));\n";
    } else if (p.specType == "f64") {
        file << tab(indent) << "message.append(String.format(\"%24.8g %16x %31a\",\n";
        file << tab(indent + 2) << value << ", "
             << "Double.doubleToRawLongBits(" << value << "), " << value << "));\n";
    } else if (p.specType[0] == 'u') {
        file << tab(indent) << "message.append(String.format(\"0x%x\", " << value << "));\n";
    } else {
        file << tab(indent) << "message.append(String.format(\"%d\", " << value << "));\n";
    }
}

void Permutation::writeJavaAppendFloatyVariableToMessage(ofstream& file, int indent,
                                                         const string& value) const {
    file << tab(indent) << "message.append(" << value << ".toString());\n";
}

void Permutation::writeJavaVectorComparison(ofstream& file, int indent,
                                            const ParameterDefinition& p) const {
    if (p.mVectorSize == "1") {
        writeJavaTestAndSetValid(file, indent, p, "", "[i]");

    } else {
        file << tab(indent) << "for (int j = 0; j < " << p.mVectorSize << " ; j++) {\n";
        writeJavaTestAndSetValid(file, indent + 1, p, "[j]", "[i * " + p.vectorWidth + " + j]");
        file << tab(indent) << "}\n";
    }
}

void Permutation::writeJavaAppendVectorInputToMessage(ofstream& file, int indent,
                                                      const ParameterDefinition& p) const {
    if (p.mVectorSize == "1") {
        writeJavaAppendInputToMessage(file, indent, p, p.javaArrayName + "[i]");
    } else {
        file << tab(indent) << "for (int j = 0; j < " << p.mVectorSize << " ; j++) {\n";
        writeJavaAppendInputToMessage(file, indent + 1, p,
                                      p.javaArrayName + "[i * " + p.vectorWidth + " + j]");
        file << tab(indent) << "}\n";
    }
}

void Permutation::writeJavaAppendVectorOutputToMessage(ofstream& file, int indent,
                                                       const ParameterDefinition& p) const {
    if (p.mVectorSize == "1") {
        writeJavaAppendOutputToMessage(file, indent, p, "", "[i]");

    } else {
        file << tab(indent) << "for (int j = 0; j < " << p.mVectorSize << " ; j++) {\n";
        writeJavaAppendOutputToMessage(file, indent + 1, p, "[j]",
                                       "[i * " + p.vectorWidth + " + j]");
        file << tab(indent) << "}\n";
    }
}

void Permutation::writeJavaVerifyVectorMethod(ofstream& file) const {
    writeJavaVerifyFunctionHeader(file);
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        writeJavaArrayInitialization(file, p);
    }
    file << tab(2) + "for (int i = 0; i < INPUTSIZE; i++) {\n";
    file << tab(3) << mJavaArgumentsNClassName << " args = new " << mJavaArgumentsNClassName
         << "();\n";

    file << tab(3) << "// Create the appropriate sized arrays in args\n";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (p.mVectorSize != "1") {
            string type = p.javaBaseType;
            if (p.isOutParameter && p.isFloatType) {
                type = "Floaty";
            }
            file << tab(3) << "args." << p.variableName << " = new " << type << "[" << p.mVectorSize
                 << "];\n";
        }
    }

    file << tab(3) << "// Fill args with the input values\n";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (!p.isOutParameter) {
            if (p.mVectorSize == "1") {
                file << tab(3) << "args." << p.variableName << " = " << p.javaArrayName + "[i]"
                     << ";\n";
            } else {
                file << tab(3) << "for (int j = 0; j < " << p.mVectorSize << " ; j++) {\n";
                file << tab(4) << "args." << p.variableName + "[j] = "
                     << p.javaArrayName + "[i * " + p.vectorWidth + " + j]"
                     << ";\n";
                file << tab(3) << "}\n";
            }
        }
    }
    file << tab(3) << "Floaty.setRelaxed(relaxed);\n";
    file << tab(3) << "CoreMathVerifier." << mJavaVerifierComputeMethodName << "(args);\n\n";

    file << tab(3) << "// Compare the expected outputs to the actual values returned by RS.\n";
    file << tab(3) << "boolean valid = true;\n";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (p.isOutParameter) {
            writeJavaVectorComparison(file, 3, p);
        }
    }

    file << tab(3) << "if (!valid) {\n";
    file << tab(4) << "StringBuilder message = new StringBuilder();\n";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (p.isOutParameter) {
            writeJavaAppendVectorOutputToMessage(file, 4, p);
        } else {
            writeJavaAppendVectorInputToMessage(file, 4, p);
        }
    }

    file << tab(4) << "assertTrue(\"Incorrect output for " << mJavaCheckMethodName << "\" +\n";
    file << tab(6) << "(relaxed ? \"_relaxed\" : \"\") + \":\\n\" + message.toString(), valid);\n";
    file << tab(3) << "}\n";
    file << tab(2) << "}\n";
    file << tab(1) << "}\n\n";
}

void Permutation::writeJavaCallToRs(ofstream& file, bool relaxed, bool generateCallToVerify) const {
    string script = "script";
    if (relaxed) {
        script += "Relaxed";
    }

    file << tab(2) << "try {\n";
    for (size_t i = 0; i < mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (p.isOutParameter) {
            writeJavaOutputAllocationDefinition(file, tab(3), p);
        }
    }

    for (int i = 0; i < (int)mParams.size(); i++) {
        const ParameterDefinition& p = *mParams[i];
        if (i != mReturnIndex && i != mFirstInputIndex) {
            file << tab(3) << script << ".set_" << p.rsAllocName << "(" << p.javaAllocName
                 << ");\n";
        }
    }

    file << tab(3) << script << ".forEach_" << mRsKernelName << "(";
    bool needComma = false;
    if (mFirstInputIndex >= 0) {
        file << mParams[mFirstInputIndex]->javaAllocName;
        needComma = true;
    }
    if (mReturnIndex >= 0) {
        if (needComma) {
            file << ", ";
        }
        file << mParams[mReturnIndex]->variableName << ");\n";
    }

    if (generateCallToVerify) {
        file << tab(3) << mJavaVerifyMethodName << "(";
        for (size_t i = 0; i < mParams.size(); i++) {
            const ParameterDefinition& p = *mParams[i];
            file << p.variableName << ", ";
        }

        if (relaxed) {
            file << "true";
        } else {
            file << "false";
        }
        file << ");\n";
    }
    file << tab(2) << "} catch (Exception e) {\n";
    file << tab(3) << "throw new RSRuntimeException(\"RenderScript. Can't invoke forEach_"
         << mRsKernelName << ": \" + e.toString());\n";
    file << tab(2) << "}\n";
}

}  // namespace

int main(int argc, char* argv[]) {
    int versionOfTestFiles = 0;
    vector<string> specFileNames;
    if (!parseCommandLine(argc, argv, &versionOfTestFiles, &specFileNames)) {
        printf("Usage: gen_runtime spec_file [spec_file...] [-v version_of_test_files]\n");
        return -1;
    }
    int result = 0;
    for (size_t i = 0; i < specFileNames.size(); i++) {
        SpecFile specFile(specFileNames[i]);
        if (!specFile.process(versionOfTestFiles)) {
            result = -1;
        }
    }
    return result;
}
