static void STD_Load( DaoProcess *proc, DaoValue *p[], int N ) { DString *name = p[0]->xString.data; int import = p[1]->xInteger.value; int runim = p[2]->xInteger.value; int safe = p[3]->xInteger.value; int wasProt = 0; int res = 0; DaoVmSpace *vms = proc->vmSpace; DaoNamespace *ns; DString_ToMBS( name ); if( safe ) vms->options |= DAO_OPTION_SAFE; if( vms->options & DAO_OPTION_SAFE ) wasProt = 1; DArray_PushFront( vms->pathLoading, proc->activeNamespace->path ); ns = DaoVmSpace_LoadEx( vms, DString_GetMBS( name ), runim ); DaoProcess_PutValue( proc, (DaoValue*) ns ); if( ! wasProt ) vms->options &= ~DAO_OPTION_SAFE; if( ns ){ /* in the case that it is cancelled from console */ DArray_PushFront( vms->pathLoading, ns->path ); res = DaoProcess_Call( proc, ns->mainRoutine, NULL, NULL, 0 ); if( proc->stopit | vms->stopit ){ DaoProcess_RaiseException( proc, DAO_ERROR, "loading cancelled" ); }else if( res ){ DaoProcess_RaiseException( proc, res, "loading failed" ); } DArray_PopFront( vms->pathLoading ); }else{ DaoProcess_RaiseException( proc, DAO_ERROR, "loading failed" ); } DArray_PopFront( vms->pathLoading ); if( import && ns ) DaoNamespace_AddParent( proc->activeNamespace, ns ); }
static void FRAME_AddList( DaoProcess *proc, DaoValue *p[], int N ) { DaoxDataColumn *col; DaoxDataFrame *self = (DaoxDataFrame*) p[0]; DaoList *list = (DaoList*) p[1]; DString *lab = DaoValue_TryGetString( p[2] ); DaoType *etype = dao_type_any; daoint i, M = self->dims[0] * self->dims[2]; if( list->unitype && list->unitype->nested->size ){ DaoType *tp = list->unitype->nested->items.pType[0]; if( tp != NULL && !(tp->tid & DAO_ANY) ) etype = tp; } DaoxDataFrame_Sliced( self ); col = DaoxDataFrame_MakeColumn( self, etype ); DArray_Append( self->columns, col ); DaoxDataColumn_Reset( col, M ); self->dims[1] += 1; if( lab->size ){ DString_ToMBS( lab ); DaoxDataFrame_AddLabel( self, DAOX_DF_COL, lab->mbs, self->dims[1]-1 ); } if( M > list->items.size ) M = list->items.size; for(i=0; i<M; ++i) DaoxDataColumn_SetCell( col, i, list->items.items.pValue[i] ); M = self->dims[0] * self->dims[2]; for(i=list->items.size; i<M; ++i) DaoxDataColumn_SetCell( col, i, NULL ); }
static void FRAME_AddArray( DaoProcess *proc, DaoValue *p[], int N ) { DaoValue value = {0}; DaoxDataColumn *col; DaoxDataFrame *self = (DaoxDataFrame*) p[0]; DaoArray *array = (DaoArray*) p[1]; DString *lab = DaoValue_TryGetString( p[2] ); DaoType *etype = dao_array_types[array->etype]; daoint i, M = self->dims[0] * self->dims[2]; etype = etype->nested->items.pType[0]; DaoxDataFrame_Sliced( self ); col = DaoxDataFrame_MakeColumn( self, etype ); DArray_Append( self->columns, col ); DaoxDataColumn_Reset( col, M ); self->dims[1] += 1; if( lab->size ){ DString_ToMBS( lab ); DaoxDataFrame_AddLabel( self, DAOX_DF_COL, lab->mbs, self->dims[1]-1 ); } if( M > array->size ) M = array->size; for(i=0; i<M; ++i){ DaoArray_GetValue( array, i, & value ); DaoxDataColumn_SetCell( col, i, & value ); } M = self->dims[0] * self->dims[2]; for(i=array->size; i<M; ++i) DaoxDataColumn_SetCell( col, i, NULL ); }
static void FRAME_GetIndex( DaoProcess *proc, DaoValue *p[], int N ) { DaoxDataFrame *self = (DaoxDataFrame*) p[0]; DString *lab = DaoValue_TryGetString( p[2] ); daoint idx, dim = p[1]->xEnum.value; DString_ToMBS( lab ); idx = DaoxDataFrame_GetIndex( self, dim, lab->mbs ); DaoProcess_PutInteger( proc, idx ); }
static void FRAME_AddLabel( DaoProcess *proc, DaoValue *p[], int N ) { DaoxDataFrame *self = (DaoxDataFrame*) p[0]; DString *lab = DaoValue_TryGetString( p[2] ); daoint dim = p[1]->xEnum.value; daoint idx = p[3]->xInteger.value; DString_ToMBS( lab ); DaoxDataFrame_AddLabel( self, dim, lab->mbs, idx ); }
int DaoValue_Serialize( DaoValue *self, DString *serial, DaoNamespace *ns, DaoProcess *proc ) { DaoType *type = DaoNamespace_GetType( ns, self ); DString *buf = DString_New(1); DMap *omap = DMap_New(0,0); int rc; DString_Clear( serial ); DString_ToMBS( serial ); rc = DaoValue_Serialize2( self, serial, ns, proc, type, buf, omap ); DString_Delete( buf ); DMap_Delete( omap ); return rc; }
int DaoFile_ReadLine( FILE *fin, DString *line ) { char buf[IO_BUF_SIZE]; DString_Reset( line, 0 ); DString_ToMBS( line ); if( feof( fin ) ) return 0; do{ buf[IO_BUF_SIZE - 1] = 1; if( !fgets( buf, IO_BUF_SIZE, fin ) ) break; DString_AppendMBS( line, buf ); } while( buf[IO_BUF_SIZE - 1] != 1 ); return 1; }
/* // Special relative paths: // 1. ::path, path relative to the current source code file; // 2. :path, path relative to the current working directory; */ static void DaoIO_MakePath( DaoProcess *proc, DString *path ) { DString_ToMBS( path ); if( path->size ==0 ) return; if( path->mbs[0] != ':' ) return; if( path->mbs[1] == ':' ){ DString_Erase( path, 0, 2 ); Dao_MakePath( proc->activeNamespace->path, path ); return; } DString_Erase( path, 0, 1 ); Dao_MakePath( proc->vmSpace->pathWorking, path ); }
int DaoFile_ReadAll( FILE *fin, DString *all, int close ) { char buf[IO_BUF_SIZE]; DString_Reset( all, 0 ); DString_ToMBS( all ); if( fin == NULL ) return 0; while(1){ size_t count = fread( buf, 1, IO_BUF_SIZE, fin ); if( count ==0 ) break; DString_AppendDataMBS( all, buf, count ); } if( close ) fclose( fin ); return 1; }
static void DString_Serialize( DString *self, DString *serial, DString *buf ) { int i; unsigned char *mbs; DString_Clear( buf ); DString_ToMBS( buf ); DString_Append( buf, self ); mbs = (unsigned char*) buf->mbs; DString_AppendChar( serial, self->mbs ? '\'' : '\"' ); for(i=0; i<buf->size; i++){ DString_AppendChar( serial, hex_digits[ mbs[i] / 16 ] ); DString_AppendChar( serial, hex_digits[ mbs[i] % 16 ] ); } DString_AppendChar( serial, self->mbs ? '\'' : '\"' ); }
static FILE* DaoIO_OpenFile( DaoProcess *proc, DString *name, const char *mode, int silent ) { DString *fname = DString_Copy( name ); char buf[IO_BUF_SIZE]; FILE *fin; DString_ToMBS( fname ); DaoIO_MakePath( proc, fname ); fin = fopen( fname->mbs, mode ); DString_Delete( fname ); if( fin == NULL && silent == 0 ){ snprintf( buf, IO_BUF_SIZE, "error opening file: %s", DString_GetMBS( name ) ); DaoProcess_RaiseException( proc, DAO_ERROR, buf ); return NULL; } return fin; }
static daoint DaoxDF_MakeIndex( DaoxDataFrame *self, int dim, DaoValue *value, DaoProcess *p ) { daoint idx = -1; if( value->type >= DAO_INTEGER && value->type <= DAO_DOUBLE ){ idx = DaoValue_GetInteger( value ); }else if( value->type == DAO_STRING ){ DString_ToMBS( value->xString.data ); idx = DaoxDataFrame_GetIndex( self, dim, value->xString.data->mbs ); }else if( value->type == DAO_NONE && self->dims[2] == 1 ){ idx = 0; } if( idx < 0 || idx >= self->dims[dim] ){ DaoProcess_RaiseException( p, DAO_ERROR_INDEX_OUTOFRANGE, "" ); return -1; } return idx; }
int DaoStream_ReadLine( DaoStream *self, DString *line ) { int ch, delim = '\n'; char buf[IO_BUF_SIZE]; char *start = buf, *end = buf + IO_BUF_SIZE; DString_Clear( line ); DString_ToMBS( line ); if( self->redirect && self->redirect->StdioRead ){ self->redirect->StdioRead( self->redirect, line, 0 ); return line->size >0; }else if( self->file ){ return DaoFile_ReadLine( self->file, line ); }else if( self->attribs & DAO_IO_STRING ){ daoint pos = DString_FindWChar( self->streamString, delim, 0 ); if( pos == MAXSIZE ){ DString_Assign( line, self->streamString ); DString_Clear( self->streamString ); }else{ DString_SubString( self->streamString, line, 0, pos+1 ); DString_Erase( self->streamString, 0, pos+1 ); } return self->streamString->size >0; }else{ *start = ch = getchar(); start += 1; while( ch != delim && ch != EOF ){ *start = ch = getchar(); start += 1; if( start == end ){ if( ch == EOF ) start -= 1; DString_AppendDataMBS( line, buf, start-buf ); start = buf; } } if( ch == EOF && start != buf ) start -= 1; DString_AppendDataMBS( line, buf, start-buf ); clearerr( stdin ); return ch != EOF; } return 0; }
static void STD_Load( DaoProcess *proc, DaoValue *p[], int N ) { DString *name = p[0]->xString.data; int import = p[1]->xInteger.value; int runim = p[2]->xInteger.value; int safe = p[3]->xInteger.value; int wasProt = 0; int res = 0; DaoVmSpace *vms = proc->vmSpace; DaoNamespace *ns; DString_ToMBS( name ); if( safe ) vms->options |= DAO_OPTION_SAFE; if( vms->options & DAO_OPTION_SAFE ) wasProt = 1; DArray_PushFront( vms->pathLoading, proc->activeNamespace->path ); ns = DaoVmSpace_LoadEx( vms, DString_GetMBS( name ), runim ); DaoProcess_PutValue( proc, (DaoValue*) ns ); if( ! wasProt ) vms->options &= ~DAO_OPTION_SAFE; if( ns == NULL ) DaoProcess_RaiseException( proc, DAO_ERROR, "loading failed" ); DArray_PopFront( vms->pathLoading ); if( import && ns ) DaoNamespace_AddParent( proc->activeNamespace, ns ); }
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 ); }
/* // C printf format: %[parameter][flags][width][.precision][length]type // // Dao writef format: %[parameter][flags][width][.precision]type[color] // // Where 'parameter', 'flags', 'width' and 'precision' will conform to the // C format, but 'type' can only be: // c, d, i, o, u, x/X : for integer; // e/E, f/F, g/G : for float and double; // s : for string; // p : for any type, write address; // a : automatic, for any type, write in the default format; // Namely the standard ones exception 'n', and plus 'a'. // // Optional 'color' format will be in form of: [foreground:background], [foreground] // or [:background]. The supported color name format will depend on the color printing // handle. Mininum requirement is the support of the following 8 color names: // black, white, red, green, blue, yellow, magenta, cyan. */ static void DaoIO_Writef0( DaoStream *self, DaoProcess *proc, DaoValue *p[], int N ) { DaoValue *value; DMap *cycData; DString *format, *fmt2; DString *fgcolor, *bgcolor; const char *convs = "aspcdiouxXfFeEgG"; char F, *s, *end, *fg, *bg, *fmt, message[100]; int k, id = 1; if( (self->attribs & (DAO_IO_FILE | DAO_IO_PIPE)) && self->file == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR, "stream is not open!" ); return; } cycData = DMap_New(0,0); fmt2 = DString_New(1); fgcolor = DString_New(1); bgcolor = DString_New(1); format = DString_Copy( p[0]->xString.data ); DString_ToMBS( format ); s = format->mbs; end = s + format->size; for(; s<end; s++){ k = 0; if( *s =='%' ){ fmt = s; s += 1; if( *s =='%' || *s == '[' ){ DaoStream_WriteChar( self, *s ); continue; } if( isdigit( *s ) && (*s > '0') ){ while( isdigit( *s ) ) s += 1; if( *s == '$' ){ /* parameter: number$ */ *s = '\0'; k = strtol( fmt + 1, NULL, 10 ); if( k == 0 || k >= N ){ DaoProcess_RaiseException( proc, DAO_WARNING, "invalid parameter number" ); } *s = '%'; fmt = s ++; } } /* flags: */ while( *s == '+' || *s == '-' || *s == '#' || *s == '0' || *s == ' ' ) s += 1; while( isdigit( *s ) ) s += 1; /* width; */ if( *s == '.' ){ /* precision: */ s += 1; while( isdigit( *s ) ) s += 1; } DString_SetDataMBS( fmt2, fmt, s - fmt + 1 ); if( strchr( convs, *s ) == NULL ){ DaoProcess_RaiseException( proc, DAO_WARNING, "invalid format conversion" ); continue; } F = *s; s += 1; fg = bg = NULL; if( *s == '[' ){ s += 1; fmt = s; while( isalnum( *s ) ) s += 1; DString_SetDataMBS( fgcolor, fmt, s - fmt ); if( fgcolor->size ) fg = fgcolor->mbs; if( *s == ':' ){ s += 1; fmt = s; while( isalnum( *s ) ) s += 1; DString_SetDataMBS( bgcolor, fmt, s - fmt ); if( bgcolor->size ) bg = bgcolor->mbs; } if( *s != ']' ) DaoProcess_RaiseException( proc, DAO_WARNING, "invalid color format" ); }else{ s -= 1; } if( k == 0 ) k = id; value = p[k]; id += 1; if( fg || bg ) DaoStream_SetColor( self, fg, bg ); self->format = fmt2->mbs; if( value == NULL ){ if( F == 'p' ){ DaoStream_WriteMBS( self, "0x0" ); }else{ DaoProcess_RaiseException( proc, DAO_WARNING, "null parameter" ); } } self->format = fmt2->mbs; if( F == 'c' || F == 'd' || F == 'i' || F == 'o' || F == 'x' || F == 'X' ){ if( sizeof(daoint) != 4 ) DString_InsertChar( fmt2, DAO_INT_FORMAT[0], fmt2->size-1 ); self->format = fmt2->mbs; if( value->type == DAO_INTEGER ){ DaoStream_WriteInt( self, value->xInteger.value ); }else{ goto WrongParameter; } }else if( toupper( F ) == 'E' || toupper( F ) == 'F' || toupper( F ) == 'G' ){ if( value->type == DAO_FLOAT ){ DaoStream_WriteFloat( self, value->xFloat.value ); }else if( value->type == DAO_DOUBLE ){ DaoStream_WriteFloat( self, value->xDouble.value ); }else{ goto WrongParameter; } }else if( F == 's' && value->type == DAO_STRING ){ DaoStream_WriteString( self, value->xString.data ); }else if( F == 'p' ){ DaoStream_WritePointer( self, value ); }else if( F == 'a' ){ self->format = NULL; DaoValue_Print( value, proc, self, cycData ); }else{ goto WrongParameter; } self->format = NULL; if( fg || bg ) DaoStream_SetColor( self, NULL, NULL ); continue; WrongParameter: self->format = NULL; if( fg || bg ) DaoStream_SetColor( self, NULL, NULL ); sprintf( message, "%i-th parameter has wrong type for format \"%s\"!", k, fmt2->mbs ); DaoProcess_RaiseException( proc, DAO_WARNING, message ); }else{ DaoStream_WriteChar( self, *s ); } } DString_Delete( fgcolor ); DString_Delete( bgcolor ); DString_Delete( format ); DString_Delete( fmt2 ); DMap_Delete( cycData ); }