From 52fe05e3e4dfa7016914e7a0ab76e4729c9f5b70d8af75d470ded2463a964093 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Sat, 31 Oct 2026 18:14:31 -0400 Subject: [PATCH] Symlink file type support. --- Entry.h | 5 +++-- cudir.cc | 19 +++++++++++++++---- format.cc | 6 +++++- helpers.cc | 12 ++++++++++-- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Entry.h b/Entry.h index 87b5193..43f1fa5 100644 --- a/Entry.h +++ b/Entry.h @@ -18,12 +18,13 @@ struct Entry unsigned day; long int hour; long int minute; - bool is_dir; + enum Type { Directory, Symlink, Normal }; + Type type; bool is_exe; }; bool is_exe( std::filesystem::directory_entry entry ); -std::string drwx( std::filesystem::directory_entry entry ); +std::string drwx( std::filesystem::directory_entry entry, Entry::Type t ); std::string format_entry( const Entry &entry, std::size_t widest ); diff --git a/cudir.cc b/cudir.cc index 1a74dcc..e8ac1d8 100644 --- a/cudir.cc +++ b/cudir.cc @@ -50,10 +50,16 @@ getEntries( const std::filesystem::path where ) } }; - entries.push_back( Entry{ entry.path().filename(), drwx( entry ), entry.is_directory() ? 0 : get_file_size( entry.path() ), + const auto type= Alepha::Utility::evaluate <=[&] + { + if( entry.is_symlink() ) return Entry::Symlink; + if( entry.is_directory() ) return Entry::Directory; + return Entry::Normal; + }; + entries.push_back( Entry{ entry.path().filename(), drwx( entry, type ), type == Entry::Normal ? get_file_size( entry.path() ) : 0, static_cast< int >( ymd.year() ), static_cast< unsigned >( ymd.month() ), static_cast< unsigned >( ymd.day() ), time_of_day.hours().count(), time_of_day.minutes().count(), - entry.is_directory(), is_exe( entry ) } ); + type, is_exe( entry ) } ); } std::sort( begin( entries ), end( entries ), []( const auto &lhs, const auto &rhs ) { return lhs.name < rhs.name; } ); @@ -124,12 +130,17 @@ main( const int argcnt, const char *const argvec[] ) { ++fileCount; totalSize+= entry.size; - std::cout << format_entry( entry, widest ) << " "; - if( entry.is_dir ) + std::cout << format_entry( entry, widest ) << ""; + if( entry.type == Entry::Directory ) { std::cout << ""; std::cout << std::setw( C::sizeWidth - 1 ) << std::setfill( ' ' ) << std::right << "" << ' '; } + else if( entry.type == Entry::Symlink ) + { + std::cout << ""; + std::cout << std::setw( C::sizeWidth - 1 ) << std::setfill( ' ' ) << std::right << "" << ' '; + } else { //std::cout << " "; diff --git a/format.cc b/format.cc index 84b34fd..8d9bcaf 100644 --- a/format.cc +++ b/format.cc @@ -9,10 +9,14 @@ format_entry( const Entry &entry, const std::size_t widest ) std::ostringstream oss; oss << "["; - if( entry.is_dir ) + if( entry.type == Entry::Directory ) { oss << "1;35;95"; } + else if( entry.type == Entry::Symlink ) + { + oss << "1;32;92"; + } else if( entry.is_exe ) { oss << "1;36;96"; diff --git a/helpers.cc b/helpers.cc index f9979ee..e702532 100644 --- a/helpers.cc +++ b/helpers.cc @@ -3,6 +3,7 @@ #include #include #include +#include bool is_exe( const std::filesystem::directory_entry entry ) @@ -13,8 +14,15 @@ is_exe( const std::filesystem::directory_entry entry ) return ( perms::none != ( p & ( perms::owner_exec | perms::group_exec | perms::others_exec ) ) ); } +static const std::map< Entry::Type, char > typeMap= +{ + { Entry::Normal, '-' }, + { Entry::Directory, 'd' }, + { Entry::Symlink, 'l' }, +}; + std::string -drwx( const std::filesystem::directory_entry entry ) +drwx( const std::filesystem::directory_entry entry, const Entry::Type type ) { auto p= status( entry.path() ).permissions(); @@ -24,7 +32,7 @@ drwx( const std::filesystem::directory_entry entry ) { oss << (perms::none == (perm bitand p) ? '-' : op); }; - oss << ( entry.is_directory() ? 'd' : '-' ); + oss << typeMap.at( type ); show('r', perms::owner_read); show('w', perms::owner_write); show('x', perms::owner_exec);