static void DArray_DeleteItems( DArray *self, daoint M, daoint N ) { daoint i; switch( self->type ){ case DAO_DATA_VALUE : for(i=M; i<N; i++) GC_DecRC( self->items.pValue[i] ); break; case DAO_DATA_VMCODE : for(i=M; i<N; i++) DaoVmCodeX_Delete( self->items.pVmc[i] ); break; case DAO_DATA_TOKEN : for(i=M; i<N; i++) DaoToken_Delete( self->items.pToken[i] ); break; case DAO_DATA_STRING : for(i=M; i<N; i++) DString_Delete( self->items.pString[i] ); break; case DAO_DATA_VECTOR : for(i=M; i<N; i++) DVector_Delete( self->items.pVector[i] ); break; case DAO_DATA_ARRAY : for(i=M; i<N; i++) DArray_Delete( self->items.pArray[i] ); break; case DAO_DATA_MAP : for(i=M; i<N; i++) DMap_Delete( self->items.pMap[i] ); break; default : break; } }
static void NS_Backup( DaoNamespace *self, DaoProcess *proc, FILE *fout, int limit, int store ) { DNode *node = DMap_First( self->lookupTable ); DString *prefix = DString_New(1); DString *serial = DString_New(1); DaoValue *value = NULL; size_t max = limit * 1000; /* limit per object in KB */ int id, pm, up, st; for( ; node !=NULL; node = DMap_Next( self->lookupTable, node ) ){ DString *name = node->key.pString; id = node->value.pInt; up = LOOKUP_UP( id ); st = LOOKUP_ST( id ); pm = LOOKUP_PM( id ); if( up ) continue; if( st != store ) continue; if( st == DAO_GLOBAL_CONSTANT ) value = DaoNamespace_GetConst( self, id ); if( st == DAO_GLOBAL_VARIABLE ) value = DaoNamespace_GetVariable( self, id ); if( value == NULL ) continue; if( DaoValue_Serialize( value, serial, self, proc ) ==0 ) continue; prefix->size = 0; switch( pm ){ case DAO_DATA_PRIVATE : DString_AppendMBS( prefix, "private " ); break; case DAO_DATA_PROTECTED : DString_AppendMBS( prefix, "protected " ); break; case DAO_DATA_PUBLIC : DString_AppendMBS( prefix, "public " ); break; } switch( st ){ case DAO_GLOBAL_CONSTANT : DString_AppendMBS( prefix, "const " ); break; case DAO_GLOBAL_VARIABLE : DString_AppendMBS( prefix, "var " ); break; } if( max && prefix->size + name->size + serial->size + 4 > max ) continue; fprintf( fout, "%s%s = %s\n", prefix->mbs, name->mbs, serial->mbs ); } DString_Delete( prefix ); DString_Delete( serial ); }
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 ); }
static DaoType* DaoInterface_CheckConversion( DaoType *self, DaoType *type, DaoRoutine *ctx ) { DaoRoutine *rout; DString *buffer = DString_NewChars( "(" ); DString_Append( buffer, type->name ); DString_AppendChars( buffer, ")" ); rout = DaoType_FindFunction( self, buffer ); DString_Delete( buffer ); if( rout != NULL ){ DaoType *ttype = DaoNamespace_GetType( ctx->nameSpace, (DaoValue*) type ); rout = DaoRoutine_MatchByType( rout, self, & ttype, 1, DVM_CALL ); if( rout ) return type; } return NULL; }
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; }
void DaoStream_WriteChar( DaoStream *self, char val ) { const char *format = "%c"; if( self->redirect && self->redirect->StdioWrite ){ DString *mbs = DString_New(1); DString_AppendChar( mbs, val ); self->redirect->StdioWrite( self->redirect, mbs ); DString_Delete( mbs ); }else if( self->file ){ fprintf( self->file, format, val ); }else if( self->attribs & DAO_IO_STRING ){ DString_AppendChar( self->streamString, val ); }else{ printf( format, val ); } }
static void CHANNEL_New( DaoProcess *proc, DaoValue *par[], int N ) { DaoType *retype = DaoProcess_GetReturnType( proc ); DaoChannel *self = DaoChannel_New( retype, 0 ); CHANNEL_SetCap( self, par[0], proc ); if( DaoType_CheckPrimitiveType( retype->nested->items.pType[0] ) == 0 ){ DString *s = DString_New(); DString_AppendChars( s, "data type " ); DString_Append( s, retype->nested->items.pType[0]->name ); DString_AppendChars( s, " is not supported for channel" ); DaoProcess_RaiseError( proc, NULL, s->chars ); DString_Delete( s ); } DaoProcess_PutValue( proc, (DaoValue*) self ); DaoCallServer_TryInit( mainVmSpace ); }
DAO_DLL int DaoOnLoad( DaoVmSpace *vmSpace, DaoNamespace *ns ) { FILE *fin = fopen( "test.xml", "r" ); DString *xml = DString_New(); DaoXmlDOM *dom = DaoXmlDOM_New(); DaoXmlParser *parser = DaoXmlParser_New(); DaoFile_ReadAll( fin, xml, 1 ); DaoXmlParser_Parse( parser, dom, xml ); DaoXmlDOM_Traverse( dom, NULL, NULL, DaoXmlNode_TestVisit ); DString_Delete( xml ); DaoXmlDOM_Delete( dom ); DaoXmlParser_Delete( parser ); return 0; }
void DaoStream_WriteWCS( DaoStream *self, const wchar_t *val ) { const char *format = self->format; if( format == NULL ) format = "%ls"; if( self->redirect && self->redirect->StdioWrite ){ DString *mbs = DString_New(1); DString_SetWCS( mbs, val ); self->redirect->StdioWrite( self->redirect, mbs ); DString_Delete( mbs ); }else if( self->file ){ fprintf( self->file, format, val ); }else if( self->attribs & DAO_IO_STRING ){ DString_AppendWCS( self->streamString, val ); }else{ printf( format, val ); } }
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; }
void DaoClass_SetName( DaoClass *self, DString *name, DaoNamespace *ns ) { DaoRoutine *rout; DString *str; if( self->classRoutine ) return; self->objType = DaoType_New( name->mbs, DAO_OBJECT, (DaoValue*)self, NULL ); self->clsType = DaoType_New( name->mbs, DAO_CLASS, (DaoValue*) self, NULL ); GC_IncRC( self->clsType ); DString_InsertMBS( self->clsType->name, "class<", 0, 0, 0 ); DString_AppendChar( self->clsType->name, '>' ); str = DString_New(1); DString_SetMBS( str, "self" ); DaoClass_AddObjectVar( self, str, NULL, self->objType, DAO_DATA_PRIVATE ); DString_Assign( self->className, name ); DaoClass_AddType( self, name, self->objType ); rout = DaoRoutine_New( ns, self->objType, 1 ); DString_Assign( rout->routName, name ); DString_AppendMBS( rout->routName, "::" ); DString_Append( rout->routName, name ); self->classRoutine = rout; /* XXX class<name> */ GC_IncRC( rout ); rout->routType = DaoType_New( "routine<=>", DAO_ROUTINE, (DaoValue*)self->objType, NULL ); DString_Append( rout->routType->name, name ); DString_AppendMBS( rout->routType->name, ">" ); GC_IncRC( rout->routType ); rout->attribs |= DAO_ROUT_INITOR; DaoClass_AddConst( self, name, (DaoValue*) self, DAO_DATA_PUBLIC ); self->objType->value = (DaoValue*) DaoObject_Allocate( self, DAO_MAX_PARENT ); self->objType->value->xObject.trait |= DAO_VALUE_CONST|DAO_VALUE_NOCOPY; self->objType->value->xObject.isDefault = 1; GC_IncRC( self->objType->value ); DString_SetMBS( str, "default" ); DaoClass_AddConst( self, str, self->objType->value, DAO_DATA_PUBLIC ); self->classRoutines = DaoRoutines_New( ns, self->objType, NULL ); DString_Assign( self->classRoutines->routName, name ); DaoClass_AddConst( self, rout->routName, (DaoValue*)self->classRoutines, DAO_DATA_PUBLIC ); DString_Delete( str ); }
void DaoStream_WriteFormatedInt( DaoStream *self, daoint val, const char *format ) { char buffer[100]; if( self->redirect && self->redirect->StdioWrite ){ DString *mbs = DString_New(1); sprintf( buffer, format, val ); DString_SetMBS( mbs, buffer ); self->redirect->StdioWrite( self->redirect, mbs ); DString_Delete( mbs ); }else if( self->file ){ fprintf( self->file, format, val ); }else if( self->attribs & DAO_IO_STRING ){ sprintf( buffer, format, val ); DString_AppendMBS( self->streamString, buffer ); }else{ printf( format, val ); } }
void DaoClass_ResetAttributes( DaoClass *self ) { DNode *node; DString *mbs = DString_New(1); int i, k, id, autodef = self->classRoutines->overloads->routines->size == 0; DaoClass_MakeInterface( self ); for(i=0; i<self->classRoutines->overloads->routines->size; i++){ DaoRoutine *r2 = self->classRoutines->overloads->routines->items.pRoutine[i]; DArray *types = r2->routType->nested; autodef = r2->parCount == 0; if( autodef ) break; for(k=0; k<types->size; k++){ int tid = types->items.pType[k]->tid; if( tid != DAO_PAR_DEFAULT && tid != DAO_PAR_VALIST ) break; } autodef = k == types->size; if( autodef ) break; } if( autodef && self->parent ){ if( self->parent->type == DAO_CLASS ){ DaoClass *klass = (DaoClass*) self->parent; autodef = autodef && (klass->attribs & DAO_CLS_AUTO_DEFAULT); }else{ autodef = 0; } } #if 0 printf( "%s %i\n", self->className->mbs, autodef ); #endif if( autodef ) self->attribs |= DAO_CLS_AUTO_DEFAULT; for(i=DVM_NOT; i<=DVM_BITRIT; i++){ DString_SetMBS( mbs, daoBitBoolArithOpers[i-DVM_NOT] ); node = DMap_Find( self->lookupTable, mbs ); if( node == NULL ) continue; if( LOOKUP_ST( node->value.pInt ) != DAO_CLASS_CONSTANT ) continue; id = LOOKUP_ID( node->value.pInt ); k = self->constants->items.pConst[id]->value->type; if( k != DAO_ROUTINE ) continue; self->attribs |= DAO_OPER_OVERLOADED | (DAO_OPER_OVERLOADED<<(i-DVM_NOT+1)); } DString_Delete( mbs ); }
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 ); }
static int DaoObject_CheckSetField( DaoType *self, DaoString *name, DaoType *value, DaoRoutine *ctx ) { DaoClass *klass = (DaoClass*) self->aux; DaoType *type = ctx->routHost; DaoClass *host = type != NULL && type->tid == DAO_OBJECT ? (DaoClass*) type->aux : NULL; DaoValue *data = DaoClass_GetData( klass, name->value, host ); DaoRoutine *rout; int error = DAO_OK; error = 0; if( strcmp( name->value->chars, "self" ) ==0 ) return DAO_ERROR_FIELD_HIDDEN; if( data == NULL ){ error = DAO_ERROR_FIELD_ABSENT; }else if( data->type == DAO_NONE ){ error = DAO_ERROR_FIELD_HIDDEN; }else if( data->xBase.subtype == DAO_CLASS_CONSTANT ){ error = DAO_ERROR_FIELD_HIDDEN; // XXX }else{ /* data->xBase.subtype == DAO_CLASS_VARIABLE || DAO_OBJECT_VARIABLE */ if( DaoType_MatchTo( value, data->xVar.dtype, NULL ) == 0 ) return DAO_ERROR_VALUE; } if( error ){ DString *field = DString_NewChars( "." ); DString_Append( field, name->value ); DString_AppendChars( field, "=" ); rout = DaoClass_FindMethod( klass, field->chars, host ); DString_Delete( field ); if( rout != NULL ){ rout = DaoRoutine_MatchByType( rout, self, & value, 1, DVM_CALL ); }else{ DaoType *args[2]; args[0] = dao_type_string; args[1] = value; rout = DaoClass_FindMethod( klass, ".=", host ); if( rout == NULL ) return error; rout = DaoRoutine_MatchByType( rout, self, args, 2, DVM_CALL ); } if( rout == NULL ) return error; } return DAO_OK; }
void DaoStream_WritePointer( DaoStream *self, void *val ) { const char *format = self->format; char buffer[100]; if( format == NULL ) format = "%p"; if( self->redirect && self->redirect->StdioWrite ){ DString *mbs = DString_New(1); sprintf( buffer, format, val ); DString_SetMBS( mbs, buffer ); self->redirect->StdioWrite( self->redirect, mbs ); DString_Delete( mbs ); }else if( self->file ){ fprintf( self->file, format, val ); }else if( self->attribs & DAO_IO_STRING ){ sprintf( buffer, format, val ); DString_AppendMBS( self->streamString, buffer ); }else{ printf( format, val ); } }
static DaoValue* DaoObject_DoConversion( DaoValue *self, DaoType *type, int copy, DaoProcess *proc ) { DaoObject *object = (DaoObject*) self; DaoClass *host = proc->activeObject ? proc->activeObject->defClass : NULL; DaoValue *base = DaoObject_CastToBase( object->rootObject, type ); DaoRoutine *rout; DString *buffer; if( base ) return base; buffer = DString_NewChars( "(" ); DString_Append( buffer, type->name ); DString_AppendChars( buffer, ")" ); rout = DaoClass_FindMethod( object->defClass, buffer->chars, host ); DString_Delete( buffer ); if( rout != NULL ){ int rc = DaoProcess_PushCall( proc, rout, self, (DaoValue**) & type, 1 ); if( rc ) return NULL; } return NULL; }
static DaoType* DaoObject_CheckConversion( DaoType *self, DaoType *type, DaoRoutine *ctx ) { DString *buffer; DaoRoutine *rout; DaoType *hostype = ctx->routHost; DaoClass *host = hostype != NULL && hostype->tid == DAO_OBJECT ? (DaoClass*) hostype->aux : NULL; if( DaoType_ChildOf( self, type ) ) return type; if( DaoType_ChildOf( type, self ) ) return type; buffer = DString_NewChars( "(" ); DString_Append( buffer, type->name ); DString_AppendChars( buffer, ")" ); rout = DaoClass_FindMethod( (DaoClass*) self->aux, buffer->chars, host ); DString_Delete( buffer ); if( rout != NULL ){ DaoType *ttype = DaoNamespace_GetType( ctx->nameSpace, (DaoValue*) type ); rout = DaoRoutine_MatchByType( rout, self, & ttype, 1, DVM_CALL ); } if( rout != NULL ) return type; return NULL; }
static void STD_Callable( DaoProcess *proc, DaoValue *p[], int N ) { DaoValue *p0 = p[0]; daoint *res = DaoProcess_PutInteger( proc, 0 ); if( p0 == NULL || p0->type == 0 ){ *res = 0; return; } switch( p0->type ){ case DAO_CLASS : case DAO_ROUTINE : *res = 1; break; case DAO_OBJECT : { DaoObject *object = & p0->xObject; DString *mbs = DString_New(1); DString_SetMBS( mbs, "()" ); DaoObject_GetData( object, mbs, & p0, proc->activeObject ); DString_Delete( mbs ); if( p0 && p0->type == DAO_ROUTINE ) *res = 1; break; } case DAO_CTYPE : { DaoType *type = p0->xCdata.ctype; *res = DaoType_FindFunctionMBS( type, type->typer->name ) != NULL; break; } case DAO_CDATA : case DAO_CSTRUCT : { *res = DaoType_FindFunctionMBS( p0->xCdata.ctype, "()" ) != NULL; break; } default : break; } }
void DaoClass_Delete( DaoClass *self ) { GC_DecRC( self->clsType ); DMap_Delete( self->abstypes ); DMap_Delete( self->lookupTable ); DMap_Delete( self->ovldRoutMap ); DArray_Delete( self->constants ); DArray_Delete( self->variables ); DArray_Delete( self->instvars ); DArray_Delete( self->objDataName ); DArray_Delete( self->cstDataName ); DArray_Delete( self->glbDataName ); DArray_Delete( self->allBases ); DArray_Delete( self->mixinBases ); DArray_Delete( self->mixins ); DVector_Delete( self->ranges ); DVector_Delete( self->offsets ); DArray_Delete( self->references ); if( self->decoTargets ) DArray_Delete( self->decoTargets ); DString_Delete( self->className ); dao_free( self ); }
DaoType* DaoValue_CheckGetField( DaoType *self, DaoString *name ) { DaoRoutine *rout = DaoType_FindFunction( self, name->value ); DaoType *argtype; DString *buffer; if( rout != NULL ) return rout->routType; buffer = DString_NewChars( "." ); DString_Append( buffer, name->value ); rout = DaoType_FindFunction( self, buffer ); DString_Delete( buffer ); if( rout != NULL ){ rout = DaoRoutine_MatchByType( rout, self, NULL, 0, DVM_CALL ); }else{ rout = DaoType_FindFunctionChars( self, "." ); if( rout == NULL ) return NULL; argtype = rout->nameSpace->vmSpace->typeString; rout = DaoRoutine_MatchByType( rout, self, & argtype, 1, DVM_CALL ); } if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; }
static DaoType* DaoObject_CheckGetField( DaoType *self, DaoString *name, DaoRoutine *ctx ) { DaoClass *klass = (DaoClass*) self->aux; DaoType *type = ctx->routHost; DaoClass *host = type != NULL && type->tid == DAO_OBJECT ? (DaoClass*) type->aux : NULL; DaoValue *data = DaoClass_GetData( klass, name->value, host ); DaoRoutine *rout; int error = DAO_OK; if( data == NULL ){ error = DAO_ERROR_FIELD_ABSENT; }else if( data->type == DAO_NONE ){ error = DAO_ERROR_FIELD_HIDDEN; }else{ switch( data->xBase.subtype ){ case DAO_OBJECT_VARIABLE : return data->xVar.dtype; case DAO_CLASS_VARIABLE : return data->xVar.dtype; case DAO_CLASS_CONSTANT : return DaoNamespace_GetType( ctx->nameSpace, data->xConst.value ); } } if( error ){ DString *field = DString_NewChars( "." ); DString_Append( field, name->value ); rout = DaoClass_FindMethod( klass, field->chars, host ); DString_Delete( field ); if( rout != NULL ){ rout = DaoRoutine_MatchByType( rout, self, NULL, 0, DVM_CALL ); }else{ rout = DaoClass_FindMethod( klass, ".", host ); if( rout == NULL ) return NULL; rout = DaoRoutine_MatchByType( rout, self, & dao_type_string, 1, DVM_CALL ); } if( rout == NULL ) return NULL; return (DaoType*) rout->routType->aux; } return NULL; }
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_GetData( file ), "r" ); if( fin == NULL ) { printf( "%s", DString_GetData( notfound ) ); return; } mbs = DString_New(); printf( "Content-Type: %s\n\n", DString_GetData( mime ) ); while(1) { size_t count = fread( buf, 1, IO_BUF_SIZE, fin ); if( count ==0 ) break; DString_Reset( mbs, 0 ); DString_AppendBytes( mbs, buf, count ); DaoFile_WriteString( stdout, mbs ); } fclose( fin ); DString_Delete( mbs ); }
void DaoNamespace_Restore( DaoNamespace *self, DaoProcess *proc, FILE *fin ) { DaoParser *parser = DaoParser_New(); DString *line = DString_New(1); DArray *types = DArray_New(0); DArray *tokens = parser->tokens; DMap *omap = DMap_New(0,0); DString *name; DNode *node; parser->nameSpace = self; parser->vmSpace = self->vmSpace; while( DaoFile_ReadLine( fin, line ) ){ DaoValue *value = NULL; int st = DAO_GLOBAL_VARIABLE; int pm = DAO_DATA_PRIVATE; int i, n, start = 0; char *mbs; DaoParser_LexCode( parser, line->mbs, 0 ); if( tokens->size == 0 ) continue; name = & tokens->items.pToken[start]->string; if( name->size == 6 && strcmp( name->mbs, "inputs" ) == 0 ){ if( tokens->size < 3 ) continue; DString_Clear( line ); n = tokens->items.pToken[start+2]->string.size; mbs = tokens->items.pToken[start+2]->string.mbs; for(i=0; i<n; i++){ char c1 = mbs[i]; char c2 = mbs[i+1]; if( c1 < 'A' || c1 > 'P' ) continue; DString_AppendChar( line, (char)((c1-'A')*16 + (c2-'A')) ); i += 1; } /* printf( "%s\n", line->mbs ); */ DaoProcess_Eval( proc, self, line->mbs ); continue; } switch( tokens->items.pToken[start]->name ){ case DKEY_PRIVATE : pm = DAO_DATA_PRIVATE; start += 1; break; case DKEY_PROTECTED : pm = DAO_DATA_PROTECTED; start += 1; break; case DKEY_PUBLIC : pm = DAO_DATA_PUBLIC; start += 1; break; } if( start >= tokens->size ) continue; switch( tokens->items.pToken[start]->name ){ case DKEY_CONST : st = DAO_GLOBAL_CONSTANT; start += 1; break; case DKEY_VAR : st = DAO_GLOBAL_VARIABLE; start += 1; break; } if( tokens->items.pToken[start]->name != DTOK_IDENTIFIER ) continue; name = & tokens->items.pToken[start]->string; start += 1; if( start + 3 >= tokens->size ) continue; if( tokens->items.pToken[start]->name != DTOK_ASSN ) continue; start += 1; DArray_Clear( parser->errors ); DArray_Clear( types ); DArray_PushFront( types, NULL ); DaoParser_Deserialize( parser, start, tokens->size-1, &value, types, self, proc, omap ); if( value == NULL ) continue; node = DMap_Find( self->lookupTable, name ); if( node ) continue; if( st == DAO_GLOBAL_CONSTANT ){ DaoNamespace_AddConst( self, name, value, pm ); }else{ DaoNamespace_AddVariable( self, name, value, NULL, pm ); } } DMap_Delete( omap ); DString_Delete( line ); DArray_Delete( types ); DaoParser_Delete( parser ); }
void DaoStringStream_Delete( DaoStringStream *self ) { DString_Delete( self->base.buffer ); DaoCstruct_Free( (DaoCstruct*) self ); dao_free( self ); }
int DaoLexer_Tokenize( DaoLexer *self, const char *src, int flags ) { DString *source = DString_New(1); DVector *lexenvs = DVector_New( sizeof(int) ); DaoToken *token = DaoToken_New(); DString *literal = & token->string; char ch, *ss, hex[11] = "0x00000000"; int replace = flags & DAO_LEX_ESCAPE; int comment = flags & DAO_LEX_COMMENT; int space = flags & DAO_LEX_SPACE; int srcSize = (int)strlen( src ); int old=0, state = TOK_START; int lexenv = LEX_ENV_NORMAL; int unicoded = 0; int line = 1; int cpos = 0; int ret = 1; int it = 0; int i, m = 4; DString_SetSharing( literal, 0 ); for(it=0; it<srcSize; it++){ if( (signed char) src[it] < 0 ){ unicoded = 1; break; } } if( unicoded && daoConfig.mbs == 0 ){ DString *wcs = DString_New(0); /* http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html */ wchar_t quotes[] = { 0x27 , 0x27 , 0x27, /* single q.m. */ 0x22 , 0x22 , 0x22, /* double q.m. */ 0x27 + 0xfee0 , 0x27 + 0xfee0 , 0x27 , /* single q.m. unicode */ 0x22 + 0xfee0 , 0x22 + 0xfee0 , 0x22 , /* double q.m. unicode */ 0x60 , 0x27 , 0x27, /* grave accent */ 0x2018 , 0x2019 , 0x27 , /* left/right single q.m. */ 0x201C , 0x201D , 0x22 /* left/right double q.m. */ }; wchar_t sl = L'\\' + 0xfee0; wchar_t stop; int i, N = 21; it = 0; DString_SetMBS( wcs, src ); while( it < wcs->size ){ // TODO: handle verbatim string! for( i=0; i<N; i+=3 ){ if( wcs->wcs[it] == quotes[i] ){ stop = quotes[i+1]; wcs->wcs[it] = quotes[i+2]; it ++; while( it < wcs->size && wcs->wcs[it] != stop ){ if( wcs->wcs[it] == sl || wcs->wcs[it] == L'\\' ){ it ++; continue; } it ++; } if( it < wcs->size ) wcs->wcs[it] = quotes[i+2]; break; } } if( it >= wcs->size ) break; if( wcs->wcs[it] == 0x3000 ){ wcs->wcs[it] = 32; /* blank space */ }else if( wcs->wcs[it] > 0xff00 && wcs->wcs[it] < 0xff5f ){ wcs->wcs[it] -= 0xfee0; /* DBC to SBC */ } it ++; } if( wcs->size ){ DString_SetWCS( source, wcs->wcs ); src = source->mbs; srcSize = source->size; } DString_Delete( wcs ); } DaoLexer_Reset( self ); DVector_PushInt( lexenvs, LEX_ENV_NORMAL ); it = 0; token->cpos = 0; while( it < srcSize ){ #if 0 printf( "tok: %i %i %i %c %s\n", srcSize, it, ch, ch, literal->mbs ); #endif token->type = state; token->name = 0; token->line = line; ch = src[it]; cpos += ch == '\t' ? daoConfig.tabspace : 1; if( ch == '\n' ) cpos = 0, line ++; if( literal->size == 0 ) token->cpos = cpos; if( state == TOK_STRING_MBS || state == TOK_STRING_WCS ){ if( ch == '\\' ){ it ++; if( replace == 0 ){ DString_AppendChar( literal, ch ); if( it < srcSize ){ if( src[it] == '\n' ) cpos = 0, line ++; DString_AppendChar( literal, src[it] ); } it ++; continue; } if( it >= srcSize ){ ret = 0; printf( "error: incomplete string at line %i.\n", line ); break; } if( src[it] == '\n' ) cpos = 0, line ++; switch( src[it] ){ case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : /* \ooo */ i = 2; while( i < 5 && it < srcSize && src[it] >= '0' && src[it] < '8' ){ hex[i] = src[it++]; hex[++i] = 0; } DString_AppendChar( literal, (char) strtol( hex+2, NULL, 8 ) ); it --; break; case '8' : case '9' : DString_AppendChar( literal, (char) (src[it] - '0') ); break; case 'x' : case 'u' : case 'U' : i = 2; switch( src[it] ){ case 'x' : m = 4; break; /* \xhh: max 2 hex digit; */ case 'u' : m = 6; break; /* \uhhhh: max 4 hex digit; */ case 'U' : m = 10; break; /* \Uhhhhhhhh: max 8 hex digit; */ } while( i < m && (it+1) < srcSize && isxdigit( src[it+1] ) ){ hex[i] = src[++it]; hex[++i] = 0; } DString_AppendWChar( literal, (wchar_t) strtol( hex, NULL, 0 ) ); break; case 't' : DString_AppendChar( literal, '\t' ); break; case 'n' : DString_AppendChar( literal, '\n' ); break; case 'r' : DString_AppendChar( literal, '\r' ); break; case '\'' : DString_AppendChar( literal, '\'' ); break; case '\"' : DString_AppendChar( literal, '\"' ); break; default : DString_AppendChar( literal, src[it] ); break; } }else if( ch == '\'' && state == TOK_STRING_MBS ){ DString_AppendChar( literal, ch ); state = TOK_RESTART; token->type = token->name = DTOK_MBS; DaoLexer_AppendToken( self, token ); DString_Clear( literal ); }else if( ch == '\"' && state == TOK_STRING_WCS ){ DString_AppendChar( literal, ch ); state = TOK_RESTART; token->type = token->name = DTOK_WCS; DaoLexer_AppendToken( self, token ); DString_Clear( literal ); }else{ DString_AppendChar( literal, ch ); } }else if( ch == ']' && state == TOK_VERBATIM ){ int len = srcSize - it - 1; DString_AppendChar( literal, ']' ); token->type = token->name = DTOK_VBT_OPEN; if( (ss = strstr( src + it + 1, literal->mbs )) != NULL ){ len = (ss - src) - it - 1 + literal->size; token->type = token->name = DTOK_VERBATIM; } for(i=0; i<len; i++) if( src[it+1+i] == '\n' ) line += 1; DString_AppendDataMBS( literal, src + it + 1, len ); state = TOK_RESTART; DaoLexer_AppendToken( self, token ); DString_Clear( literal ); it += len; }else if( lexenv == LEX_ENV_NORMAL ){ old = state; if( ch >=0 ){ state = daoLexTable[ state ][ (int)ch ]; }else if( state <= TOK_START ){ state = TOK_RESTART; }else if( state != TOK_IDENTIFIER && state != TOK_STRING_MBS && state != TOK_STRING_WCS && state != TOK_COMT_LINE && state != TOK_COMT_OPEN ){ state = TOK_RESTART; } if( state >= TOK_END ){ DString_AppendChar( literal, ch ); token->type = token->name = daoTokenMap[ state ]; if( token->type == DTOK_ID_THTYPE || token->type == DTOK_ID_SYMBOL ) token->type = DTOK_IDENTIFIER; if( space || comment || token->type != DTOK_COMMENT ){ if( isspace( token->string.mbs[0] ) ) token->type = token->name = daoSpaceType[ (int)token->string.mbs[0] ]; DaoLexer_AppendToken( self, token ); } /* may be a token before the line break; */ DString_Clear( literal ); state = TOK_START; }else if( state == TOK_RESTART ){ if( literal->size ){ if( old == TOK_IDENTIFIER ){ token->name = dao_key_hash( literal->mbs, literal->size ); token->type = DTOK_IDENTIFIER; if( token->name == 0 ) token->name = DTOK_IDENTIFIER; DaoLexer_AppendToken( self, token ); }else if( old > TOK_RESTART && old != TOK_END ){ token->type = token->name = daoTokenMap[ old ]; if( token->type == DTOK_ID_THTYPE || token->type == DTOK_ID_SYMBOL ) token->type = DTOK_IDENTIFIER; DaoLexer_AppendToken( self, token ); }else if( space ){ if( isspace( token->string.mbs[0] ) ) token->type = token->name = daoSpaceType[ (int)token->string.mbs[0] ]; DaoLexer_AppendToken( self, token ); } DString_Clear( literal ); token->cpos = cpos; } DString_AppendChar( literal, ch ); if( ch >=0 ) state = daoLexTable[ TOK_START ][ (int)ch ]; else state = TOK_IDENTIFIER; }else if( state == TOK_COMT_OPEN ){ DString_AppendChar( literal, ch ); lexenv = LEX_ENV_COMMENT; DVector_PushInt( lexenvs, LEX_ENV_COMMENT ); }else{ DString_AppendChar( literal, ch ); } }else if( lexenv == LEX_ENV_COMMENT ){ DString_AppendChar( literal, ch ); if( ch == '#' ){ state = TOK_OP_SHARP; }else if( ch == '{' && state == TOK_OP_SHARP ){ state = TOK_COMT_OPEN; DVector_PushInt( lexenvs, LEX_ENV_COMMENT ); }else if( ch == '}' && state == TOK_OP_SHARP ){ state = TOK_COMT_CLOSE; DVector_Pop( lexenvs ); lexenv = lexenvs->data.ints[lexenvs->size-1]; if( lexenv != LEX_ENV_COMMENT ){ token->type = token->name = DTOK_COMMENT; if( comment ) DaoLexer_AppendToken( self, token ); DString_Clear( literal ); state = TOK_RESTART; } }else{ state = TOK_START; } } it ++; } if( literal->size ){ token->type = token->name = daoTokenMap[ state ]; if( lexenv == LEX_ENV_COMMENT ) token->type = token->name = DTOK_CMT_OPEN; switch( state ){ case TOK_STRING_MBS : token->type = token->name = DTOK_MBS_OPEN; break; case TOK_STRING_WCS : token->type = token->name = DTOK_WCS_OPEN; break; } if( token->type == DTOK_IDENTIFIER ){ token->name = dao_key_hash( literal->mbs, literal->size ); if( token->name == 0 ) token->name = DTOK_IDENTIFIER; }else if( token->type == DTOK_ID_THTYPE || token->type == DTOK_ID_SYMBOL ){ token->type = DTOK_IDENTIFIER; } if( token->type || space ){ if( isspace( token->string.mbs[0] ) ) token->type = token->name = daoSpaceType[ (int)token->string.mbs[0] ]; DaoLexer_AppendToken( self, token ); } } DaoToken_Delete( token ); DVector_Delete( lexenvs ); DString_Delete( source ); #if 0 for(i=0; i<self->tokens->size; i++){ DaoToken *tk = self->tokens->items.pToken[i]; printf( "%4i: %4i %4i , %4i, %s\n", i, tk->type, tk->name, tk->cpos, tk->string.mbs ); } #endif return ret ? line : 0; }
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 ); }
static void PreparePostData( DaoProcess *proc, DaoMap *httpPOSTS, DaoMap *httpPOST, DaoMap *httpFILE ) { DString *fname; DString *buffer = DString_New(); DaoValue *vk = (DaoValue*) DaoProcess_NewString( proc, NULL, 0 ); DaoValue *vv = (DaoValue*) DaoProcess_NewString( proc, NULL, 0 ); DString *key = DaoString_Get( DaoValue_CastString( vk ) ); DString *value = DaoString_Get( DaoValue_CastString( vv ) ); char *content_length = getenv( "CONTENT_LENGTH" ); char *content_type = getenv( "CONTENT_TYPE" ); const char *boundary; char postbuf[1024]; daoint postlen, boundarylen, len = 0; daoint pos, pos2, pos_rnrn, offset; if( content_length != NULL ) len = strtol( content_length, NULL, 10); if( len == 0 ) return; DString_SetSharing( buffer, 0 ); if( content_type == NULL || strstr( content_type, "multipart/form-data" ) == NULL ) { postlen = fread( postbuf, 1, sizeof(postbuf), stdin ); while( postlen ) { DString_AppendBytes( buffer, postbuf, postlen ); postlen = fread( postbuf, 1, sizeof(postbuf), stdin ); } ParseKeyValueString( proc, httpPOSTS, httpPOST, buffer->chars ); DString_Delete( buffer ); return; } boundary = strstr( content_type, "boundary=" ) + strlen( "boundary=" ); boundarylen = strlen( boundary ); fname = DString_New(); buffer->size = 0; for(;;) { postlen = fread( postbuf, 1, sizeof(postbuf), stdin ); if( postlen == 0 && buffer->size < boundarylen ) break; DString_AppendBytes( buffer, postbuf, postlen ); while( strstr( buffer->chars, "\r\n\r\n" ) == 0 && postlen != 0 ) { postlen = fread( postbuf, 1, sizeof(postbuf), stdin ); DString_AppendBytes( buffer, postbuf, postlen ); } //printf( "###############\n%s\n", buffer->chars ); key->size = 0; fname->size = 0; pos = DString_FindChars( buffer, "name=", 20 ); /* Skip: Content-Disposition: ; */ pos2 = DString_FindChar( buffer, '\"', pos+6 ); DString_SubString( buffer, key, pos + 6, pos2 - pos - 6 ); pos_rnrn = DString_FindChars( buffer, "\r\n\r\n", pos2 ); pos = DString_FindChars( buffer, "filename=", pos2 ); if( pos != DAO_NULLPOS && pos < pos_rnrn ) { daoint pos3 = DString_FindChar( buffer, '\"', pos+10 ); DString_SubString( buffer, fname, pos + 10, pos3 - pos - 10 ); } buffer->size -= pos_rnrn + 4; memmove( buffer->chars, buffer->chars + pos_rnrn + 4, buffer->size ); if( fname->size == 0 ) { offset = 0; while( (pos2 = DString_FindChars( buffer, boundary, offset )) == DAO_NULLPOS ) { offset = buffer->size - boundarylen; if( offset < 0 ) offset = 0; postlen = fread( postbuf, 1, sizeof(postbuf), stdin ); DString_AppendBytes( buffer, postbuf, postlen ); } DString_SubString( buffer, value, 0, pos2 - 4 ); /* \r\n-- */ DaoMap_Insert( httpPOST, (DaoValue*) vk, (DaoValue*) vv ); buffer->size -= pos2 + boundarylen; memmove( buffer->chars, buffer->chars + pos2 + boundarylen, buffer->size ); } else { DaoInteger isize = {DAO_INTEGER,0,0,0,0,0}; DaoFileStream *stream = _DaoFileStream_New(); DaoTuple *tuple = DaoTuple_New(3); FILE *file = tmpfile(); DaoString_Set( (DaoString*) vv, fname ); stream->file = file; stream->base.mode |= DAO_STREAM_READABLE|DAO_STREAM_WRITABLE; _DaoFileStream_InitCallbacks( stream ); DaoTuple_SetType( tuple, daox_type_namestream ); DaoTuple_SetItem( tuple, (DaoValue*) vv, 0 ); DaoTuple_SetItem( tuple, (DaoValue*) stream, 2 ); DaoMap_Insert( httpFILE, (DaoValue*) vk, (DaoValue*) tuple ); offset = 0; while( (pos2 = DString_FindChars( buffer, boundary, 0 )) == DAO_NULLPOS ) { offset = buffer->size - boundarylen; if( offset > 0 ) { isize.value += offset; fwrite( buffer->chars, 1, offset, file ); buffer->size -= offset; memmove( buffer->chars, buffer->chars + offset, buffer->size ); } postlen = fread( postbuf, 1, sizeof(postbuf), stdin ); DString_AppendBytes( buffer, postbuf, postlen ); } isize.value += pos2 - 4; fwrite( buffer->chars, 1, pos2 - 4, file ); /* \r\n-- */ buffer->size -= pos2 + boundarylen; memmove( buffer->chars, buffer->chars + pos2 + boundarylen, buffer->size ); rewind( file ); DaoTuple_SetItem( tuple, (DaoValue*) & isize, 1 ); } } DString_Delete( buffer ); }
void DaoProfiler_Report( DaoProfiler *self0, DaoStream *stream ) { DaoComplex com = {DAO_COMPLEX,0,0,0,1,{0.0,0.0}}; DaoxProfiler *self = (DaoxProfiler*) self0; DMap *summary = DMap_New( DAO_DATA_VALUE, 0 ); DMap *summary2 = DMap_New( DAO_DATA_VALUE, 0 ); DString *name1 = DString_New(); DString *name2 = DString_New(); DNode *it, *it2; int count, max = 20; char buf1[32]; char buf2[24]; char buf[120]; for(it=DMap_First(self->profile); it; it=DMap_Next(self->profile,it)){ DaoRoutine *callee = (DaoRoutine*) it->key.pValue; com.value = DaoProfiler_Sum( it->value.pMap ); com.value.real = - com.value.real; com.value.imag = - com.value.imag; DMap_Insert( summary, & com, it ); } DaoStream_WriteChars( stream, "\n" ); DaoStream_WriteChars( stream, delimiter ); DaoStream_WriteChars( stream, delimiter2 ); snprintf( buf, sizeof(buf), header_format, "Routine", "#Calls", "CPU Time" ); DaoStream_WriteChars( stream, buf ); DaoStream_WriteChars( stream, delimiter2 ); for(count=max,it=DMap_First(summary); it; it=DMap_Next(summary,it),--count){ DNode *it2 = (DNode*) it->value.pVoid; dao_complex data = it->key.pValue->xComplex.value; DaoRoutine *callee = (DaoRoutine*) it2->key.pValue; DaoRoutine_MakeName( callee, name1, 28, 10, 2 ); snprintf( buf, sizeof(buf), row_format, name1->chars, (int) -data.imag, -data.real ); DaoStream_WriteChars( stream, buf ); if( count == 0 ) break; } DaoStream_WriteChars( stream, "\n" ); DaoStream_WriteChars( stream, delimiter3 ); snprintf( buf, sizeof(buf), header_format2, "Routine", "Caller", "#Calls", "CPU Time" ); DaoStream_WriteChars( stream, buf ); DaoStream_WriteChars( stream, delimiter3 ); for(count=max,it=DMap_First(summary); it; it=DMap_Next(summary,it),--count){ DNode *it2 = (DNode*) it->value.pVoid; DaoRoutine *callee = (DaoRoutine*) it2->key.pValue; DMap *profile = it2->value.pMap; DaoRoutine_MakeName( callee, name1, 30, 0, 0 ); DMap_Reset( summary2 ); for(it2=DMap_First(profile); it2; it2=DMap_Next(profile,it2)){ DaoRoutine *caller = (DaoRoutine*) it2->key.pValue; DaoComplex *data = (DaoComplex*) it2->value.pValue; com.value.real = - data->value.real; com.value.imag = - data->value.imag; DMap_Insert( summary2, & com, caller ); } for(it2=DMap_First(summary2); it2; it2=DMap_Next(summary2,it2)){ DaoRoutine *caller = (DaoRoutine*) it2->value.pValue; dao_complex data = it2->key.pValue->xComplex.value; DString_Reset( name2, 0 ); if( caller ) DaoRoutine_MakeName( caller, name2, 22, 0, 0 ); snprintf( buf, sizeof(buf), row_format2, name1->chars, name2->chars, (int) -data.imag, -data.real ); DaoStream_WriteChars( stream, buf ); DString_Reset( name1, 0 ); } if( count == 0 ) break; } DString_Delete( name1 ); DString_Delete( name2 ); }
void STD_Debug( DaoProcess *proc, DaoValue *p[], int N ) { DaoUserHandler *handler = proc->vmSpace->userHandler; DaoRoutine *routine = proc->activeRoutine; DaoStream *stream = proc->vmSpace->stdioStream; DString *input; DArray *tokens; DMap *cycData; char *chs, *cmd; int i; if( ! (proc->vmSpace->options & DAO_OPTION_DEBUG ) ) return; input = DString_New(1); if( N > 0 && DaoValue_CastCstruct( p[0], dao_type_stream ) ){ stream = (DaoStream*)p[0]; p ++; N --; } if( N > 0 ){ Dao_AboutVars( proc->activeNamespace, p, N, input ); DaoStream_WriteString( stream, input ); DaoStream_WriteMBS( stream, "\n" ); DString_Delete( input ); return; } if( handler && handler->StdlibDebug ){ handler->StdlibDebug( handler, proc ); return; } tokens = DArray_New(D_STRING); cycData = DMap_New(0,0); while(1){ if( proc->vmSpace->ReadLine ){ chs = proc->vmSpace->ReadLine( "(debug) " ); if( chs ){ DString_SetMBS( input, chs ); DString_Trim( input ); if( input->size && proc->vmSpace->AddHistory ) proc->vmSpace->AddHistory( chs ); dao_free( chs ); } }else{ DaoStream_WriteMBS( stream, "(debug) " ); DaoStream_ReadLine( stream, input ); } if( input->size == 0 ) continue; SplitByWhiteSpaces( input->mbs, tokens ); if( tokens->size == 0 ) continue; cmd = tokens->items.pString[0]->mbs; if( strcmp( cmd, "q" ) == 0 || strcmp( cmd, "quit" ) == 0 ){ break; }else if( strcmp( cmd, "k" ) == 0 || strcmp( cmd, "kill" ) == 0 ){ proc->status = DAO_PROCESS_ABORTED; break; }else if( strcmp( cmd, "a" ) == 0 || strcmp( cmd, "about" ) == 0 ){ if( tokens->size > 1 ){ ushort_t reg = (ushort_t)strtod( tokens->items.pString[1]->mbs, 0 ); DaoType *tp = proc->activeTypes[ reg ]; DString_Clear( input ); Dao_AboutVar( proc->activeNamespace, proc->activeValues[reg], input ); DaoStream_WriteMBS( stream, "type: " ); if( tp ) DaoStream_WriteString( stream, tp->name ); else DaoStream_WriteMBS( stream, "?" ); DaoStream_WriteMBS( stream, ", value: " ); DaoStream_WriteString( stream, input ); DaoStream_WriteMBS( stream, "\n" ); } }else if( strcmp( cmd, "g" ) == 0 || strcmp( cmd, "goto" ) == 0 ){ if( tokens->size > 1 ){ int n = atoi( tokens->items.pString[1]->mbs ); int entry = proc->activeCode - proc->activeRoutine->body->vmCodes->data.codes; if( n < 0 ) n = entry - n; if( n >= routine->body->vmCodes->size ) n = routine->body->vmCodes->size -1; proc->topFrame->entry = n; proc->status = DAO_PROCESS_STACKED; return; } }else if( strcmp( cmd, "h" ) == 0 || strcmp( cmd, "help" ) == 0 ){ DaoStream_WriteMBS( stream, help ); }else if( strcmp( cmd, "l" ) == 0 || strcmp( cmd, "list" ) == 0 ){ DString *mbs = DString_New(1); int entry = proc->activeCode - proc->activeRoutine->body->vmCodes->data.codes; int start = entry - 10; int end = entry; if( tokens->size >1 ){ int dn = atoi( tokens->items.pString[1]->mbs ); if( dn < 0 ){ start = entry + dn; }else if( dn > 0 ){ start = entry; end = entry + dn; } } if( start < 0 ) start = 0; if( end >= routine->body->vmCodes->size ) end = routine->body->vmCodes->size - 1; DaoStream_WriteString( stream, routine->routName ); DaoStream_WriteMBS( stream, "(): " ); if( routine->routType ) DaoStream_WriteString( stream, routine->routType->name ); DaoStream_WriteMBS( stream, "\n" ); DaoStream_WriteMBS( stream, daoRoutineCodeHeader ); DaoStream_WriteMBS( stream, sep ); for( i=start; i<=end; i++ ){ DaoRoutine_FormatCode( routine, i, *routine->body->annotCodes->items.pVmc[i], mbs ); DaoStream_WriteString( stream, mbs ); } DString_Delete( mbs ); }else if( strcmp( cmd, "p" ) == 0 || strcmp( cmd, "print" ) == 0 ){ if( tokens->size > 1 ){ ushort_t reg = (ushort_t)atoi( tokens->items.pString[1]->mbs ); DaoValue_Print( proc->activeValues[reg], proc, stream, cycData ); DaoStream_WriteMBS( stream, "\n" ); } }else if( strcmp( cmd, "t" ) == 0 || strcmp( cmd, "trace" ) == 0 ){ int depth = 1; if( tokens->size >1 ) depth = atoi( tokens->items.pString[1]->mbs ); DaoProcess_Trace( proc, depth ); }else{ DaoStream_WriteMBS( stream, "Unknown debugging command.\n" ); } } DString_Delete( input ); DArray_Delete( tokens ); }