bug#81530: Problems with both replace-match and substring
Sean MacLennan <[email protected]> Sat, 1 Aug 2026 01:46:53 -0400
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <20260801014653.18ecb1e1@zonker> |
I am having problems with a function to pretty print filenames. It basically just removes the current directory, or removes the home directory if it can. It works great in testing, but does not work in place. I have tried with a fairly new (updated Thursday) 32.0.50 and the stock 29.3 from Ubuntu. And, yes, I tried -Q in both cases. I have attached a test program and a sample text file in the correct format. Put the sample file somewhere in a directory under your home directory. The program massages the file to produce something that will work for your setup. If I run it with out-of-place, it works. I have two examples in the program. But if I run it as part of the "real" code, it gives me an `Args out of range: 0,10`, which is the length of my home directory. The code shows substring, I also tried replace-match. I have no idea what I am doing wrong. I am not doing anything complex. Really just converting a coverity output file into something that works with `next-error`. You can set do-pretty to nil if you want to see that it works without the pretty-print-fname function. If you need any more information or want me to try something I can. Cheers, Sean
cov.el
(text/x-emacs-lisp, 2 KB)
;; -*- lexical-binding: nil; -*-
(defvar do-pretty t)
(defun pretty-print-fname (base fname)
(if (eq (string-match base fname) 0)
(setq fname (substring fname (match-end 0)))
(if (string-match abbreviated-home-dir fname)
(setq fname (substring fname (match-end 0)))))
fname)
(defun parse-output (dir)
(with-current-buffer (get-buffer-create "*cov*")
(setq buffer-read-only nil)
(erase-buffer)
(buffer-disable-undo)
(setq default-directory dir)
(insert-file-contents "defects.csv")
;; Now massage to look like compiler output
(let (rule type fname line)
(goto-char (point-min))
(while (re-search-forward
"^\\([^,]+\\),\\([^,]+\\),\\([^,]+\\),\\([^,]+\\),\\(.+\\)$"
nil t)
(setq rule (match-string 1)
type (match-string 2)
fname (match-string 3)
line (match-string 4))
(when do-pretty
(setq fname (pretty-print-fname dir fname)))
(replace-match (concat fname ":" line ": error: " type " " rule))))))
;; For debugging
(defun do-parse-output (dir)
(interactive "DDir: ")
;; Normalize dir
(setq dir (expand-file-name
(file-name-as-directory dir)))
;; This is so it will match your home directory
(let ((home (getenv "HOME")))
;; Prove it works standalone
(message "Remove base %s"
(pretty-print-fname
"/home/nobody/work/boards/utils/"
"/home/nobody/work/boards/utils/ipaddr/ipaddr.c"))
(message "Use home %s"
(pretty-print-fname
(concat home "/work/boards/utils/")
(concat home "/work/boards/important/ipaddr/ipaddr.c")))
(with-temp-buffer
(setq default-directory dir)
(insert-file-contents "defects.csv.orig")
;; Make the first half home
(dotimes (i 4)
(search-forward "/home/nobody")
(replace-match home))
;; Make the rest base
(while (search-forward "/home/nobody/work/boards/" nil t)
(replace-match dir))
(write-file "defects.csv")))
;; Now try it in place
(parse-output dir)
(message "Done"))
defects.csv.orig
(application/octet-stream, 928 B) - not displayed