[flang-commits] [flang] [llvm] Flang improve fidelity of unformatted I/O endianness with FORT_CONVERT_UNIT (PR #223831)
David Parks via flang-commits
flang-commits at lists.llvm.org
Fri Sep 18 09:12:55 PDT 2026
================
@@ -97,6 +98,157 @@ common::optional<Convert> GetConvertFromString(const char *x, std::size_t n) {
}
RT_OFFLOAD_API_GROUP_END
+bool ExecutionEnvironment::ParseFortConvertUnit(const char *cenvStr) {
+ bool success{true};
+ char *envStr{strdup(cenvStr)};
+
+ if (nullptr == envStr) {
+ Terminator{__FILE__, __LINE__}.Crash(
+ "FORT_CONVERT_UNIT: could not allocate memory");
+ }
+
+ char *exceptionSvptr{nullptr};
+ char *exceptionStr;
+ char *unitListStr;
+ bool firstException{true};
+ Convert gblConversion{conversion};
+
+ // Flang's FORT_CONVERT_UNIT syntax follows NVIDIA's FORT_CONVERT_UNIT and
+ // GNU's gfortran GFORTRAN_CONVERT_UNIT.
+ //
+ // FORT_CONVERT_UNIT: mode | mode ';' exception | exception ;
+ // mode: 'native' | 'swap' | 'big_endian' | 'little_endian' ;
+ // exception: mode ':' unit_list | unit_list ;
+ // unit_list: unit_spec | unit_list ',' unit_spec ;
+ // unit_spec: INTEGER | INTEGER '-' INTEGER ;
+
+ while (success) {
+#if _WIN32
+ exceptionStr =
+ strtok_s(exceptionSvptr ? nullptr : envStr, ";", &exceptionSvptr);
+#else
+ exceptionStr =
+ strtok_r(exceptionSvptr ? nullptr : envStr, ";", &exceptionSvptr);
+#endif
+ if (nullptr == exceptionStr) {
+ break;
+ }
+
+ // unitList is not yet correct, might be nullptr or pointing to ':'.
+ unitListStr = strchr(exceptionStr, ':');
+
+ if (firstException && (nullptr == unitListStr) &&
+ !isdigit(exceptionStr[0])) {
+ // if first pass extracting an exception, and exceptionStr does not
+ // contain a ':' this becomes the global setting.
+ // Akin to specifying FORT_CONVERT=<mode>.
+ if (auto convert{
+ GetConvertFromString(exceptionStr, std::strlen(exceptionStr))}) {
+ gblConversion = *convert;
+ } else {
+ success = false;
+ break;
+ }
+ firstException = false;
+ continue;
+ }
+
+ // mode ';' exception | exception
+ char *unitListSvptr{nullptr};
+ // For the case where <mode> is unspecified
+ Convert conversion{Convert::BigEndian};
+
+ // If unitListStr != nullptr extract mode from modeStr[:unitListStr-1].
+ if (nullptr != unitListStr) {
+ *unitListStr++ = '\0'; // Advance unitListStr
+ if (auto convert{
+ GetConvertFromString(exceptionStr, std::strlen(exceptionStr))}) {
+ conversion = *convert;
+ } else {
+ success = false;
+ break;
+ }
+ } else {
+ unitListStr = exceptionStr;
+ }
+
+ unitListSvptr = nullptr;
+
+ // Loop over unit list extracting individual or ranges of units, separated
+ // by commas.
+
+ while (success) {
+ char *units;
+ int lb, ub;
+ char remStr[2];
+ int nread;
+ int nexpected;
+
+ lb = ub = -1;
+#if _WIN32
+ units =
+ strtok_s(unitListSvptr ? nullptr : unitListStr, ";", &unitListSvptr);
----------------
d-parks wrote:
Fixed.
https://github.com/llvm/llvm-project/pull/223831
More information about the flang-commits
mailing list