void CArchiveScanner::ReadCacheData(const std::string& filename) { if (!FileSystem::FileExists(filename)) { LOG_L(L_INFO, "Archive cache doesn't exist: %s", filename.c_str()); return; } LuaParser p(filename, SPRING_VFS_RAW, SPRING_VFS_BASE); if (!p.Execute()) { LOG_L(L_ERROR, "Failed to parse archive cache: %s", p.GetErrorLog().c_str()); return; } const LuaTable archiveCache = p.GetRoot(); // Do not load old version caches const int ver = archiveCache.GetInt("internalVer", (INTERNAL_VER + 1)); if (ver != INTERNAL_VER) { return; } const LuaTable archives = archiveCache.SubTable("archives"); for (int i = 1; archives.KeyExists(i); ++i) { const LuaTable curArchive = archives.SubTable(i); const LuaTable archived = curArchive.SubTable("archivedata"); std::string name = curArchive.GetString("name", ""); ArchiveInfo& ai = archiveInfos[StringToLower(name)]; ai.origName = name; ai.path = curArchive.GetString("path", ""); // do not use LuaTable.GetInt() for 32-bit integers, the Spring lua // library uses 32-bit floats to represent numbers, which can only // represent 2^24 consecutive integers ai.modified = strtoul(curArchive.GetString("modified", "0").c_str(), 0, 10); ai.checksum = strtoul(curArchive.GetString("checksum", "0").c_str(), 0, 10); ai.updated = false; ai.archiveData = CArchiveScanner::ArchiveData(archived, true); if (ai.archiveData.GetModType() == modtype::map) { AddDependency(ai.archiveData.GetDependencies(), "Map Helper v1"); } else if (ai.archiveData.GetModType() == modtype::primary) { AddDependency(ai.archiveData.GetDependencies(), "Spring content v1"); } } const LuaTable brokenArchives = archiveCache.SubTable("brokenArchives"); for (int i = 1; brokenArchives.KeyExists(i); ++i) { const LuaTable curArchive = brokenArchives.SubTable(i); std::string name = curArchive.GetString("name", ""); StringToLowerInPlace(name); BrokenArchive& ba = this->brokenArchives[name]; ba.path = curArchive.GetString("path", ""); ba.modified = strtoul(curArchive.GetString("modified", "0").c_str(), 0, 10); ba.updated = false; ba.problem = curArchive.GetString("problem", "unknown"); } isDirty = false; }
void CArchiveScanner::ReadCacheData(const std::string& filename) { std::lock_guard<spring::recursive_mutex> lck(scannerMutex); if (!FileSystem::FileExists(filename)) { LOG_L(L_INFO, "[AS::%s] ArchiveCache %s doesn't exist", __func__, filename.c_str()); return; } LuaParser p(filename, SPRING_VFS_RAW, SPRING_VFS_BASE); if (!p.Execute()) { LOG_L(L_ERROR, "[AS::%s] failed to parse ArchiveCache: %s", __func__, p.GetErrorLog().c_str()); return; } const LuaTable& archiveCache = p.GetRoot(); const LuaTable& archives = archiveCache.SubTable("archives"); const LuaTable& brokenArchives = archiveCache.SubTable("brokenArchives"); // Do not load old version caches const int ver = archiveCache.GetInt("internalVer", (INTERNAL_VER + 1)); if (ver != INTERNAL_VER) return; for (int i = 1; archives.KeyExists(i); ++i) { const LuaTable& curArchive = archives.SubTable(i); const LuaTable& archived = curArchive.SubTable("archivedata"); std::string name = curArchive.GetString("name", ""); ArchiveInfo& ai = archiveInfos[StringToLower(name)]; ai.origName = name; ai.path = curArchive.GetString("path", ""); // do not use LuaTable.GetInt() for 32-bit integers: the Spring lua // library uses 32-bit floats to represent numbers, which can only // represent 2^24 consecutive integers ai.modified = strtoul(curArchive.GetString("modified", "0").c_str(), 0, 10); ai.checksum = strtoul(curArchive.GetString("checksum", "0").c_str(), 0, 10); ai.updated = false; ai.archiveData = CArchiveScanner::ArchiveData(archived, true); if (ai.archiveData.IsMap()) { AddDependency(ai.archiveData.GetDependencies(), GetMapHelperContentName()); } else if (ai.archiveData.IsGame()) { AddDependency(ai.archiveData.GetDependencies(), GetSpringBaseContentName()); } } for (int i = 1; brokenArchives.KeyExists(i); ++i) { const LuaTable& curArchive = brokenArchives.SubTable(i); const std::string& name = StringToLower(curArchive.GetString("name", "")); BrokenArchive& ba = this->brokenArchives[name]; ba.path = curArchive.GetString("path", ""); ba.modified = strtoul(curArchive.GetString("modified", "0").c_str(), 0, 10); ba.updated = false; ba.problem = curArchive.GetString("problem", "unknown"); } isDirty = false; }
fwRefContainer<ComponentData> ComponentLoader::LoadComponent(const char* componentName) { auto component = m_knownComponents[componentName]; if (!component.GetRef()) { FatalError("Unknown component %s.", componentName); } if (component->IsLoaded()) { return component; } // match and resolve dependencies auto dependencies = component->GetDepends(); for (auto& dependency : dependencies) { // find the first component to provide this bool match = false; for (auto& it : m_knownComponents) { auto matchProvides = it.second->GetProvides(); for (auto& provide : matchProvides) { if (dependency.IsMatchedBy(provide)) { trace("Resolving dependency for %s by %s (%s).\n", dependency.GetString().c_str(), it.second->GetName().c_str(), provide.GetString().c_str()); auto dependencyData = LoadComponent(it.second->GetName().c_str()); component->AddDependency(dependencyData); match = true; break; } } // break if matched if (match) { break; } } if (!match && dependency.GetCategory() != "vendor") { trace("Unable to resolve dependency for %s.\n", dependency.GetString().c_str()); return nullptr; } } // load the component component->Load(); return component; }
File *Parser::GetIncludedFile(sym_t preprocessor, const char *line, FILE **outf, bool& in_compiler_dir) { bool quoted = true; CC_STRING ifpath, itoken, iline; File *retval = NULL; iline = ExpandLine(intab, true, line, errmsg); if(!errmsg.isnull()) goto done; itoken = GetIncludeFileName(iline, quoted); iline.clear(); if( itoken.isnull() ) { errmsg.Format("Invalid include preprocessor: %s", pline.from.c_str()); goto done; } if(!rtc->get_include_file_path(itoken, GetCurrentFileName(), quoted, preprocessor == SSID_SHARP_INCLUDE_NEXT, ifpath, &in_compiler_dir)) { errmsg.Format("Cannot find include file \"%s\"", itoken.c_str()); goto done; } RealFile *file; pline.to = pline.from; file = new RealFile; file->SetFileName(ifpath); retval = file; *outf = NULL; if(has_dep_file() && ! in_compiler_dir) AddDependency(" ", ifpath.c_str()); done: return retval; }
status_t Job::_AddRequirement(BJob* dependency) { if (dependency == NULL) return B_OK; switch (dependency->State()) { case B_JOB_STATE_WAITING_TO_RUN: case B_JOB_STATE_STARTED: case B_JOB_STATE_IN_PROGRESS: AddDependency(dependency); break; case B_JOB_STATE_SUCCEEDED: // Just queue it without any dependencies break; case B_JOB_STATE_FAILED: case B_JOB_STATE_ABORTED: // TODO: return appropriate error return B_BAD_VALUE; } return B_OK; }
bool Parser::GetCmdLineIncludeFiles(const CC_ARRAY<CC_STRING>& ifiles, size_t np) { if( ifiles.size() == 0) return true; CC_STRING path; bool in_compiler_dir; for(size_t i = 0; i < ifiles.size(); i++) { if(!rtc->get_include_file_path(ifiles[i], CC_STRING(""), true, false, path, &in_compiler_dir)) { errmsg.Format("Can not find include file \"%s\"", ifiles[i].c_str()); return false; } RealFile *file; file = new RealFile; file->SetFileName(path); if( ! file->Open() ) { errmsg.Format("Can not open include file \"%s\"", ifiles[i].c_str()); return false; } PushIncludedFile(file, NULL, np, in_compiler_dir, conditionals.size()); if( ! RunEngine(1) ) return false; if(has_dep_file() && ! in_compiler_dir) AddDependency(" ", path.c_str()); } return true; }
WsGateService::WsGateService() :NTService("FreeRDP-WebConnect", "FreeRDP WebConnect") { m_dwServiceStartupType = SERVICE_AUTO_START; m_sDescription.assign("RDP Web access gateway"); AddDependency("Eventlog"); }
ResLocation SemCopyRawFile( const char *filename ) /************************************************/ { WResFileID fid; RcStatus ret; char *buffer; char full_filename[_MAX_PATH]; ResLocation loc; int err_code; WResFileOffset pos; buffer = RESALLOC( BUFFER_SIZE ); if( RcFindResource( filename, full_filename ) == -1 ) { RcError( ERR_CANT_FIND_FILE, filename ); goto HANDLE_ERROR; } if( AddDependency( full_filename ) ) goto HANDLE_ERROR; fid = RcIoOpenInput( full_filename, false ); if( fid == WRES_NIL_HANDLE ) { RcError( ERR_CANT_OPEN_FILE, filename, strerror( errno ) ); goto HANDLE_ERROR; } loc.start = SemStartResource(); pos = RESTELL( fid ); if( pos == -1 ) { RcError( ERR_READING_DATA, full_filename, strerror( errno ) ); RESCLOSE( fid ); goto HANDLE_ERROR; } else { ret = SemCopyDataUntilEOF( pos, fid, buffer, BUFFER_SIZE, &err_code ); if( ret != RS_OK ) { ReportCopyError( ret, ERR_READING_DATA, full_filename, err_code ); RESCLOSE( fid ); goto HANDLE_ERROR; } } loc.len = SemEndResource( loc.start ); RESCLOSE( fid ); RESFREE( buffer ); return( loc ); HANDLE_ERROR: ErrorHasOccured = true; loc.start = 0; loc.len = 0; RESFREE( buffer ); return( loc ); }
/** ** Define a new dependency. ** ** @param l Lua state. */ static int CclDefineDependency(lua_State *l) { const char *target; const char *required; int count; const char *value; int or_flag; int args; int j; int subargs; int k; args = lua_gettop(l); j = 0; target = LuaToString(l, j + 1); ++j; // // All or rules. // or_flag = 0; for (; j < args; ++j) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } subargs = lua_objlen(l, j + 1); for (k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); required = LuaToString(l, -1); lua_pop(l, 1); count = 1; if (k + 1 < subargs) { lua_rawgeti(l, j + 1, k + 2); if (lua_isnumber(l, -1)) { count = LuaToNumber(l, -1); ++k; } lua_pop(l, 1); } AddDependency(target, required, count, or_flag); or_flag = 0; } if (j + 1 < args) { ++j; value = LuaToString(l, j + 1); if (strcmp(value, "or")) { LuaError(l, "not or symbol: %s" _C_ value); return 0; } or_flag = 1; } } return 0; }
void FRCPassPostProcessVisualizeBuffer::AddVisualizationBuffer(FRenderingCompositeOutputRef InSource, const FString& InName) { Tiles.Add(TileData(InSource, InName)); if (InSource.IsValid()) { AddDependency(InSource); } }
std::vector<std::string> CArchiveScanner::GetAllArchivesUsedBy(const std::string& root, int depth) const { LOG_S(LOG_SECTION_ARCHIVESCANNER, "GetArchives: %s (depth %u)", root.c_str(), depth); // Protect against circular dependencies // (worst case depth is if all archives form one huge dependency chain) if ((unsigned)depth > archiveInfos.size()) { throw content_error("Circular dependency"); } std::vector<std::string> ret; std::string resolvedName = ArchiveNameResolver::GetGame(root); std::string lcname = StringToLower(ArchiveFromName(resolvedName)); std::map<std::string, ArchiveInfo>::const_iterator aii = archiveInfos.find(lcname); if (aii == archiveInfos.end()) { #ifdef UNITSYNC // unresolved dep, add it, so unitsync still shows this file ret.push_back(lcname); return ret; #else throw content_error("Archive \"" + lcname + "\" not found"); #endif } // Check if this archive has been replaced while (aii->second.replaced.length() > 0) { // FIXME instead of this, call this function recursively, to get the propper error handling aii = archiveInfos.find(aii->second.replaced); if (aii == archiveInfos.end()) { #ifdef UNITSYNC // unresolved dep, add it, so unitsync still shows this file ret.push_back(lcname); return ret; #else throw content_error("Unknown error parsing archive replacements"); #endif } } // add depth-first ret.push_back(aii->second.path + aii->second.origName); for (const std::string& dep: aii->second.archiveData.GetDependencies()) { const std::vector<std::string>& deps = GetAllArchivesUsedBy(dep, depth + 1); for (const std::string& depSub: deps) { AddDependency(ret, depSub); } } return ret; }
void File::ReadDependencies(FileManager& fileManager, const filesystem::path& file) { auto dependencyFile = fileManager.GetOrCreateFile(file); auto dependencyFileStream = fileManager.GetFileSystem().OpenStream(file); if (dependencyFileStream) { std::string line; std::getline(*dependencyFileStream, line, ':'); while (std::getline(*dependencyFileStream, line, '\\')) { AddDependency(fileManager.GetOrCreateFile(internal::Trim(line))); } } }
void TodoTab::handleAddChildTodoRequested () { const auto& curIdx = Ui_.TodoTree_->currentIndex (); if (!curIdx.isValid () || curIdx.parent ().isValid ()) return; AddTodoDialog dia; if (dia.exec () != QDialog::Accepted) return; const auto& selectedId = curIdx.data (StorageModel::Roles::ItemID).toString (); const auto& item = dia.GetItem (); const auto storage = Core::Instance ().GetTodoManager ()->GetTodoStorage (); storage->AddItem (item); storage->AddDependency (selectedId, item->GetID ()); }
void SemWINAddResFile( char *filename ) /*************************************/ { char full_filename[_MAX_PATH]; if( RcFindResource( filename, full_filename ) == -1 ) { RcError( ERR_CANT_FIND_FILE, filename ); goto HANDLE_ERROR; } if( AddDependency( full_filename ) ) goto HANDLE_ERROR; if( copyResourcesFromRes( full_filename ) ) goto HANDLE_ERROR; RESFREE( filename ); return; HANDLE_ERROR: ErrorHasOccured = true; RESFREE( filename ); }
void CArchiveScanner::ScanArchive(const std::string& fullName, bool doChecksum) { struct stat info; stat(fullName.c_str(), &info); const std::string fn = filesystem.GetFilename(fullName); const std::string fpath = filesystem.GetDirectory(fullName); const std::string lcfn = StringToLower(fn); //! Determine whether this archive has earlier be found to be broken std::map<std::string, BrokenArchive>::iterator bai = brokenArchives.find(lcfn); if (bai != brokenArchives.end()) { if ((unsigned)info.st_mtime == bai->second.modified && fpath == bai->second.path) { bai->second.updated = true; return; } } //! Determine whether to rely on the cached info or not bool cached = false; std::map<std::string, ArchiveInfo>::iterator aii = archiveInfo.find(lcfn); if (aii != archiveInfo.end()) { //! This archive may have been obsoleted, do not process it if so if (aii->second.replaced.length() > 0) { return; } if ((unsigned)info.st_mtime == aii->second.modified && fpath == aii->second.path) { cached = true; aii->second.updated = true; } //! If we are here, we could have invalid info in the cache //! Force a reread if it's a directory archive, as st_mtime only //! reflects changes to the directory itself, not the contents. if (!cached) { archiveInfo.erase(aii); } } //! Time to parse the info we are interested in if (cached) { //! If cached is true, aii will point to the archive if (doChecksum && (aii->second.checksum == 0)) aii->second.checksum = GetCRC(fullName); } else { CArchiveBase* ar = CArchiveFactory::OpenArchive(fullName); if (!ar || !ar->IsOpen()) { logOutput.Print("Unable to open archive: %s", fullName.c_str()); return; } ArchiveInfo ai; std::string error = ""; std::string mapfile; bool hasModinfo = ar->FileExists("modinfo.lua"); bool hasMapinfo = ar->FileExists("mapinfo.lua"); //! check for smf/sm3 and if the uncompression of important files is too costy for (unsigned fid = 0; fid != ar->NumFiles(); ++fid) { std::string name; int size; ar->FileInfo(fid, name, size); const std::string lowerName = StringToLower(name); const std::string ext = filesystem.GetExtension(lowerName); if ((ext == "smf") || (ext == "sm3")) { mapfile = name; } const unsigned char metaFileClass = GetMetaFileClass(lowerName); if ((metaFileClass != 0) && !(ar->HasLowReadingCost(fid))) { //! is a meta-file and not cheap to read if (metaFileClass == 1) { //! 1st class error = "Unpacking/reading cost for meta file " + name + " is too high, please repack the archive (make sure to use a non-solid algorithm, if applicable)"; break; } else if (metaFileClass == 2) { //! 2nd class logOutput.Print(LOG_ARCHIVESCANNER, "Warning: Archive %s: The cost for reading a 2nd class meta-file is too high: %s", fullName.c_str(), name.c_str()); } } } if (!error.empty()) { //! we already have an error, no further evaluation required } if (hasMapinfo || !mapfile.empty()) { //! it is a map if (hasMapinfo) { ScanArchiveLua(ar, "mapinfo.lua", ai, error); } else if (hasModinfo) { //! backwards-compat for modinfo.lua in maps ScanArchiveLua(ar, "modinfo.lua", ai, error); } if (ai.archiveData.GetName().empty()) { //! FIXME The name will never be empty, if version is set (see HACK in ArchiveData) ai.archiveData.SetInfoItemValueString("name", filesystem.GetBasename(mapfile)); } if (ai.archiveData.GetMapFile().empty()) { ai.archiveData.SetInfoItemValueString("mapfile", mapfile); } AddDependency(ai.archiveData.GetDependencies(), "Map Helper v1"); ai.archiveData.SetInfoItemValueInteger("modType", modtype::map); logOutput.Print(LOG_ARCHIVESCANNER, "Found new map: %s", ai.archiveData.GetName().c_str()); } else if (hasModinfo) { //! it is a mod ScanArchiveLua(ar, "modinfo.lua", ai, error); if (ai.archiveData.GetModType() == modtype::primary) { AddDependency(ai.archiveData.GetDependencies(), "Spring content v1"); } logOutput.Print(LOG_ARCHIVESCANNER, "Found new game: %s", ai.archiveData.GetName().c_str()); } else { //! neither a map nor a mod: error error = "missing modinfo.lua/mapinfo.lua"; } delete ar; if (!error.empty()) { //! for some reason, the archive is marked as broken logOutput.Print("Failed to scan %s (%s)", fullName.c_str(), error.c_str()); //! record it as broken, so we don't need to look inside everytime BrokenArchive ba; ba.path = fpath; ba.modified = info.st_mtime; ba.updated = true; ba.problem = error; brokenArchives[lcfn] = ba; return; } ai.path = fpath; ai.modified = info.st_mtime; ai.origName = fn; ai.updated = true; //! Optionally calculate a checksum for the file //! To prevent reading all files in all directory (.sdd) archives //! every time this function is called, directory archive checksums //! are calculated on the fly. if (doChecksum) { ai.checksum = GetCRC(fullName); } else { ai.checksum = 0; } archiveInfo[lcfn] = ai; } }
static YYTOKENTYPE scanCPPDirective( ScanValue *value ) /******************************************************/ /* This function takes the correct action for the #line directive and returns */ /* the token following the preprocessor stuff. It uses Scan to do it's */ /* scanning. DON'T call this function from within Scan or the functions it */ /* calls unless you are very careful about recurtion. */ { YYTOKENTYPE token; int linenum; if( StopInvoked ) { RcFatalError( ERR_STOP_REQUESTED ); } /* get the "line" or "pragma" directive */ token = scanDFA( value ); if( token != Y_NAME ) { RcFatalError( ERR_INVALID_CPP ); } if( stricmp( value->string.string, "line" ) == 0 ) { RESFREE( value->string.string ); /* get the line number */ token = scanDFA( value ); if( token != Y_INTEGER ) { RcFatalError( ERR_INVALID_CPP_LINE ); } RESFREE( value->intinfo.str ); value->intinfo.str = NULL; linenum = value->intinfo.val; /* get the filename if there is one */ token = scanDFA( value ); if( token == Y_STRING ) { RcIoSetLogicalFileInfo( linenum, value->string.string ); if( AddDependency( value->string.string ) ) { ErrorHasOccured = true; } RESFREE( value->string.string ); token = scanDFA( value ); } else { RcIoSetLogicalFileInfo( linenum, NULL ); } } else if( stricmp( value->string.string, "pragma" ) == 0 ) { RESFREE( value->string.string ); token = Y_POUND_PRAGMA; } else if( stricmp( value->string.string, "error" ) == 0 ) { char buf[80]; unsigned i; i = 0; while( LookAhead != '\n' && LookAhead != EOF ) { buf[i] = LookAhead; i ++; GetNextChar(); } buf[i] = '\0'; RcFatalError( ERR_TEXT_FROM_CPP, buf ); } else { RcFatalError( ERR_INVALID_CPP ); } return( token ); } /* scanCPPDirective */
void CArchiveScanner::ReadCacheData(const std::string& filename) { LuaParser p(filename, SPRING_VFS_RAW, SPRING_VFS_BASE); if (!p.Execute()) { logOutput.Print("ERROR in " + filename + ": " + p.GetErrorLog()); } const LuaTable archiveCache = p.GetRoot(); const LuaTable archives = archiveCache.SubTable("archives"); // Do not load old version caches const int ver = archiveCache.GetInt("internalVer", (INTERNAL_VER + 1)); if (ver != INTERNAL_VER) { return; } for (int i = 1; archives.KeyExists(i); ++i) { const LuaTable curArchive = archives.SubTable(i); const LuaTable archived = curArchive.SubTable("archivedata"); ArchiveInfo ai; ai.origName = curArchive.GetString("name", ""); ai.path = curArchive.GetString("path", ""); // do not use LuaTable.GetInt() for 32-bit integers, the Spring lua // library uses 32-bit floats to represent numbers, which can only // represent 2^24 consecutive integers ai.modified = strtoul(curArchive.GetString("modified", "0").c_str(), 0, 10); ai.checksum = strtoul(curArchive.GetString("checksum", "0").c_str(), 0, 10); ai.updated = false; ai.archiveData = GetArchiveData(archived); if (ai.archiveData.modType == modtype::map) { AddDependency(ai.archiveData.dependencies, "Map Helper v1"); } else if (ai.archiveData.modType == modtype::primary) { AddDependency(ai.archiveData.dependencies, "Spring content v1"); } std::string lcname = StringToLower(ai.origName); archiveInfo[lcname] = ai; } const LuaTable brokenArchives = archiveCache.SubTable("brokenArchives"); for (int i = 1; brokenArchives.KeyExists(i); ++i) { const LuaTable curArchive = brokenArchives.SubTable(i); BrokenArchive ba; std::string name = curArchive.GetString("name", ""); ba.path = curArchive.GetString("path", ""); ba.modified = strtoul(curArchive.GetString("modified", "0").c_str(), 0, 10); ba.updated = false; std::string lcname = StringToLower(name); this->brokenArchives[lcname] = ba; } isDirty = false; }
ModuleC::ModuleC() { AddDependency(CLASSINFO(ModuleD)); }
ModuleA::ModuleA() { AddDependency(CLASSINFO(ModuleB)); AddDependency(CLASSINFO(ModuleD)); }
void Plan::ReplaceDependency(Unit* source, Unit* target, Unit* unit) { RemoveDependency(source, target); AddDependency(source, unit); AddDependency(unit, target); }
/* Replaces the current dependents set for s with a new one */ void Dependency_Graph::ReplaceDependents(std::string s, std::set<std::string> newDependents){ std::map<std::string, std::set<std::string> >::iterator temp_it; std::set<std::string>::iterator temp_set; std::map<std::string, std::set<std::string> >::iterator temp_set2; std::set<std::string>::iterator temp_set3; //access the set of dependents temp_name = s + dependents; temp_it = omni_set.find(temp_name); //make sure it exists if (temp_it != omni_set.end()){ //iterate through the old set and remove s from each elements dependees set for (temp_set = temp_it->second.begin(); temp_set != temp_it->second.end(); temp_set++){ pair_count--; //pair is gone temp_name = *temp_set + dependees; //find the dependees set for the element of dependents temp_set2 = omni_set.find(temp_name); if (temp_set2 != omni_set.end()){ //find s in the set of dependees temp_set3 = temp_set2->second.find(s); if (temp_set3 != temp_set2->second.end()){ temp_set2->second.erase(s);//delete s from the set } } } } temp_name = s + dependents; //find dependents set for s temp_it = omni_set.find(temp_name); // make sure set exists if (temp_it != omni_set.end()){ temp_it->second.clear(); //delete all the contents of the set //for each element of the replacement set add it and s to dependency graph for (temp_set = newDependents.begin(); temp_set != newDependents.end(); temp_set++){ AddDependency(s, *temp_set); } } else{ // if set did not exist no need to clear it //create a dependency between s and each element of the new dependents set for (temp_set = newDependents.begin(); temp_set != newDependents.end(); temp_set++){ AddDependency(s, *temp_set); } } }
int main(int argc, char *argv[]) { ModularContext mctx; Module *master; Module *output; int timer; srand(0); mctx.rate = SAMPLE_RATE; ModularInitialize(&mctx); master = ModularMaster(&mctx); output = ModularOutput(&mctx); Module *osc = NewModule(&mctx, &ModOscillator); Module *env = NewModule(&mctx, &ModADSR); OscillatorGet(osc)->waveform = OscBandlimitedSaw; *ADSRGet(env)->A = 0.006; *ADSRGet(env)->D = 0.700; *ADSRGet(env)->S = 0.000; *ADSRGet(env)->R = 0.100; *ADSRGet(env)->trig = 0.0; OscillatorGet(osc)->gain = env->out; AddDependency(&mctx, osc, env); Module *filt = NewModule(&mctx, &ModFilter); FilterSetInput(&mctx, filt, osc); Module *env2filt = NewModule(&mctx, &ModMatrix); MatrixSetInput(&mctx, env2filt, env); MatrixScale(env2filt, 0.0, 1.0, 10.0, 10000.0); FilterGet(filt)->cutoff = env2filt->out; AddDependency(&mctx, filt, env2filt); Module *env2reso = NewModule(&mctx, &ModMatrix); MatrixSetInput(&mctx, env2reso, env); MatrixScale(env2reso, 0.0, 1.0, 0.1, 2.0); FilterGet(filt)->reso = env2reso->out; AddDependency(&mctx, filt, env2reso); MixerSlot *slot = MixerAddSlot(&mctx, master, filt, 0.3, 0.0); KeyController *kc = NewMonoSynth(); OscillatorGet(osc)->freq = MonoSynthGet(kc)->freq; ADSRGet(env)->trig = MonoSynthGet(kc)->trig; Module *bassosc = NewModule(&mctx, &ModOscillator); Module *bassenv = NewModule(&mctx, &ModADSR); OscillatorGet(bassosc)->waveform = OscBandlimitedSaw; *ADSRGet(bassenv)->A = 0.006; *ADSRGet(bassenv)->D = 0.200; *ADSRGet(bassenv)->S = 0.000; *ADSRGet(bassenv)->R = 0.100; *ADSRGet(bassenv)->trig = 0.0; //OscillatorGet(bassosc)->gain = bassenv->out; AddDependency(&mctx, bassosc, bassenv); Module *bassfilt = NewModule(&mctx, &ModFilter); FilterSetInput(&mctx, bassfilt, bassosc); Module *bassenv2filt = NewModule(&mctx, &ModMatrix); MatrixSetInput(&mctx, bassenv2filt, bassenv); MatrixScale(bassenv2filt, 0.0, 1.0, 50.0, 5000.0); FilterGet(bassfilt)->cutoff = bassenv2filt->out; AddDependency(&mctx, bassfilt, bassenv2filt); *FilterGet(bassfilt)->reso = 0.4; MixerSlot *bassslot = MixerAddSlot(&mctx, master, bassfilt, 0.3, 0.0); KeyController *bkc = NewMonoSynth(); OscillatorGet(bassosc)->freq = MonoSynthGet(bkc)->freq; ADSRGet(bassenv)->trig = MonoSynthGet(bkc)->trig; for (timer=0; ; timer++) { ModularStep(&mctx); if (timer % 96000 == 84000) seq = seqs[((timer / 96000) % 2)]; if (timer % 12000 == 0) KeyControllerKeyDown(kc, seq[(timer / 12000) % 4] - 12, 64); if (timer % 24000 == 22000) KeyControllerKeyUp(kc, seq[(timer / 12000) % 4] - 12); KeyControllerUpdate(kc); if (timer % 12000 == 0) KeyControllerKeyDown(bkc, bass[(timer / 12000) % 16], 64); if (timer % 12000 == 11000) KeyControllerKeyUp(bkc, bass[(timer / 12000) % 16]); KeyControllerUpdate(bkc); put_frame(output->out[0] * OUTPUT_SCALE, output->out[1] * OUTPUT_SCALE); } return 0; }
void SemWINAddSingleLineResource( WResID * name, YYTOKENTYPE type, FullMemFlags * fullflags, char * filename ) /***************************************************************/ { ResMemFlags flags; ResMemFlags group_flags; ResMemFlags purity_option; /* used for icon and cursor resoures */ char full_filename[_MAX_PATH]; if( ErrorHasOccured ) { RCFREE( name ); RCFREE( filename ); return; } if( CmdLineParms.VersionStamp30 ) { purity_option = CUR_ICON_PURITY_30; } else { purity_option = CUR_ICON_PURITY_31; } if( RcFindResource( filename, full_filename ) == -1 ) { RcError( ERR_CANT_FIND_FILE, filename ); goto HANDLE_ERROR; } if( AddDependency( full_filename ) ) goto HANDLE_ERROR; switch( type ) { case Y_ICON: if( fullflags != NULL ) { SemWINCheckMemFlags( fullflags, 0, MEMFLAG_MOVEABLE|MEMFLAG_DISCARDABLE, purity_option ); flags = fullflags->flags; SemWINCheckMemFlags( fullflags, 0, MEMFLAG_MOVEABLE|MEMFLAG_DISCARDABLE, MEMFLAG_PURE ); group_flags = fullflags->flags; } else { flags = MEMFLAG_MOVEABLE|MEMFLAG_DISCARDABLE| purity_option; group_flags = MEMFLAG_MOVEABLE|MEMFLAG_DISCARDABLE|MEMFLAG_PURE; } AddIconResource( name, flags, group_flags, full_filename ); break; case Y_CURSOR: if( fullflags != NULL ) { SemWINCheckMemFlags( fullflags, 0, MEMFLAG_MOVEABLE|MEMFLAG_DISCARDABLE, purity_option ); flags = fullflags->flags; SemWINCheckMemFlags( fullflags, 0, MEMFLAG_MOVEABLE|MEMFLAG_DISCARDABLE, MEMFLAG_PURE ); group_flags = fullflags->flags; } else { flags = MEMFLAG_MOVEABLE|MEMFLAG_DISCARDABLE| purity_option; group_flags = MEMFLAG_MOVEABLE|MEMFLAG_DISCARDABLE|MEMFLAG_PURE; } AddCursorResource( name, flags, group_flags, full_filename ); break; case Y_BITMAP: if( fullflags != NULL ) { SemWINCheckMemFlags( fullflags, 0, MEMFLAG_MOVEABLE, MEMFLAG_PURE ); flags = fullflags->flags; } else { flags = MEMFLAG_MOVEABLE|MEMFLAG_PURE; } AddBitmapResource( name, flags, full_filename ); break; case Y_FONT: if( fullflags != NULL ) { SemWINCheckMemFlags( fullflags, 0, MEMFLAG_MOVEABLE|MEMFLAG_DISCARDABLE, MEMFLAG_PURE ); flags = fullflags->flags; } else { flags = MEMFLAG_MOVEABLE|MEMFLAG_DISCARDABLE|MEMFLAG_PURE; } AddFontResources( name, flags, full_filename ); break; default: RCFREE( name ); break; } RCFREE( filename ); return; HANDLE_ERROR: ErrorHasOccured = true; RCFREE( name ); RCFREE( filename ); } /* SemWINAddSingleLineResource */
void CArchiveScanner::ScanArchive(const std::string& fullName, bool doChecksum) { const std::string fn = FileSystem::GetFilename(fullName); const std::string fpath = FileSystem::GetDirectory(fullName); const std::string lcfn = StringToLower(fn); // Stat file struct stat info = {0}; int statfailed = stat(fullName.c_str(), &info); // If stat fails, assume the archive is not broken nor cached if (!statfailed) { // Determine whether this archive has earlier be found to be broken std::map<std::string, BrokenArchive>::iterator bai = brokenArchives.find(lcfn); if (bai != brokenArchives.end()) { if ((unsigned)info.st_mtime == bai->second.modified && fpath == bai->second.path) { bai->second.updated = true; return; } } // Determine whether to rely on the cached info or not std::map<std::string, ArchiveInfo>::iterator aii = archiveInfos.find(lcfn); if (aii != archiveInfos.end()) { // This archive may have been obsoleted, do not process it if so if (!aii->second.replaced.empty()) { return; } if ((unsigned)info.st_mtime == aii->second.modified && fpath == aii->second.path) { // cache found update checksum if wanted aii->second.updated = true; if (doChecksum && (aii->second.checksum == 0)) { aii->second.checksum = GetCRC(fullName); } return; } else { if (aii->second.updated) { const std::string filename = aii->first; LOG_L(L_ERROR, "Found a \"%s\" already in \"%s\", ignoring.", fullName.c_str(), (aii->second.path + aii->second.origName).c_str()); if (IsBaseContent(filename)) { throw user_error(std::string("duplicate base content detected:\n\t") + aii->second.path + std::string("\n\t") + fpath + std::string("\nPlease fix your configuration/installation as this can cause desyncs!")); } return; } // If we are here, we could have invalid info in the cache // Force a reread if it is a directory archive (.sdd), as // st_mtime only reflects changes to the directory itself, // not the contents. archiveInfos.erase(aii); } } } boost::scoped_ptr<IArchive> ar(archiveLoader.OpenArchive(fullName)); if (!ar || !ar->IsOpen()) { LOG_L(L_WARNING, "Unable to open archive: %s", fullName.c_str()); // record it as broken, so we don't need to look inside everytime BrokenArchive& ba = brokenArchives[lcfn]; ba.path = fpath; ba.modified = info.st_mtime; ba.updated = true; ba.problem = "Unable to open archive"; return; } std::string error; std::string mapfile; const bool hasModinfo = ar->FileExists("modinfo.lua"); const bool hasMapinfo = ar->FileExists("mapinfo.lua"); ArchiveInfo ai; auto& ad = ai.archiveData; if (hasMapinfo) { ScanArchiveLua(ar.get(), "mapinfo.lua", ai, error); if (ad.GetMapFile().empty()) { LOG_L(L_WARNING, "%s: mapfile isn't set in mapinfo.lua, please set it for faster loading!", fullName.c_str()); mapfile = SearchMapFile(ar.get(), error); } } else if (hasModinfo) { ScanArchiveLua(ar.get(), "modinfo.lua", ai, error); } else { mapfile = SearchMapFile(ar.get(), error); } CheckCompression(ar.get(), fullName, error); if (!error.empty()) { // for some reason, the archive is marked as broken LOG_L(L_WARNING, "Failed to scan %s (%s)", fullName.c_str(), error.c_str()); // record it as broken, so we don't need to look inside everytime BrokenArchive& ba = brokenArchives[lcfn]; ba.path = fpath; ba.modified = info.st_mtime; ba.updated = true; ba.problem = error; return; } if (hasMapinfo || !mapfile.empty()) { // it is a map if (ad.GetName().empty()) { // FIXME The name will never be empty, if version is set (see HACK in ArchiveData) ad.SetInfoItemValueString("name_pure", FileSystem::GetBasename(mapfile)); ad.SetInfoItemValueString("name", FileSystem::GetBasename(mapfile)); } if (ad.GetMapFile().empty()) { ad.SetInfoItemValueString("mapfile", mapfile); } AddDependency(ad.GetDependencies(), "Map Helper v1"); ad.SetInfoItemValueInteger("modType", modtype::map); LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new map: %s", ad.GetNameVersioned().c_str()); } else if (hasModinfo) { // it is a game if (ad.GetModType() == modtype::primary) { AddDependency(ad.GetDependencies(), "Spring content v1"); } LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new game: %s", ad.GetNameVersioned().c_str()); } else { // neither a map nor a mod: error error = "missing modinfo.lua/mapinfo.lua"; } ai.path = fpath; ai.modified = info.st_mtime; ai.origName = fn; ai.updated = true; ai.checksum = (doChecksum) ? GetCRC(fullName) : 0; archiveInfos[lcfn] = ai; }
/* Replaces the dependees set for s with a new set of dependees */ void Dependency_Graph::ReplaceDependees(std::string s, std::set<std::string> newDependees){ std::map<std::string, std::set<std::string> >::iterator temp_it; std::set<std::string>::iterator temp_set; std::map<std::string, std::set<std::string> >::iterator temp_set2; std::set<std::string>::iterator temp_set3; temp_name = s + dependees; //find the set of dependees temp_it = omni_set.find(temp_name); if (temp_it != omni_set.end()){ //remove s from the dependents set for each element in the current dependees for s for (temp_set = temp_it->second.begin(); temp_set != temp_it->second.end(); temp_set++){ pair_count--; // pair gone temp_name = *temp_set + dependents; temp_set2 = omni_set.find(temp_name); if (temp_set2 != omni_set.end()){ temp_set3 = temp_set2->second.find(s); if (temp_set3 != temp_set2->second.end()){ temp_set2->second.erase(s); } } } } //get dependees set for s temp_name = s + dependees; temp_it = omni_set.find(temp_name); //delete dependees set and then add each dependency for each element in new set of dependees and s if (temp_it != omni_set.end()){ temp_it->second.clear(); for (temp_set = newDependees.begin(); temp_set != newDependees.end(); temp_set++){ AddDependency(*temp_set, s); } } else{ // if set did not exist just add dependency between each element of new dependees and s for (temp_set = newDependees.begin(); temp_set != newDependees.end(); temp_set++){ AddDependency(*temp_set, s); } } }
void CArchiveScanner::ScanArchive(const std::string& fullName, bool doChecksum) { unsigned modifiedTime = 0; if (CheckCachedData(fullName, &modifiedTime, doChecksum)) return; isDirty = true; const std::string& fn = FileSystem::GetFilename(fullName); const std::string& fpath = FileSystem::GetDirectory(fullName); const std::string& lcfn = StringToLower(fn); std::unique_ptr<IArchive> ar(archiveLoader.OpenArchive(fullName)); if (ar == nullptr || !ar->IsOpen()) { LOG_L(L_WARNING, "[AS::%s] unable to open archive \"%s\"", __func__, fullName.c_str()); // record it as broken, so we don't need to look inside everytime BrokenArchive& ba = brokenArchives[lcfn]; ba.path = fpath; ba.modified = modifiedTime; ba.updated = true; ba.problem = "Unable to open archive"; // does not count as a scan // numScannedArchives += 1; return; } std::string error; std::string arMapFile; // file in archive with "smf" or "sm3" extension std::string miMapFile; // value for the 'mapfile' key parsed from mapinfo const bool hasModinfo = ar->FileExists("modinfo.lua"); const bool hasMapinfo = ar->FileExists("mapinfo.lua"); ArchiveInfo ai; ArchiveData& ad = ai.archiveData; // execute the respective .lua, otherwise assume this archive is a map if (hasMapinfo) { ScanArchiveLua(ar.get(), "mapinfo.lua", ai, error); if ((miMapFile = ad.GetMapFile()).empty()) { LOG_L(L_WARNING, "[AS::%s] set the 'mapfile' key in mapinfo.lua of archive \"%s\" for faster loading!", __func__, fullName.c_str()); arMapFile = SearchMapFile(ar.get(), error); } } else if (hasModinfo) { ScanArchiveLua(ar.get(), "modinfo.lua", ai, error); } else { arMapFile = SearchMapFile(ar.get(), error); } if (!CheckCompression(ar.get(), fullName, error)) { // for some reason, the archive is marked as broken LOG_L(L_WARNING, "[AS::%s] failed to scan \"%s\" (%s)", __func__, fullName.c_str(), error.c_str()); // record it as broken, so we don't need to look inside everytime BrokenArchive& ba = brokenArchives[lcfn]; ba.path = fpath; ba.modified = modifiedTime; ba.updated = true; ba.problem = error; // does count as a scan numScannedArchives += 1; return; } if (hasMapinfo || !arMapFile.empty()) { // map archive if ((ad.GetName()).empty()) { // FIXME The name will never be empty, if version is set (see HACK in ArchiveData) ad.SetInfoItemValueString("name_pure", FileSystem::GetBasename(arMapFile)); ad.SetInfoItemValueString("name", FileSystem::GetBasename(arMapFile)); } if (miMapFile.empty()) ad.SetInfoItemValueString("mapfile", arMapFile); AddDependency(ad.GetDependencies(), GetMapHelperContentName()); ad.SetInfoItemValueInteger("modType", modtype::map); LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new map: %s", ad.GetNameVersioned().c_str()); } else if (hasModinfo) { // game or base-type (cursors, bitmaps, ...) archive // babysitting like this is really no longer required if (ad.IsGame() || ad.IsMenu()) AddDependency(ad.GetDependencies(), GetSpringBaseContentName()); LOG_S(LOG_SECTION_ARCHIVESCANNER, "Found new game: %s", ad.GetNameVersioned().c_str()); } else { // neither a map nor a mod: error error = "missing modinfo.lua/mapinfo.lua"; } ai.path = fpath; ai.modified = modifiedTime; ai.origName = fn; ai.updated = true; ai.checksum = (doChecksum) ? GetCRC(fullName) : 0; archiveInfos[lcfn] = ai; numScannedArchives += 1; }
ModuleB::ModuleB() { AddDependency(CLASSINFO(ModuleC)); AddDependency(CLASSINFO(ModuleD)); }
void CArchiveScanner::ScanArchive(const std::string& fullName, bool doChecksum) { struct stat info; stat(fullName.c_str(), &info); const std::string fn = filesystem.GetFilename(fullName); const std::string fpath = filesystem.GetDirectory(fullName); const std::string lcfn = StringToLower(fn); // Determine whether this archive has earlier be found to be broken std::map<std::string, BrokenArchive>::iterator bai = brokenArchives.find(lcfn); if (bai != brokenArchives.end()) { if ((unsigned)info.st_mtime == bai->second.modified && fpath == bai->second.path) { bai->second.updated = true; return; } } // Determine whether to rely on the cached info or not bool cached = false; std::map<std::string, ArchiveInfo>::iterator aii = archiveInfo.find(lcfn); if (aii != archiveInfo.end()) { // This archive may have been obsoleted, do not process it if so if (aii->second.replaced.length() > 0) { return; } if ((unsigned)info.st_mtime == aii->second.modified && fpath == aii->second.path) { cached = true; aii->second.updated = true; } // If we are here, we could have invalid info in the cache // Force a reread if it's a directory archive, as st_mtime only // reflects changes to the directory itself, not the contents. if (!cached) { archiveInfo.erase(aii); } } // Time to parse the info we are interested in if (cached) { // If cached is true, aii will point to the archive if (doChecksum && (aii->second.checksum == 0)) aii->second.checksum = GetCRC(fullName); } else { CArchiveBase* ar = CArchiveFactory::OpenArchive(fullName); if (ar && ar->IsOpen()) { ArchiveInfo ai; std::string mapfile; bool hasModinfo = false; bool hasMapinfo = false; for (unsigned fid = 0; fid != ar->NumFiles(); ++fid) { std::string name; int size; ar->FileInfo(fid, name, size); const std::string lowerName = StringToLower(name); const std::string ext = filesystem.GetExtension(lowerName); if ((ext == "smf") || (ext == "sm3")) { mapfile = name; } else if (lowerName == "modinfo.lua") { hasModinfo = true; } else if (lowerName == "mapinfo.lua") { hasMapinfo = true; } } if (hasMapinfo || !mapfile.empty()) { // it is a map if (hasMapinfo) { ScanArchiveLua(ar, "mapinfo.lua", ai); } else if (hasModinfo) { // backwards-compat for modinfo.lua in maps ScanArchiveLua(ar, "modinfo.lua", ai); } if (ai.archiveData.name.empty()) { ai.archiveData.name = filesystem.GetBasename(mapfile); } if (ai.archiveData.mapfile.empty()) { ai.archiveData.mapfile = mapfile; } AddDependency(ai.archiveData.dependencies, "Map Helper v1"); ai.archiveData.modType = modtype::map; } else if (hasModinfo) { // it is a mod ScanArchiveLua(ar, "modinfo.lua", ai); if (ai.archiveData.modType == modtype::primary) AddDependency(ai.archiveData.dependencies, "Spring content v1"); } else { // neither a map nor a mod: error logOutput.Print(LOG_ARCHIVESCANNER, "Failed to scan %s (missing modinfo.lua/mapinfo.lua)", fullName.c_str()); delete ar; // record it as broken, so we don't need to look inside everytime BrokenArchive ba; ba.path = fpath; ba.modified = info.st_mtime; ba.updated = true; brokenArchives[lcfn] = ba; return; } ai.path = fpath; ai.modified = info.st_mtime; ai.origName = fn; ai.updated = true; delete ar; // Optionally calculate a checksum for the file // To prevent reading all files in all directory (.sdd) archives // every time this function is called, directory archive checksums // are calculated on the fly. if (doChecksum) { ai.checksum = GetCRC(fullName); } else { ai.checksum = 0; } archiveInfo[lcfn] = ai; } else { logOutput.Print(LOG_ARCHIVESCANNER, "Unable to open archive: %s", fullName.c_str()); } } }
void SemOS2AddSingleLineResource( WResID *name, YYTOKENTYPE type, FullOptFlagsOS2 *fullflags, char *filename ) /*****************************************************************/ { ResLocation start; ResMemFlags flags, flagsMDP, flagsMP; char full_filename[_MAX_PATH]; static bool firstIcon = true; if( ErrorHasOccured ) { RCFREE( name ); RCFREE( filename ); return; } if( RcFindResource( filename, full_filename ) == -1 ) { RcError( ERR_CANT_FIND_FILE, filename ); goto HANDLE_ERROR; } if( AddDependency( full_filename ) ) goto HANDLE_ERROR; flagsMDP = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE | MEMFLAG_PURE; flagsMP = MEMFLAG_MOVEABLE | MEMFLAG_PURE; switch( type ) { case Y_DEFAULTICON: /* DEFAULTICON doesn't have a name, let's make our own */ name = (WResID*)RCALLOC( sizeof( WResID ) ); name->IsName = false; name->ID.Num = 999; firstIcon = true; /* Trigger a warning if we have one already */ /* Note the fallthrough! */ case Y_POINTER: case Y_ICON: if( fullflags != NULL ) { SemOS2CheckResFlags( fullflags, 0, MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE, 0 ); flags = fullflags->flags; } else { flags = flagsMDP; } /* Duplicate the first icon encountered as the default icon IFF it has resource ID equal to 1 */ if( firstIcon && !name->IsName && (name->ID.Num == 999 || name->ID.Num == 1) ) { WResID *id; id = (WResID*)RCALLOC( sizeof( WResID ) ); if( id == NULL ) break; firstIcon = false; id->IsName = false; id->ID.Num = 22; start = SemCopyRawFile( filename ); SemAddResourceFree( name, WResIDFromNum( OS2_RT_POINTER ), flags, start ); start = SemCopyRawFile( filename ); SemAddResourceFree( id, WResIDFromNum( OS2_RT_DEFAULTICON ), flagsMDP, start ); } else { start = SemCopyRawFile( filename ); SemAddResourceFree( name, WResIDFromNum( OS2_RT_POINTER ), flags, start ); } break; case Y_BITMAP: if( fullflags != NULL ) { SemOS2CheckResFlags( fullflags, 0, MEMFLAG_MOVEABLE, MEMFLAG_PURE ); flags = fullflags->flags; } else { flags = flagsMP; } start = SemCopyRawFile( filename ); SemAddResourceFree( name, WResIDFromNum( OS2_RT_BITMAP ), flags, start ); break; case Y_FONT: if( fullflags != NULL ) { SemOS2CheckResFlags( fullflags, 0, MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE, MEMFLAG_PURE ); flags = fullflags->flags; } else { flags = flagsMDP; } AddFontResources( name, flags, full_filename ); break; default: RCFREE( name ); break; } RCFREE( filename ); return; HANDLE_ERROR: ErrorHasOccured = true; RCFREE( name ); RCFREE( filename ); } /* SemOS2AddSingleLineResource */
/* Parse the input file and update the global symbol table and macro table, * output the stripped file contents to devices if OUTFILE is not nil. * * Returns a pointer to the error messages on failure, or nil on success. */ bool Parser::DoFile(InternalTables *intab, size_t num_preprocessors, File *infile, ParserContext *ctx) { bool ignored; FILE *out_fp; bool retval = false; CC_STRING bak_fname, out_fname; struct stat stb; struct utimbuf utb; if(ctx) { ignored = ctx->check_ignore(infile->name); if( ignored && ! has_dep_file() ) return true; } else ignored = false; if( stat(infile->name, &stb) == 0 ) { utb.actime = stb.st_atime; utb.modtime = stb.st_mtime; } if( ! infile->Open() ) { errmsg.Format("Cannot open \"%s\" for reading\n"); return false; } out_fp = NULL; if(ctx != NULL && ctx->outfile != ParserContext::OF_NULL ) { if( ctx->outfile == ParserContext::OF_STDOUT ) out_fp = stdout; else { #if SANITY_CHECK assert( ! ctx->baksuffix.isnull() ); #endif if( ctx->baksuffix[0] != ParserContext::MAGIC_CHAR ) bak_fname = infile->name + ctx->baksuffix; else out_fname = infile->name; int fd; char tmp_outfile[32]; strcpy(tmp_outfile, "@cl@-XXXXXX"); fd = mkstemp(tmp_outfile); if( fd < 0 ) { errmsg.Format("Cannot open \"%s\" for writing\n", tmp_outfile); infile->Close(); return false; } out_fp = fdopen(fd, "wb"); out_fname = tmp_outfile; } } if(ctx == NULL) memset(writers, 0, sizeof(writers)); else { writers[VCH_CL] = NULL; if(!ctx->of_array[VCH_DEP].isnull()) writers[VCH_DEP] = gvar_file_writers[VCH_DEP]; if(!ctx->of_array[VCH_CV].isnull()) writers[VCH_CV] = gvar_file_writers[VCH_CV]; } if( num_preprocessors >= COUNT_OF(Parser::preprocessors) ) num_preprocessors = COUNT_OF(Parser::preprocessors); Reset(intab, num_preprocessors, ctx); if(has_dep_file()) AddDependency("", infile->name); PushIncludedFile(infile, out_fp, COUNT_OF(Parser::preprocessors), false, conditionals.size()); if(ctx != NULL) { GetCmdLineIncludeFiles(ctx->imacro_files, 2); GetCmdLineIncludeFiles(ctx->include_files, COUNT_OF(preprocessors)); } if( ! RunEngine(0) ) goto error; SaveDepInfo(deptext); if( conditionals.size() != 0 ) errmsg = "Unmatched #if"; else retval = true; error: if(!retval) { if(included_files.size() > 0) { CC_STRING tmp; tmp.Format("%s:%u: %s\n%s\n", GetCurrentFileName().c_str(), GetCurrentLineNumber(), pline.from.c_str(), GetError()); errmsg = tmp; } #if 0 IncludedFile *ilevel; while(included_files.size() > 0) { ilevel = PopIncludedFile(); if(infile != ilevel->ifile) delete ilevel; } #endif } if(out_fp != NULL && out_fp != stdout) fclose(out_fp); if( retval && ctx != NULL && ! ignored ) { CC_STRING semname; sem_t *sem; semname = MakeSemaName(infile->name); sem = sem_open(semname.c_str(), O_CREAT, 0666, 1); sem_wait(sem); if( ! bak_fname.isnull() ) rename(infile->name, bak_fname); if( ! out_fname.isnull() ) { rename(out_fname, infile->name); utime(infile->name.c_str(), &utb); } sem_post(sem); sem_unlink(semname.c_str()); } else if( ! out_fname.isnull() ) unlink(out_fname.c_str()); return retval; }