static void SYS_Popen( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *stream = NULL; char *mode; DString *fname; stream = DaoStream_New(); stream->attribs |= DAO_IO_PIPE; fname = stream->fname; DString_Assign( fname, p[0]->xString.data ); if( DString_Size( fname ) >0 ){ mode = DString_GetMBS( p[1]->xString.data ); stream->file = popen( DString_GetMBS( fname ), mode ); if( stream->file == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR, "error opening pipe" ); } 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; } }else{ DaoProcess_RaiseException( proc, DAO_ERROR, "empty command line" ); } DaoProcess_PutValue( proc, (DaoValue*)stream ); }
static void AUX_Backup( DaoProcess *proc, DaoValue *p[], int N ) { FILE *fout = fopen( DString_GetMBS( p[0]->xString.data ), "w+" ); if( fout == NULL ){ DaoProcess_RaiseException( proc,DAO_ERROR_FILE, DString_GetMBS( p[0]->xString.data ) ); return; } DaoNamespace_Backup( proc->activeNamespace, proc, fout, p[1]->xInteger.value ); fclose( fout ); }
static void AUX_Restore( DaoProcess *proc, DaoValue *p[], int N ) { FILE *fin = fopen( DString_GetMBS( p[0]->xString.data ), "r" ); if( fin == NULL ){ DaoProcess_RaiseException( proc,DAO_ERROR_FILE, DString_GetMBS( p[0]->xString.data ) ); return; } DaoNamespace_Restore( proc->activeNamespace, proc, fin ); fclose( fin ); }
static void SYS_PutEnv( DaoProcess *proc, DaoValue *p[], int N ) { char *name = DString_GetMBS( p[0]->xString.data ); char *value = DString_GetMBS( p[1]->xString.data ); char *buf = malloc( strlen( name ) + strlen( value ) + 2 ); if( !buf ){ DaoProcess_RaiseException( proc, DAO_ERROR, "memory allocation failed" ); return; } sprintf( buf, "%s=%s", name, value ); if( putenv( buf ) ){ DaoProcess_RaiseException( proc, DAO_ERROR, "error putting environment variable" ); free( buf ); } }
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 ); }
/* // Note: reference count is not handled for "self"! // But it is cached in the DaoProcess object, so no need to handle it by user! */ int DaoValue_Deserialize( DaoValue **self, DString *serial, DaoNamespace *ns, DaoProcess *proc ) { DaoParser *parser = DaoParser_New(); DArray *types = DArray_New(0); DMap *omap = DMap_New(0,0); int rc; *self = NULL; parser->nameSpace = ns; parser->vmSpace = ns->vmSpace; DaoParser_LexCode( parser, DString_GetMBS( serial ), 0 ); if( parser->tokens->size == 0 ) goto Failed; DArray_PushFront( types, NULL ); rc = DaoParser_Deserialize( parser, 0, parser->tokens->size-1, self, types, ns, proc, omap ); if( *self ) DaoProcess_CacheValue( proc, *self ); DaoParser_Delete( parser ); DArray_Delete( types ); DMap_Delete( omap ); return rc; Failed: DaoParser_Delete( parser ); DArray_Delete( types ); DMap_Delete( omap ); return 0; }
void DaoxShader_CompileShader( DaoxShader *self, int type, DArray *strings ) { daoint i, n = strings->size; uint_t shader = glCreateShader( type ); const GLchar **sources; GLint length, shader_ok; if( shader == 0 ){ fprintf(stderr, "Failed to create shader of type %i\n", type ); return; } sources = (const GLchar**) malloc( n*sizeof(GLchar*) ); for(i=0; i<n; ++i){ sources[i] = (const GLchar*) DString_GetMBS( strings->items.pString[i] ); if( i == 0 ) sources[i] += 2; /* skip //; */ } glShaderSource( shader, n, sources, NULL ); glCompileShader( shader ); free( sources ); glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok); if( !shader_ok ){ const char *log2; DString *log = DString_New(1); glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length ); DString_Resize( log, length ); log2 = DString_GetMBS(log); glGetShaderInfoLog( shader, length, NULL, (char*)log2 ); fprintf(stderr, "Failed to compile shader!\nWith error message: %s", log2 ); glDeleteShader(shader); return; } switch( type ){ case GL_VERTEX_SHADER : if( self->vertexShader ) glDeleteShader( self->vertexShader ); self->vertexShader = shader; break; case GL_FRAGMENT_SHADER : if( self->fragmentShader ) glDeleteShader( self->fragmentShader ); self->fragmentShader = shader; break; } if( shader && self->program ) glAttachShader( self->program, shader ); }
static void STD_Path( DaoProcess *proc, DaoValue *p[], int N ) { char *path = DString_GetMBS( p[0]->xString.data ); switch( p[1]->xEnum.value ){ case 0 : DaoVmSpace_SetPath( proc->vmSpace, path ); break; case 1 : DaoVmSpace_AddPath( proc->vmSpace, path ); break; case 2 : DaoVmSpace_DelPath( proc->vmSpace, path ); break; } }
void DaoCGI_SendFile( DaoProcess *proc, DaoValue *p[], int N ) { DString *mbs; DString *file = DaoValue_TryGetString( p[0] ); DString *mime = DaoValue_TryGetString( p[1] ); DString *notfound = DaoValue_TryGetString( p[2] ); char buf[IO_BUF_SIZE]; FILE *fin = fopen( DString_GetMBS( file ), "r" ); if( fin == NULL ){ printf( "%s", DString_GetMBS( notfound ) ); return; } mbs = DString_New(1); printf( "Content-Type: %s\n\n", DString_GetMBS( mime ) ); while(1){ size_t count = fread( buf, 1, IO_BUF_SIZE, fin ); if( count ==0 ) break; DString_Reset( mbs, 0 ); DString_AppendDataMBS( mbs, buf, count ); DaoFile_WriteString( stdout, mbs ); } fclose( fin ); DString_Delete( 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 void SYS_SetLocale( DaoProcess *proc, DaoValue *p[], int N ) { int category = 0; char* old; switch( p[0]->xEnum.value ){ case 0: category = LC_ALL; break; case 1: category = LC_COLLATE; break; case 2: category = LC_CTYPE; break; case 3: category = LC_MONETARY; break; case 4: category = LC_NUMERIC; break; case 5: category = LC_TIME; break; } old = setlocale( category, N == 1 ? NULL : DString_GetMBS( p[1]->xString.data ) ); if ( old ) DaoProcess_PutMBString( proc, old ); else DaoProcess_RaiseException( proc, DAO_ERROR, "invalid locale" ); }
static void DaoClass_GetField( DaoValue *self0, DaoProcess *proc, DString *name ) { int tid = proc->activeRoutine->routHost ? proc->activeRoutine->routHost->tid : 0; DaoType *type = proc->activeRoutine->routHost; DaoClass *host = tid == DAO_OBJECT ? & type->aux->xClass : NULL; DaoClass *self = & self0->xClass; DString *mbs = DString_New(1); DaoValue *value = NULL; int rc = DaoClass_GetData( self, name, & value, host ); if( rc ){ DString_SetMBS( mbs, DString_GetMBS( self->className ) ); DString_AppendMBS( mbs, "." ); DString_Append( mbs, name ); DaoProcess_RaiseException( proc, rc, mbs->mbs ); }else{ DaoProcess_PutReference( proc, value ); } DString_Delete( mbs ); }
void DaoxShader_Finalize( DaoxShader *self ) { GLint length, program_ok; if( self->program == 0 ) return; int shaderAttribute = 0; glBindFragDataLocation( self->program, 0, "fragColor"); glLinkProgram( self->program ); glGetProgramiv( self->program, GL_LINK_STATUS, &program_ok ); if( !program_ok ){ const char *log2; DString *log = DString_New(1); glGetProgramiv( self->program, GL_INFO_LOG_LENGTH, &length ); DString_Resize( log, length ); log2 = DString_GetMBS(log); glGetProgramInfoLog( self->program, length, NULL, (char*)log2 ); fprintf(stderr, "Failed to link shader program with error message: %s\n", log2 ); glDeleteProgram(self->program); self->program = 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 ); }
static void dao_FakeList_SetName( DaoContext *_ctx, DValue *_p[], int _n ) { const char *name = DString_GetMBS( _p[1]->v.s ); printf( "new name: %s\n", name ); }
static void STD_Warn( DaoProcess *proc, DaoValue *p[], int N ) { DaoProcess_RaiseException( proc, DAO_WARNING, DString_GetMBS( p[0]->xString.data ) ); }
static void STD_Error( DaoProcess *proc, DaoValue *p[], int N ) { DaoProcess_RaiseException( proc, DAO_ERROR, DString_GetMBS( p[0]->xString.data ) ); }
static void PreparePostData( DaoProcess *proc, DaoMap *httpPOSTS, DaoMap *httpPOST, DaoMap *httpFILE ) { DaoValue *vk = (DaoValue*) DaoProcess_NewMBString( proc, NULL, 0 ); DaoValue *vv = (DaoValue*) DaoProcess_NewMBString( proc, NULL, 0 ); DString *key = DaoString_Get( DaoValue_CastString( vk ) ); DString *value = DaoString_Get( DaoValue_CastString( vv ) ); DString *dynaBuffer = DString_New(1); int i = 0; int len = 0; char buffer[ LOCAL_BUF_SIZE + 1 ]; char *last = buffer + (LOCAL_BUF_SIZE-1); char *contentLength = getenv( "CONTENT_LENGTH" ); char *contentType = getenv( "CONTENT_TYPE" ); len = 0; *last = 0; if( contentLength != NULL ) len = strtol( contentLength, NULL, 10); if( contentType != NULL ){ //printf( "CONTENT_TYPE = %s\n", contentType ); if( strstr( contentType, "multipart/form-data" ) == NULL ){ i = 0; DString_Clear( dynaBuffer ); while( i < len ){ int n = 0; int ch = getchar(); while( ch != EOF ){ buffer[n] = (char)ch; n ++; if( n == LOCAL_BUF_SIZE ) break; ch = getchar(); } buffer[ n ] = 0; //printf( "%s|||||||||||||||||\n", buffer ); char *p = strchr( buffer, '&' ); if( p != NULL ){ *p = 0; // null-terminating p++; DString_AppendMBS( dynaBuffer, buffer ); ParseKeyValueString( proc, httpPOSTS, httpPOST, DString_GetMBS( dynaBuffer ) ); DString_Clear( dynaBuffer ); DString_AppendMBS( dynaBuffer, p ); }else{ DString_AppendMBS( dynaBuffer, buffer ); } i += LOCAL_BUF_SIZE; } ParseKeyValueString( proc, httpPOSTS, httpPOST, DString_GetMBS( dynaBuffer ) ); }else{ char *boundary = strstr( contentType, "boundary" ); boundary = strstr( boundary, "=" ) + 1; i = 0; char *part = NULL; while( ! feof( stdin ) ){ if( part == NULL ) part = fgets( buffer, LOCAL_BUF_SIZE, stdin ); if( part == NULL ) break; if( strstr( part, boundary ) == NULL ) break; // read content information DString_Clear( dynaBuffer ); buffer[ LOCAL_BUF_SIZE ] = 0; // null-terminating char *p = fgets( buffer, LOCAL_BUF_SIZE, stdin ); if( p == NULL ) break; // the last boundary scanned p = strchr( p, '\n' ); *p = 0; // null-terminating DString_AppendMBS( dynaBuffer, buffer ); char *info = (char*)DString_GetMBS( dynaBuffer ); info = strchr( info, '=' ); info += 2; // at char after name=" p = info; while( *p != '\"' ) p ++; *p = 0; // null-terminating DString_SetMBS( key, info ); p ++; if( (p = strstr(p,"filename") ) == NULL ){ p = fgets( buffer, LOCAL_BUF_SIZE, stdin ); p = fgets( buffer, LOCAL_BUF_SIZE, stdin ); // now real data: DString_Clear( value ); while( p != NULL && strstr( p, boundary ) == NULL ){ char *t = strstr( p, "\r\n" ); if( t != NULL ) *t = 0; DString_AppendMBS( value, buffer ); if( feof( stdin ) ) break; p = fgets( buffer, LOCAL_BUF_SIZE, stdin ); t = strchr( p, '\n' ); if( t!= NULL ) *(t+1) = 0; } if( p != NULL ) part = p; DaoMap_Insert( httpPOST, vk, vv ); }else{ DaoValue *vs = (DaoValue*) DaoProcess_NewStream( proc, tmpfile() ); FILE *file = DaoStream_GetFile( DaoValue_CastStream( vs ) ); char *t = NULL; p = strchr( p, '\"' ) + 1; info = p; while( *p != '\"' ) p ++; *p = 0; // null-terminating //XXX stream->TYPER->SetName( stream, info ); DString_Clear( value ); // Content-Type ...\r\n p = fgets( buffer, LOCAL_BUF_SIZE, stdin ); // \r\n p = fgets( buffer, LOCAL_BUF_SIZE, stdin ); // data #if 0 int count = fread( buffer, 1, LOCAL_BUF_SIZE, stdin ); while( count && strstr( buffer, boundary ) == NULL ){ fwrite( buffer, 1, count, file ); fprintf( file, "%s\n", "===========================" ); if( feof( stdin ) ) break; count = fread( buffer, 1, LOCAL_BUF_SIZE, stdin ); } #else char tail[3] = { 0, 0, 0 }; int count, ntail = 0; p = fgets( buffer, LOCAL_BUF_SIZE, stdin ); while( p != NULL && strstr( p, boundary ) == NULL ){ if( feof( stdin ) ){ // XXX break; }else{ t = p; while( t != last && (*t) != '\n' ) t ++; if( (*t) == '\n' ){ count = t-p+1; if( count >= 2 ){ count -= 2; if( ntail ) fwrite( tail, 1, ntail, file ); tail[0] = p[ count ]; tail[1] = p[ count+1 ]; ntail = 2; fwrite( p, 1, count, file ); }else if( count == 1 ){ if( ntail == 2 ){ fwrite( tail, 1, 1, file ); tail[0] = tail[1]; tail[1] = p[0]; }else if( ntail ==1 ){ tail[1] = p[0]; ntail = 2; }else{ tail[0] = p[0]; ntail = 1; } } }else{ if( ntail ) fwrite( tail, 1, ntail, file ); count = LOCAL_BUF_SIZE-3; tail[0] = p[ count ]; tail[1] = p[ count+1 ]; ntail = 2; fwrite( p, 1, count, file ); } } p = fgets( buffer, LOCAL_BUF_SIZE, stdin ); } #endif //if( p != NULL ) part = p; rewind( file ); DaoMap_Insert( httpFILE, vk, vs ); } } } } DString_Delete( dynaBuffer ); }
char* DaoValue_TryGetMBString( DaoValue *self ) { if( self->type != DAO_STRING ) return NULL; return DString_GetMBS( self->xString.data ); }
static void SYS_Shell( DaoProcess *proc, DaoValue *p[], int N ) { DaoProcess_PutInteger( proc, system( DString_GetMBS( p[0]->xString.data ) ) ); }
static void SYS_Ctimef( DaoProcess *proc, DaoValue *p[], int N ) { int i; int halfday = 0; const int size = p[1]->xString.data->size; const char *format = DString_GetMBS( p[1]->xString.data ); char buf[100]; char *p1 = buf+1; char *p2; DaoMap *sym = NULL; DaoString *ds = DaoString_New(1); DaoValue *key = (DaoValue*) ds; DString *S; struct tm *ctime; time_t t = (time_t)p[0]->xInteger.value; if( t == 0 ) t = time(NULL); ctime = gmtime( & t ); if( N > 1 ){ sym = (DaoMap*)p[2]; if( sym->items->size == 0 ) sym = NULL; } S = DaoProcess_PutMBString( proc, "" ); for( i=0; i+1<size; i++ ){ if( format[i] == '%' && ( format[i+1] == 'a' || format[i+1] == 'A' ) ){ halfday = 1; break; } } buf[0] = '0'; /* for padding */ for( i=0; i+1<size; i++ ){ p2 = p1; p1[0] = 0; if( format[i] == '%' ){ const char ch = format[i+1]; switch( ch ){ case 'Y' : sprintf( p1, "%i", ctime->tm_year+1900 ); break; case 'y' : sprintf( p1, "%i", ctime->tm_year+1900 ); p2 += 2; break; case 'M' : case 'm' : if( ! addStringFromMap( key, S, sym, "month", ctime->tm_mon ) ){ sprintf( p1, "%i", ctime->tm_mon+1 ); if( ch=='M' && p1[1]==0 ) p2 = buf; /* padding 0; */ }else p2 = NULL; break; case 'D' : case 'd' : if( ! addStringFromMap( key, S, sym, "date", ctime->tm_mday ) ){ sprintf( p1, "%i", ctime->tm_mday ); if( ch=='D' && p1[1]==0 ) p2 = buf; /* padding 0; */ }else p2 = NULL; break; case 'W' : case 'w' : if( ! addStringFromMap( key, S, sym, "week", ctime->tm_wday ) ) sprintf( p1, "%i", ctime->tm_wday+1 ); else p2 = NULL; break; case 'H' : case 'h' : if( halfday ) sprintf( p1, "%i", ctime->tm_hour %12 ); else sprintf( p1, "%i", ctime->tm_hour ); if( ch=='H' && p1[1]==0 ) p2 = buf; /* padding 0; */ break; case 'I' : case 'i' : sprintf( p1, "%i", ctime->tm_min ); if( ch=='I' && p1[1]==0 ) p2 = buf; /* padding 0; */ break; case 'S' : case 's' : sprintf( p1, "%i", ctime->tm_sec ); if( ch=='S' && p1[1]==0 ) p2 = buf; /* padding 0; */ break; case 'a' : if( ! addStringFromMap( key, S, sym, "halfday", 0 ) ){ if( ctime->tm_hour >= 12 ) strcpy( p1, "pm" ); else strcpy( p1, "am" ); }else p2 = NULL; break; case 'A' : if( ! addStringFromMap( key, S, sym, "halfday", 1 ) ){ if( ctime->tm_hour >= 12 ) strcpy( p1, "PM" ); else strcpy( p1, "AM" ); }else p2 = NULL; break; default : break; } if( p2 ) DString_AppendMBS( S, p2 ); i ++; }else{ DString_AppendChar( S, format[i] ); } } if( i+1 == size ) DString_AppendChar( S, format[i] ); DaoString_Delete( ds ); }
static void SYS_GetEnv( DaoProcess *proc, DaoValue *p[], int N ) { char *evar = getenv( DString_GetMBS( p[0]->xString.data ) ); DaoProcess_PutMBString( proc, evar? evar : "" ); }