Compiler - implement shader and program queries
TRAC #11599
Signed-off-by: Shannon Woods
Signed-off-by: Daniel Koch
Author:    Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/trunk@76 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Program.cpp b/src/libGLESv2/Program.cpp
index a9f2f64..5686b16 100644
--- a/src/libGLESv2/Program.cpp
+++ b/src/libGLESv2/Program.cpp
@@ -41,6 +41,8 @@
         mAttributeName[index] = NULL;
     }
 
+    mInfoLog = NULL;
+
     unlink();
 
     mDeleteStatus = false;
@@ -107,6 +109,11 @@
     return true;
 }
 
+int Program::getAttachedShadersCount() const
+{
+    return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0);
+}
+
 IDirect3DPixelShader9 *Program::getPixelShader()
 {
     return mPixelExecutable;
@@ -385,6 +392,7 @@
     if (errorMessage)
     {
         const char *message = (const char*)errorMessage->GetBufferPointer();
+
         TRACE("\n%s", hlsl);
         TRACE("\n%s", message);
     }
@@ -404,6 +412,9 @@
 
     unlink();
 
+    delete[] mInfoLog;
+    mInfoLog = NULL;
+
     if (!mFragmentShader || !mFragmentShader->isCompiled())
     {
         return;
@@ -910,6 +921,32 @@
     return true;
 }
 
+void Program::appendToInfoLog(const char *info)
+{
+    if (!info)
+    {
+        return;
+    }
+
+    size_t infoLength = strlen(info);
+
+    if (!mInfoLog)
+    {
+        mInfoLog = new char[infoLength + 1];
+        strcpy(mInfoLog, info);
+    }
+    else
+    {
+        size_t logLength = strlen(mInfoLog);
+        char *newLog = new char[logLength + infoLength + 1];
+        strcpy(newLog, mInfoLog);
+        strcpy(newLog + logLength, info);
+
+        delete[] mInfoLog;
+        mInfoLog = newLog;
+    }
+}
+
 // Returns the program object to an unlinked state, after detaching a shader, before re-linking, or at destruction
 void Program::unlink(bool destroy)
 {
@@ -932,6 +969,9 @@
             delete[] mAttributeName[index];
             mAttributeName[index] = NULL;
         }
+
+        delete[] mInfoLog;
+        mInfoLog = NULL;
     }
 
     if (mPixelExecutable)
@@ -982,6 +1022,42 @@
     return mLinked;
 }
 
+int Program::getInfoLogLength() const
+{
+    if (!mInfoLog)
+    {
+        return 0;
+    }
+    else
+    {
+       return strlen(mInfoLog) + 1;
+    }
+}
+
+void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
+{
+    int index = 0;
+
+    if (mInfoLog)
+    {
+        while (index < bufSize - 1 && index < (int)strlen(mInfoLog))
+        {
+            infoLog[index] = mInfoLog[index];
+            index++;
+        }
+    }
+
+    if (bufSize)
+    {
+        infoLog[index] = '\0';
+    }
+
+    if (length)
+    {
+        *length = index;
+    }
+}
+
 void Program::flagForDeletion()
 {
     mDeleteStatus = true;