/* =====> PROCIOSP.C */ /* TIPC Scheme '84 Runtime Support - File Input/Output Support (C) Copyright 1985 by Texas Instruments Incorporated. All rights reserved. Author: John C. Jensen Installation: Texas Instruments Incorporated, Dallas, Texas Division: Central Research Laboratories Cost Center: Computer Science Laboratory Project: Computer Architecture Branch Date Written: 4 February 1985 Last Modification: 14 Jan 1987 - dbs Modified to allow for random i/o. 16 Mar 1987 - tc Dos I/O errors call DOS-ERR now. 24 Nov 1987 - tc Renamed from SIN_OUT.C to IOSUPORT.C Combined routines from sprint.c,sread.c get_port.c and zcio.c */ #include "scheme.h" #include "sport.h" #include "slist.h" #define FILE_NOT_FOUND 2 /* MS-DOS error code */ #define NON_RESTART 1 /* Operation not restartable */ extern char decpoint; /* Current decimal point character */ extern unsigned GC_ING; /* Garbage collecting indicator */ char *getmem(); /* Lattice C's memory allocation support */ /************************************************************************/ /* Get Port Object */ /* */ /* Purpose: To determine is a register contains a valid port object */ /* representation and to return the appropriate port */ /* pointer in "tmp_reg". */ /************************************************************************/ get_port(reg, mode) int reg[2], mode; { int disp; /* displacement component of a pointer */ int page; /* page number component of a pointer */ /* fetch page and displacement portions of port pointer */ page = CORRPAGE(reg[C_PAGE]); disp = reg[C_DISP]; /* check to see if port pointer is nil-- if so, search fluid env */ if (!page) { if (mode) intern (tmp_reg, "OUTPUT-PORT", 11); else intern (tmp_reg, "INPUT-PORT", 10); /* search fluid environment for interned symbol */ ASSERT(fluid_lookup(tmp_reg)); page = CORRPAGE(tmp_page); disp = tmp_disp; } /* end: if (!page) */ /* At this point, the page, disp should point to a port, or the symbol 'console */ if (ptype[page] != PORTTYPE*2) { if (CORRPAGE(CON_PAGE) != page || CON_DISP != disp) return(1); tmp_page = SPECPOR*2; tmp_disp = (mode ? OUT_DISP : IN_DISP); } else { tmp_page = ADJPAGE(page); tmp_disp = disp; } return(0); } /* end of function: get_port(reg, mode) */ /************************************************************************/ /* Open a Port */ /************************************************************************/ spopen(file, mode) int file[2]; /* pathname, 'console, nil, or # */ int mode[2]; /* 'read, 'write, 'append */ { /* extern int prn_handle; (tc) */ int direction; /* 'read, 'write, 'append code */ int disp; /* displacement component of a pointer */ int handle; /* handle assigned to file by open */ int hsize; /* high word of file size - dbs */ int lsize; /* low word of file size - dbs */ int i; /* our old favorite index variable */ int len; /* length of file's pathname (plus 1) */ int page; /* page number component of a pointer */ int p_flags; /* port flags */ int retstat = 0; /* the return status */ int stat; /* status returned from open request */ char *string; /* file pathname buffer pointer */ float fsize; /* file size - dbs */ ENTER(spopen); /* identify mode value */ if ((direction = get_mode(mode)) == -1) goto src_err; page = CORRPAGE(file[C_PAGE]); disp = file[C_DISP]; switch(ptype[page]) { case STRTYPE*2: len = get_word(page, disp+1); if (len < 0) /* Adjust for small string */ len = len + BLK_OVHD; else len = len - BLK_OVHD; if (!(string = getmem(len+1))) getmem_error(rtn_name); get_str(string, page, disp); string[len] = '\0'; for (i=0; i=1.0e7)); } /***************************************************************/ /* MAKEFLO(flo,buf,prec,ex) */ /* Takes a flonum FLO and converts it to a human-readable */ /* form, storing the characters in the buffer BUF. PREC */ /* specifies the number of decimal places to be used (as many */ /* as necessary, up to a maximum, if PREC is 0) and EX */ /* specifies whether to use exponential (if nonzero) or fixed- */ /* decimal format. MAKEFLO returns the number of characters */ /* placed in BUF, and BUF should be at least 32 bytes. */ /***************************************************************/ makeflo(flo,buf,prec,ex) double flo; char *buf; int prec,ex; { char digits[32]; int scl = 0; if (flo==0.0) { *digits='0'; ex=0; } else { scale(&flo,&scl); flo2big(flo*1.0e15,buf); big2asc(buf,digits); } return(formflo(digits,buf,scl,prec,ex)); } /***************************************************************/ /* SCALE(&flo,&x) */ /* Given a pointer FLO to a double-length flonum and a */ /* pointer X to an integer, SCALE puts at those two locations */ /* a new flonum and integer such that FLO equals the new */ /* flonum times 10 to the integer's power and the new flonum */ /* is in the interval [ 1.0, 10.0 ). */ /***************************************************************/ scale(flo,x) double *flo; int *x; { double local; double squar = 10.0; double tensquar[9]; int scale,wassmall,i; scale = wassmall = i = 0; local = ((*flo>0) ? *flo : -*flo); if (local == 0) *x = 0; else { if (local < 1.0) { wassmall = -1; local = 1.0/local; } tensquar[0] = 10.0; while (++i<9) { squar *= squar; tensquar[i] = squar; } while (--i>=0) { scale <<=1; if (local>=tensquar[i]) { local /= tensquar[i]; scale++; } } if (wassmall) { scale = -scale; local = 1.0/local; if (local!=1.0) { local *= 10; scale--; } } *x = scale; *flo = ((*flo < 0.0) ? -local : local); } } /**************************************************************/ /* SCANFLO(s,flo,base) */ /* The string S, which ends in a control char, holds a */ /* representation of a floating-point number. The value of */ /* this number is stored in *FLO. */ /**************************************************************/ scanflo(s,flo,base) char *s; double *flo; int base; { int i=0; int neg=0; int x=0; double place; switch (*s) { case '-': neg=-1; case '+': i++; break; default: break; } while (s[i]=='#') i+=2; *flo = 0.0; while (isdig(s[i],base)) { *flo = (*flo * base) + digval(s[i++]); } if (!(s[i]==decpoint)) goto EXPON; POINT: i++; place = 1.0; while (isdig(s[i],base)) { place /= base; *flo += place*digval(s[i++]); } if (s[i]<' ') goto GOTFLO; EXPON: i++; if (s[i]=='-') { i++; place = 1.0/base; } else place=base; while (isdigit(s[i])) x = (x*10) + digval(s[i++]); while (x) { if (x!=(x>>1)<<1) *flo *= place; if (place<1.0e153) place*=place; x >>= 1; } GOTFLO: if (neg) *flo = -*flo; } /**************************************************************/ /* ALLOC_INT(reg,buf) */ /* This allocates an integer, either a fixnum or a */ /* bignum, depending on the size of the integer, i.e., if */ /* the absolute value < 16384, then a fixnum is allocated. */ /* The value is read from BUF. */ /**************************************************************/ alloc_int(reg,buf) int reg[2]; char *buf; { unsigned i,j; int pg; i = 256*buf[1] + buf[0]; j = 256*buf[4] + buf[3]; pg = buf[2] & 1; if ((i == 1) && (j <= 16383+pg)) /* If fixnum */ alloc_fixnum(reg, (pg ? -j : j)); else { alloc_block(reg, BIGTYPE, 2*i + 1); toblock(reg, 3, buf+2, 2*i +1); } } /************************************************************************/ /* Write "GC On"Message to the who-line */ /************************************************************************/ gc_on() { int lcl_reg[2]; char *text; char *string_asciz(); GC_ING = 1; intern(lcl_reg, "PCS-GC-MESSAGE", 14); if (sym_lookup (lcl_reg, GNV_reg) && (text = string_asciz(lcl_reg))) { who_write("\n"); who_write(text); rlsstr(text); } else { who_write("\n * Garbage Collecting *"); } } /* end of function: gc_on() */ /************************************************************************/ /* Un-Write "GC On"Message to the who-line */ /************************************************************************/ gc_off() { GC_ING = 0; who_clear(); } /* end of function: gc_off() */