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