/* * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * See the copyright notice in the ACK home directory, in the file "Copyright". * */ #include "ass00.h" #include "assex.h" #include "assrl.h" #include #include #include #include "system.h" /* * this file contains several library routines. */ static char filename[L_tmpnam]; /* VARARGS1 */ static void pr_error(const char* string1, va_list ap) { /* * diagnostic output */ fprintf(stderr,"%s: ",progname); if (curfile) { fprintf(stderr,"file %s",curfile); if (archmode) fprintf(stderr," (%.14s)",archhdr.ar_name); fprintf(stderr,": "); } if ( pstate.s_curpro ) { fprintf(stderr,"proc %s, ",pstate.s_curpro->p_name); } fprintf(stderr,"line %d: ",line_num); vfprintf(stderr,string1,ap); fprintf(stderr,"\n"); } /* VARARGS1 */ void error(const char* string1, ...) { va_list ap; va_start(ap, string1); pr_error(string1, ap); va_end(ap); nerrors++ ; } /* VARARGS1 */ void werror(const char* string1, ...) { va_list ap; if ( wflag ) return ; va_start(ap, string1); pr_error(string1, ap); va_end(ap); } void fatal(char *s) { /* * handle fatal errors */ error("Fatal error: %s",s); dump(0); exit(EXIT_FAILURE); } int xgetc(register FILE *af) { register int nextc; nextc=fgetc(af) ; if ( feof(af) ) fatal("unexpected end of file"); return nextc ; } void xputc(int c,register FILE *af) { fputc(c,af) ; if ( ferror(af) ) fatal("write error") ; } void putblk(register FILE *stream,register char *from, register int amount) { for ( ; amount-- ; from++ ) { fputc(*from,stream) ; if ( ferror(stream) ) fatal("write error") ; } } int getblk(register FILE *stream, register char *from, register int amount) { for ( ; amount-- ; from++ ) { *from = fgetc(stream) ; if ( feof(stream) ) return 1 ; } return 0 ; } void xput16(int w,FILE *f) { /* * two times xputc */ xputc(w,f); xputc(w>>8,f); } void xputarb(int l,cons_t w, FILE* f) { while ( l-- ) { xputc( int_cast w,f) ; w >>=8 ; } } void put8(int n) { xputc(n,tfile); textoff++; } void put16(int n) { /* * note reversed order of bytes. * this is done for faster interpretation. */ xputc(n>>8,tfile); xputc(n&0377,tfile); textoff += 2; } void put32(cons_t n) { put16( int_cast (n>>16)) ; put16( int_cast n) ; } void put64(cons_t n) { fatal("put64 called") ; } int xget8(void) { /* * Read one byte from ifile. */ if (libeof && inpoff >= libeof) return EOF ; inpoff++; return fgetc(ifile) ; } unsigned int get8(void) { register int nextc; /* * Read one byte from ifile. */ nextc=xget8(); if ( nextc==EOF ) { if (libeof) fatal("Tried to read past end of arentry\n"); else fatal("end of file on input"); } return nextc ; } cons_t xgetarb(int l,FILE *f) { cons_t val ; register int shift ; int c; shift=0 ; val=0 ; while ( l-- ) { /* val += ((cons_t)(c = ctrunc(xgetc(f))))< 8 && ((shift>>3)&1)) { while (shift < 8*sizeof(cons_t)) { val += ((cons_t)c)<>= 8 ; } } void extarb(int size, long value) { /* Assemble the 'size' constant value. * The bytes are again written low to high. */ register int i ; for ( i=size ; i-- ; ) { ext8( int_cast value ) ; value >>=8 ; } } void extadr(cons_t a) { /* Assemble the pointer constant a. * NOTE: The bytes are written low to high. */ register int i ; for ( i=ptrsize ; i-- ; ) { ext8( int_cast a) ; a >>= 8 ; } } void xputa(cons_t a,FILE* f) { register int i ; for ( i=ptrsize ; i-- ; ) { xputc( int_cast a,f) ; a >>= 8 ; } } cons_t xgeta(FILE* f) { register int i, shift ; cons_t val ; val = 0 ; shift=0 ; for ( i=ptrsize ; i-- ; ) { val += ((cons_t)xgetc(f))<MAXBYTE) fatal("Descriptor overflow"); return amount ; } void set_mode(int mode) { if (datamode==mode) { /* in right mode already */ switch ( datamode ) { case DATA_CONST: if ( (dataoff-lastoff)/wordsize < MAXBYTE ) return ; break ; case DATA_BYTES: if ( dataoff-lastoff < MAXBYTE ) return ; break ; case DATA_IPTR: case DATA_DPTR: if ( (dataoff-lastoff)/ptrsize < MAXBYTE ) return ; break ; case DATA_ICON: case DATA_FCON: case DATA_UCON: case DATA_BSS: break ; default: return ; } set_mode(DATA_NUL) ; /* flush current descriptor */ set_mode(mode) ; return; } switch(datamode) { /* terminate current mode */ case DATA_NUL: break; /* nothing to terminate */ case DATA_CONST: lastheader->r_val.rel_i=icount(wordsize) ; lastheader->r_typ = RELHEAD; datablocks++; break; case DATA_BYTES: lastheader->r_val.rel_i=icount(1) ; lastheader->r_typ = RELHEAD; datablocks++; break; case DATA_DPTR: case DATA_IPTR: lastheader->r_val.rel_i=icount(ptrsize) ; lastheader->r_typ = RELHEAD; datablocks++; break; default: datablocks++; break; } datamode=mode; switch(datamode) { case DATA_NUL: break; case DATA_CONST: ext8(HEADCONST); lastheader=data_reloc( chp_cast 0,dataoff,RELNULL); ext8(0); lastoff=dataoff; break; case DATA_BYTES: ext8(HEADBYTE); lastheader=data_reloc( chp_cast 0,dataoff,RELNULL); ext8(0); lastoff=dataoff; break; case DATA_IPTR: ext8(HEADIPTR); lastheader=data_reloc( chp_cast 0,dataoff,RELNULL); ext8(0); lastoff=dataoff; break; case DATA_DPTR: ext8(HEADDPTR); lastheader=data_reloc( chp_cast 0,dataoff,RELNULL); ext8(0); lastoff=dataoff; break; case DATA_ICON: ext8(HEADICON) ; ext8( int_cast consiz) ; break; case DATA_FCON: ext8(HEADFCON) ; ext8( int_cast consiz) ; break; case DATA_UCON: ext8(HEADUCON) ; ext8( int_cast consiz) ; break; case DATA_REP: ext8(HEADREP) ; break ; case DATA_BSS: ext8(HEADBSS) ; break; default: fatal("Unknown mode in set_mode") ; } } char* tmpfil(void) { if (sys_tmpnam(filename)==NULL) { fatal("Cannot create temporary filename."); } return filename; }