コード例 #1
0
ファイル: daoClass.c プロジェクト: wherby/dao
void DaoClass_SetName( DaoClass *self, DString *name, DaoNamespace *ns )
{
	DaoRoutine *rout;
	DString *str;

	if( self->classRoutine ) return;

	self->inter = DaoInterface_New( ns, name->mbs );
	DString_SetMBS( self->inter->abtype->name, "interface<" );
	DString_Append( self->inter->abtype->name, name );
	DString_AppendChar( self->inter->abtype->name, '>' );
	DaoClass_AddReference( self, self->inter );

	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->classRoutines = DaoRoutines_New( ns, self->objType, NULL );
	DString_Assign( self->classRoutines->routName, name );

	DaoClass_AddConst( self, rout->routName, (DaoValue*)self->classRoutines, DAO_DATA_PUBLIC );

	self->objType->value = (DaoValue*) DaoObject_Allocate( self, 0 );
	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 );

	DString_Delete( str );
}
コード例 #2
0
ファイル: daoMacro.c プロジェクト: sanyaade-teachings/dao
static int DaoParser_FindPair( DaoParser *self,  const char *lw, const char *rw, int start, int to )
{
	DaoToken **tokens = self->tokens->items.pToken;
	int i, k = 0;
	int found = 0;

	if( start < 0 ) goto ErrorUnPaired;
	if( to < 0 ) to = self->tokens->size - 1;
	for(i=start; i<=to; ++i){
		if( strcmp( lw, tokens[i]->string.mbs ) == 0 ){
			k++;
		}else if( strcmp( rw, tokens[i]->string.mbs ) == 0 ){
			k--;
			found = 1;
		}
		if( k == 0 && found ) return i;
	}
ErrorUnPaired:
	if( self->vmSpace ){
		DString_SetMBS( self->mbs, lw );
		if( k ==0 ){
			DaoParser_Error( self, DAO_TOKEN_NOT_FOUND, self->mbs );
		}else{
			DString_AppendChar( self->mbs, ' ' );
			DString_AppendMBS( self->mbs, rw );
			DaoParser_Error( self, DAO_TOKENS_NOT_PAIRED, self->mbs );
		}
	}
	return -100;
}
コード例 #3
0
ファイル: daoStream.c プロジェクト: wherby/dao
void DaoStream_WriteFloat( DaoStream *self, double val )
{
	const char *format = self->format;
	const char *iconvs = "diouxXcC";
	char buffer[100];
	if( format && strchr( iconvs, format[ strlen(format)-1 ] ) && val ==(long)val ){
		DaoStream_WriteInt( self, (daoint)val );
		return;
	}
	if( format == NULL ) format = "%f";
	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 );
	}
}
コード例 #4
0
ファイル: daoLexer.c プロジェクト: hooloong/dao
void DaoToken_Set( DaoToken *self, int type, int name, int index, const char *s )
{
	if( name == DTOK_ID_THTYPE || name == DTOK_ID_SYMBOL ) type = DTOK_IDENTIFIER;
	self->type = type;
	self->name = name;
	self->index = index;
	if( s ) DString_SetMBS( & self->string, s );
}
コード例 #5
0
ファイル: fake_list.cpp プロジェクト: DawidvC/dao
int main( int argc, char *argv[] )
{
  DString *src;
  DaoVmSpace *vms;
  DaoNameSpace *ns;
  DaoVmProcess *vmp;

  // Search and load the Dao library.
  // DaoInitLibrary() can take a parameter which is the path
  // to the dynamic loading file of the Dao library.
  // If the parameter is NULL, the current path is searched,
  // then the path defined by environment variable DAO_DIR,
  // then $(HOME)/dao, and then the default system path:
  // /usr/local/dao/ or C:\dao\.
  //
  // With direct APIs, the example must be linked against the Dao library.
  // So if direct APIs are used, the following call is not necessary.
#ifndef DAO_DIRECT_API
  if( DaoInitLibrary( NULL ) ==0 ) return 1;
#endif

  // Initialize Dao library, and get the default DaoVmSpace object.
  // DaoVmSpace is responsible for handling interpreter settings,
  // paths and module loading etc. It is need to create several
  // other types of objects.
  vms = DaoInit();

  // Get the main namespace of an DaoVmSpace object.
  // You can also call DaoNameSpace_New( vms ) to create one.
  ns  = DaoVmSpace_MainNameSpace( vms );

  // Get the main virtual machine process of an DaoVmSpace object.
  // You can also call DaoVmProcess_New( vms ) to create one.
  vmp = DaoVmSpace_MainVmProcess( vms );

  // Prepare the Dao source codes:
  src = DString_New(1);
  DString_SetMBS( src, dao_source );

  // Wrap and setup a C/C++ type:
  DaoNameSpace_WrapType( ns, dao_FakeList_Typer );

  // Execute the Dao scripts:
  // Since the wrapped functions and types are imported into
  // namespace ns, it is need to access the wrapped functions and types
  // in the Dao scripts when it is executed:
  DaoVmProcess_Eval( vmp, ns, src, 1 );

  DString_Delete( src );
  DaoQuit(); // Finalizing
  return 0;
}
コード例 #6
0
ファイル: daoStream.c プロジェクト: wherby/dao
void DaoStream_WriteMBS( DaoStream *self, const char *val )
{
	const char *format = self->format;
	if( format == NULL ) format = "%s";
	if( self->redirect && self->redirect->StdioWrite ){
		DString *mbs = DString_New(1);
		DString_SetMBS( 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_AppendMBS( self->streamString, val );
	}else{
		printf( format, val );
	}
}
コード例 #7
0
ファイル: daoStream.c プロジェクト: wherby/dao
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 );
	}
}
コード例 #8
0
ファイル: daoClass.c プロジェクト: wherby/dao
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 );
}
コード例 #9
0
ファイル: daoValue.c プロジェクト: wherby/dao
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;
}
コード例 #10
0
ファイル: daoClass.c プロジェクト: wherby/dao
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 );
}
コード例 #11
0
ファイル: dao_sys.c プロジェクト: sanyaade-teachings/dao
static int addStringFromMap( DaoValue *self, DString *S, DaoMap *sym, const char *key, int id )
{
	DNode *node;

	if( S==NULL || sym==NULL ) return 0;
	DString_SetMBS( self->xString.data, key );
	node = DMap_Find( sym->items, & self );
	if( node ){
		DaoList *list = & node->value.pValue->xList;
		if( list->type == DAO_LIST && list->items.size > id ){
			DaoValue *p = list->items.items.pValue[ id ];
			if( p->type == DAO_STRING ){
				DString_Append( S, p->xString.data );
				return 1;
			}
		}
	}
	return 0;
}
コード例 #12
0
ファイル: daoStream.c プロジェクト: wherby/dao
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 );
	}
}
コード例 #13
0
ファイル: daoStdlib.c プロジェクト: hooloong/dao
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;
	}
}
コード例 #14
0
ファイル: daoStdlib.c プロジェクト: hooloong/dao
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 );
}
コード例 #15
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 );
	}
}
コード例 #16
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 );
}
コード例 #17
0
ファイル: daoLexer.c プロジェクト: hooloong/dao
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;
}
コード例 #18
0
ファイル: daoMacro.c プロジェクト: hooloong/dao
static int DaoParser_MacroApply( DaoParser *self, DArray *tokens,
		DMacroGroup *group, DMap *tokMap, DMap *used,
		int level, DString *tag, int pos0, int adjust )
{
	DMacroUnit **units = (DMacroUnit**) group->units->items.pVoid;
	DMacroUnit  *unit;
	DMacroGroup *grp;
	DMacroNode *node, *node2;
	DArray *toks = DArray_New(D_TOKEN);
	DaoToken *tk = DaoToken_New();
	DaoToken *tt = NULL;
	DNode  *kwnode = NULL;
	DMap *check = NULL;
	DMap one = { NULL, 0, 0, 0 };
	int M, N = group->units->size;
	int i, j, gid = -1;
	int repeated = 0;
	int start_mbs = -1;
	int start_wcs = -1;
	int squote, dquote;

	if( group->repeat != DMACRO_AUTO ) level ++;

	for( i=0; i<N; i++ ){
		unit = units[i];
		if( tokens->size >0 ) pos0 = tokens->items.pToken[ tokens->size -1 ]->line;
		self->curLine = pos0;
		/*
		   printf( "apply unit %i: %i\n", i, unit->type );
		 */
		switch( unit->type ){
		case DMACRO_TOK :
			squote = unit->marker->type == DTOK_ESC_SQUO;
			dquote = unit->marker->type == DTOK_ESC_DQUO;
			if( (squote && start_mbs >=0) || (dquote && start_wcs >=0) ){
				int qstart = squote ? start_mbs : start_wcs;
				tt = tokens->items.pToken[ qstart ];
				for(j=qstart+1,M=tokens->size; j<M; j++){
					DaoToken *jtok = tokens->items.pToken[j];
					int t = j ? tokens->items.pToken[j-1]->type : 0;
					if( t == DTOK_IDENTIFIER && jtok->type == t )
						DString_AppendChar( & tt->string, ' ' );
					DString_Append( & tt->string, & jtok->string );
				}
				if( squote ){
					DString_AppendChar( & tt->string, '\'' );
					DArray_Erase( tokens, start_mbs+1, tokens->size );
				}else{
					DString_AppendChar( & tt->string, '\"' );
					DArray_Erase( tokens, start_wcs+1, tokens->size );
				}
				start_mbs = -1;
				break;
			}else if( squote ){
				start_mbs = tokens->size;
				DArray_Append( tokens, unit->marker );
				tt = tokens->items.pToken[ start_mbs ];
				tt->type = tt->name = DTOK_MBS;
				DString_SetMBS( & tt->string, "\'" );
				break;
			}else if( dquote ){
				start_wcs = tokens->size;
				DArray_Append( tokens, unit->marker );
				tt = tokens->items.pToken[ start_wcs ];
				tt->type = tt->name = DTOK_WCS;
				DString_SetMBS( & tt->string, "\"" );
				break;
			}
			DArray_Append( tokens, unit->marker );
			tokens->items.pToken[ tokens->size-1 ]->cpos += adjust;
			break;
		case DMACRO_VAR :
			DaoToken_Assign( tk, unit->marker );
			DString_Append( & tk->string, tag );
			DArray_Append( tokens, tk );
			break;
		case DMACRO_EXP :
		case DMACRO_ID :
		case DMACRO_OP :
		case DMACRO_BL :
		case DMACRO_IBL :

			kwnode = MAP_Find( tokMap, & unit->marker->string );
			if( kwnode ==NULL ){
				DaoParser_Error( self, DAO_CTW_UNDEF_MAC_MARKER, & unit->marker->string );
				goto Failed;
			}
			node = (DMacroNode*) kwnode->value.pVoid;
			kwnode = MAP_Find( used, unit );
			if( kwnode == NULL ){
				DMap_Insert( used, unit, & one );
				kwnode = MAP_Find( used, unit );
			}
			check = (DMap*) kwnode->value.pVoid;
			repeated = 1;

			/*
			   printf( ">>>\n%s level %i: \n", unit->marker->string.mbs, level );
			   DMacroNode_Print( node );
			   printf( "\n" );
			 */
			/* search a leaf */
			node2 = DMacroNode_FindLeaf( node, check, level );
			if( node2 ){
				/*
				   printf( "appending tokens\n" );
				   DMacroNode_Print( node2 );
				   printf( "\n" );
				 */
				DArray_InsertArray( tokens, tokens->size, node2->leaves, 0, -1 );
				DMap_Insert( check, node2, NULL );
				/* DArray_Clear( node2->leaves ); */
			}else{
				DMacroNode_RemoveEmptyLeftBranch( node, level );
				goto Failed;
			}
			break;
		case DMACRO_GRP :
		case DMACRO_ALT :
			grp = (DMacroGroup*) unit;
			DArray_Clear( toks );
			j = DaoParser_MacroApply( self, toks, grp, tokMap, used, level, tag, pos0, adjust );
			switch( grp->repeat ){
			case DMACRO_AUTO :
			case DMACRO_ONE :
				if( j <0 && group->type != DMACRO_ALT ) goto Failed;
				repeated = (j>0);
				if( j >=0 ){
					gid = i;
					DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
				}
				break;
			case DMACRO_ZERO_OR_ONE :
				gid = i;
				repeated = (j>0);
				if( j >=0 ){
					DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
				}
				break;
			case DMACRO_ZERO_OR_MORE :
				gid = i;
				repeated = (j>0);
				if( j >=0 ){
					DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
				}
				while( j >0 ){
					DArray_Clear( toks );
					j = DaoParser_MacroApply( self, toks, grp, tokMap, used, level, tag, pos0, adjust );
					if( j >0 ){
						DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
					}
				}
				break;
			case DMACRO_ONE_OR_MORE :
				if( j <0 && group->type != DMACRO_ALT ) goto Failed;
				repeated = (j>0);
				if( j >=0 ){
					DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
				}

				while( j >0 ){
					gid = i;
					DArray_Clear( toks );
					j = DaoParser_MacroApply( self, toks, grp, tokMap, used, level, tag, pos0, adjust );
					if( j >0 ){
						DArray_InsertArray( tokens, tokens->size, toks, 0, -1 );
					}
				}
				break;
			}
			break;
		default : goto Failed;
		}
		if( group->type == DMACRO_ALT && gid >=0 ) break;
	}
	if( group->repeat != DMACRO_AUTO ) level --;
	if( group->type == DMACRO_ALT && gid <0 ) goto Failed;
	DaoToken_Delete( tk );
	DArray_Delete( toks );
	return repeated;
Failed :
	DaoToken_Delete( tk );
	DArray_Delete( toks );
	return -1;
}
コード例 #19
0
ファイル: daoMacro.c プロジェクト: hooloong/dao
static int DaoParser_MakeMacroGroup( DaoParser *self,
		DMacroGroup *group, DMacroGroup *parent, int from, int to )
{
	DaoToken **toks = self->tokens->items.pToken;
	unsigned char tk;
	int i, sep, rb, prev;
	DMacroUnit *unit;
	DMacroGroup *grp, *group2; /* mingw don't like grp2 ?! */

	/*
	   for( i=from; i<to; i++ ) printf( "%s  ", toks[i]->mbs ); printf("\n");
	 */

	i = from;
	while( i < to ){
		char *chs = toks[i]->string.mbs;
		self->curLine = toks[i]->line;
		tk = toks[i]->name;
#if 0
		//printf( "%i %s\n", i, chs );
#endif
		if( tk == DTOK_ESC_LB || tk == DTOK_ESC_LSB || tk == DTOK_ESC_LCB ){
			grp = DMacroGroup_New();
			grp->cpos = toks[i]->cpos;
			grp->parent = parent;
			DArray_Append( group->units, (void*)grp );
			switch( tk ){
			case DTOK_ESC_LB :
				rb = DaoParser_FindPairToken( self, DTOK_ESC_LB, DTOK_ESC_RB, i, to );
				break;
			case DTOK_ESC_LSB :
				rb = DaoParser_FindPairToken( self, DTOK_ESC_LSB, DTOK_ESC_RSB, i, to );
				grp->repeat = DMACRO_ZERO_OR_ONE;
				break;
			case DTOK_ESC_LCB :
				rb = DaoParser_FindPairToken( self, DTOK_ESC_LCB, DTOK_ESC_RCB, i, to );
				grp->repeat = DMACRO_ZERO_OR_MORE;
				break;
			default :
				{
					rb = -1;
					DaoParser_Error( self, DAO_CTW_INV_MAC_OPEN, & toks[i]->string );
					break;
				}
			}
			if( rb <0 ) return 0;

			prev = i+1;
			sep = DaoParser_FindOpenToken( self, DTOK_ESC_PIPE, i+1, rb, 0 );
			if( sep >=0 ){
				while( sep >=0 ){
					group2 = DMacroGroup_New();
					group2->parent = grp;
					if( DaoParser_MakeMacroGroup( self, group2, group2, prev, sep ) == 0 )
						return 0;
					DArray_Append( grp->units, (void*)group2 );
					prev = sep +1;
					sep = DaoParser_FindOpenToken( self, DTOK_ESC_PIPE, prev, rb, 0 );
					if( prev < rb && sep <0 ) sep = rb;
				}
				grp->type = DMACRO_ALT;
			}else if( DaoParser_MakeMacroGroup( self, grp, grp, i+1, rb ) == 0 ){
				return 0;
			}
			i = rb +1;
			self->curLine = toks[i]->line;
			if( toks[i]->string.mbs[0] == '\\' ){
				switch( toks[i]->name ){
				case DTOK_ESC_EXCLA : grp->repeat = DMACRO_ZERO; i++; break;
				case DTOK_ESC_QUES  : grp->repeat = DMACRO_ZERO_OR_ONE; i++; break;
				case DTOK_ESC_STAR  : grp->repeat = DMACRO_ZERO_OR_MORE; i++; break;
				case DTOK_ESC_PLUS  : grp->repeat = DMACRO_ONE_OR_MORE; i++; break;
				case DTOK_ESC_SQUO : case DTOK_ESC_DQUO :
				case DTOK_ESC_LB :  case DTOK_ESC_RB :
				case DTOK_ESC_LCB : case DTOK_ESC_RCB :
				case DTOK_ESC_LSB : case DTOK_ESC_RSB : break;
				default : DaoParser_Error( self, DAO_CTW_INV_MAC_REPEAT, & toks[i]->string );
						  return 0;
				}
			}
			continue;
		}

		self->curLine = toks[i]->line;
		unit  = DMacroUnit_New();
		DaoToken_Assign( unit->marker, toks[i] );
		DArray_Append( group->units, (void*)unit );
		switch( chs[0] ){
		case '$' :
			if( DString_FindMBS( & toks[i]->string, "EXP", 0 ) == 1 ){
				unit->type = DMACRO_EXP;
			}else if( DString_FindMBS( & toks[i]->string, "VAR", 0 ) == 1 ){
				unit->type = DMACRO_VAR;
			}else if( DString_FindMBS( & toks[i]->string, "ID", 0 ) == 1 ){
				unit->type = DMACRO_ID;
			}else if( DString_FindMBS( & toks[i]->string, "OP", 0 ) == 1 ){
				unit->type = DMACRO_OP;
			}else if( DString_FindMBS( & toks[i]->string, "BL", 0 ) == 1 ){
				unit->type = DMACRO_BL;
			}else if( DString_FindMBS( & toks[i]->string, "IBL", 0 ) == 1 ){
				unit->type = DMACRO_IBL;
			}
			break;
		case '(' :
		case '[' :
		case '{' :
			switch( chs[0] ){
			case '(' :
				rb = DaoParser_FindPairToken( self, DTOK_LB, DTOK_RB, i, to );
				break;
			case '[' :
				rb = DaoParser_FindPairToken( self, DTOK_LSB, DTOK_RSB, i, to );
				break;
			case '{' :
				rb = DaoParser_FindPairToken( self, DTOK_LCB, DTOK_RCB, i, to );
				break;
			default : rb = -1;
			}
			if( rb <0 ) return 0;

			grp = DMacroGroup_New();
			grp->parent = group;
			grp->repeat = DMACRO_AUTO;
			DArray_Append( group->units, (void*)grp );
			if( DaoParser_MakeMacroGroup( self, grp, parent, i+1, rb ) == 0 ) return 0;
			i = rb;
			continue;
		case '\'' :
			if( chs[2] == '\'' ){
				unit->marker->type = 0;
				switch( chs[1] ){
				case '(' : unit->marker->type = unit->marker->name = DTOK_LB; break;
				case ')' : unit->marker->type = unit->marker->name = DTOK_RB; break;
				case '[' : unit->marker->type = unit->marker->name = DTOK_LSB; break;
				case ']' : unit->marker->type = unit->marker->name = DTOK_RSB; break;
				case '{' : unit->marker->type = unit->marker->name = DTOK_LCB; break;
				case '}' : unit->marker->type = unit->marker->name = DTOK_RCB; break;
				case '\'' : unit->marker->type= unit->marker->name = DTOK_ESC_SQUO;break;
							case '\"' : unit->marker->type= unit->marker->name = DTOK_ESC_DQUO;break;
				default : break;
				}
				if( unit->marker->type == 0 ){
					DaoParser_Error( self, DAO_CTW_INV_MAC_SPECTOK, & toks[i]->string );
					return 0;
				}
				unit->type = DMACRO_BR;
				DString_SetMBS( & unit->marker->string, chs+1 );
				DString_Erase( & unit->marker->string, unit->marker->string.size-1, 1 );
			}
		default : break;
		}
		if( i+1 < to && toks[i+1]->string.mbs[0] == '@' ){
			char ch = toks[i+1]->string.mbs[1];
			if( ch != '@' ){
				if( toks[i+1]->string.size != 2 || ch < '1' || ch >'9' ){
					DaoParser_Error( self, DAO_CTW_INV_MAC_INDENT, & toks[i+1]->string );
					return 0;
				}
				unit->indent = ch - '0';
				i ++;
			}
		}
		i ++;
	}
	return 1;
}
コード例 #20
0
ファイル: daoMacro.c プロジェクト: hooloong/dao
int DaoParser_MacroTransform( DaoParser *self, DaoMacro *macro, int start, int tag )
{
	DString *mbs = DString_New(1);
	DArray *toks = DArray_New(D_TOKEN);
	DArray *all = DArray_New(0);
	DMap *tokMap = DMap_New(D_STRING,0);
	DMap *used = DMap_New(0,D_MAP);
	DNode *it;
	daoint i;
	int j, p0, lev = 0, adjust=0;
	int indent[10];
	char buf[20];

	sprintf( buf, " %p %x", self->nameSpace, tag );
	DString_SetMBS( mbs, buf );
	for(i=0; i<10; i++) indent[i] = -1;

	j = DaoParser_MacroMatch( self, start, self->tokens->size, macro->macroMatch, tokMap, lev, all, indent );
	/*
	   printf( "MacroTransform %i\n", j );
	 */
	if( j <0 ) goto Failed;

	for( it = DMap_First( tokMap ); it != NULL; it = DMap_Next( tokMap, it ) ){
		DMacroNode *node = (DMacroNode*) it->value.pVoid;
		while( node->parent ) node = node->parent;
		it->value.pVoid = node;
	}

	lev = 0;
	p0 = self->tokens->items.pToken[start]->line;
	adjust = self->tokens->items.pToken[start]->cpos - macro->macroApply->cpos;
	if( DaoParser_MacroApply( self, toks, macro->macroApply, tokMap, used, lev, mbs, p0, adjust ) <0 )
		goto Failed;

	/*
	   for(i=0; i<toks->size; i++) printf( "%s  ", toks->items.pToken[i]->string.mbs );
	   printf( "\n" );
	 */
	DArray_Erase( self->tokens, start, j-start );
	DArray_InsertArray( self->tokens, start, toks, 0, -1 );
	/*
	   for(i=0; i<toks->size; i++){
	   DArray_Insert( self->tokStr, (void*)toks->items.pString[i], start+i );
	   DArray_Insert( self->tokPos, (void*)poss->items.pInt[i], start+i );
	   }
	 */
	j = toks->size;
	DString_Delete( mbs );
	for(i=0; i<all->size; i++) DMacroNode_Delete( (DMacroNode*) all->items.pVoid[i] );
	DArray_Delete( all );
	DArray_Delete( toks );
	DMap_Delete( tokMap );
	DMap_Delete( used );
	return start + j;
Failed :
	DString_Delete( mbs );
	for(i=0; i<all->size; i++) DMacroNode_Delete( (DMacroNode*) all->items.pVoid[i] );
	DArray_Delete( all );
	DArray_Delete( toks );
	DMap_Delete( tokMap );
	DMap_Delete( used );
	return -1;
}