cl-grep

Simple implementation of grep
Log | Files | Refs

commit 232cc39e8eae536edebde11ab3145ab9cd976dbe
parent 8368c15fb5036701e43639f01196af31c94b7044
Author: ChanderG <[email protected]>
Date:   Mon,  8 Dec 2025 17:59:52 +0530

add command line flags to control behaviour

Diffstat:
Mgrep.asd | 4+++-
Mgrep.lisp | 17+++++++++++------
Aoptions.lisp | 37+++++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/grep.asd b/grep.asd @@ -2,6 +2,7 @@ :version "0.0.1" :author "Chander Govindarajan" :components ((:file "package") + (:file "options") (:file "log") (:file "mmap") (:file "grep")) @@ -12,7 +13,8 @@ :lparallel :bordeaux-threads :cl-string-match - :mmap) + :mmap + :unix-opts) :build-operation "program-op" :build-pathname "cl-grep" :entry-point "cl-grep:main") diff --git a/grep.lisp b/grep.lisp @@ -1,8 +1,9 @@ (in-package :cl-grep) (declaim (optimize (speed 3) (debug 0) (safety 0))) -(declaim (inline format-file-result search-line grep-file)) +(declaim (inline format-file-result search-line)) +(defparameter +numw+ 4) (defparameter +file-lc-blacklist+ '(#\~ #\#)) (defparameter +file-ext-blacklist+ '("pwd" "png" "svg" "jpeg" "gif" "mov" "mp4" "mkv" @@ -97,10 +98,14 @@ (lq:push-queue (make-file-result :name file :entries results) *print-queue*)) (end-mfile mf))) +(defparameter grep-file-mode 'disk) + (defun grep-file (file match-idx) (lo "Grepping file: ~a" file) (handler-case - (grep-file-memory file match-idx) + (if (eq grep-file-mode 'disk) + (grep-file-disk file match-idx) + (grep-file-memory file match-idx)) (stream-error (stream) (lo "Skipping binary file: ~a" file)) (error (c) @@ -174,13 +179,12 @@ (log-setup) (setf *match* str) (setup-tasks-mgmt) - (let* ((numw 4) - (workers (loop for i from 0 below numw + (let* ((workers (loop for i from 0 below +numw+ collect (bt:make-thread #'process-task))) (print-worker (bt:make-thread #'result-printer))) (fs-walker dir) (lo "Finished processing target walking!") - (loop for i from 0 below numw + (loop for i from 0 below +numw+ do (lq:push-queue :done *queue*)) (loop for w in workers do (bt:join-thread w)) (lq:push-queue :done *print-queue*) @@ -191,7 +195,8 @@ (grep-launcher str dir))) (defun main () - (let* ((args (uiop:command-line-arguments)) + (let* ((raw-args (uiop:command-line-arguments)) + (args (process-options raw-args)) (nargs (length args))) (when (or (eq nargs 0) (> nargs 2)) (format t "Incorrect number of args passed!~%") diff --git a/options.lisp b/options.lisp @@ -0,0 +1,37 @@ +(in-package :cl-grep) + +;; Adapted from original unix-opts example: +;; https://github.com/libre-man/unix-opts/blob/master/example/example.lisp + +(opts:define-opts + (:name :num-workers + :description "Number of core grep worker threads to spawn" + :short #\j + :long "jobs" + :arg-parser #'parse-integer + :meta-var "JOBS") + (:name :mmap + :description "Whether to enable mmap based file processing" + :short #\m + :long "mmap") + (:name :chunk-size + :description "Size of chunks to load when mmaping" + :short #\c + :long "chunksize" + :arg-parser #'parse-integer + :meta-var "CHUNKSIZE")) + +(defun process-options (raw-args) + (multiple-value-bind (options free-args) + (handler-case (opts:get-opts raw-args) + (opts:unknown-option (c) + (format t "Unknown option: ~a. Aborting!" (opts:option c)) + (opts:exit 1))) + ;; deal with the options here + (if (getf options :jobs) + (setf +numw+ (getf options :jobs))) + (if (getf options :mmap) + (setf grep-file-mode 'mmap)) + (if (getf options :chunk-size) + (setf +chunk-size+ (getf options :chunk-size))) + free-args))