📄 pdoh.cpp
字号:
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 + -