static void TEST_AssertError( DaoProcess *proc, DaoValue* p[], int N ) { DString *expected = p[0]->xString.value; DString *actual = NULL; DList *errors = proc->exceptions; DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 0 ); int catched = 0; int size = errors->size; if( sect == NULL ) return; DaoProcess_Execute( proc ); if ( proc->status == DAO_PROCESS_ABORTED && errors->size > size ){ DaoException *e = (DaoException*)&errors->items.pValue[errors->size - 1]->xCdata; if ( DString_Compare( expected, e->ctype->name ) != 0 ) actual = DString_Copy( e->ctype->name ); else catched = 1; DList_Clear( errors ); } DaoProcess_PopFrame( proc ); if ( !catched ){ char buf[512]; if ( actual ){ snprintf( buf, sizeof(buf), "expected %s error, intercepted %s", expected->chars, actual->chars ); DString_Delete( actual ); } else snprintf( buf, sizeof(buf), "expected %s error, intercepted nothing", expected->chars ); DaoProcess_RaiseError( proc, "Test::AssertError", buf ); } }
int DaoRegex_Change( DaoRegex *self, DString *source, DString *target, int index ) { DString *input = DString_Copy( source ); int count = DaoRegex_ChangeExt( self, input, source, target, index, NULL, NULL ); DString_Delete( input ); return count; }
void DaoStream_WriteLocalString( DaoStream *self, DString *str ) { str = DString_Copy( str ); DString_ToLocal( str ); DaoStream_WriteString( self, str ); DString_Delete( str ); }
static void STD_Resource( DaoProcess *proc, DaoValue *p[], int N ) { FILE *fin; DString *file = DString_Copy( p[0]->xString.data ); if( DaoVmSpace_SearchResource( proc->vmSpace, file ) == 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR, "resource file not found" ); DString_Delete( file ); return; } DaoVmSpace_ReadSource( proc->vmSpace, file, file ); DaoProcess_PutString( proc, file ); DString_Delete( file ); }
static void DaoSTD_Resource( DaoProcess *proc, DaoValue *p[], int N ) { FILE *fin; DString *file = DString_Copy( p[0]->xString.value ); if( DaoVmSpace_SearchResource( proc->vmSpace, file, proc->activeNamespace->path ) == 0 ){ DString_InsertChars( file, "resource file not found: ", 0, 0, -1 ); DaoProcess_RaiseError( proc, NULL, file->chars ); DString_Delete( file ); return; } DaoVmSpace_ReadFile( proc->vmSpace, file, file ); DaoProcess_PutString( proc, file ); DString_Delete( file ); }
int DaoxResource_SearchFile( DaoxResource *self, DString *fname, DString *search ) { DString *tmp; if( DaoVmSpace_SearchResource( self->vmSpace, fname, search ) ) return 1; tmp = DString_Copy( fname ); Dao_MakePath( search, tmp ); if( DaoVmSpace_TestFile( self->vmSpace, tmp ) ){ DString_Assign( fname, tmp ); DString_Delete( tmp ); return 1; } DString_Delete( tmp ); return 0; }
static FILE* DaoIO_OpenFile( DaoProcess *proc, DString *name, const char *mode, int silent ) { DString *fname = DString_Copy( name ); char buf[200]; FILE *fin; DaoIO_MakePath( proc, fname ); fin = Dao_OpenFile( fname->chars, mode ); DString_Delete( fname ); if( fin == NULL && silent == 0 ){ snprintf( buf, sizeof(buf), "error opening file: %s", DString_GetData( name ) ); DaoProcess_RaiseError( proc, "Stream", buf ); return NULL; } return fin; }
static void* DArray_CopyItem( DArray *self, void *item ) { DaoValue *v; if( item == NULL ) return NULL; switch( self->type ){ case DAO_DATA_VALUE : v = DaoValue_SimpleCopy( (DaoValue*) item ); GC_IncRC( v ); return v; case DAO_DATA_VMCODE : return DaoVmCodeX_Copy( (DaoVmCodeX*) item ); case DAO_DATA_TOKEN : return DaoToken_Copy( (DaoToken*) item ); case DAO_DATA_STRING : return DString_Copy( (DString*) item ); case DAO_DATA_VECTOR : return DVector_Copy( (DVector*) item ); case DAO_DATA_ARRAY : return DArray_Copy( (DArray*) item ); case DAO_DATA_MAP : return DMap_Copy( (DMap*) item ); default : break; } return item; }
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; }
DaoxImage* DaoxResource_LoadImage( DaoxResource *self, DString *fname, DString *path ) { DaoxImage *image = NULL; DString *file = DString_Copy( fname ); DString *source = DString_New(); DString_Change( file, "\\\\", "/", 0 ); DString_Change( file, "\\", "/", 0 ); if( DaoxResource_SearchFile( self, file, path ) ){ DNode *it = DMap_Find( self->images, file ); if( it != NULL ){ image = (DaoxImage*) it->value.pValue; }else if( DaoxResource_ReadFile( self, file, source ) ){ image = DaoxImage_New(); DaoxImage_Decode( image, source ); DMap_Insert( self->images, file, image ); } } DString_Delete( source ); DString_Delete( file ); return image; }
void DString_MakePath( DString *base, DString *path ) { if( base->size == 0 ) return; if( path->size >= 2 && path->chars[0] == '$' && path->chars[1] == '(' ) return; if( path->size >= 2 && isalpha( path->chars[0] ) && path->chars[1] == ':' ) return; if( path->chars[0] == '/' ) return; base = DString_Copy( base ); Dao_NormalizePathSep( base ); Dao_NormalizePathSep( path ); while( DString_Match( path, " ^ %.%. / ", NULL, NULL ) ){ if( DString_Match( base, " [^/] + ( / | ) $ ", NULL, NULL ) ){ DString_Change( path, " ^ %.%. / ", "", 1 ); DString_Change( base, " [^/] + ( / |) $ ", "", 0 ); }else{ DString_Delete( base ); return; } } if( DString_Match( path, " ^ %.%. $ ", NULL, NULL ) ){ if( DString_Match( base, " [^/] + ( / | ) $ ", NULL, NULL ) ){ DString_Clear( path ); DString_Change( base, " [^/] + ( / |) $ ", "", 0 ); } } if( base->size && path->size ){ if( base->chars[ base->size-1 ] != '/' && path->chars[0] != '/' ) DString_InsertChar( path, '/', 0 ); DString_Insert( path, base, 0, 0, 0 ); }else if( base->size && path->size == 0 ){ DString_Assign( path, base ); } while( DString_Change( path, "/ %. (/|$)", "/", 0 ) ); DString_Delete( base ); }
/* // 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 ); }
int main( int argc, char **argv ) { int restart = 0; int i, k, idsrc, vmods = 0; DString *opts = NULL, *args = NULL; /*mtrace(); */ for(i=1; i<argc; i++){ if( strcmp( argv[i], "-r" ) ==0 || strcmp( argv[i], "--restart" ) ==0 ){ restart = i; break; } } if( restart ) DaoRestartRun( argv, argc, restart ); vmSpace = DaoInit( argv[0] ); idsrc = -1; for(i=1; i<argc; i++){ if( strcmp( argv[i], "-e" ) ==0 || strcmp( argv[i], "--eval" ) ==0 ) break; /* also allows execution of script files without suffix .dao */ if( argv[i][0] != '-' ){ idsrc = i; break; } } #ifdef DAO_WITH_STATIC_MODULES /* // For single file deployment. // Identify the script argument, such that the arguments before the script // can be passed in as virtual machine arguments. // Example: ./script --restart script.dao ... */ args = DString_Copy( vmSpace->daoBinFile ); DString_Erase( args, 0, vmSpace->daoBinPath->size ); DString_AppendChars( args, ".dao" ); idsrc = 1; for(i=1; i<argc; i++){ if( strcmp( argv[i], args->chars ) == 0 ){ idsrc = i; break; } } vmods = DaoVmSpace_AddVirtualModules( vmSpace, dao_virtual_modules ); DString_Reset( args, 0 ); #endif k = idsrc; if( k < 0 ) k = argc; if( opts == NULL ) opts = DString_New(); if( args == NULL ) args = DString_New(); for(i=1; i<k; i++ ){ DString_AppendChars( opts, argv[i] ); DString_AppendChar( opts, '\1' ); } if( idsrc >= 0 ){ #ifdef DAO_WITH_STATIC_MODULES idsrc += 1; #endif for(i=idsrc; i<argc; i++ ){ DString_AppendChars( args, argv[i] ); DString_AppendChar( args, '\1' ); } } DaoVmSpace_ParseOptions( vmSpace, DString_GetData( opts ) ); #ifdef DAO_WITH_STATIC_MODULES if( vmods ){ DString_InsertChars( args, "/@/\1", 0, 0, 0 ); DString_InsertChars( args, dao_virtual_modules[0].name, 3, 0, 0 ); /* set the path for the virtual files: */ DaoVmSpace_SetPath( vmSpace, "/@/" ); }else #endif if( idsrc < 0 && argc == 1 ){ DString_AppendChar( opts, '\1' ); DString_AppendChars( opts, "-vi" ); DaoVmSpace_ParseOptions( vmSpace, DString_GetData( opts ) ); } #ifdef DAO_USE_READLINE DaoVmSpace_ReadLine( vmSpace, DaoReadLine ); DaoVmSpace_AddHistory( vmSpace, (AddHistory) add_history ); read_history( NULL ); #endif signal( SIGINT, DaoSignalHandler ); signal( SIGSEGV, DaoStackTrace ); /* Start execution. */ k = DaoVmSpace_RunMain( vmSpace, DString_GetData( args ) ); #ifdef DAO_USE_READLINE write_history( NULL ); #endif DString_Delete( args ); DString_Delete( opts ); DaoQuit(); return k; }