@@ -486,6 +486,42 @@ absl::StatusOr<FileName> FileName::MakeRelative(const FileName& base) const {
486486  return  FileName::FromString (rel);
487487}
488488
489+ absl::StatusOr<FileName> FileName::Resolve () const  {
490+ #ifdef  _WIN32
491+   constexpr  DWORD access = 0 ;
492+   constexpr  DWORD share = 0 ;
493+   constexpr  DWORD disposition = OPEN_EXISTING;
494+   constexpr  DWORD open_flags = FILE_FLAG_BACKUP_SEMANTICS;
495+   const  HANDLE handle = ::CreateFileW (this ->pointer (), access, share, nullptr ,
496+                                       disposition, open_flags, nullptr );
497+   if  (handle == INVALID_HANDLE_VALUE) {
498+     return  WindowsStatus (" CreateFileW" absl::Hex (access), absl::Hex (share),
499+                          nullptr , disposition, absl::Hex (open_flags), nullptr );
500+   }
501+   const  absl::Cleanup cleanup = [handle] {
502+     if  (!::CloseHandle (handle)) LOG (ERROR) << WindowsStatus (" CloseHandle" 
503+   };
504+   std::array<wchar_t , 0x8000 > buffer;
505+   constexpr  DWORD name_flags = FILE_NAME_NORMALIZED | VOLUME_NAME_DOS;
506+   const  DWORD length = ::GetFinalPathNameByHandleW (handle, buffer.data (),
507+                                                    buffer.size (), name_flags);
508+   if  (length == 0 ) {
509+     return  WindowsStatus (" GetFinalPathNameByHandleW" kEllipsis , kEllipsis ,
510+                          absl::Hex (buffer.size ()), absl::Hex (name_flags));
511+   }
512+   if  (length >= buffer.size ()) {
513+     return  absl::FailedPreconditionError (absl::StrFormat (
514+         " Resolved filename is too long (%d characters)" 
515+   }
516+   return  FileName::FromString (std::wstring_view (buffer.data (), length));
517+ #else 
518+   char * const  absl_nullable result = realpath (this ->pointer (), nullptr );
519+   if  (result == nullptr ) return  ErrnoStatus (" realpath" this , nullptr );
520+   const  absl::Cleanup cleanup = [result] { std::free (result); };
521+   return  FileName::FromString (result);
522+ #endif 
523+ }
524+ 
489525absl::StatusOr<std::string> ReadFile (const  FileName& file) {
490526  std::ifstream stream (file.string (), std::ios::in | std::ios::binary);
491527  if  (!stream.is_open () || !stream.good ()) {
0 commit comments