Skip to content

[libc++] Refactors fstream open. #76617

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 3, 2024
Merged

Conversation

mordante
Copy link
Member

This moves the duplicated code to one new function.

This is a preparation to fix
#60509

@mordante mordante force-pushed the users/mordante/fstream_refactor_open branch from 2fafdd2 to 0a34830 Compare December 30, 2023 16:28
This moves the duplicated code to one new function.

This is a preparation to fix
#60509
@mordante mordante force-pushed the users/mordante/fstream_refactor_open branch from 0a34830 to 26065dd Compare December 30, 2023 18:05
@mordante mordante marked this pull request as ready for review December 30, 2023 19:38
@mordante mordante requested a review from a team as a code owner December 30, 2023 19:38
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Dec 30, 2023
@llvmbot
Copy link
Member

llvmbot commented Dec 30, 2023

@llvm/pr-subscribers-libcxx

Author: Mark de Wever (mordante)

Changes

This moves the duplicated code to one new function.

This is a preparation to fix
#60509


Full diff: https://github.com/llvm/llvm-project/pull/76617.diff

1 Files Affected:

  • (modified) libcxx/include/fstream (+99-121)
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index 7a4e15b55d56fe..21fee202873e76 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -247,6 +247,9 @@ public:
   basic_filebuf* close();
 
   _LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
+#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
+  _LIBCPP_HIDE_FROM_ABI inline static const wchar_t* __make_mdwstring(ios_base::openmode __mode) _NOEXCEPT;
+#  endif
 
 protected:
   // 27.9.1.5 Overridden virtual functions:
@@ -282,6 +285,25 @@ private:
   void __write_mode();
 
   _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
+
+  // There are multiple (__)open function, they use different C-API open
+  // function.  After that call these functions behave the same. This function
+  // does that part and determines the final return value.
+  _LIBCPP_HIDE_FROM_ABI basic_filebuf* __open_common_part(ios_base::openmode __mode) {
+    if (!__file_)
+      return nullptr;
+
+    __om_ = __mode;
+    if (__mode & ios_base::ate) {
+      if (fseek(__file_, 0, SEEK_END)) {
+        fclose(__file_);
+        __file_ = nullptr;
+        return nullptr;
+      }
+    }
+
+    return this;
+  }
 };
 
 template <class _CharT, class _Traits>
@@ -516,50 +538,81 @@ const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode _
   __libcpp_unreachable();
 }
 
+#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
 template <class _CharT, class _Traits>
-basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
-  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
-  if (__file_ == nullptr) {
-    if (const char* __mdstr = __make_mdstring(__mode)) {
-      __rt    = this;
-      __file_ = fopen(__s, __mdstr);
-      if (__file_) {
-        __om_ = __mode;
-        if (__mode & ios_base::ate) {
-          if (fseek(__file_, 0, SEEK_END)) {
-            fclose(__file_);
-            __file_ = nullptr;
-            __rt    = nullptr;
-          }
-        }
-      } else
-        __rt = nullptr;
-    }
+const wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT {
+  switch (__mode & ~ios_base::ate) {
+  case ios_base::out:
+  case ios_base::out | ios_base::trunc:
+    return L"w";
+  case ios_base::out | ios_base::app:
+  case ios_base::app:
+    return L"a";
+  case ios_base::in:
+    return L"r";
+  case ios_base::in | ios_base::out:
+    return L"r+";
+  case ios_base::in | ios_base::out | ios_base::trunc:
+    return L"w+";
+  case ios_base::in | ios_base::out | ios_base::app:
+  case ios_base::in | ios_base::app:
+    return L"a+";
+  case ios_base::out | ios_base::binary:
+  case ios_base::out | ios_base::trunc | ios_base::binary:
+    return L"wb";
+  case ios_base::out | ios_base::app | ios_base::binary:
+  case ios_base::app | ios_base::binary:
+    return L"ab";
+  case ios_base::in | ios_base::binary:
+    return L"rb";
+  case ios_base::in | ios_base::out | ios_base::binary:
+    return L"r+b";
+  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
+    return L"w+b";
+  case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
+  case ios_base::in | ios_base::app | ios_base::binary:
+    return L"a+b";
+#    if _LIBCPP_STD_VER >= 23
+  case ios_base::out | ios_base::noreplace:
+  case ios_base::out | ios_base::trunc | ios_base::noreplace:
+    return L"wx";
+  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
+    return L"w+x";
+  case ios_base::out | ios_base::binary | ios_base::noreplace:
+  case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
+    return L"wbx";
+  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
+    return L"w+bx";
+#    endif // _LIBCPP_STD_VER >= 23
+  default:
+    return nullptr;
   }
-  return __rt;
+  __libcpp_unreachable();
+}
+#  endif
+
+template <class _CharT, class _Traits>
+basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
+  if (__file_)
+    return nullptr;
+  const char* __mdstr = __make_mdstring(__mode);
+  if (!__mdstr)
+    return nullptr;
+
+  __file_ = fopen(__s, __mdstr);
+  return __open_common_part(__mode);
 }
 
 template <class _CharT, class _Traits>
 inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
-  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
-  if (__file_ == nullptr) {
-    if (const char* __mdstr = __make_mdstring(__mode)) {
-      __rt    = this;
-      __file_ = fdopen(__fd, __mdstr);
-      if (__file_) {
-        __om_ = __mode;
-        if (__mode & ios_base::ate) {
-          if (fseek(__file_, 0, SEEK_END)) {
-            fclose(__file_);
-            __file_ = nullptr;
-            __rt    = nullptr;
-          }
-        }
-      } else
-        __rt = nullptr;
-    }
-  }
-  return __rt;
+  if (__file_)
+    return nullptr;
+  const char* __mdstr = __make_mdstring(__mode);
+  if (!__mdstr)
+    return nullptr;
+
+  __file_ = fdopen(__fd, __mdstr);
+  return __open_common_part(__mode);
 }
 
 #  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
@@ -567,89 +620,14 @@ inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(in
 // and long mode strings.
 template <class _CharT, class _Traits>
 basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
-  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
-  if (__file_ == nullptr) {
-    __rt = this;
-    const wchar_t* __mdstr;
-    switch (__mode & ~ios_base::ate) {
-    case ios_base::out:
-    case ios_base::out | ios_base::trunc:
-      __mdstr = L"w";
-      break;
-    case ios_base::out | ios_base::app:
-    case ios_base::app:
-      __mdstr = L"a";
-      break;
-    case ios_base::in:
-      __mdstr = L"r";
-      break;
-    case ios_base::in | ios_base::out:
-      __mdstr = L"r+";
-      break;
-    case ios_base::in | ios_base::out | ios_base::trunc:
-      __mdstr = L"w+";
-      break;
-    case ios_base::in | ios_base::out | ios_base::app:
-    case ios_base::in | ios_base::app:
-      __mdstr = L"a+";
-      break;
-    case ios_base::out | ios_base::binary:
-    case ios_base::out | ios_base::trunc | ios_base::binary:
-      __mdstr = L"wb";
-      break;
-    case ios_base::out | ios_base::app | ios_base::binary:
-    case ios_base::app | ios_base::binary:
-      __mdstr = L"ab";
-      break;
-    case ios_base::in | ios_base::binary:
-      __mdstr = L"rb";
-      break;
-    case ios_base::in | ios_base::out | ios_base::binary:
-      __mdstr = L"r+b";
-      break;
-    case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
-      __mdstr = L"w+b";
-      break;
-    case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
-    case ios_base::in | ios_base::app | ios_base::binary:
-      __mdstr = L"a+b";
-      break;
-#    if _LIBCPP_STD_VER >= 23
-    case ios_base::out | ios_base::noreplace:
-    case ios_base::out | ios_base::trunc | ios_base::noreplace:
-      __mdstr = L"wx";
-      break;
-    case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
-      __mdstr = L"w+x";
-      break;
-    case ios_base::out | ios_base::binary | ios_base::noreplace:
-    case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
-      __mdstr = L"wbx";
-      break;
-    case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
-      __mdstr = L"w+bx";
-      break;
-#    endif // _LIBCPP_STD_VER >= 23
-    default:
-      __rt = nullptr;
-      break;
-    }
-    if (__rt) {
-      __file_ = _wfopen(__s, __mdstr);
-      if (__file_) {
-        __om_ = __mode;
-        if (__mode & ios_base::ate) {
-          if (fseek(__file_, 0, SEEK_END)) {
-            fclose(__file_);
-            __file_ = nullptr;
-            __rt    = nullptr;
-          }
-        }
-      } else
-        __rt = nullptr;
-    }
-  }
-  return __rt;
+  if (__file_)
+    return nullptr;
+  const wchar_t* __mdstr = __make_mdwstring(__mode);
+  if (!__mdstr)
+    return nullptr;
+
+  __file_ = _wfopen(__s, __mdstr);
+  return __open_common_part(__mode);
 }
 #  endif
 

@mordante mordante force-pushed the users/mordante/fstream_refactor_open branch from 2711bba to 1686352 Compare February 11, 2024 18:58
@mordante mordante merged commit a5d3a1d into main Mar 3, 2024
@mordante mordante deleted the users/mordante/fstream_refactor_open branch March 3, 2024 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants