📄 int_streams.c
字号:
/*..........................................................................*//* *//* L a s t W a v e K e r n e l 3 . 0 *//* *//* Copyright (C) 1998-2002 Emmanuel Bacry. *//* email : lastwave@cmap.polytechnique.fr *//* *//*..........................................................................*//* *//* This program is a free software, you can redistribute it and/or *//* modify it under the terms of the GNU General Public License as *//* published by the Free Software Foundation; either version 2 of the *//* License, or (at your option) any later version *//* *//* This program is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *//* GNU General Public License for more details. *//* *//* You should have received a copy of the GNU General Public License *//* along with this program (in a file named COPYRIGHT); *//* if not, write to the Free Software Foundation, Inc., *//* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* *//*..........................................................................*//****************************************************************************//* *//* stream.c Everything on streams *//* *//****************************************************************************/#include "lastwave.h"#include "xx_system.h"#include "xx_terminal.h"#include <stdarg.h>/*#define DEBUG *//*************************************************************** * * Functions on buffers * ***************************************************************//* * Allocation */BUFFER NewBuffer(int size){ BUFFER buf; if (size <= 0) Errorf("NewBuffer() : size of buffer cannot be <= 0 (size == %d)",size); #ifdef DEBUGALLOCDebugType = "Buffer";#endif buf = (BUFFER) Malloc(sizeof(struct buffer_)); buf->buffer = Malloc(sizeof(long)*(size+1)); buf->size = size+1; buf->start = buf->end = buf->buffer; buf->flagEof = NO; return(buf);}/* * Desallocation */void DeleteBuffer(BUFFER buf){ if (buf != NULL) { Free(buf->buffer); #ifdef DEBUGALLOCDebugType = "Buffer";#endif Free(buf); }}/* * Push a long into a buffer */char PushBuffer(BUFFER b,long c){ if (b->flagEof) return(NO); /* We return NO if no room in the buffer */ if ((b->end-b->start+b->size)%b->size == b->size-1) return(NO); *(b->end) = c; b->end = ((b->end-b->buffer)+1)%b->size+b->buffer; return(YES);}/* * Pull a long from a buffer (0 if empty) */long PullBuffer(BUFFER b){ long c; if (b->flagEof == YES) return(EofKC); if (b->end == b->start) return(0); c = *(b->start); b->start = ((b->start-b->buffer)+1)%b->size+b->buffer; if (c == EofKC) b->flagEof = YES; return(c);} /* * Copy the buffer to a string */long Buffer2Str(BUFFER b, char *str){ int i; long *pc; if (b->flagEof) { str[0] = '\0'; return(0); } if (*(b->start) == EofKC) { b->flagEof = YES; str[0] = '\0'; return(0); } i = 0; while (1) { pc = ((b->start-b->buffer)+i)%b->size+b->buffer; if (pc == b->end || *pc == EofKC) break; *(str++) = *pc; i++; } *str = '\0';} /* * Returns the next element in the buffer without pulling it */long TestBuffer(BUFFER b){ if (b->flagEof == YES) return(EofKC); if (b->end == b->start) return(0); return(*(b->start));}/* * Empty the buffer */void EmptyBuffer(BUFFER b){ b->end = b->start;}/* * Ask if there is an occurence of a new line or an eof in the buffer. */char TestBufferNewLine(BUFFER b){ int i; long c; if (b->flagEof) return(YES); if (b->end == b->start) return(NO); i = 0; while(1) { if (((b->start-b->buffer)+i)%b->size+b->buffer == b->end) return(NO); c = *(((b->start-b->buffer)+i)%b->size+b->buffer); if (c == NewlineKC || c == EofKC) return(YES); i++; }} /*************************************************************** * * Functions on streams * ***************************************************************/ /* * The standard streams (not redirectionned) */STREAM _StdinStream = NULL;STREAM _StdoutStream = NULL;STREAM _StderrStream = NULL;STREAM _StdnullStream = NULL;/* * The standard streams (evenetually redirectionned) */STREAM stdinStream = NULL;STREAM stdoutStream = NULL;STREAM stderrStream = NULL;STREAM stdnullStream = NULL;/* * Convert a unix type filename in a real filename *//* ANSI changed */char *ConvertFilename(char *file){ return(XXConvertFilename(file));}/* * Convert a unix type filename in a real filename and open it * returns the FILE * or NULL (if file could not be opened) */static FILE * _FOpen(char *file, const char * mode){ return(fopen(ConvertFilename(file),mode)); }/* * FOpen and FClose routines (called by C-functions that don't want to deal with Streams) */FILE * FOpen(char *filename, char * mode){ STREAM stream; /* We open a stream */ stream = OpenFileStream(filename,mode); if (stream == NULL) return(NULL);// Printf("--> FOpen %s %p\n",filename,stream->stream); else return(stream->stream);}int FClose(FILE *s){ int i; // Printf(" FClose %p\n",s); if (s == NULL) return(1); /* We look for the corresponding stream */ for (i=4;i<MaxNumStreams;i++) if (toplevelCur->theStreams[i] != NULL && toplevelCur->theStreams[i]->stream == s) break; if (i != MaxNumStreams) CloseStream(toplevelCur->theStreams[i]); else fclose(s); return(1);}/* * Allocation of a stream associated to a file * (filename == NULL for opening stderr or stdout) * returns NULL if could not be opened */STREAM OpenFileStream(char *filename,char *mode) { STREAM stream; FILE *f; int id,i; int nStream; char mymode; /* Looking for some room in the toplevel stream array */ if (toplevelCur->nStream < MaxNumStreams) { id = toplevelCur->nStream; nStream = toplevelCur->nStream+1; } else { for (i=4;i<MaxNumStreams;i++) if (toplevelCur->theStreams[i] == NULL) break; if (i == MaxNumStreams) Errorf("NewStream() : too many streams already opened (< %d)",MaxNumStreams); id = i; nStream = toplevelCur->nStream; } /* Checking the mode */ if (!strcmp(mode,"r")) mymode = StreamRead; else if (!strcmp(mode,"w")) mymode = StreamWrite; else if (!strcmp(mode,"a")) mymode = StreamWrite; else Errorf("NewStream() : Bad mode '%s'",mode); /* Opening 'filename' if != NULL */ if (filename != NULL) { f = _FOpen(filename,mode); if (f == NULL) return(NULL); } else f = NULL; /* Allocation of the stream structure */ stream = (STREAM) Malloc(sizeof(struct stream_)); /* Let's fill up the fields ! */ stream->mode = mymode; stream->refCount = 1; stream->stream = f; stream->id = id; stream->buffer = NULL; toplevelCur->nStream = nStream; toplevelCur->theStreams[id] = stream; #ifdef DEBUGprintf("stream %d ---> %d\n",stream->id,stream->refCount);#endif return(stream);}/* * Allocation of a input stream associated to a buffer */STREAM OpenBufferStream(int size) { STREAM stream; int id,i; int nStream; /* Looking for some room in the toplevel stream array */ if (toplevelCur->nStream < MaxNumStreams) { id = toplevelCur->nStream; nStream = toplevelCur->nStream+1; } else { for (i=4;i<MaxNumStreams;i++) if (toplevelCur->theStreams[i] == NULL) break; if (i == MaxNumStreams) Errorf("NewStream() : too many streams already opened (< %d)",MaxNumStreams); id = i; nStream = toplevelCur->nStream; } /* Allocation of the stream structure and buffer */ stream = (STREAM) Malloc(sizeof(struct stream_)); stream->buffer = NewBuffer(size); /* Let's fill up the fields ! */ stream->mode = StreamRead; stream->refCount = 1; stream->stream = NULL; stream->id = id; toplevelCur->nStream = nStream; toplevelCur->theStreams[id] = stream;#ifdef DEBUGprintf("stream %d ---> %d\n",stream->id,stream->refCount);#endif return(stream);}/* * Allocation of a input stream associated to a input buffer and we fill it up with a string */ #define MaxStringBuffer 500 STREAM OpenStringStream(char *str){ int i; STREAM stream; if (strlen(str)+1 > MaxStringBuffer) Errorf("OpenStringStream() : Buffer is too large (asked for %d and max is %d)",strlen(str)+1,MaxStringBuffer); stream = OpenBufferStream(strlen(str)+1); i = 0; while (*str != '\0') stream->buffer->buffer[i++] = *(str++); stream->buffer->buffer[i] = EofKC; stream->buffer->end = stream->buffer->buffer+stream->buffer->size -1; return(stream);} /* * DesAllocation of a stream */void CloseStream(STREAM stream){ if (stream == NULL) return; stream->refCount--;#ifdef DEBUGprintf("stream %d ---> %d\n",stream->id,stream->refCount);#endif if (stream->refCount == 0) { toplevelCur->theStreams[stream->id] = NULL; while (toplevelCur->nStream != 0 && toplevelCur->theStreams[toplevelCur->nStream-1] == NULL) toplevelCur->nStream--; if (stream->stream != NULL) fclose(stream->stream); if (stream->buffer != NULL) DeleteBuffer(stream->buffer); Free(stream); }}/* * Add 1 reference to a stream and returns it */STREAM RefStream(STREAM stream){ if (stream == NULL) return(NULL); stream->refCount++;#ifdef DEBUGprintf("stream %d ---> %d\n",stream->id,stream->refCount);#endif return(stream);}/* * Copy a stream in an other one (after closing the latter) and returns the stream */STREAM CopyStream(STREAM *streamIn,STREAM *streamOut){ if (*streamOut == *streamIn) return(*streamOut); CloseStream(*streamOut); *streamOut = NULL; *streamOut = RefStream(*streamIn); return(*streamOut);}/* * Parsing a stream */char ParseStream_(char *arg, STREAM defVal, STREAM *stream){ int s; *stream = defVal; if (arg == NULL) { SetErrorf("ParseStream_() : NULL string cannot be converted to a stream"); return(NO); } if (!strcmp(arg,"stdin")) { *stream = toplevelCur->in; return(YES); } if (!strcmp(arg,"stdout")) { *stream = toplevelCur->out; return(YES); } if (!strcmp(arg,"stderr")) { *stream = toplevelCur->err; return(YES); } if (!strcmp(arg,"stdnull")) { *stream = stdnullStream; return(YES); } if (ParseInt_(arg,0,&s)) { if (s< 0) { SetErrorf("ParseStream_() : '%d' invalid stream i.d. (must be positive)",s); return(NO); } if (s >= toplevelCur->nStream) { SetErrorf("ParseStream_() : '%d' invalid streamId i.d. (too large --> only '%d' streams are currently open)",s, toplevelCur->nStream); return(NO); } if (toplevelCur->theStreams[s] == NULL) { SetErrorf("ParseStream_() : '%d' invalid streamId i.d.",s); return(NO); } *stream = toplevelCur->theStreams[s]; return(YES); } SetErrorf("ParseStream_() : '%s' invalid stream name",arg); return(NO);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -