aboutsummaryrefslogtreecommitdiffhomepage
path: root/libslang/slsh
diff options
context:
space:
mode:
Diffstat (limited to 'libslang/slsh')
-rw-r--r--libslang/slsh/INSTALL26
-rw-r--r--libslang/slsh/Makefile.g3236
-rw-r--r--libslang/slsh/Makefile.in74
-rw-r--r--libslang/slsh/README43
-rw-r--r--libslang/slsh/lib/arrayfuns.sl50
-rw-r--r--libslang/slsh/lib/autoload.sl4
-rw-r--r--libslang/slsh/lib/require.sl82
-rw-r--r--libslang/slsh/lib/slsh.rc46
-rwxr-xr-xlibslang/slsh/scripts/badlinks78
-rwxr-xr-xlibslang/slsh/scripts/htmlstrip48
-rwxr-xr-xlibslang/slsh/scripts/ls333
-rwxr-xr-xlibslang/slsh/scripts/lsrpm85
-rwxr-xr-xlibslang/slsh/scripts/mv143
-rwxr-xr-xlibslang/slsh/scripts/purge65
-rw-r--r--libslang/slsh/slsh.c481
15 files changed, 1594 insertions, 0 deletions
diff --git a/libslang/slsh/INSTALL b/libslang/slsh/INSTALL
new file mode 100644
index 0000000..f129243
--- /dev/null
+++ b/libslang/slsh/INSTALL
@@ -0,0 +1,26 @@
+Before building slsh, it is wise to first build the slang library and
+install it via, e.g., 'make install-elf'.
+
+On Unix, running 'make install' will put:
+
+ * the slsh executable in $prefix/bin/
+ * lib/slsh.rc in $prefix/etc/
+ * lib/*.sl in $prefix/share/slsh/
+
+(See ../INSTALL.unx for information about $prefix.) To change these
+locations, edit the Makefile.
+
+A mingw32 windows executable may be created using Makefile.g32 via
+
+ make -f Makefile.g32
+ make -f Makefile.g32 install
+
+As above, edit the makefile to change the installation locations. You
+will also have to put something like:
+
+ set SLSH_PATH=C:/etc
+ set SLSH_CONF_DIR=C:/etc
+
+in your autoexec.bat file and then reboot.
+
+Good luck.
diff --git a/libslang/slsh/Makefile.g32 b/libslang/slsh/Makefile.g32
new file mode 100644
index 0000000..55010f6
--- /dev/null
+++ b/libslang/slsh/Makefile.g32
@@ -0,0 +1,36 @@
+# This is a makefile for mingw32. Compiling slsh using other compilers should
+# be equally simple.
+#
+CC = gcc
+CFLAGS = -W -Wall -O2
+COPY = cp
+SLCONFIG_H = ../src/slconfig.h
+#---------------------------------------------------------------------------
+# Installation location of the slang library
+#---------------------------------------------------------------------------
+SLANG_INC = -I../src
+SLANG_LIB = -L../src/gw32objs -lslang
+#----------------------------------------------------------------------------
+# Installation location of lib/slsh.rc and lib/*.sl
+#----------------------------------------------------------------------------
+COPY = cp
+MKDIR = mkdir
+SLSH_CONF_DIR = C:/slsh
+SLSH_LIB_DIR = C:/slsh
+#----------------------------------------------------------------------------
+# End of user configuration
+#----------------------------------------------------------------------------
+LIBS = $(RPATH) $(SLANG_LIB) $(DL_LIB) -lm
+#DEFS = -DSLSH_CONF_DIR='"$(SLSH_CONF_DIR)"' -DSLSH_PATH='"$(SLSH_LIB_DIR)"'
+
+slsh: slsh.c config.h
+ $(CC) $(CFLAGS) slsh.c -o slsh $(SLANG_INC) $(LIBS)
+config.h: ../src/config.h
+ $(COPY) $(SLCONFIG_H) config.h
+install: slsh
+ -$(MKDIR) $(SLSH_CONF_DIR)
+ -$(MKDIR) $(SLSH_LIB_DIR)
+ $(COPY) lib/*.sl $(SLSH_LIB_DIR)
+ $(COPY) lib/slsh.rc $(SLSH_CONF_DIR)
+
+
diff --git a/libslang/slsh/Makefile.in b/libslang/slsh/Makefile.in
new file mode 100644
index 0000000..be30d3e
--- /dev/null
+++ b/libslang/slsh/Makefile.in
@@ -0,0 +1,74 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+LDFLAGS = @LDFLAGS@ @DYNAMIC_LINK_FLAGS@
+#---------------------------------------------------------------------------
+# Installation location of the slang library
+#---------------------------------------------------------------------------
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+SLANG_INC = -I@includedir@
+SLANG_LIB = -L@libdir@ -lslang
+#---------------------------------------------------------------------------
+DL_LIB = @DYNAMIC_LINK_LIB@
+RPATH = @RPATH@
+#----------------------------------------------------------------------------
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSDIR = ../autoconf/mkinsdir.sh
+#----------------------------------------------------------------------------
+# Where system-wide slsh.rc and library files reside
+#----------------------------------------------------------------------------
+SLSH_CONF_DIR = @sysconfdir@
+SLSH_LIB_DIR = @datadir@/slsh
+SLSH_LOCALLIB_DIR = $(SLSH_LIB_DIR)/local-packages
+#---------------------------------------------------------------------------
+# DESTDIR is designed to facilitate making packages. Normally it is empty
+#---------------------------------------------------------------------------
+DESTDIR =
+BIN_DIR = @bindir@
+DEST_BIN_DIR = $(DESTDIR)$(BIN_DIR)
+DEST_SLSH_CONF_DIR = $(DESTDIR)$(SLSH_CONF_DIR)
+DEST_SLSH_LIB_DIR = $(DESTDIR)$(SLSH_LIB_DIR)
+DEST_SLSH_LOCALLIB_DIR = $(DESTDIR)$(SLSH_LOCALLIB_DIR)
+#----------------------------------------------------------------------------
+# End of user configuration
+#----------------------------------------------------------------------------
+@SET_MAKE@
+SHELL = /bin/sh
+LIBS = $(RPATH) $(SLANG_LIB) $(DL_LIB) -lm
+DEFS = -DSLSH_CONF_DIR='"$(SLSH_CONF_DIR)"' -DSLSH_PATH='"$(SLSH_LIB_DIR)"'
+
+slsh: slsh.c config.h
+ $(CC) $(CFLAGS) $(DEFS) slsh.c -o slsh $(SLANG_INC) $(LDFLAGS) $(LIBS)
+config.h: ../src/config.h
+ cp ../src/config.h .
+install_directories:
+ $(MKINSDIR) $(DEST_BIN_DIR)
+ $(MKINSDIR) $(DEST_SLSH_CONF_DIR)
+ $(MKINSDIR) $(DEST_SLSH_LIB_DIR)
+ $(MKINSDIR) $(DEST_SLSH_LOCALLIB_DIR)
+install_lib_files:
+ @for X in lib/*.sl; \
+ do \
+ echo $(INSTALL_DATA) $$X $(DEST_SLSH_LIB_DIR); \
+ $(INSTALL_DATA) $$X $(DEST_SLSH_LIB_DIR); \
+ if [ "$$?" != "0" ]; then \
+ exit 1; \
+ fi; \
+ done
+
+install: slsh install_directories install_lib_files
+ $(INSTALL) slsh $(DEST_BIN_DIR)/
+ $(INSTALL_DATA) lib/slsh.rc $(DEST_SLSH_CONF_DIR)/
+ echo 'prepend_to_slang_load_path("$(SLSH_LOCALLIB_DIR)");' >> $(DEST_SLSH_CONF_DIR)/slsh.rc
+#---------------------------------------------------------------------------
+# Housekeeping
+#---------------------------------------------------------------------------
+clean:
+ -/bin/rm -f *~ slsh scripts/*~ lib/*~
+distclean: clean
+ -/bin/rm -f Makefile
+symlinks:
+ -/bin/rm -f $(ARCH)objs
+ -mkdir -p $(HOME)/sys/$(ARCH)/objs/jdl/src
+ ln -s $(HOME)/sys/$(ARCH)/objs/jdl/src $(ARCH)objs
diff --git a/libslang/slsh/README b/libslang/slsh/README
new file mode 100644
index 0000000..9fd402e
--- /dev/null
+++ b/libslang/slsh/README
@@ -0,0 +1,43 @@
+slsh (slang-shell) is a work in progress. See the scripts/
+subdirectory for some trivial examples of its use.
+
+Usage: slsh [OPTIONS] [[-|file] [args ...]]
+ --help Print this help
+ --version Show slsh version information
+ -g Compile with debugging code, tracebacks, etc
+ -n Don't load personal init file
+ -i init-file Use this file instead of default
+ -v Show verbose loading messages
+
+Along with the slsh executable, the files lib/slsh.rc and lib/*.sl
+will also get installed.
+
+Upon startup, the program will try to load slsh.rc as follows:
+
+ If either SLSH_CONF_DIR or SLSH_LIB_DIR environment variables
+ exist, then look in the corresponding directories for slsh.rc.
+ Otherwise look in:
+
+ $(prefix)/etc (specified in Makefile)
+ /usr/local/etc/
+ /usr/local/etc/slsh/
+ /etc/
+ /etc/slsh/
+
+The slsh.rc file may load other files from slsh's library directory in
+the manner described below.
+
+Once slsh.rc is loaded, slsh will load $HOME/.slshrc if present.
+Finally, it will load the script specified on the command line. If
+the name of the script is "-", then it will be read from stdin.
+
+When a script loads a file via the built-in "evalfile" function or the
+"require" function (autoloaded by slsh.rc), the file is searched for
+along the SLSH_PATH as specified in the Makefile. An alternate path
+may be specified by the SLSH_PATH environment variable.
+
+The search path may be queried and set during run time via set the
+get_lib_path and set_lib_path functions, e.g.,
+
+ set_lib_path ("/home/bill/lib/slsh:/usr/share/slsh");
+
diff --git a/libslang/slsh/lib/arrayfuns.sl b/libslang/slsh/lib/arrayfuns.sl
new file mode 100644
index 0000000..17d9a49
--- /dev/null
+++ b/libslang/slsh/lib/arrayfuns.sl
@@ -0,0 +1,50 @@
+%!%+
+%\function{reverse}
+%\synopsis{Reverse the elements of a 1-d array}
+%\usage{Array_Type reverse (Array_Type A)}
+%\description
+% The \slfun{reverse} function reverses the elements of a 1-d array and
+% returns the result.
+%\seealso{shift}
+%!%-
+public define reverse (a)
+{
+ variable i = length (a);
+ if (i <= 1)
+ return a;
+
+ i--;
+ __tmp(a)[[i:0:-1]];
+}
+
+
+%!%+
+%\function{shift}
+%\synopsis{Shift the elements of a 1-d array}
+%\usage{Array_Type shift (Array_Type A, Int_Type n)}
+%\description
+% The \slfun{shift} function shifts the elements of an array by a specified amount
+% and returns the result. If \exmp{n} is positive, the ith element of the array
+% will be shifted to the position \exmp{i-n} of the array. Elements for
+% which \exmp{i-n} is less than 0 will be moved to the end of the array.
+%\example
+%#v+
+% A = [1,2,3,4,5,6,7,8,9];
+% B = shift (A, 3); % ==> B = [4,5,6,7,8,9,1,2,3];
+% C = shift (A, -1); % ==> C = [9,1,2,3,4,5,6,7,8];
+%#v-
+%\notes
+% It many ways \exmp{rotate} would be a better name for this function.
+%\seealso{reverse, transpose}
+%!%-
+public define shift (x, n)
+{
+ variable len = length(x);
+ variable i = [0:len-1];
+
+ % allow n to be negative and large
+ n = len + n mod len;
+ return x[(i + n)mod len];
+}
+
+provide ("arrayfuns");
diff --git a/libslang/slsh/lib/autoload.sl b/libslang/slsh/lib/autoload.sl
new file mode 100644
index 0000000..db5837a
--- /dev/null
+++ b/libslang/slsh/lib/autoload.sl
@@ -0,0 +1,4 @@
+autoload ("require", "require");
+autoload ("provide", "require");
+autoload ("reverse", "arrayfuns");
+autoload ("shift", "arrayfuns");
diff --git a/libslang/slsh/lib/require.sl b/libslang/slsh/lib/require.sl
new file mode 100644
index 0000000..eec1e0d
--- /dev/null
+++ b/libslang/slsh/lib/require.sl
@@ -0,0 +1,82 @@
+% These functions were taken from the jed editor
+
+static variable Features = Assoc_Type [Int_Type,0];
+
+%!%+
+%\function{_featurep}
+%\synopsis{Test whether or not a feature is present}
+%\usage{Int_Type _featurep (String_Type feature)}
+%\description
+% The \sfun{_featurep} function returns a non-zero value if the specified
+% feature is present. Otherwise, it returns 0 to indicate that the feature
+% has not been loaded.
+%\seealso{require, provide}
+%!%-
+public define _featurep (f)
+{
+ Features[f];
+}
+
+
+%!%+
+%\function{provide}
+%\synopsis{Declare that a specified feature is available}
+%\usage{provide (String_Type feature)}
+%\description
+% The \sfun{provide} function may be used to declare that a "feature" has
+% been loaded. See the documentation for \sfun{require} for more information.
+%\seealso{require, _featurep}
+%!%-
+public define provide (f)
+{
+ Features[f] = 1;
+}
+
+%!%+
+%\function{require}
+%\synopsis{Make sure a feature is present, and load it if not}
+%\usage{require (String_Type feature [,String_Type file]}
+%\description
+% The \sfun{require} function ensures that a specified "feature" is present.
+% If the feature is not present, the \sfun{require} function will attempt to
+% load the feature from a file. If called with two arguments, the feature
+% will be loaded from the file specified by the second argument. Otherwise,
+% the feature will be loaded from a file given by the name of the feature,
+% with ".sl" appended.
+%
+% If after loading the file, if the feature is not present,
+% a warning message will be issued.
+%\notes
+% "feature" is an abstract quantity that is undefined here.
+%
+% A popular use of the \sfun{require} function is to ensure that a specified
+% file has already been loaded. In this case, the feature is the
+% filename itself. The advantage of using this mechanism over using
+% \ifun{evalfile} is that if the file has already been loaded, \sfun{require}
+% will not re-load it. For this to work, the file must indicate that it
+% provides the feature via the \sfun{provide} function.
+%\seealso{provide, _featurep, evalfile}
+%!%-
+public define require ()
+{
+ variable f, file;
+
+ if (_NARGS == 2)
+ {
+ (f, file) = ();
+ }
+ else
+ {
+ f = ();
+ file = f;
+ }
+
+ if (_featurep (f))
+ return;
+
+ () = evalfile (file);
+ !if (_featurep (f))
+ vmessage ("***Warning: feature %s not found in %s", f, file);
+}
+
+
diff --git a/libslang/slsh/lib/slsh.rc b/libslang/slsh/lib/slsh.rc
new file mode 100644
index 0000000..10ce328
--- /dev/null
+++ b/libslang/slsh/lib/slsh.rc
@@ -0,0 +1,46 @@
+% -*- slang -*-
+
+% This file gets loaded whenever slsh runs. Its primary purpose is to define
+% some functions that are useful in scripts, and to set up some local paths
+
+static define dir_exists (dir)
+{
+ variable s = stat_file (dir);
+ if (s == NULL) return 0;
+ return stat_is ("dir", s.st_mode);
+}
+
+%!%+
+%\function{prepend_to_slang_load_path}
+%\synopsis{Prepend a directory to the load-path}
+%\usage{prepend_to_slang_load_path (String_Type dir)}
+%\description
+% This function adds a directory to the beginning of the interpreter's
+% load-path.
+%\seealso{append_to_slang_load_path, set_slang_load_path}
+%!%-
+public define prepend_to_slang_load_path (p)
+{
+ if (dir_exists (p))
+ set_slang_load_path (strcat (p, ":", get_slang_load_path ()));
+}
+
+%!%+
+%\function{append_to_slang_load_path}
+%\synopsis{Append a directory to the load-path}
+%\usage{append_to_slang_load_path (String_Type dir)}
+%\description
+% This function adds a directory to the end of the interpreter's
+% load-path.
+%\seealso{prepend_to_slang_load_path, set_slang_load_path}
+%!%-
+public define append_to_slang_load_path (p)
+{
+ if (dir_exists (p))
+ set_slang_load_path (get_slang_load_path (), ":", p);
+}
+
+() = evalfile ("autoload.sl");
+
+% Add local additions here
+
diff --git a/libslang/slsh/scripts/badlinks b/libslang/slsh/scripts/badlinks
new file mode 100755
index 0000000..77409bd
--- /dev/null
+++ b/libslang/slsh/scripts/badlinks
@@ -0,0 +1,78 @@
+#!/usr/bin/env slsh
+% Find links that point to non-existent files
+
+static define warn ()
+{
+ variable args = __pop_args (_NARGS-1);
+ variable err = ();
+ variable msg;
+
+ msg = sprintf (__push_args (args));
+
+ if (err)
+ err = ": " + errno_string (err);
+ else
+ err == "";
+
+ () = fprintf (stderr, "%s: %s%s\n",
+ __argv[0], msg, err);
+}
+
+static define badlinks (dir)
+{
+ variable files, file;
+ variable st;
+
+ files = listdir (dir);
+ if (files == NULL)
+ {
+ warn (errno, dir);
+ return;
+ }
+
+ foreach (files)
+ {
+ file = ();
+
+ file = path_concat (dir, file);
+ st = stat_file (file);
+ if (st != NULL)
+ continue;
+
+ if (errno != ENOENT)
+ {
+ warn (errno, file);
+ continue;
+ }
+
+ if (-1 == fprintf (stdout, "%s\n", file))
+ break;
+ }
+}
+
+define main (argc, argv)
+{
+ if (argc > 1)
+ {
+ if (argv[1] == "--help")
+ {
+ () = fprintf (stdout, "Usage: %s [--help] [dirs....]\n",
+ __argv[0]);
+ exit (1);
+ }
+ }
+
+ if (argc == 1)
+ {
+ badlinks (".");
+ exit (0);
+ }
+
+ foreach (argv[[1:]])
+ badlinks ();
+
+ exit (0);
+}
+
+main (__argc, __argv);
+
diff --git a/libslang/slsh/scripts/htmlstrip b/libslang/slsh/scripts/htmlstrip
new file mode 100755
index 0000000..c6a6b36
--- /dev/null
+++ b/libslang/slsh/scripts/htmlstrip
@@ -0,0 +1,48 @@
+#! /usr/bin/env slsh
+% -*- mode: slang -*-
+%_debug_info = 1;
+
+% This file strips HTML tags from one or more html files and write the result
+% to stdout. It is very simple minded.
+
+define process_file (file)
+{
+ variable fp, l;
+
+ if (file != NULL)
+ {
+ fp = fopen (file, "r");
+ if (fp == NULL)
+ {
+ () = fputs (sprintf ("Unable to open %s\n", file), stderr);
+ return;
+ }
+ }
+ else fp = stdin;
+
+ foreach (fp)
+ {
+ l = ();
+
+ l = strtrim (str_uncomment_string (l, "<", ">"));
+ !if (strlen (l))
+ continue;
+
+ () = fputs (l, stdout);
+ () = fputs ("\n", stdout);
+ }
+}
+
+if (__argc == 1)
+{
+ if (isatty (stdin))
+ {
+ () = fprintf (stderr, "Usage: %s [files...]\n", __argv[0]);
+ exit (1);
+ }
+ process_file (NULL);
+ exit (0);
+}
+
+foreach (__argv[[1:]]) process_file ();
+exit (0);
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);
diff --git a/libslang/slsh/scripts/lsrpm b/libslang/slsh/scripts/lsrpm
new file mode 100755
index 0000000..dcd607a
--- /dev/null
+++ b/libslang/slsh/scripts/lsrpm
@@ -0,0 +1,85 @@
+#! /usr/bin/env slsh
+% Generate a listing of an RPM file
+
+static define pgm_usage ()
+{
+ vmessage ("Usage: lsrpm FILENAME");
+ exit (1);
+}
+
+static variable RPM_Command = "rpm -q -l --dump -p ";
+
+static define exit_error (msg)
+{
+ () = fprintf (stderr, "%s\n", msg);
+ exit (1);
+}
+
+
+static define run_rpm (file)
+{
+ variable fp;
+ variable lines;
+ variable months =
+ ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
+ "Oct", "Nov", "Dec"];
+ variable s;
+
+ fp = popen (RPM_Command + file, "r");
+ if (fp == NULL)
+ exit_error ("Failed to open RPM process");
+
+ % each line contains:
+ % path size mtime md5sum mode owner group isconfig isdoc rdev symlink
+
+ variable six_months_ago = _time () - 3600*24*30*6;
+
+ foreach (fp)
+ {
+ variable path, size, mode, owner, group, symlink, mtime;
+ variable mstring;
+ variable tm;
+
+ s = ();
+ s = strchop (strtrim_end (s, "\n"), ' ', 0);
+
+ path = s[0];
+ size = s[1];
+ mtime = integer (s[2]);
+ mode = integer (s[4]);
+ owner = s[5];
+ group = s[6];
+
+ tm = localtime (mtime);
+ 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 = "";
+ if (stat_is ("lnk", mode))
+ symlink = " -> " + s[10];
+
+ mstring = stat_mode_to_string (mode);
+
+ if (-1 == fprintf (stdout,
+ "%8s %8s %8s %10s %s %s%s\n",
+ mstring, owner, group, size, mtime, path, symlink))
+ exit_error (sprintf ("Write failed: %s", errno_string (errno)));
+ }
+ () = pclose (fp);
+}
+
+if (__argc != 2)
+ pgm_usage ();
+
+run_rpm (__argv[1]);
+exit (0);
diff --git a/libslang/slsh/scripts/mv b/libslang/slsh/scripts/mv
new file mode 100755
index 0000000..47bc25f
--- /dev/null
+++ b/libslang/slsh/scripts/mv
@@ -0,0 +1,143 @@
+#!/usr/bin/env slsh
+% -*- slang -*-
+
+static variable Confirm_Move = 0;
+
+static define get_yn ()
+{
+ variable args = __pop_args (_NARGS);
+ () = fprintf (stdout, __push_args (args));
+ () = fflush (stdout);
+
+ variable yn;
+ if (fgets (&yn, stdin) <= 0)
+ return -1;
+
+ "y" == strlow (strtrim (yn));
+}
+
+
+static define move_file (from, to)
+{
+ if (from == to)
+ {
+ () = fprintf (stderr, "%s: Cannot move a file to itself.\n", __argv[0]);
+ return -1;
+ }
+
+ if (0 == rename (from, to))
+ return 0;
+
+ variable st = stat_file (to);
+
+ if (st != NULL)
+ {
+ if (1 != get_yn ("%s exists. Overwrite? [y/n]", to))
+ {
+ () = fputs ("Not Confirmed\n", stdout);
+ return -1;
+ }
+ () = remove (to);
+ }
+
+ if (0 == rename (from, to))
+ return 0;
+
+ ()=fprintf (stderr, "Failed to rename %s to %s: %s\n",
+ from, to, errno_string (errno));
+
+ return -1;
+}
+
+define move_files (from_files, to)
+{
+ variable st = stat_file (to);
+ if (st == NULL)
+ {
+ if (length (from_files) != 1)
+ {
+ () = fprintf (stderr, "%s must be a directory\n", to);
+ exit (1);
+ }
+ if (-1 == move_file (from_files[0], to))
+ exit (1);
+ exit (0);
+ }
+
+ !if (stat_is ("dir", st.st_mode))
+ {
+ if (length (from_files) != 1)
+ {
+ () = fprintf (stderr, "%s must be a directory\n", to);
+ exit (1);
+ }
+ if (-1 == move_file (from_files[0], to))
+ exit (1);
+ exit (0);
+ }
+
+
+ foreach (from_files)
+ {
+ variable old = ();
+ variable new = path_concat (to, path_basename (old));
+
+ if (NULL == stat_file (old))
+ {
+ () = fprintf (stderr, "Unable to access %s\n", old);
+ continue;
+ }
+
+ if (Confirm_Move)
+ {
+ if (1 != get_yn ("Move %s to %s/? [y/n]", old, to))
+ {
+ () = fputs ("Not Confirmed\n", stdout);
+ continue;
+ }
+ }
+
+
+ () = move_file (old, new);
+ }
+}
+
+static define usage ()
+{
+ () = fprintf (stdout, "Usage: %s [-i] files ... dir\n", __argv[0]);
+ exit (1);
+}
+
+define main (argc, argv)
+{
+ argc--;
+ argv = argv[[1:]];
+
+ while (argc > 1)
+ {
+ if (argv[0] == "-i")
+ {
+ Confirm_Move = 1;
+ argc--;
+ argv = argv[[1:]];
+ continue;
+ }
+ break;
+ }
+
+ if (argc < 2)
+ usage ();
+
+ move_files (argv[[0:argc-2]], argv[argc-1]);
+}
+
+
+define slsh_main ()
+{
+ main (__argc, __argv);
+}
+
+
+
+
+
diff --git a/libslang/slsh/scripts/purge b/libslang/slsh/scripts/purge
new file mode 100755
index 0000000..fae0e20
--- /dev/null
+++ b/libslang/slsh/scripts/purge
@@ -0,0 +1,65 @@
+#! /usr/bin/env slsh
+% -*- mode: slang -*-
+_debug_info = 1;
+
+static define purge_file (file, age, print_option)
+{
+ variable st = stat_file (file);
+ if (st == NULL)
+ {
+ () = fprintf (stderr, "stat %s failed: %s\n", file, errno_string (errno));
+ return;
+ }
+
+ if (st.st_ctime >= age)
+ return;
+
+ if (print_option)
+ {
+ () = fprintf (stdout, "%s\n", file);
+ return;
+ }
+
+ if (-1 == remove (file))
+ () = fprintf (stderr, "remove %s failed: %s\n", file, errno_string (errno));
+}
+
+static define purge_usage ()
+{
+ () = fprintf (stderr, "Usage: %s [-n] NUM-DAYS-OLD files...\n", __argv[0]);
+ () = fprintf (stderr, " Files older than NUM-DAYS-OLD be deleted.\n");
+ () = fprintf (stderr, " -n ==> Just print the files to be removed but do not remove them.\n");
+ exit (1);
+}
+
+static define main (argc, argv)
+{
+ variable age, i, print_option, file;
+
+ if (argc < 3) purge_usage ();
+
+ i = 2;
+ print_option = 0;
+ if (argv[1] == "-n")
+ {
+ i++;
+ print_option = 1;
+ if (argc < 4)
+ purge_usage ();
+ }
+
+ age = __argv[i-1];
+ if (String_Type == _slang_guess_type (age))
+ purge_usage ();
+
+ age = _time() - atof(age) * 24 * 3600;
+
+ foreach (argv[[i:]])
+ {
+ file = ();
+ purge_file (file, age, print_option);
+ }
+ exit (0);
+}
+
+main (__argc, __argv);
diff --git a/libslang/slsh/slsh.c b/libslang/slsh/slsh.c
new file mode 100644
index 0000000..ffa6c3d
--- /dev/null
+++ b/libslang/slsh/slsh.c
@@ -0,0 +1,481 @@
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef __WIN32__
+# include <windows.h>
+#endif
+
+#include <sys/stat.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <string.h>
+#include <slang.h>
+
+static char *Slsh_Version = "0.6-0";
+#define SLSHRC_FILE "slsh.rc"
+
+#ifdef REAL_UNIX_SYSTEM
+/* # define DEFAULT_LIBRARY_PATH "/usr/local/share/slsh:/usr/local/lib/slsh:/usr/share/slsh:/usr/lib/slsh"; */
+# define DEFAULT_CONF_PATH "/usr/local/etc:/usr/local/slsh:/etc:/etc/slsh";
+# define USER_SLSHRC ".slshrc"
+#else
+# define DEFAULT_LIBRARY_PATH NULL
+# define USER_SLSHRC "slsh.rc"
+#endif
+
+#ifdef __os2__
+# ifdef __IBMC__
+/* IBM VA3 doesn't declare S_IFMT */
+# define S_IFMT (S_IFDIR | S_IFCHR | S_IFREG)
+# endif
+#endif
+
+#ifndef S_ISLNK
+# ifdef S_IFLNK
+# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+# else
+# define S_ISLNK(m) 0
+# endif
+#endif
+
+#ifndef S_ISREG
+# ifdef S_IFREG
+# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+# else
+# define S_ISREG(m) 0
+# endif
+#endif
+
+#ifndef S_ISDIR
+# ifdef S_IFDIR
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+# else
+# define S_ISDIR(m) 0
+# endif
+#endif
+
+#ifndef S_ISCHR
+# ifdef S_IFCHR
+# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+# else
+# define S_ISCHR(m) 0
+# endif
+#endif
+
+#ifndef S_ISBLK
+# ifdef S_IFBLK
+# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+# else
+# define S_ISBLK(m) 0
+# endif
+#endif
+
+#ifndef S_ISFIFO
+# ifdef S_IFIFO
+# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+# else
+# define S_ISFIFO(m) 0
+# endif
+#endif
+
+#ifndef S_ISSOCK
+# ifdef S_IFSOCK
+# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+# else
+# define S_ISSOCK(m) 0
+# endif
+#endif
+
+
+#ifndef S_IRUSR
+# define S_IRUSR 0400
+#endif
+#ifndef S_IWUSR
+# define S_IWUSR 0200
+#endif
+#ifndef S_IXUSR
+# define S_IXUSR 0100
+#endif
+#ifndef S_IRGRP
+# define S_IRGRP 0040
+#endif
+#ifndef S_IWGRP
+# define S_IWGRP 0020
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0010
+#endif
+#ifndef S_IROTH
+# define S_IROTH 0004
+#endif
+#ifndef S_IWOTH
+# define S_IWOTH 0002
+#endif
+#ifndef S_IXOTH
+# define S_IXOTH 0001
+#endif
+#ifndef S_ISUID
+# define S_ISUID 04000
+#endif
+#ifndef S_ISGID
+# define S_ISGID 02000
+#endif
+#ifndef S_ISVTX
+# define S_ISVTX 01000
+#endif
+
+typedef struct _AtExit_Type
+{
+ SLang_Name_Type *nt;
+ struct _AtExit_Type *next;
+}
+AtExit_Type;
+
+static AtExit_Type *AtExit_Hooks;
+
+static void at_exit (SLang_Ref_Type *ref)
+{
+ SLang_Name_Type *nt;
+ AtExit_Type *a;
+
+ if (NULL == (nt = SLang_get_fun_from_ref (ref)))
+ return;
+
+ a = (AtExit_Type *) SLmalloc (sizeof (AtExit_Type));
+ if (a == NULL)
+ return;
+
+ a->nt = nt;
+ a->next = AtExit_Hooks;
+ AtExit_Hooks = a;
+}
+
+static void c_exit (int *code)
+{
+ while (AtExit_Hooks != NULL)
+ {
+ AtExit_Type *next = AtExit_Hooks->next;
+ if (SLang_Error == 0)
+ (void) SLexecute_function (AtExit_Hooks->nt);
+
+ SLfree ((char *) AtExit_Hooks);
+ AtExit_Hooks = next;
+ }
+ exit (*code);
+}
+
+
+static void stat_mode_to_string (void)
+{
+ int mode, opts;
+ char mode_string[12];
+
+ opts = 0;
+ if (SLang_Num_Function_Args == 2)
+ {
+ if (-1 == SLang_pop_integer (&opts))
+ return;
+ }
+
+ if (-1 == SLang_pop_integer (&mode))
+ return;
+
+
+ if (S_ISREG(mode)) mode_string[0] = '-';
+ else if (S_ISDIR(mode)) mode_string[0] = 'd';
+ else if (S_ISLNK(mode)) mode_string[0] = 'l';
+ else if (S_ISCHR(mode)) mode_string[0] = 'c';
+ else if (S_ISFIFO(mode)) mode_string[0] = 'f';
+ else if (S_ISSOCK(mode)) mode_string[0] = 's';
+ else if (S_ISBLK(mode)) mode_string[0] = 'b';
+
+ if (mode & S_IRUSR) mode_string[1] = 'r'; else mode_string[1] = '-';
+ if (mode & S_IWUSR) mode_string[2] = 'w'; else mode_string[2] = '-';
+ if (mode & S_IXUSR) mode_string[3] = 'x'; else mode_string[3] = '-';
+ if (mode & S_ISUID) mode_string[3] = 's';
+
+#ifdef __WIN32__
+ mode_string[4] = '-';
+ mode_string[5] = '-';
+ mode_string[6] = '-';
+
+ if (opts & FILE_ATTRIBUTE_ARCHIVE) mode_string[7] = 'A'; else mode_string[7] = '-';
+ if (opts & FILE_ATTRIBUTE_SYSTEM) mode_string[8] = 'S'; else mode_string[8] = '-';
+ if (opts & FILE_ATTRIBUTE_HIDDEN) mode_string[9] = 'H'; else mode_string[9] = '-';
+#else
+ if (mode & S_IRGRP) mode_string[4] = 'r'; else mode_string[4] = '-';
+ if (mode & S_IWGRP) mode_string[5] = 'w'; else mode_string[5] = '-';
+ if (mode & S_IXGRP) mode_string[6] = 'x'; else mode_string[6] = '-';
+ if (mode & S_ISGID) mode_string[6] = 'g';
+
+ if (mode & S_IROTH) mode_string[7] = 'r'; else mode_string[7] = '-';
+ if (mode & S_IWOTH) mode_string[8] = 'w'; else mode_string[8] = '-';
+ if (mode & S_IXOTH) mode_string[9] = 'x'; else mode_string[9] = '-';
+ if (mode & S_ISVTX) mode_string[9] = 't';
+#endif
+
+ mode_string[10] = 0;
+ (void) SLang_push_string (mode_string);
+}
+
+
+static int Verbose_Loading;
+
+static int try_to_load_file (char *path, char *file, char *ns)
+{
+ int status;
+
+ if (path == NULL)
+ path = ".";
+
+ if (file != NULL)
+ {
+ file = SLpath_find_file_in_path (path, file);
+ if (file == NULL)
+ return 0;
+ }
+ /* otherwise use stdin */
+
+ status = SLns_load_file (file, ns);
+ SLfree (file);
+ if (status == 0)
+ return 1;
+ return -1;
+}
+
+
+static int load_startup_file (void)
+{
+ char *dir;
+ int status;
+
+ dir = getenv ("SLSH_CONF_DIR");
+ if (dir == NULL)
+ dir = getenv ("SLSH_LIB_DIR");
+
+ if (NULL == dir)
+ {
+#ifdef SLSH_CONF_DIR
+ dir = SLSH_CONF_DIR;
+ if (dir != NULL)
+ {
+ status = try_to_load_file (dir, SLSHRC_FILE, NULL);
+ if (status == -1)
+ return -1;
+ if (status == 1)
+ return 0;
+ }
+#endif
+ dir = DEFAULT_CONF_PATH;
+ }
+
+ if (-1 == (status = try_to_load_file (dir, SLSHRC_FILE, NULL)))
+ return -1;
+
+ if ((status == 0) && Verbose_Loading)
+ {
+ SLang_vmessage ("*** Installation Problem? Unable to find the %s config file.",
+ SLSHRC_FILE);
+ }
+
+ return 0;
+}
+
+
+#if 0
+static int is_script (char *file)
+{
+ FILE *fp;
+ char buf[3];
+ int is;
+
+ if (NULL == (fp = fopen (file, "r")))
+ return 0;
+
+ is = ((NULL != fgets (buf, sizeof(buf), fp))
+ && (buf[0] == '#') && (buf[1] == '!'));
+
+ fclose (fp);
+ return is;
+}
+#endif
+
+static int setup_paths (void)
+{
+ char *libpath;
+
+ if (NULL == (libpath = getenv ("SLSH_PATH")))
+ {
+#ifdef SLSH_PATH
+ libpath = SLSH_PATH;
+#endif
+ }
+
+ return SLpath_set_load_path (libpath);
+}
+
+/* Create the Table that S-Lang requires */
+static SLang_Intrin_Fun_Type Intrinsics [] =
+{
+ MAKE_INTRINSIC_I("exit", c_exit, VOID_TYPE),
+ MAKE_INTRINSIC_1("atexit", at_exit, VOID_TYPE, SLANG_REF_TYPE),
+ MAKE_INTRINSIC_0("stat_mode_to_string", stat_mode_to_string, VOID_TYPE),
+ SLANG_END_INTRIN_FUN_TABLE
+};
+
+static void usage (void)
+{
+ char *libpath;
+ fprintf (stderr, "\
+Usage: slsh [OPTIONS] [-|file [args...]]\n\
+ --help Print this help\n\
+ --version Show slsh version information\n\
+ -g Compile with debugging code, tracebacks, etc\n\
+ -n Don't load personal init file\n\
+ -i init-file Use this file instead of ~/%s\n\
+ -v Show verbose loading messages\n\
+",
+ USER_SLSHRC
+ );
+ libpath = SLpath_get_load_path ();
+ fprintf (stderr, "Default search path: %s\n", (libpath == NULL) ? "" : libpath);
+ SLang_free_slstring (libpath);
+
+ exit (1);
+}
+
+static void version (void)
+{
+ fprintf (stdout, "slsh version %s\n", Slsh_Version);
+ fprintf (stdout, "S-Lang Library Version: %s\n", SLang_Version_String);
+ if (SLANG_VERSION != SLang_Version)
+ {
+ fprintf (stdout, "\t** Note: This program was compiled against version %s.\n",
+ SLANG_VERSION_STRING);
+ }
+
+ exit (0);
+}
+
+int main (int argc, char **argv)
+{
+ char *file = NULL;
+ char *init_file = USER_SLSHRC;
+ char *init_file_dir;
+
+ if (SLang_Version < SLANG_VERSION)
+ {
+ fprintf (stderr, "***Warning: Executable compiled against S-Lang %s but linked to %s\n",
+ SLANG_VERSION_STRING, SLang_Version_String);
+ fflush (stderr);
+ }
+
+ if ((-1 == SLang_init_all ())
+ || (-1 == SLang_init_array_extra ())
+ || (-1 == SLang_init_import ()) /* dynamic linking */
+ || (-1 == SLadd_intrin_fun_table (Intrinsics, NULL)))
+ {
+ fprintf(stderr, "Unable to initialize S-Lang.\n");
+ return 1;
+ }
+
+ /* FIXME for other systems */
+ init_file_dir = getenv ("HOME");
+
+ if (-1 == setup_paths ())
+ return -1;
+
+ while (argc > 1)
+ {
+ if (0 == strcmp (argv[1], "--version"))
+ version ();
+
+ if (0 == strcmp (argv[1], "--help"))
+ usage ();
+
+ if (0 == strcmp (argv[1], "-g"))
+ {
+ SLang_generate_debug_info (1);
+ argc--;
+ argv++;
+ continue;
+ }
+
+ if (0 == strcmp (argv[1], "-n"))
+ {
+ init_file = NULL;
+ argc--;
+ argv++;
+ continue;
+ }
+
+ if (0 == strcmp (argv[1], "-v"))
+ {
+ (void) SLang_load_file_verbose (1);
+ Verbose_Loading = 1;
+ argc--;
+ argv++;
+ continue;
+ }
+
+ if ((0 == strcmp (argv[1], "-i"))
+ && (argc > 2))
+ {
+ init_file = argv[2];
+ init_file_dir = NULL;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+ break;
+ }
+
+ if (argc == 1)
+ {
+ if (0 == isatty (fileno(stdin)))
+ file = NULL;
+ else
+ usage ();
+ }
+ else
+ {
+ file = argv[1];
+ if (0 == strcmp (file, "-"))
+ file = NULL;
+#if 0
+ if (is_script (file))
+ {
+ argv++;
+ argc--;
+ }
+#else
+ argc--;
+ argv++;
+#endif
+ }
+ /* fprintf (stdout, "slsh: argv[0]=%s\n", argv[0]); */
+ if (-1 == SLang_set_argc_argv (argc, argv))
+ return 1;
+
+ /* Turn on traceback generation */
+ SLang_Traceback = 1;
+
+ if (-1 == load_startup_file ())
+ return SLang_Error;
+
+ if ((init_file != NULL)
+ && (-1 == try_to_load_file (init_file_dir, init_file, NULL)))
+ return SLang_Error;
+
+ /* Now load an initialization file and exit */
+ if (0 == try_to_load_file (NULL, file, NULL))
+ {
+ fprintf (stderr, "%s: file not found\n", file);
+ exit (1);
+ }
+
+ (void) SLang_run_hooks ("slsh_main", 0);
+ return SLang_Error;
+}