From 224c49f96a62505285bb92e1ba7151d3a78ab6b8 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Sun, 20 Apr 1997 19:58:45 +0000 Subject: Move most of the guts of shell command processing into libguile, so guile.c can be very small (and eventuallly auto-generated. (I mean, generated mechanically, not self-generated. Hmm.)) * guile.c, script.c, script.h: New source files. * init.c (scm_boot_guile_1): Call scm_init_script. * libguile.h: #include "script.h". * Makefile.am (bin_PROGRAMS, guile_SOURCES, guile_LDADD): New targets, for new executable. (libguile_la_SOURCES): Mention script.c. (modinclude_HEADERS): Add script.h. * configure.in: Always check for -lm, -lsocket, -lnsl, whether or not dynamic linking is enabled. This is because we're generating executables now. Move CY_AC_WITH_THREADS call after those, so the values of cy_cv_threads_libs captures the libs chosen above. * Makefile.in, configure, aclocal.m4: Regenerated. --- libguile/script.c | 816 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ libguile/script.h | 60 ++++ 2 files changed, 876 insertions(+) create mode 100644 libguile/script.c create mode 100644 libguile/script.h diff --git a/libguile/script.c b/libguile/script.c new file mode 100644 index 000000000..acf8bbaf9 --- /dev/null +++ b/libguile/script.c @@ -0,0 +1,816 @@ +/* Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * As a special exception, the Free Software Foundation gives permission + * for additional uses of the text contained in its release of GUILE. + * + * The exception is that, if you link the GUILE library with other files + * to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the GUILE library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the + * Free Software Foundation under the name GUILE. If you copy + * code from other Free Software Foundation releases into a copy of + * GUILE, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for GUILE, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/* "script.c" argv tricks for `#!' scripts. + Author: Aubrey Jaffer */ + +#include +#include +#include "_scm.h" +#include "gh.h" +#include "load.h" + +#include "script.h" + +#ifdef __IBMC__ +#include +#endif /* def __IBMC__ */ + +#ifdef linux +#include /* for X_OK define */ +#endif /* def linux */ +#ifdef __svr4__ +#include /* for X_OK define */ +#else +#ifdef __sgi__ +#include /* for X_OK define */ +#endif /* def __sgi__ */ +#endif /* def __svr4__ */ +#ifdef hpux +#define const +/**/ +#endif + +/* Concatentate str2 onto str1 at position n and return concatenated + string if file exists; 0 otherwise. */ + +static char * +scm_cat_path (str1, str2, n) + char *str1; + const char *str2; + long n; +{ + if (!n) + n = strlen (str2); + if (str1) + { + long len = strlen (str1); + str1 = (char *) realloc (str1, (scm_sizet) (len + n + 1)); + if (!str1) + return 0L; + strncat (str1 + len, str2, n); + return str1; + } + str1 = (char *) malloc ((scm_sizet) (n + 1)); + if (!str1) + return 0L; + str1[0] = 0; + strncat (str1, str2, n); + return str1; +} + +#if 0 +static char * +scm_try_path (path) + char *path; +{ + FILE *f; + /* fprintf(stderr, "Trying %s\n", path);fflush(stderr); */ + if (!path) + return 0L; + SCM_SYSCALL (f = fopen (path, "r"); + ); + if (f) + { + fclose (f); + return path; + } + free (path); + return 0L; +} + +static char * +scm_sep_init_try (path, sep, initname) + char *path; + const char *sep, *initname; +{ + if (path) + path = scm_cat_path (path, sep, 0L); + if (path) + path = scm_cat_path (path, initname, 0L); + return scm_try_path (path); +} +#endif + +#ifndef LINE_INCREMENTORS +#define LINE_INCREMENTORS '\n' +#ifdef MSDOS +#define WHITE_SPACES ' ':case '\t':case '\r':case '\f':case 26 +#else +#define WHITE_SPACES ' ':case '\t':case '\r':case '\f' +#endif /* def MSDOS */ +#endif /* ndef LINE_INCREMENTORS */ + +#ifndef MAXPATHLEN +#define MAXPATHLEN 80 +#endif /* ndef MAXPATHLEN */ +#ifndef X_OK +#define X_OK 1 +#endif /* ndef X_OK */ + +#ifdef unix +#include + +char * +scm_find_executable (name) + const char *name; +{ + char tbuf[MAXPATHLEN]; + int i = 0; + FILE *f; + + /* fprintf(stderr, "s_f_e checking access %s ->%d\n", name, access(name, X_OK)); fflush(stderr); */ + if (access (name, X_OK)) + return 0L; + f = fopen (name, "r"); + if (!f) + return 0L; + if ((fgetc (f) == '#') && (fgetc (f) == '!')) + { + while (1) + switch (tbuf[i++] = fgetc (f)) + { + case /*WHITE_SPACES */ ' ': + case '\t': + case '\r': + case '\f': + case EOF: + tbuf[--i] = 0; + fclose (f); + return scm_cat_path (0L, tbuf, 0L); + } + } + fclose (f); + return scm_cat_path (0L, name, 0L); +} +#endif /* unix */ + +#ifdef MSDOS + +#define DEFAULT_PATH "C:\\DOS" +#define PATH_DELIMITER ';' +#define ABSOLUTE_FILENAME_P(fname) ((fname[0] == '\\') \ + || (fname[0] && (fname[1] == ':'))) + +char * +dld_find_executable (file) + const char *file; +{ + /* fprintf(stderr, "dld_find_executable %s -> %s\n", file, scm_cat_path(0L, file, 0L)); fflush(stderr); */ + return scm_cat_path (0L, file, 0L); +} +#endif /* def MSDOS */ + +#if 0 +/* This code was originally borrowed from SCM; Guile sees things + differently. */ + +/* Given dld_find_executable()'s best guess for the pathname of this + executable, find (and verify the existence of) initname in the + implementation-vicinity of this program. Returns a newly allocated + string if successful, 0 if not */ + +char * +scm_find_impl_file (exec_path, generic_name, initname, sep) + char *exec_path; + const char *generic_name, *initname, *sep; +{ + char *sepptr = strrchr (exec_path, sep[0]); + char *extptr = exec_path + strlen (exec_path); + char *path = 0; + /* fprintf(stderr, "dld_find_e %s\n", exec_path); fflush(stderr); */ + if (sepptr) + { + long sepind = sepptr - exec_path + 1L; + + /* In case exec_path is in the source directory, look first in + exec_path's directory. */ + path = scm_cat_path (0L, exec_path, sepind - 1L); + path = scm_sep_init_try (path, sep, initname); + if (path) + return path; + +#ifdef MSDOS + if (!strcmp (extptr - 4, ".exe") || !strcmp (extptr - 4, ".com") || + !strcmp (extptr - 4, ".EXE") || !strcmp (extptr - 4, ".COM")) + extptr = extptr - 4; +#endif /* def MSDOS */ + + if (generic_name && + !strncmp (exec_path + sepind, generic_name, extptr - exec_path)) + generic_name = 0; + + /* If exec_path is in directory "exe" or "bin": */ + path = scm_cat_path (0L, exec_path, sepind - 1L); + sepptr = path + sepind - 4; + if (!strcmp (sepptr, "exe") || !strcmp (sepptr, "bin") || + !strcmp (sepptr, "EXE") || !strcmp (sepptr, "BIN")) + { + char *peer; + + /* Look for initname in peer directory "lib". */ + if (path) + { + strncpy (sepptr, "lib", 3); + path = scm_sep_init_try (path, sep, initname); + if (path) + return path; + } + + /* Look for initname in peer directories "lib" and "src" in + subdirectory with the name of the executable (sans any type + extension like .EXE). */ + for (peer = "lib"; !0; peer = "src") + { + path = scm_cat_path (0L, exec_path, extptr - exec_path + 0L); + if (path) + { + strncpy (path + sepind - 4, peer, 3); + path[extptr - exec_path] = 0; + path = scm_sep_init_try (path, sep, initname); + if (path) + return path; + } + if (!strcmp (peer, "src")) + break; + } + + if (generic_name) + { + + /* Look for initname in peer directories "lib" and "src" in + subdirectory with the generic name. */ + for (peer = "lib"; !0; peer = "src") + { + path = scm_cat_path (0L, exec_path, sepind); + if (path) + { + strncpy (path + sepind - 4, "lib", 3); + path = scm_cat_path (path, generic_name, 0L); + path = scm_sep_init_try (path, sep, initname); + if (path) + return path; + } + if (!strcmp (peer, "src")) + break; + } + } + } + +#ifdef MSDOS + if (strlen (extptr)) + { + /* If exec_path has type extension, look in a subdirectory with + the name of the executable sans the executable file's type + extension. */ + path = scm_cat_path (0L, exec_path, extptr - exec_path + 0L); + path = scm_sep_init_try (path, sep, initname); + if (path) + return path; + + if (generic_name) + { + + /* Also look in generic_name subdirectory. */ + path = scm_cat_path (0L, exec_path, sepind); + if (path) + path = scm_cat_path (path, generic_name, 0L); + path = scm_sep_init_try (path, sep, initname); + if (path) + return path; + } + } +#endif /* def MSDOS */ + } + else + { + + /* We don't have a parse-able exec_path. The only path to try is + just initname. */ + path = scm_cat_path (0L, initname, 0L); + if (path) + path = scm_try_path (path); + if (path) + return path; + } + return 0L; +} +#endif /* 0 */ + + +/* Read a \nnn-style escape. We've just read the backslash. */ +static int +script_get_octal (f) + FILE *f; +{ + int i; + int value = 0; + + for (i = 0; i < 3; i++) + { + int c = getc (f); + if ('0' <= c && c <= '7') + value = (value * 8) + (c - '0'); + else + scm_wta (SCM_UNDEFINED, + "malformed script: bad octal backslash escape", + "script argument parser"); + } + return value; +} + + +static int +script_get_backslash (f) + FILE *f; +{ + int c = getc (f); + + switch (c) + { + case 'a': return '\a'; + case 'b': return '\b'; + case 'f': return '\f'; + case 'n': return '\n'; + case 'r': return '\r'; + case 't': return '\t'; + case 'v': return '\v'; + + case '\\': + case ' ': + case '\t': + case '\n': + return c; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + ungetc (c, f); + return script_get_octal (f); + + case EOF: + scm_wta (SCM_UNDEFINED, + "malformed script: backslash followed by EOF", + "script argument parser"); + return 0; /* not reached? */ + + default: + scm_wta (SCM_UNDEFINED, + "malformed script: bad backslash sequence", + "script argument parser"); + return 0; /* not reached? */ + } +} + + +static char * +script_read_arg (f) + FILE *f; +{ + int size = 7; + char *buf = malloc (size + 1); + int len = 0; + + if (! buf) + return 0; + + for (;;) + { + int c = getc (f); + switch (c) + { + case '\\': + c = script_get_backslash (f); + /* The above produces a new character to add to the argument. + Fall through. */ + default: + if (len >= size) + { + size = (size + 1) * 2; + buf = realloc (buf, size); + if (! buf) + return 0; + } + buf[len++] = c; + break; + + case '\n': + /* This may terminate an arg now, but it will terminate the + entire list next time through. */ + ungetc ('\n', f); + case EOF: + if (len == 0) + { + free (buf); + return 0; + } + /* Otherwise, those characters terminate the argument; fall + through. */ + case ' ': + buf[len] = '\0'; + return buf; + + case '\t': + free (buf); + scm_wta (SCM_UNDEFINED, + "malformed script: TAB in meta-arguments", + "argument parser"); + return 0; /* not reached? */ + } + } +} + + +static int +script_meta_arg_P (arg) + char *arg; +{ + if ('\\' != arg[0]) + return 0L; +#ifdef MSDOS + return !arg[1]; +#else + switch (arg[1]) + { + case 0: + case '%': + case WHITE_SPACES: + return !0; + default: + return 0L; + } +#endif +} + +char ** +scm_get_meta_args (argc, argv) + int argc; + char **argv; +{ + int nargc = argc, argi = 1, nargi = 1; + char *narg, **nargv; + if (!(argc > 2 && script_meta_arg_P (argv[1]))) + return 0L; + if (!(nargv = (char **) malloc ((1 + nargc) * sizeof (char *)))) + return 0L; + nargv[0] = argv[0]; + while (((argi + 1) < argc) && (script_meta_arg_P (argv[argi]))) + { + FILE *f = fopen (argv[++argi], "r"); + if (f) + { + nargc--; /* to compensate for replacement of '\\' */ + while (1) + switch (getc (f)) + { + case EOF: + return 0L; + default: + continue; + case '\n': + goto found_args; + } + found_args: + while ((narg = script_read_arg (f))) + if (!(nargv = (char **) realloc (nargv, + (1 + ++nargc) * sizeof (char *)))) + return 0L; + else + nargv[nargi++] = narg; + fclose (f); + nargv[nargi++] = argv[argi++]; + } + } + while (argi <= argc) + nargv[nargi++] = argv[argi++]; + return nargv; +} + +int +scm_count_argv (argv) + char **argv; +{ + int argc = 0; + while (argv[argc]) + argc++; + return argc; +} + + +/* For use in error messages. */ +char *scm_usage_name = 0; + +void +scm_shell_usage (int fatal, char *message) +{ + if (message) + fprintf (stderr, "%s\n", message); + + fprintf (stderr, + "Usage: %s OPTION ...\n" + "Evaluate Scheme code, interactively or from a script.\n" + "\n" + " -s SCRIPT load Scheme source code from FILE, and exit\n" + " -c EXPR evalute Scheme expression EXPR, and exit\n" + " -- stop scanning arguments; run interactively\n" + "The above switches stop argument processing, and pass all\n" + "remaining arguments as the value of (command-line).\n" + "\n" + " -l FILE load Scheme source code from FILE\n" + " -e FUNCTION after reading script, apply FUNCTION to\n" + " command line arguments\n" + " -ds do -s script at this point\n" + " --emacs enable Emacs protocol (experimental)\n" + " -h, --help display this help and exit\n" + " -v, --version display version information and exit\n" + " \\ read arguments from following script lines\n", + scm_usage_name); + + if (fatal) + exit (1); +} + + +/* Some symbols used by the command-line compiler. */ +SCM_SYMBOL (sym_load, "load"); +SCM_SYMBOL (sym_eval_string, "eval-string"); +SCM_SYMBOL (sym_command_line, "command-line"); +SCM_SYMBOL (sym_begin, "begin"); +SCM_SYMBOL (sym_load_user_init, "load-user-init"); +SCM_SYMBOL (sym_top_repl, "top-repl"); +SCM_SYMBOL (sym_quit, "quit"); + + +/* Given an array of command-line switches, return a Scheme expression + to carry out the actions specified by the switches. + + If you told me this should have been written in Scheme, I'd + probably agree. I'd say I didn't feel comfortable doing that in + the present system. You'd say, well, fix the system so you are + comfortable doing that. I'd agree again. *shrug* + + We load the ice-9 system from here. It might be nicer if the + libraries initialized from the inner_main function in guile.c (which + will be auto-generated eventually) could assume ice-9 were already + loaded. Then again, it might be nice if ice-9 could assume that + certain libraries were already loaded. The solution is to break up + ice-9 into modules which can be frozen and statically linked like any + other module. Then all the modules can describe their dependencies in + the usual way, and the auto-generated inner_main will do the right + thing. */ + +SCM +scm_compile_shell_switches (int argc, char **argv) +{ + SCM tail = SCM_EOL; /* We accumulate the list backwards, + and then reverse! it before we + return it. */ + SCM do_script = SCM_EOL; /* The element of the list containing + the "load" command, in case we get + the "-ds" switch. */ + SCM entry_point = SCM_EOL; /* for -e switch */ + int interactive = 1; /* Should we go interactive when done? */ + int use_emacs_interface = 0; + int i; + char *argv0; + + if (argc > 0) + { + scm_usage_name = strrchr (argv[0], '/'); + if (! scm_usage_name) + scm_usage_name = argv[0]; + else + scm_usage_name++; + } + if (! scm_usage_name) + scm_usage_name = "guile"; + argv0 = scm_usage_name; + + for (i = 1; i < argc; i++) + { + if (! strcmp (argv[i], "-s")) /* load script */ + { + if (++i >= argc) + scm_shell_usage (1, "missing argument to `-s' switch"); + + /* If we specified the -ds option, do_script points to the + cdr of an expression like (load #f); we replace the car + (i.e., the #f) with the script name. */ + if (do_script != SCM_EOL) + { + SCM_SETCAR (do_script, scm_makfrom0str (argv[i])); + do_script = SCM_EOL; + } + else + /* Construct an application of LOAD to the script name. */ + tail = scm_cons (scm_cons2 (sym_load, + scm_makfrom0str (argv[i]), + SCM_EOL), + tail); + argv0 = argv[i]; + i++; + interactive = 0; + break; + } + + else if (! strcmp (argv[i], "-c")) /* evaluate expr */ + { + if (++i >= argc) + scm_shell_usage (1, "missing argument to `-c' switch"); + tail = scm_cons (scm_cons2 (sym_eval_string, + scm_makfrom0str (argv[i]), + SCM_EOL), + tail); + i++; + interactive = 0; + break; + } + + else if (! strcmp (argv[i], "--")) /* end args; go interactive */ + { + i++; + break; + } + + else if (! strcmp (argv[i], "-l")) /* load a file */ + { + if (++i < argc) + tail = scm_cons (scm_cons2 (sym_load, + scm_makfrom0str (argv[i]), + SCM_EOL), + tail); + else + scm_shell_usage (1, "missing argument to `-l' switch"); + } + + else if (! strcmp (argv[i], "-e")) /* entry point */ + { + if (++i < argc) + entry_point = gh_symbol2scm (argv[i]); + else + scm_shell_usage (1, "missing argument to `-e' switch"); + } + + else if (! strcmp (argv[i], "-ds")) /* do script here */ + { + /* We put a dummy "load" expression, and let the -s put the + filename in. */ + if (do_script != SCM_EOL) + scm_shell_usage (1, "the -ds switch may only be specified once"); + do_script = scm_cons (SCM_BOOL_F, SCM_EOL); + tail = scm_cons (scm_cons (sym_load, do_script), + tail); + } + + else if (! strcmp (argv[i], "--emacs")) /* use emacs protocol */ + use_emacs_interface = 1; + + else if (! strcmp (argv[i], "-h") + || ! strcmp (argv[i], "--help")) + { + scm_shell_usage (0, 0); + exit (0); + } + + else if (! strcmp (argv[i], "-v") + || ! strcmp (argv[i], "--version")) + { + /* Print version number. */ + printf ("Guile %s\n" + "Copyright (c) 1995, 1996 Free Software Foundation\n" + "Guile may be distributed under the terms of the GNU General Public Licence;\n" + "certain other uses are permitted as well. For details, see the file\n" + "`COPYING', which is included in the Guile distribution.\n" + "There is no warranty, to the extent permitted by law.\n", + GUILE_VERSION); + exit (0); + } + + else + { + fprintf (stderr, "%s: Unrecognized switch `%s'\n", + scm_usage_name, argv[i]); + scm_shell_usage (1, 0); + } + } + + /* Check to make sure the -ds got a -s. */ + if (do_script != SCM_EOL) + scm_shell_usage (1, "the `-ds' switch requires the use of `-s' as well"); + + /* Make any remaining arguments available to the + script/command/whatever. */ + scm_set_program_arguments (argc - i, argv + i, argv0); + + /* If the --emacs switch was set, now is when we process it. */ + scm_sysintern ("use-emacs-interface", + (use_emacs_interface) ? SCM_BOOL_T : SCM_BOOL_F); + + /* Handle the `-e' switch, if it was specified. */ + if (entry_point != SCM_EOL) + tail = scm_cons (scm_cons2 (entry_point, + scm_cons (sym_command_line, SCM_EOL), + SCM_EOL), + tail); + + /* If we didn't end with a -c or a -s, load the user's customization + file, and start the repl. */ + if (interactive) + { + tail = scm_cons (scm_cons (sym_load_user_init, SCM_EOL), tail); + tail = scm_cons (scm_cons (sym_top_repl, SCM_EOL), tail); + } + + /* After doing all the other actions prescribed by the command line, + quit. */ + tail = scm_cons (scm_cons (sym_quit, SCM_EOL), + tail); + + { + /* We want a path only containing directories from SCHEME_LOAD_PATH, + SCM_SITE_DIR and SCM_LIBRARY_DIR when searching for the site init + file, so we do this before loading Ice-9. */ + SCM init_path = scm_sys_search_load_path (scm_makfrom0str ("init.scm")); + + /* Load Ice-9. */ + scm_primitive_load_path (scm_makfrom0str ("ice-9/boot-9.scm")); + + /* Load the init.scm file. */ + if (SCM_NFALSEP (init_path)) + scm_primitive_load (init_path); + } + + { + SCM val = scm_cons (sym_begin, scm_list_reverse_x (tail, SCM_UNDEFINED)); + + scm_write (val, SCM_UNDEFINED); + scm_newline (SCM_UNDEFINED); + + return val; + } +} + + +void +scm_shell (argc, argv) + int argc; + char **argv; +{ + /* If present, add SCSH-style meta-arguments from the top of the + script file to the argument vector. See the SCSH manual: "The + meta argument" for more details. */ + { + char **new_argv = scm_get_meta_args (argc, argv); + + if (new_argv) + { + argv = new_argv; + argc = scm_count_argv (new_argv); + } + } + + scm_eval_x (scm_compile_shell_switches (argc, argv)); +} + + +void +scm_init_script () +{ +#include "script.x" +} diff --git a/libguile/script.h b/libguile/script.h new file mode 100644 index 000000000..406e76645 --- /dev/null +++ b/libguile/script.h @@ -0,0 +1,60 @@ +/* classes: h_files */ + +#ifndef SCRIPTH +#define SCRIPTH +/* Copyright (C) 1995,1996 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * As a special exception, the Free Software Foundation gives permission + * for additional uses of the text contained in its release of GUILE. + * + * The exception is that, if you link the GUILE library with other files + * to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the GUILE library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the + * Free Software Foundation under the name GUILE. If you copy + * code from other Free Software Foundation releases into a copy of + * GUILE, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for GUILE, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +#include "libguile/__scm.h" + + +extern char *scm_find_executable SCM_P ((const char *name)); +extern char *scm_find_impl_file SCM_P ((char *exec_path, + const char *generic_name, + const char *initname, + const char *sep)); +extern char **scm_get_meta_args SCM_P ((int argc, char **argv)); +extern int scm_count_argv SCM_P ((char **argv)); +extern void scm_shell SCM_P ((int argc, char **argv)); +extern char *scm_usage_name; +extern void scm_init_script (); + +#endif /* SCRIPTH */ -- cgit v1.2.1