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 75c6c1daeSBarry Smith #undef __FUNCT__ 85c6c1daeSBarry Smith #define __FUNCT__ "setupConnection" 9a6dfd86eSKarl Rupp static int setupConnection(MLENV *env, MLINK *link, const char *linkhost, LinkMode linkmode) 10a6dfd86eSKarl Rupp { 115c6c1daeSBarry Smith int argc = 5; 125c6c1daeSBarry Smith char *argv[5]; 135c6c1daeSBarry Smith char hostname[256]; 145c6c1daeSBarry Smith long lerr; 155c6c1daeSBarry Smith int ierr; 165c6c1daeSBarry Smith 175c6c1daeSBarry Smith PetscFunctionBegin; 185c6c1daeSBarry Smith /* Link name */ 195c6c1daeSBarry Smith argv[0] = "-linkname"; 205c6c1daeSBarry Smith argv[1] = "8001"; 21*a297a907SKarl Rupp 225c6c1daeSBarry Smith /* Link host */ 235c6c1daeSBarry Smith argv[2] = "-linkhost"; 245c6c1daeSBarry Smith if (!linkhost) { 255c6c1daeSBarry Smith ierr = PetscGetHostName(hostname, 255);CHKERRQ(ierr); 265c6c1daeSBarry Smith argv[3] = hostname; 27*a297a907SKarl Rupp } else argv[3] = (char*) linkhost; 28*a297a907SKarl Rupp 295c6c1daeSBarry Smith /* Link mode */ 305c6c1daeSBarry Smith switch (linkmode) { 315c6c1daeSBarry Smith case MATHEMATICA_LINK_CREATE: 325c6c1daeSBarry Smith argv[4] = "-linkcreate"; 335c6c1daeSBarry Smith break; 345c6c1daeSBarry Smith case MATHEMATICA_LINK_CONNECT: 355c6c1daeSBarry Smith argv[4] = "-linkconnect"; 365c6c1daeSBarry Smith break; 375c6c1daeSBarry Smith case MATHEMATICA_LINK_LAUNCH: 385c6c1daeSBarry Smith argv[4] = "-linklaunch"; 395c6c1daeSBarry Smith break; 405c6c1daeSBarry Smith } 415c6c1daeSBarry Smith 425c6c1daeSBarry Smith *env = MLInitialize(0); 43*a297a907SKarl Rupp for (lerr = 0; lerr < argc; lerr++) printf("argv[%ld] = %s\n", lerr, argv[lerr]); 445c6c1daeSBarry Smith *link = MLOpenInEnv(*env, argc, argv, &lerr); 455c6c1daeSBarry Smith printf("lerr = %ld\n", lerr); 465c6c1daeSBarry Smith PetscFunctionReturn(0); 475c6c1daeSBarry Smith } 485c6c1daeSBarry Smith 495c6c1daeSBarry Smith #undef __FUNCT__ 505c6c1daeSBarry Smith #define __FUNCT__ "printIndent" 51a6dfd86eSKarl Rupp static int printIndent(int indent) 52a6dfd86eSKarl Rupp { 535c6c1daeSBarry Smith int i; 545c6c1daeSBarry Smith 555c6c1daeSBarry Smith PetscFunctionBegin; 565c6c1daeSBarry Smith for (i = 0; i < indent; i++) printf(" "); 575c6c1daeSBarry Smith PetscFunctionReturn(0); 585c6c1daeSBarry Smith } 595c6c1daeSBarry Smith 605c6c1daeSBarry Smith #undef __FUNCT__ 615c6c1daeSBarry Smith #define __FUNCT__ "processPacket" 62a6dfd86eSKarl Rupp static int processPacket(MLINK link, int indent) 63a6dfd86eSKarl Rupp { 645c6c1daeSBarry Smith static int isHead = 0; 655c6c1daeSBarry Smith int tokenType = MLGetNext(link); 665c6c1daeSBarry Smith int ierr; 675c6c1daeSBarry Smith 685c6c1daeSBarry Smith PetscFunctionBegin; 695c6c1daeSBarry Smith ierr = printIndent(indent);CHKERRQ(ierr); 705c6c1daeSBarry Smith switch (tokenType) { 715c6c1daeSBarry Smith case MLTKFUNC: 725c6c1daeSBarry Smith { 735c6c1daeSBarry Smith long numArguments; 745c6c1daeSBarry Smith int arg; 755c6c1daeSBarry Smith 765c6c1daeSBarry Smith printf("Function:\n"); 775c6c1daeSBarry Smith MLGetArgCount(link, &numArguments); 785c6c1daeSBarry Smith /* Process head */ 795c6c1daeSBarry Smith printf(" Head:\n"); 805c6c1daeSBarry Smith isHead = 1; 815c6c1daeSBarry Smith ierr = processPacket(link, indent+4); 825c6c1daeSBarry Smith if (ierr) PetscFunctionReturn(ierr); 835c6c1daeSBarry Smith isHead = 0; 845c6c1daeSBarry Smith /* Process arguments */ 855c6c1daeSBarry Smith printf(" Arguments:\n"); 865c6c1daeSBarry Smith for (arg = 0; arg < numArguments; arg++) { 875c6c1daeSBarry Smith ierr = processPacket(link, indent+4);CHKERRQ(ierr); 885c6c1daeSBarry Smith } 895c6c1daeSBarry Smith } 905c6c1daeSBarry Smith break; 915c6c1daeSBarry Smith case MLTKSYM: 925c6c1daeSBarry Smith { 935c6c1daeSBarry Smith const char *symbol; 945c6c1daeSBarry Smith 955c6c1daeSBarry Smith MLGetSymbol(link, &symbol); 965c6c1daeSBarry Smith printf("Symbol: %s\n", symbol); 975c6c1daeSBarry Smith if (isHead && !strcmp(symbol, "Shutdown")) { 985c6c1daeSBarry Smith MLDisownSymbol(link, symbol); 995c6c1daeSBarry Smith PetscFunctionReturn(2); 1005c6c1daeSBarry Smith } 1015c6c1daeSBarry Smith MLDisownSymbol(link, symbol); 1025c6c1daeSBarry Smith } 1035c6c1daeSBarry Smith break; 1045c6c1daeSBarry Smith case MLTKINT: 1055c6c1daeSBarry Smith { 1065c6c1daeSBarry Smith int i; 1075c6c1daeSBarry Smith 1085c6c1daeSBarry Smith MLGetInteger(link, &i); 1095c6c1daeSBarry Smith printf("Integer: %d\n", i); 1105c6c1daeSBarry Smith } 1115c6c1daeSBarry Smith break; 1125c6c1daeSBarry Smith case MLTKREAL: 1135c6c1daeSBarry Smith { 1145c6c1daeSBarry Smith double r; 1155c6c1daeSBarry Smith 1165c6c1daeSBarry Smith MLGetReal(link, &r); 1175c6c1daeSBarry Smith printf("Real: %g\n", r); 1185c6c1daeSBarry Smith } 1195c6c1daeSBarry Smith break; 1205c6c1daeSBarry Smith case MLTKSTR: 1215c6c1daeSBarry Smith { 1225c6c1daeSBarry Smith const char *string; 1235c6c1daeSBarry Smith 1245c6c1daeSBarry Smith MLGetString(link, &string); 1255c6c1daeSBarry Smith printf("String: %s\n", string); 1265c6c1daeSBarry Smith MLDisownString(link, string); 1275c6c1daeSBarry Smith } 1285c6c1daeSBarry Smith break; 1295c6c1daeSBarry Smith default: 1305c6c1daeSBarry Smith printf("Unknown code %d\n", tokenType); 1315c6c1daeSBarry Smith MLClearError(link); 1325c6c1daeSBarry Smith fprintf(stderr, "ERROR: %s\n", (char*) MLErrorMessage(link)); 1335c6c1daeSBarry Smith PetscFunctionReturn(1); 1345c6c1daeSBarry Smith } 1355c6c1daeSBarry Smith PetscFunctionReturn(0); 1365c6c1daeSBarry Smith } 1375c6c1daeSBarry Smith 1385c6c1daeSBarry Smith #undef __FUNCT__ 1395c6c1daeSBarry Smith #define __FUNCT__ "processPackets" 140a6dfd86eSKarl Rupp static int processPackets(MLINK link) 141a6dfd86eSKarl Rupp { 1425c6c1daeSBarry Smith int packetType; 1435c6c1daeSBarry Smith int loop = 1; 1445c6c1daeSBarry Smith int errors = 0; 1455c6c1daeSBarry Smith int ierr; 1465c6c1daeSBarry Smith 1475c6c1daeSBarry Smith PetscFunctionBegin; 1485c6c1daeSBarry Smith while (loop) { 1495c6c1daeSBarry Smith while ((packetType = MLNextPacket(link)) && (packetType != RETURNPKT)) { 1505c6c1daeSBarry Smith switch (packetType) { 1515c6c1daeSBarry Smith case BEGINDLGPKT: 1525c6c1daeSBarry Smith printf("Begin dialog packet\n"); 1535c6c1daeSBarry Smith break; 1545c6c1daeSBarry Smith case CALLPKT: 1555c6c1daeSBarry Smith printf("Call packet\n"); 1565c6c1daeSBarry Smith break; 1575c6c1daeSBarry Smith case DISPLAYPKT: 1585c6c1daeSBarry Smith printf("Display packet\n"); 1595c6c1daeSBarry Smith break; 1605c6c1daeSBarry Smith case DISPLAYENDPKT: 1615c6c1daeSBarry Smith printf("Display end packet\n"); 1625c6c1daeSBarry Smith break; 1635c6c1daeSBarry Smith case ENDDLGPKT: 1645c6c1daeSBarry Smith printf("End dialog packet\n"); 1655c6c1daeSBarry Smith break; 1665c6c1daeSBarry Smith case ENTERTEXTPKT: 1675c6c1daeSBarry Smith printf("Enter text packet\n"); 1685c6c1daeSBarry Smith break; 1695c6c1daeSBarry Smith case ENTEREXPRPKT: 1705c6c1daeSBarry Smith printf("Enter expression packet\n"); 1715c6c1daeSBarry Smith break; 1725c6c1daeSBarry Smith case EVALUATEPKT: 1735c6c1daeSBarry Smith printf("Evaluate packet\n"); 1745c6c1daeSBarry Smith break; 1755c6c1daeSBarry Smith case INPUTPKT: 1765c6c1daeSBarry Smith printf("Input packet\n"); 1775c6c1daeSBarry Smith break; 1785c6c1daeSBarry Smith case INPUTNAMEPKT: 1795c6c1daeSBarry Smith printf("Input name packet\n"); 1805c6c1daeSBarry Smith break; 1815c6c1daeSBarry Smith case INPUTSTRPKT: 1825c6c1daeSBarry Smith printf("Input string packet\n"); 1835c6c1daeSBarry Smith break; 1845c6c1daeSBarry Smith case MENUPKT: 1855c6c1daeSBarry Smith printf("Menu packet\n"); 1865c6c1daeSBarry Smith break; 1875c6c1daeSBarry Smith case MESSAGEPKT: 1885c6c1daeSBarry Smith printf("Message packet\n"); 1895c6c1daeSBarry Smith break; 1905c6c1daeSBarry Smith case OUTPUTNAMEPKT: 1915c6c1daeSBarry Smith printf("Output name packet\n"); 1925c6c1daeSBarry Smith break; 1935c6c1daeSBarry Smith case RESUMEPKT: 1945c6c1daeSBarry Smith printf("Resume packet\n"); 1955c6c1daeSBarry Smith break; 1965c6c1daeSBarry Smith case RETURNTEXTPKT: 1975c6c1daeSBarry Smith printf("Return text packet\n"); 1985c6c1daeSBarry Smith break; 1995c6c1daeSBarry Smith case RETURNEXPRPKT: 2005c6c1daeSBarry Smith printf("Return expression packet\n"); 2015c6c1daeSBarry Smith break; 2025c6c1daeSBarry Smith case SUSPENDPKT: 2035c6c1daeSBarry Smith printf("Suspend packet\n"); 2045c6c1daeSBarry Smith break; 2055c6c1daeSBarry Smith case SYNTAXPKT: 2065c6c1daeSBarry Smith printf("Syntax packet\n"); 2075c6c1daeSBarry Smith break; 2085c6c1daeSBarry Smith case TEXTPKT: 2095c6c1daeSBarry Smith printf("Text packet\n"); 2105c6c1daeSBarry Smith break; 2115c6c1daeSBarry Smith } 2125c6c1daeSBarry Smith MLNewPacket(link); 2135c6c1daeSBarry Smith } 2145c6c1daeSBarry Smith 2155c6c1daeSBarry Smith /* Got a Return packet */ 2165c6c1daeSBarry Smith if (!packetType) { 2175c6c1daeSBarry Smith MLClearError(link); 2185c6c1daeSBarry Smith printf("ERROR: %s\n", (char*) MLErrorMessage(link)); 2195c6c1daeSBarry Smith errors++; 2205c6c1daeSBarry Smith } else if (packetType == RETURNPKT) { 2215c6c1daeSBarry Smith ierr = processPacket(link, 0); 2225c6c1daeSBarry Smith if (ierr == 1) CHKERRQ(ierr); 2235c6c1daeSBarry Smith if (ierr == 2) loop = 0; 2245c6c1daeSBarry Smith } else { 2255c6c1daeSBarry Smith fprintf(stderr, "Invalid packet type %d\n", packetType); 2265c6c1daeSBarry Smith loop = 0; 2275c6c1daeSBarry Smith } 2285c6c1daeSBarry Smith if (errors > 10) loop = 0; 2295c6c1daeSBarry Smith } 2305c6c1daeSBarry Smith PetscFunctionReturn(0); 2315c6c1daeSBarry Smith } 2325c6c1daeSBarry Smith 2335c6c1daeSBarry Smith #undef __FUNCT__ 2345c6c1daeSBarry Smith #define __FUNCT__ "cleanupConnection" 235a6dfd86eSKarl Rupp static int cleanupConnection(MLENV env, MLINK link) 236a6dfd86eSKarl Rupp { 2375c6c1daeSBarry Smith PetscFunctionBegin; 2385c6c1daeSBarry Smith MLClose(link); 2395c6c1daeSBarry Smith MLDeinitialize(env); 2405c6c1daeSBarry Smith PetscFunctionReturn(0); 2415c6c1daeSBarry Smith } 2425c6c1daeSBarry Smith 2435c6c1daeSBarry Smith #undef __FUNCT__ 2445c6c1daeSBarry Smith #define __FUNCT__ "main" 245a6dfd86eSKarl Rupp int main(int argc, char *argv[]) 246a6dfd86eSKarl Rupp { 2475c6c1daeSBarry Smith MLENV env; 2485c6c1daeSBarry Smith MLINK link; 2495c6c1daeSBarry Smith int ierr; 2505c6c1daeSBarry Smith 2515c6c1daeSBarry Smith ierr = PetscInitialize(&argc, &argv, PETSC_NULL, help);CHKERRABORT(PETSC_COMM_WORLD, ierr); 2525c6c1daeSBarry Smith ierr = setupConnection(&env, &link, "192.168.119.1", MATHEMATICA_LINK_CONNECT);CHKERRABORT(PETSC_COMM_WORLD, ierr); 2535c6c1daeSBarry Smith ierr = processPackets(link);CHKERRABORT(PETSC_COMM_WORLD, ierr); 2545c6c1daeSBarry Smith ierr = cleanupConnection(env, link);CHKERRABORT(PETSC_COMM_WORLD, ierr); 2555c6c1daeSBarry Smith ierr = PetscFinalize();CHKERRABORT(PETSC_COMM_WORLD, ierr); 2565c6c1daeSBarry Smith return(0); 2575c6c1daeSBarry Smith } 258