static void DaoIO_WriteLines( DaoProcess *proc, DaoValue *p[], int N ) { DString *string; DaoInteger idint = {DAO_INTEGER,0,0,0,0,0}; DaoValue *res, *index = (DaoValue*)(void*)&idint; DaoVmCode *sect = DaoGetSectionCode( proc->activeCode ); daoint i, entry, lines = p[1]->xInteger.value; FILE *fout = stdout; if( p[0]->type == DAO_STRING ){ fout = DaoIO_OpenFile( proc, p[0]->xString.data, "w+", 0 ); if( fout == NULL ) return; }else{ if( p[0]->xStream.file ) fout = p[0]->xStream.file; } if( sect == NULL || DaoProcess_PushSectionFrame( proc ) == NULL ) return; entry = proc->topFrame->entry; for(i=0; i<lines; i++){ idint.value = i; if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, index ); proc->topFrame->entry = entry; DaoProcess_Execute( proc ); if( proc->status == DAO_PROCESS_ABORTED ) break; string = proc->stackValues[0]->xString.data; if( string->mbs ){ fprintf( fout, "%s", string->mbs ); }else{ fprintf( fout, "%ls", string->wcs ); } } DaoProcess_PopFrame( proc ); }
static void DaoIO_ReadFile( DaoProcess *proc, DaoValue *p[], int N ) { DString *res = DaoProcess_PutMBString( proc, "" ); daoint silent = p[1]->xInteger.value; if( proc->vmSpace->options & DAO_OPTION_SAFE ){ DaoProcess_RaiseException( proc, DAO_ERROR, "not permitted" ); return; } if( DString_Size( p[0]->xString.data ) ==0 ){ char buf[1024]; while(1){ size_t count = fread( buf, 1, sizeof( buf ), stdin ); if( count ==0 ) break; DString_AppendDataMBS( res, buf, count ); } }else{ FILE *fin = DaoIO_OpenFile( proc, p[0]->xString.data, "r", silent ); struct stat info; if( fin == NULL ) return; fstat( fileno( fin ), &info ); DString_Resize( res, info.st_size ); DString_Resize( res, fread( res->mbs, 1, res->size, fin ) ); fclose( fin ); } }
static void DaoIO_Open( DaoProcess *proc, DaoValue *p[], int N ) { DaoFileStream *self = NULL; char *mode; self = DaoFileStream_New(); DaoProcess_PutValue( proc, (DaoValue*)self ); if( N == 0 ){ do self->file = tmpfile(); while ( !self->file && errno == EINTR ); self->base.Read = DaoFileStream_Read; self->base.Write = DaoFileStream_Write; self->base.AtEnd = DaoFileStream_AtEnd; self->base.Flush = DaoFileStream_Flush; self->base.mode |= DAO_STREAM_WRITABLE | DAO_STREAM_READABLE; if( !self->file ){ char errbuf[512]; GetErrorMessage( errno, errbuf, sizeof(errbuf) ); DaoProcess_RaiseError( proc, "Stream", errbuf ); return; } }else{ mode = DString_GetData( p[1]->xString.value ); if( p[0]->type == DAO_INTEGER ){ self->file = fdopen( p[0]->xInteger.value, mode ); if( self->file == NULL ){ char errbuf[512]; GetErrorMessage( errno, errbuf, sizeof(errbuf) ); DaoProcess_RaiseError( proc, "Stream", errbuf ); return; } }else{ self->file = DaoIO_OpenFile( proc, p[0]->xString.value, mode, 0 ); } if( strstr( mode, "+" ) ){ self->base.mode |= DAO_STREAM_WRITABLE | DAO_STREAM_READABLE; }else{ if( strstr( mode, "r" ) ){ self->base.mode |= DAO_STREAM_READABLE; } if( strstr( mode, "w" ) || strstr( mode, "a" ) ){ self->base.mode |= DAO_STREAM_WRITABLE; } } DaoFileStream_InitCallbacks( self ); } }
static void DaoIO_ReadLines( DaoProcess *proc, DaoValue *p[], int N ) { DString *fname; DaoValue *res; DaoString *line; DaoVmCode *sect = DaoGetSectionCode( proc->activeCode ); DaoList *list = DaoProcess_PutList( proc ); int chop = p[1]->xInteger.value; char buf[IO_BUF_SIZE]; FILE *fin; if( proc->vmSpace->options & DAO_OPTION_SAFE ){ DaoProcess_RaiseException( proc, DAO_ERROR, "not permitted" ); return; } fin = DaoIO_OpenFile( proc, p[0]->xString.data, "r", 0 ); if( fin == NULL ) return; if( sect == NULL || DaoProcess_PushSectionFrame( proc ) == NULL ){ line = DaoString_New(1); while( DaoFile_ReadLine( fin, line->data ) ){ if( chop ) DString_Chop( line->data ); DaoList_Append( list, (DaoValue*) line ); } DaoString_Delete( line ); }else{ ushort_t entry = proc->topFrame->entry; DaoString tmp = {DAO_STRING,0,0,0,1,NULL}; tmp.data = p[0]->xString.data; line = (DaoString*) DaoProcess_SetValue( proc, sect->a, (DaoValue*)(void*) &tmp ); DaoProcess_AcquireCV( proc ); while( DaoFile_ReadLine( fin, line->data ) ){ if( chop ) DString_Chop( line->data ); proc->topFrame->entry = entry; DaoProcess_Execute( proc ); if( proc->status == DAO_PROCESS_ABORTED ) break; res = proc->stackValues[0]; if( res && res->type != DAO_NONE ) DaoList_Append( list, res ); } DaoProcess_ReleaseCV( proc ); DaoProcess_PopFrame( proc ); } fclose( fin ); }
static void DaoIO_ReadFile( DaoProcess *proc, DaoValue *p[], int N ) { DString *res = DaoProcess_PutChars( proc, "" ); daoint silent = p[1]->xBoolean.value; if( DString_Size( p[0]->xString.value ) ==0 ){ char buf[4096]; while(1){ size_t count = fread( buf, 1, sizeof( buf ), stdin ); if( count ==0 ) break; DString_AppendBytes( res, buf, count ); } }else{ FILE *fin = DaoIO_OpenFile( proc, p[0]->xString.value, "r", silent ); struct stat info; if( fin == NULL ) return; fstat( fileno( fin ), &info ); DString_Reserve( res, info.st_size ); DString_Reset( res, fread( res->chars, 1, info.st_size, fin ) ); fclose( fin ); } }
static void DaoIO_Open( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *stream = NULL; char *mode; if( proc->vmSpace->options & DAO_OPTION_SAFE ){ DaoProcess_RaiseException( proc, DAO_ERROR, "not permitted" ); return; } stream = DaoStream_New(); stream->attribs |= DAO_IO_FILE; if( N==0 ){ stream->file = tmpfile(); if( stream->file <= 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR, "failed to create temporary file" ); return; } }else{ /* XXX Error handling? */ mode = DString_GetMBS( p[1]->xString.data ); if( p[0]->type == DAO_INTEGER ){ stream->file = fdopen( p[0]->xInteger.value, mode ); }else{ DString_Assign( stream->fname, p[0]->xString.data ); DString_ToMBS( stream->fname ); stream->file = DaoIO_OpenFile( proc, stream->fname, mode, 0 ); } stream->mode = 0; if( strstr( mode, "+" ) ) stream->mode = DAO_IO_WRITE | DAO_IO_READ; else{ if( strstr( mode, "r" ) ) stream->mode |= DAO_IO_READ; if( strstr( mode, "w" ) || strstr( mode, "a" ) ) stream->mode |= DAO_IO_WRITE; } } DaoProcess_PutValue( proc, (DaoValue*)stream ); }