branch: externals/sql-indent
commit 75a4e24426f15643716dbc140e6e1e6fb4630755
Author: Pierre Téchoueyres <[email protected]>
Commit: Alex Harsányi <[email protected]>
Correct detection of labels in `for` or `while` loops. (#48)
Correct detection of labels in `for` or `while` loops.
---
sql-indent-test.el | 3 +++
sql-indent.el | 24 +++++++++++++---------
test-data/pr48-syn.eld | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++
test-data/pr48.sql | 25 ++++++++++++++++++++++
4 files changed, 98 insertions(+), 10 deletions(-)
diff --git a/sql-indent-test.el b/sql-indent-test.el
index f3d2e51..69be7e2 100644
--- a/sql-indent-test.el
+++ b/sql-indent-test.el
@@ -342,4 +342,7 @@ information read from DATA-FILE (as generated by
(ert-deftest sqlind-ert-pr46 ()
(sqlind-ert-check-file-syntax "test-data/pr46.sql" "test-data/pr46-syn.eld"))
+(ert-deftest sqlind-ert-pr48 ()
+ (sqlind-ert-check-file-syntax "test-data/pr48.sql" "test-data/pr48-syn.eld"))
+
;;; sql-indent-test.el ends here
diff --git a/sql-indent.el b/sql-indent.el
index 34844ae..586166f 100644
--- a/sql-indent.el
+++ b/sql-indent.el
@@ -300,7 +300,7 @@ But don't go before LIMIT."
(catch 'done
(while (> (point) (or limit (point-min)))
(when (re-search-backward
-
";\\|:=\\|\\_<\\(declare\\|begin\\|cursor\\|for\\|loop\\|if\\|then\\|else\\|elsif\\)\\_>\\|)"
+
";\\|:=\\|\\_<\\(declare\\|begin\\|cursor\\|for\\|while\\|loop\\|if\\|then\\|else\\|elsif\\)\\_>\\|)"
limit 'noerror)
(unless (sqlind-in-comment-or-string (point))
(let ((candidate-pos (match-end 0)))
@@ -309,7 +309,7 @@ But don't go before LIMIT."
;; of the keywords inside one of them and think this is a
;; statement start.
(progn (forward-char 1) (forward-sexp -1)))
- ((looking-at "cursor\\|for")
+ ((looking-at "cursor\\|for\\|while")
;; statement begins at the start of the keyword
(throw 'done (point)))
((looking-at "then\\|else")
@@ -530,19 +530,23 @@ See also `sqlind-beginning-of-block'"
;; note that we might have found a loop in an "end loop;" statement.
(or (sqlind-maybe-end-statement)
(progn
- (let ((loop-label (if (looking-at "<<\\([a-z0-9_]+\\)>>")
- (sqlind-match-string 1) "")))
- ;; start of loop. this always starts a block, we only check if
- ;; the labels match
- (if (null sqlind-end-stmt-stack)
- (throw 'finished (list 'in-block 'loop loop-label))
+ (let ((posn (point)))
+ (forward-word -1)
+ (sqlind-beginning-of-statement)
+ (let ((loop-label (if (looking-at "<<\\([a-z0-9_]+\\)>>")
+ (sqlind-match-string 1) "")))
+ (goto-char posn)
+ ;; start of loop. this always starts a block, we only check if
+ ;; the labels match
+ (if (null sqlind-end-stmt-stack)
+ (throw 'finished (list 'in-block 'loop loop-label))
(cl-destructuring-bind (pos kind label)
(pop sqlind-end-stmt-stack)
(unless (and (eq kind 'loop)
(sqlind-labels-match label loop-label))
(throw 'finished
- (list 'syntax-error
- "bad closing for loop block" (point)
pos)))))))))))
+ (list 'syntax-error
+ "bad closing for loop block" (point)
pos))))))))))))
(defun sqlind-maybe-begin-statement ()
"Return the syntax of a \"begin\" statement.
diff --git a/test-data/pr48-syn.eld b/test-data/pr48-syn.eld
new file mode 100644
index 0000000..8357c18
--- /dev/null
+++ b/test-data/pr48-syn.eld
@@ -0,0 +1,56 @@
+((((block-start begin)
+ . 1)
+ (toplevel . 1))
+ (((in-begin-block toplevel-block "")
+ . 1))
+ (((in-begin-block toplevel-block "")
+ . 1))
+ (((in-begin-block toplevel-block "")
+ . 1))
+ ((labeled-statement-start . 87)
+ (statement-continuation . 87))
+ (((in-block loop "my_loop")
+ . 101))
+ (((block-end loop "my_loop")
+ . 101)
+ ((in-block loop "my_loop")
+ . 101))
+ (((in-begin-block toplevel-block "")
+ . 1))
+ (((in-begin-block toplevel-block "")
+ . 1))
+ (((in-begin-block toplevel-block "")
+ . 1))
+ ((labeled-statement-start . 229)
+ (statement-continuation . 229))
+ (((in-block loop "my_second_loop")
+ . 250))
+ (((in-block loop "my_second_loop")
+ . 250))
+ (((block-end loop "my_second_loop")
+ . 250)
+ ((in-block loop "my_second_loop")
+ . 250))
+ (((in-begin-block toplevel-block "")
+ . 1))
+ (((block-end toplevel-block "")
+ . 1)
+ ((in-begin-block toplevel-block "")
+ . 1))
+ ((toplevel . 1))
+ ((toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((comment-start . 1)
+ (toplevel . 1))
+ ((toplevel . 1)))
diff --git a/test-data/pr48.sql b/test-data/pr48.sql
new file mode 100644
index 0000000..527ee54
--- /dev/null
+++ b/test-data/pr48.sql
@@ -0,0 +1,25 @@
+begin
+ goto my_loop;
+ dbms_output.put_line('If you read it, you''re in trouble');
+ <<my_loop>>
+ for ind in 1..5 loop
+ dbms_output.put_line('ind: ' || ind);
+ end loop my_loop;
+
+ dbms_output.put_line('end of my_loop');
+ <<my_second_loop>>
+ while true loop
+ dbms_output.put_line('in my_second_loop');
+ goto out_of_loop;
+ end loop my_second_loop;
+ dbms_output.put_line('end of my_second_loop');
+end;
+/
+
+-- Local Variables:
+-- indent-tabs-mode: nil
+-- mode: sql
+-- mode: sqlind-minor
+-- sql-product: oracle
+-- tab-width: 2
+-- End: