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