bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#20704: info.el bug fix; Interprets Info format wrongly


From: Stefan Monnier
Subject: bug#20704: info.el bug fix; Interprets Info format wrongly
Date: Wed, 10 Jun 2015 13:50:29 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

> Using byte-to-position would make things worse for Latin-1 and the likes.

There's also the problem of EOL encoding, but I'll just ignore it for now.
Could someone test the patch below?


        Stefan


diff --git a/lisp/info.el b/lisp/info.el
index 9602337..0de7f1e 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -1020,7 +1020,7 @@ which the match was found."
       (beginning-of-line)
       (when (re-search-forward regexp nil t)
        (list (string-equal "Ref:" (match-string 1))
-             (+ (point-min) (read (current-buffer)))
+              (filepos-to-bufferpos (read (current-buffer)) 'approximate)
              major-mode)))))
 
 (defun Info-find-in-tag-table (marker regexp &optional strict-case)
@@ -1187,7 +1187,8 @@ is non-nil)."
 
                  (when found
                    ;; FOUND is (ANCHOR POS MODE).
-                   (setq guesspos (nth 1 found))
+                   (setq guesspos (filepos-to-bufferpos (nth 1 found)
+                                                         'approximate))
 
                    ;; If this is an indirect file, determine which
                    ;; file really holds this node and read it in.
@@ -1203,8 +1204,7 @@ is non-nil)."
                      (throw 'foo t)))))
 
              ;; Else we may have a node, which we search for:
-             (goto-char (max (point-min)
-                             (- (byte-to-position guesspos) 1000)))
+             (goto-char (max (point-min) (- guesspos 1000)))
 
              ;; Now search from our advised position (or from beg of
              ;; buffer) to find the actual node.  First, check
@@ -1523,7 +1523,9 @@ is non-nil)."
                        thisfilepos thisfilename)
                    (search-forward ": ")
                    (setq thisfilename  (buffer-substring beg (- (point) 2)))
-                   (setq thisfilepos (+ (point-min) (read (current-buffer))))
+                   (setq thisfilepos
+                          (filepos-to-bufferpos (read (current-buffer))
+                                                'approximate))
                    ;; read in version 19 stops at the end of number.
                    ;; Advance to the next line.
                    (forward-line 1)
@@ -1554,7 +1556,7 @@ is non-nil)."
     ;; Don't add the length of the skipped summary segment to
     ;; the value returned to `Info-find-node-2'.  (Bug#14125)
     (if (numberp nodepos)
-       (+ (- nodepos lastfilepos) (point-min)))))
+       (- nodepos lastfilepos))))
 
 (defun Info-unescape-quotes (value)
   "Unescape double quotes and backslashes in VALUE."
@@ -2013,8 +2015,9 @@ If DIRECTION is `backward', search in the reverse 
direction."
                        (re-search-backward "\\(^.*\\): [0-9]+$")
                      (re-search-forward "\\(^.*\\): [0-9]+$"))
                    (goto-char (+ (match-end 1) 2))
-                   (setq list (cons (cons (+ (point-min)
-                                             (read (current-buffer)))
+                   (setq list (cons (cons (filepos-to-bufferpos
+                                            (read (current-buffer))
+                                            'approximate)
                                           (match-string-no-properties 1))
                                     list))
                    (goto-char (if backward
diff --git a/lisp/international/mule-util.el b/lisp/international/mule-util.el
index eae787b..1f7df0b 100644
--- a/lisp/international/mule-util.el
+++ b/lisp/international/mule-util.el
@@ -313,6 +313,35 @@ per-character basis, this may not be accurate."
                                  (throw 'tag3 charset)))
                          charset-list)
                    nil)))))))))
+
+;;;###autoload
+(defun filepos-to-bufferpos (byte &optional quality coding-system)
+  "Try to return the buffer position corresponding to a particular file 
position.
+The file position is given as a BYTE count.
+The function presumes the file is encoded with CODING-SYSTEM, which defaults
+to `buffer-file-coding-system'.
+QUALITY can be:
+  `approximate', in which case we may cut some corners to avoid
+    excessive work.
+  nil, in which case we may return nil rather than an approximation."
+  ;; `exact', in which case we may end up re-(en|de)coding a large
+  ;;   part of the file.
+  (unless coding-system (setq coding-system buffer-file-coding-system))
+  (let ((eol (coding-system-eol-type coding-system))
+        (type (coding-system-type coding-system))
+        (pm (save-restriction (widen) (point-min))))
+    (pcase (cons type eol)
+      (`(utf-8 . ,(or 0 2))
+       (let ((bom-offset (coding-system-get coding-system :bom)))
+         (byte-to-position
+          (+ pm (max 0 (- byte (if bom-offset 3 0)))))))
+      ;; FIXME: What if it's a 2-byte charset?  Are there such beasts?
+      (`(charset . ,(or 0 2)) (+ pm byte))
+      (_
+       (pcase quality
+         (`approximate (+ pm (byte-to-position byte)))
+         ;; (`exact ...)
+         )))))
 
 (provide 'mule-util)
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]