diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2011-10-14 04:55:05 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2011-10-14 04:55:05 +0200 |
commit | 6aa0e0017d7d0cddc006da885946934b06949a91 (patch) | |
tree | 66b688ec32e2f91266db760b1762f2a50cc52036 /libslang/slsh | |
parent | a966db5b71328f6adf9dd767e64b322a3bd7ed9c (diff) | |
download | erlang-slang-fork-6aa0e0017d7d0cddc006da885946934b06949a91.tar.gz |
include libslang-1.4.9 and automatically build it and link erlang-slang against it
few (erlang) people will still have libslang-1.4.9 installed or spend time
to get it to link against the driver
Diffstat (limited to 'libslang/slsh')
-rw-r--r-- | libslang/slsh/INSTALL | 26 | ||||
-rw-r--r-- | libslang/slsh/Makefile.g32 | 36 | ||||
-rw-r--r-- | libslang/slsh/Makefile.in | 74 | ||||
-rw-r--r-- | libslang/slsh/README | 43 | ||||
-rw-r--r-- | libslang/slsh/lib/arrayfuns.sl | 50 | ||||
-rw-r--r-- | libslang/slsh/lib/autoload.sl | 4 | ||||
-rw-r--r-- | libslang/slsh/lib/require.sl | 82 | ||||
-rw-r--r-- | libslang/slsh/lib/slsh.rc | 46 | ||||
-rwxr-xr-x | libslang/slsh/scripts/badlinks | 78 | ||||
-rwxr-xr-x | libslang/slsh/scripts/htmlstrip | 48 | ||||
-rwxr-xr-x | libslang/slsh/scripts/ls | 333 | ||||
-rwxr-xr-x | libslang/slsh/scripts/lsrpm | 85 | ||||
-rwxr-xr-x | libslang/slsh/scripts/mv | 143 | ||||
-rwxr-xr-x | libslang/slsh/scripts/purge | 65 | ||||
-rw-r--r-- | libslang/slsh/slsh.c | 481 |
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; +} |