Exemplo n.º 1
0
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 ++;
    }
}
Exemplo n.º 2
0
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 ++;
	}
}
Exemplo n.º 3
0
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 );
}
Exemplo n.º 4
0
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 );
	}
}
Exemplo n.º 5
0
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 );
}
Exemplo n.º 6
0
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 );
	}
}
Exemplo n.º 7
0
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, " " );
	}
}
Exemplo n.º 8
0
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) );
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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, " " );
	}
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
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 ? '\'' : '\"' );
}
Exemplo n.º 15
0
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 );
}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
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 );
}
Exemplo n.º 19
0
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 );
	}
}
Exemplo n.º 20
0
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 );
}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
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 );
}
Exemplo n.º 23
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 );
}
Exemplo n.º 24
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 );
}
Exemplo n.º 25
0
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 );
	}
}