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
setupConnection(MLENV * env,MLINK * link,const char * linkhost,LinkMode linkmode)11d71ae5a4SJacob Faibussowitsch static PetscErroCode setupConnection(MLENV *env, MLINK *link, const char *linkhost, LinkMode linkmode)
12d71ae5a4SJacob 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) {
33d71ae5a4SJacob Faibussowitsch case MATHEMATICA_LINK_CREATE:
34d71ae5a4SJacob Faibussowitsch argv[4] = "-linkcreate";
35d71ae5a4SJacob Faibussowitsch break;
36d71ae5a4SJacob Faibussowitsch case MATHEMATICA_LINK_CONNECT:
37d71ae5a4SJacob Faibussowitsch argv[4] = "-linkconnect";
38d71ae5a4SJacob Faibussowitsch break;
39d71ae5a4SJacob Faibussowitsch case MATHEMATICA_LINK_LAUNCH:
40d71ae5a4SJacob Faibussowitsch argv[4] = "-linklaunch";
41d71ae5a4SJacob 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);
48*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
495c6c1daeSBarry Smith }
505c6c1daeSBarry Smith
printIndent(int indent)51d71ae5a4SJacob Faibussowitsch static PetscErrorCode printIndent(int indent)
52d71ae5a4SJacob Faibussowitsch {
535c6c1daeSBarry Smith int i;
545c6c1daeSBarry Smith
555c6c1daeSBarry Smith PetscFunctionBegin;
565c6c1daeSBarry Smith for (i = 0; i < indent; i++) printf(" ");
57*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
585c6c1daeSBarry Smith }
595c6c1daeSBarry Smith
processPacket(MLINK link,int indent,int * result)60d71ae5a4SJacob Faibussowitsch static PetscErrorCode processPacket(MLINK link, int indent, int *result)
61d71ae5a4SJacob 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));
79*3ba16761SJacob Faibussowitsch if (*result) PetscFunctionReturn(PETSC_SUCCESS);
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;
93*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
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;
121*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1225c6c1daeSBarry Smith }
123*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1245c6c1daeSBarry Smith }
1255c6c1daeSBarry Smith
processPackets(MLINK link)126d71ae5a4SJacob Faibussowitsch static PetscErrorCode processPackets(MLINK link)
127d71ae5a4SJacob 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) {
137d71ae5a4SJacob Faibussowitsch case BEGINDLGPKT:
138d71ae5a4SJacob Faibussowitsch printf("Begin dialog packet\n");
139d71ae5a4SJacob Faibussowitsch break;
140d71ae5a4SJacob Faibussowitsch case CALLPKT:
141d71ae5a4SJacob Faibussowitsch printf("Call packet\n");
142d71ae5a4SJacob Faibussowitsch break;
143d71ae5a4SJacob Faibussowitsch case DISPLAYPKT:
144d71ae5a4SJacob Faibussowitsch printf("Display packet\n");
145d71ae5a4SJacob Faibussowitsch break;
146d71ae5a4SJacob Faibussowitsch case DISPLAYENDPKT:
147d71ae5a4SJacob Faibussowitsch printf("Display end packet\n");
148d71ae5a4SJacob Faibussowitsch break;
149d71ae5a4SJacob Faibussowitsch case ENDDLGPKT:
150d71ae5a4SJacob Faibussowitsch printf("End dialog packet\n");
151d71ae5a4SJacob Faibussowitsch break;
152d71ae5a4SJacob Faibussowitsch case ENTERTEXTPKT:
153d71ae5a4SJacob Faibussowitsch printf("Enter text packet\n");
154d71ae5a4SJacob Faibussowitsch break;
155d71ae5a4SJacob Faibussowitsch case ENTEREXPRPKT:
156d71ae5a4SJacob Faibussowitsch printf("Enter expression packet\n");
157d71ae5a4SJacob Faibussowitsch break;
158d71ae5a4SJacob Faibussowitsch case EVALUATEPKT:
159d71ae5a4SJacob Faibussowitsch printf("Evaluate packet\n");
160d71ae5a4SJacob Faibussowitsch break;
161d71ae5a4SJacob Faibussowitsch case INPUTPKT:
162d71ae5a4SJacob Faibussowitsch printf("Input packet\n");
163d71ae5a4SJacob Faibussowitsch break;
164d71ae5a4SJacob Faibussowitsch case INPUTNAMEPKT:
165d71ae5a4SJacob Faibussowitsch printf("Input name packet\n");
166d71ae5a4SJacob Faibussowitsch break;
167d71ae5a4SJacob Faibussowitsch case INPUTSTRPKT:
168d71ae5a4SJacob Faibussowitsch printf("Input string packet\n");
169d71ae5a4SJacob Faibussowitsch break;
170d71ae5a4SJacob Faibussowitsch case MENUPKT:
171d71ae5a4SJacob Faibussowitsch printf("Menu packet\n");
172d71ae5a4SJacob Faibussowitsch break;
173d71ae5a4SJacob Faibussowitsch case MESSAGEPKT:
174d71ae5a4SJacob Faibussowitsch printf("Message packet\n");
175d71ae5a4SJacob Faibussowitsch break;
176d71ae5a4SJacob Faibussowitsch case OUTPUTNAMEPKT:
177d71ae5a4SJacob Faibussowitsch printf("Output name packet\n");
178d71ae5a4SJacob Faibussowitsch break;
179d71ae5a4SJacob Faibussowitsch case RESUMEPKT:
180d71ae5a4SJacob Faibussowitsch printf("Resume packet\n");
181d71ae5a4SJacob Faibussowitsch break;
182d71ae5a4SJacob Faibussowitsch case RETURNTEXTPKT:
183d71ae5a4SJacob Faibussowitsch printf("Return text packet\n");
184d71ae5a4SJacob Faibussowitsch break;
185d71ae5a4SJacob Faibussowitsch case RETURNEXPRPKT:
186d71ae5a4SJacob Faibussowitsch printf("Return expression packet\n");
187d71ae5a4SJacob Faibussowitsch break;
188d71ae5a4SJacob Faibussowitsch case SUSPENDPKT:
189d71ae5a4SJacob Faibussowitsch printf("Suspend packet\n");
190d71ae5a4SJacob Faibussowitsch break;
191d71ae5a4SJacob Faibussowitsch case SYNTAXPKT:
192d71ae5a4SJacob Faibussowitsch printf("Syntax packet\n");
193d71ae5a4SJacob Faibussowitsch break;
194d71ae5a4SJacob Faibussowitsch case TEXTPKT:
195d71ae5a4SJacob Faibussowitsch printf("Text packet\n");
196d71ae5a4SJacob 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 }
215*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2165c6c1daeSBarry Smith }
2175c6c1daeSBarry Smith
cleanupConnection(MLENV env,MLINK link)218d71ae5a4SJacob Faibussowitsch static PetscErrorCode cleanupConnection(MLENV env, MLINK link)
219d71ae5a4SJacob Faibussowitsch {
2205c6c1daeSBarry Smith PetscFunctionBegin;
2215c6c1daeSBarry Smith MLClose(link);
2225c6c1daeSBarry Smith MLDeinitialize(env);
223*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2245c6c1daeSBarry Smith }
2255c6c1daeSBarry Smith
main(int argc,char * argv[])226d71ae5a4SJacob Faibussowitsch int main(int argc, char *argv[])
227d71ae5a4SJacob 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