1: static char Sccsid[] = "aplcvt.c @(#)aplcvt.c 1.2 10/1/82 Berkeley "; 2: # 3: 4: /* 5: * aplcvt - convert APL workspace to/from VAX format 6: */ 7: 8: #include <stdio.h> 9: 10: #define PDPMAGIC 0100554 /* PDP-11 magic number */ 11: #define VAXMAGIC 0100556 /* VAX magic number */ 12: 13: #define DA 1 /* data type */ 14: #define NF 8 /* niladic function type */ 15: #define MF 9 /* monadic function type */ 16: #define DF 10 /* dyadic function type */ 17: #define MRANK 8 /* maximum rank */ 18: 19: /* 20: * The following define the internal data structures for APL 21: * on both the PDP-11 and the VAX. Two short integers are 22: * used instead of a long integer for the VAX definitions so 23: * that the program can be compiled and run on either machine 24: * without changes. (Otherwise, the reversal of long integers 25: * between the two machines would cause problems.) 26: */ 27: 28: struct pdp_thread { 29: double pt_fuzz; 30: short pt_iorg; 31: short pt_rl; 32: short pt_digits; 33: short pt_width; 34: } pthread; 35: #define PTSIZE 14 /* its real size, not the sizeof */ 36: 37: struct vax_thread { 38: double vt_fuzz; 39: short vt_iorg[2]; 40: short vt_rl[2]; 41: short vt_digits[2]; 42: short vt_width[2]; 43: } vthread; 44: 45: 46: struct pdp_item { 47: char pi_rank; 48: char pi_type; 49: short pi_size; 50: short pi_index; 51: short pi_datap; /* really a 16-bit pointer */ 52: short pi_dim[MRANK]; 53: } pitem; 54: 55: struct vax_item { 56: char vi_rank; 57: char vi_type; 58: char vi_pad[2]; 59: short vi_size[2]; 60: short vi_index[2]; 61: short vi_datap[2]; /* really a 32-bit pointer */ 62: short vi_dim[MRANK][2]; /* array of 32-bit integers */ 63: } vitem; 64: 65: union uci { 66: char cv[4]; 67: unsigned short s; 68: }; 69: 70: #define eperror(x,y) {eprintf(x); perror(y);} 71: char *base(), *strcpy(), *strcmp(); 72: 73: #ifdef vax 74: int makevax = 1; /* by default, convert to VAX format */ 75: #else 76: int makevax = 0; /* by default, convert to PDP format */ 77: #endif 78: 79: char *pname; /* holds argv[0] */ 80: char *ifname; /* points to input file name */ 81: char ofname[128]; /* contains output file name */ 82: 83: main(argc, argv) 84: char **argv; 85: { 86: register FILE *ifp, *ofp; 87: register char **ap; 88: 89: /* Parse the arguments */ 90: 91: pname = *argv; 92: ap = argv+1; 93: if (argc > 1 && *argv[1] == '-'){ 94: switch(argv[1][1]){ 95: case 'v': 96: case 'p': 97: makevax = (argv[1][1] == 'v'); 98: break; 99: default: 100: eprintf("unknown flag \"%s\"\n", argv[1]); 101: exit(1); 102: } 103: ap++; 104: } 105: 106: 107: /* If there are no filename arguments, convert standard 108: * input to standard output. However, if one of these is 109: * a tty, just exit with a syntax error message (it is highly 110: * unlikely that the user wanted input or output from/to his 111: * tty. 112: * 113: * If there are filenames, convert each one. 114: */ 115: 116: if (!*ap){ 117: if(isatty(0) || isatty(1)){ 118: fprintf(stderr, "Syntax: \"%s [-v|-p] filename ...\"\n", 119: pname); 120: exit(1); 121: } 122: ifname = "<stdin>"; 123: strcpy(ofname, "<stdout>"); 124: if (makevax ? tovax(stdin,stdout) : topdp(stdin,stdout)){ 125: eprintf("don't trust the output file!\n"); 126: exit(1); 127: } 128: } else 129: for(; *ap; ap++){ 130: ifname = *ap; 131: if ((ifp=fopen(ifname, "r")) == NULL){ 132: eperror("can't open ", ifname); 133: continue; 134: } 135: strcat(strcpy(ofname,base(ifname)), 136: makevax ? ".vax" : ".pdp"); 137: if ((ofp=fopen(ofname, "w")) == NULL){ 138: eperror("can't create ", ofname); 139: fclose(ifp); 140: continue; 141: } 142: if (makevax ? tovax(ifp,ofp) : topdp(ifp,ofp)) 143: if (unlink(ofname) < 0) 144: eperror("unlink ", ofname); 145: fclose(ifp); 146: fclose(ofp); 147: } 148: 149: exit(0); 150: } 151: 152: char * 153: base(s) 154: register char *s; 155: { 156: static char basename[128]; 157: register char *p; 158: 159: /* Strip off a trailing ".pdp" or ".vax" (depending upon the 160: * direction of conversion. 161: */ 162: 163: for(p=basename; *p = *s; p++,s++) 164: if (*s == '.' && !strcmp(s+1, makevax ? "pdp" : "vax")){ 165: *p = '\0'; 166: break; 167: } 168: 169: return(basename); 170: } 171: 172: topdp(ifp, ofp) 173: FILE *ifp, *ofp; 174: { 175: unsigned short magic; 176: short nsz; 177: union uci iz; 178: char name[128]; 179: register c; 180: register j; 181: 182: /* Look for proper magic number */ 183: 184: if (fread(&magic, sizeof magic, 1, ifp) != 1){ 185: eperror("read error on ", ifname); 186: return(-1); 187: } 188: 189: if ((magic|1) != (VAXMAGIC|1)){ 190: eprintf("%s is not a VAX APL workspace\n", ifname); 191: return(-1); 192: } 193: 194: if (fread(&magic, sizeof magic, 1, ifp) != 1){ 195: eperror("read error on ", ifname); 196: return(-1); 197: } 198: 199: if (magic){ 200: eprintf("warning: %s may be corrupted\n", ifname); 201: eprintf("attempting to continue\n"); 202: } 203: 204: magic = (magic&1) | PDPMAGIC; 205: if (fwrite(&magic, sizeof magic, 1, ofp) != 1){ 206: eperror("write error on ", ofname); 207: return(-1); 208: } 209: 210: 211: /* Convert the "thread" structure */ 212: 213: if (fread(&vthread, sizeof vthread, 1, ifp) != 1){ 214: eperror("read error on ", ifname); 215: return(-1); 216: } 217: 218: pthread.pt_fuzz = vthread.vt_fuzz; 219: pthread.pt_iorg = vthread.vt_iorg[0]; 220: pthread.pt_rl = vthread.vt_rl[0]; 221: pthread.pt_digits = vthread.vt_digits[0]; 222: pthread.pt_width = vthread.vt_width[0]; 223: 224: if (fwrite(&pthread, PTSIZE, 1, ofp) != 1){ 225: eperror("write error on ", ofname); 226: return(-1); 227: } 228: 229: 230: /* Convert each data item or function */ 231: 232: loop: 233: if ((j=fread(&iz, sizeof(long), 1, ifp)) != 1) 234: if (j <= 0) 235: return(0); 236: else { 237: eperror("read error on ", ifname); 238: return(-1); 239: } 240: if (fwrite(&iz, sizeof(short), 1, ofp) != 1){ 241: eperror("write error on ", ofname); 242: return(-1); 243: } 244: 245: if (fread(name, sizeof(char), (unsigned)iz.cv[1], ifp) != iz.cv[1]){ 246: eperror("read error on ", ifname); 247: return(-1); 248: } 249: if (fwrite(name, sizeof(char), (unsigned)iz.cv[1], ofp) != iz.cv[1]){ 250: eperror("write error on ", ofname); 251: return(-1); 252: } 253: 254: switch(iz.cv[0]){ 255: default: 256: eprintf("unknown item, type = %d\n", iz.cv[0]); 257: eprintf("conversion aborted\n"); 258: return(-1); 259: 260: case NF: 261: case MF: 262: case DF: 263: do { 264: if ((c=getc(ifp)) == EOF){ 265: eperror("getc error on ", ifname); 266: return(-1); 267: } 268: putc(c, ofp); 269: } while (c); 270: break; 271: 272: case DA: 273: if (fread(&iz, sizeof(long), 1, ifp) != 1){ 274: eperror("read error on ", ifname); 275: return(-1); 276: } 277: if (iz.cv[2] | iz.cv[3]){ 278: eprintf("item %s too large -- aborting\n", name); 279: return(-1); 280: } 281: if (fread(&vitem, sizeof vitem - MRANK*sizeof(long), 282: 1, ifp) != 1){ 283: eperror("read error on ", ifname); 284: return(-1); 285: } 286: if (fread(vitem.vi_dim, sizeof(long), vitem.vi_rank, ifp) 287: != vitem.vi_rank){ 288: eperror("read error on ", ifname); 289: return(-1); 290: } 291: pitem.pi_rank = vitem.vi_rank; 292: pitem.pi_type = vitem.vi_type; 293: pitem.pi_size = vitem.vi_size[0]; 294: for(j=0; j<vitem.vi_rank; j++) 295: pitem.pi_dim[j] = vitem.vi_dim[j][0]; 296: nsz = sizeof pitem - (MRANK-pitem.pi_rank)*sizeof(short) 297: - sizeof vitem + (MRANK-vitem.vi_rank)*sizeof(long) 298: + iz.s; 299: if (fwrite(&nsz, sizeof nsz, 1, ofp) != 1){ 300: eperror("write error on ", ofname); 301: return(-1); 302: } 303: j = sizeof pitem - (MRANK-pitem.pi_rank)*sizeof(short); 304: if (fwrite(&pitem, j, 1, ofp) != 1){ 305: eperror("write error on ", ofname); 306: return(-1); 307: } 308: j = sizeof vitem - (MRANK-vitem.vi_rank)*sizeof(long); 309: if (copy(ifp, ofp, iz.s-j)) 310: return(-1); 311: } 312: 313: goto loop; /* should be while(1) */ 314: } 315: 316: tovax(ifp, ofp) 317: FILE *ifp, *ofp; 318: { 319: unsigned short magic; 320: static short zero = 0; 321: short nsz; 322: union uci iz; 323: char name[128]; 324: register c; 325: register j; 326: 327: /* Look for proper magic number. */ 328: 329: if (fread(&magic, sizeof magic, 1, ifp) != 1){ 330: eperror("read error on ", ifname); 331: return(-1); 332: } 333: 334: if ((magic|1) != (PDPMAGIC|1)){ 335: eprintf("%s is not a PDP-11 APL workspace\n", ifname); 336: return(-1); 337: } 338: 339: magic = (magic&1) | VAXMAGIC; 340: if (fwrite(&magic, sizeof magic, 1, ofp) != 1 341: || fwrite(&zero, sizeof zero, 1, ofp) != 1){ 342: eperror("write error on ", ofname); 343: return(-1); 344: } 345: 346: 347: /* Convert the "thread" structure. */ 348: 349: if (fread(&pthread, PTSIZE, 1, ifp) != 1){ 350: eperror("read error on ", ifname); 351: return(-1); 352: } 353: 354: vthread.vt_fuzz = pthread.pt_fuzz; 355: vthread.vt_iorg[0] = pthread.pt_iorg; 356: vthread.vt_iorg[1] = 0; 357: vthread.vt_rl[0] = pthread.pt_rl; 358: vthread.vt_rl[1] = 0; 359: vthread.vt_digits[0] = pthread.pt_digits; 360: vthread.vt_digits[1] = 0; 361: vthread.vt_width[0] = pthread.pt_width; 362: vthread.vt_width[1] = 0; 363: 364: if (fwrite(&vthread, sizeof vthread, 1, ofp) != 1){ 365: eperror("write error on ", ofname); 366: return(-1); 367: } 368: 369: 370: /* Convert each data item or function. */ 371: 372: loop: 373: if ((j=fread(&iz, sizeof(short), 1, ifp)) != 1) 374: if (j <= 0) 375: return(0); 376: else { 377: eperror("read error on ", ifname); 378: return(-1); 379: } 380: iz.cv[2] = iz.cv[3] = 0; 381: if (fwrite(&iz, sizeof(long), 1, ofp) != 1){ 382: eperror("write error on ", ofname); 383: return(-1); 384: } 385: 386: if (fread(name, sizeof(char), (unsigned)iz.cv[1], ifp) != iz.cv[1]){ 387: eperror("read error on ", ifname); 388: return(-1); 389: } 390: if (fwrite(name, sizeof(char), (unsigned)iz.cv[1], ofp) != iz.cv[1]){ 391: eperror("write error on ", ofname); 392: return(-1); 393: } 394: 395: switch(iz.cv[0]){ 396: default: 397: eprintf("unknown item, type = %d\n", iz.cv[0]); 398: eprintf("conversion aborted\n"); 399: return(-1); 400: 401: case NF: 402: case MF: 403: case DF: 404: do { 405: if ((c=getc(ifp)) == EOF){ 406: eperror("getc error on ", ifname); 407: return(-1); 408: } 409: putc(c, ofp); 410: } while (c); 411: break; 412: 413: case DA: 414: if (fread(&iz, sizeof(short), 1, ifp) != 1){ 415: eperror("read error on ", ifname); 416: return(-1); 417: } 418: if (fread(&pitem, sizeof pitem - MRANK*sizeof(short), 419: 1, ifp) != 1){ 420: eperror("read error on ", ifname); 421: return(-1); 422: } 423: if (fread(pitem.pi_dim, sizeof(short), pitem.pi_rank, ifp) 424: != pitem.pi_rank){ 425: eperror("read error on ", ifname); 426: return(-1); 427: } 428: vitem.vi_rank = pitem.pi_rank; 429: vitem.vi_type = pitem.pi_type; 430: vitem.vi_size[0] = pitem.pi_size; 431: vitem.vi_size[1] = 0; 432: for(j=0; j<pitem.pi_rank; j++){ 433: vitem.vi_dim[j][0] = pitem.pi_dim[j]; 434: vitem.vi_dim[j][1] = 0; 435: } 436: nsz = sizeof vitem - (MRANK-vitem.vi_rank)*sizeof(long) 437: - sizeof pitem + (MRANK-pitem.pi_rank)*sizeof(short) 438: + iz.s; 439: if (fwrite(&nsz, sizeof nsz, 1, ofp) != 1 440: || fwrite(&zero, sizeof zero, 1, ofp) != 1){ 441: perror("write error on ", ofname); 442: return(-1); 443: } 444: j = sizeof vitem - (MRANK-vitem.vi_rank)*sizeof(long); 445: if (fwrite(&vitem, j, 1, ofp) != 1){ 446: eperror("write error on ", ofname); 447: return(-1); 448: } 449: j = sizeof pitem - (MRANK-pitem.pi_rank)*sizeof(short); 450: if (copy(ifp, ofp, iz.s-j)) 451: return(-1); 452: } 453: 454: goto loop; /* should be while(1) */ 455: } 456: 457: copy(ifp, ofp, len) 458: FILE *ifp, *ofp; 459: register len; 460: { 461: register c; 462: 463: while(len--){ 464: if ((c=getc(ifp)) == EOF){ 465: eperror("getc error on ", ifname); 466: return(-1); 467: } 468: putc(c, ofp); 469: } 470: return(0); 471: } 472: 473: /*VARARGS 1*/ 474: eprintf(a, b, c, d, e, f, g, h, i, j){ 475: 476: fprintf(stderr, "%s: ", pname); 477: fprintf(stderr, a, b, c, d, e, f, g, h, i, j); 478: }