#!/bin/sh
: ; exec klone $0 "$@"
; The above line finds the klone executable in the $PATH
;; This is an example script on how to parse lots of Klone files to track
;; use of some syntax. Here the old syntax for setting locators:
;; #[a b = c] which is to be replaced (not by this script) by:
;; #[a b := c]

;;Skeleton of a typical klone script

(setq files (getopts "USAGE: %0 [options] files...
Scans files and find all usage of (old) klone syntax.
Try to print them in a meanungful, emacs-friendly way.
Warning: some hits may mask others. Re-run the prog after edits until 
everything seems Ok"
    ("-dot" () FindDot "dots in symbols")
    ("-oldlocator" () FindLoc "Old locator syntax: #[a b = c] instead of #[a b := c]")
    ("-locator" () FindAllLoc "Find locators: #[a b]")
;; --- Hidden Options ---
    ("-debug" () enter-debugger-on-error "enter klone debugger on error"
    :hidden t)
    ("-stackdump" () stackdump-on-error "verbose stack dump on error"
    :hidden t)
))

(if enter-debugger-on-error (kdb t))
(if stackdump-on-error (stack-dump-on-error t))

;; define this predicate to return non-nil if the expr is the form 
;;you are looking for
;; the ExpressionToFindp:value will be printed to help user...

(setq re-dot (regcomp "^.[.].$"))
(defun ExpressionToFindp (expr)
  (if
    ;;  Find Symbols with dots
    (and FindDot
      (typep expr Symbol) (regexec re-dot expr))
    (setq ExpressionToFindp:value expr)

    ;;  finds the form  #[a b = c]
    (and FindLoc
      (typep expr Locator) (= '= (getn expr (- (length expr) 2))))
    (setq ExpressionToFindp:value expr)

    ;;  any locator  #[a b ...]
    (and FindAllLoc (typep expr Locator))
    (setq ExpressionToFindp:value expr)

    t ()
  )
)

(setq *quote-inlines* t)

(defun main (&aux
  )
  (dolist (file files)
    (catch 'ALL
      (process-file file)
    )
  )
)

(defun process-file (file &aux
    (fd (open file))
    expr 
  )
  (catch 'EOF
    (while t
      (setq expr (read fd))
      (setq is-in-expr:count 0)
      (if (is-in-expr expr ExpressionToFindp)
	(print-format "%0:%1: %2 occurences (%4) in: %3\n"
	  file (file-lineno fd) is-in-expr:count (truncate-to expr 40)
	  ExpressionToFindp:value
)))))

;; find current line in file
(defun file-lineno (fd &aux
    (cur-pos (file-position fd))
    (line 0)
  )
  (file-position fd 0)			;rewind
  (catch 'EOF
    (while (< (file-position fd) cur-pos)	;count from start
      (read-line fd)
      (incf line)
  ))
  (file-position fd cur-pos)
  line
)

(defvar is-in-expr:count 0)

(defun is-in-expr (expr subexprp )
  (if (apply subexprp (list expr))
    (incf is-in-expr:count)
    (if (typep expr List)
      (catch 'Found
	(dolist (se expr)
	  (if (and (boundp 'se)		;if se is set to *undefined*
	      (is-in-expr se subexprp))
	    (throw 'Found t)
	))
	()
      )
      () 
)))

(defun truncate-to (expr N &aux
    (s (print-format String "%0" expr))
  )
  (if (> (length s) N)
    (subseq s 0 N)
    s
  )
)


(main)

;;; EMACS MODES
;;; Local Variables: ***
;;; mode:lisp ***
;;; End: ***

