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