15c6c1daeSBarry Smith static const char help[] = "Tests PETSc -- Mathematica connection\n"; 25c6c1daeSBarry Smith #include <petscksp.h> 35c6c1daeSBarry Smith #include <mathlink.h> 45c6c1daeSBarry Smith 59371c9d4SSatish Balay typedef enum { 69371c9d4SSatish Balay MATHEMATICA_LINK_CREATE, 79371c9d4SSatish Balay MATHEMATICA_LINK_CONNECT, 89371c9d4SSatish Balay MATHEMATICA_LINK_LAUNCH 99371c9d4SSatish Balay } LinkMode; 105c6c1daeSBarry Smith 119371c9d4SSatish Balay static int setupConnection(MLENV *env, MLINK *link, const char *linkhost, LinkMode linkmode) { 125c6c1daeSBarry Smith int argc = 5; 135c6c1daeSBarry Smith char *argv[5]; 145c6c1daeSBarry Smith char hostname[256]; 155c6c1daeSBarry Smith long lerr; 165c6c1daeSBarry Smith int ierr; 175c6c1daeSBarry Smith 185c6c1daeSBarry Smith PetscFunctionBegin; 195c6c1daeSBarry Smith /* Link name */ 205c6c1daeSBarry Smith argv[0] = "-linkname"; 215c6c1daeSBarry Smith argv[1] = "8001"; 22a297a907SKarl Rupp 235c6c1daeSBarry Smith /* Link host */ 245c6c1daeSBarry Smith argv[2] = "-linkhost"; 255c6c1daeSBarry Smith if (!linkhost) { 269566063dSJacob Faibussowitsch PetscCall(PetscGetHostName(hostname, sizeof(hostname))); 275c6c1daeSBarry Smith argv[3] = hostname; 28a297a907SKarl Rupp } else argv[3] = (char *)linkhost; 29a297a907SKarl Rupp 305c6c1daeSBarry Smith /* Link mode */ 315c6c1daeSBarry Smith switch (linkmode) { 329371c9d4SSatish Balay case MATHEMATICA_LINK_CREATE: argv[4] = "-linkcreate"; break; 339371c9d4SSatish Balay case MATHEMATICA_LINK_CONNECT: argv[4] = "-linkconnect"; break; 349371c9d4SSatish Balay case MATHEMATICA_LINK_LAUNCH: argv[4] = "-linklaunch"; break; 355c6c1daeSBarry Smith } 365c6c1daeSBarry Smith 375c6c1daeSBarry Smith *env = MLInitialize(0); 38a297a907SKarl Rupp for (lerr = 0; lerr < argc; lerr++) printf("argv[%ld] = %s\n", lerr, argv[lerr]); 395c6c1daeSBarry Smith *link = MLOpenInEnv(*env, argc, argv, &lerr); 405c6c1daeSBarry Smith printf("lerr = %ld\n", lerr); 415c6c1daeSBarry Smith PetscFunctionReturn(0); 425c6c1daeSBarry Smith } 435c6c1daeSBarry Smith 449371c9d4SSatish Balay static int printIndent(int indent) { 455c6c1daeSBarry Smith int i; 465c6c1daeSBarry Smith 475c6c1daeSBarry Smith PetscFunctionBegin; 485c6c1daeSBarry Smith for (i = 0; i < indent; i++) printf(" "); 495c6c1daeSBarry Smith PetscFunctionReturn(0); 505c6c1daeSBarry Smith } 515c6c1daeSBarry Smith 529371c9d4SSatish Balay static int processPacket(MLINK link, int indent) { 535c6c1daeSBarry Smith static int isHead = 0; 545c6c1daeSBarry Smith int tokenType = MLGetNext(link); 555c6c1daeSBarry Smith int ierr; 565c6c1daeSBarry Smith 575c6c1daeSBarry Smith PetscFunctionBegin; 589566063dSJacob Faibussowitsch PetscCall(printIndent(indent)); 595c6c1daeSBarry Smith switch (tokenType) { 609371c9d4SSatish Balay case MLTKFUNC: { 615c6c1daeSBarry Smith long numArguments; 625c6c1daeSBarry Smith int arg; 635c6c1daeSBarry Smith 645c6c1daeSBarry Smith printf("Function:\n"); 655c6c1daeSBarry Smith MLGetArgCount(link, &numArguments); 665c6c1daeSBarry Smith /* Process head */ 675c6c1daeSBarry Smith printf(" Head:\n"); 685c6c1daeSBarry Smith isHead = 1; 695c6c1daeSBarry Smith ierr = processPacket(link, indent + 4); 705c6c1daeSBarry Smith if (ierr) PetscFunctionReturn(ierr); 715c6c1daeSBarry Smith isHead = 0; 725c6c1daeSBarry Smith /* Process arguments */ 735c6c1daeSBarry Smith printf(" Arguments:\n"); 74*48a46eb9SPierre Jolivet for (arg = 0; arg < numArguments; arg++) PetscCall(processPacket(link, indent + 4)); 759371c9d4SSatish Balay } break; 769371c9d4SSatish Balay case MLTKSYM: { 775c6c1daeSBarry Smith const char *symbol; 785c6c1daeSBarry Smith 795c6c1daeSBarry Smith MLGetSymbol(link, &symbol); 805c6c1daeSBarry Smith printf("Symbol: %s\n", symbol); 815c6c1daeSBarry Smith if (isHead && !strcmp(symbol, "Shutdown")) { 825c6c1daeSBarry Smith MLDisownSymbol(link, symbol); 835c6c1daeSBarry Smith PetscFunctionReturn(2); 845c6c1daeSBarry Smith } 855c6c1daeSBarry Smith MLDisownSymbol(link, symbol); 869371c9d4SSatish Balay } break; 879371c9d4SSatish Balay case MLTKINT: { 885c6c1daeSBarry Smith int i; 895c6c1daeSBarry Smith 905c6c1daeSBarry Smith MLGetInteger(link, &i); 915c6c1daeSBarry Smith printf("Integer: %d\n", i); 929371c9d4SSatish Balay } break; 939371c9d4SSatish Balay case MLTKREAL: { 945c6c1daeSBarry Smith double r; 955c6c1daeSBarry Smith 965c6c1daeSBarry Smith MLGetReal(link, &r); 975c6c1daeSBarry Smith printf("Real: %g\n", r); 989371c9d4SSatish Balay } break; 999371c9d4SSatish Balay case MLTKSTR: { 1005c6c1daeSBarry Smith const char *string; 1015c6c1daeSBarry Smith 1025c6c1daeSBarry Smith MLGetString(link, &string); 1035c6c1daeSBarry Smith printf("String: %s\n", string); 1045c6c1daeSBarry Smith MLDisownString(link, string); 1059371c9d4SSatish Balay } break; 1065c6c1daeSBarry Smith default: 1075c6c1daeSBarry Smith printf("Unknown code %d\n", tokenType); 1085c6c1daeSBarry Smith MLClearError(link); 1095c6c1daeSBarry Smith fprintf(stderr, "ERROR: %s\n", (char *)MLErrorMessage(link)); 1105c6c1daeSBarry Smith PetscFunctionReturn(1); 1115c6c1daeSBarry Smith } 1125c6c1daeSBarry Smith PetscFunctionReturn(0); 1135c6c1daeSBarry Smith } 1145c6c1daeSBarry Smith 1159371c9d4SSatish Balay static int processPackets(MLINK link) { 1165c6c1daeSBarry Smith int packetType; 1175c6c1daeSBarry Smith int loop = 1; 1185c6c1daeSBarry Smith int errors = 0; 1192e58f0efSBarry Smith int err; 1205c6c1daeSBarry Smith 1215c6c1daeSBarry Smith PetscFunctionBegin; 1225c6c1daeSBarry Smith while (loop) { 1235c6c1daeSBarry Smith while ((packetType = MLNextPacket(link)) && (packetType != RETURNPKT)) { 1245c6c1daeSBarry Smith switch (packetType) { 1259371c9d4SSatish Balay case BEGINDLGPKT: printf("Begin dialog packet\n"); break; 1269371c9d4SSatish Balay case CALLPKT: printf("Call packet\n"); break; 1279371c9d4SSatish Balay case DISPLAYPKT: printf("Display packet\n"); break; 1289371c9d4SSatish Balay case DISPLAYENDPKT: printf("Display end packet\n"); break; 1299371c9d4SSatish Balay case ENDDLGPKT: printf("End dialog packet\n"); break; 1309371c9d4SSatish Balay case ENTERTEXTPKT: printf("Enter text packet\n"); break; 1319371c9d4SSatish Balay case ENTEREXPRPKT: printf("Enter expression packet\n"); break; 1329371c9d4SSatish Balay case EVALUATEPKT: printf("Evaluate packet\n"); break; 1339371c9d4SSatish Balay case INPUTPKT: printf("Input packet\n"); break; 1349371c9d4SSatish Balay case INPUTNAMEPKT: printf("Input name packet\n"); break; 1359371c9d4SSatish Balay case INPUTSTRPKT: printf("Input string packet\n"); break; 1369371c9d4SSatish Balay case MENUPKT: printf("Menu packet\n"); break; 1379371c9d4SSatish Balay case MESSAGEPKT: printf("Message packet\n"); break; 1389371c9d4SSatish Balay case OUTPUTNAMEPKT: printf("Output name packet\n"); break; 1399371c9d4SSatish Balay case RESUMEPKT: printf("Resume packet\n"); break; 1409371c9d4SSatish Balay case RETURNTEXTPKT: printf("Return text packet\n"); break; 1419371c9d4SSatish Balay case RETURNEXPRPKT: printf("Return expression packet\n"); break; 1429371c9d4SSatish Balay case SUSPENDPKT: printf("Suspend packet\n"); break; 1439371c9d4SSatish Balay case SYNTAXPKT: printf("Syntax packet\n"); break; 1449371c9d4SSatish Balay case TEXTPKT: printf("Text packet\n"); break; 1455c6c1daeSBarry Smith } 1465c6c1daeSBarry Smith MLNewPacket(link); 1475c6c1daeSBarry Smith } 1485c6c1daeSBarry Smith 1495c6c1daeSBarry Smith /* Got a Return packet */ 1505c6c1daeSBarry Smith if (!packetType) { 1515c6c1daeSBarry Smith MLClearError(link); 1525c6c1daeSBarry Smith printf("ERROR: %s\n", (char *)MLErrorMessage(link)); 1535c6c1daeSBarry Smith errors++; 1545c6c1daeSBarry Smith } else if (packetType == RETURNPKT) { 1552e58f0efSBarry Smith err = processPacket(link, 0); 15608401ef6SPierre Jolivet PetscCheck(err != 1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error returned from Mathematica"); 1572e58f0efSBarry Smith if (err == 2) loop = 0; 1585c6c1daeSBarry Smith } else { 1595c6c1daeSBarry Smith fprintf(stderr, "Invalid packet type %d\n", packetType); 1605c6c1daeSBarry Smith loop = 0; 1615c6c1daeSBarry Smith } 1625c6c1daeSBarry Smith if (errors > 10) loop = 0; 1635c6c1daeSBarry Smith } 1645c6c1daeSBarry Smith PetscFunctionReturn(0); 1655c6c1daeSBarry Smith } 1665c6c1daeSBarry Smith 1679371c9d4SSatish Balay static int cleanupConnection(MLENV env, MLINK link) { 1685c6c1daeSBarry Smith PetscFunctionBegin; 1695c6c1daeSBarry Smith MLClose(link); 1705c6c1daeSBarry Smith MLDeinitialize(env); 1715c6c1daeSBarry Smith PetscFunctionReturn(0); 1725c6c1daeSBarry Smith } 1735c6c1daeSBarry Smith 1749371c9d4SSatish Balay int main(int argc, char *argv[]) { 1755c6c1daeSBarry Smith MLENV env; 1765c6c1daeSBarry Smith MLINK link; 1775c6c1daeSBarry Smith int ierr; 1785c6c1daeSBarry Smith 1799566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 1809566063dSJacob Faibussowitsch PetscCall(setupConnection(&env, &link, "192.168.119.1", MATHEMATICA_LINK_CONNECT)); 1819566063dSJacob Faibussowitsch PetscCall(processPackets(link)); 1829566063dSJacob Faibussowitsch PetscCall(cleanupConnection(env, link)); 1839566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 184095b3734SBarry Smith return (ierr); 1855c6c1daeSBarry Smith } 186