#!/bin/sh : ; exec klone $0 "$@" ; The above line finds the klone executable in the $PATH (setq files (getopts "gr [options] pattern files... grep pattern into files but outputs the result like cc error messages for parsing via emacs error system file can be a file or \"@container\", then container is a list of one filename per line to be included, as if `cat container` was given" ("-i" () nocase "ignore case") ("-d" () match-def "match C definition of symbol, not all occurrences") ("-f" () fgrep "fgrep, quotes pattern") )) (defun main (files) (setq pattern (get files 0 "")) (delete files 0) (if (not files) (setq files '("@FILES"))) (setq files (expand-files files)) (if nocase (setq pattern (re-nocase pattern))) (if fgrep (setq pattern (quote-string-for-regexp pattern))) (if match-def (setq pattern (definition-pattern pattern))) (dolist (file files) (grepn pattern file) ) ) (defun definition-pattern (pat) (+ "(^|^#[ \t]*define[ \t]+)" pat) ) (defun expand-files (files &aux (res (copy ())) (re-wildcard (regcomp "[][*?]")) ) (dolist (file files) (if (= #\@ (get file 0)) (with (fd (open (subseq file 1)) line ()) (while (setq line (read-line fd ())) (lappend res line) )) (regexec re-wildcard file) (with (re (regcomp (wildcard-to-regexp file))) (dolist (f (directory)) (if (and (/= #\. (get f 0)) (regexec re f)) (lappend res f) ))) (lappend res file) )) res ) (defun grepn (re file &aux (fd (open file)) line (linenum 1) ) (setq re (regcomp re)) ;precompile regexp (catch 'EOF (while t (if (regexec re (setq line (read-line fd))) (print-format "%n0:%n1:%n2\n" file linenum line) ) (incf linenum) ))) (main files) ;;; EMACS MODES ;;; Local Variables: *** ;;; mode:lisp *** ;;; End: ***