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

📄 pdoh.cpp

📁 The library provides supports for run-time loaded plugin classes in C++
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		sb1.Push("}");	}	if( !brief ) sb1.Push("");	if( is_header ) cb = "#endif //DO_USE_...";	sb1.Push(cb);	sb1.Push("// %%DYNOBJ section end");	sb1.Push("");	// Generate the implements section 	//pfs = EapFind(afs,sImpl);	pfs = afs.Find(sImpl);	StrBuf &sb2(pfs->m_sb);	sb2.Push("// %%DYNOBJ section implement");	sb2.Push("// This section is auto-generated and manual changes will be lost when regenerated!!");	if( !brief ){		sb2.Push("//");		sb2.Push("// This section is for setting up the type system at run-time using global or ");		sb2.Push("// static variable constructors. For types deriving from DynI, the doGetType ");		sb2.Push("// member function is implemented. For other types, global declarations are used.");		if( is_header ){			sb2.Push("//");			sb2.Push("// Define the symbol below from -only one place- in the project implementing ");			sb2.Push("// these interfaces/classes [the library/module].");			sb2.Push("");		}	}	if( is_header ) sb2.Push(cb_ifdef_impl);	sb2.Push("");	sb2.Push("// Generate type information that auto-registers on module load");	// For each class, make global type structures and possibly doGetType function 	int sb_cnt = 0;	CharBuf cb_type_var;	int id_ix = 0;	// #ifdef index	for( EapIter<Type*> it(acl); it(); it++ ){		if( it()->m_only_in_lib ) continue;		// if( it()->m_is_di ) sb2.Push("");		// Generate #ifdefs around implementation statements that were ifdeffed previously  		// Remove old ifdefs		bool new_line=true;		while( id_ix>it()->m_defines.Size() ){			if( *(acl[it.Index()-1]->m_defines[id_ix-1].Get()) ){				if( new_line ) { sb2.Push(""); new_line=false; }				sb2.Push("#endif");			}			id_ix--;		}		while( id_ix>0 && strcmp(acl[it.Index()-1]->m_defines[id_ix-1],it()->m_defines[id_ix-1]) ){			if( *(acl[it.Index()-1]->m_defines[id_ix-1].Get()) ){				if( new_line ) { sb2.Push(""); new_line=false; }				sb2.Push("#endif");			}			id_ix--;		}		// Add new ones		new_line = true;		while( id_ix<it()->m_defines.Size() ){			if( *(it()->m_defines[id_ix].Get()) ){				if( new_line ) { sb2.Push(""); new_line=false; }				sb2.Push(it()->m_defines[id_ix].Get());			}			id_ix++;		}			// It's a general VTable type. Emit global variable for type.		// DynObjType g_do_vtype_file_3("Main:Base",MAIN_TYPE_ID,sizeof(Main),NULL,NULL);		const char *mb = it()->m_name;		const char *fb;		if( it()->m_bases.Size()>0 )			fb = it()->m_bases[0].Get();		else if( it()->m_is_vobj )			fb = "VObj"; 		else fb = NULL;		if( fb && !strcmp(mb,fb) ) fb = NULL;				// Generate name without template brackets in it		CharBuf cb_mb = mb;		UnTemplate( cb_mb.Get(), false );				/*		if( it()->m_bases.Size()<2 )			cb = "// Type declaration for: ";		else 			cb = "// Type and side type declarations for: ";		cb += mb;		if( !brief ) sb2.Push(cb);		*/				cb = FileNamePart(argv[1]);		RemoveSlashDots((char*)cb.Get());				//sprintf( buf, "g_do_vtype_%s_%d", cb.Get(), it.Index() );		//sprintf( buf, "g_do_vtype_%s", cb_mb.Get() );		//cb_type_var = buf;		cb_type_var.cbprintf( "g_do_vtype_%s", cb_mb.Get() );                CharBuf cb1;        bool sep = false;        if( it()->m_user_type ) cb1 += "DOT_USER_TYPE", sep=true;        if( it()->m_static_type ) cb1 += CharBuf(sep?"|":"")+"DOT_STATIC_TYPE", sep=true;        if( it()->m_novcorr ) cb1 += CharBuf(sep?"|":"")+"DOT_NO_VTABLE_CORR", sep=true;        if( cb1.Length() ) cb1 = "((" + cb1 + ")<<16)|";        cb1 += cbprintf( "%d", it()->m_version );                const char *base = !fb || !strcmp(fb,"VObj") ? "void" : fb;        CharBuf cb_sizeof;        if( !strcmp(mb,"VObj") ) cb_sizeof = "VOBJ_SIZE";        else cb_sizeof.cbprintf( "sizeof(%s)", mb );            		if( it()->m_inst2reg || it()->m_user_type ){			// This is when we instantiate an object to get its type            const char *is_do = it()->m_user_type ? "true" : "false";            cb.cbprintf( "DynObjTypeI2R<%s,%s,%s> %s(\"%s:%s\",%s,%s);", mb, base, is_do, cb_type_var.Get(), mb, fb, type_id_defs[it.Index()].Get(), cb1.Get() );		}		else{			if( fb )				cb.cbprintf( "DynObjType %s(\"%s:%s\",%s,%s,%s);", cb_type_var.Get(), mb, fb, type_id_defs[it.Index()].Get(), cb1.Get(), cb_sizeof.Str() );				//sprintf( buf, "DynObjType %s(\"%s:%s\",%s,%s,sizeof(%s));", cb_type_var.Get(), mb, fb, type_id_defs[it.Index()].Get(), cb1.Get(), mb );			else				cb.cbprintf( "DynObjType %s(\"%s\",%s,%s,%s);", cb_type_var.Get(), mb, type_id_defs[it.Index()].Get(), cb1.Get(), cb_sizeof.Str() );				//sprintf( buf, "DynObjType %s(\"%s\",%s,%s,sizeof(%s));", cb_type_var.Get(), mb, type_id_defs[it.Index()].Get(), cb1.Get(), mb );		}		sb2.Push(cb);				// Emit for each side base class		for( int ix=1; ix<it()->m_bases.Size(); ix++ ){			const char *sb = it()->m_bases[ix];			cb = FileNamePart(argv[1]);			RemoveSlashDots((char*)cb.Get());			//sprintf(buf, "SideBaseDecl g_do_vtype_sbd_%s_%s_%d(\"%s\",\"%s\",sizeof(%s),", cb.Get(), mb, ix, mb, sb, sb );			cb.cbprintf("SideBaseDecl g_do_vtype_sbd_%s_%d(\"%s\",\"%s\",sizeof(%s),", mb, ix, mb, sb, sb );						CharBuf cb1;			if( vtab_corr )				// This forces instantiation of sidebase class (GetVTable...)				cb1.cbprintf("sidebase_offset<%s,%s>(),NULL,GetVTableSizeOf<%s>(),GetVTableOf<%s>());", mb, sb, sb, sb);			else				// Better do without that in the general case				cb1.cbprintf("sidebase_offset<%s,%s>(),NULL,-1,NULL);", mb, sb);			cb += cb1;			sb2.Push(cb);		}				// Is it a DynI ?		if( it()->m_is_di ){			cb.cbprintf( "// DynI::doGetType implementation for: %s", it()->m_name.Get() );			if( !brief ) sb2.Push(cb);            // If template type, The function will be a specialization            if( strchr(it()->m_name, '<') || it()->m_is_template )                sb2.Push("template<>");			cb.cbprintf( "DynObjType* %s::doGetType( const DynI **pself ) const {", it()->m_name.Get() );			sb2.Push(cb);			sb2.Push("   if(pself) *pself=(const DynI*)(const void*)this;");			cb.cbprintf( "   return &%s;", cb_type_var.Get() );			sb2.Push(cb);			sb2.Push( "}" );		}	}	while( id_ix>0 ){		if( *acl.Top()->m_defines[id_ix-1].Get() )			sb2.Push("#endif");		id_ix--;	}	// Make public type declaration for classes tagged with usertype	bool found_ut = false;	for( EapIter<Type*> it(acl); it(); it++ ){		if( it()->m_user_type ){			if( !found_ut ){				found_ut = true;				sb2.Push("");				sb2.Push("// Declarations to make types visible to library users");			}			cb = FileNamePart(argv[1]);			RemoveSlashDots((char*)cb.Get());			CharBuf cb1 = it()->m_name;			if( it()->m_bases.Size() ){				cb1 += ":";				cb1 += it()->m_bases[0];			}			cb.cbprintf( "doUserTypeDecl g_do_ut_decl_%s_%d(\"%s\",%s);", cb.Get(), it.Index(), cb1.Get(), type_id_defs[it.Index()].Get() );			sb2.Push(cb);		}	}	if( !brief && found_ut )		sb2.Push("");		if(is_header){		cb = "#endif //DO_IMPLEMENT_...";		sb2.Push(cb);	}	if( !brief ) sb2.Push("//");	sb2.Push("// %%DYNOBJ section end");	sb2.Push("");	// Should we generate all sections?	// Command line overrides file settings 	const char *po = GetOpt(argc,argv,"-s");	if( po ) sections = atoi(po);	po = GetOpt(argc,argv,"-f");	if( po ) file_sections = atoi(po);		// Generate the library section if requested    if( sections&(1<<(sLib-1)) ){        FileSections fs;	// Insertion code loaded here        bool b_ok = true;        int sl;        if( !fs.AddFile("sect-lib.fs.cpp") ){            cb = GetOpt(argc,argv,"-p");	            if( sl=cb.Length() ){                if( cb.Get()[sl-1]!='/' && cb.Get()[sl-1]!='\\' )                    cb += "/";                cb += "sect-lib.fs.cpp";                if( !fs.AddFile(cb) )                    b_ok = false;            }            else                b_ok = false;        }        if( !b_ok ){            printf( "Failed loading \"sect-lib.fs.cpp\", cannot generate library section\n" );            printf( "Use option -p<path> to specify where \"sect-lib.fs.cpp\" can be found\n" );            exit( -1 );        }                    if( b_ok ){            pfs = afs.Find(sLib);            StrBuf &sb3(pfs->m_sb);            StrBuf sb_ob, sb_sr;            sb3.Push("// %%DYNOBJ section library");            sb3.Push("// This section is auto-generated and manual changes will be lost when regenerated!!");            sb3.Push("");            sb3.Push("// The code below implements the library part in a loadable class library (plugin). ");            sb3.Push("");                        // Init section for library            sb3.Push( fs.GetSection("InitDynLib", b_ok) );            if( !b_ok ) printf("sLib: No InitDynLib section found\n");            sb3.Push("");            if( adv_lib ){                sb3.Push( fs.GetSection("Init-Adv", b_ok) );                if( !b_ok ) printf("sLib: No Init-Adv section found\n");                else sb3.Push("");                            // A NewClass function for each class                for( EapIter<Type*> it(acl); it(); it++ ){                    sb_sr.Empty(); sb_sr.Push("$CLASS$"); sb_sr.Push(it()->m_name.Get());                    // Fix for template types                    cb = it()->m_name;                    UnTemplate( cb.Str(), false );                    sb_sr.Push("$CLASSFUNC$"); sb_sr.Push(cb);                    fs.SubstSection("NewClass",sb_sr,sb_ob);                    sb3.Push(sb_ob);                    sb3.Push("");                }                sb3.Push("");            }            // Create DynObj function            if( !adv_lib )                sb3.Push( fs.GetSection("CreateDynObj-Top", b_ok) );            else                sb3.Push( fs.GetSection("CreateDynObj-TopAdv", b_ok) );            sb3.Push("");                            // For each class, a section to recognize class & base name / type id            int sl;            for( EapIter<Type*> it(acl); it(); it++ ){                cb = "    if( (";                sb_sr.Empty(); sb_sr.Push("$CLASS$").Push(it()->m_name);                sb_sr.Push("$ID$").Push(type_id_defs[it.Index()].Get());                if( it()->m_chk_der==ctBoth )                    fs.SubstSection("CreateDynObj-PerType-NameAndId",sb_sr,sb_ob);                else if( it()->m_chk_der==ctEither )                    fs.SubstSection("CreateDynObj-PerType-NameOrId",sb_sr,sb_ob);                else if( it()->m_chk_der==ctId )                    fs.SubstSection("CreateDynObj-PerType-Id",sb_sr,sb_ob);                else if( it()->m_chk_der==ctName )                    fs.SubstSection("CreateDynObj-PerType-Name",sb_sr,sb_ob);                if( !sb_ob.Size() ){                    printf("sLib: Seems we have no CreateDynObj-PerType-... sections, skipping\n");                    break;	// In this case, have no sections                }                sl = sb_ob[0].Length();                if( strchr("\r\n",sb_ob[0][sl-1]) ) sb_ob[0].Str()[sl-1] = 0;                cb += sb_ob[0];                cb += ") ";                if( it()->m_bases.Size() ) cb += "|| ";                else cb += "){";                sb3.Push(cb);                                if( it()->m_bases.Size() ){                    sb_sr.Empty(); sb_sr.Push("$CLASS$").Push(it()->m_bases[0]);                    CharBuf cb_base_id = it()->m_bases[0];                    ToDefineSymbol( (char*)cb_base_id.Get() );                    cb.cbprintf( "%s_TYPE_ID", cb_base_id.Get() );                    sb_sr.Push("$ID$").Push(cb);                    cb = "        (";                    if( it()->m_chk_base==ctBoth )                        fs.SubstSection("CreateDynObj-PerType-NameAndId",sb_sr,sb_ob);                    else if( it()->m_chk_base==ctEither )                        fs.SubstSection("CreateDynObj-PerType-NameOrId",sb_sr,sb_ob);                    else if( it()->m_chk_base==ctId )                        fs.SubstSection("CreateDynObj-PerType-Id",sb_sr,sb_ob);                    else if( it()->m_chk_base==ctName )                        fs.SubstSection("CreateDynObj-PerType-Name",sb_sr,sb_ob);                    sl = sb_ob[0].Length();                    if( strchr("\r\n",sb_ob[0][sl-1]) ) sb_ob[0].Str()[sl-1] = 0;                    cb += sb_ob[0];                    cb += ") ){";                    sb3.Push(cb);                }                                    sb_sr.Empty(); sb_sr.Push("$CLASS$").Push(it()->m_name);                if( !adv_lib )                    fs.SubstSection("CreateDynObj-PerType-Body",sb_sr,sb_ob);                else{                    // Fix for template types                    cb = it()->m_name;                    UnTemplate( cb.Str(), false );                    sb_sr.Push("$CLASSFUNC$").Push(cb);                    fs.SubstSection("CreateDynObj-PerType-Body-Adv",sb_sr,sb_ob);                    printf("PerType-Body adv-lib\n");                }                sb3.Push(sb_ob);            }            if( !adv_lib )                sb3.Push( fs.GetSection("CreateDynObj-End",b_ok) );            else                sb3.Push( fs.GetSection("CreateDynObj-EndAdv",b_ok) );            sb3.Push("");                        // Win32 specifics (DllMain)            sb3.Push( fs.GetSection("WIN32",b_ok) );            sb3.Push("");            // The ExitDynLib function            sb3.Push( fs.GetSection("Exit",b_ok) );            // Close section		            sb3.Push("// %%DYNOBJ section end");            sb3.Push("");        }    }		// Print result to stdout or file	pf = stdout;	po = GetOpt(argc,argv,"-o");	if( po ){		if( *po )pf = fopen(po,"w");		else pf = fopen(argv[1],"w");		if( !pf ){			printf("Failed creating output file");			return -2;		}	}	// Put the general section first, it gives a good overview	if( n_new_sect>=3 ){		int ix = afs.FindIndexOf(sGen);		if( ix>0 ){			pfs = afs[ix];			afs.RemoveIndexOrdered(ix);			afs.InsertOrdered(pfs,0);		}	}		// We want to catch the last #endif and put it last in the file	// Write to main output file	int ix_last_endif = -1;	for( int ix=0; ix<afs.Size(); ix++ ){		// Skip section?		if( afs[ix]->m_sect!=sNone && !(sections&(1<<(afs[ix]->m_sect-1))) ) continue;		for( int jx=0; jx<afs[ix]->m_sb.Size(); jx++ ){			const char *pc = afs[ix]->m_sb[jx];			if( last_endif!=pc || !is_header )				fprintf( pf, "%s\n", pc );			else {				ix_last_endif = jx;				pfs = afs[ix];				break;			}		}	}	if( ix_last_endif>=0 ){		for( int jx=ix_last_endif; jx<pfs->m_sb.Size(); jx++ ){			const char *pc = pfs->m_sb[jx];			fprintf( pf, "%s\n", pc );		}	}	if( pf!=stdout ) fclose(pf);	// Write to separate files if requested	if( file_sections ){		po = GetOpt(argc,argv,"-o");		cb = po ? po : argv[1];	// Initial filename		if( pc=(char*)strchr(cb,'.') ) *pc=0;		int fnl = strlen(cb);		for( int ix=0; ix<afs.Size(); ix++ ){			// Skip section?			if( afs[ix]->m_sect==sNone || !(file_sections&(1<<(afs[ix]->m_sect-1))) ) continue;			if( afs[ix]->m_sect==sGen )				cb += "-gen.h";			else if( afs[ix]->m_sect==sUse )				cb += "-use.cpp";			else if( afs[ix]->m_sect==sImpl )				cb += "-impl.cpp";			else if( afs[ix]->m_sect==sLib )				cb += "-lib.cpp";			pf = fopen(cb,"w");			cb.Get()[fnl] = 0;			if( !pf ){				printf("Failed creating output file: %s", cb.Get());				return -2;			}			// These are used as locks in header file, but are not needed in cpp file			cb = "DO_IMPLEMENT_";			cb += FileNamePart(argv[1]);			ToDefineSymbol( (char*)cb.Get()+10 );			CharBuf cb1 = "DO_USE_";			cb1 += FileNamePart(argv[1]);			ToDefineSymbol( (char*)cb1.Get()+10 );			// Iterate 			for( int jx=0; jx<afs[ix]->m_sb.Size(); jx++ ){				const char *pc = afs[ix]->m_sb[jx];				if( !strstr(pc,cb) && !strstr(pc,cb1) )					fprintf( pf, "%s\n", pc );			}			fclose(pf);		}	}	//int nerr = sq_checkmem( );		// Done!	afs.DeleteAll();	acl.DeleteAll();		return 0;}

⌨️ 快捷键说明

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