void DaoProcess_Trace( DaoProcess *self, int depth ) { DaoStream *stream = self->vmSpace->stdioStream; DaoStackFrame *frame = self->topFrame; int k, i = 0; while( frame && frame->routine ){ DaoRoutine *routine = frame->routine; if( depth && ++i > depth ) break; DaoStream_SetColor( stream, "white", "green" ); DaoStream_WriteString( stream, routine->routName ); DaoStream_WriteChars( stream, "()" ); DaoStream_SetColor( stream, NULL, NULL ); DaoStream_WriteChars( stream, ": " ); DaoStream_SetColor( stream, "green", NULL ); if( routine->routType ) DaoStream_WriteString( stream, routine->routType->name ); DaoStream_SetColor( stream, NULL, NULL ); if( frame->routine->body ){ k = (i==1) ? (int)( self->activeCode - frame->codes ) : frame->entry; if( k >= 0 && k < frame->routine->body->annotCodes->size ){ DaoStream_WriteChars( stream, ", instruction " ); DaoStream_WriteInt( stream, k ); DaoStream_WriteChars( stream, " at line " ); DaoStream_WriteInt( stream, frame->routine->body->annotCodes->items.pVmc[k]->line ); } } DaoStream_WriteChars( stream, " in " ); DaoStream_WriteString( stream, routine->nameSpace->name ); DaoStream_WriteChars( stream, ";" ); DaoStream_WriteNewLine( stream ); frame = frame->prev; } }
void DaoStream_TryHighlight( DaoStream *self, int tag ) { const char *color = NULL; if( ! (self->mode & DAO_STREAM_HIGHLIGHT) ) return; if( tag == 0 ){ DaoStream_SetColor( self, NULL, NULL ); return; } switch( tag ){ case '"' : color = "red"; break; case '0' : color = "red"; break; case 'A' : color = "green"; break; case '.' : color = "green"; break; case '(' : case ')' : color = "blue"; break; case '[' : case ']' : color = "blue"; break; case '{' : case '}' : color = "blue"; break; case ',' : color = "magenta"; break; case ';' : color = "magenta"; break; case ':' : color = "cyan"; break; default: break; } DaoStream_SetColor( self, color, NULL ); }
/* // 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 ); }
/* // C printf format: %[parameter][flags][width][.precision][length]type // // Dao writef format: %[flags][width][.precision]type[color] // // Where 'flags', 'width' and 'precision' will conform to the C format, // but 'type' can only be: // d, i, o, u, x/X : for integer; // e/E, f/F, g/G : for float and double; // c/C : for character, C for local encoding; // s/S : for string, S for local encoding; // p : for any type, write address; // a : automatic, for any type, write in the default format; // Namely the standard ones except '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; DString *fmt2; DString *fgcolor = NULL; DString *bgcolor = NULL; DMap *cycmap = NULL; const char *convs = "asSpcCdiouxXfFeEgG"; char F, *s, *end, *fg, *bg, *fmt, message[100]; int i, k, id = 0; if( DaoIO_CheckMode( self, proc, DAO_STREAM_WRITABLE ) == 0 ) return; fmt2 = DString_New(); for(i=0; i<N; i++){ if( p[i]->type > DAO_ARRAY ){ cycmap = DHash_New(0,0); break; } } s = p[0]->xString.value->chars; end = s + p[0]->xString.value->size; for(; s<end; s++){ if( *s != '%' ){ DaoStream_WriteChar( self, *s ); continue; } fmt = s; s += 1; if( *s =='%' || *s == '[' ){ DaoStream_WriteChar( self, *s ); continue; } if( ++id >= N || p[id] == NULL ) goto NullParameter; value = p[id]; /* 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_SetBytes( fmt2, fmt, s - fmt + 1 ); if( strchr( convs, *s ) == NULL ){ DaoProcess_RaiseWarning( proc, NULL, "invalid format conversion" ); continue; } F = *s; s += 1; fg = bg = NULL; if( *s == '[' ){ s += 1; fmt = s; while( isalnum( *s ) ) s += 1; if( fgcolor == NULL ) fgcolor = DString_New(); DString_SetBytes( fgcolor, fmt, s - fmt ); if( fgcolor->size ) fg = fgcolor->chars; if( *s == ':' ){ s += 1; fmt = s; while( isalnum( *s ) ) s += 1; if( bgcolor == NULL ) bgcolor = DString_New(); DString_SetBytes( bgcolor, fmt, s - fmt ); if( bgcolor->size ) bg = bgcolor->chars; } if( *s != ']' ) goto WrongColor; }else{ s -= 1; } if( fg || bg ){ if( DaoStream_SetColor( self, fg, bg ) == 0 ) goto WrongColor; } self->format = fmt2->chars; if( F == 'c' || F == 'C' ){ if( value->type != DAO_INTEGER ) goto WrongParameter; DString_Reset( fmt2, 0 ); DString_AppendWChar( fmt2, value->xInteger.value ); self->format = "%s"; if( F == 'C' ) DString_ToLocal( fmt2 ); DaoStream_WriteString( self, fmt2 ); }else if( F == 'd' || F == 'i' || F == 'o' || F == 'x' || F == 'X' ){ if( value->type == DAO_NONE || value->type > DAO_FLOAT ) goto WrongParameter; DString_InsertChars( fmt2, "ll", fmt2->size-1, 0, 2 ); self->format = fmt2->chars; DaoStream_WriteInt( self, DaoValue_GetInteger( value ) ); }else if( toupper( F ) == 'E' || toupper( F ) == 'F' || toupper( F ) == 'G' ){ if( value->type == DAO_NONE || value->type > DAO_FLOAT ) goto WrongParameter; DaoStream_WriteFloat( self, DaoValue_GetFloat( value ) ); }else if( F == 's' && value->type == DAO_STRING ){ DaoStream_WriteString( self, value->xString.value ); }else if( F == 'S' && value->type == DAO_STRING ){ DaoStream_WriteLocalString( self, value->xString.value ); }else if( F == 'p' ){ DaoStream_WritePointer( self, value ); }else if( F == 'a' ){ self->format = NULL; if( value->type > DAO_ARRAY ) DMap_Reset( cycmap ); DaoValue_Print( value, self, cycmap, proc ); }else{ goto WrongParameter; } self->format = NULL; if( fg || bg ) DaoStream_SetColor( self, NULL, NULL ); continue; NullParameter: sprintf( message, "%i-th parameter is null!", id ); DaoProcess_RaiseWarning( proc, NULL, message ); continue; WrongColor: sprintf( message, "%i-th parameter has wrong color format!", id ); DaoProcess_RaiseWarning( proc, NULL, message ); continue; WrongParameter: self->format = NULL; if( fg || bg ) DaoStream_SetColor( self, NULL, NULL ); sprintf( message, "%i-th parameter has wrong type for format \"%s\"!", id, fmt2->chars ); DaoProcess_RaiseWarning( proc, NULL, message ); } if( cycmap ) DMap_Delete( cycmap ); if( fgcolor ) DString_Delete( fgcolor ); if( bgcolor ) DString_Delete( bgcolor ); DString_Delete( fmt2 ); }