changeset 14:e1f87438e34c

Work around for lock-up when used by triserver project. By god it's ugly but it seems to work.
author samer
date Thu, 02 Feb 2012 03:01:20 +0000
parents 440734a35533
children e395e387bd3c
files cpp/plml.cpp
diffstat 1 files changed, 53 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/cpp/plml.cpp	Wed Feb 01 00:27:48 2012 +0000
+++ b/cpp/plml.cpp	Thu Feb 02 03:01:20 2012 +0000
@@ -88,7 +88,8 @@
 #define BUFSIZE  32768 // buffer for matlab output
 #define MAXCMDLEN 256
 // #define EVALFMT "t__ex=[];\ntry\n%s\ncatch t__ex\ndisp(getReport(t__ex))\nend"
-#define EVALFMT "lasterr('');disp(' ');%s\nt__ex=lasterr;"
+//#define EVALFMT "lasterr('');disp('#');%s\nt__ex=lasterr;"
+#define EVALFMT "lasterr('');disp('#');%s"
 
 using namespace std;
 
@@ -475,7 +476,7 @@
 
 
 static int raise_exception(const char *msg) {
-  printf("\n!! raising exception: %s\n",msg);
+  // printf("\n!! raising exception: %s\n",msg);
   // return FALSE;
  
   term_t ex = PL_new_term_ref();
@@ -516,24 +517,23 @@
   if (engEvalString(x.engine, "t__0=uniquevar([])")) {
 	  return raise_exception("mlWSAlloc: Cannot execute uniquevar");
   }
+ 
+  if (strncmp(engine->outbuf,">> \nt__0 =",10)!=0) {
+     //printf("\n** mlWSAlloc: output buffer looks bad: '%s'\n",engine->outbuf);
+	  return raise_exception("mlWSAlloc: Bad output buffer.");
+  }
+  mxArray *newname=engGetVariable(x.engine, "t__0");
 
-  // fputs("\n>",stdout); fputs(engine->outbuf,stdout); fputs("<\n",stdout);
-  if (strlen(engine->outbuf)==0) {
-	  return raise_exception("mlWSAlloc: Empty output buffer.");
-  }
-  memset(x.name,sizeof(x.name),0);
-  // printf(" - mlWSAlloc: Getting variable name...        \r"); fflush(stdout); 
-  mxArray *newname=engGetVariable(x.engine, "t__0");
   if (newname==NULL) {
 	  return raise_exception("mlWSAlloc: Cannot get new variable name.");
   }
+  memset(x.name,sizeof(x.name),0);
   rc = mxGetString(newname,x.name, sizeof(x.name));
   mxDestroyArray(newname);
   if (rc) {
 	  return raise_exception("mlWSAlloc: Cannot read new variable name.");
   }
 
-  // printf("                                                  \r"); fflush(stdout); 
   return PL_unify_blob(blob,&x,sizeof(x),&ws_blob);
 }
 
@@ -606,15 +606,18 @@
 	 //printf("-- Returned from Matlab engine...            \r"); fflush(stdout);
 	 delete [] eval_cmd;
 
-	 // EVALFMT starts with disp(' '). This means that the output buffer should
+	 // EVALFMT starts with disp('#'). This means that the output buffer should
 	 // contain at least the 5 characters: ">> *\n". If they are not there,
 	 // something is terribly wrong and we must throw an exeption to avoid
 	 // locking up.
-    if (strlen(eng->outbuf)<5) {
-		 printf("\n** mlExec: evaluation error. Empty output buffer.\n");
-		 throw PlException("mlExec: empty output buffer");
+    if (strncmp(eng->outbuf,">> #\n",5)!=0) {
+		 //printf("\n** mlExec: Output buffer looks bad: '%s'.\n",eng->outbuf);
+		 throw PlException("mlExec: output buffer looks bad.");
 	 }
-    if (rc) printf("\n** mlExec: evaluation error. Output buffer contains:\n");
+    if (rc) {
+		 // printf("\n** mlExec: evaluation error. Output buffer contains:\n");
+		 throw PlException("mlExec: engEvalString failed.");
+	 }
 	 // write whatever is in the output buffer now.
     fputs(eng->outbuf+5,stdout);
 
@@ -623,14 +626,44 @@
 		 return FALSE;
 	 }
 
-	 //printf(" - mlExec: Getting last error...             \r"); fflush(stdout);
+	 rc=engEvalString(eng->ep,"lasterr");
+	 if (rc) {
+		 //printf("\n** mlExec: unable to execute lasterr.\n");
+		 throw PlException("mlExec: unable to execute lasterr");
+	 }
+	 if (strncmp(eng->outbuf,">> \nans =",9)!=0) {
+		 //printf("\n** mlExec: Bad output buffer post lasterr: '%s'.\n",eng->outbuf);
+		 throw PlException("mlExec: bad output buffer post lasterr");
+	 }
+
+	 if (strncmp(eng->outbuf+11,"     ''",7)!=0) {
+		int len=strlen(eng->outbuf+11)-2;
+		char *lasterr=(char *)malloc(len+1);
+		term_t desc=PL_new_term_ref();
+		term_t cmd=PL_new_term_ref();
+		term_t ex=PL_new_term_ref();
+		memcpy(lasterr,eng->outbuf+11,len);
+		lasterr[len]=0;
+
+		PL_put_atom_chars(desc,lasterr);
+		PL_put_atom_chars(cmd,cmdstr);
+		free(lasterr);
+		check(PL_cons_functor(ex,mlerror,engine,desc,cmd));
+		throw PlException(ex);
+    }
+
+
+/*
+	 //printf(" - mlExec: output buffer: '%s'\n",eng->outbuf);
     mxArray *lasterr = engGetVariable(eng->ep, "t__ex");
+	 //printf(" - mlExec: output buffer after: ++%s++\n",eng->outbuf);
 	 //printf(" - mlExec: Got last error (%p)               \r",lasterr); fflush(stdout);
 
 	 if (!lasterr) {
 		 printf("\n** mlExec: unable to get lasterr.\n");
+		 printf("** mlExec: Output buffer contains: '%s'.\n",eng->outbuf);
 		 throw PlException("mlExec: unable to get lasterr");
-	}
+	 }
     
     if (mxGetNumberOfElements(lasterr)>0) {
 		 //char *string=mxArrayToString(mxGetField(lasterr,0,"message"));
@@ -648,12 +681,13 @@
 		throw PlException(ex);
 		 
 	 } else mxDestroyArray(lasterr);
+*/
     
     // if we've got this far, then everything went well, so
-	 printf("                                        \r"); fflush(stdout); 
+	 //printf("                                        \r"); fflush(stdout); 
 	 return TRUE;
   } catch (PlException &e) { 
-	 printf("\n** mlExec: Throwing exception\n");
+	 //printf("\n** mlExec: Throwing exception\n");
     return e.plThrow(); 
   }
 }