Add an ls example to demonstrate some of the fs components
authorMikko Rasa <tdb@tdb.fi>
Sun, 31 Jul 2011 15:34:38 +0000 (18:34 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 31 Jul 2011 15:35:39 +0000 (18:35 +0300)
Build
examples/ls.cpp [new file with mode: 0644]

diff --git a/Build b/Build
index 318f3414df20eae3cecb296bce4be288fb5e2b19..fc7b33a27b94569f6851d500f6996d96a02ef60c 100644 (file)
--- a/Build
+++ b/Build
@@ -93,6 +93,15 @@ package "mspcore"
                };
        };
 
+       program "ls"
+       {
+               source "examples/ls.cpp";
+               build_info
+               {
+                       library "mspcore";
+               };
+       };
+
        tarball "@src"
        {
                source "License.txt";
diff --git a/examples/ls.cpp b/examples/ls.cpp
new file mode 100644 (file)
index 0000000..fd4d71f
--- /dev/null
@@ -0,0 +1,146 @@
+#include <msp/core/application.h>
+#include <msp/core/getopt.h>
+#include <msp/fs/dir.h>
+#include <msp/fs/stat.h>
+#include <msp/fs/utils.h>
+#include <msp/io/print.h>
+#include <msp/time/datetime.h>
+
+using namespace std;
+using namespace Msp;
+
+class Ls: public RegisteredApplication<Ls>
+{
+private:
+       typedef vector<string> Row;
+
+       bool long_format;
+       vector<string> args;
+
+public:
+       Ls(int, char **);
+
+       virtual int main();
+private:
+       Row create_row(const string &, const FS::Stat &);
+       void print_rows(const list<Row> &);
+};
+
+Ls::Ls(int argc, char **argv):
+       long_format(false)
+{
+       GetOpt getopt;
+       getopt.add_option('l', "long", long_format, GetOpt::NO_ARG);
+       getopt(argc, argv);
+
+       args = getopt.get_args();
+       if(args.empty())
+               args.push_back(".");
+}
+
+int Ls::main()
+{
+       list<Row> file_rows;
+       bool first = true;
+       for(vector<string>::const_iterator i=args.begin(); i!=args.end(); ++i)
+       {
+               FS::Path path = *i;
+               FS::Stat stat = FS::lstat(path);
+               if(stat.is_directory())
+               {
+                       list<Row> rows;
+                       list<string> files = FS::list_files(path);
+                       files.sort();
+                       for(list<string>::iterator j=files.begin(); j!=files.end(); ++j)
+                       {
+                               if(long_format)
+                                       rows.push_back(create_row(*j, FS::lstat(path / *j)));
+                               else
+                               {
+                                       Row r;
+                                       r.push_back(*j);
+                                       rows.push_back(r);
+                               }
+                       }
+
+                       if(!first)
+                               IO::print("\n");
+                       if(args.size()>1)
+                               IO::print("%s:\n", *i);
+                       print_rows(rows);
+
+                       first = false;
+               }
+               else if(long_format)
+                       file_rows.push_back(create_row(*i, stat));
+               else
+               {
+                       Row r;
+                       r.push_back(*i);
+                       file_rows.push_back(r);
+               }
+       }
+
+       if(!file_rows.empty())
+       {
+               if(!first)
+                       IO::print("\n");
+               print_rows(file_rows);
+       }
+
+       return 0;
+}
+
+Ls::Row Ls::create_row(const string &name, const FS::Stat &st)
+{
+       Row result;
+       if(st.is_regular())
+               result.push_back("-");
+       else if(st.is_directory())
+               result.push_back("D");
+       else if(st.is_symlink())
+               result.push_back("L");
+       else
+               result.push_back("?");
+
+       result.push_back(st.get_owner());
+       result.push_back(st.get_group());
+       result.push_back(format("%d", st.get_size()));
+       result.push_back(Time::DateTime(st.get_modify_time()).format("%Y-%m-%d %H:%M:%S"));
+       result.push_back(name);
+
+       return result;
+}
+
+void Ls::print_rows(const list<Row> &rows)
+{
+       vector<unsigned> col_width;
+
+       for(list<Row>::const_iterator i=rows.begin(); i!=rows.end(); ++i)
+       {
+               const Row &row = *i;
+               if(row.size()>col_width.size())
+                       col_width.resize(row.size(), 0);
+               for(unsigned j=0; j<row.size(); ++j)
+                       col_width[j] = max(col_width[j], row[j].size());
+       }
+
+       for(list<Row>::const_iterator i=rows.begin(); i!=rows.end(); ++i)
+       {
+               const Row &row = *i;
+               string line;
+               for(unsigned j=0; j<row.size(); ++j)
+               {
+                       if(j>0)
+                               line += ' ';
+                       unsigned padding = col_width[j]-row[j].size();
+                       if(j==3)
+                               line += string(padding, ' ');
+                       line += row[j];
+                       if(j!=3)
+                               line += string(padding, ' ');
+               }
+               line += '\n';
+               IO::print(line);
+       }
+}