1 #include <msp/core/application.h>
2 #include <msp/core/getopt.h>
3 #include <msp/fs/dir.h>
4 #include <msp/fs/stat.h>
5 #include <msp/fs/utils.h>
6 #include <msp/io/print.h>
7 #include <msp/time/datetime.h>
12 class Ls: public RegisteredApplication<Ls>
15 typedef vector<string> Row;
25 Row create_row(const string &, const FS::Stat &);
26 void print_rows(const list<Row> &);
29 Ls::Ls(int argc, char **argv):
33 getopt.add_option('l', "long", long_format, GetOpt::NO_ARG);
36 args = getopt.get_args();
45 for(vector<string>::const_iterator i=args.begin(); i!=args.end(); ++i)
48 FS::Stat stat = FS::lstat(path);
49 if(stat.is_directory())
52 list<string> files = FS::list_files(path);
54 for(list<string>::iterator j=files.begin(); j!=files.end(); ++j)
57 rows.push_back(create_row(*j, FS::lstat(path / *j)));
69 IO::print("%s:\n", *i);
75 file_rows.push_back(create_row(*i, stat));
80 file_rows.push_back(r);
84 if(!file_rows.empty())
88 print_rows(file_rows);
94 Ls::Row Ls::create_row(const string &name, const FS::Stat &st)
98 result.push_back("-");
99 else if(st.is_directory())
100 result.push_back("D");
101 else if(st.is_symlink())
102 result.push_back("L");
104 result.push_back("?");
106 result.push_back(st.get_owner());
107 result.push_back(st.get_group());
108 result.push_back(format("%d", st.get_size()));
109 result.push_back(Time::DateTime(st.get_modify_time()).format("%Y-%m-%d %H:%M:%S"));
110 result.push_back(name);
115 void Ls::print_rows(const list<Row> &rows)
117 vector<unsigned> col_width;
119 for(list<Row>::const_iterator i=rows.begin(); i!=rows.end(); ++i)
122 if(row.size()>col_width.size())
123 col_width.resize(row.size(), 0);
124 for(unsigned j=0; j<row.size(); ++j)
125 col_width[j] = max(col_width[j], row[j].size());
128 for(list<Row>::const_iterator i=rows.begin(); i!=rows.end(); ++i)
132 for(unsigned j=0; j<row.size(); ++j)
136 unsigned padding = col_width[j]-row[j].size();
138 line += string(padding, ' ');
141 line += string(padding, ' ');