xref: /petsc/src/sys/classes/viewer/impls/mathematica/runtime.c (revision c4762a1b19cd2af06abeed90e8f9d34fb975dd94)
1 static const char help[] = "Tests PETSc -- Mathematica connection\n";
2 #include <petscksp.h>
3 #include <mathlink.h>
4 
5 typedef enum {MATHEMATICA_LINK_CREATE, MATHEMATICA_LINK_CONNECT, MATHEMATICA_LINK_LAUNCH} LinkMode;
6 
7 static int setupConnection(MLENV *env, MLINK *link, const char *linkhost, LinkMode linkmode)
8 {
9   int  argc = 5;
10   char *argv[5];
11   char hostname[256];
12   long lerr;
13   int  ierr;
14 
15   PetscFunctionBegin;
16   /* Link name */
17   argv[0] = "-linkname";
18   argv[1] = "8001";
19 
20   /* Link host */
21   argv[2] = "-linkhost";
22   if (!linkhost) {
23     ierr    = PetscGetHostName(hostname, 255);CHKERRQ(ierr);
24     argv[3] = hostname;
25   } else argv[3] = (char*) linkhost;
26 
27   /* Link mode */
28   switch (linkmode) {
29   case MATHEMATICA_LINK_CREATE:
30     argv[4] = "-linkcreate";
31     break;
32   case MATHEMATICA_LINK_CONNECT:
33     argv[4] = "-linkconnect";
34     break;
35   case MATHEMATICA_LINK_LAUNCH:
36     argv[4] = "-linklaunch";
37     break;
38   }
39 
40   *env = MLInitialize(0);
41   for (lerr = 0; lerr < argc; lerr++) printf("argv[%ld] = %s\n", lerr, argv[lerr]);
42   *link = MLOpenInEnv(*env, argc, argv, &lerr);
43   printf("lerr = %ld\n", lerr);
44   PetscFunctionReturn(0);
45 }
46 
47 static int printIndent(int indent)
48 {
49   int i;
50 
51   PetscFunctionBegin;
52   for (i = 0; i < indent; i++) printf(" ");
53   PetscFunctionReturn(0);
54 }
55 
56 static int processPacket(MLINK link, int indent)
57 {
58   static int isHead    = 0;
59   int        tokenType = MLGetNext(link);
60   int        ierr;
61 
62   PetscFunctionBegin;
63   ierr = printIndent(indent);CHKERRQ(ierr);
64   switch (tokenType) {
65   case MLTKFUNC:
66   {
67     long numArguments;
68     int  arg;
69 
70     printf("Function:\n");
71     MLGetArgCount(link, &numArguments);
72     /* Process head */
73     printf("  Head:\n");
74     isHead = 1;
75     ierr   = processPacket(link, indent+4);
76     if (ierr) PetscFunctionReturn(ierr);
77     isHead = 0;
78     /* Process arguments */
79     printf("  Arguments:\n");
80     for (arg = 0; arg < numArguments; arg++) {
81       ierr = processPacket(link, indent+4);CHKERRQ(ierr);
82     }
83   }
84     break;
85   case MLTKSYM:
86   {
87     const char *symbol;
88 
89     MLGetSymbol(link, &symbol);
90     printf("Symbol: %s\n", symbol);
91     if (isHead && !strcmp(symbol, "Shutdown")) {
92       MLDisownSymbol(link, symbol);
93       PetscFunctionReturn(2);
94     }
95     MLDisownSymbol(link, symbol);
96   }
97     break;
98   case MLTKINT:
99   {
100     int i;
101 
102     MLGetInteger(link, &i);
103     printf("Integer: %d\n", i);
104   }
105     break;
106   case MLTKREAL:
107   {
108     double r;
109 
110     MLGetReal(link, &r);
111     printf("Real: %g\n", r);
112   }
113     break;
114   case MLTKSTR:
115   {
116     const char *string;
117 
118     MLGetString(link, &string);
119     printf("String: %s\n", string);
120     MLDisownString(link, string);
121   }
122     break;
123   default:
124     printf("Unknown code %d\n", tokenType);
125     MLClearError(link);
126     fprintf(stderr, "ERROR: %s\n", (char*) MLErrorMessage(link));
127     PetscFunctionReturn(1);
128   }
129   PetscFunctionReturn(0);
130 }
131 
132 static int processPackets(MLINK link)
133 {
134   int packetType;
135   int loop   = 1;
136   int errors = 0;
137   int ierr;
138 
139   PetscFunctionBegin;
140   while (loop) {
141     while ((packetType = MLNextPacket(link)) && (packetType != RETURNPKT)) {
142       switch (packetType) {
143       case BEGINDLGPKT:
144         printf("Begin dialog packet\n");
145         break;
146       case CALLPKT:
147         printf("Call packet\n");
148         break;
149       case DISPLAYPKT:
150         printf("Display packet\n");
151         break;
152       case DISPLAYENDPKT:
153         printf("Display end packet\n");
154         break;
155       case ENDDLGPKT:
156         printf("End dialog packet\n");
157         break;
158       case ENTERTEXTPKT:
159         printf("Enter text packet\n");
160         break;
161       case ENTEREXPRPKT:
162         printf("Enter expression packet\n");
163         break;
164       case EVALUATEPKT:
165         printf("Evaluate packet\n");
166         break;
167       case INPUTPKT:
168         printf("Input packet\n");
169         break;
170       case INPUTNAMEPKT:
171         printf("Input name packet\n");
172         break;
173       case INPUTSTRPKT:
174         printf("Input string packet\n");
175         break;
176       case MENUPKT:
177         printf("Menu packet\n");
178         break;
179       case MESSAGEPKT:
180         printf("Message packet\n");
181         break;
182       case OUTPUTNAMEPKT:
183         printf("Output name packet\n");
184         break;
185       case RESUMEPKT:
186         printf("Resume packet\n");
187         break;
188       case RETURNTEXTPKT:
189         printf("Return text packet\n");
190         break;
191       case RETURNEXPRPKT:
192         printf("Return expression packet\n");
193         break;
194       case SUSPENDPKT:
195         printf("Suspend packet\n");
196         break;
197       case SYNTAXPKT:
198         printf("Syntax packet\n");
199         break;
200       case TEXTPKT:
201         printf("Text packet\n");
202         break;
203       }
204       MLNewPacket(link);
205     }
206 
207     /* Got a Return packet */
208     if (!packetType) {
209       MLClearError(link);
210       printf("ERROR: %s\n", (char*) MLErrorMessage(link));
211       errors++;
212     } else if (packetType == RETURNPKT) {
213       ierr = processPacket(link, 0);
214       if (ierr == 1) CHKERRQ(ierr);
215       if (ierr == 2) loop = 0;
216     } else {
217       fprintf(stderr, "Invalid packet type %d\n", packetType);
218       loop = 0;
219     }
220     if (errors > 10) loop = 0;
221   }
222   PetscFunctionReturn(0);
223 }
224 
225 static int cleanupConnection(MLENV env, MLINK link)
226 {
227   PetscFunctionBegin;
228   MLClose(link);
229   MLDeinitialize(env);
230   PetscFunctionReturn(0);
231 }
232 
233 int main(int argc, char *argv[])
234 {
235   MLENV env;
236   MLINK link;
237   int   ierr;
238 
239   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return(ierr);
240   ierr = setupConnection(&env, &link, "192.168.119.1", MATHEMATICA_LINK_CONNECT);CHKERRQ(ierr);
241   ierr = processPackets(link);CHKERRQ(ierr);
242   ierr = cleanupConnection(env, link);CHKERRQ(ierr);
243   ierr = PetscFinalize();
244   return(ierr);
245 }
246