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, sizeof(hostname));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