static void ParseKeyValueStringArray( DaoProcess *proc, DaoMap *map, char **p ) { int nc = 0; char buffer[ LOCAL_BUF_SIZE + 1 ]; 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 ) ); while( *p != NULL ) { char *c = *p; nc = 0; while( *c != '=' ) { if( nc >= LOCAL_BUF_SIZE ) { buffer[ nc ] = 0; DString_AppendChars( key, buffer ); nc = 0; } buffer[ nc ] = *c; nc ++; c ++; } buffer[ nc ] = 0; DString_AppendChars( key, buffer ); c ++; DString_AppendChars( value, c ); DaoMap_Insert( map, vk, vv ); DString_Clear( key ); DString_Clear( value ); p ++; } }
static void SYS_EnvVars( DaoProcess *proc, DaoValue *p[], int N ) { #define LOCAL_BUF_SIZE 256 DaoMap *map = DaoProcess_PutMap( proc, 0 ); 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 ) ); char **envs = environ; char buffer[ LOCAL_BUF_SIZE + 1 ]; int nc = 0; while( *envs != NULL ){ char *c = *envs; nc = 0; while( *c != '=' ){ if( nc >= LOCAL_BUF_SIZE ){ buffer[ nc ] = 0; DString_AppendMBS( key, buffer ); nc = 0; } buffer[ nc ] = *c; nc ++; c ++; } buffer[ nc ] = 0; DString_AppendMBS( key, buffer ); c ++; DString_AppendMBS( value, c ); DaoMap_Insert( map, vk, vv ); DString_Clear( key ); DString_Clear( value ); envs ++; } }
static void Dao_ParseTarget( DString *target, DList *parts, DaoValue *sval ) { DString *tmp = sval->xString.value; DaoInteger ival = {DAO_INTEGER,0,0,0,0,0}; daoint i, n = DString_Size( target ); int ch, ch2; DString_Clear( tmp ); for(i=0; i<n; i++){ ch = target->chars[i]; ch2 = target->chars[i+1]; if( ch == '%' && isdigit( ch2 ) ){ DList_PushBack( parts, sval ); DString_Clear( tmp ); ival.value = ch2 - '0'; DList_PushBack( parts, (DaoValue*) & ival ); i ++; }else if( ch == '%' ){ if( i+1 < n ){ DString_AppendChar( tmp, (char)ch2 ); } i ++; }else{ DString_AppendChar( tmp, (char)ch ); } } DList_PushBack( parts, sval ); }
void DaoxDataColumn_Reset( DaoxDataColumn *self, daoint size ) { daoint i, datatype = DaoType_GetDataType( self->type ); if( size < self->cells->size ){ for(i=size; i<self->cells->size; ++i){ if( datatype == DAO_STRING ){ DString_Clear( self->cells->data.strings + i ); }else if( datatype == 0 ){ GC_DecRC( self->cells->data.values[i] ); } } DVector_Reset( self->cells, size ); }else if( size > self->cells->size ){ DVector_Reserve( self->cells, size ); for(i=self->cells->size; i<size; ++i){ if( datatype == DAO_STRING ){ DString_Init( self->cells->data.strings + i, 0 ); DString *s = & self->cells->data.strings[i]; }else if( datatype == 0 ){ self->cells->data.values[i] = NULL; } } DVector_Reset( self->cells, size ); } }
static void DaoIO_GetString( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *self = & p[0]->xStream; DString *res = DaoProcess_PutMBString( proc, "" ); DString_Assign( res, self->streamString ); DString_Clear( self->streamString ); }
void DString_SetBytes( DString *self, const char *bytes, daoint count ) { if( count < 0 ){ DString_SetChars( self, bytes ); }else{ DString_Clear( self ); DString_AppendBytes( self, bytes, count ); } }
static void Dao_AboutVars( DaoNamespace *ns, DaoValue *par[], int N, DString *str ) { int i; DString_Clear( str ); for( i=0; i<N; i++ ){ Dao_AboutVar( ns, par[i], str ); if( i+1<N ) DString_AppendMBS( str, " " ); } }
void DString_SetChars( DString *self, const char *chs ) { if( self->chars && self->chars == chs ) return; if( chs == NULL ){ DString_Clear( self ); return; } DString_Reset( self, strlen( chs ) ); memcpy( self->chars, chs, self->size*sizeof(char) ); }
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; }
void DaoLexer_Reset( DaoLexer *self ) { daoint i; for(i=0; i<self->tokens->size; ++i){ /* No copying of tokens: */ DaoToken *token = self->tokens->items.pToken[i]; if( token->string.size > 64 ) DString_Clear( & token->string ); DArray_Append( self->tokbuf, token ); } self->tokens->size = 0; }
static void Dao_AboutVars( DaoProcess *proc, DaoValue *par[], int N, DString *str ) { DaoVmCode *vmc = proc->activeCode; DaoType **types = proc->activeTypes + vmc->a + 1; int i; DString_Clear( str ); if( vmc->code == DVM_MCALL ) types += 1; for( i=0; i<N; i++ ){ Dao_AboutVar( proc, types[i], par[i], str ); if( i+1<N ) DString_AppendChars( str, " " ); } }
int DaoRegex_ChangeExt( DaoRegex *self, DString *input, DString *output, DString *target, int index, daoint *start2, daoint *end2 ) { daoint start = start2 ? (daoint) *start2 : 0; daoint end = end2 ? (daoint) *end2 : 0; daoint i, n=0, p1=start, p2=end, p3, last; DaoValue *value = NULL; DaoString matched = {DAO_STRING,0,0,0,0,NULL}; DList *array = DList_New( DAO_DATA_VALUE ); DString *tmp = DString_New(); DString *tmp2 = DString_New(); DString_Reset( output, 0 ); if( self == NULL || input->size == 0 ) goto DoNothing; matched.value = tmp; Dao_ParseTarget( target, array, (DaoValue*) & matched ); if( end == 0 ) end = p2 = DString_Size( input ); n = last = 0; while( DaoRegex_Match( self, input, & p1, & p2 ) ){ n += 1; if( index ==0 || n == index ){ DString_SubString( input, tmp2, last, p1 - last ); DString_Append( output, tmp2 ); DString_Clear( tmp ); for(i=0; i<array->size; i++){ value = array->items.pValue[i]; if( value->type == DAO_INTEGER ){ if( DaoRegex_SubMatch( self, value->xInteger.value, & p1, & p3 ) ){ DString_SubString( input, tmp2, p1, p3 - p1 ); DString_Append( tmp, tmp2 ); } }else{ DString_Append( tmp, value->xString.value ); } } DString_Append( output, tmp ); last = p2; } if( start2 ) *start2 = p1; if( end2 ) *end2 = p2; p1 = p2; p2 = end; if( index && n == index ) break; } DString_SubString( input, tmp2, last, end - last ); DString_Append( output, tmp2 ); DoNothing: DString_Delete( tmp ); DString_Delete( tmp2 ); DList_Delete( array ); return n; }
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; }
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 ? '\'' : '\"' ); }
void DaoXmlDOM_CacheNode( DaoXmlDOM *self, DaoXmlNode *node ) { daoint i; for(i=0; i<node->children->size; ++i){ DaoXmlDOM_CacheNode( self, (DaoXmlNode*) node->children->items.pVoid[i] ); } node->id = 0; node->parent = NULL; node->data = NULL; node->children->size = 0; node->name->size = 0; /* Most nodes will have empty contents, and some may have long contents, // so it is better to clear the string: */ DString_Clear( node->content ); DMap_Reset( node->attributes ); DList_Append( self->caches, node ); }
DString* DaoValue_GetString( DaoValue *self, DString *str ) { char chs[100] = {0}; DString_Clear( str ); switch( self->type ){ case DAO_INTEGER : sprintf( chs, "%" DAO_INT_FORMAT, self->xInteger.value ); break; case DAO_FLOAT : sprintf( chs, "%g", self->xFloat.value ); break; case DAO_DOUBLE : sprintf( chs, "%g", self->xDouble.value ); break; case DAO_COMPLEX : sprintf( chs, (self->xComplex.value.imag < 0) ? "%g%gC" : "%g+%gC", self->xComplex.value.real, self->xComplex.value.imag ); break; #ifdef DAO_WITH_LONGINT case DAO_LONG : DLong_Print( self->xLong.value, str ); break; #endif case DAO_ENUM : DaoEnum_MakeName( & self->xEnum, str ); break; case DAO_STRING : DString_Assign( str, self->xString.data ); break; default : break; } if( self->type <= DAO_COMPLEX ) DString_SetMBS( str, chs ); return str; }
DString* DaoValue_GetString( DaoValue *self, DString *str ) { dao_complex *com; char chs[100] = {0}; DString_Clear( str ); switch( self->type ){ case DAO_COMPLEX : com = & self->xComplex.value; sprintf( chs, (com->imag < 0) ? "%g%gC" : "%g+%gC", com->real, com->imag ); break; case DAO_BOOLEAN : strcat( chs, self->xBoolean.value ? "true" : "false" ); break; case DAO_INTEGER : sprintf( chs, "%"DAO_I64, (long long) self->xInteger.value ); break; case DAO_FLOAT : sprintf( chs, "%g", self->xFloat.value ); break; case DAO_STRING : DString_Assign( str, self->xString.value ); break; case DAO_ENUM : DaoEnum_MakeName( & self->xEnum, str ); break; default : break; } if( self->type <= DAO_COMPLEX ) DString_SetChars( str, chs ); return str; }
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 void DaoIO_Read( DaoProcess *proc, DaoValue *p[], int N ) { DaoStream *self = proc->stdioStream; DString *ds = DaoProcess_PutMBString( proc, "" ); int count = 0; if( self == NULL ) self = proc->vmSpace->stdioStream; if( N >0 ) self = & p[0]->xStream; if( N >1 ) count = p[1]->xInteger.value; if( (self->attribs & (DAO_IO_FILE | DAO_IO_PIPE)) && self->file == NULL ){ DaoProcess_RaiseException( proc, DAO_ERROR, "stream is not open!" ); return; } if( ( self->mode & DAO_IO_READ ) == 0 ){ DaoProcess_RaiseException( proc, DAO_ERROR, "stream is not readable" ); return; } if( self->file == NULL && self->redirect && self->redirect->StdioRead ){ self->redirect->StdioRead( self->redirect, ds, count ); }else if( count ){ FILE *fd = stdin; DString_Clear( ds ); if( self->file ) fd = self->file; if( count >0 ){ DString_Resize( ds, count ); DString_Resize( ds, fread( ds->mbs, 1, count, fd ) ); }else{ struct stat info; fstat( fileno( fd ), &info ); DString_Resize( ds, info.st_size - ftell( fd )/2 ); DString_Resize( ds, fread( ds->mbs, 1, ds->size, fd ) ); } if( fd == stdin ) fseek( stdin, 0, SEEK_END ); }else{ DaoStream_ReadLine( self, ds ); } }
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 ); }
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; }
void DaoLexer_AnnotateCode( DArray *self, DaoVmCodeX vmc, DString *annot, int max ) { DaoToken *t1, *t2, **tokens; daoint i, k, len, pos, m = max/(vmc.middle + vmc.last + 2); int max2 = max/2; if( m < 5 ) m = 5; DString_Clear( annot ); if( self == NULL ) return; /* DaoRoutine::source could be null */ if( vmc.middle > vmc.last ) return; tokens = self->items.pToken; for(i=0; i<vmc.middle; i++){ k = i + vmc.first; if( k >= self->size ) break; t2 = tokens[k]; if( k != (daoint)vmc.first ){ t1 = tokens[k-1]; pos = t1->cpos + t1->string.size; if( t1->line != t2->line || pos < t2->cpos ) DString_AppendChar( annot, ' ' ); } len = t2->string.size; if( t2->type == DTOK_IDENTIFIER ){ if( len > max2 ) len = max2 - 3; }else{ if( len > m+3 ) len = m; } if( annot->size + len >= max2 ) len = max2 - annot->size; DString_AppendDataMBS( annot, t2->string.mbs, len ); if( len != t2->string.size ){ DString_AppendMBS( annot, "..." ); if( t2->type == DTOK_MBS ) DString_AppendChar( annot, '\'' ); else if( t2->type == DTOK_WCS ) DString_AppendChar( annot, '\"' ); else break; } if( (i+1) < vmc.middle && annot->size >= max2 ){ DString_AppendMBS( annot, "..." ); break; } } for(i=vmc.middle; i<=vmc.last; i++){ k = i + vmc.first; if( k >= self->size ) break; t2 = tokens[k]; if( k != (daoint)vmc.first ){ t1 = tokens[k-1]; pos = t1->cpos + t1->string.size; if( t1->line != t2->line || pos < t2->cpos ) DString_AppendChar( annot, ' ' ); } len = t2->string.size; if( t2->type == DTOK_IDENTIFIER ){ if( len > max2 ) len = max2-3; }else{ if( len > m+3 ) len = m; } if( annot->size + len >= max ) len = max - annot->size; DString_AppendDataMBS( annot, t2->string.mbs, len ); if( len != t2->string.size ){ DString_AppendMBS( annot, "..." ); if( t2->type == DTOK_MBS ) DString_AppendChar( annot, '\'' ); else if( t2->type == DTOK_WCS ) DString_AppendChar( annot, '\"' ); else break; } if( i < vmc.last && annot->size >= max ){ DString_AppendMBS( annot, "..." ); break; } } DString_ChangeMBS( annot, "{{\n}}", "\\n", 0 ); }
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 ); }
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 ParseKeyValueString( DaoProcess *proc, DaoMap *mulmap, DaoMap *map, const char *s ) { int i = 0; int nc = 0; int len = 0; char buffer[ LOCAL_BUF_SIZE + 1 ]; 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 ) ); len = strlen( s ); nc = 0; int isKey = 1; char tmp[3]; tmp[2] = 0; for(i=0; i<len; i++){ if( s[i] == '=' ){ buffer[nc] = 0; DString_AppendMBS( key, buffer ); nc = 0; isKey = 0; }else if( s[i] == '&' || s[i] == ';' || i+1==len ){ if( i+1 == len ){ buffer[ nc ] = s[i]; nc ++; } if( DString_Size( key ) > 0 ){ buffer[ nc ] = 0; DString_AppendMBS( value, buffer ); InsertKeyValue( proc, mulmap, map, vk, vv ); DString_Clear( key ); DString_Clear( value ); nc = 0; isKey = 1; }else if( nc > 0 ){ buffer[ nc ] = 0; DString_AppendMBS( key, buffer ); DString_SetMBS( value, "NULL" ); InsertKeyValue( proc, mulmap, map, vk, vv ); DString_Clear( key ); DString_Clear( value ); nc = 0; isKey = 1; } }else if( s[i] != ' ' ){ if( nc >= LOCAL_BUF_SIZE ){ buffer[ nc ] = 0; if( isKey ){ DString_AppendMBS( key, buffer ); }else{ DString_AppendMBS( value, buffer ); } nc = 0; } if( s[i] == '%' ){ tmp[0] = s[i+1]; tmp[1] = s[i+2]; buffer[ nc ] = strtol( tmp, NULL, 16 ); i += 2; }else if( s[i] == '+' ){ buffer[ nc ] = ' '; }else{ buffer[ nc ] = s[i]; } nc ++; } } if( DString_Size( key ) > 0 ){ buffer[ nc ] = 0; DString_AppendMBS( value, buffer ); InsertKeyValue( proc, mulmap, map, vk, vv ); }else if( nc > 0 ){ buffer[ nc ] = 0; DString_AppendMBS( key, buffer ); DString_SetMBS( value, "NULL" ); InsertKeyValue( proc, mulmap, map, vk, vv ); } }