[fr] access to (main-args) ix of script just being executed

Started by hartrock, August 11, 2015, 09:19:50 AM

Previous topic - Next topic

hartrock

Currently there is the following for guessing, which could be the script currently being executed:

(context sys)
;;
;; A (scriptpath), (scriptname), (scriptargs) solution for skipping newlisp opts
;; and their args: could be a helper for getopts.
;;
;; Should be correct for typical shebang (#!/...) cases, but of interest here
;; are newlisp calls like:
;;   newlisp -s 4096 -m 10 someScript.lsp
;; .
;;
;; But it has limitations: it is only correkt, if *first* non-option arg of
;; newlisp is the script of interest.
;; E.g. calling
;;   newlisp -m 10 nonExistentFile
;; results into
;;   > (sys:scriptname)
;;   "nonExistentFile"
;; .
;; Therefrom it should be allowed and documented how to override; this can be
;; done by setting scriptpath_ix explicitely, in case of used heuristics fails.
;;
;; See file:///usr/share/doc/newlisp/newlisp_manual.html#options:
;;
;;  -h this help                   -> OK (enters interpreter)
;;  -n no init.lsp (must be first) -> OK
;;  -x <source> <target> link      -> error: should not been reached by script
;;  -v version                     -> OK (enters interpreter)
;;  -s <stacksize>                 -> OK
;;  -m <max-mem-MB> cell memory    -> OK
;;  -e <quoted lisp expression>    -> OK (enters interpreter)
;;  -l <path-file> log connections -> OK
;;  -L <path-file> log all         -> OK
;;  -w <working dir>               -> OK
;;  -c no prompts, HTTP            -> OK
;;  -C force prompts               -> OK
;;  -t <usec-server-timeout>       -> OK
;;  -p <port-no>                   -> OK
;;  -d <port-no> demon mode        -> OK
;;  -http only                     -> OK
;;  -6 IPv6 mode                   -> OK
;;
(set'opt_without_arg
 '("-h" ; enters interpreter
   "-n" ; -> skipped
   "-v" ; enters interpreter
   "-c" ; -> skipped
   "-C" ; -> skipped
   "-http" ; -> skipped
   "-6" ; -> skipped
   )
 'opt_with_arg
 '("-s" ; -> skipped
   "-e" ; enters interpreter
   "-m" ; -> skipped
   "-l" ; -> skipped
   "-L" ; -> skipped
   "-w" ; -> skipped
   "-t" ; -> skipped
   "-p" ; -> skipped
   "-d" ; -> skipped
   )
 'opt_with_2_args
 '("-x" ; should not been reached by script
   ;;"-y" ; for testing errorcase...
   ))
(local (breakFlag skip_next ix execPath)
  (set 'ix 0) ; without any args ix 0 refers to newlisp bin
  (dolist (o (1 (main-args)) breakFlag) ; without args, there is no loop here
   (cond
    (skip_next
     (++ ix)
     (set 'skip_next nil)) ; skip once
    ((find o opt_without_arg)
     (++ ix))
    ((find o opt_with_arg)
     (++ ix)
     (set 'skip_next true))
    ((find o opt_with_2_args)
     (throw-error "should not been reached"))
    ("default" ; end loop: first newlisp noopt should be script
     (++ ix) ; needed: loop started with ix of previous element
     (set 'breakFlag true))))
  (set 'scriptpath_ix ix)) ; 0 or index of first element not being a newlisp option with its args
;; iface
(define (scriptpath-ix) ; needed for getopts below
  scriptpath_ix)
(define (scriptargs) ; good as getopts arg
  ((++ (scriptpath-ix)) (main-args)))
(define (scriptpath)
  (main-args scriptpath_ix))
(define (scriptname) ; Linux (to be extended for other OSes)
  (last (parse (scriptpath) "/")))

This approach replicates interpreter code and has serious limitations, because it is unknown, which given script is currently being executed after its interpreter load, if there are multiple args, which all could be scripts: e.g.

- newlisp arg_1.lsp arg_2.lsp arg_3.lsp [options][/list]

could mean

- newlisp lib_1.lsp lib_2.lsp scriptOfInterest.lsp [options]

or

- newlisp lib_1.lsp scriptOfInterest.lsp scriptArg.lsp [options]

.

What about having a way to get the (main-args) index of last interpreter loaded and currently executed script?

This would allow to get the best possible scriptname for more complicate cases than just having only one script directly after newlisp opts, which is helpful for a most general getopts module.

It would also allow to do

- newlisp scriptOfInterest_1.lsp scriptOfInterest_2.lsp

and give different (scriptname)s - for e.g. err messages - then (without setting them explicitely by the scripts themselves).