ass80.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  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[] = "$Header$" ;
  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. rewind(f);
  69. tmp=fdopen(dup(fileno(f)),"r");
  70. fclose(f);
  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. shift += 8 ;
  168. }
  169. if (c == 0377 && shift > 8 && ((shift>>3)&1)) {
  170. while (shift < 8*sizeof(cons_t)) {
  171. val += ((cons_t)c)<<shift ;
  172. shift += 8;
  173. }
  174. }
  175. return val ;
  176. }
  177. ext8(b) {
  178. /*
  179. * Handle one byte of data.
  180. */
  181. ++dataoff;
  182. xputc(b,dfile);
  183. }
  184. extword(w) cons_t w ; {
  185. /* Assemble the word constant w.
  186. * NOTE: The bytes are written low to high.
  187. */
  188. register i ;
  189. for ( i=wordsize ; i-- ; ) {
  190. ext8( int_cast w) ;
  191. w >>= 8 ;
  192. }
  193. }
  194. extarb(size,value) int size ; long value ; {
  195. /* Assemble the 'size' constant value.
  196. * The bytes are again written low to high.
  197. */
  198. register i ;
  199. for ( i=size ; i-- ; ) {
  200. ext8( int_cast value ) ;
  201. value >>=8 ;
  202. }
  203. }
  204. extadr(a) cons_t a ; {
  205. /* Assemble the word constant a.
  206. * NOTE: The bytes are written low to high.
  207. */
  208. register i ;
  209. for ( i=ptrsize ; i-- ; ) {
  210. ext8( int_cast a) ;
  211. a >>= 8 ;
  212. }
  213. }
  214. xputa(a,f) cons_t a ; FILE *f ; {
  215. /* Assemble the pointer constant a.
  216. * NOTE: The bytes are written low to high.
  217. */
  218. register i ;
  219. for ( i=ptrsize ; i-- ; ) {
  220. xputc( int_cast a,f) ;
  221. a >>= 8 ;
  222. }
  223. }
  224. cons_t xgeta(f) FILE *f ; {
  225. /* Read the pointer constant a.
  226. * NOTE: The bytes were written low to high.
  227. */
  228. register i, shift ;
  229. cons_t val ;
  230. val = 0 ; shift=0 ;
  231. for ( i=ptrsize ; i-- ; ) {
  232. val += ((cons_t)xgetc(f))<<shift ;
  233. shift += 8 ;
  234. }
  235. return val ;
  236. }
  237. int icount(size) {
  238. int amount ;
  239. amount=(dataoff-lastoff)/size ;
  240. if ( amount>MAXBYTE) fatal("Descriptor overflow");
  241. return amount ;
  242. }
  243. setmode(mode) {
  244. if (datamode==mode) { /* in right mode already */
  245. switch ( datamode ) {
  246. case DATA_CONST:
  247. if ( (dataoff-lastoff)/wordsize < MAXBYTE ) return ;
  248. break ;
  249. case DATA_BYTES:
  250. if ( dataoff-lastoff < MAXBYTE ) return ;
  251. break ;
  252. case DATA_IPTR:
  253. case DATA_DPTR:
  254. if ( (dataoff-lastoff)/ptrsize < MAXBYTE ) return ;
  255. break ;
  256. case DATA_ICON:
  257. case DATA_FCON:
  258. case DATA_UCON:
  259. case DATA_BSS:
  260. break ;
  261. default:
  262. return ;
  263. }
  264. setmode(DATA_NUL) ; /* flush current descriptor */
  265. setmode(mode) ;
  266. return;
  267. }
  268. switch(datamode) { /* terminate current mode */
  269. case DATA_NUL:
  270. break; /* nothing to terminate */
  271. case DATA_CONST:
  272. lastheader->r_val.rel_i=icount(wordsize) ;
  273. lastheader->r_typ = RELHEAD;
  274. datablocks++;
  275. break;
  276. case DATA_BYTES:
  277. lastheader->r_val.rel_i=icount(1) ;
  278. lastheader->r_typ = RELHEAD;
  279. datablocks++;
  280. break;
  281. case DATA_DPTR:
  282. case DATA_IPTR:
  283. lastheader->r_val.rel_i=icount(ptrsize) ;
  284. lastheader->r_typ = RELHEAD;
  285. datablocks++;
  286. break;
  287. default:
  288. datablocks++;
  289. break;
  290. }
  291. datamode=mode;
  292. switch(datamode) {
  293. case DATA_NUL:
  294. break;
  295. case DATA_CONST:
  296. ext8(HEADCONST);
  297. lastheader=data_reloc( chp_cast 0,dataoff,RELNULL);
  298. ext8(0);
  299. lastoff=dataoff;
  300. break;
  301. case DATA_BYTES:
  302. ext8(HEADBYTE);
  303. lastheader=data_reloc( chp_cast 0,dataoff,RELNULL);
  304. ext8(0);
  305. lastoff=dataoff;
  306. break;
  307. case DATA_IPTR:
  308. ext8(HEADIPTR);
  309. lastheader=data_reloc( chp_cast 0,dataoff,RELNULL);
  310. ext8(0);
  311. lastoff=dataoff;
  312. break;
  313. case DATA_DPTR:
  314. ext8(HEADDPTR);
  315. lastheader=data_reloc( chp_cast 0,dataoff,RELNULL);
  316. ext8(0);
  317. lastoff=dataoff;
  318. break;
  319. case DATA_ICON:
  320. ext8(HEADICON) ;
  321. ext8( int_cast consiz) ;
  322. break;
  323. case DATA_FCON:
  324. ext8(HEADFCON) ;
  325. ext8( int_cast consiz) ;
  326. break;
  327. case DATA_UCON:
  328. ext8(HEADUCON) ;
  329. ext8( int_cast consiz) ;
  330. break;
  331. case DATA_REP:
  332. ext8(HEADREP) ;
  333. break ;
  334. case DATA_BSS:
  335. ext8(HEADBSS) ;
  336. break;
  337. default:
  338. fatal("Unknown mode in setmode") ;
  339. }
  340. }
  341. #ifndef CPM
  342. int tmpfil() {
  343. register char *fname, *cpname ;
  344. char *sfname;
  345. register fildes,pid;
  346. static char name[80] = TMP_DIR ;
  347. int count;
  348. /*
  349. * This procedure returns a file-descriptor of a temporary
  350. * file valid for reading and writing.
  351. * After closing the tmpfil-descriptor the file is lost
  352. * Calling this routine frees the program from generating uniqe names.
  353. */
  354. sfname = fname = "tmp.00000";
  355. count = 10;
  356. pid = getpid();
  357. fname += 4;
  358. while (pid!=0) {
  359. *fname++ = (pid&07) + '0';
  360. pid >>= 3;
  361. }
  362. *fname = 0;
  363. for ( fname=name ; *fname ; fname++ ) ;
  364. cpname=sfname ;
  365. while ( *fname++ = *cpname++ ) ;
  366. do {
  367. fname = name;
  368. if ((fildes = creat(fname, 0600)) < 0)
  369. if ((fildes = creat(fname=sfname, 0600)) < 0)
  370. return(-1);
  371. if (close(fildes) < 0)
  372. ;
  373. } while((fildes = open(fname, 2)) < 0 && count--);
  374. if (unlink(fname) < 0)
  375. ;
  376. return(fildes);
  377. }
  378. #endif