THRIFT-3742 haxe php cli support
Client: Haxe
Patch: Oleksii Prudkyi + minor changes from Jens Geyer

This closes #950
diff --git a/test/haxe/Makefile.am b/test/haxe/Makefile.am
index 37ccfc3..6094452 100644
--- a/test/haxe/Makefile.am
+++ b/test/haxe/Makefile.am
@@ -22,11 +22,12 @@
 THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift
 
 BIN_CPP = bin/Main-debug
+BIN_PHP = bin/php/Main-debug.php
 
 gen-haxe/thrift/test/ThriftTest.hx: $(THRIFTTEST)
 	$(THRIFTCMD) $(THRIFTTEST)
 
-all-local: $(BIN_CPP)
+all-local: $(BIN_CPP) $(BIN_PHP)
 
 $(BIN_CPP): \
 		src/*.hx \
@@ -34,6 +35,14 @@
 		gen-haxe/thrift/test/ThriftTest.hx
 	$(HAXE) --cwd .  cpp.hxml
 
+$(BIN_PHP): \
+		src/*.hx \
+		../../lib/haxe/src/org/apache/thrift/**/*.hx \
+		gen-haxe/thrift/test/ThriftTest.hx
+	$(HAXE) --cwd .  php.hxml
+
+
+
 
 #TODO: other haxe targets
 #    $(HAXE)  --cwd .  csharp
@@ -41,19 +50,27 @@
 #    $(HAXE)  --cwd .  java
 #    $(HAXE)  --cwd .  javascript
 #    $(HAXE)  --cwd .  neko
-#    $(HAXE)  --cwd .  php
 #    $(HAXE)  --cwd .  python  # needs Haxe 3.2.0
 
 
 clean-local:
 	$(RM) -r gen-haxe bin
 
-check: $(BIN_CPP)
+check: check_cpp check_php
+
+check_cpp: $(BIN_CPP) 
 	timeout 10 $(BIN_CPP) server &
 	sleep 1
 	$(BIN_CPP) client
 	sleep 10
 
+check_php: $(BIN_PHP) 
+	timeout 10 php -f $(BIN_PHP) server &
+	sleep 1
+	php -f $(BIN_PHP) client
+	sleep 10
+
+
 EXTRA_DIST = \
              src \
              cpp.hxml \
diff --git a/test/haxe/php.hxml b/test/haxe/php.hxml
index 1eaac8b..9651898 100644
--- a/test/haxe/php.hxml
+++ b/test/haxe/php.hxml
@@ -26,7 +26,9 @@
 -main Main
 
 #PHP target
--php bin/Tutorial.php
+-php bin/php/
+--php-front Main-debug.php
+
 
 #Add debug information
 -debug
@@ -35,4 +37,4 @@
 #"-dce no" : do not remove unused code
 #"-dce std" : remove unused code in the std lib (default)
 #"-dce full" : remove all unused code
--dce full
\ No newline at end of file
+-dce full
diff --git a/test/haxe/src/TestClient.hx b/test/haxe/src/TestClient.hx
index 5c0de7c..ee1f019 100644
--- a/test/haxe/src/TestClient.hx
+++ b/test/haxe/src/TestClient.hx
@@ -43,6 +43,8 @@
 import thrift.test.*;  // generated code
 
 
+using StringTools;
+
 class TestResults {
     private var successCnt : Int = 0;
     private var errorCnt : Int = 0;
@@ -102,7 +104,7 @@
         if ( errorCnt > 0)
         {
             trace('===========================');
-              trace('FAILED TESTS: $failedTests');
+            trace('FAILED TESTS: $failedTests');
         }
         trace('===========================');
     }
@@ -118,20 +120,15 @@
         {
             var difft = Timer.stamp();
 
-            if( args.numThreads > 1) {
-                var threads = new List<Thread>();
-                for( test in 0 ... args.numThreads) {
-                    threads.add( StartThread( args));
-                }
-                exitCode = 0;
-                for( thread in threads) {
-                    exitCode |= Thread.readMessage(true);
-                }
+            if ( args.numThreads > 1) {
+                #if cpp
+                exitCode = MultiThreadClient(args);
+                #else
+                trace('Threads not supported/implemented for this platform.');
+                exitCode = SingleThreadClient(args);
+                #end
             } else {
-                var rslt = new TestResults(true);
-                RunClient(args,rslt);
-                rslt.PrintSummary();
-                exitCode = rslt.CalculateExitCode();
+                exitCode = SingleThreadClient(args);
             }
 
             difft = Math.round( 1000 * (Timer.stamp() - difft)) / 1000;
@@ -154,6 +151,31 @@
     }
 
 
+    public static function SingleThreadClient(args : Arguments) :  Int
+    {
+        var rslt = new TestResults(true);
+        RunClient(args,rslt);
+        rslt.PrintSummary();
+        return rslt.CalculateExitCode();
+    }
+
+
+    #if cpp
+    public static function MultiThreadClient(args : Arguments) :  Int
+    {
+        var threads = new List<Thread>();
+        for( test in 0 ... args.numThreads) {
+            threads.add( StartThread( args));
+        }
+        var exitCode : Int = 0;
+        for( thread in threads) {
+            exitCode |= Thread.readMessage(true);
+        }
+        return exitCode;
+    }
+    #end
+
+    #if cpp
     private static function StartThread(args : Arguments) : Thread {
         var thread = Thread.create(
             function() : Void {
@@ -179,6 +201,7 @@
         thread.sendMessage(Thread.current());
         return thread;
     }
+    #end
 
 
     public static function RunClient(args : Arguments, rslt : TestResults)
@@ -297,8 +320,9 @@
         rslt.Expect( c32 == c64, "Int64Map<Int32> Test #30");
         rslt.Expect( '$ksum64' == '$ksum32', '$ksum64 == $ksum32   Test #31');
 
-        var s32 = map32.toString();
-        var s64 = map64.toString();
+        //compare without spaces because differ in php and cpp
+        var s32 = map32.toString().replace(' ', '');
+        var s64 = map64.toString().replace(' ', '');
         rslt.Expect( s32 == s64, "Int64Map<Int32>.toString(): " + ' ("$s32" == "$s64") Test #32');
 
         map32.remove( 42);
@@ -322,8 +346,8 @@
 
     // core module unit tests
     public static function ModuleUnitTests( args : Arguments, rslt : TestResults) : Void {
-		#if debug
-		
+        #if debug
+
         try {
             BitConverter.UnitTest();
             rslt.Expect( true, 'BitConverter.UnitTest  Test #100');
@@ -339,8 +363,8 @@
         catch( e : Dynamic) {
             rslt.Expect( false, 'ZigZag.UnitTest: $e  Test #101');
         }
-		
-		#end
+
+        #end
     }
 
 
@@ -464,11 +488,11 @@
         trace('testBool(${true})');
         var b = client.testBool(true);
         trace(' = $b');
-		rslt.Expect(b, '$b == "${true}"');
+        rslt.Expect(b, '$b == "${true}"');
         trace('testBool(${false})');
         b = client.testBool(false);
         trace(' = $b');
-		rslt.Expect( ! b, '$b == "${false}"');
+        rslt.Expect( ! b, '$b == "${false}"');
 
         trace('testString("Test")');
         var s = client.testString("Test");
diff --git a/test/haxe/src/TestServer.hx b/test/haxe/src/TestServer.hx
index bff5a47..8f4604a 100644
--- a/test/haxe/src/TestServer.hx
+++ b/test/haxe/src/TestServer.hx
@@ -106,7 +106,7 @@
         }
         catch (x : TException)
         {
-			trace('$x ${x.errorID} ${x.errorMsg}');
+            trace('$x ${x.errorID} ${x.errorMsg}');
         }
         catch (x : Dynamic)
         {
diff --git a/test/haxe/src/TestServerHandler.hx b/test/haxe/src/TestServerHandler.hx
index 74a8805..9fba136 100644
--- a/test/haxe/src/TestServerHandler.hx
+++ b/test/haxe/src/TestServerHandler.hx
@@ -51,14 +51,14 @@
         trace("testVoid()");
     }
 
-	/**
-	* Prints 'testBool("%s")' where '%s' with thing as 'true' or 'false'
-	* @param bool  thing - the bool data to print
-	* @return bool  - returns the bool 'thing'
-	* 
-	* @param thing
-	*/
-	public function testBool(thing : Bool) : Bool
+    /**
+    * Prints 'testBool("%s")' where '%s' with thing as 'true' or 'false'
+    * @param bool  thing - the bool data to print
+    * @return bool  - returns the bool 'thing'
+    *
+    * @param thing
+    */
+    public function testBool(thing : Bool) : Bool
     {
         trace('testBool($thing)');
         return thing;