void
JVariableValue::Print
	(
	ostream& output
	)
	const
{
	PrintVariable(output);
}
void
JDiscreteEquality::Print
	(
	ostream& output
	)
	const
{
	PrintVariable(output);
	output << ' ' << JPGetEqualityString() << ' ';
	const JString& valueName =
		(GetVariableList())->GetDiscreteValueName(GetVariableIndex(), itsValue);
	valueName.Print(output);
}
void PrintVariable(const std::string &prefix, size_t index, const sh::ShaderVariable &var)
{
    std::string typeName;
    switch (var.type)
    {
      case GL_FLOAT: typeName = "GL_FLOAT"; break;
      case GL_FLOAT_VEC2: typeName = "GL_FLOAT_VEC2"; break;
      case GL_FLOAT_VEC3: typeName = "GL_FLOAT_VEC3"; break;
      case GL_FLOAT_VEC4: typeName = "GL_FLOAT_VEC4"; break;
      case GL_INT: typeName = "GL_INT"; break;
      case GL_INT_VEC2: typeName = "GL_INT_VEC2"; break;
      case GL_INT_VEC3: typeName = "GL_INT_VEC3"; break;
      case GL_INT_VEC4: typeName = "GL_INT_VEC4"; break;
      case GL_UNSIGNED_INT: typeName = "GL_UNSIGNED_INT"; break;
      case GL_UNSIGNED_INT_VEC2: typeName = "GL_UNSIGNED_INT_VEC2"; break;
      case GL_UNSIGNED_INT_VEC3: typeName = "GL_UNSIGNED_INT_VEC3"; break;
      case GL_UNSIGNED_INT_VEC4: typeName = "GL_UNSIGNED_INT_VEC4"; break;
      case GL_BOOL: typeName = "GL_BOOL"; break;
      case GL_BOOL_VEC2: typeName = "GL_BOOL_VEC2"; break;
      case GL_BOOL_VEC3: typeName = "GL_BOOL_VEC3"; break;
      case GL_BOOL_VEC4: typeName = "GL_BOOL_VEC4"; break;
      case GL_FLOAT_MAT2: typeName = "GL_FLOAT_MAT2"; break;
      case GL_FLOAT_MAT3: typeName = "GL_FLOAT_MAT3"; break;
      case GL_FLOAT_MAT4: typeName = "GL_FLOAT_MAT4"; break;
      case GL_FLOAT_MAT2x3: typeName = "GL_FLOAT_MAT2x3"; break;
      case GL_FLOAT_MAT3x2: typeName = "GL_FLOAT_MAT3x2"; break;
      case GL_FLOAT_MAT4x2: typeName = "GL_FLOAT_MAT4x2"; break;
      case GL_FLOAT_MAT2x4: typeName = "GL_FLOAT_MAT2x4"; break;
      case GL_FLOAT_MAT3x4: typeName = "GL_FLOAT_MAT3x4"; break;
      case GL_FLOAT_MAT4x3: typeName = "GL_FLOAT_MAT4x3"; break;
      case GL_SAMPLER_2D: typeName = "GL_SAMPLER_2D"; break;
      case GL_SAMPLER_CUBE: typeName = "GL_SAMPLER_CUBE"; break;
      case GL_SAMPLER_EXTERNAL_OES: typeName = "GL_SAMPLER_EXTERNAL_OES"; break;
      default: typeName = "UNKNOWN"; break;
    }

    printf("%s %lu : name=%s, type=%s, arraySize=%u\n",
           prefix.c_str(), index, var.name.c_str(), typeName.c_str(), var.arraySize);
    if (var.fields.size())
    {
        std::string structPrefix;
        for (size_t i = 0; i < prefix.size(); ++i)
            structPrefix += ' ';
        printf("%s  struct %s\n", structPrefix.c_str(), var.structName.c_str());
        structPrefix += "    field";
        for (size_t i = 0; i < var.fields.size(); ++i)
            PrintVariable(structPrefix, i, var.fields[i]);
    }
}
static void PrintActiveVariables(ShHandle compiler)
{
    const std::vector<sh::Uniform> *uniforms = ShGetUniforms(compiler);
    const std::vector<sh::Varying> *varyings = ShGetVaryings(compiler);
    const std::vector<sh::Attribute> *attributes = ShGetAttributes(compiler);
    for (size_t varCategory = 0; varCategory < 3; ++varCategory)
    {
        size_t numVars = 0;
        std::string varCategoryName;
        if (varCategory == 0)
        {
            numVars = uniforms->size();
            varCategoryName = "uniform";
        }
        else if (varCategory == 1)
        {
            numVars = varyings->size();
            varCategoryName = "varying";
        }
        else
        {
            numVars = attributes->size();
            varCategoryName = "attribute";
        }
        for (size_t i = 0; i < numVars; ++i)
        {
            const sh::ShaderVariable *var;
            if (varCategory == 0)
                var = &((*uniforms)[i]);
            else if (varCategory == 1)
                var = &((*varyings)[i]);
            else
                var = &((*attributes)[i]);
            PrintVariable(varCategoryName, i, *var);
        }
        printf("\n");
    }
}