home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / smalltk / src / unixio.c < prev    next >
C/C++ Source or Header  |  1991-10-12  |  5KB  |  201 lines

  1. /*
  2.     Little Smalltalk, version 2
  3.  
  4.     Unix specific input and output routines
  5.     written by tim budd, January 1988
  6. */
  7. # include <stdio.h>
  8. # include "env.h"
  9. # include "memory.h"
  10. # include "names.h"
  11.  
  12. struct {
  13.     int di;
  14.     object cl;
  15.     short ds;
  16.     } dummyObject;
  17.  
  18. /*
  19.     imageRead - read in an object image
  20.         we toss out the free lists built initially,
  21.         reconstruct the linkages, then rebuild the free
  22.         lists around the new objects.
  23.         The only objects with nonzero reference counts
  24.         will be those reachable from either symbols
  25. */
  26. static int fr(fp, p, s)
  27. FILE *fp;
  28. char *p;
  29. int s;
  30. {    int r;
  31.  
  32.     r = fread(p, s, 1, fp);
  33.     if (r && (r != 1))
  34.         sysError("imageRead count error","");
  35.     return r;
  36. }
  37.  
  38. noreturn imageRead(fp)
  39. FILE *fp;
  40. {    short i, size;
  41.     object *mBlockAlloc();
  42.  
  43.     ignore fr(fp, (char *) &symbols, sizeof(object));
  44.     i = 0;
  45.  
  46.     while(fr(fp, (char *) &dummyObject, sizeof(dummyObject))) {
  47.         i = dummyObject.di;
  48.         
  49.         if ((i < 0) || (i > ObjectTableMax))
  50.             sysError("reading index out of range","");
  51.         objectTable[i].class = dummyObject.cl;
  52.         if ((objectTable[i].class < 0) || 
  53.             ((objectTable[i].class>>1) > ObjectTableMax)) {
  54.             fprintf(stderr,"index %d\n", dummyObject.cl);
  55.             sysError("class out of range","imageRead");
  56.             }
  57.         objectTable[i].size = size = dummyObject.ds;
  58.         if (size < 0) size = ((- size) + 1) / 2;
  59.         if (size != 0) {
  60.             objectTable[i].memory = mBlockAlloc((int) size);
  61.             ignore fr(fp, (char *) objectTable[i].memory,
  62.                 sizeof(object) * (int) size);
  63.                 }
  64.         else
  65.             objectTable[i].memory = (object *) 0;
  66.         }
  67.  
  68.     /* now restore ref counts, getting rid of unneeded junk */
  69.     visit(symbols);
  70.     /* toss out the old free lists, build new ones */
  71.     setFreeLists();
  72.     
  73. }
  74.  
  75. /*
  76.     imageWrite - write out an object image
  77. */
  78.  
  79. static fw(fp, p, s)
  80. FILE *fp;
  81. char *p;
  82. int  s;
  83. {
  84.     if (fwrite(p, s, 1, fp) != 1) {
  85.         sysError("imageWrite size error","");
  86.         }
  87. }
  88.  
  89. noreturn imageWrite(fp)
  90. FILE *fp;
  91. {    short i, size;
  92.  
  93.     fw(fp, (char *) &symbols, sizeof(object));
  94.  
  95.     for (i = 0; i < ObjectTableMax; i++) {
  96.         if (objectTable[i].referenceCount > 0) {
  97.             dummyObject.di = i;
  98.             dummyObject.cl = objectTable[i].class;
  99.             dummyObject.ds = size = objectTable[i].size;
  100.             fw(fp, (char *) &dummyObject, sizeof(dummyObject));
  101.             if (size < 0) size = ((- size) + 1) / 2;
  102.             if (size != 0)
  103.                 fw(fp, (char *) objectTable[i].memory,
  104.                     sizeof(object) * size);
  105.             }
  106.         }
  107. }
  108.  
  109. /* i/o primitives - necessarily rather UNIX dependent;
  110.     basically, files are all kept in a large array.
  111.     File operations then just give an index into this array 
  112. */
  113. # define MAXFILES 20
  114. /* we assume this is initialized to NULL */
  115. static FILE *fp[MAXFILES];
  116.  
  117. object ioPrimitive(number, arguments)
  118. int number;
  119. object *arguments;
  120. {    int i, j;
  121.     char *p, buffer[1024];
  122.     object returnedObject;
  123.  
  124.     returnedObject = nilobj;
  125.  
  126.     i = intValue(arguments[0]);
  127.  
  128.     switch(number) {
  129.         case 0:        /* file open */
  130.             i = intValue(arguments[0]);
  131.             p = charPtr(arguments[1]);
  132.             if (streq(p, "stdin")) 
  133.                 fp[i] = stdin;
  134.             else if (streq(p, "stdout"))
  135.                 fp[i] = stdout;
  136.             else if (streq(p, "stderr"))
  137.                 fp[i] = stderr;
  138.             else {
  139.                 fp[i] = fopen(p, charPtr(arguments[2]));
  140.                 }
  141.             if (fp[i] == NULL)
  142.                 returnedObject = nilobj;
  143.             else
  144.                 returnedObject = newInteger(i);
  145.             break;
  146.  
  147.         case 1:        /* file close - recover slot */
  148.             if (fp[i]) ignore fclose(fp[i]);
  149.             fp[i] = NULL;
  150.             break;
  151.  
  152.         case 2:        /* file size */
  153.         case 3:        /* file in */
  154.             if (fp[i]) fileIn(fp[i], true);
  155.             break;
  156.  
  157.         case 4:        /* get character */
  158.             sysError("file operation not implemented yet","");
  159.  
  160.         case 5:        /* get string */
  161.             if (! fp[i]) break;
  162.             j = 0; buffer[j] = '\0';
  163.             while (1) {
  164.                if (fgets(&buffer[j], 512, fp[i]) == NULL)
  165.                   return(nilobj); /* end of file */
  166.                if (fp[i] == stdin) {
  167.                 /* delete the newline */
  168.                 j = strlen(buffer);
  169.                 if (buffer[j-1] == '\n')
  170.                     buffer[j-1] = '\0';
  171.                 }
  172.                j = strlen(buffer)-1;
  173.                if (buffer[j] != '\\')
  174.                   break;
  175.                /* else we loop again */
  176.             }
  177.             returnedObject = newStString(buffer);
  178.             break;
  179.  
  180.         case 7:        /* write an object image */
  181.             if (fp[i]) imageWrite(fp[i]);
  182.             returnedObject = trueobj;
  183.             break;
  184.  
  185.         case 8:        /* print no return */
  186.         case 9:        /* print string */
  187.             if (! fp[i]) break; 
  188.             ignore fputs(charPtr(arguments[1]), fp[i]);
  189.             if (number == 8)
  190.                 ignore fflush(fp[i]);
  191.             else
  192.                 ignore fputc('\n', fp[i]);
  193.             break;
  194.  
  195.         default:
  196.             sysError("unknown primitive","filePrimitive");
  197.         }
  198.  
  199.     return(returnedObject);
  200. }
  201.