LispObj * Lisp_GetOutputStreamString(LispBuiltin *builtin) /* get-output-stream-string string-output-stream */ { int length; char *string; LispObj *string_output_stream, *result; string_output_stream = ARGUMENT(0); if (!STREAMP(string_output_stream) || string_output_stream->data.stream.type != LispStreamString || string_output_stream->data.stream.readable || !string_output_stream->data.stream.writable) LispDestroy("%s: %s is not an output string stream", STRFUN(builtin), STROBJ(string_output_stream)); string = LispGetSstring(SSTREAMP(string_output_stream), &length); result = LSTRING(string, length); /* reset string */ SSTREAMP(string_output_stream)->output = SSTREAMP(string_output_stream)->length = SSTREAMP(string_output_stream)->column = 0; return (result); }
LispObj * Lisp_Listen(LispBuiltin *builtin) /* listen &optional input-stream */ { LispFile *file = NULL; LispObj *result = NIL; LispObj *stream; stream = ARGUMENT(0); if (stream == UNSPEC) stream = NIL; else if (stream != NIL) { CHECK_STREAM(stream); } else stream = lisp__data.standard_input; if (stream->data.stream.readable) { switch (stream->data.stream.type) { case LispStreamString: if (SSTREAMP(stream)->input < SSTREAMP(stream)->length) result = T; break; case LispStreamFile: file = FSTREAMP(stream); break; case LispStreamStandard: file = FSTREAMP(stream); break; case LispStreamPipe: file = IPSTREAMP(stream); break; } if (file != NULL) { if (file->available || file->offset < file->length) result = T; else { unsigned char c; if (!file->nonblock) { if (fcntl(file->descriptor, F_SETFL, O_NONBLOCK) < 0) LispDestroy("%s: fcntl: %s", STRFUN(builtin), strerror(errno)); file->nonblock = 1; } if (read(file->descriptor, &c, 1) == 1) { LispFungetc(file, c); result = T; } } } } return (result); }
/* * Implementation */ int LispGet(void) { int ch = EOF; LispUngetInfo *unget = lisp__data.unget[lisp__data.iunget]; if (unget->offset) ch = ((unsigned char*)unget->buffer)[--unget->offset]; else if (SINPUT->data.stream.readable) { LispFile *file = NULL; switch (SINPUT->data.stream.type) { case LispStreamStandard: case LispStreamFile: file = FSTREAMP(SINPUT); break; case LispStreamPipe: file = IPSTREAMP(SINPUT); break; case LispStreamString: ch = LispSgetc(SSTREAMP(SINPUT)); break; default: ch = EOF; break; } if (file != NULL) { if (file->nonblock) { if (fcntl(file->descriptor, F_SETFL, 0) < 0) LispDestroy("fcntl: %s", strerror(errno)); file->nonblock = 0; } ch = LispFgetc(file); } } else LispDestroy("cannot read from *STANDARD-INPUT*"); if (ch == EOF) lisp__data.eof = 1; return (ch); }