int LibMain::Run(int argc, char **argv) { Utils::banner(argv[0]); CmdSwitchFile internalConfig(SwitchParser); std::string configName = Utils::QualifiedFile(argv[0], ".cfg"); std::fstream configTest(configName.c_str(), std::ios::in); if (!configTest.fail()) { configTest.close(); if (!internalConfig.Parse(configName.c_str())) Utils::fatal("Corrupt configuration file"); } if (!SwitchParser.Parse(&argc, argv)) { Utils::usage(argv[0], usageText); } if (argc < 2 && File.GetCount() < 3) { Utils::usage(argv[0], usageText); } // setup ObjString outputFile = argv[1]; size_t n = outputFile.find_last_of('.'); if (n == std::string::npos || (n != outputFile.size()-1 && outputFile[n+1] != 'l')) { outputFile += ".l"; } LibManager librarian(outputFile, caseSensitiveSwitch.GetValue()); if (librarian.IsOpen()) if (!librarian.LoadLibrary()) { std::cout << outputFile.c_str() << " is not a library" << std::endl; return 1; } for (int i= 2; i < argc; i++) AddFile(librarian, argv[i]); for (int i = 1; i < File.GetCount(); i++) AddFile(librarian, File.GetValue()[i]); for (CmdFiles::FileNameIterator it = addFiles.FileNameBegin(); it != addFiles.FileNameEnd(); ++it) { librarian.AddFile(*(*it)); } for (CmdFiles::FileNameIterator it = replaceFiles.FileNameBegin(); it != replaceFiles.FileNameEnd(); ++it) { librarian.ReplaceFile(*(*it)); } if (modified) if (!librarian.SaveLibrary()) { std::cout << "Error writing library file" << std::endl; return 1; } return 0; }
void LibFiles::Extract(FILE *stream, const ObjString &Name) { int count = 0; ObjIeeeIndexManager im1; ObjFactory fact1(&im1); for (FileIterator it = FileBegin(); it != FileEnd(); ++it) { if ((*it)->name == Name) { ObjFile *p = LoadModule(stream, count, &fact1); if (p) { FILE *ostr = fopen(Name.c_str(), "wb"); if (ostr != NULL) { WriteData(ostr, p, (*it)->name); fclose(ostr); } else { std::cout << "Warning: Module '" << Name << "' not extracted, could not open output file" << std::endl; } } else { std::cout << "Warning: Module '" << Name << "' not extracted, library corrupt" << std::endl; } return; } } std::cout << "Warning: Module '" << Name << "' not in library and could not be extracted" << std::endl; }
void LibFiles::WriteData(FILE *stream, ObjFile *file, const ObjString &name) { ObjIeeeIndexManager im1; ObjFactory fact1(&im1); ObjIeee ieee(name.c_str()); ieee.Write(stream, file, &fact1); }
LinkRegionFileSpecContainer::LinkRegionFileSpecContainer(const ObjString &Spec) { const char *data = Spec.c_str(); int start=0, end; while (data[start]) { if (data[start] == '*') specs.push_back(new LinkRegionFileSpec(LinkRegionFileSpec::eStar)), start++; else if (data[start] == '?') specs.push_back(new LinkRegionFileSpec(LinkRegionFileSpec::eQuestionMark)), start++; else { end = start; while (data[end] && data[end] != '*' && data[end] != '?') { end++; } specs.push_back(new LinkRegionFileSpec(LinkRegionFileSpec::eSpan, Spec.substr(start, end))); start = end; } } }
ObjString ObjIeeeAscii::GetSymbolName(const char *buffer, int *index) { int pos = 2; *index = ObjUtil::FromHex(buffer, &pos); if (buffer[pos++] != ',') ThrowSyntax(buffer, eAll); ObjString rv = ParseString(buffer, &pos); CheckTerm(buffer + pos); if (!GetCaseSensitiveFlag()) { char buf[256]; strncpy(buf, rv.c_str(), sizeof(buf)); buf[sizeof(buf) - 1] = 0; char *p = buf; while (*p) { *p = toupper(*p); p++; } rv = buf; } return rv; }
bool LinkRegionFileSpecContainer::Matches(const ObjString &Spec) { ObjString working = Spec; for (auto spec : specs) for (auto it = specs.begin(); it != specs.end(); ++it) { switch ((*it)->GetType()) { case LinkRegionFileSpec::eStar: { ++it; if (it != specs.end()) { if ((*it)->GetType() != LinkRegionFileSpec::eSpan) return false; unsigned pos = working.find((*it)->GetSpan()); if (pos == ObjString::npos) return false; working = working.substr(pos + (*it)->GetSpan().size()); } else return true; break; } case LinkRegionFileSpec::eQuestionMark: if (working.size() < 1) return false; working = working.substr(1); break; default: { int pos = working.find((*it)->GetSpan()); if (pos != 0) return false; working = working.substr((*it)->GetSpan().size()); break; } } } return true; }
bool ObjIeeeAscii::Comment(const char *buffer, eParseType ParseType) { if (!file) ThrowSyntax(buffer, ParseType); int pos = 2; int cnum = ObjUtil::FromDecimal(buffer, &pos,3); if (buffer[pos++] != ',') ThrowSyntax(buffer, ParseType); ObjString contents = ParseString(buffer, &pos); const char *data = contents.c_str(); CheckTerm(buffer + pos); switch (cnum) { case eAbsolute: absolute = true; // absolute file break; case eMakePass: if (ParseType == eMake) return true; break; case eLinkPass: if (ParseType == eLink) return true; break; case eBrowsePass: if (ParseType == eBrowse) return true; break; case eConfig: /* not supported */ break; case eDefinition: { int pos = 0; ObjString name = ParseString(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); ObjInt value = ObjUtil::FromDecimal(data, &pos); ObjDefinitionSymbol *sym = factory->MakeDefinitionSymbol(name); sym->SetValue(value); file->Add(sym); break; } case eExport: { bool byOrdinal; if (data[0] == 'O') byOrdinal = true; else if (data[0] == 'N') byOrdinal = false; else ThrowSyntax(buffer, ParseType); if (data[1] != ',') ThrowSyntax(buffer, ParseType); int pos = 2; ObjString name = ParseString(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); ObjString externalName; int ordinal = 0xffffffff; if (byOrdinal) ordinal = ObjUtil::FromDecimal(data, &pos); else externalName = ParseString(data, &pos); ObjString moduleName; if (data[pos] == ',') { pos++; moduleName = ParseString(data, &pos); } if (!GetCaseSensitiveFlag()) { for (int i=0; i < name.size(); i++) name[i] = toupper(name[i]); } ObjExportSymbol *sym = factory->MakeExportSymbol(name); sym->SetByOrdinal(byOrdinal); sym->SetOrdinal(ordinal); sym->SetExternalName(externalName); sym->SetDllName(moduleName); file->Add(sym); break; } case eImport: { bool byOrdinal; if (data[0] == 'O') byOrdinal = true; else if (data[0] == 'N') byOrdinal = false; else ThrowSyntax(buffer, ParseType); if (data[1] != ',') ThrowSyntax(buffer, ParseType); int pos = 2; ObjString name = ParseString(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); ObjString externalName; int ordinal = 0xffffffff; ObjString dllName; if (byOrdinal) ordinal = ObjUtil::FromDecimal(data, &pos); else externalName = ParseString(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); dllName = ParseString(data, &pos); if (!GetCaseSensitiveFlag()) { for (int i=0; i < name.size(); i++) name[i] = toupper(name[i]); } ObjImportSymbol *sym = factory->MakeImportSymbol(name); sym->SetByOrdinal(byOrdinal); sym->SetOrdinal(ordinal); sym->SetExternalName(externalName); sym->SetDllName(dllName); file->Add(sym); break; } case eSourceFile: { int pos = 0; int index = ObjUtil::FromDecimal(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); ObjString name = ParseString(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); std::tm time; ParseTime(data, time, &pos); ObjSourceFile *sf = factory->MakeSourceFile(name, index); sf->SetFileTime(time); PutFile(index, sf); break; } case eBrowseInfo: { ObjBrowseInfo::eType type; ObjBrowseInfo::eQual qual; int pos = 0; type = (ObjBrowseInfo::eType)ObjUtil::FromHex(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); qual = (ObjBrowseInfo::eQual)ObjUtil::FromHex(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); int filenum = ObjUtil::FromDecimal(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); int lineno = ObjUtil::FromDecimal(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); int charpos = ObjUtil::FromDecimal(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); ObjString extra = ParseString(data, &pos); ObjSourceFile *sf = files[filenum]; if (!sf) ThrowSyntax(buffer, ParseType); ObjLineNo *line = factory->MakeLineNo(sf, lineno); ObjBrowseInfo *bi = factory->MakeBrowseInfo(type, qual, line, charpos, extra); file->Add(bi); break; } case eLineNo: { int pos = 0; int index = ObjUtil::FromDecimal(data, &pos); if (data[pos++] != ',') ThrowSyntax(buffer, ParseType); int line = ObjUtil::FromDecimal(data, &pos); ObjSourceFile *file = files[index]; if (!file) ThrowSyntax(buffer, ParseType); ObjLineNo *lineNo= factory->MakeLineNo(file, line); ObjDebugTag *tag = factory->MakeDebugTag(lineNo); currentTags->push_back(tag); break; } case eVar: { int pos = 0; int ch = data[pos++]; int index = ObjUtil::FromHex(data, &pos); ObjSymbol *sym = FindSymbol(ch, index); if (!sym) ThrowSyntax(buffer, ParseType); ObjDebugTag *tag = factory->MakeDebugTag(sym); currentTags->push_back(tag); break; } case eBlockStart: { ObjDebugTag *tag = factory->MakeDebugTag(true); currentTags->push_back(tag); break; } case eBlockEnd: { ObjDebugTag *tag = factory->MakeDebugTag(false); currentTags->push_back(tag); break; } case eFunctionStart: case eFunctionEnd: int pos = 0; int ch = data[pos++]; int index = ObjUtil::FromHex(data, &pos); ObjSymbol *sym = FindSymbol(ch, index); if (!sym) ThrowSyntax(buffer, ParseType); ObjDebugTag *tag = factory->MakeDebugTag(sym, cnum == eFunctionStart); currentTags->push_back(tag); break; } return false; }