⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdoh.cpp

📁 The library provides supports for run-time loaded plugin classes in C++
💻 CPP
📖 第 1 页 / 共 3 页
字号:
					if( aval.IndexOfKwi("general")!=-1 )						sections |= (1<<(sGen-1));					if( aval.IndexOfKwi("use")!=-1 )						sections |= (1<<(sUse-1));					if( aval.IndexOfKwi("implement")!=-1 )						sections |= (1<<(sImpl-1));					if( aval.IndexOfKwi("library")!=-1 )						sections |= (1<<(sLib-1));					if( aval.Size() && isdigit(aval[0][0]) )						sections = atoi(aval[0]);				}				if( GetAValI(pc1,aval,"tofile") ){					got_word = true;					file_sections = 0;					if( aval.IndexOfKwi("general")!=-1 )						file_sections |= (1<<(sGen-1));					if( aval.IndexOfKwi("use")!=-1 )						file_sections |= (1<<(sUse-1));					if( aval.IndexOfKwi("implement")!=-1 )						file_sections |= (1<<(sImpl-1));					if( aval.IndexOfKwi("library")!=-1 )						file_sections |= (1<<(sLib-1));					if( aval.Size() && isdigit(aval[0][0]) )						file_sections = atoi(aval[0]);				}								if( GetAValIAt(pc1,aval,"library",(const char**)&pc1) ){                    printf("Found library insertion point\n");					got_word = true;					// Make a new library section to follow immediately here 					pfs = new FileSect(sLib);					afs.Push(pfs);					// Include library section be default					sections |= 1<<(sLib-1);					                    if( aval.IndexOfKwi("advanced")!=-1 )                        adv_lib = true;                    					// Insert library code here					if( GetAValIAt(pc1,aval,"types",(const char**)&pc1) ){						StrBufKwi type;						CharBuf name;						Type *pt;						// The value of types is an array of strings like 						// DerCl1(both):BaseCl1(name),...						for( int ix=0; ix<aval.Size(); ix++ ){							const char *pc = aval[ix];							// This reads the derived class name							if( GetAValIAtAny( pc, type, name, &pc) ){								//if( !(pt=EapFind(acl,name.Get())) )								if( !(pt=acl.Find(name.Get())) )									acl.Push( pt = new Type(name,false,true) );								if( type.IndexOfKwi("both")!=-1 )									pt->m_chk_der = ctBoth; 								else if( type.IndexOfKwi("either")!=-1 )									pt->m_chk_der = ctEither;								else if( type.IndexOfKwi("name")!=-1 )									pt->m_chk_der = ctName; 								else if( type.IndexOfKwi("id")!=-1 )									pt->m_chk_der = ctId;																	pc = (char*)SkipSpace(pc);								if( *pc==':' ){									pc++;									// This reads the base class name									if( GetAValIAtAny( pc, type, name, &pc) ){										if( !pt->m_bases.Size() )											pt->m_bases.Push(name);										if( strcmp(pt->m_bases[0],name) )											printf( "(%d) Conflicting base class name found in library declaration: %s, %s\n", line, pt->m_bases[0].Get(), name.Get() );										if( type.IndexOfKwi("both")!=-1 )											pt->m_chk_base = ctBoth; 										else if( type.IndexOfKwi("either")!=-1 )											pt->m_chk_base = ctEither;										else if( type.IndexOfKwi("name")!=-1 )											pt->m_chk_base = ctName; 										else if( type.IndexOfKwi("id")!=-1 )											pt->m_chk_base = ctId;									}								}							}						}					}				}								if( GetAValIAt(pc1,aval,"class",(const char**)&pc1) ){                    //printf( "Found class %s\n", pc1 );					got_word = true;					// Class declaration to follow					bool is_di = (aval.IndexOfKwi("dyni")!=-1) || (aval.IndexOfKwi("dynobj")!=-1); 					do_next_cl = true;					acl.Push(new Type(NULL,is_di,false));					if( aval.IndexOfKwi("vobj")!=-1 ) 						acl.Top()->m_is_vobj = true;					acl.Top()->m_user_type = (aval.IndexOfKwi("usertype")!=-1);										if( GetAValI(pc1,aval,"name") && aval.Size()>0 )						acl.Top()->m_name = aval[0];					if( GetAValI(pc1,aval,"bases") )						acl.Top()->m_bases.MoveFrom(aval);					if( GetAValI(pc1,aval,"version") )						acl.Top()->m_version = atoi(aval[0]);					if( GetAValI(pc1,aval,"flags") && aval.Size()>0 ){						if( aval.IndexOfKwi("notypeid")!=-1 )							acl.Top()->m_skip_tid = true;						//if( aval.IndexOfKwi("keepi")!=-1 )						//	acl.Top()->m_keep_I = true;						if( aval.IndexOfKwi("usertype")!=-1 )							acl.Top()->m_user_type = true;						if( aval.IndexOfKwi("inst2reg")!=-1 )							acl.Top()->m_inst2reg = true;						if( aval.IndexOfKwi("novcorr")!=-1 )							acl.Top()->m_novcorr = true;						if( aval.IndexOfKwi("static")!=-1 )							acl.Top()->m_static_type = true;						if( aval.IndexOfKwi("noproto")!=-1 )							acl.Top()->m_no_proto = true;						if( aval.IndexOfKwi("template")!=-1 )							acl.Top()->m_is_template = true;					}				}				if( !got_word ){					printf("Error (%d): Unknown %%DYNOBJ keyword found: %s\n",line,pc);					fclose(pf);					return -2;				}			}		}		else{			if( strstr(buf,"_TYPE_ID") && strstr(buf,"#define") )				type_ids.Push(buf);			if( !in_auto ){				// Only keep lines when not in auto section				pfs->m_sb.Push(buf);				in_comment = StripComment(buf,in_comment);				if( !in_comment ){					if( strstr(buf,"#endif") )						last_endif = pfs->m_sb.Top();											// Is it an ifdef line?					pc = (char*)SkipSpace(buf);					if( !strnicmp(pc,"#if",3) )						defines.Push(buf);					else if( !strnicmp(pc,"#endif",6) ){						if( defines.Size() )							defines.Pop();					}					else if( (!strnicmp(pc,"#define",7) || !strnicmp(pc,"#undef",6)) && defines.Size() ){						// See if we're just defining last #ifndef						const char *pc1 = SkipSpace(SkipToSpace(pc));						static CharBuf cb;						cb.Assign(pc1,SkipToSpace(pc1)-pc1);						if( strstr(defines.Top(),cb) )							defines.Top() = "";	// Set to nothing					}				}									if( !in_comment && do_next_cl && 					(!(is_struct=!((pc=strstr(buf,"class")))) || (pc=strstr(buf,"struct"))) ){					char *pcol = strchr(pc,':');					if( !pcol ) pcol = strchr(pc,'{');					if( pcol ){						// Find class name						Type *pt = acl.Top();						pt->m_is_struct = is_struct;						pt->m_defines = defines; 						if( !pt->m_name.Length() )							pt->m_name = GetWordRev(pcol-1);						// Only read bases if not given in tag  						if( !pt->m_bases.Size() ){							// Find each base class - before ' or { or eol							pc = pcol;							if( *pcol==':' ){	// Must have : for base classes								while( 1 ){									char ch, *pc1 = strchr(pc,',');									if( !pc1 ) pc1 = strchr(pc,'{');									if( !pc1 ) pc1 = pc+strlen(pc);									ch = *pc1;									pt->m_bases.Push(GetWordRev(pc1-1));									if( ch!=',' ) break;									pc = pc1+1;								}							}						}					}				}			}            else{                // In Auto,             }			if( !in_comment )				do_next_cl = false;		}	}	fclose(pf);	// If no class declarations found, quit 	if( !acl.Size() ){		printf("No class declarations found, nothing to do, exiting.\n");		return 0;	}		CharBuf cb;	// Caching only makes sense when writing to a file    bool on_file = GetOpt(argc,argv,"-o")!=NULL;    if( on_file ){	    //printf( "%x %x\n", chk_sum1, chk_sum2 );	    // See if checksum same as last. Then quit.	    CharBuf cb_cache = argv[1];	    pc = (char*)strrchr(cb_cache,'/');	    if( !pc ) pc = (char*)strrchr(cb_cache,'\\');	    int name_pos = pc ? pc+1-cb_cache : 0;	    if( pc ) pc[1]=0;	    else cb_cache.Reset();	    int nl = strlen(argv[1]+name_pos);	    bool is_modified = true, found_entry=false;	    cb_cache += ".pdoh-cache.txt";	    //printf("%s\n",(const char*)cb_cache);	    if( cb.LoadFromFile( cb_cache ) ){	        const char *pc1 = strstr(cb,argv[1]+name_pos);	        if( pc1 ){	            // Found entry	            found_entry = true;	            int chk1, chk2;	            sscanf(pc1+nl+1,"%x",&chk1);	            sscanf(pc1+nl+1+9,"%x",&chk2);	            //printf( "old: %08x %08x\n", chk1, chk2 );	            if( chk1==chk_sum1 && chk2==chk_sum2 ){	                // Same check sum, no need to update anything	                //printf( "Checksum match, exiting\n" );	                return 0; 	            }	            // Update checksums in contents	            char buf[32];	            sprintf( buf,"%08x", chk_sum1 );	            memcpy( (char*)pc1+nl+1, buf, 8 );	            sprintf( buf,"%08x", chk_sum2 );	            memcpy( (char*)pc1+nl+1+9, buf, 8 );	        }	    }	    if( !found_entry )	        cb += cbprintf( "%s:%08x:%08x\n", argv[1]+name_pos, chk_sum1, chk_sum2 );	    cb.SaveToFile( cb_cache );	    printf("Found changes, updating sections - %s\n", argv[1] );    }		// Make sure we have each section	int n_new_sect = 0;	//if( !EapFind(afs,sGen) ){	if( !afs.Find(sGen) ){		afs.Push(new FileSect(sGen));		n_new_sect++;	}	//if( !EapFind(afs,sUse) ){	if( !afs.Find(sUse) ){		afs.Push(new FileSect(sUse));		n_new_sect++;		}	//if( !EapFind(afs,sImpl) ){	if( !afs.Find(sImpl) ){		afs.Push(new FileSect(sImpl));		n_new_sect++;	}	//if( !EapFind(afs,sLib) ){	if( !afs.Find(sLib) ){		afs.Push(new FileSect(sLib));		n_new_sect++;	}			// Generate sections	// Get a good random seed (2nd time)	srand( (rand()<<16) + (rl_sum<<8) + *(int*)(buf+(rand()%48)) + acl.Size()*7261612 );	// For generating type IDs		// We need this string in a couple of places	cb = "DO_IMPLEMENT_";	cb += FileNamePart(argv[1]);	ToDefineSymbol( (char*)cb.Get() );	CharBuf cb_ifdef_impl = "#ifdef "+cb;	pfs = afs.Find(sGen);	StrBuf &sb(pfs->m_sb);	sb.Push("// %%DYNOBJ section general");	sb.Push("// This section is auto-generated and manual changes will be lost when regenerated!!");    if( is_header ){        sb.Push(cb_ifdef_impl);        sb.Push("    #define DO_IMPLEMENTING     // If app has not defined it already");        sb.Push("#endif");    }    else        // Source file        sb.Push("#define DO_IMPLEMENTING     // Source file, always implementing");	sb.Push("#include \"dynobj/DynObj.h\"");	if( is_header && !brief ){		sb.Push("//");		sb.Push("// These are general definitions & declarations used on both the user side [main program]");		sb.Push("// and the implementor [library] side. ");	}		sb.Push("");	if( !brief ) sb.Push("//");	sb.Push("// --- Integer type ids for defined interfaces/classes ---");	int prev_sz = sb.Size();	// For each class, define TYPE_ID	StrBuf type_id_defs;	int max_id_len = 0;	for( EapIter<Type*> it(acl); it(); it++ ){		if( !it()->m_name ){			// Undefined class - remove			delete it();			acl.RemoveIndexUnordered(it.Index());			it--;			continue;		}		//strcpy(buf,it()->m_name);		cb = it()->m_name;		for( pc=cb.Str(); *pc; pc++){			*pc=toupper(*pc);			//if( *pc=='<' || *pc=='>' ) printf("Warning: Template types not supported: %s (use typedef for it)\n",buf);		}		UnTemplate( cb.Str(), true );		        /*		// Take version number from interface name? - NO GOOD		if( it()->m_version==1 && isdigit(pc[-1]) ){			while( isdigit(pc[-1]) ) pc--;			it()->m_version = atoi(pc);			while( isdigit(pc[0]) ) pc++;		}        */		//strcat(buf,"_TYPE_ID");		cb += "_TYPE_ID";		type_id_defs.Push(cb);		if( (int)strlen(cb)>max_id_len )			max_id_len = strlen(cb);	}	if( max_id_len>0 ){		for( EapIter<Type*> it(acl); it(); it++ ){			if( it()->m_skip_tid || it()->m_only_in_lib ) 				continue;			CharBuf cb_tid = type_id_defs[it.Index()];			// Align the defines			cb.cbprintf( "%s                              ", cb_tid.Get() );			if( max_id_len+1<cb.Length() ) cb.Str()[max_id_len+1]= 0;			pc = NULL;			// Look among already defined type ids			for( int ix=0; ix<type_ids.Size(); ix++ )				if( pc=(char*)strstr(type_ids[ix],cb_tid) )					break;			if( pc ){				// Resuse old ID				pc += strlen(cb_tid);				cb += GetWordFwd((char*)pc);			}			else{				// Generate new ID				// We leave the 12 low bits clear for general purpose type information				// The MSB bit (31) is set for local/app-global type ID				int r = 0x80000000 | ((rand()&0x7FFFF)<<12);				//int r = 0;				//while( r<BASE_CUSTOM_TYPE_ID )				//	r = ((rand()<<16)+rand())&0xFFFFFF00;				//sprintf(buf+strlen(buf),"0x%08X", r );				cb += cbprintf("0x%08X",r);			}			sb.Push("#define "+cb);		}	}	if( sb.Size()==prev_sz ) sb.Pop();	else sb.Push("");	 	if( is_header ){ 		if( !brief ) sb.Push("//"); 		sb.Push("// --- Forward class declarations ---"); 		int prev_sz = sb.Size(); 		for( EapIter<Type*> it(acl); it(); it++ ){ 			if( it()->m_no_proto ) continue;  			cb.cbprintf( "%s %s;", it()->m_is_struct?"struct":"class", it()->m_name.Get() ); 			sb.Push(cb); 		} 		if( sb.Size()==prev_sz ) sb.Pop(); 		else sb.Push("");		 		prev_sz = sb.Size();		sb.Push("// --- For each declared class, doTypeInfo template specializations ---");		if( !brief ) sb.Push("// This allows creating objects from a C++ types and in run-time casts");		for( EapIter<Type*> it(acl); it(); it++ ){			cb.cbprintf( "DO_DECL_TYPE_INFO(%s,%s);", it()->m_name.Get(), type_id_defs[it.Index()].Get() );			sb.Push(cb);		} 		if( sb.Size()==prev_sz ) sb.Pop(); 		else sb.Push("");	} 		sb.Push("// %%DYNOBJ section end");	sb.Push("");		// Generate the use section 	//pfs = EapFind(afs,sUse);	pfs = afs.Find(sUse);	StrBuf &sb1(pfs->m_sb);	sb1.Push("// %%DYNOBJ section use");	sb1.Push("// This section is auto-generated and manual changes will be lost when regenerated!!");	if( !brief ){		sb1.Push("//");		sb1.Push("// Define the symbol below from -only one place- in the project using these ");		sb1.Push("// interfaces/classes [the client] (to avoid multiple definitions of functions).");		sb1.Push("");	}	cb = "#ifdef DO_USE_";	cb += FileNamePart(argv[1]);	ToDefineSymbol( (char*)cb.Get()+10 );	if(is_header) sb1.Push(cb);		sb1.Push("");	if( !brief )sb1.Push("//");	sb1.Push("// --- DoTypeName function bodies for declared interfaces/classes ---");	// For each class, implement DoTypeName function 	for( EapIter<Type*> it(acl); it(); it++ ){		if( it()->m_only_in_lib ) continue;		cb = "const char* DoTypeName( ";		cb += it()->m_name;		cb += "* p ){";		sb1.Push((const char*)cb);		cb = "   return \"";		cb += it()->m_name;		cb += "\";";		sb1.Push((const char*)cb);		sb1.Push("}");	}		sb1.Push("");	if( !brief ) sb1.Push("//");	sb1.Push("// --- DoTypeId function bodies for declared interfaces/classes ---");	// For each class, implement DoTypeId function 	for( EapIter<Type*> it(acl); it(); it++ ){		if( it()->m_only_in_lib ) continue;		cb = "int DoTypeId( ";		cb += it()->m_name;		cb += "* p ){";		sb1.Push((const char*)cb);		cb = "   return ";		cb += type_id_defs[it.Index()];		cb += ";";		sb1.Push((const char*)cb);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -