;;; cc-awk.el --- AWK specific code within cc-mode.
-;; Copyright (C) 1988, 1994, 1996, 2000-2013 Free Software Foundation,
+;; Copyright (C) 1988, 1994, 1996, 2000-2016 Free Software Foundation,
;; Inc.
;; Author: Alan Mackenzie <acm@muc.de> (originally based on awk-mode.el)
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
;; Keywords: AWK, cc-mode, unix, languages
;; Package: cc-mode
(cc-bytecomp-defun c-backward-token-1)
(cc-bytecomp-defun c-beginning-of-statement-1)
(cc-bytecomp-defun c-backward-sws)
+(cc-bytecomp-defun c-forward-sws)
(defvar awk-mode-syntax-table
(let ((st (make-syntax-table)))
(modify-syntax-entry ?\# "< " st)
;; / can delimit regexes or be a division operator. By default we assume
;; that it is a division sign, and fix the regexp operator cases with
- ;; `font-lock-syntactic-keywords'.
+ ;; `c-awk-set-syntax-table-properties'.
(modify-syntax-entry ?/ "." st) ; ACM 2002/4/27.
(modify-syntax-entry ?* "." st)
(modify-syntax-entry ?+ "." st)
(concat "\\=_?\"" c-awk-string-innards-re))
;; Matches an AWK string at point up to, but not including, any terminator.
;; A gawk 3.1+ string may look like _"localizable string".
-(defconst c-awk-one-line-possibly-open-string-re
- (concat "\"\\(" c-awk-string-ch-re "\\|" c-awk-non-eol-esc-pair-re "\\)*"
- "\\(\"\\|\\\\?$\\|\\'\\)"))
+(defconst c-awk-possibly-open-string-re
+ (concat "\"\\(" c-awk-string-ch-re "\\|" c-awk-esc-pair-re "\\)*"
+ "\\(\"\\|$\\|\\'\\)"))
;; REGEXPS FOR AWK REGEXPS.
(defconst c-awk-regexp-normal-re "[^[/\\\n\r]")
"\\|" "[^]\n\r]" "\\)*" "\\(]\\|$\\)"))
;; Matches a regexp char list, up to (but not including) EOL if the ] is
;; missing.
-(defconst c-awk-regexp-one-line-possibly-open-char-list-re
- (concat "\\[\\]?\\(" c-awk-non-eol-esc-pair-re "\\|" "[^]\n\r]" "\\)*"
- "\\(]\\|\\\\?$\\|\\'\\)"))
-;; Matches the head (or all) of a regexp char class, up to (but not
-;; including) the first EOL.
(defconst c-awk-regexp-innards-re
(concat "\\(" c-awk-esc-pair-re "\\|" c-awk-regexp-char-list-re
- "\\|" c-awk-regexp-normal-re "\\)*"))
+ "\\|" c-awk-regexp-normal-re "\\)*"))
;; Matches the inside of an AWK regexp (i.e. without the enclosing /s)
(defconst c-awk-regexp-without-end-re
(concat "/" c-awk-regexp-innards-re))
;; Matches an AWK regexp up to, but not including, any terminating /.
-(defconst c-awk-one-line-possibly-open-regexp-re
- (concat "/\\(" c-awk-non-eol-esc-pair-re
- "\\|" c-awk-regexp-one-line-possibly-open-char-list-re
- "\\|" c-awk-regexp-normal-re "\\)*"
- "\\(/\\|\\\\?$\\|\\'\\)"))
-;; Matches as much of the head of an AWK regexp which fits on one line,
-;; possibly all of it.
;; REGEXPS used for scanning an AWK buffer in order to decide IF A '/' IS A
;; REGEXP OPENER OR A DIVISION SIGN. By "state" in the following is meant
(defconst c-awk-neutrals*-re
(concat "\\(" c-awk-neutral-re "\\)*"))
;; A (possibly empty) string of neutral characters (or character pairs).
-(defconst c-awk-var-num-ket-re "[]\)0-9a-zA-Z_$.\x80-\xff]+")
+(defconst c-awk-var-num-ket-re "[])0-9a-zA-Z_$.\x80-\xff]+")
;; Matches a char which is a constituent of a variable or number, or a ket
;; (i.e. closing bracKET), round or square. Assume that all characters \x80 to
;; \xff are "letters".
;; will only work when there won't be a preceding " or / before the sought /
;; to foul things up.
(defconst c-awk-non-arith-op-bra-re
- "[[\({&=:!><,?;'~|]")
+ "[[({&=:!><,?;'~|]")
;; Matches an opening BRAcket (of any sort), or any operator character
;; apart from +,-,/,*,%. For the purpose at hand (detecting a / which is a
;; regexp bracket) these arith ops are unnecessary and a pain, because of "++"
;; REGEXPS USED FOR FINDING THE POSITION OF A "virtual semicolon"
(defconst c-awk-_-harmless-nonws-char-re "[^#/\"\\\\\n\r \t]")
-;; NEW VERSION! (which will be restricted to the current line)
-(defconst c-awk-one-line-non-syn-ws*-re
- (concat "\\([ \t]*"
- "\\(" c-awk-_-harmless-nonws-char-re "\\|"
- c-awk-non-eol-esc-pair-re "\\|"
- c-awk-one-line-possibly-open-string-re "\\|"
- c-awk-one-line-possibly-open-regexp-re
- "\\)"
- "\\)*"))
+(defconst c-awk-non-/-syn-ws*-re
+ (concat
+ "\\(" c-awk-escaped-nls*-with-space*
+ "\\(" c-awk-_-harmless-nonws-char-re "\\|"
+ c-awk-non-eol-esc-pair-re "\\|"
+ c-awk-possibly-open-string-re
+ "\\)"
+ "\\)*"))
+(defconst c-awk-space*-/-re (concat c-awk-escaped-nls*-with-space* "/"))
+;; Matches optional whitespace followed by "/".
+(defconst c-awk-space*-regexp-/-re
+ (concat c-awk-escaped-nls*-with-space* "\\s\""))
+;; Matches optional whitespace followed by a "/" with string syntax (a matched
+;; regexp delimiter).
+(defconst c-awk-space*-unclosed-regexp-/-re
+ (concat c-awk-escaped-nls*-with-space* "\\s|"))
+;; Matches optional whitespace followed by a "/" with string fence syntax (an
+;; unmatched regexp delimiter).
\f
;; ACM, 2002/5/29:
(defun c-awk-at-vsemi-p (&optional pos)
;; Is there a virtual semicolon at POS (or POINT)?
(save-excursion
- (let (nl-prop
- (pos-or-point (progn (if pos (goto-char pos)) (point))))
- (forward-line 0)
- (search-forward-regexp c-awk-one-line-non-syn-ws*-re)
+ (let* (nl-prop
+ (pos-or-point (progn (if pos (goto-char pos)) (point)))
+ (bol (c-point 'bol)) (eol (c-point 'eol)))
+ (c-awk-beginning-of-logical-line)
+ ;; Next `while' goes round one logical line (ending in, e.g. "\\") per
+ ;; iteration. Such a line is rare, and can only be an open string
+ ;; ending in an escaped \.
+ (while
+ (progn
+ ;; Next `while' goes over a division sign or /regexp/ per iteration.
+ (while
+ (and
+ (< (point) eol)
+ (progn
+ (search-forward-regexp c-awk-non-/-syn-ws*-re eol)
+ (looking-at c-awk-space*-/-re)))
+ (cond
+ ((looking-at c-awk-space*-regexp-/-re) ; /regexp/
+ (forward-sexp))
+ ((looking-at c-awk-space*-unclosed-regexp-/-re) ; Unclosed /regexp
+ (condition-case nil
+ (progn
+ (forward-sexp)
+ (backward-char)) ; Move to end of (logical) line.
+ (error (end-of-line)))) ; Happens at EOB.
+ (t ; division sign
+ (c-forward-syntactic-ws)
+ (forward-char))))
+ (< (point) bol))
+ (forward-line))
(and (eq (point) pos-or-point)
(progn
(while (and (eq (setq nl-prop (c-awk-get-NL-prop-cur-line)) ?\\)
;; Scan the buffer text between point and LIM, setting (and clearing) the
;; syntax-table property where necessary.
;;
-;; This function is designed to be called as the FUNCTION in a MATCHER in
-;; font-lock-syntactic-keywords, and it always returns NIL (to inhibit
-;; repeated calls from font-lock: See elisp info page "Search-based
-;; Fontification"). It also gets called, with a bit of glue, from
-;; after-change-functions when font-lock isn't active. Point is left
-;; "undefined" after this function exits. THE BUFFER SHOULD HAVE BEEN
-;; WIDENED, AND ANY PRECIOUS MATCH-DATA SAVED BEFORE CALLING THIS ROUTINE.
+;; This function is designed to be called as the FUNCTION in a MATCHER
+;; in font-lock-syntactic-keywords, and it always returns NIL (to
+;; inhibit repeated calls from font-lock: See elisp info page
+;; "Search-based Fontification"). (2015-11-24: CC Mode doesn't use
+;; `font-lock-syntactic-keywords' and hasn't done for a very long
+;; time, if ever. ACM.) This function gets called, with a bit of
+;; glue, from after-change-functions whether or not font-lock is
+;; active. Point is left "undefined" after this function exits. THE
+;; BUFFER SHOULD HAVE BEEN WIDENED, AND ANY PRECIOUS MATCH-DATA SAVED
+;; BEFORE CALLING THIS ROUTINE.
;;
;; We need to set/clear the syntax-table property on:
;; (i) / - It is set to "string" on a / which is the opening or closing
\f
(cc-provide 'cc-awk) ; Changed from 'awk-mode, ACM 2002/5/21
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
;;; awk-mode.el ends here