summaryrefslogtreecommitdiff
path: root/lisp/ses.el
diff options
context:
space:
mode:
authorVincent Belaïche <vincentb1@users.sourceforge.net>2017-06-23 11:16:37 +0200
committerVincent Belaïche <vincentb1@users.sourceforge.net>2017-06-23 11:16:37 +0200
commiteebb9783e1674732b7c63d50211b524ff0fea7bd (patch)
treebed257f0db158f3086066c6d12c35b63a0cddcc7 /lisp/ses.el
parentd533f5f2a783e4c6448f841e709f4528f498b7ea (diff)
downloademacs-eebb9783e1674732b7c63d50211b524ff0fea7bd.tar.gz
Fix symbol relocation when the relocated cell is renamed.
* lisp/ses.el (ses-sym-rowcol): Check that the renamed cell hashmap has been instantiated before getting data from it. When editing several spreadsheets, and you have spreadsheet #1 with a cell named `foo', and no renamed cell in spreadsheet #2, then if you make a formula with `foo' in spreadsheet #2, not doing this check will make an error. (ses-cell-set-formula): Robustify versus incorrect cell references given in the user provided formula. An explicit error message is provided after the action when the user gives an incorrect cell reference, but the formula edition is not changed. This means that if the incorrect reference is to a cell that is created someday, then this new cell will not have the edited cell in its reference list. Fixing this can still be done by editing again the first cell formula. (ses-relocate-symbol): Do not create symbol of referred-to cell when this is a renamed cell.
Diffstat (limited to 'lisp/ses.el')
-rw-r--r--lisp/ses.el46
1 files changed, 32 insertions, 14 deletions
diff --git a/lisp/ses.el b/lisp/ses.el
index b3686076358..97bade380ec 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -437,7 +437,7 @@ is nil if SYM is not a symbol that names a cell."
(declare (debug t))
`(let ((rc (and (symbolp ,sym) (get ,sym 'ses-cell))))
(if (eq rc :ses-named)
- (gethash ,sym ses--named-cell-hashmap)
+ (and ses--named-cell-hashmap (gethash ,sym ses--named-cell-hashmap))
rc)))
(defun ses-cell-p (cell)
@@ -868,27 +868,39 @@ means Emacs will crash if FORMULA contains a circular list."
(oldref (ses-formula-references old))
(newref (ses-formula-references formula))
(inhibit-quit t)
+ not-a-cell-ref-list
x xrow xcol)
(cl-pushnew sym ses--deferred-recalc)
;;Delete old references from this cell. Skip the ones that are also
;;in the new list.
(dolist (ref oldref)
(unless (memq ref newref)
- (setq x (ses-sym-rowcol ref)
- xrow (car x)
- xcol (cdr x))
- (ses-set-cell xrow xcol 'references
- (delq sym (ses-cell-references xrow xcol)))))
+ ;; because we do not cancel edit when the user provides a
+ ;; false reference in it, then we need to check that ref
+ ;; points to a cell that is within the spreadsheet.
+ (setq x (ses-sym-rowcol ref))
+ (and x
+ (< (setq xrow (car x)) ses--numrows)
+ (< (setq xcol (cdr x)) ses--numcols)
+ (ses-set-cell xrow xcol 'references
+ (delq sym (ses-cell-references xrow xcol))))))
;;Add new ones. Skip ones left over from old list
(dolist (ref newref)
- (setq x (ses-sym-rowcol ref)
- xrow (car x)
- xcol (cdr x)
- x (ses-cell-references xrow xcol))
- (or (memq sym x)
- (ses-set-cell xrow xcol 'references (cons sym x))))
+ (setq x (ses-sym-rowcol ref))
+ ;;Do not trust the user, the reference may be outside the spreadsheet
+ (if (and
+ x
+ (< (setq xrow (car x)) ses--numrows)
+ (< (setq xcol (cdr x)) ses--numcols))
+ (progn
+ (setq x (ses-cell-references xrow xcol))
+ (or (memq sym x)
+ (ses-set-cell xrow xcol 'references (cons sym x))))
+ (cl-pushnew ref not-a-cell-ref-list)))
(ses-formula-record formula)
- (ses-set-cell row col 'formula formula))))
+ (ses-set-cell row col 'formula formula)
+ (and not-a-cell-ref-list
+ (error "Found in formula cells not in spreadsheet: %S" not-a-cell-ref-list)))))
(defun ses-repair-cell-reference-all ()
@@ -1529,7 +1541,13 @@ by (ROWINCR,COLINCR)."
;;Relocate this variable, unless it is a named cell
(if (eq (get sym 'ses-cell) :ses-named)
sym
- (ses-create-cell-symbol row col))
+ ;; otherwise, we create the relocated cell symbol because
+ ;; ses-cell-symbol gives the old symbols, however since
+ ;; renamed cell are not relocated we keep the relocated
+ ;; cell old symbol in this case.
+ (if (eq (get (setq sym (ses-cell-symbol row col)) 'ses-cell) :ses-named)
+ sym
+ (ses-create-cell-symbol row col)))
;;Delete reference to a deleted cell
nil))))