[llvm] [GOFF] Refactor writing GOFF records (PR #93855)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 26 23:40:10 PDT 2024


================
@@ -185,81 +158,71 @@ class GOFFState {
             yaml::ErrorHandler ErrHandler)
       : GW(OS), Doc(Doc), ErrHandler(ErrHandler), HasError(false) {}
 
-  ~GOFFState() { GW.finalize(); }
-
   bool writeObject();
 
 public:
   static bool writeGOFF(raw_ostream &OS, GOFFYAML::Object &Doc,
                         yaml::ErrorHandler ErrHandler);
 
 private:
-  GOFFOstream GW;
+  GOFFOStream GW;
   GOFFYAML::Object &Doc;
   yaml::ErrorHandler ErrHandler;
   bool HasError;
 };
 
-void GOFFState::writeHeader(GOFFYAML::FileHeader &FileHdr) {
-  SmallString<16> CCSIDName;
-  if (std::error_code EC =
-          ConverterEBCDIC::convertToEBCDIC(FileHdr.CharacterSetName, CCSIDName))
-    reportError("Conversion error on " + FileHdr.CharacterSetName);
-  if (CCSIDName.size() > 16) {
-    reportError("CharacterSetName too long");
-    CCSIDName.resize(16);
-  }
-  SmallString<16> LangProd;
-  if (std::error_code EC = ConverterEBCDIC::convertToEBCDIC(
-          FileHdr.LanguageProductIdentifier, LangProd))
-    reportError("Conversion error on " + FileHdr.LanguageProductIdentifier);
-  if (LangProd.size() > 16) {
-    reportError("LanguageProductIdentifier too long");
-    LangProd.resize(16);
-  }
-
-  GW.makeNewRecord(GOFF::RT_HDR, GOFF::PayloadLength);
-  GW << binaryBe(FileHdr.TargetEnvironment)     // TargetEnvironment
-     << binaryBe(FileHdr.TargetOperatingSystem) // TargetOperatingSystem
-     << zeros(2)                                // Reserved
-     << binaryBe(FileHdr.CCSID)                 // CCSID
-     << CCSIDName                               // CharacterSetName
-     << zeros(16 - CCSIDName.size())            // Fill bytes
-     << LangProd                                // LanguageProductIdentifier
-     << zeros(16 - LangProd.size())             // Fill bytes
-     << binaryBe(FileHdr.ArchitectureLevel);    // ArchitectureLevel
-  // The module propties are optional. Figure out if we need to write them.
-  uint16_t ModPropLen = 0;
-  if (FileHdr.TargetSoftwareEnvironment)
-    ModPropLen = 3;
-  else if (FileHdr.InternalCCSID)
-    ModPropLen = 2;
-  if (ModPropLen) {
-    GW << binaryBe(ModPropLen) << zeros(6);
-    if (ModPropLen >= 2)
-      GW << binaryBe(FileHdr.InternalCCSID ? *FileHdr.InternalCCSID : 0);
-    if (ModPropLen >= 3)
-      GW << binaryBe(FileHdr.TargetSoftwareEnvironment
-                         ? *FileHdr.TargetSoftwareEnvironment
-                         : 0);
-  }
+void GOFFState::writeHeader(const GOFFYAML::ModuleHeader &ModHdr) {
+  // See
+  // https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-module-header-record.
+  GW.newRecord(GOFF::RT_HDR);
+  LogicalRecord LR(GW);
+  LR << zeros(45)                          // Reserved.
+     << binaryBe(ModHdr.ArchitectureLevel) // The architecture level.
+     << binaryBe(ModHdr.PropertiesLength)  // Length of module properties.
+     << zeros(6);                          // Reserved.
+  if (ModHdr.Properties)
+    LR << *ModHdr.Properties; // Module properties.
 }
 
-void GOFFState::writeEnd() {
-  GW.makeNewRecord(GOFF::RT_END, GOFF::PayloadLength);
-  GW << binaryBe(uint8_t(0)) // No entry point
-     << binaryBe(uint8_t(0)) // No AMODE
-     << zeros(3)             // Reserved
-     << binaryBe(GW.logicalRecords());
-  // No entry point yet. Automatically fill remaining space with zero bytes.
-  GW.finalize();
+void GOFFState::writeEnd(const GOFFYAML::EndOfModule &EndMod) {
+  // See https://www.ibm.com/docs/en/zos/3.1.0?topic=formats-end-module-record.
+  SmallString<16> EntryName;
+  if (std::error_code EC =
+          ConverterEBCDIC::convertToEBCDIC(EndMod.EntryName, EntryName))
+    reportError("failed to convert '" + EndMod.EntryName + "' to EBCDIC 1047");
+
+  GW.newRecord(GOFF::RT_END);
+  LogicalRecord LR(GW);
+  LR << binaryBe(uint8_t(EndMod.Flags)) // The flags.
+     << binaryBe(uint8_t(EndMod.AMODE)) // The addressing mode.
+     << zeros(3)                        // Reserved.
+     << binaryBe(EndMod.RecordCount)    // The record count.
+     << binaryBe(EndMod.ESDID)          // ESDID of the entry point.
+     << zeros(4)                        // Reserved.
+     << binaryBe(EndMod.Offset)         // Offset of entry point.
+     << binaryBe(EndMod.NameLength)     // Length of external name.
----------------
EsmeYi wrote:

Ditto. It can be filled with a calculated value when it's omitted.

https://github.com/llvm/llvm-project/pull/93855


More information about the llvm-commits mailing list