emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Sesquicolon -- Alternative to Shebang


From: John H Swaby
Subject: Sesquicolon -- Alternative to Shebang
Date: Sun, 08 Sep 2002 00:39:48 -0600 (MDT)

I see no reason to modify Emacs.  The sesquicolon, :;, does the job,
essentially, of the shebang, #!.  Permit me to elaborate.

The shebang works for many languages because their comment character
is a number sign, #, and they require only two arguments to run a
script.

The sesquicolon works for Emacs because it allows for more than two
arguments and it is compatible with the Lisp comment character, the
semicolon.

In many versions of Unix, if the first two characters of a script are
the shebang, then the program specified after the shebang is run with,
optionally, the one argument that can appear on the shebang line.  The
program is then passed, as its last argument, the script to be
interpreted.

If the first two characters of the file are not the shebang; but the
first character is a number sign, #, then the C Shell, csh, will be
invoked to interpret the script.

If neither of the above, then the Bourne Shell, sh, will be invoked as
the interpreter (keeping in mind that on some systems either the Korn
Shell, ksh, or the Bourne Again Shell, bash, will stand in for the
Bourne Shell).

Emacs requires more than two arguments to run a script; but the
sesquicolon allows for this.  Since the first two characters of the
script are the sesquicolon, :;, the third of the cases described above
is the one that applies and, hence, sh (or ksh or bash, as the case
may be) is invoked as the interpreter.

The colon is a null command in sh, ksh, or bash, and so does nothing.
The semicolon is a command delimiter in all three shells.  And, in all
three shells, the exec command has the same meaning.  Hence,

  :;exec emacs -batch -l $0 -f main $*

will have Emacs interpreting the current script, with the entry
function being "main".  [ For the Korn shell, replace "$0" with "$_".]

When Emacs loads the script the colon evaluates to itself (the colon
is a self-evaluating constant in current versions of Emacs) and the
remainder of the line is ignored as a comment.  [ For older versions
of Emacs, adding the arguments "-eval '(setq : t)'" to the sesquicolon
line will take care of Emacs's evaluation of the colon. ]

The remaining arguments, $*, are accessabile by way of the variable
"command-line-args-left".  Setting this variable to nil or calling the
function kill-emacs at the exit point of the script will prevent Emacs
from loading the remaining arguments as files or directories into
buffers if that is so desired.

So, in my humble opinion, Emacs is already quite fit as an interpreter
of scripts.  For Emacs use the sesquicolon, for other languages use
the shebang.  Emacs marches to a different drummer -- all the better.

Sincerely,  John H. Swaby
            address@hidden

P.S. Another sample script (takes two absolute paths as arguments and
produces two strings.  The second is a repeat of the first argument
and the first is the relative path from the first argument to the
second argument):

:;exec emacs -batch -l $0 -f : $* # -*- Emacs-Lisp -*-
(defun : ()
  (setq args command-line-args-left command-line-args-left ())
  (cond ((null (cdr args))
         (princ (format "Usage: %s absolute_path1 absolute_path2\n"
                        (file-name-nondirectory (nth 2 command-line-args))))
         (kill-emacs 1)))
  (set 'p (pre-link (split-string (nth 0 args) "/")
                    (split-string (nth 1 args) "/")))
  (if p (print-link p) (princ "."))
  (princ (format " %s\n" (car args))))

(defun pre-link (p1 p2)
  (if (and (cdr p1) p2 (equal (car p1) (car p2))) (pre-link (cdr p1) (cdr p2))
    (append (if p1 (dot-dot-list p1) '(())) p2)))

(defun dot-dot-list (ls) (if (cdr ls) (cons ".." (dot-dot-list (cdr ls)))))

(defun print-link (ls)
  (if (car ls) (princ (car ls)))
  (if (or (cdr ls) (null (car ls))) (princ "/"))
  (if (cdr ls) (print-link (cdr ls))))
;;; end of relink





reply via email to

[Prev in Thread] Current Thread [Next in Thread]