ack/util/ass/ass80.c

393 lines
6.5 KiB
C
Raw Normal View History

1984-07-02 15:35:56 +00:00
/*
1987-03-10 01:26:51 +00:00
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
1984-07-02 15:35:56 +00:00
*
*/
#include "ass00.h"
#include "assex.h"
2019-03-17 14:41:25 +00:00
#include "assrl.h"
#include <stddef.h>
#include <stdio.h>
#include <stdarg.h>
2019-03-17 14:41:25 +00:00
#include "system.h"
1984-07-02 15:35:56 +00:00
1984-11-08 12:08:31 +00:00
1984-07-02 15:35:56 +00:00
/*
* this file contains several library routines.
*/
2019-03-17 14:41:25 +00:00
static char filename[L_tmpnam];
1984-07-02 15:35:56 +00:00
/* VARARGS1 */
static void pr_error(const char* string1, va_list ap) {
1984-07-02 15:35:56 +00:00
/*
* 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);
1984-07-02 15:35:56 +00:00
fprintf(stderr,"\n");
}
/* VARARGS1 */
void error(const char* string1, ...)
{
va_list ap;
va_start(ap, string1);
pr_error(string1, ap);
va_end(ap);
1984-07-02 15:35:56 +00:00
nerrors++ ;
}
/* VARARGS1 */
2019-03-17 14:41:25 +00:00
void werror(const char* string1, ...)
{
va_list ap;
1984-07-02 15:35:56 +00:00
if ( wflag ) return ;
va_start(ap, string1);
pr_error(string1, ap);
va_end(ap);
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
void fatal(char *s)
{
1984-07-02 15:35:56 +00:00
/*
* handle fatal errors
*/
error("Fatal error: %s",s);
dump(0);
2019-03-17 14:41:25 +00:00
exit(EXIT_FAILURE);
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
int xgetc(register FILE *af)
{
1984-07-02 15:35:56 +00:00
register int nextc;
nextc=fgetc(af) ;
if ( feof(af) )
fatal("unexpected end of file");
return nextc ;
}
2019-03-17 14:41:25 +00:00
void xputc(int c,register FILE *af)
{
1984-07-02 15:35:56 +00:00
fputc(c,af) ;
if ( ferror(af) ) fatal("write error") ;
}
2019-03-17 14:41:25 +00:00
void putblk(register FILE *stream,register char *from, register int amount)
{
1984-07-02 15:35:56 +00:00
for ( ; amount-- ; from++ ) {
fputc(*from,stream) ;
if ( ferror(stream) ) fatal("write error") ;
}
}
2019-03-17 14:41:25 +00:00
int getblk(register FILE *stream, register char *from, register int amount)
{
1984-07-02 15:35:56 +00:00
for ( ; amount-- ; from++ ) {
*from = fgetc(stream) ;
if ( feof(stream) ) return 1 ;
}
return 0 ;
}
2019-03-17 14:41:25 +00:00
void xput16(int w,FILE *f)
{
1984-07-02 15:35:56 +00:00
/*
* two times xputc
*/
xputc(w,f);
xputc(w>>8,f);
}
2019-03-17 14:41:25 +00:00
void xputarb(int l,cons_t w, FILE* f)
{
1984-07-02 15:35:56 +00:00
while ( l-- ) {
xputc( int_cast w,f) ;
w >>=8 ;
}
}
2019-03-17 14:41:25 +00:00
void put8(int n)
{
1984-07-02 15:35:56 +00:00
xputc(n,tfile);
textoff++;
}
2019-03-17 14:41:25 +00:00
void put16(int n)
{
1984-07-02 15:35:56 +00:00
/*
* note reversed order of bytes.
* this is done for faster interpretation.
*/
xputc(n>>8,tfile);
xputc(n&0377,tfile);
textoff += 2;
}
2019-03-17 14:41:25 +00:00
void put32(cons_t n)
{
1984-07-02 15:35:56 +00:00
put16( int_cast (n>>16)) ;
put16( int_cast n) ;
}
2019-03-17 14:41:25 +00:00
void put64(cons_t n)
{
1984-07-02 15:35:56 +00:00
fatal("put64 called") ;
}
2019-03-17 14:41:25 +00:00
int xget8(void)
{
1984-07-02 15:35:56 +00:00
/*
* Read one byte from ifile.
*/
if (libeof && inpoff >= libeof)
return EOF ;
inpoff++;
return fgetc(ifile) ;
}
2019-03-17 14:41:25 +00:00
unsigned int get8(void)
{
1984-07-02 15:35:56 +00:00
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 ;
}
2019-03-17 14:41:25 +00:00
cons_t xgetarb(int l,FILE *f)
{
1984-07-02 15:35:56 +00:00
cons_t val ;
register int shift ;
1991-03-20 16:24:50 +00:00
int c;
1984-07-02 15:35:56 +00:00
shift=0 ; val=0 ;
while ( l-- ) {
2019-03-17 14:41:25 +00:00
/* val += ((cons_t)(c = ctrunc(xgetc(f))))<<shift ;
Bug here: shifts with too large shift counts
get unspecified results. --Ceriel */
c = ctrunc(xgetc(f));
if (shift < 8 * sizeof(cons_t)) {
val += ((cons_t)c)<<shift ;
}
1984-07-02 15:35:56 +00:00
shift += 8 ;
}
1991-03-20 16:24:50 +00:00
if (c == 0377 && shift > 8 && ((shift>>3)&1)) {
while (shift < 8*sizeof(cons_t)) {
val += ((cons_t)c)<<shift ;
shift += 8;
}
}
1984-07-02 15:35:56 +00:00
return val ;
}
2019-03-17 14:41:25 +00:00
void ext8(int b)
{
1984-07-02 15:35:56 +00:00
/*
* Handle one byte of data.
*/
++dataoff;
xputc(b,dfile);
}
2019-03-17 14:41:25 +00:00
void extword(cons_t w)
{
1984-07-02 15:35:56 +00:00
/* Assemble the word constant w.
* NOTE: The bytes are written low to high.
*/
2019-03-17 14:41:25 +00:00
register int i ;
1984-07-02 15:35:56 +00:00
for ( i=wordsize ; i-- ; ) {
ext8( int_cast w) ;
w >>= 8 ;
}
}
2019-03-17 14:41:25 +00:00
void extarb(int size, long value)
{
1984-07-02 15:35:56 +00:00
/* Assemble the 'size' constant value.
* The bytes are again written low to high.
*/
2019-03-17 14:41:25 +00:00
register int i ;
1984-07-02 15:35:56 +00:00
for ( i=size ; i-- ; ) {
ext8( int_cast value ) ;
value >>=8 ;
}
}
2019-03-17 14:41:25 +00:00
void extadr(cons_t a)
{
/* Assemble the pointer constant a.
1984-07-02 15:35:56 +00:00
* NOTE: The bytes are written low to high.
*/
2019-03-17 14:41:25 +00:00
register int i ;
1984-07-02 15:35:56 +00:00
for ( i=ptrsize ; i-- ; ) {
ext8( int_cast a) ;
a >>= 8 ;
}
}
2019-03-17 14:41:25 +00:00
void xputa(cons_t a,FILE* f)
{
register int i ;
1984-07-02 15:35:56 +00:00
for ( i=ptrsize ; i-- ; ) {
xputc( int_cast a,f) ;
a >>= 8 ;
}
}
2019-03-17 14:41:25 +00:00
cons_t xgeta(FILE* f)
{
register int i, shift ;
1984-07-02 15:35:56 +00:00
cons_t val ;
val = 0 ; shift=0 ;
for ( i=ptrsize ; i-- ; ) {
val += ((cons_t)xgetc(f))<<shift ;
shift += 8 ;
}
return val ;
}
2019-03-17 14:41:25 +00:00
int icount(int size)
{
1984-07-02 15:35:56 +00:00
int amount ;
amount=(dataoff-lastoff)/size ;
if ( amount>MAXBYTE) fatal("Descriptor overflow");
return amount ;
}
2019-03-17 14:41:25 +00:00
void set_mode(int mode)
{
1984-07-02 15:35:56 +00:00
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:
1984-07-02 15:35:56 +00:00
break ;
default:
return ;
}
set_mode(DATA_NUL) ; /* flush current descriptor */
set_mode(mode) ;
1984-07-02 15:35:56 +00:00
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;
1984-07-02 15:35:56 +00:00
default:
fatal("Unknown mode in set_mode") ;
1984-07-02 15:35:56 +00:00
}
}
2019-03-17 14:41:25 +00:00
char* tmpfil(void)
{
if (sys_tmpnam(filename)==NULL)
{
fatal("Cannot create temporary filename.");
1984-07-02 15:35:56 +00:00
}
2019-03-17 14:41:25 +00:00
return filename;
1984-07-02 15:35:56 +00:00
}