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 ); }
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; }
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 ); } }
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 ); }
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; }
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 ); } }
void DaoStream_WriteFormatedInt( DaoStream *self, daoint val, const char *format ) { char buffer[100]; if( self->redirect && self->redirect->StdioWrite ){ DString *mbs = DString_New(1); sprintf( buffer, format, val ); DString_SetMBS( mbs, buffer ); self->redirect->StdioWrite( self->redirect, mbs ); DString_Delete( mbs ); }else if( self->file ){ fprintf( self->file, format, val ); }else if( self->attribs & DAO_IO_STRING ){ sprintf( buffer, format, val ); DString_AppendMBS( self->streamString, buffer ); }else{ printf( format, val ); } }
void DaoClass_ResetAttributes( DaoClass *self ) { DNode *node; DString *mbs = DString_New(1); int i, k, id, autodef = self->classRoutines->overloads->routines->size == 0; DaoClass_MakeInterface( self ); for(i=0; i<self->classRoutines->overloads->routines->size; i++){ DaoRoutine *r2 = self->classRoutines->overloads->routines->items.pRoutine[i]; DArray *types = r2->routType->nested; autodef = r2->parCount == 0; if( autodef ) break; for(k=0; k<types->size; k++){ int tid = types->items.pType[k]->tid; if( tid != DAO_PAR_DEFAULT && tid != DAO_PAR_VALIST ) break; } autodef = k == types->size; if( autodef ) break; } if( autodef && self->parent ){ if( self->parent->type == DAO_CLASS ){ DaoClass *klass = (DaoClass*) self->parent; autodef = autodef && (klass->attribs & DAO_CLS_AUTO_DEFAULT); }else{ autodef = 0; } } #if 0 printf( "%s %i\n", self->className->mbs, autodef ); #endif if( autodef ) self->attribs |= DAO_CLS_AUTO_DEFAULT; for(i=DVM_NOT; i<=DVM_BITRIT; i++){ DString_SetMBS( mbs, daoBitBoolArithOpers[i-DVM_NOT] ); node = DMap_Find( self->lookupTable, mbs ); if( node == NULL ) continue; if( LOOKUP_ST( node->value.pInt ) != DAO_CLASS_CONSTANT ) continue; id = LOOKUP_ID( node->value.pInt ); k = self->constants->items.pConst[id]->value->type; if( k != DAO_ROUTINE ) continue; self->attribs |= DAO_OPER_OVERLOADED | (DAO_OPER_OVERLOADED<<(i-DVM_NOT+1)); } DString_Delete( mbs ); }
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; }
static void DaoClass_GetField( DaoValue *self0, DaoProcess *proc, DString *name ) { int tid = proc->activeRoutine->routHost ? proc->activeRoutine->routHost->tid : 0; DaoType *type = proc->activeRoutine->routHost; DaoClass *host = tid == DAO_OBJECT ? & type->aux->xClass : NULL; DaoClass *self = & self0->xClass; DString *mbs = DString_New(1); DaoValue *value = NULL; int rc = DaoClass_GetData( self, name, & value, host ); if( rc ){ DString_SetMBS( mbs, DString_GetMBS( self->className ) ); DString_AppendMBS( mbs, "." ); DString_Append( mbs, name ); DaoProcess_RaiseException( proc, rc, mbs->mbs ); }else{ DaoProcess_PutReference( proc, value ); } DString_Delete( mbs ); }
static int 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; }
void DaoStream_WritePointer( DaoStream *self, void *val ) { const char *format = self->format; char buffer[100]; if( format == NULL ) format = "%p"; if( self->redirect && self->redirect->StdioWrite ){ DString *mbs = DString_New(1); sprintf( buffer, format, val ); DString_SetMBS( mbs, buffer ); self->redirect->StdioWrite( self->redirect, mbs ); DString_Delete( mbs ); }else if( self->file ){ fprintf( self->file, format, val ); }else if( self->attribs & DAO_IO_STRING ){ sprintf( buffer, format, val ); DString_AppendMBS( self->streamString, buffer ); }else{ printf( format, val ); } }
static void STD_Callable( DaoProcess *proc, DaoValue *p[], int N ) { DaoValue *p0 = p[0]; daoint *res = DaoProcess_PutInteger( proc, 0 ); if( p0 == NULL || p0->type == 0 ){ *res = 0; return; } switch( p0->type ){ case DAO_CLASS : case DAO_ROUTINE : *res = 1; break; case DAO_OBJECT : { DaoObject *object = & p0->xObject; DString *mbs = DString_New(1); DString_SetMBS( mbs, "()" ); DaoObject_GetData( object, mbs, & p0, proc->activeObject ); DString_Delete( mbs ); if( p0 && p0->type == DAO_ROUTINE ) *res = 1; break; } case DAO_CTYPE : { DaoType *type = p0->xCdata.ctype; *res = DaoType_FindFunctionMBS( type, type->typer->name ) != NULL; break; } case DAO_CDATA : case DAO_CSTRUCT : { *res = DaoType_FindFunctionMBS( p0->xCdata.ctype, "()" ) != NULL; break; } default : break; } }
void 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 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 ); } }
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 ); }
int DaoLexer_Tokenize( DaoLexer *self, const char *src, int flags ) { DString *source = DString_New(1); DVector *lexenvs = DVector_New( sizeof(int) ); DaoToken *token = DaoToken_New(); DString *literal = & token->string; char ch, *ss, hex[11] = "0x00000000"; int replace = flags & DAO_LEX_ESCAPE; int comment = flags & DAO_LEX_COMMENT; int space = flags & DAO_LEX_SPACE; int srcSize = (int)strlen( src ); int old=0, state = TOK_START; int lexenv = LEX_ENV_NORMAL; int unicoded = 0; int line = 1; int cpos = 0; int ret = 1; int it = 0; int i, m = 4; DString_SetSharing( literal, 0 ); for(it=0; it<srcSize; it++){ if( (signed char) src[it] < 0 ){ unicoded = 1; break; } } if( unicoded && daoConfig.mbs == 0 ){ DString *wcs = DString_New(0); /* http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html */ wchar_t quotes[] = { 0x27 , 0x27 , 0x27, /* single q.m. */ 0x22 , 0x22 , 0x22, /* double q.m. */ 0x27 + 0xfee0 , 0x27 + 0xfee0 , 0x27 , /* single q.m. unicode */ 0x22 + 0xfee0 , 0x22 + 0xfee0 , 0x22 , /* double q.m. unicode */ 0x60 , 0x27 , 0x27, /* grave accent */ 0x2018 , 0x2019 , 0x27 , /* left/right single q.m. */ 0x201C , 0x201D , 0x22 /* left/right double q.m. */ }; wchar_t sl = L'\\' + 0xfee0; wchar_t stop; int i, N = 21; it = 0; DString_SetMBS( wcs, src ); while( it < wcs->size ){ // TODO: handle verbatim string! for( i=0; i<N; i+=3 ){ if( wcs->wcs[it] == quotes[i] ){ stop = quotes[i+1]; wcs->wcs[it] = quotes[i+2]; it ++; while( it < wcs->size && wcs->wcs[it] != stop ){ if( wcs->wcs[it] == sl || wcs->wcs[it] == L'\\' ){ it ++; continue; } it ++; } if( it < wcs->size ) wcs->wcs[it] = quotes[i+2]; break; } } if( it >= wcs->size ) break; if( wcs->wcs[it] == 0x3000 ){ wcs->wcs[it] = 32; /* blank space */ }else if( wcs->wcs[it] > 0xff00 && wcs->wcs[it] < 0xff5f ){ wcs->wcs[it] -= 0xfee0; /* DBC to SBC */ } it ++; } if( wcs->size ){ DString_SetWCS( source, wcs->wcs ); src = source->mbs; srcSize = source->size; } DString_Delete( wcs ); } DaoLexer_Reset( self ); DVector_PushInt( lexenvs, LEX_ENV_NORMAL ); it = 0; token->cpos = 0; while( it < srcSize ){ #if 0 printf( "tok: %i %i %i %c %s\n", srcSize, it, ch, ch, literal->mbs ); #endif token->type = state; token->name = 0; token->line = line; ch = src[it]; cpos += ch == '\t' ? daoConfig.tabspace : 1; if( ch == '\n' ) cpos = 0, line ++; if( literal->size == 0 ) token->cpos = cpos; if( state == TOK_STRING_MBS || state == TOK_STRING_WCS ){ if( ch == '\\' ){ it ++; if( replace == 0 ){ DString_AppendChar( literal, ch ); if( it < srcSize ){ if( src[it] == '\n' ) cpos = 0, line ++; DString_AppendChar( literal, src[it] ); } it ++; continue; } if( it >= srcSize ){ ret = 0; printf( "error: incomplete string at line %i.\n", line ); break; } if( src[it] == '\n' ) cpos = 0, line ++; switch( src[it] ){ case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : /* \ooo */ i = 2; while( i < 5 && it < srcSize && src[it] >= '0' && src[it] < '8' ){ hex[i] = src[it++]; hex[++i] = 0; } DString_AppendChar( literal, (char) strtol( hex+2, NULL, 8 ) ); it --; break; case '8' : case '9' : DString_AppendChar( literal, (char) (src[it] - '0') ); break; case 'x' : case 'u' : case 'U' : i = 2; switch( src[it] ){ case 'x' : m = 4; break; /* \xhh: max 2 hex digit; */ case 'u' : m = 6; break; /* \uhhhh: max 4 hex digit; */ case 'U' : m = 10; break; /* \Uhhhhhhhh: max 8 hex digit; */ } while( i < m && (it+1) < srcSize && isxdigit( src[it+1] ) ){ hex[i] = src[++it]; hex[++i] = 0; } DString_AppendWChar( literal, (wchar_t) strtol( hex, NULL, 0 ) ); break; case 't' : DString_AppendChar( literal, '\t' ); break; case 'n' : DString_AppendChar( literal, '\n' ); break; case 'r' : DString_AppendChar( literal, '\r' ); break; case '\'' : DString_AppendChar( literal, '\'' ); break; case '\"' : DString_AppendChar( literal, '\"' ); break; default : DString_AppendChar( literal, src[it] ); break; } }else if( ch == '\'' && state == TOK_STRING_MBS ){ DString_AppendChar( literal, ch ); state = TOK_RESTART; token->type = token->name = DTOK_MBS; DaoLexer_AppendToken( self, token ); DString_Clear( literal ); }else if( ch == '\"' && state == TOK_STRING_WCS ){ DString_AppendChar( literal, ch ); state = TOK_RESTART; token->type = token->name = DTOK_WCS; DaoLexer_AppendToken( self, token ); DString_Clear( literal ); }else{ DString_AppendChar( literal, ch ); } }else if( ch == ']' && state == TOK_VERBATIM ){ int len = srcSize - it - 1; DString_AppendChar( literal, ']' ); token->type = token->name = DTOK_VBT_OPEN; if( (ss = strstr( src + it + 1, literal->mbs )) != NULL ){ len = (ss - src) - it - 1 + literal->size; token->type = token->name = DTOK_VERBATIM; } for(i=0; i<len; i++) if( src[it+1+i] == '\n' ) line += 1; DString_AppendDataMBS( literal, src + it + 1, len ); state = TOK_RESTART; DaoLexer_AppendToken( self, token ); DString_Clear( literal ); it += len; }else if( lexenv == LEX_ENV_NORMAL ){ old = state; if( ch >=0 ){ state = daoLexTable[ state ][ (int)ch ]; }else if( state <= TOK_START ){ state = TOK_RESTART; }else if( state != TOK_IDENTIFIER && state != TOK_STRING_MBS && state != TOK_STRING_WCS && state != TOK_COMT_LINE && state != TOK_COMT_OPEN ){ state = TOK_RESTART; } if( state >= TOK_END ){ DString_AppendChar( literal, ch ); token->type = token->name = daoTokenMap[ state ]; if( token->type == DTOK_ID_THTYPE || token->type == DTOK_ID_SYMBOL ) token->type = DTOK_IDENTIFIER; if( space || comment || token->type != DTOK_COMMENT ){ if( isspace( token->string.mbs[0] ) ) token->type = token->name = daoSpaceType[ (int)token->string.mbs[0] ]; DaoLexer_AppendToken( self, token ); } /* may be a token before the line break; */ DString_Clear( literal ); state = TOK_START; }else if( state == TOK_RESTART ){ if( literal->size ){ if( old == TOK_IDENTIFIER ){ token->name = dao_key_hash( literal->mbs, literal->size ); token->type = DTOK_IDENTIFIER; if( token->name == 0 ) token->name = DTOK_IDENTIFIER; DaoLexer_AppendToken( self, token ); }else if( old > TOK_RESTART && old != TOK_END ){ token->type = token->name = daoTokenMap[ old ]; if( token->type == DTOK_ID_THTYPE || token->type == DTOK_ID_SYMBOL ) token->type = DTOK_IDENTIFIER; DaoLexer_AppendToken( self, token ); }else if( space ){ if( isspace( token->string.mbs[0] ) ) token->type = token->name = daoSpaceType[ (int)token->string.mbs[0] ]; DaoLexer_AppendToken( self, token ); } DString_Clear( literal ); token->cpos = cpos; } DString_AppendChar( literal, ch ); if( ch >=0 ) state = daoLexTable[ TOK_START ][ (int)ch ]; else state = TOK_IDENTIFIER; }else if( state == TOK_COMT_OPEN ){ DString_AppendChar( literal, ch ); lexenv = LEX_ENV_COMMENT; DVector_PushInt( lexenvs, LEX_ENV_COMMENT ); }else{ DString_AppendChar( literal, ch ); } }else if( lexenv == LEX_ENV_COMMENT ){ DString_AppendChar( literal, ch ); if( ch == '#' ){ state = TOK_OP_SHARP; }else if( ch == '{' && state == TOK_OP_SHARP ){ state = TOK_COMT_OPEN; DVector_PushInt( lexenvs, LEX_ENV_COMMENT ); }else if( ch == '}' && state == TOK_OP_SHARP ){ state = TOK_COMT_CLOSE; DVector_Pop( lexenvs ); lexenv = lexenvs->data.ints[lexenvs->size-1]; if( lexenv != LEX_ENV_COMMENT ){ token->type = token->name = DTOK_COMMENT; if( comment ) DaoLexer_AppendToken( self, token ); DString_Clear( literal ); state = TOK_RESTART; } }else{ state = TOK_START; } } it ++; } if( literal->size ){ token->type = token->name = daoTokenMap[ state ]; if( lexenv == LEX_ENV_COMMENT ) token->type = token->name = DTOK_CMT_OPEN; switch( state ){ case TOK_STRING_MBS : token->type = token->name = DTOK_MBS_OPEN; break; case TOK_STRING_WCS : token->type = token->name = DTOK_WCS_OPEN; break; } if( token->type == DTOK_IDENTIFIER ){ token->name = dao_key_hash( literal->mbs, literal->size ); if( token->name == 0 ) token->name = DTOK_IDENTIFIER; }else if( token->type == DTOK_ID_THTYPE || token->type == DTOK_ID_SYMBOL ){ token->type = DTOK_IDENTIFIER; } if( token->type || space ){ if( isspace( token->string.mbs[0] ) ) token->type = token->name = daoSpaceType[ (int)token->string.mbs[0] ]; DaoLexer_AppendToken( self, token ); } } DaoToken_Delete( token ); DVector_Delete( lexenvs ); DString_Delete( source ); #if 0 for(i=0; i<self->tokens->size; i++){ DaoToken *tk = self->tokens->items.pToken[i]; printf( "%4i: %4i %4i , %4i, %s\n", i, tk->type, tk->name, tk->cpos, tk->string.mbs ); } #endif return ret ? line : 0; }
static 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; }
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; }
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; }