Page 1 of 1

trial to get script info from outside interpreter core

Posted: Fri Sep 25, 2015 4:49 am
by hartrock
There has been a trial to get some script info - e.g. for getopts - from outside interpreter core:

Code: Select all

;;
;; script properties
;; - could become part of getopts or an own module
;;

;; *** old basename (now scriptname) too limited ***
;;
;;;; works for both newLisp and #!/.../newlisp
;;(define (basename)
;;  (setq execPath (or (main-args 1) (main-args 0)))
;;  (last (parse execPath "/")))

;;
;; 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
;;   > (Logger: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
       'scriptargs_ ((+ 1 scriptpath_ix) (main-args))
       'scriptpath_ (main-args scriptpath_ix)
       'scriptname_ (last (parse scriptpath_ "/"))))
;; iface
(define (scriptpath-ix)
  scriptpath_ix)
(define (scriptargs) ; good as getopts arg
  scriptargs_)
(define (scriptpath)
  scriptpath_)
(define (scriptname) ; Linux (to be extended for other OSes)
  scriptname_)
(define (shebang?) ; works for Linux; to be extended for other OSes
  (and (= (main-args 0) "/usr/local/bin/newlisp")
       (!= (scriptname) "newlisp")))

;;
;; .. script properties
;;
But I don't like it:
  • it repeats parsing of CLI args of the interpreter;
  • it has serious limitations.
From such efforts stems my interest in having $main-args-load-ix (or similar) as base for a better solution.