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 11*d71ae5a4SJacob Faibussowitsch static PetscErroCode setupConnection(MLENV *env, MLINK *link, const char *linkhost, LinkMode linkmode) 12*d71ae5a4SJacob Faibussowitsch { 135c6c1daeSBarry Smith int argc = 5; 145c6c1daeSBarry Smith char *argv[5]; 155c6c1daeSBarry Smith char hostname[256]; 165c6c1daeSBarry Smith long lerr; 175c6c1daeSBarry Smith int ierr; 185c6c1daeSBarry Smith 195c6c1daeSBarry Smith PetscFunctionBegin; 205c6c1daeSBarry Smith /* Link name */ 215c6c1daeSBarry Smith argv[0] = "-linkname"; 225c6c1daeSBarry Smith argv[1] = "8001"; 23a297a907SKarl Rupp 245c6c1daeSBarry Smith /* Link host */ 255c6c1daeSBarry Smith argv[2] = "-linkhost"; 265c6c1daeSBarry Smith if (!linkhost) { 279566063dSJacob Faibussowitsch PetscCall(PetscGetHostName(hostname, sizeof(hostname))); 285c6c1daeSBarry Smith argv[3] = hostname; 29a297a907SKarl Rupp } else argv[3] = (char *)linkhost; 30a297a907SKarl Rupp 315c6c1daeSBarry Smith /* Link mode */ 325c6c1daeSBarry Smith switch (linkmode) { 33*d71ae5a4SJacob Faibussowitsch case MATHEMATICA_LINK_CREATE: 34*d71ae5a4SJacob Faibussowitsch argv[4] = "-linkcreate"; 35*d71ae5a4SJacob Faibussowitsch break; 36*d71ae5a4SJacob Faibussowitsch case MATHEMATICA_LINK_CONNECT: 37*d71ae5a4SJacob Faibussowitsch argv[4] = "-linkconnect"; 38*d71ae5a4SJacob Faibussowitsch break; 39*d71ae5a4SJacob Faibussowitsch case MATHEMATICA_LINK_LAUNCH: 40*d71ae5a4SJacob Faibussowitsch argv[4] = "-linklaunch"; 41*d71ae5a4SJacob Faibussowitsch break; 425c6c1daeSBarry Smith } 435c6c1daeSBarry Smith 445c6c1daeSBarry Smith *env = MLInitialize(0); 45a297a907SKarl Rupp for (lerr = 0; lerr < argc; lerr++) printf("argv[%ld] = %s\n", lerr, argv[lerr]); 465c6c1daeSBarry Smith *link = MLOpenInEnv(*env, argc, argv, &lerr); 475c6c1daeSBarry Smith printf("lerr = %ld\n", lerr); 485c6c1daeSBarry Smith PetscFunctionReturn(0); 495c6c1daeSBarry Smith } 505c6c1daeSBarry Smith 51*d71ae5a4SJacob Faibussowitsch static PetscErrorCode printIndent(int indent) 52*d71ae5a4SJacob Faibussowitsch { 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 60*d71ae5a4SJacob Faibussowitsch static PetscErrorCode processPacket(MLINK link, int indent, int *result) 61*d71ae5a4SJacob Faibussowitsch { 625c6c1daeSBarry Smith static int isHead = 0; 635c6c1daeSBarry Smith int tokenType = MLGetNext(link); 645c6c1daeSBarry Smith int ierr; 655c6c1daeSBarry Smith 665c6c1daeSBarry Smith PetscFunctionBegin; 679566063dSJacob Faibussowitsch PetscCall(printIndent(indent)); 685c6c1daeSBarry Smith switch (tokenType) { 699371c9d4SSatish Balay case MLTKFUNC: { 705c6c1daeSBarry Smith long numArguments; 715c6c1daeSBarry Smith int arg; 725c6c1daeSBarry Smith 735c6c1daeSBarry Smith printf("Function:\n"); 745c6c1daeSBarry Smith MLGetArgCount(link, &numArguments); 755c6c1daeSBarry Smith /* Process head */ 765c6c1daeSBarry Smith printf(" Head:\n"); 775c6c1daeSBarry Smith isHead = 1; 7811cc89d2SBarry Smith PetscCall(processPacket(link, indent + 4, result)); 7911cc89d2SBarry Smith if (*result) PetscFunctionReturn(0); 805c6c1daeSBarry Smith isHead = 0; 815c6c1daeSBarry Smith /* Process arguments */ 825c6c1daeSBarry Smith printf(" Arguments:\n"); 8348a46eb9SPierre Jolivet for (arg = 0; arg < numArguments; arg++) PetscCall(processPacket(link, indent + 4)); 849371c9d4SSatish Balay } break; 859371c9d4SSatish Balay case MLTKSYM: { 865c6c1daeSBarry Smith const char *symbol; 875c6c1daeSBarry Smith 885c6c1daeSBarry Smith MLGetSymbol(link, &symbol); 895c6c1daeSBarry Smith printf("Symbol: %s\n", symbol); 905c6c1daeSBarry Smith if (isHead && !strcmp(symbol, "Shutdown")) { 915c6c1daeSBarry Smith MLDisownSymbol(link, symbol); 9211cc89d2SBarry Smith *result = 2; 9311cc89d2SBarry Smith PetscFunctionReturn(0); 945c6c1daeSBarry Smith } 955c6c1daeSBarry Smith MLDisownSymbol(link, symbol); 969371c9d4SSatish Balay } break; 979371c9d4SSatish Balay case MLTKINT: { 985c6c1daeSBarry Smith int i; 995c6c1daeSBarry Smith 1005c6c1daeSBarry Smith MLGetInteger(link, &i); 1015c6c1daeSBarry Smith printf("Integer: %d\n", i); 1029371c9d4SSatish Balay } break; 1039371c9d4SSatish Balay case MLTKREAL: { 1045c6c1daeSBarry Smith double r; 1055c6c1daeSBarry Smith 1065c6c1daeSBarry Smith MLGetReal(link, &r); 1075c6c1daeSBarry Smith printf("Real: %g\n", r); 1089371c9d4SSatish Balay } break; 1099371c9d4SSatish Balay case MLTKSTR: { 1105c6c1daeSBarry Smith const char *string; 1115c6c1daeSBarry Smith 1125c6c1daeSBarry Smith MLGetString(link, &string); 1135c6c1daeSBarry Smith printf("String: %s\n", string); 1145c6c1daeSBarry Smith MLDisownString(link, string); 1159371c9d4SSatish Balay } break; 1165c6c1daeSBarry Smith default: 1175c6c1daeSBarry Smith printf("Unknown code %d\n", tokenType); 1185c6c1daeSBarry Smith MLClearError(link); 1195c6c1daeSBarry Smith fprintf(stderr, "ERROR: %s\n", (char *)MLErrorMessage(link)); 12011cc89d2SBarry Smith *result = 1; 12111cc89d2SBarry Smith PetscFunctionReturn(0); 1225c6c1daeSBarry Smith } 1235c6c1daeSBarry Smith PetscFunctionReturn(0); 1245c6c1daeSBarry Smith } 1255c6c1daeSBarry Smith 126*d71ae5a4SJacob Faibussowitsch static PetscErrorCode processPackets(MLINK link) 127*d71ae5a4SJacob Faibussowitsch { 1285c6c1daeSBarry Smith int packetType; 1295c6c1daeSBarry Smith int loop = 1; 1305c6c1daeSBarry Smith int errors = 0; 13111cc89d2SBarry Smith int err, result; 1325c6c1daeSBarry Smith 1335c6c1daeSBarry Smith PetscFunctionBegin; 1345c6c1daeSBarry Smith while (loop) { 1355c6c1daeSBarry Smith while ((packetType = MLNextPacket(link)) && (packetType != RETURNPKT)) { 1365c6c1daeSBarry Smith switch (packetType) { 137*d71ae5a4SJacob Faibussowitsch case BEGINDLGPKT: 138*d71ae5a4SJacob Faibussowitsch printf("Begin dialog packet\n"); 139*d71ae5a4SJacob Faibussowitsch break; 140*d71ae5a4SJacob Faibussowitsch case CALLPKT: 141*d71ae5a4SJacob Faibussowitsch printf("Call packet\n"); 142*d71ae5a4SJacob Faibussowitsch break; 143*d71ae5a4SJacob Faibussowitsch case DISPLAYPKT: 144*d71ae5a4SJacob Faibussowitsch printf("Display packet\n"); 145*d71ae5a4SJacob Faibussowitsch break; 146*d71ae5a4SJacob Faibussowitsch case DISPLAYENDPKT: 147*d71ae5a4SJacob Faibussowitsch printf("Display end packet\n"); 148*d71ae5a4SJacob Faibussowitsch break; 149*d71ae5a4SJacob Faibussowitsch case ENDDLGPKT: 150*d71ae5a4SJacob Faibussowitsch printf("End dialog packet\n"); 151*d71ae5a4SJacob Faibussowitsch break; 152*d71ae5a4SJacob Faibussowitsch case ENTERTEXTPKT: 153*d71ae5a4SJacob Faibussowitsch printf("Enter text packet\n"); 154*d71ae5a4SJacob Faibussowitsch break; 155*d71ae5a4SJacob Faibussowitsch case ENTEREXPRPKT: 156*d71ae5a4SJacob Faibussowitsch printf("Enter expression packet\n"); 157*d71ae5a4SJacob Faibussowitsch break; 158*d71ae5a4SJacob Faibussowitsch case EVALUATEPKT: 159*d71ae5a4SJacob Faibussowitsch printf("Evaluate packet\n"); 160*d71ae5a4SJacob Faibussowitsch break; 161*d71ae5a4SJacob Faibussowitsch case INPUTPKT: 162*d71ae5a4SJacob Faibussowitsch printf("Input packet\n"); 163*d71ae5a4SJacob Faibussowitsch break; 164*d71ae5a4SJacob Faibussowitsch case INPUTNAMEPKT: 165*d71ae5a4SJacob Faibussowitsch printf("Input name packet\n"); 166*d71ae5a4SJacob Faibussowitsch break; 167*d71ae5a4SJacob Faibussowitsch case INPUTSTRPKT: 168*d71ae5a4SJacob Faibussowitsch printf("Input string packet\n"); 169*d71ae5a4SJacob Faibussowitsch break; 170*d71ae5a4SJacob Faibussowitsch case MENUPKT: 171*d71ae5a4SJacob Faibussowitsch printf("Menu packet\n"); 172*d71ae5a4SJacob Faibussowitsch break; 173*d71ae5a4SJacob Faibussowitsch case MESSAGEPKT: 174*d71ae5a4SJacob Faibussowitsch printf("Message packet\n"); 175*d71ae5a4SJacob Faibussowitsch break; 176*d71ae5a4SJacob Faibussowitsch case OUTPUTNAMEPKT: 177*d71ae5a4SJacob Faibussowitsch printf("Output name packet\n"); 178*d71ae5a4SJacob Faibussowitsch break; 179*d71ae5a4SJacob Faibussowitsch case RESUMEPKT: 180*d71ae5a4SJacob Faibussowitsch printf("Resume packet\n"); 181*d71ae5a4SJacob Faibussowitsch break; 182*d71ae5a4SJacob Faibussowitsch case RETURNTEXTPKT: 183*d71ae5a4SJacob Faibussowitsch printf("Return text packet\n"); 184*d71ae5a4SJacob Faibussowitsch break; 185*d71ae5a4SJacob Faibussowitsch case RETURNEXPRPKT: 186*d71ae5a4SJacob Faibussowitsch printf("Return expression packet\n"); 187*d71ae5a4SJacob Faibussowitsch break; 188*d71ae5a4SJacob Faibussowitsch case SUSPENDPKT: 189*d71ae5a4SJacob Faibussowitsch printf("Suspend packet\n"); 190*d71ae5a4SJacob Faibussowitsch break; 191*d71ae5a4SJacob Faibussowitsch case SYNTAXPKT: 192*d71ae5a4SJacob Faibussowitsch printf("Syntax packet\n"); 193*d71ae5a4SJacob Faibussowitsch break; 194*d71ae5a4SJacob Faibussowitsch case TEXTPKT: 195*d71ae5a4SJacob Faibussowitsch printf("Text packet\n"); 196*d71ae5a4SJacob Faibussowitsch break; 1975c6c1daeSBarry Smith } 1985c6c1daeSBarry Smith MLNewPacket(link); 1995c6c1daeSBarry Smith } 2005c6c1daeSBarry Smith 2015c6c1daeSBarry Smith /* Got a Return packet */ 2025c6c1daeSBarry Smith if (!packetType) { 2035c6c1daeSBarry Smith MLClearError(link); 2045c6c1daeSBarry Smith printf("ERROR: %s\n", (char *)MLErrorMessage(link)); 2055c6c1daeSBarry Smith errors++; 2065c6c1daeSBarry Smith } else if (packetType == RETURNPKT) { 20711cc89d2SBarry Smith PetscCall(processPacket(link, result)); 20811cc89d2SBarry Smith if (result == 2) loop = 0; 2095c6c1daeSBarry Smith } else { 2105c6c1daeSBarry Smith fprintf(stderr, "Invalid packet type %d\n", packetType); 2115c6c1daeSBarry Smith loop = 0; 2125c6c1daeSBarry Smith } 2135c6c1daeSBarry Smith if (errors > 10) loop = 0; 2145c6c1daeSBarry Smith } 2155c6c1daeSBarry Smith PetscFunctionReturn(0); 2165c6c1daeSBarry Smith } 2175c6c1daeSBarry Smith 218*d71ae5a4SJacob Faibussowitsch static PetscErrorCode cleanupConnection(MLENV env, MLINK link) 219*d71ae5a4SJacob Faibussowitsch { 2205c6c1daeSBarry Smith PetscFunctionBegin; 2215c6c1daeSBarry Smith MLClose(link); 2225c6c1daeSBarry Smith MLDeinitialize(env); 2235c6c1daeSBarry Smith PetscFunctionReturn(0); 2245c6c1daeSBarry Smith } 2255c6c1daeSBarry Smith 226*d71ae5a4SJacob Faibussowitsch int main(int argc, char *argv[]) 227*d71ae5a4SJacob Faibussowitsch { 2285c6c1daeSBarry Smith MLENV env; 2295c6c1daeSBarry Smith MLINK link; 2305c6c1daeSBarry Smith 2319566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 2329566063dSJacob Faibussowitsch PetscCall(setupConnection(&env, &link, "192.168.119.1", MATHEMATICA_LINK_CONNECT)); 2339566063dSJacob Faibussowitsch PetscCall(processPackets(link)); 2349566063dSJacob Faibussowitsch PetscCall(cleanupConnection(env, link)); 2359566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 23611cc89d2SBarry Smith return 0; 2375c6c1daeSBarry Smith } 238