#!/bin/sh : ; exec klone $0 "$@" ; The above line allows not to embed the exact path of the klone executable ;;Skeleton of a typical klone script (setq args (getopts "USAGE: %0 [options] " ("-v" () verbose "verbose operation") ("-debug" () enter-debugger-on-error "enter klone debugger on error") ("-stackdump" () stackdump-on-error "verbose stack dump on error") )) (if enter-debugger-on-error (kdb t)) (if stackdump-on-error (stack-dump-on-error t)) (defun main (&aux) (dolist (file args) (bspinfo file) ) ) (setq re-key (regcomp "\"[-a-zA-Z_0-9+=#.,/]+\"")) (defun bspinfo (file &aux (s (String (open file))) pos ;start of entities ent (stats (list)) ;plist name occurences_count ) ;; check (if (setq pos (seek s "{\n\"")) (if (not (regexec re-key s (+ pos 2))) (fatal-error 1 "Error: No valid BSP entities section in %0\n" file) ) (fatal-error 1 "Error: No BSP entities section in %0\n" file) ) (while (setq ent (parse-entity s 'pos)) (process-entity stats ent) ) (if (getn stats "name") (print-stats file stats) ) ) (setq re-ent-start (regcomp "^[ \t\n]*{[ \t\n]*\n")) (setq re-ent-end (regcomp "^[ \t\n]*}[ \t\n]*\n")) (setq re-ent-item (regcomp "^[ \t\n]*\"([^\"]+)\"[ \t\n]*\"([^\"]*)\"[ \t\n]*\n")) (defun parse-entity (s posvar &aux (p (eval posvar)) (ent (list)) (notdone t) ) (while notdone (if (= 0 (get s p)) (setq notdone ()) (regexec re-ent-start s p) (setq p (1 (get re-ent-start 0))) (regexec re-ent-end s p) (progn (setq notdone ()) (set posvar (1 (get re-ent-end 0))) ) (regexec re-ent-item s p) (progn (lappend ent (regsub re-ent-item 1)) (lappend ent (regsub re-ent-item 2)) (setq p (1 (get re-ent-item 0))) ) t (fatal-error 1 "Bad entity syntax: %r0\n" (subseq s p (+ p 100))) )) ent ) (defun process-entity (stats ent &aux val) (if (= "worldspawn" (getn ent "classname")) (progn (insert stats 0 (getn ent "message")) (insert stats 0 "name") ) ) ) (defun print-stats (file stats) (PF "%0 %1\n" (file-part file) (trim-chars (get stats "name" ""))) ) (setq file-part:re (regcomp "^(.*[/])?([^/]*)([.][bB][sS][pP])$")) (defun file-part (s) (if (regexec file-part:re s) (setq s (regsub file-part:re 2))) (tolower s) ) (setq re-space (regcomp "^[\x01-\x20\x7f-\xff]+")) (setq re-nospace (regcomp "^[^\x01-\x20\x7f-\xff]+")) (setq re-newline (regcomp "[\\]n")) (setq re-redchars (regcomp "[\x7f-\xff]")) (defun trim-chars (s &aux (res (copy "")) (pos 0)) (replace-string s re-newline "" :all t :quote t) (replace-string s re-redchars printable-version :all t :quote t) (if (regexec re-space s pos) (setq pos (1 (get re-space 0))) ) (while (regexec re-nospace s pos) (if (/= "" res) (nconc res " ")) (nconc res (regsub re-nospace 0)) (setq pos (1 (get re-nospace 0))) (if (regexec re-space s pos) (setq pos (1 (get re-space 0))) ) ) res ) ;; converts a red char into its ascii equivalent (defun printable-version (s &aux (c (get (regsub s 0) 0))) (String (list (if (and (>= c 225) (<= c 250)) (- c 128) (and (>= c 193) (<= c 218)) (- c 128) (and (>= c 176) (<= c 185)) (- c 128) c )))) (main) ;;; EMACS MODES ;;; Local Variables: *** ;;; mode:lisp *** ;;; End: ***