branch: scratch/editorconfig commit 205be47ee0215abf6a18dfa06a7314b891f7c72a Author: Stefan Monnier <monn...@iro.umontreal.ca> Commit: Stefan Monnier <monn...@iro.umontreal.ca>
WiP: reduce allocation in parser --- editorconfig-core-handle.el | 95 +++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 56 deletions(-) diff --git a/editorconfig-core-handle.el b/editorconfig-core-handle.el index 071329c006..d369a05028 100644 --- a/editorconfig-core-handle.el +++ b/editorconfig-core-handle.el @@ -94,12 +94,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. @@ -157,10 +152,7 @@ This function is a fnmatch with a few modification for EditorConfig usage." (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 @@ -172,8 +164,6 @@ If CONF is not found return nil." (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 @@ -181,58 +171,51 @@ 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)) (cond - ((string-equal "" line) + ((looking-at "^[ \t]*\\(?:[#;].*\\)$") 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 "^\\[\\(.*\\)\\]$") + (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]*\\(.*?\\)[ \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