A Lisp implemented in AWK
;; SPDX-License-Identifier: BSD-2-Clause

(setq *indent* 0)
(setq *log-tags* '( :info :warning :error :probe :rule :change))

(macro with-indent
       (lambda (args)
         `(let ((oldindent *indent*))
            (setq *indent* (+ *indent* 2))
            (prog1
                (progn ,@args)
              (setq *indent* oldindent)))))

(defun indented-printf args
  (let ((fmt (car args))
        (args (cdr args)))
    (apply printf (sprintf "%%-%ds%s" *indent* fmt) "" args)))

(defun err-ind-printf args
  (with-output-to ">>" "/dev/stderr"
                  (apply indented-printf args)
                  (printf "\n")
                  (fflush)))

(defun log-debug args
  (when (memq :debug *log-tags*)
    (apply err-ind-printf
           (cons (strcat "%s " (car args))
                 (cons "DEBUG " (cdr args))))))

(defun log-info args
  (when (memq :info *log-tags*)
    (apply err-ind-printf
           (cons (strcat "%s " (car args))
                 (cons "INFO  " (cdr args))))))

(defun log-warning args
  (when (memq :warning *log-tags*)
    (apply err-ind-printf
           (cons (strcat "%s " (car args))
                 (cons "WARN  " (cdr args))))))

(defun log-error args
  (when (memq :error *log-tags*)
    (apply err-ind-printf
           (cons (strcat "%s " (car args))
                 (cons "ERROR " (cdr args))))))

(defun log-bucket (file-path meta new-path)
  (err-ind-printf "%s -> %s (meta: %s)\n" file-path new-path meta))

(defun log-probe args
  (when (memq :probe *log-tags*)
    (apply err-ind-printf
           (cons (strcat "%s " (car args))
                 (cons "probe " (cdr args))))))
         
(defun log-rule-start args
  (when (memq :rule *log-tags*)
    (apply err-ind-printf
           (cons (strcat "%s\n%s " (car args))
                 (cons "-----" (cons "rule  " (cdr args)))))))

(defun log-rule-end ()
  (when (memq :rule *log-tags*)
    (err-ind-printf ".....\n")))

(macro with-log-rule
  (lambda (args)
    `(progn
       (log-rule-start ,@(car args))
       (with-indent
        (progn
          ,@(cdr args)))
       (log-rule-end))))

(defun log-change args
  (when (memq :change *log-tags*)
    (apply err-ind-printf
           (cons (strcat "%s " (car args))
                 (cons "CHANGE " (cdr args))))))

;; see the set-x macro
(defun log-command (cmd)
  (err-ind-printf "+ %s" cmd))