xref: /petsc/src/sys/classes/viewer/impls/mathematica/runtime.c (revision 2e58f0ef736ac50018a264b9bb00d7c98f78484b)
15c6c1daeSBarry Smith static const char help[] = "Tests PETSc -- Mathematica connection\n";
25c6c1daeSBarry Smith #include <petscksp.h>
35c6c1daeSBarry Smith #include <mathlink.h>
45c6c1daeSBarry Smith 
55c6c1daeSBarry Smith typedef enum {MATHEMATICA_LINK_CREATE, MATHEMATICA_LINK_CONNECT, MATHEMATICA_LINK_LAUNCH} LinkMode;
65c6c1daeSBarry Smith 
7a6dfd86eSKarl Rupp static int setupConnection(MLENV *env, MLINK *link, const char *linkhost, LinkMode linkmode)
8a6dfd86eSKarl Rupp {
95c6c1daeSBarry Smith   int  argc = 5;
105c6c1daeSBarry Smith   char *argv[5];
115c6c1daeSBarry Smith   char hostname[256];
125c6c1daeSBarry Smith   long lerr;
135c6c1daeSBarry Smith   int  ierr;
145c6c1daeSBarry Smith 
155c6c1daeSBarry Smith   PetscFunctionBegin;
165c6c1daeSBarry Smith   /* Link name */
175c6c1daeSBarry Smith   argv[0] = "-linkname";
185c6c1daeSBarry Smith   argv[1] = "8001";
19a297a907SKarl Rupp 
205c6c1daeSBarry Smith   /* Link host */
215c6c1daeSBarry Smith   argv[2] = "-linkhost";
225c6c1daeSBarry Smith   if (!linkhost) {
23589a23caSBarry Smith     ierr    = PetscGetHostName(hostname, sizeof(hostname));CHKERRQ(ierr);
245c6c1daeSBarry Smith     argv[3] = hostname;
25a297a907SKarl Rupp   } else argv[3] = (char*) linkhost;
26a297a907SKarl Rupp 
275c6c1daeSBarry Smith   /* Link mode */
285c6c1daeSBarry Smith   switch (linkmode) {
295c6c1daeSBarry Smith   case MATHEMATICA_LINK_CREATE:
305c6c1daeSBarry Smith     argv[4] = "-linkcreate";
315c6c1daeSBarry Smith     break;
325c6c1daeSBarry Smith   case MATHEMATICA_LINK_CONNECT:
335c6c1daeSBarry Smith     argv[4] = "-linkconnect";
345c6c1daeSBarry Smith     break;
355c6c1daeSBarry Smith   case MATHEMATICA_LINK_LAUNCH:
365c6c1daeSBarry Smith     argv[4] = "-linklaunch";
375c6c1daeSBarry Smith     break;
385c6c1daeSBarry Smith   }
395c6c1daeSBarry Smith 
405c6c1daeSBarry Smith   *env = MLInitialize(0);
41a297a907SKarl Rupp   for (lerr = 0; lerr < argc; lerr++) printf("argv[%ld] = %s\n", lerr, argv[lerr]);
425c6c1daeSBarry Smith   *link = MLOpenInEnv(*env, argc, argv, &lerr);
435c6c1daeSBarry Smith   printf("lerr = %ld\n", lerr);
445c6c1daeSBarry Smith   PetscFunctionReturn(0);
455c6c1daeSBarry Smith }
465c6c1daeSBarry Smith 
47a6dfd86eSKarl Rupp static int printIndent(int indent)
48a6dfd86eSKarl Rupp {
495c6c1daeSBarry Smith   int i;
505c6c1daeSBarry Smith 
515c6c1daeSBarry Smith   PetscFunctionBegin;
525c6c1daeSBarry Smith   for (i = 0; i < indent; i++) printf(" ");
535c6c1daeSBarry Smith   PetscFunctionReturn(0);
545c6c1daeSBarry Smith }
555c6c1daeSBarry Smith 
56a6dfd86eSKarl Rupp static int processPacket(MLINK link, int indent)
57a6dfd86eSKarl Rupp {
585c6c1daeSBarry Smith   static int isHead    = 0;
595c6c1daeSBarry Smith   int        tokenType = MLGetNext(link);
605c6c1daeSBarry Smith   int        ierr;
615c6c1daeSBarry Smith 
625c6c1daeSBarry Smith   PetscFunctionBegin;
635c6c1daeSBarry Smith   ierr = printIndent(indent);CHKERRQ(ierr);
645c6c1daeSBarry Smith   switch (tokenType) {
655c6c1daeSBarry Smith   case MLTKFUNC:
665c6c1daeSBarry Smith   {
675c6c1daeSBarry Smith     long numArguments;
685c6c1daeSBarry Smith     int  arg;
695c6c1daeSBarry Smith 
705c6c1daeSBarry Smith     printf("Function:\n");
715c6c1daeSBarry Smith     MLGetArgCount(link, &numArguments);
725c6c1daeSBarry Smith     /* Process head */
735c6c1daeSBarry Smith     printf("  Head:\n");
745c6c1daeSBarry Smith     isHead = 1;
755c6c1daeSBarry Smith     ierr   = processPacket(link, indent+4);
765c6c1daeSBarry Smith     if (ierr) PetscFunctionReturn(ierr);
775c6c1daeSBarry Smith     isHead = 0;
785c6c1daeSBarry Smith     /* Process arguments */
795c6c1daeSBarry Smith     printf("  Arguments:\n");
805c6c1daeSBarry Smith     for (arg = 0; arg < numArguments; arg++) {
815c6c1daeSBarry Smith       ierr = processPacket(link, indent+4);CHKERRQ(ierr);
825c6c1daeSBarry Smith     }
835c6c1daeSBarry Smith   }
845c6c1daeSBarry Smith     break;
855c6c1daeSBarry Smith   case MLTKSYM:
865c6c1daeSBarry Smith   {
875c6c1daeSBarry Smith     const char *symbol;
885c6c1daeSBarry Smith 
895c6c1daeSBarry Smith     MLGetSymbol(link, &symbol);
905c6c1daeSBarry Smith     printf("Symbol: %s\n", symbol);
915c6c1daeSBarry Smith     if (isHead && !strcmp(symbol, "Shutdown")) {
925c6c1daeSBarry Smith       MLDisownSymbol(link, symbol);
935c6c1daeSBarry Smith       PetscFunctionReturn(2);
945c6c1daeSBarry Smith     }
955c6c1daeSBarry Smith     MLDisownSymbol(link, symbol);
965c6c1daeSBarry Smith   }
975c6c1daeSBarry Smith     break;
985c6c1daeSBarry Smith   case MLTKINT:
995c6c1daeSBarry Smith   {
1005c6c1daeSBarry Smith     int i;
1015c6c1daeSBarry Smith 
1025c6c1daeSBarry Smith     MLGetInteger(link, &i);
1035c6c1daeSBarry Smith     printf("Integer: %d\n", i);
1045c6c1daeSBarry Smith   }
1055c6c1daeSBarry Smith     break;
1065c6c1daeSBarry Smith   case MLTKREAL:
1075c6c1daeSBarry Smith   {
1085c6c1daeSBarry Smith     double r;
1095c6c1daeSBarry Smith 
1105c6c1daeSBarry Smith     MLGetReal(link, &r);
1115c6c1daeSBarry Smith     printf("Real: %g\n", r);
1125c6c1daeSBarry Smith   }
1135c6c1daeSBarry Smith     break;
1145c6c1daeSBarry Smith   case MLTKSTR:
1155c6c1daeSBarry Smith   {
1165c6c1daeSBarry Smith     const char *string;
1175c6c1daeSBarry Smith 
1185c6c1daeSBarry Smith     MLGetString(link, &string);
1195c6c1daeSBarry Smith     printf("String: %s\n", string);
1205c6c1daeSBarry Smith     MLDisownString(link, string);
1215c6c1daeSBarry Smith   }
1225c6c1daeSBarry Smith     break;
1235c6c1daeSBarry Smith   default:
1245c6c1daeSBarry Smith     printf("Unknown code %d\n", tokenType);
1255c6c1daeSBarry Smith     MLClearError(link);
1265c6c1daeSBarry Smith     fprintf(stderr, "ERROR: %s\n", (char*) MLErrorMessage(link));
1275c6c1daeSBarry Smith     PetscFunctionReturn(1);
1285c6c1daeSBarry Smith   }
1295c6c1daeSBarry Smith   PetscFunctionReturn(0);
1305c6c1daeSBarry Smith }
1315c6c1daeSBarry Smith 
132a6dfd86eSKarl Rupp static int processPackets(MLINK link)
133a6dfd86eSKarl Rupp {
1345c6c1daeSBarry Smith   int packetType;
1355c6c1daeSBarry Smith   int loop   = 1;
1365c6c1daeSBarry Smith   int errors = 0;
137*2e58f0efSBarry Smith   int err;
1385c6c1daeSBarry Smith 
1395c6c1daeSBarry Smith   PetscFunctionBegin;
1405c6c1daeSBarry Smith   while (loop) {
1415c6c1daeSBarry Smith     while ((packetType = MLNextPacket(link)) && (packetType != RETURNPKT)) {
1425c6c1daeSBarry Smith       switch (packetType) {
1435c6c1daeSBarry Smith       case BEGINDLGPKT:
1445c6c1daeSBarry Smith         printf("Begin dialog packet\n");
1455c6c1daeSBarry Smith         break;
1465c6c1daeSBarry Smith       case CALLPKT:
1475c6c1daeSBarry Smith         printf("Call packet\n");
1485c6c1daeSBarry Smith         break;
1495c6c1daeSBarry Smith       case DISPLAYPKT:
1505c6c1daeSBarry Smith         printf("Display packet\n");
1515c6c1daeSBarry Smith         break;
1525c6c1daeSBarry Smith       case DISPLAYENDPKT:
1535c6c1daeSBarry Smith         printf("Display end packet\n");
1545c6c1daeSBarry Smith         break;
1555c6c1daeSBarry Smith       case ENDDLGPKT:
1565c6c1daeSBarry Smith         printf("End dialog packet\n");
1575c6c1daeSBarry Smith         break;
1585c6c1daeSBarry Smith       case ENTERTEXTPKT:
1595c6c1daeSBarry Smith         printf("Enter text packet\n");
1605c6c1daeSBarry Smith         break;
1615c6c1daeSBarry Smith       case ENTEREXPRPKT:
1625c6c1daeSBarry Smith         printf("Enter expression packet\n");
1635c6c1daeSBarry Smith         break;
1645c6c1daeSBarry Smith       case EVALUATEPKT:
1655c6c1daeSBarry Smith         printf("Evaluate packet\n");
1665c6c1daeSBarry Smith         break;
1675c6c1daeSBarry Smith       case INPUTPKT:
1685c6c1daeSBarry Smith         printf("Input packet\n");
1695c6c1daeSBarry Smith         break;
1705c6c1daeSBarry Smith       case INPUTNAMEPKT:
1715c6c1daeSBarry Smith         printf("Input name packet\n");
1725c6c1daeSBarry Smith         break;
1735c6c1daeSBarry Smith       case INPUTSTRPKT:
1745c6c1daeSBarry Smith         printf("Input string packet\n");
1755c6c1daeSBarry Smith         break;
1765c6c1daeSBarry Smith       case MENUPKT:
1775c6c1daeSBarry Smith         printf("Menu packet\n");
1785c6c1daeSBarry Smith         break;
1795c6c1daeSBarry Smith       case MESSAGEPKT:
1805c6c1daeSBarry Smith         printf("Message packet\n");
1815c6c1daeSBarry Smith         break;
1825c6c1daeSBarry Smith       case OUTPUTNAMEPKT:
1835c6c1daeSBarry Smith         printf("Output name packet\n");
1845c6c1daeSBarry Smith         break;
1855c6c1daeSBarry Smith       case RESUMEPKT:
1865c6c1daeSBarry Smith         printf("Resume packet\n");
1875c6c1daeSBarry Smith         break;
1885c6c1daeSBarry Smith       case RETURNTEXTPKT:
1895c6c1daeSBarry Smith         printf("Return text packet\n");
1905c6c1daeSBarry Smith         break;
1915c6c1daeSBarry Smith       case RETURNEXPRPKT:
1925c6c1daeSBarry Smith         printf("Return expression packet\n");
1935c6c1daeSBarry Smith         break;
1945c6c1daeSBarry Smith       case SUSPENDPKT:
1955c6c1daeSBarry Smith         printf("Suspend packet\n");
1965c6c1daeSBarry Smith         break;
1975c6c1daeSBarry Smith       case SYNTAXPKT:
1985c6c1daeSBarry Smith         printf("Syntax packet\n");
1995c6c1daeSBarry Smith         break;
2005c6c1daeSBarry Smith       case TEXTPKT:
2015c6c1daeSBarry Smith         printf("Text packet\n");
2025c6c1daeSBarry Smith         break;
2035c6c1daeSBarry Smith       }
2045c6c1daeSBarry Smith       MLNewPacket(link);
2055c6c1daeSBarry Smith     }
2065c6c1daeSBarry Smith 
2075c6c1daeSBarry Smith     /* Got a Return packet */
2085c6c1daeSBarry Smith     if (!packetType) {
2095c6c1daeSBarry Smith       MLClearError(link);
2105c6c1daeSBarry Smith       printf("ERROR: %s\n", (char*) MLErrorMessage(link));
2115c6c1daeSBarry Smith       errors++;
2125c6c1daeSBarry Smith     } else if (packetType == RETURNPKT) {
213*2e58f0efSBarry Smith       err = processPacket(link, 0);
214*2e58f0efSBarry Smith       if (err == 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error returned from Mathematica");
215*2e58f0efSBarry Smith       if (err == 2) loop = 0;
2165c6c1daeSBarry Smith     } else {
2175c6c1daeSBarry Smith       fprintf(stderr, "Invalid packet type %d\n", packetType);
2185c6c1daeSBarry Smith       loop = 0;
2195c6c1daeSBarry Smith     }
2205c6c1daeSBarry Smith     if (errors > 10) loop = 0;
2215c6c1daeSBarry Smith   }
2225c6c1daeSBarry Smith   PetscFunctionReturn(0);
2235c6c1daeSBarry Smith }
2245c6c1daeSBarry Smith 
225a6dfd86eSKarl Rupp static int cleanupConnection(MLENV env, MLINK link)
226a6dfd86eSKarl Rupp {
2275c6c1daeSBarry Smith   PetscFunctionBegin;
2285c6c1daeSBarry Smith   MLClose(link);
2295c6c1daeSBarry Smith   MLDeinitialize(env);
2305c6c1daeSBarry Smith   PetscFunctionReturn(0);
2315c6c1daeSBarry Smith }
2325c6c1daeSBarry Smith 
233a6dfd86eSKarl Rupp int main(int argc, char *argv[])
234a6dfd86eSKarl Rupp {
2355c6c1daeSBarry Smith   MLENV env;
2365c6c1daeSBarry Smith   MLINK link;
2375c6c1daeSBarry Smith   int   ierr;
2385c6c1daeSBarry Smith 
2392da392ccSBarry Smith   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr;
240095b3734SBarry Smith   ierr = setupConnection(&env, &link, "192.168.119.1", MATHEMATICA_LINK_CONNECT);CHKERRQ(ierr);
241095b3734SBarry Smith   ierr = processPackets(link);CHKERRQ(ierr);
242095b3734SBarry Smith   ierr = cleanupConnection(env, link);CHKERRQ(ierr);
243095b3734SBarry Smith   ierr = PetscFinalize();
244095b3734SBarry Smith   return(ierr);
2455c6c1daeSBarry Smith }
246