home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug103.arc / GETREL.C < prev    next >
Text File  |  1979-12-31  |  4KB  |  121 lines

  1. /*
  2. ** getrel -- read a relocatable-object file
  3. */
  4. #include <stdio.h>
  5. #include "rel.h"
  6. #include "mac.h"
  7.  
  8. /*
  9. ** get next REL item
  10. ** return item code on success, ERR on error
  11. ** on successful return:
  12. **    item = item code
  13. **    type = type of field
  14. **   field = value of field
  15. **  symbol = symbol name
  16. */ 
  17. getrel() {
  18.   if(!getbits(1)) return (ERR);        /* get 1 bit */
  19.   if(field == 0) {            /* absolute item */
  20.     if(!getbits(8)) return (ERR);    /* get next 8 bits */
  21.     return (type = item = ABS);        /* absolute item */
  22.     }
  23.   if(!getbits(2)) return (ERR);        /* get next 2 bits */
  24.   switch(type = item = field) {
  25.     case 0: return (getspec());        /* special link item */
  26.     case 1:                /* program relative item */
  27.     case 2:                /* data relative item */
  28.     case 3:                /* common relative item */
  29.     }
  30.   if(getfld() == ERR) return (ERR);    /* get next 16 bits */
  31.   return (item);            /* relative items */
  32.   }
  33.  
  34. getspec() {                /* get next special item */
  35.   if(!getbits(4)) return (ERR);        /* get next 4 bits */
  36.   type = ABS;                /* default type */
  37.   item = field + 4;
  38.   switch(field) {
  39.     case  0:                /* entry symbol */
  40.     case  1:                /* select common block */
  41.     case  2:                /* program name */
  42.     case  3:                /* request library search */
  43.     case  4:                /* extension link items */
  44.       if(getsym() == ERR) return (ERR);
  45.       break;
  46.     case  5:                /* define common size */
  47.     case  6:                /* head of external reference chain */
  48.     case  7:                /* define entry point */
  49.       if(gettyp() == ERR || getfld() == ERR || getsym() == ERR) return (ERR);
  50.       break;
  51.     case  8:                /* external - offset */
  52.     case  9:                /* external + offset */
  53.     case 10:                /* size of data area */
  54.     case 11:                /* set loading location counter */
  55.     case 12:                /* chain addr (fill chain with lc) */
  56.     case 13:                /* size of program */
  57.       if(gettyp() == ERR || getfld() == ERR) return (ERR);
  58.       break;
  59.     case 14:                /* end of program */
  60.       if(gettyp() == ERR || getfld() == ERR) return (ERR);
  61.       inrem = 0;            /* force byte boundary */
  62.       break;
  63.     case 15:                /* end of file */
  64.       inrem = 0;            /* force byte boundary */
  65.     }
  66.   return (item);
  67.   }
  68.  
  69. gettyp() {
  70.   if(!getbits(2)) return (ERR);        /* get 2-bit field type */
  71.   return (type = field);
  72.   }
  73.  
  74. getfld() {                /* get type and value of field */
  75.   int low;
  76.   if(!getbits(8)) return (ERR);        /* get first 8 bits */
  77.   low = field;                /* save as low order byte */
  78.   if(!getbits(8)) return (ERR);        /* get next 8 bits */
  79.   field = (field << 8) | low;        /* combine high & low bytes */
  80.   return (item);
  81.   }
  82.  
  83. getsym() {                /* get symbol */
  84.   int i, save; char *cp;
  85.   cp = symbol;
  86.   save = field;                /* save field */
  87.   if(!getbits(3)) return (ERR);        /* get 3-bit symbol length */
  88.   i = field;                /* capture symbol length */
  89.   while(i--) {
  90.     if(!getbits(8)) return (ERR);    /* get next byte */
  91.     *cp++ = field;
  92.     }
  93.   *cp = NULL;                /* terminate symbol */
  94.   field = save;                /* restore field */
  95.   return (item);
  96.   }
  97.  
  98. /*
  99. ** get next n bits from REL file into "field"
  100. ** return true on success, false on error
  101. */
  102. getbits(n) int n; {
  103.   int get;
  104.   field = 0;                    /* initialize result */
  105.   while(n) {                    /* more bits to fetch */
  106.     if(inrem == 0) {                /* need another chunk */
  107.       if(read(inrel, &inchunk, 1) != 1) {    /* get next bit cluster */
  108.         fputs("\n\7- Abnormal End of REL File\n", stdout);
  109.         return (NO);                /* failure */
  110.         }
  111.       inrem = 8;                /* 8 bits remain */
  112.       }
  113.     if(n > inrem) get = inrem; else get = n;    /* how many from this chunk */
  114.     n     -= get;                /* decrement bits needed */
  115.     inrem   -= get;                /* decr remaining bits */
  116.     field  = (field  << get) +
  117.              ((inchunk >> inrem) & ~(ONES << get));
  118.     }
  119.   return (YES);                    /* success */
  120.   }
  121.