branch: scratch/editorconfig
commit c70df617723d1bf06ad390089e6a7bc7395a9eca
Author: Stefan Monnier <monn...@iro.umontreal.ca>
Commit: Stefan Monnier <monn...@iro.umontreal.ca>

    (editorconfig-core-handle--parse-file): Streamline
    
    * editorconfig-core-handle.el: Change copyright to the FSF since all
    the contributors have signed the corresponding paperwork.
    (editorconfig-core-handle--parse-file): Directly return
    a `editorconfig-core-handle`; parse the buffer directly rather than
    matching on strings extracted from the buffer; avoid O(N²) complexity
    by constructing the lists in reverse and using `nreverse` at the end.
    (editorconfig-core-handle): Simplify accordingly.
    (editorconfig-core-handle--string-trim): Delete function, not used any more.
---
 editorconfig-core-handle.el | 130 ++++++++++++++++++--------------------------
 1 file changed, 53 insertions(+), 77 deletions(-)

diff --git a/editorconfig-core-handle.el b/editorconfig-core-handle.el
index 20f52a3b97..8ab8a5b191 100644
--- a/editorconfig-core-handle.el
+++ b/editorconfig-core-handle.el
@@ -1,27 +1,29 @@
 ;;; editorconfig-core-handle.el --- Handle Class for EditorConfig File  -*- 
lexical-binding: t -*-
 
-;; Copyright (C) 2011-2024 EditorConfig Team
+;; Copyright (C) 2011-2024  Free Software Foundation, Inc.
 
 ;; Author: EditorConfig Team <editorcon...@googlegroups.com>
+;; Package: editorconfig
 
 ;; See
-;; https://github.com/editorconfig/editorconfig-emacs/graphs/contributors
-;; or the CONTRIBUTORS file for the list of contributors.
+;; https://github.com/editorconfig/editorconfig-emacs/graphs/contributors or
+;; https://github.com/editorconfig/editorconfig-emacs/blob/master/CONTRIBUTORS
+;; for the list of contributors.
 
 ;; This file is part of EditorConfig Emacs Plugin.
 
 ;; EditorConfig Emacs Plugin is free software: you can redistribute it and/or
 ;; modify it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or (at your
-;; option) any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; EditorConfig Emacs Plugin is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-;; Public License for more details.
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+;; See the GNU General Public License for more details.
 
-;; You should have received a copy of the GNU General Public License along with
-;; EditorConfig Emacs Plugin. If not, see <https://www.gnu.org/licenses/>.
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
@@ -75,8 +77,7 @@ Slots:
   Last modified time of .editorconfig file.
 
 `path'
-  Absolute path to .editorconfig file.'
-"
+  Absolute path to .editorconfig file."
   (top-props nil)
   (sections nil)
   (mtime nil)
@@ -94,12 +95,7 @@ If CONF does not exist return nil."
                (equal (editorconfig-core-handle-mtime cached) mtime))
           cached
         (let ((parsed (editorconfig-core-handle--parse-file conf)))
-          (puthash conf
-                   (make-editorconfig-core-handle :top-props (plist-get parsed 
:top-props)
-                                                  :sections (plist-get parsed 
:sections)
-                                                  :mtime mtime
-                                                  :path conf)
-                   editorconfig-core-handle--cache-hash))))))
+          (puthash conf parsed editorconfig-core-handle--cache-hash))))))
 
 (defun editorconfig-core-handle-root-p (handle)
   "Return non-nil if HANDLE represent root EditorConfig file.
@@ -153,21 +149,10 @@ This function is a fnmatch with a few modification for 
EditorConfig usage."
     (or (editorconfig-fnmatch-p name pattern)
         (editorconfig-fnmatch-p name (concat "**/" pattern)))))
 
-(defsubst editorconfig-core-handle--string-trim (str)
-  "Remove leading and trailing whitespaces from STR."
-  (replace-regexp-in-string "[[:space:]]+\\'"
-                            ""
-                            (replace-regexp-in-string "\\`[[:space:]]+"
-                                                      ""
-                                                      str)))
-
 (defun editorconfig-core-handle--parse-file (conf)
   "Parse EditorConfig file CONF.
 
-This function returns cons of its top properties alist and
-alist of patterns and its properties alist.
-The list returned will be ordered by the lines they appear.
-
+This function returns a `editorconfig-core-handle'.
 If CONF is not found return nil."
   (when (file-readable-p conf)
     (with-temp-buffer
@@ -175,12 +160,9 @@ If CONF is not found return nil."
       ;; code conversion
       (insert-file-contents conf)
       (goto-char (point-min))
-      (let ((point-max (point-max))
-            (sections ())
+      (let ((sections ())
             (top-props nil)
 
-            ;; String of current line
-            (line "")
             ;; nil when pattern not appeared yet, "" when pattern is empty 
("[]")
             (pattern nil)
             ;; Alist of properties for current PATTERN
@@ -188,58 +170,52 @@ If CONF is not found return nil."
 
             ;; Current line num
             (current-line-number 1))
-        (while (not (eq (point) point-max))
-          (setq line
-                (buffer-substring-no-properties (line-beginning-position)
-                                                (line-end-position)))
-          (setq line
-                (replace-regexp-in-string "\\(^\\| \\)\\(#\\|;\\).*$"
-                                          ""
-                                          
(editorconfig-core-handle--string-trim line)))
-
+        (while (not (eobp))
+          (skip-chars-forward " \t\f")
           (cond
-           ((string-equal "" line)
+           ((looking-at "\\(?:[#;].*\\)?$")
             nil)
 
            ;; Start of section
-           ((string-match "^\\[\\(.*\\)\\]$"
-                          line)
-            (when pattern
-              (setq sections
-                    `(,@sections ,(make-editorconfig-core-handle-section
-                                   :name pattern
-                                   :props props)))
-              (setq pattern nil)
-              (setq props nil))
-            (setq pattern (match-string 1 line)))
-
-           (t
-            (let ((idx (string-match "=\\|:" line)))
-              (unless idx
-                (error "Error while reading config file: %s:%d:\n    %s\n"
-                       conf current-line-number line))
-              (let ((key (downcase (editorconfig-core-handle--string-trim
-                                    (substring line 0 idx))))
-                    (value (editorconfig-core-handle--string-trim
-                            (substring line (1+ idx)))))
-                (when (and (< (length key) 51)
-                           (< (length value) 256))
-                  (if pattern
-                      (when (< (length pattern) 4097)
-                        (setq props
-                              `(,@props (,key . ,value))))
-                    (setq top-props
-                          `(,@top-props (,key . ,value)))))))))
+           ((looking-at "\\[\\(.*\\)\\][ \t]*$")
+            (let ((newpattern (match-string 1)))
+              (when pattern
+                (push (make-editorconfig-core-handle-section
+                       :name pattern
+                       :props (nreverse props))
+                      sections))
+              (setq props nil)
+              (setq pattern newpattern)))
+
+           ((looking-at "\\([^=: \t]+\\)[ \t]*[=:][ \t]*\\(.*?\\)[ \t]*$")
+            (let ((key (downcase (match-string 1)))
+                  (value (match-string 2)))
+              (when (and (< (length key) 51)
+                         (< (length value) 256))
+                (if pattern
+                    (when (< (length pattern) 4097) ;;FIXME: 4097?
+                      (push `(,key . ,value)
+                            props))
+                  (push `(,key . ,value)
+                        top-props)))))
+
+           (t (error "Error while reading config file: %s:%d:\n    %s\n"
+                     conf current-line-number
+                     (buffer-substring-no-properties (line-beginning-position)
+                                                     (line-end-position)))))
           (setq current-line-number (1+ current-line-number))
           (goto-char (point-min))
           (forward-line (1- current-line-number)))
         (when pattern
-          (setq sections
-                `(,@sections ,(make-editorconfig-core-handle-section
-                               :name pattern
-                               :props props))))
-        (list :top-props top-props
-              :sections sections)))))
+          (push (make-editorconfig-core-handle-section
+                 :name pattern
+                 :props (nreverse props))
+                sections))
+        (make-editorconfig-core-handle
+         :top-props (nreverse top-props)
+         :sections (nreverse sections)
+         :mtime (nth 5 (file-attributes conf))
+         :path conf)))))
 
 (provide 'editorconfig-core-handle)
 ;;; editorconfig-core-handle.el ends here

Reply via email to