aboutsummaryrefslogtreecommitdiffhomepage
path: root/libslang/slsh/scripts/ls
diff options
context:
space:
mode:
Diffstat (limited to 'libslang/slsh/scripts/ls')
-rwxr-xr-xlibslang/slsh/scripts/ls333
1 files changed, 333 insertions, 0 deletions
diff --git a/libslang/slsh/scripts/ls b/libslang/slsh/scripts/ls
new file mode 100755
index 0000000..197d47d
--- /dev/null
+++ b/libslang/slsh/scripts/ls
@@ -0,0 +1,333 @@
+#!/usr/bin/env slsh
+%_debug_info = 1;
+% A simple ls designed primarily for windows.
+
+static variable Months =
+ ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
+ "Oct", "Nov", "Dec"];
+
+static variable Six_Months_Ago = _time () - 3600*24*30*6;
+
+
+static define ls_long (this_dir, file_list, st_list)
+{
+ _for (0, length(file_list)-1, 1)
+ {
+ variable i = ();
+ variable file = file_list[i];
+ variable st = st_list[i];
+
+ variable size, mode, owner, group, symlink, mtime;
+ variable mstring;
+ variable tm;
+
+ size = st.st_size;
+ mtime = st.st_mtime;
+ mode = st.st_mode;
+ owner = st.st_uid;
+ group = st.st_gid;
+#ifdef WIN32
+ variable attrs = st.st_opt_attrs;
+#endif
+ tm = localtime (mtime);
+#ifdef WIN32
+ if (tm == NULL)
+ mtime = "Jan 01 1980";
+ else
+#endif
+ if (mtime < Six_Months_Ago)
+ mtime = sprintf ("%s %2d %4d",
+ Months[tm.tm_mon],
+ tm.tm_mday,
+ 1900 + tm.tm_year);
+ else
+ mtime = sprintf ("%s %2d %2d:%02d",
+ Months[tm.tm_mon],
+ tm.tm_mday,
+ tm.tm_hour,
+ tm.tm_min);
+
+ symlink = "";
+#ifexists readlink
+ if (stat_is ("lnk", mode))
+ {
+ symlink = readlink (path_concat (this_dir, file));
+ if (symlink == NULL)
+ symlink = "??";
+
+ symlink = " -> " + symlink;
+ }
+#endif
+#ifdef WIN32
+ mstring = stat_mode_to_string (mode, attrs);
+#else
+ mstring = stat_mode_to_string (mode);
+#endif
+ () = fprintf (stdout,
+ "%8s %8S %8S %10S %s %s%s\n",
+ mstring, owner, group, size, mtime, file, symlink);
+ }
+}
+
+static variable
+ Use_Long_Form = 0,
+ Use_atime = 0,
+ Sort_By_Time = 0,
+ Sort_By_Size = 0,
+ Use_a_Option = 0,
+ Use_F_Option = 1,
+ Use_R_Option = 0,
+ Use_d_Option = 0;
+
+
+static define parse_args (args)
+{
+ variable ch;
+
+ foreach (args)
+ {
+ ch = ();
+ switch (ch)
+ { case 'l': Use_Long_Form = 1; }
+ { case 'u': Use_atime = 1; }
+ { case 't': Sort_By_Time = 1; }
+ { case 'S': Sort_By_Size = 1; }
+ { case 'd': Use_d_Option = 1; }
+ { case 'a': Use_a_Option = 1; }
+ { case 'R': Use_R_Option = 1; }
+ { case '-':} % ignore it
+ {
+ () = fprintf (stderr, "Option '%c' not supported.\n", ch);
+ }
+ }
+}
+
+define ls_short (dirs)
+{
+ variable max_len;
+ variable ncols;
+ variable num, num_per_row, num_rows;
+ variable stride;
+
+ num = length (dirs);
+ max_len = 0;
+ foreach (dirs)
+ {
+ variable dir;
+
+ dir = ();
+ if (strlen (dir) > max_len)
+ max_len = strlen (dir);
+ }
+
+ max_len += 2;
+
+ variable format = "%-" + string (max_len) + "s";
+
+ ncols = 80;
+ num_per_row = ncols / max_len;
+ if (num_per_row == 0)
+ num_per_row = 1;
+
+ num_rows = (num + num_per_row - 1) / num_per_row;
+ _for (0, num_rows-1, 1)
+ {
+ variable r = ();
+ _for (0, num_per_row-1, 1)
+ {
+ variable c = ();
+ variable i = r + num_rows * c;
+
+ if (i < num)
+ {
+ if (c + 1 < num_per_row)
+ () = fprintf (stdout, format, dirs[i]);
+ else
+ () = fputs (dirs[i], stdout);
+ }
+ }
+ () = fputs ("\n", stdout);
+ }
+}
+
+static define size_sort (a, b)
+{
+ b.st_size - a.st_size;
+}
+
+static define time_sort (a, b)
+{
+ b.st_mtime - a.st_mtime;
+}
+
+static define is_non_null_fun (a)
+{
+ a != NULL;
+}
+
+
+define sort_files (dirs, sts)
+{
+ variable st, i, non_null;
+
+ % Some of the sts structs may be NULL. Get rid of those
+ non_null = array_map (Char_Type, &is_non_null_fun, sts);
+
+ i = where (non_null);
+ dirs = dirs [i];
+ sts = sts [i];
+
+
+ if (Use_atime)
+ {
+ foreach (sts)
+ {
+ st = ();
+ st.st_mtime = st.st_atime;
+ }
+ }
+
+ if (Sort_By_Time)
+ i = array_sort (sts, &time_sort);
+ else if (Sort_By_Size)
+ i = array_sort (sts, &size_sort);
+ else
+ i = array_sort (dirs);
+
+ return dirs[i], sts[i];
+}
+
+static define isdir_fun (st)
+{
+ stat_is ("dir", st.st_mode);
+}
+
+static define list_dir (dir)
+{
+#ifndef UNIX
+ if (Use_a_Option)
+ listdir (dir, "");
+ else
+#endif
+ listdir (dir);
+}
+
+
+define do_ls ();
+define do_ls (dirs, this_dir, recurse, prune_hidden)
+{
+ variable i, len, st, sts, dir;
+
+ if (dirs == NULL)
+ return;
+
+ len = length(dirs);
+ sts = Struct_Type [len];
+
+
+ _for (0, len-1, 1)
+ {
+ i = ();
+ dir = dirs[i];
+
+ if (prune_hidden)
+ {
+ if ((dir[0] == '.') and (Use_a_Option == 0))
+ {
+ !if (is_substr (dir, "\\"))
+ continue;
+ }
+ }
+
+ st = lstat_file (path_concat (this_dir, dir));
+ if (st == NULL)
+ () = fprintf (stderr, "%s: %s: %s\n",
+ __argv[0],
+ path_concat (this_dir, dir),
+ errno_string (errno));
+ else
+ sts[i] = st;
+ }
+
+
+ (dirs, sts) = sort_files (dirs, sts);
+
+ variable isdir;
+
+ if (length (sts)) isdir = array_map (Char_Type, &isdir_fun, sts);
+ else isdir = Int_Type[0];
+
+ variable i_reg = where (isdir == 0);
+ variable i_dir = where (isdir);
+ variable dont_recurse;
+
+
+ if (Use_F_Option and length (i_dir))
+ dirs[i_dir] = array_map (String_Type, &path_concat, dirs[i_dir], "");
+
+ dont_recurse = (Use_d_Option or not recurse);
+
+ if (dont_recurse)
+ {
+ if (Use_Long_Form)
+ ls_long (this_dir, dirs, sts);
+ else
+ ls_short (dirs);
+ return;
+ }
+
+ if (Use_Long_Form)
+ ls_long (this_dir, dirs[i_reg], sts[i_reg]);
+ else
+ ls_short (dirs[i_reg]);
+
+
+ if (length(i_dir) == 1)
+ {
+ if (length (i_reg) == 0)
+ {
+ dir = dirs[i_dir][0];
+
+ do_ls (list_dir (dir), dir, Use_R_Option, 1);
+ return;
+ }
+ () = fputs ("\n", stdout);
+ }
+
+
+ foreach (dirs[i_dir])
+ {
+ dir = ();
+ dir = path_concat (this_dir, dir);
+ () = fprintf (stdout, "%s:\n", dir);
+ do_ls (list_dir (dir), dir, Use_R_Option, 1);
+ () = fprintf (stdout, "\n");
+ }
+}
+
+define main (argc, argv)
+{
+ variable dirs;
+
+ if (argc == 1)
+ return do_ls (list_dir("."), ".", 0, 1);
+ else if (__argv[1][0] == '-')
+ {
+ parse_args (__argv[1]);
+
+ if (Use_d_Option and Use_R_Option)
+ Use_R_Option = 0;
+
+ if (__argc > 2)
+ dirs = __argv[[2:]];
+ else
+ return do_ls (list_dir("."), ".", Use_R_Option, 1);
+ }
+ else
+ dirs = __argv[[1:]];
+
+ do_ls (dirs, ".", 1, 0);
+}
+
+
+main (__argc, __argv);