patch: executable modules support with "guile -e ENTRYPOINT"

Thien-Thi Nguyen <[email protected]>
Newsgroups gmane.lisp.guile.user,gmane.lisp.guile.sources
Message-ID <[email protected]>
the patch to libguile/script.c below extends the guile interpreter's
handling of "-e ENTRYPOINT" to support "executable modules".  before,
ENTRYPOINT named a procedure only.  now, you can additionally specify:

	-e "(some module)"		-- proc assumed to be "main"
	-e "(some module) some-proc"

generally, "MODULE-NAME PROC-NAME" constructs the expression (to be
evaluated after reading the script):

	((module-ref (resolve-module 'MODULE-NAME) 'PROC-NAME)
         (command-line))

which means scripts can now look like:

	#!/bin/sh
	exec ${GUILE-guile} -e '(my module) start' -s $0 "$@"
	!#
	(define (outside args)
	  (format #t "outside: ~S\n" args))
	(define-module (my module))
	(define (start args)
	  (format #t "start: ~S\n" args))

if saved to "example-script" and chmod +x, invocation looks like:

	$ ./example-script 3 2 1 contact!
	start: ("./example-script" "3" "2" "1" "contact!")

if '(my module) start' is changed to 'outside', you see:

	$ ./example-script 3 2 1 contact!
	outside: ("./example-script" "3" "2" "1" "contact!")

this patch is released under the same terms of guile-1.4.x, q.v.
fsf already has papers for my changes to guile.

thi

___________________________________________________
2003-08-21  Thien-Thi Nguyen  <[email protected]>

	* script.c (scm_shell_usage): Update description of "-e" handling.
	(scm_compile_shell_switches): Add handling for "MODULE-NAME"
	and "MODULE-NAME PROC-NAME" for "-e" switch.

________________________
Index: script.c
===================================================================
RCS file: /home/ttn/cvs/guile-core/libguile/script.c,v
retrieving revision 1.2
diff -c -p -w -c -r1.2 script.c
*** script.c	2002/08/29 18:12:46	1.2
--- script.c	2003/08/21 12:31:11
*************** scm_shell_usage (int fatal, char *messag
*** 376,383 ****
             "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"
             "  --debug        start with debugging evaluator and backtraces\n"
  	   "  -q             inhibit loading of user init file\n"
--- 376,388 ----
             "remaining arguments as the value of (command-line).\n"
             "\n"
             "  -l FILE        load Scheme source code from FILE\n"
!            "  -e ENTRYPOINT  after reading script, apply ENTRYPOINT to\n"
!            "                 command line arguments; ENTRYPOINT may name\n"
!            "                 - a procedure\n"
!            "                 - a module (procedure assumed to be \"main\")\n"
!            "                      example: \"(my script)\"\n"
!            "                 - a module followed by a procedure\n"
!            "                      example: \"(my script) actual-main\"\n"
             "  -ds            do -s script at this point\n"
             "  --debug        start with debugging evaluator and backtraces\n"
  	   "  -q             inhibit loading of user init file\n"
*************** scm_compile_shell_switches (int argc, ch
*** 510,516 ****
--- 515,554 ----
        else if (! strcmp (argv[i], "-e")) /* entry point */
  	{
  	  if (++i < argc)
+             {
+               if (argv[i][0] == '(')
+                 /* Handle "(some module name) some-proc-name".  Believe me,
+                    this approach is much less hairy than a three-page tree of
+                    scm_cons and scm_sym_FOO!  --ttn  */
+                 {
+                   char *end_modulename = index (argv[i], ')');
+ 
+                   if (! end_modulename)
+                     scm_shell_usage (1, "incomplete module name in `-e' switch");
+ 
+                   end_modulename++;
+                   {
+                     char *fmt = "'(module-ref (resolve-module '%s) '%s)";
+                     char *buf = (char *) malloc (strlen (argv[i]) +
+                                                  strlen (fmt) + 6);
+                     char *proc = end_modulename;
+ 
+                     while (' ' == *proc || '\t' == *proc || '\n' == *proc)
+                       proc++;
+                     if ('\0' == *proc)
+                       proc = "main";
+ 
+                     *end_modulename = '\0';
+ 
+                     sprintf (buf, fmt, argv[i], proc);
+                     entry_point = scm_eval_string (scm_makfrom0str (buf));
+                     free (buf);
+                   }
+                 }
+               else
+                 /* Handle "proc-name" alone.  */
                  entry_point = gh_symbol2scm (argv[i]);
+             }
  	  else
  	    scm_shell_usage (1, "missing argument to `-e' switch");
  	}


_______________________________________________
Guile-user mailing list
[email protected]
http://mail.gnu.org/mailman/listinfo/guile-user
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.