ass80.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. */
  6. #include "ass00.h"
  7. #include "assex.h"
  8. #include <em_path.h>
  9. #ifndef NORCSID
  10. static char rcs_id[] = "$Id$" ;
  11. #endif
  12. /*
  13. * this file contains several library routines.
  14. */
  15. zero(area,length) char *area; unsigned length ; {
  16. register char *p;
  17. register n;
  18. /*
  19. * Clear area of length bytes.
  20. */
  21. if ((n=length)==0)
  22. return;
  23. p = area;
  24. do *p++=0; while (--n);
  25. }
  26. /* VARARGS1 */
  27. static void pr_error(string1,a1,a2,a3,a4) char *string1 ; {
  28. /*
  29. * diagnostic output
  30. */
  31. fprintf(stderr,"%s: ",progname);
  32. if (curfile) {
  33. fprintf(stderr,"file %s",curfile);
  34. if (archmode)
  35. fprintf(stderr," (%.14s)",archhdr.ar_name);
  36. fprintf(stderr,": ");
  37. }
  38. if ( pstate.s_curpro ) {
  39. fprintf(stderr,"proc %s, ",pstate.s_curpro->p_name);
  40. }
  41. fprintf(stderr,"line %d: ",line_num);
  42. fprintf(stderr,string1,a1,a2,a3,a4);
  43. fprintf(stderr,"\n");
  44. }
  45. /* VARARGS1 */
  46. void error(string1,a1,a2,a3,a4) char *string1 ; {
  47. pr_error(string1,a1,a2,a3,a4) ;
  48. nerrors++ ;
  49. }
  50. /* VARARGS1 */
  51. void werror(string1,a1,a2,a3,a4) char *string1 ; {
  52. if ( wflag ) return ;
  53. pr_error(string1,a1,a2,a3,a4) ;
  54. }
  55. fatal(s) char *s; {
  56. /*
  57. * handle fatal errors
  58. */
  59. error("Fatal error: %s",s);
  60. dump(0);
  61. exit(-1);
  62. }
  63. #ifndef CPM
  64. FILE *frewind(f) FILE *f ; {
  65. /* Rewind a file open for writing and open it for reading */
  66. /* Assumption, file descriptor is r/w */
  67. register FILE *tmp ;
  68. tmp=fdopen(dup(fileno(f)),"r");
  69. fclose(f);
  70. rewind(tmp);
  71. return tmp ;
  72. }
  73. #endif
  74. int xgetc(af) register FILE *af; {
  75. register int nextc;
  76. /*
  77. * read next character; fatal if there isn't one
  78. */
  79. nextc=fgetc(af) ;
  80. if ( feof(af) )
  81. fatal("unexpected end of file");
  82. return nextc ;
  83. }
  84. xputc(c,af) register FILE *af; {
  85. /* output one character and scream if it gives an error */
  86. fputc(c,af) ;
  87. if ( ferror(af) ) fatal("write error") ;
  88. }
  89. putblk(stream,from,amount)
  90. register FILE *stream; register char *from ; register int amount ; {
  91. for ( ; amount-- ; from++ ) {
  92. fputc(*from,stream) ;
  93. if ( ferror(stream) ) fatal("write error") ;
  94. }
  95. }
  96. int getblk(stream,from,amount)
  97. register FILE *stream; register char *from ; register int amount ; {
  98. for ( ; amount-- ; from++ ) {
  99. *from = fgetc(stream) ;
  100. if ( feof(stream) ) return 1 ;
  101. }
  102. return 0 ;
  103. }
  104. xput16(w,f) FILE *f; {
  105. /*
  106. * two times xputc
  107. */
  108. xputc(w,f);
  109. xputc(w>>8,f);
  110. }
  111. xputarb(l,w,f) int l ; cons_t w ; FILE *f ; {
  112. while ( l-- ) {
  113. xputc( int_cast w,f) ;
  114. w >>=8 ;
  115. }
  116. }
  117. put8(n) {
  118. xputc(n,tfile);
  119. textoff++;
  120. }
  121. put16(n) {
  122. /*
  123. * note reversed order of bytes.
  124. * this is done for faster interpretation.
  125. */
  126. xputc(n>>8,tfile);
  127. xputc(n&0377,tfile);
  128. textoff += 2;
  129. }
  130. put32(n) cons_t n ; {
  131. put16( int_cast (n>>16)) ;
  132. put16( int_cast n) ;
  133. }
  134. put64(n) cons_t n ; {
  135. fatal("put64 called") ;
  136. }
  137. int xget8() {
  138. /*
  139. * Read one byte from ifile.
  140. */
  141. if (libeof && inpoff >= libeof)
  142. return EOF ;
  143. inpoff++;
  144. return fgetc(ifile) ;
  145. }
  146. unsigned get8() {
  147. register int nextc;
  148. /*
  149. * Read one byte from ifile.
  150. */
  151. nextc=xget8();
  152. if ( nextc==EOF ) {
  153. if (libeof)
  154. fatal("Tried to read past end of arentry\n");
  155. else
  156. fatal("end of file on input");
  157. }
  158. return nextc ;
  159. }
  160. cons_t xgetarb(l,f) int l; FILE *f ; {
  161. cons_t val ;
  162. register int shift ;
  163. int c;
  164. shift=0 ; val=0 ;
  165. while ( l-- ) {
  166. // val += ((cons_t)(c = ctrunc(xgetc(f))))<<shift ;
  167. // Bug here: shifts with too large shift counts
  168. // get unspecified results. --Ceriel
  169. c = ctrunc(xgetc(f));
  170. if (shift < 8 * sizeof(cons_t)) {
  171. val += ((cons_t)c)<<shift ;
  172. }
  173. shift += 8 ;
  174. }
  175. if (c == 0377 && shift > 8 && ((shift>>3)&1)) {
  176. while (shift < 8*sizeof(cons_t)) {
  177. val += ((cons_t)c)<<shift ;
  178. shift += 8;
  179. }
  180. }
  181. return val ;
  182. }
  183. ext8(b) {
  184. /*
  185. * Handle one byte of data.
  186. */
  187. ++dataoff;
  188. xputc(b,dfile);
  189. }
  190. extword(w) cons_t w ; {
  191. /* Assemble the word constant w.
  192. * NOTE: The bytes are written low to high.
  193. */
  194. register i ;
  195. for ( i=wordsize ; i-- ; ) {
  196. ext8( int_cast w) ;
  197. w >>= 8 ;
  198. }
  199. }
  200. extarb(size,value) int size ; long value ; {
  201. /* Assemble the 'size' constant value.
  202. * The bytes are again written low to high.
  203. */
  204. register i ;
  205. for ( i=size ; i-- ; ) {
  206. ext8( int_cast value ) ;
  207. value >>=8 ;
  208. }
  209. }
  210. extadr(a) cons_t a ; {
  211. /* Assemble the word constant a.
  212. * NOTE: The bytes are written low to high.
  213. */
  214. register i ;
  215. for ( i=ptrsize ; i-- ; ) {
  216. ext8( int_cast a) ;
  217. a >>= 8 ;
  218. }
  219. }
  220. xputa(a,f) cons_t a ; FILE *f ; {
  221. /* Assemble the pointer constant a.
  222. * NOTE: The bytes are written low to high.
  223. */
  224. register i ;
  225. for ( i=ptrsize ; i-- ; ) {
  226. xputc( int_cast a,f) ;
  227. a >>= 8 ;
  228. }
  229. }
  230. cons_t xgeta(f) FILE *f ; {
  231. /* Read the pointer constant a.
  232. * NOTE: The bytes were written low to high.
  233. */
  234. register i, shift ;
  235. cons_t val ;
  236. val = 0 ; shift=0 ;
  237. for ( i=ptrsize ; i-- ; ) {
  238. val += ((cons_t)xgetc(f))<<shift ;
  239. shift += 8 ;
  240. }
  241. return val ;
  242. }
  243. int icount(size) {
  244. int amount ;
  245. amount=(dataoff-lastoff)/size ;
  246. if ( amount>MAXBYTE) fatal("Descriptor overflow");
  247. return amount ;
  248. }
  249. setmode(mode) {
  250. if (datamode==mode) { /* in right mode already */
  251. switch ( datamode ) {
  252. case DATA_CONST:
  253. if ( (dataoff-lastoff)/wordsize < MAXBYTE ) return ;
  254. break ;
  255. case DATA_BYTES:
  256. if ( dataoff-lastoff < MAXBYTE ) return ;
  257. break ;
  258. case DATA_IPTR:
  259. case DATA_DPTR:
  260. if ( (dataoff-lastoff)/ptrsize < MAXBYTE ) return ;
  261. break ;
  262. case DATA_ICON:
  263. case DATA_FCON:
  264. case DATA_UCON:
  265. case DATA_BSS:
  266. break ;
  267. default:
  268. return ;
  269. }
  270. setmode(DATA_NUL) ; /* flush current descriptor */
  271. setmode(mode) ;
  272. return;
  273. }
  274. switch(datamode) { /* terminate current mode */
  275. case DATA_NUL:
  276. break; /* nothing to terminate */
  277. case DATA_CONST:
  278. lastheader->r_val.rel_i=icount(wordsize) ;
  279. lastheader->r_typ = RELHEAD;
  280. datablocks++;
  281. break;
  282. case DATA_BYTES:
  283. lastheader->r_val.rel_i=icount(1) ;
  284. lastheader->r_typ = RELHEAD;
  285. datablocks++;
  286. break;
  287. case DATA_DPTR:
  288. case DATA_IPTR:
  289. lastheader->r_val.rel_i=icount(ptrsize) ;
  290. lastheader->r_typ = RELHEAD;
  291. datablocks++;
  292. break;
  293. default:
  294. datablocks++;
  295. break;
  296. }
  297. datamode=mode;
  298. switch(datamode) {
  299. case DATA_NUL:
  300. break;
  301. case DATA_CONST:
  302. ext8(HEADCONST);
  303. lastheader=data_reloc( chp_cast 0,dataoff,RELNULL);
  304. ext8(0);
  305. lastoff=dataoff;
  306. break;
  307. case DATA_BYTES:
  308. ext8(HEADBYTE);
  309. lastheader=data_reloc( chp_cast 0,dataoff,RELNULL);
  310. ext8(0);
  311. lastoff=dataoff;
  312. break;
  313. case DATA_IPTR:
  314. ext8(HEADIPTR);
  315. lastheader=data_reloc( chp_cast 0,dataoff,RELNULL);
  316. ext8(0);
  317. lastoff=dataoff;
  318. break;
  319. case DATA_DPTR:
  320. ext8(HEADDPTR);
  321. lastheader=data_reloc( chp_cast 0,dataoff,RELNULL);
  322. ext8(0);
  323. lastoff=dataoff;
  324. break;
  325. case DATA_ICON:
  326. ext8(HEADICON) ;
  327. ext8( int_cast consiz) ;
  328. break;
  329. case DATA_FCON:
  330. ext8(HEADFCON) ;
  331. ext8( int_cast consiz) ;
  332. break;
  333. case DATA_UCON:
  334. ext8(HEADUCON) ;
  335. ext8( int_cast consiz) ;
  336. break;
  337. case DATA_REP:
  338. ext8(HEADREP) ;
  339. break ;
  340. case DATA_BSS:
  341. ext8(HEADBSS) ;
  342. break;
  343. default:
  344. fatal("Unknown mode in setmode") ;
  345. }
  346. }
  347. #ifndef CPM
  348. int tmpfil() {
  349. register char *fname, *cpname ;
  350. static char sfname[] = "tmp.00000";
  351. register fildes,pid;
  352. static char name[80] = TMP_DIR ;
  353. int count;
  354. /*
  355. * This procedure returns a file-descriptor of a temporary
  356. * file valid for reading and writing.
  357. * After closing the tmpfil-descriptor the file is lost
  358. * Calling this routine frees the program from generating uniqe names.
  359. */
  360. fname = sfname+4;
  361. count = 10;
  362. pid = getpid();
  363. while (pid!=0) {
  364. *fname++ = (pid&07) + '0';
  365. pid >>= 3;
  366. }
  367. *fname = 0;
  368. for ( fname=name ; *fname ; fname++ ) ;
  369. cpname=sfname ;
  370. while ( *fname++ = *cpname++ ) ;
  371. do {
  372. fname = name;
  373. if ((fildes = creat(fname, 0600)) < 0)
  374. if ((fildes = creat(fname=sfname, 0600)) < 0)
  375. return(-1);
  376. if (close(fildes) < 0)
  377. ;
  378. } while((fildes = open(fname, 2)) < 0 && count--);
  379. if (unlink(fname) < 0)
  380. ;
  381. return(fildes);
  382. }
  383. #endif