#!/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: ***

