From: Vincent Belaïche Date: Mon, 27 Jun 2011 06:11:36 +0000 (+0200) Subject: (ses-repair-cell-reference-all): New function. X-Git-Tag: emacs-pretest-24.0.90~104^2~152^2~371 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=5e5d49b6d4b736e96be98d8e392c846bbc803142;p=emacs.git (ses-repair-cell-reference-all): New function. (ses-cell-symbol): Set macro as safe, so that it can be used in formulas. --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c0833592e7e..f7b1a336c88 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2011-06-27 Vincent Belaïche + + * ses.el (ses-repair-cell-reference-all): New function. + (ses-cell-symbol): Set macro as safe, so that it can be used in + formulas. + 2011-06-27 Vincent Belaïche * ses.el: Update cycle detection algorithm. diff --git a/lisp/ses.el b/lisp/ses.el index b54a7519093..2e6c24ab5e8 100644 --- a/lisp/ses.el +++ b/lisp/ses.el @@ -348,6 +348,7 @@ when to emit a progress message.") (defmacro ses-cell-symbol (row &optional col) "From a CELL or a pair (ROW,COL), get the symbol that names the local-variable holding its value. (0,0) => A1." `(aref ,(if col `(ses-get-cell ,row ,col) row) 0)) +(put 'ses-cell-symbol 'safe-function t) (defmacro ses-cell-formula (row &optional col) "From a CELL or a pair (ROW,COL), get the function that computes its value." @@ -755,6 +756,75 @@ means Emacs will crash if FORMULA contains a circular list." (ses-formula-record formula) (ses-set-cell row col 'formula formula)))) + +(defun ses-repair-cell-reference-all () + "Repair cell reference and warn if there was some reference corruption." + (interactive "*") + (let (errors) + ;; Step 1, reset :ses-repair-reference cell property in the whole sheet. + (dotimes (row ses--numrows) + (dotimes (col ses--numcols) + (let ((references (ses-cell-property-pop :ses-repair-reference + row col))) + (when references + (push (list + (ses-cell-symbol row col) + :corrupt-property + references) errors))))) + + ;; Step 2, build new. + (dotimes (row ses--numrows) + (dotimes (col ses--numcols) + (let* ((cell (ses-get-cell row col)) + (sym (ses-cell-symbol cell)) + (formula (ses-cell-formula cell)) + (new-ref (ses-formula-references formula))) + (dolist (ref new-ref) + (let* ((rowcol (ses-sym-rowcol ref)) + (h (ses-cell-property-get-handle :ses-repair-reference + (car rowcol) (cdr rowcol)))) + (unless (memq ref (ses-cell-property-handle-car h)) + (ses-cell-property-handle-setcar + h + (cons sym + (ses-cell-property-handle-car h))))))))) + + ;; Step 3, overwrite with check. + (dotimes (row ses--numrows) + (dotimes (col ses--numcols) + (let* ((cell (ses-get-cell row col)) + (irrelevant (ses-cell-references cell)) + (new-ref (ses-cell-property-pop :ses-repair-reference cell)) + missing) + (dolist (ref new-ref) + (if (memq ref irrelevant) + (setq irrelevant (delq ref irrelevant)) + (push ref missing))) + (ses-set-cell row col 'references new-ref) + (when (or missing irrelevant) + (push `( ,(ses-cell-symbol cell) + ,@(and missing (list :missing missing)) + ,@(and irrelevant (list :irrelevant irrelevant))) + errors))))) + (if errors + (warn "---------------------------------------------------------------- +Some reference where corrupted. + +The following is a list of where each element ELT is such +that (car ELT) is the reference of cell CELL with corruption, +and (cdr ELT) is a property list where + +* property `:corrupt-property' means that + property `:ses-repair-reference' of cell CELL was initially non + nil, + +* property `:missing' is a list of missing references + +* property `:irrelevant' is a list of non needed references + +%S" errors) + (message "No reference corruption found")))) + (defun ses-calculate-cell (row col force) "Calculate and print the value for cell (ROW,COL) using the cell's formula function and print functions, if any. Result is nil for normal operation, or