From mboxrd@z Thu Jan 1 00:00:00 1970 From: Aaron Ecay Subject: [RFC] [PATCH] org-table: introduce an upper bound on the number of lines `org-table-convert-region-max-lines' will attempt. Date: Sat, 23 Aug 2014 03:44:13 -0400 Message-ID: <1408779853-15052-1-git-send-email-aaronecay@gmail.com> Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:41839) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XL601-00080r-EC for emacs-orgmode@gnu.org; Sat, 23 Aug 2014 03:44:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XL5zs-0007rn-C3 for emacs-orgmode@gnu.org; Sat, 23 Aug 2014 03:44:33 -0400 Received: from mail-qa0-x22a.google.com ([2607:f8b0:400d:c00::22a]:58482) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XL5zs-0007rj-5P for emacs-orgmode@gnu.org; Sat, 23 Aug 2014 03:44:24 -0400 Received: by mail-qa0-f42.google.com with SMTP id j15so10502167qaq.15 for ; Sat, 23 Aug 2014 00:44:23 -0700 (PDT) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org * lisp/org-table.el (org-table-convert-region-max-lines): New defcustom. (org-table-convert-region): Use it. This is useful primarily for babel results. If a large table-like object is returned by a code block, this function will become bogged down in trying to read it, and hang emacs (necessitating a C-g). This situation most commonly arises when a :results none header has been ommitted. With the patch, the user will not experience a hang, but rather an error message. --- lisp/org-table.el | 95 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 41 deletions(-) diff --git a/lisp/org-table.el b/lisp/org-table.el index 06a1008..bf88d11 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -366,6 +366,16 @@ available parameters." :group 'org-table-import-export :type 'string) +(defcustom org-table-convert-region-max-lines 999 + "Max lines that `org-table-convert-region' will attempt to process. + +The function can be slow on larger regions; this safety feature +prevents it from hanging emacs." + :group 'org-table-import-export + :type 'integer + :version "24.5" + :package-version '(Org . "8.4")) + (defconst org-table-auto-recalculate-regexp "^[ \t]*| *# *\\(|\\|$\\)" "Detects a table line marked for automatic recalculation.") (defconst org-table-recalculate-regexp "^[ \t]*| *[#*] *\\(|\\|$\\)" @@ -566,49 +576,52 @@ nil When nil, the command tries to be smart and figure out the (let* ((beg (min beg0 end0)) (end (max beg0 end0)) re) - (if (equal separator '(64)) - (setq separator (read-regexp "Regexp for field separator"))) - (goto-char beg) - (beginning-of-line 1) - (setq beg (point-marker)) - (goto-char end) - (if (bolp) (backward-char 1) (end-of-line 1)) - (setq end (point-marker)) - ;; Get the right field separator - (unless separator + (if (> (count-lines beg end) org-table-convert-region-max-lines) + (user-error "Region is longer than `org-table-convert-region-max-lines' (%s) lines; not converting" + org-table-convert-region-max-lines) + (if (equal separator '(64)) + (setq separator (read-regexp "Regexp for field separator"))) (goto-char beg) - (setq separator + (beginning-of-line 1) + (setq beg (point-marker)) + (goto-char end) + (if (bolp) (backward-char 1) (end-of-line 1)) + (setq end (point-marker)) + ;; Get the right field separator + (unless separator + (goto-char beg) + (setq separator + (cond + ((not (re-search-forward "^[^\n\t]+$" end t)) '(16)) + ((not (re-search-forward "^[^\n,]+$" end t)) '(4)) + (t 1)))) + (goto-char beg) + (if (equal separator '(4)) + (while (< (point) end) + ;; parse the csv stuff (cond - ((not (re-search-forward "^[^\n\t]+$" end t)) '(16)) - ((not (re-search-forward "^[^\n,]+$" end t)) '(4)) - (t 1)))) - (goto-char beg) - (if (equal separator '(4)) - (while (< (point) end) - ;; parse the csv stuff - (cond - ((looking-at "^") (insert "| ")) - ((looking-at "[ \t]*$") (replace-match " |") (beginning-of-line 2)) - ((looking-at "[ \t]*\"\\([^\"\n]*\\)\"") - (replace-match "\\1") - (if (looking-at "\"") (insert "\""))) - ((looking-at "[^,\n]+") (goto-char (match-end 0))) - ((looking-at "[ \t]*,") (replace-match " | ")) - (t (beginning-of-line 2)))) - (setq re (cond - ((equal separator '(4)) "^\\|\"?[ \t]*,[ \t]*\"?") - ((equal separator '(16)) "^\\|\t") - ((integerp separator) - (if (< separator 1) - (user-error "Number of spaces in separator must be >= 1") - (format "^ *\\| *\t *\\| \\{%d,\\}" separator))) - ((stringp separator) - (format "^ *\\|%s" separator)) - (t (error "This should not happen")))) - (while (re-search-forward re end t) - (replace-match "| " t t))) - (goto-char beg) - (org-table-align))) + ((looking-at "^") (insert "| ")) + ((looking-at "[ \t]*$") (replace-match " |") (beginning-of-line 2)) + ((looking-at "[ \t]*\"\\([^\"\n]*\\)\"") + (replace-match "\\1") + (if (looking-at "\"") (insert "\""))) + ((looking-at "[^,\n]+") (goto-char (match-end 0))) + ((looking-at "[ \t]*,") (replace-match " | ")) + (t (beginning-of-line 2)))) + (setq re (cond + ((equal separator '(4)) "^\\|\"?[ \t]*,[ \t]*\"?") + ((equal separator '(16)) "^\\|\t") + ((integerp separator) + (if (< separator 1) + (user-error "Number of spaces in separator must be >= 1") + (format "^ *\\| *\t *\\| \\{%d,\\}" separator))) + ((stringp separator) + (format "^ *\\|%s" separator)) + (t (error "This should not happen")))) + (while (re-search-forward re end t) + (replace-match "| " t t))) + (goto-char beg) + (org-table-align)))) ;;;###autoload (defun org-table-import (file arg) -- 2.0.4