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: }