all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Vivek Dasmohapatra <vivek@etla.org>
Subject: patch: make hexl mode support 8, 32 and 64 bit groups (fwd)
Date: Fri, 13 Oct 2006 12:03:14 +0100 (BST)	[thread overview]
Message-ID: <Pine.LNX.4.62.0610131200480.24379@pike.pepperfish.net> (raw)

[-- Attachment #1: Type: TEXT/PLAIN, Size: 881 bytes --]

Hi - this kind of sank without a trace last time I posted it, and it's
been a couple of months, so I thought I'd post it again to see if there
was any interest this time around. Apologies if this is considered bad 
manners.

---------- Forwarded message ----------
Date: Fri, 11 Aug 2006 16:31:49 +0100 (BST)
From: Vivek Dasmohapatra <vivek@etla.org>
To: emacs-devel@gnu.org
Subject: patch: make hexl mode support 8, 32 and 64 bit groups

The hexl binary supports 8, 16, 32 and 64 bit groups, but hexl mode
currently only supports 16 bit groups.

This patch adds support (controlled by a custom item, `hexl-bits')
for the other group sizes.

Oh, and there was a minor bug in hexl-scroll-up (and -down) which meant it
scrolled by one line too many (didn't take account of the ruler line) by
default, so you'd miss one line of data if you weren't careful.

Change log entry included.

[-- Attachment #2: Type: TEXT/PLAIN, Size: 11946 bytes --]

diff -u -r1.9921 ChangeLog
--- ChangeLog	11 Aug 2006 14:11:10 -0000	1.9921
+++ ChangeLog	11 Aug 2006 15:19:44 -0000
@@ -1,3 +1,33 @@
+2006-08-11  Vivek Dasmohapatra  <vivek@etla.org>
+
+	* hexl.el: lift the "16 bit grouping only" restriction: mostly this 
+	involves tracking down all the code that ssumes a hardwired bit
+	grouping of 16 in various layout/offset calculations.
+	(hexl-bits): new custom option to control the bit grouping in the 
+	hexlified buffer.
+	(hexl-options): doc update mentioning `hexl-bits'.
+	(hexl-rulerise): function to create basic rulers for each bit grouping.
+	(hexl-rulers): variable to hold bit grouping -> ruler map.
+	(hexl-line-displen): work out the display length bases on `hexl-bits'.
+	(hexl-mode): doc update mentioning `hexl-bits'.
+	(hexl-mode): max-address calculated using `hexl-line-displen'.
+	(hexl-current-address): current-column from `hexl-line-displen'.
+	(hexl-current-address): hexl-address from `hexl-ascii-start-column'.
+	(hexl-ascii-start-column): derive ascii start column from `hexl-bits'.
+	(hexl-address-to-marker): incorporate `hexl-bits' into calculation.
+	(hexl-beginning-of-line): derive from `hexl-line-displen'.
+	(hexl-scroll-down): ruler means window-height -2 should be used, not -1
+	(hexl-scroll-up): ditto
+	(hexl-options): use `hexl-bits' to get the correct command line options
+	(hexlify-buffer): use `hexl-options' function mentioned above.
+	(dehexlify-buffer): ditto.
+	(hexl-insert-char): use `hexl-line-displen' and 
+	`hexl-ascii-start-column' in position calculations.
+	(hexl-follow-ascii-find): use `hexl-ascii-start-column' in calculations.
+	(hexl-mode-ruler): use new rulers from `hexl-rulers'.
+	(hexl-mode-ruler): use `hexl-bits' and `hexl-ascii-start-column' in 
+	offset calculations.
+
 2006-08-10  Chong Yidong  <cyd@stupidchicken.com>
 
 	* emacs-lisp/edebug.el (edebug-recursive-edit): Don't save and
diff -u -r1.105 hexl.el
--- hexl.el	8 Jul 2006 15:52:23 -0000	1.105
+++ hexl.el	11 Aug 2006 15:19:46 -0000
@@ -53,6 +53,13 @@
   "Edit a file in a hex dump format using the hexl filter."
   :group 'data)
 
+(defcustom hexl-bits 16
+  "The bit grouping that hexl will use."
+  :type '(choice (const 8 )
+                 (const 16)
+                 (const 32)
+                 (const 64))
+  :group 'hexl)
 
 (defcustom hexl-program "hexl"
   "The program that will hexlify and dehexlify its stdin.
@@ -69,7 +76,9 @@
 
 (defcustom hexl-options (format "-hex %s" hexl-iso)
   "Space separated options to `hexl-program' that suit your needs.
-Quoting cannot be used, so the arguments cannot themselves contain spaces."
+Quoting cannot be used, so the arguments cannot themselves contain spaces.
+If you wish to set the `-group-by-X-bits' options, set `hexl-bits' instead,
+as that will override any bit grouping options set here."
   :type 'string
   :group 'hexl)
 
@@ -125,10 +134,35 @@
      (2 'hexl-ascii-region t t)))
   "Font lock keywords used in `hexl-mode'.")
 
+(defun hexl-rulerise (string bits) 
+  (let ((size (/ bits 4)) (strlen (length string)) (pos 0) (ruler ""))
+    (while (< pos strlen)
+      (setq ruler (concat ruler " " (substring string pos (+ pos size))))
+      (setq pos (+ pos size)))
+    (substring ruler 1) ))
+
+(defvar hexl-rulers 
+  (mapcar 
+   (lambda (bits) 
+     (cons bits
+           (concat " 87654321  " 
+                   (hexl-rulerise "00112233445566778899aabbccddeeff" bits) 
+                   "  0123456789abcdef")))
+   '(8 16 32 64)))
 ;; routines
 
 (put 'hexl-mode 'mode-class 'special)
 
+;; 10 chars for the "address: "
+;; 32 chars for the hexlified bytes
+;; 1 char for the space 
+;; 16 chars for the character display
+;; X chars for the spaces (128 bits divided by the hexl-bits)
+;; 1 char for the newline.
+(defun hexl-line-displen ()
+  "The length of a hexl display line (varies with `hexl-bits')."
+  (+ 60 (/ 128 (or hexl-bits 16))))
+
 ;;;###autoload
 (defun hexl-mode (&optional arg)
   "\\<hexl-mode-map>A mode for editing binary files in hex dump format.
@@ -142,7 +176,7 @@
 Each line in the buffer has an \"address\" (displayed in hexadecimal)
 representing the offset into the file that the characters on this line
 are at and 16 characters from the file (displayed as hexadecimal
-values grouped every 16 bits) and as their ASCII values.
+values grouped every `hexl-bits' bits) and as their ASCII values.
 
 If any of the characters (displayed as ASCII characters) are
 unprintable (control or meta characters) they will be replaced as
@@ -213,7 +247,8 @@
 	   (setq original-point (1- original-point)))
       (if (not (or (eq arg 1) (not arg)))
 	  ;; if no argument then we guess at hexl-max-address
-          (setq max-address (+ (* (/ (1- (buffer-size)) 68) 16) 15))
+          (setq max-address 
+                (+ (* (/ (1- (buffer-size)) (hexl-line-displen)) 16) 15))
         (setq max-address (1- (buffer-size)))
 	;; If the buffer's EOL type is -dos, we need to account for
 	;; extra CR characters added when hexlify-buffer writes the
@@ -416,17 +451,20 @@
 (defun hexl-current-address (&optional validate)
   "Return current hexl-address."
   (interactive)
-  (let ((current-column (- (% (- (point) (point-min) -1) 68) 11))
+  (let ((current-column 
+         (- (% (- (point) (point-min) -1) (hexl-line-displen)) 11))
 	(hexl-address 0))
     (if (< current-column 0)
 	(if validate
 	    (error "Point is not on a character in the file")
 	  (setq current-column 0)))
     (setq hexl-address
-	  (+ (* (/ (- (point) (point-min) -1) 68) 16)
-	     (if (>= current-column 41)
-		 (- current-column 41)
-	       (/ (- current-column  (/ current-column 5)) 2))))
+	  (+ (* (/ (- (point) (point-min) -1) 
+                   (hexl-line-displen)) 16)
+	     (if (>= current-column (- (hexl-ascii-start-column) 10))
+		 (- current-column (- (hexl-ascii-start-column) 10))
+               (/ (- current-column 
+                     (/ current-column (1+ (/ hexl-bits 4)))) 2) )) )
     (when (interactive-p)
       (message "Current address is %d/0x%08x" hexl-address hexl-address))
     hexl-address))
@@ -437,10 +475,18 @@
   (let ((addr (hexl-current-address)))
     (format "Current address is %d/0x%08x" addr addr)))
 
+(defun hexl-ascii-start-column () 
+  "Column at which the ascii portion of the hexl display starts."
+  (+ 43 (/ 128 hexl-bits)))
+
 (defun hexl-address-to-marker (address)
   "Return buffer position for ADDRESS."
   (interactive "nAddress: ")
-  (+ (* (/ address 16) 68) 10 (point-min) (/ (* (% address 16) 5) 2)))
+  (let ((N (* (% address 16) 2)))
+    (+ (* (/ address 16) (hexl-line-displen)) ; hexl line no * display length
+       10                      ; 10 chars for the "address: " prefix
+       (point-min)             ; base offset (point usually starts at 1, not 0)
+       (+ N (/ N (/ hexl-bits 4))) )) ) ; char offset into hexl display line
 
 (defun hexl-goto-address (address)
   "Goto hexl-mode (decimal) address ADDRESS.
@@ -610,7 +656,7 @@
 (defun hexl-beginning-of-line ()
   "Goto beginning of line in hexl mode."
   (interactive)
-  (goto-char (+ (* (/ (point) 68) 68) 11)))
+  (goto-char (+ (* (/ (point) (hexl-line-displen)) (hexl-line-displen)) 11)))
 
 (defun hexl-end-of-line ()
   "Goto end of line in hexl mode."
@@ -624,7 +670,7 @@
   "Scroll hexl buffer window upward ARG lines; or near full window if no ARG."
   (interactive "P")
   (if (null arg)
-      (setq arg (1- (window-height)))
+      (setq arg (- (window-height) 2))
     (setq arg (prefix-numeric-value arg)))
   (hexl-scroll-up (- arg)))
 
@@ -633,7 +679,7 @@
 If there's no byte at the target address, move to the first or last line."
   (interactive "P")
   (if (null arg)
-      (setq arg (1- (window-height)))
+      (setq arg (- (window-height) 2))
     (setq arg (prefix-numeric-value arg)))
   (let* ((movement (* arg 16))
 	 (address (hexl-current-address))
@@ -690,6 +736,18 @@
 
 ;00000000: 0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789ABCDEF
 
+(defun hexl-options (&optional test)
+  "Combine `hexl-bits' with `hexl-options', altering `hexl-options' as needed
+to produce the command line options to pass to the hexl command."
+  (let ((opts (or test hexl-options)))
+    (when (memq hexl-bits '(8 16 32 64))
+      (when (string-match "\\(.*\\)-group-by-[0-9]+-bits\\(.*\\)" opts)
+        (setq opts (concat (match-string 1 opts) 
+                           (match-string 2 opts))) ) 
+      (setq opts (format "%s -group-by-%d-bits " opts hexl-bits)) )
+    opts))
+
+
 ;;;###autoload
 (defun hexlify-buffer ()
   "Convert a binary buffer to hexl format.
@@ -710,7 +768,7 @@
            ;; coding-system-for-write (i.e. buffer-file-coding-system) which
            ;; may not be what we want (e.g. utf-16 on a non-utf-16 system).
            (mapcar (lambda (s) (encode-coding-string s locale-coding-system))
-                   (split-string hexl-options)))
+                   (split-string (hexl-options))))
     (if (> (point) (hexl-address-to-marker hexl-max-address))
 	(hexl-goto-address hexl-max-address))))
 
@@ -727,7 +785,7 @@
 	(buffer-undo-list t))
     (apply 'call-process-region (point-min) (point-max)
 	   (expand-file-name hexl-program exec-directory)
-	   t t nil "-de" (split-string hexl-options))))
+	   t t nil "-de" (split-string (hexl-options)))))
 
 (defun hexl-char-after-point ()
   "Return char for ASCII hex digits at point."
@@ -824,12 +882,15 @@
   (let ((address (hexl-current-address t)))
     (while (> num 0)
       (let ((hex-position
-	     (+ (* (/ address 16) 68)
+	     (+ (* (/ address 16) (hexl-line-displen))
 		10 (point-min)
 		(* 2 (% address 16))
 		(/ (% address 16) 2)))
 	    (ascii-position
-	     (+ (* (/ address 16) 68) 51 (point-min) (% address 16)))
+	     (+ (* (/ address 16) (hexl-line-displen)) 
+                (hexl-ascii-start-column) 
+                (point-min) 
+                (% address 16)))
 	    at-ascii-position)
 	(if (= (point) ascii-position)
 	    (setq at-ascii-position t))
@@ -845,7 +906,7 @@
 	(if at-ascii-position
 	    (progn
 	      (beginning-of-line)
-	      (forward-char 51)
+	      (forward-char (hexl-ascii-start-column))
 	      (forward-char (% address 16)))))
       (setq num (1- num)))))
 
@@ -956,7 +1017,7 @@
 
 (defun hexl-follow-ascii-find ()
   "Find and highlight the ASCII element corresponding to current point."
-  (let ((pos (+ 51
+  (let ((pos (+ (hexl-ascii-start-column)
 		(- (point) (current-column))
 		(mod (hexl-current-address) 16))))
     (move-overlay hexl-ascii-overlay pos (1+ pos))
@@ -965,7 +1026,7 @@
 (defun hexl-mode-ruler ()
   "Return a string ruler for hexl mode."
   (let* ((highlight (mod (hexl-current-address) 16))
-	 (s " 87654321  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789abcdef")
+	 (s (cdr (assq hexl-bits hexl-rulers)))
 	 (pos 0))
     (set-text-properties 0 (length s) nil s)
     ;; Turn spaces in the header into stretch specs so they work
@@ -977,12 +1038,12 @@
 			 `(space :align-to ,(1- pos))
 			 s))
     ;; Highlight the current column.
-    (put-text-property (+ 11 (/ (* 5 highlight) 2))
-		       (+ 13 (/ (* 5 highlight) 2))
-		       'face 'highlight s)
+    (let ( (offset (+ (* 2 highlight) (/ (* 8 highlight) hexl-bits))) )
+      (put-text-property (+ 11 offset) (+ 13 offset) 'face 'highlight s))
     ;; Highlight the current ascii column
-    (put-text-property (+ 13 39 highlight) (+ 13 40 highlight)
-		       'face 'highlight s)
+    (put-text-property (+ (hexl-ascii-start-column) highlight 1) 
+                       (+ (hexl-ascii-start-column) highlight 2)
+                       'face 'highlight s)
     s))
 
 ;; startup stuff.


[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

             reply	other threads:[~2006-10-13 11:03 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-10-13 11:03 Vivek Dasmohapatra [this message]
2006-10-13 11:29 ` patch: make hexl mode support 8, 32 and 64 bit groups (fwd) Masatake YAMATO
2006-10-13 12:16   ` Masatake YAMATO
2006-10-16  9:45     ` Vivek Dasmohapatra
2006-10-13 14:22 ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.LNX.4.62.0610131200480.24379@pike.pepperfish.net \
    --to=vivek@etla.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.