This is unixstuff.c in view mode; [Download] [Up]
/* unixtuff.c - unix interface routines for xlisp
* HISTORY
* 2-Aprl-88 Dale Amon at CMU-CSD
* Upgraded to xlisp 2.0. Used msstuff.c as a template.
*
* 20-Apr-87 Dale Amon at CMU-CSD
* Added control-c interrupt handler. Puts user in breakloop and allows
* continue. Prints line at which the interrupt occured. Interrupt
* occurs at first eval after ^C has been typed.
*
* 19-APR-87 Dale Amon at CMU-CSD
* switched from rand to random package. Corrected bug in osrand(). It
* did not use the argument n to calculate a rand in range 0 to n-1 as
* advertised.
*/
#include <stdio.h>
#include "xlisp.h"
#define LBSIZE 200
/* external variables */
extern LVAL s_unbound,true;
extern FILE *tfp;
extern int errno;
/* local variables */
static char lbuf[LBSIZE];
static int lpos[LBSIZE];
static int lindex;
static int lcount = 0;
static int lposition;
/*==========================================================================*/
/* control-c interrupt handling routines and variables. Uses B4.2 signal
handling. Previous SIGINT handler is saved just in case someday we want
to play with turning control c on and off.
*/
#include <signal.h>
static int (*save_sig)();
static int ctc = FALSE;
static control_c() {ctc = TRUE;}
static ctcinit() {save_sig = signal ( SIGINT, control_c );}
static ctcreset() {signal ( SIGINT, control_c );}
/*==========================================================================*/
/* osinit - initialize */
osinit(banner)
char *banner;
{ printf("%s\n",banner);
/* start the random number generator. Older version was srand(1)
seed of 1 makes the sequence repeatable. Random gives better
pseudo randomness than does rand().
*/
srandom(1);
/* set control c trap to local routine */
ctcinit();
lposition = 0;
lindex = 0;
lcount = 0;
}
/* osfinish - clean up before returning to the operating system */
osfinish() {}
/* oserror - print an error message */
oserror(msg) char *msg; {printf("error: %s\n",msg);}
extern long random();
extern srandom();
int osrand(n) int n; {return (((int) random()) % n);}
/* osaopen - open an ascii file */
FILE *osaopen(name,mode) char *name,*mode; {
FILE *fp;
/* printf("aopening %s\n", name);*/
fp = fopen(name,mode);
/* printf("FILE is %x\n", fp);*/
return fp;
}
/* osbopen - open a binary file */
FILE *osbopen(name,mode) char *name,*mode;
{ char bmode[10];
FILE *fp;
strcpy(bmode,mode); strcat(bmode,"b");
/* printf("bopening %s\n", name);*/
fp = fopen(name,bmode);
/* printf("FILE is %x\n", fp);*/
return fp;
}
/* osclose - close a file */
int osclose(fp) FILE *fp; {
/* printf("closing FILE %x\n", fp);*/
return (fclose(fp));}
/* osagetc - get a character from an ascii file */
int osagetc(fp) FILE *fp; {return (getc(fp));}
/* osaputc - put a character to an ascii file */
int osaputc(ch,fp) int ch; FILE *fp; {return (putc(ch,fp));}
extern int dbgflg;
/* osbgetc - get a character from a binary file */
/* int osbgetc(fp) FILE *fp; {return (getc(fp));} */
int osbgetc(fp) FILE *fp; {int c; c = (getc(fp));
/* if (dbgflg) printf("osbgetc: got %d from FILE %x\n", c, fp);
* return c;
*/
}
/* osbputc - put a character to a binary file */
int osbputc(ch,fp) int ch; FILE *fp; {return (putc(ch,fp));}
/* ostgetc - get a character from the terminal */
int ostgetc()
{ int ch;
switch (ch = getchar()) {
case '\n':
lbuf[lcount++] = '\n';
lposition = 0;
if (tfp)
for (lindex = 0; lindex < lcount; ++lindex)
osaputc(lbuf[lindex],tfp);
lindex = 0; lcount = 0;
return (ch);
case '\010':
case '\177':
if (lcount) {
lcount--;
while (lposition > lpos[lcount]) {
lposition--;
}
}
break;
case '\032':
xflush();
return (EOF);
default:
if (ch == '\t' || (ch >= 0x20 && ch < 0x7F)) {
lbuf[lcount] = ch;
lpos[lcount] = lposition;
if (ch == '\t')
do {} while (++lposition & 7);
else {lposition++;}
lcount++;
return (ch);
}
else {
xflush();
switch (ch) {
case '\003': xltoplevel(); /* control-c */
case '\007': xlcleanup(); /* control-g */
case '\020': xlcontinue(); /* control-p */
case '\032': return (EOF); /* control-z */
/* moved from oscheck until I figure out how to
set up interrupt to handle these two */
case '\002': xflush(); xlbreak("BREAK",s_unbound);
break; /* control-b */
case '\024': xinfo(); break; /* control-t */
default: return (ch);
}
}
}
}
/* ostputc - put a character to the terminal */
ostputc(ch) int ch;
{
oscheck(); /* check for control characters */
/* output the character */
if (ch == '\n') {lposition = 0;}
else {lposition++;}
/* output the character to the transcript file */
if (tfp) osaputc(ch,tfp);
putchar(((char) ch));
}
/* osflush - flush the terminal input buffer */
osflush() {lindex = lcount = lposition = 0;}
/* oscheck - check for control characters during execution */
oscheck()
{
#ifdef FOOBAZ
int ch;
#endif
if (ctc) {ctc=FALSE; ctcreset();
xflush(); xltoplevel(); return;} /* control-c */
#ifdef FOOBAZ
if (ch = xcheck())
switch (ch) {
case '\002': xflush(); xlbreak("BREAK",s_unbound);
break; /* control-b */
case '\024': xinfo(); break; /* control-t */
}
#endif
}
/* xinfo - show information on control-t */
static xinfo()
{
extern int nfree,gccalls;
extern long total;
char buf[80];
sprintf(buf,"\n[ Free: %d, GC calls: %d, Total: %ld ]",
nfree,gccalls,total);
errputstr(buf);
}
/* xflush - flush the input line buffer and start a new line */
static xflush() {osflush(); ostputc('\n');}
/* xsystem - execute a system command */
LVAL xsystem()
{ /*LVAL strval;*/
unsigned char *cmd;
if (moreargs())
cmd = (unsigned char *)getstring(xlgastring());
xllastarg();
return (system(cmd) == -1 ? cvfixnum((FIXTYPE)errno) : true);
}
/* xgetkey - get a key from the keyboard */
LVAL xgetkey() {xllastarg(); return (cvfixnum((FIXTYPE)getchar()));}
/* ossymbols - enter os specific symbols */
ossymbols() {}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.