Show
Ignore:
Timestamp:
07/29/06 07:48:34 (2 years ago)
Author:
miyoshi
Message:

Sync up with Emacs CVS HEAD.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lisp/progmodes/sh-script.el

    r4098 r4131  
    981981 
    982982(defun sh-quoted-subshell (limit) 
    983   "Search for a subshell embedded in a string. Find all the unescaped 
    984 \" characters within said subshell, remembering that subshells can nest." 
    985   (if (re-search-forward "\"\\(?:.\\|\n\\)*?\\(\\$(\\|`\\)" limit t) 
    986       ;; bingo we have a $( or a ` inside a "" 
    987       (let ((char (char-after (point))) 
    988             (continue t) 
    989             (pos (point)) 
    990             (data nil)    ;; value to put into match-data (and return) 
    991             (last nil)    ;; last char seen 
    992             (bq  (equal (match-string 1) "`")) ;; ` state flip-flop 
    993             (seen nil)    ;; list of important positions 
    994             (nest 1))     ;; subshell nesting level 
    995         (while (and continue char (<= pos limit)) 
    996           ;; unescaped " inside a $( ... ) construct. 
    997           ;; state machine time... 
    998           ;; \ => ignore next char; 
    999           ;; ` => increase or decrease nesting level based on bq flag 
    1000           ;; ) [where nesting > 0] => decrease nesting 
    1001           ;; ( [where nesting > 0] => increase nesting 
    1002           ;; ( [preceeded by $ ]   => increase nesting 
    1003           ;; " [nesting <= 0 ]     => terminate, we're done. 
    1004           ;; " [nesting >  0 ]     => remember this, it's not a proper " 
    1005           (if (eq ?\\ last) nil 
    1006             (if (eq ?\` char) (setq nest (+ nest (if bq -1 1)) bq (not bq)) 
    1007               (if (and (> nest 0) (eq ?\) char))  (setq nest (1- nest)) 
    1008                 (if (and (eq ?$ last) (eq ?\( char)) (setq nest (1+ nest)) 
    1009                   (if (and (> nest 0) (eq ?\( char)) (setq nest (1+ nest)) 
    1010                     (if (eq char ?\") 
    1011                         (if (>= 0 nest) (setq continue nil) 
    1012                           (setq seen (cons pos seen)) ) )))))) 
    1013           ;;(message "POS: %d [%d]" pos nest) 
    1014           (setq last char 
    1015                 pos  (1+ pos) 
    1016                 char (char-after pos)) ) 
    1017         (when seen 
    1018           ;;(message "SEEN: %S" seen) 
    1019           (setq data (list (current-buffer))) 
    1020           (mapc (lambda (P) 
    1021                   (setq data (cons P (cons (1+ P) data)) ) ) seen) 
    1022           (store-match-data data)) 
    1023         data) )) 
     983  "Search for a subshell embedded in a string. 
     984Find all the unescaped \" characters within said subshell, remembering that 
     985subshells can nest." 
     986  ;; FIXME: This can (and often does) match multiple lines, yet it makes no 
     987  ;; effort to handle multiline cases correctly, so it ends up being 
     988  ;; rather flakey. 
     989  (when (re-search-forward "\"\\(?:\\(?:.\\|\n\\)*?[^\\]\\(?:\\\\\\\\\\)*\\)??\\(\\$(\\|`\\)" limit t) 
     990    ;; bingo we have a $( or a ` inside a "" 
     991    (let ((char (char-after (point))) 
     992          (continue t) 
     993          (pos (point)) 
     994          (data nil)      ;; value to put into match-data (and return) 
     995          (last nil)      ;; last char seen 
     996          (bq  (equal (match-string 1) "`")) ;; ` state flip-flop 
     997          (seen nil)                         ;; list of important positions 
     998          (nest 1))                          ;; subshell nesting level 
     999      (while (and continue char (<= pos limit)) 
     1000        ;; unescaped " inside a $( ... ) construct. 
     1001        ;; state machine time... 
     1002        ;; \ => ignore next char; 
     1003        ;; ` => increase or decrease nesting level based on bq flag 
     1004        ;; ) [where nesting > 0] => decrease nesting 
     1005        ;; ( [where nesting > 0] => increase nesting 
     1006        ;; ( [preceeded by $ ]   => increase nesting 
     1007        ;; " [nesting <= 0 ]     => terminate, we're done. 
     1008        ;; " [nesting >  0 ]     => remember this, it's not a proper " 
     1009        ;; FIXME: don't count parens that appear within quotes. 
     1010        (cond 
     1011         ((eq ?\\ last) nil) 
     1012         ((eq ?\` char) (setq nest (+ nest (if bq -1 1)) bq (not bq))) 
     1013         ((and (> nest 0) (eq ?\) char))   (setq nest (1- nest))) 
     1014         ((and (eq ?$ last) (eq ?\( char)) (setq nest (1+ nest))) 
     1015         ((and (> nest 0) (eq ?\( char))   (setq nest (1+ nest))) 
     1016         ((eq char ?\") 
     1017          (if (>= 0 nest) (setq continue nil) (push pos seen)))) 
     1018        ;;(message "POS: %d [%d]" pos nest) 
     1019        (setq last char 
     1020              pos  (1+ pos) 
     1021              char (char-after pos)) ) 
     1022      ;; FIXME: why construct a costly match data to pass to 
     1023      ;; sh-apply-quoted-subshell rather than apply the highlight 
     1024      ;; directly here?  -- Stef 
     1025      (when seen 
     1026        ;;(message "SEEN: %S" seen) 
     1027        (setq data (list (current-buffer))) 
     1028        (dolist(P seen) 
     1029          (setq data (cons P (cons (1+ P) data)))) 
     1030        (store-match-data data)) 
     1031      data) )) 
    10241032 
    10251033(defun sh-is-quoted-p (pos)