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) { 239566063dSJacob Faibussowitsch PetscCall(PetscGetHostName(hostname, sizeof(hostname))); 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; 639566063dSJacob Faibussowitsch PetscCall(printIndent(indent)); 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++) { 819566063dSJacob Faibussowitsch PetscCall(processPacket(link, indent+4)); 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; 1372e58f0efSBarry 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) { 2132e58f0efSBarry Smith err = processPacket(link, 0); 214*08401ef6SPierre Jolivet PetscCheck(err != 1,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error returned from Mathematica"); 2152e58f0efSBarry 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 2399566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 2409566063dSJacob Faibussowitsch PetscCall(setupConnection(&env, &link, "192.168.119.1", MATHEMATICA_LINK_CONNECT)); 2419566063dSJacob Faibussowitsch PetscCall(processPackets(link)); 2429566063dSJacob Faibussowitsch PetscCall(cleanupConnection(env, link)); 2439566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 244095b3734SBarry Smith return(ierr); 2455c6c1daeSBarry Smith } 246