-;;; make-mode.el --- makefile editing commands for Emacs
+;;; make-mode.el --- makefile editing commands for Emacs -*- lexical-binding:t -*-
-;; Copyright (C) 1992, 1994, 1999-2011 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1994, 1999-2016 Free Software Foundation, Inc.
;; Author: Thomas Neumann <tom@smart.bo.open.de>
;; Eric S. Raymond <esr@snark.thyrsus.com>
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
;; Adapted-By: ESR
;; Keywords: unix, tools
:version "22.1")
(defcustom makefile-browser-buffer-name "*Macros and Targets*"
- "*Name of the macro- and target browser buffer."
+ "Name of the macro- and target browser buffer."
:type 'string
:group 'makefile)
(defcustom makefile-target-colon ":"
- "*String to append to all target names inserted by `makefile-insert-target'.
+ "String to append to all target names inserted by `makefile-insert-target'.
\":\" or \"::\" are common values."
:type 'string
:group 'makefile)
(defcustom makefile-macro-assign " = "
- "*String to append to all macro names inserted by `makefile-insert-macro'.
+ "String to append to all macro names inserted by `makefile-insert-macro'.
The normal value should be \" = \", since this is what
standard make expects. However, newer makes such as dmake
allow a larger variety of different macro assignments, so you
:group 'makefile)
(defcustom makefile-electric-keys nil
- "*If non-nil, Makefile mode should install electric keybindings.
+ "If non-nil, Makefile mode should install electric keybindings.
Default is nil."
:type 'boolean
:group 'makefile)
(defcustom makefile-use-curly-braces-for-macros-p nil
- "*Controls the style of generated macro references.
+ "Controls the style of generated macro references.
Non-nil means macro references should use curly braces, like `${this}'.
nil means use parentheses, like `$(this)'."
:type 'boolean
:group 'makefile)
(defcustom makefile-tab-after-target-colon t
- "*If non-nil, insert a TAB after a target colon.
+ "If non-nil, insert a TAB after a target colon.
Otherwise, a space is inserted.
The default is t."
:type 'boolean
:group 'makefile)
(defcustom makefile-browser-leftmost-column 10
- "*Number of blanks to the left of the browser selection mark."
+ "Number of blanks to the left of the browser selection mark."
:type 'integer
:group 'makefile)
(defcustom makefile-browser-cursor-column 10
- "*Column the cursor goes to when it moves up or down in the Makefile browser."
+ "Column the cursor goes to when it moves up or down in the Makefile browser."
:type 'integer
:group 'makefile)
(defcustom makefile-backslash-column 48
- "*Column in which `makefile-backslash-region' inserts backslashes."
+ "Column in which `makefile-backslash-region' inserts backslashes."
:type 'integer
:group 'makefile)
(defcustom makefile-backslash-align t
- "*If non-nil, `makefile-backslash-region' will align backslashes."
+ "If non-nil, `makefile-backslash-region' will align backslashes."
:type 'boolean
:group 'makefile)
(defcustom makefile-browser-selected-mark "+ "
- "*String used to mark selected entries in the Makefile browser."
+ "String used to mark selected entries in the Makefile browser."
:type 'string
:group 'makefile)
(defcustom makefile-browser-unselected-mark " "
- "*String used to mark unselected entries in the Makefile browser."
+ "String used to mark unselected entries in the Makefile browser."
:type 'string
:group 'makefile)
(defcustom makefile-browser-auto-advance-after-selection-p t
- "*If non-nil, cursor will move after item is selected in Makefile browser."
+ "If non-nil, cursor will move after item is selected in Makefile browser."
:type 'boolean
:group 'makefile)
(defcustom makefile-pickup-everything-picks-up-filenames-p nil
- "*If non-nil, `makefile-pickup-everything' picks up filenames as targets.
+ "If non-nil, `makefile-pickup-everything' picks up filenames as targets.
This means it calls `makefile-pickup-filenames-as-targets'.
Otherwise filenames are omitted."
:type 'boolean
:group 'makefile)
(defcustom makefile-cleanup-continuations nil
- "*If non-nil, automatically clean up continuation lines when saving.
+ "If non-nil, automatically clean up continuation lines when saving.
A line is cleaned up by removing all whitespace following a trailing
backslash. This is done silently.
IMPORTANT: Please note that enabling this option causes Makefile mode
:group 'makefile)
(defcustom makefile-mode-hook nil
- "*Normal hook run by `makefile-mode'."
+ "Normal hook run by `makefile-mode'."
:type 'hook
:group 'makefile)
"List of special targets.
You will be offered to complete on one of those in the minibuffer whenever
you enter a \".\" at the beginning of a line in `makefile-mode'."
- :type '(repeat (list string))
+ :type '(repeat string)
:group 'makefile)
(put 'makefile-special-targets-list 'risky-local-variable t)
(defcustom makefile-runtime-macros-list
'(("@") ("&") (">") ("<") ("*") ("^") ("+") ("?") ("%") ("$"))
- "*List of macros that are resolved by make at runtime.
+ "List of macros that are resolved by make at runtime.
If you insert a macro reference using `makefile-insert-macro-ref', the name
of the macro is checked against this list. If it can be found its name will
not be enclosed in { } or ( )."
;; (spanning potentially several lines).
;; "^ *\\([^ \n\t][^:#= \t\n]*\\)[ \t]*\\(?:!=[ \t]*\\(\\(?:.+\\\\\n\\)*.+\\)\\|[*:+]?[:?]?=[ \t]*\\(\\(?:.*\\\\\n\\)*.*\\)\\)"
;; What about the define statement? What about differentiating this for makepp?
- "\\(?:^\\|^export\\|^override\\|:\\|: *override\\) *\\([^ \n\t][^:#= \t\n]*\\)[ \t]*\\(?:!=\\|[*:+]?[:?]?=\\)"
+ "\\(?:^\\|^export\\|^override\\|:\\|:[ \t]*override\\)[ \t]*\\([^ \n\t][^:#= \t\n]*\\)[ \t]*\\(?:!=\\|[*:+]?[:?]?=\\)"
"Regex used to find macro assignment lines in a makefile.")
(defconst makefile-var-use-regex
"List of keywords understood by automake.")
(defconst makefile-gmake-statements
- `("-sinclude" "sinclude" "vpath" ; makefile-makepp-statements takes rest
+ `("-sinclude" "sinclude" ; makefile-makepp-statements takes rest
"ifdef" "ifndef" "ifeq" "ifneq" "-include" "define" "endef" "export"
- "override define" "override" "unexport"
+ "override define" "override" "unexport" "vpath"
,@(cdr makefile-automake-statements))
"List of keywords understood by gmake.")
-;; These are even more silly, because you can have more spaces in between.
(defconst makefile-makepp-statements
- `("and ifdef" "and ifndef" "and ifeq" "and ifneq" "and ifperl"
- "and ifmakeperl" "and ifsys" "and ifnsys" "build_cache" "build_check"
+ `(t ; - alternately means _
+ ;; todo: take if* out of these lists, and let the negation regexp do it all
+ "ifperl" "ifmakeperl" "ifsys" "ifnsys" "iftrue" "ifntrue"
+ "and ifdef" "and ifndef" "and ifeq" "and ifneq" "and ifperl"
+ "and ifmakeperl" "and ifsys" "and ifnsys" "and iftrue" "and ifntrue"
"else ifdef" "else ifndef" "else ifeq" "else ifneq" "else ifperl"
- "else ifmakeperl" "else ifsys" "else ifnsys" "enddef" "global"
- "load_makefile" "ifperl" "ifmakeperl" "ifsys" "ifnsys" "_include"
- "makeperl" "makesub" "no_implicit_load" "perl" "perl-begin" "perl_begin"
- "perl-end" "perl_end" "prebuild" "or ifdef" "or ifndef" "or ifeq"
- "or ifneq" "or ifperl" "or ifmakeperl" "or ifsys" "or ifnsys"
- "override export" "override global" "register_command_parser"
- "register_scanner" "repository" "runtime" "signature" "sub"
- ,@(nthcdr 3 makefile-gmake-statements))
+ "else ifmakeperl" "else ifsys" "else ifnsys" "else iftrue" "else ifntrue"
+ "or ifdef" "or ifndef" "or ifeq" "or ifneq" "or ifperl"
+ "or ifmakeperl" "or ifsys" "or ifnsys" "or iftrue" "or ifntrue"
+
+ "autoload" "build-cache" "build-check" "enddef" "export define"
+ "global" "global build-cache" "global build-check" "global define"
+ "global signature" "global override signature" "load-makefile"
+ "make" "makeperl" "makesub" "no-implicit-load" "perl" "perl-begin"
+ "perl-end" "prebuild" "override export" "override global" "register-parser"
+ "register-command-parser" "register-input-suffix"
+ "register-scanner" "repository" "runtime" "signature" "sub"
+
+ ,@(nthcdr 2 makefile-gmake-statements))
"List of keywords understood by gmake.")
(defconst makefile-bsdmake-statements
;; Fontify conditionals and includes.
(,(concat "^\\(?: [ \t]*\\)?"
- (regexp-opt keywords t)
+ (replace-regexp-in-string
+ " " "[ \t]+"
+ (if (eq (car keywords) t)
+ (replace-regexp-in-string "-" "[_-]"
+ (regexp-opt (cdr keywords) t))
+ (regexp-opt keywords t)))
"\\>[ \t]*\\([^: \t\n#]*\\)")
(1 font-lock-keyword-face) (2 font-lock-variable-name-face))
makefile-var-use-regex
makefile-makepp-statements
nil
- "^\\(?: [ \t]*\\)?\\(?:and[ \t]+\\|else[ \t]+\\|or[ \t]+\\)?if\\(n\\)\\(?:def\\|eq\\|sys\\)\\>"
+ "^\\(?: [ \t]*\\)?\\(?:and[ \t]+\\|else[ \t]+\\|or[ \t]+\\)?if\\(n\\)\\(?:def\\|eq\\|sys\\|true\\)\\>"
'("[^$]\\(\\$[({]\\(?:output\\|stem\\|target\\)s?\\_>.*?[})]\\)"
1 'makefile-targets append)
(2 font-lock-keyword-face t)
(3 font-lock-variable-name-face t))
- ;; $(function ...) $((function ...)) ${function ...} ${{function ...}}
- '("[^$]\\$\\(?:((?\\|{{?\\)\\([-a-zA-Z0-9_.]+\\s \\)"
+ ;; $(function ...) $((function ...)) ${...} ${{...}} $[...] $[[...]]
+ '("[^$]\\$\\(?:((?\\|{{?\\|\\[\\[?\\)\\([-a-zA-Z0-9_.]+\\s \\)"
1 font-lock-function-name-face prepend)
- ;; $(shell ...) $((shell ...)) ${shell ...} ${{shell ...}}
- '("[^$]\\$\\(((?\\|{{?\\)shell\\(?:[-_]\\(?:global[-_]\\)?once\\)?[ \t]+"
+ ;; $(shell ...) $((shell ...)) ${...} ${{...}} $[...] $[[...]]
+ '("[^$]\\$\\(((?\\|{{?\\|\\[\\[?\\)shell\\(?:[-_]\\(?:global[-_]\\)?once\\)?[ \t]+"
makefile-match-function-end nil nil
(1 'makefile-shell prepend t))
- ;; $(perl ...) $((perl ...)) ${perl ...} ${{perl ...}}
- '("[^$]\\$\\(((?\\|{{?\\)makeperl[ \t]+"
+ ;; $(perl ...) $((perl ...)) ${...} ${{...}} $[...] $[[...]]
+ '("[^$]\\$\\(((?\\|{{?\\|\\[\\[?\\)makeperl[ \t]+"
makefile-match-function-end nil nil
(1 'makefile-makepp-perl prepend t))
'("[^$]\\$\\(((?\\|{{?\\)perl[ \t]+"
;; should return an exit status of zero if the target `foo' is
;; up to date and a nonzero exit status otherwise.
;; Many makes can do this although the docs/manpages do not mention
-;; it. Try it with your favourite one. GNU make, System V make, and
+;; it. Try it with your favorite one. GNU make, System V make, and
;; Dennis Vadura's DMake have no problems.
;; Set the variable `makefile-brave-make' to the name of the
;; make utility that does this on your system.
;; ------------------------------------------------------------
(defcustom makefile-brave-make "make"
- "*How to invoke make, for `makefile-query-targets'.
+ "How to invoke make, for `makefile-query-targets'.
This should identify a `make' command that can handle the `-q' option."
:type 'string
:group 'makefile)
(defcustom makefile-query-one-target-method-function
'makefile-query-by-make-minus-q
- "*Function to call to determine whether a make target is up to date.
+ "Function to call to determine whether a make target is up to date.
The function must satisfy this calling convention:
* As its first argument, it must accept the name of the target to
'makefile-query-one-target-method-function)
(defcustom makefile-up-to-date-buffer-name "*Makefile Up-to-date overview*"
- "*Name of the Up-to-date overview buffer."
+ "Name of the Up-to-date overview buffer."
:type 'string
:group 'makefile)
(define-key map "\C-c\C-m\C-p" 'makefile-makepp-mode)
(define-key map "\M-p" 'makefile-previous-dependency)
(define-key map "\M-n" 'makefile-next-dependency)
- (define-key map "\e\t" 'makefile-complete)
+ (define-key map "\e\t" 'completion-at-point)
;; Make menus.
(define-key map [menu-bar makefile-mode]
'(menu-item "Find Targets and Macros" makefile-pickup-everything
:help "Notice names of all macros and targets in Makefile"))
(define-key map [menu-bar makefile-mode complete]
- '(menu-item "Complete Target or Macro" makefile-complete
+ '(menu-item "Complete Target or Macro" completion-at-point
:help "Perform completion on Makefile construct preceding point"))
(define-key map [menu-bar makefile-mode backslash]
'(menu-item "Backslash Region" makefile-backslash-region
(modify-syntax-entry ?\` "\" " st)
(modify-syntax-entry ?# "< " st)
(modify-syntax-entry ?\n "> " st)
- st))
+ (modify-syntax-entry ?= "." st)
+ st)
+ "Syntax table used in `makefile-mode'.")
(defvar makefile-imake-mode-syntax-table
(let ((st (make-syntax-table makefile-mode-syntax-table)))
List of special targets. You will be offered to complete
on one of those in the minibuffer whenever you enter a `.'.
at the beginning of a line in Makefile mode."
+ (add-hook 'completion-at-point-functions
+ #'makefile-completions-at-point nil t)
(add-hook 'write-file-functions
'makefile-warn-suspicious-lines nil t)
(add-hook 'write-file-functions
(make-local-variable 'makefile-need-macro-pickup)
;; Font lock.
- (set (make-local-variable 'font-lock-defaults)
- ;; SYNTAX-BEGIN set to backward-paragraph to avoid slow-down
- ;; near the end of a large buffer, due to parse-partial-sexp's
- ;; trying to parse all the way till the beginning of buffer.
- '(makefile-font-lock-keywords
- nil nil
- ((?$ . "."))
- backward-paragraph))
- (set (make-local-variable 'syntax-propertize-function)
- makefile-syntax-propertize-function)
+ (setq-local font-lock-defaults
+ ;; Set SYNTAX-BEGIN to backward-paragraph to avoid
+ ;; slow-down near the end of a large buffer, due to
+ ;; `parse-partial-sexp' trying to parse all the way till
+ ;; the beginning of buffer.
+ '(makefile-font-lock-keywords
+ nil nil
+ ((?$ . "."))
+ backward-paragraph))
+ (setq-local syntax-propertize-function
+ makefile-syntax-propertize-function)
;; Add-log.
- (set (make-local-variable 'add-log-current-defun-function)
- 'makefile-add-log-defun)
+ (setq-local add-log-current-defun-function
+ 'makefile-add-log-defun)
;; Imenu.
- (set (make-local-variable 'imenu-generic-expression)
- makefile-imenu-generic-expression)
+ (setq-local imenu-generic-expression
+ makefile-imenu-generic-expression)
;; Dabbrev.
- (set (make-local-variable 'dabbrev-abbrev-skip-leading-regexp) "\\$")
+ (setq-local dabbrev-abbrev-skip-leading-regexp "\\$")
;; Other abbrevs.
(setq local-abbrev-table makefile-mode-abbrev-table)
;; Filling.
- (set (make-local-variable 'fill-paragraph-function) 'makefile-fill-paragraph)
+ (setq-local fill-paragraph-function 'makefile-fill-paragraph)
;; Comment stuff.
- (set (make-local-variable 'comment-start) "#")
- (set (make-local-variable 'comment-end) "")
- (set (make-local-variable 'comment-start-skip) "#+[ \t]*")
+ (setq-local comment-start "#")
+ (setq-local comment-end "")
+ (setq-local comment-start-skip "#+[ \t]*")
;; Make sure TAB really inserts \t.
- (set (make-local-variable 'indent-line-function) 'indent-to-left-margin)
+ (setq-local indent-line-function 'indent-to-left-margin)
;; Real TABs are important in makefiles
(setq indent-tabs-mode t))
;;;###autoload
(define-derived-mode makefile-makepp-mode makefile-mode "Makeppfile"
"An adapted `makefile-mode' that knows about makepp."
- (set (make-local-variable 'makefile-rule-action-regex)
- makefile-makepp-rule-action-regex)
+ (setq-local makefile-rule-action-regex makefile-makepp-rule-action-regex)
(setq font-lock-defaults
`(makefile-makepp-font-lock-keywords ,@(cdr font-lock-defaults))
imenu-generic-expression
;;;###autoload
(define-derived-mode makefile-bsdmake-mode makefile-mode "BSDmakefile"
"An adapted `makefile-mode' that knows about BSD make."
- (set (make-local-variable 'makefile-dependency-regex)
- makefile-bsdmake-dependency-regex)
- (set (make-local-variable 'makefile-dependency-skip) "^:!")
- (set (make-local-variable 'makefile-rule-action-regex)
- makefile-bsdmake-rule-action-regex)
+ (setq-local makefile-dependency-regex makefile-bsdmake-dependency-regex)
+ (setq-local makefile-dependency-skip "^:!")
+ (setq-local makefile-rule-action-regex makefile-bsdmake-rule-action-regex)
(setq font-lock-defaults
`(makefile-bsdmake-font-lock-keywords ,@(cdr font-lock-defaults))))
(define-derived-mode makefile-imake-mode makefile-mode "Imakefile"
"An adapted `makefile-mode' that knows about imake."
:syntax-table makefile-imake-mode-syntax-table
- (set (make-local-variable 'syntax-propertize-function) nil)
+ (setq-local syntax-propertize-function nil)
(setq font-lock-defaults
`(makefile-imake-font-lock-keywords ,@(cdr font-lock-defaults))))
;;; Completion.
-(defun makefile-complete ()
- "Perform completion on Makefile construct preceding point.
-Can complete variable and target names.
-The context determines which are considered."
- (interactive)
+(defun makefile-completions-at-point ()
(let* ((beg (save-excursion
(skip-chars-backward "^$(){}:#= \t\n")
(point)))
;; Preceding "$(" or "${" means macros only.
((and (memq pc '(?\{ ?\())
(progn
- (setq paren (if (eq paren ?\{) ?\} ?\)))
+ (setq paren (if (eq pc ?\{) ?\} ?\)))
(backward-char)
(= (preceding-char) ?$)))
t)))))
-
- (table (apply-partially 'completion-table-with-terminator
- (cond
- (do-macros (or paren ""))
- ((save-excursion (goto-char beg) (bolp)) ":")
- (t " "))
- (append (if do-macros
- '()
- makefile-target-table)
- makefile-macro-table))))
- (completion-in-region beg (point) table)))
-
+ (suffix (cond
+ (do-macros (if paren (string paren)))
+ ((save-excursion (goto-char beg) (bolp)) ":")
+ (t " "))))
+ (list beg (point)
+ (append (if do-macros '() makefile-target-table)
+ makefile-macro-table)
+ :exit-function
+ (if suffix
+ (lambda (_s finished)
+ (when (memq finished '(sole finished))
+ (if (looking-at (regexp-quote suffix))
+ (goto-char (match-end 0))
+ (insert suffix))))))))
+
+(define-obsolete-function-alias 'makefile-complete 'completion-at-point "24.1")
\f
;; Backslashification. Stolen from cc-mode.el.
(save-excursion
(goto-char from)
(let ((column makefile-backslash-column)
- (endmark (make-marker)))
- (move-marker endmark to)
+ (endmark (copy-marker to)))
;; Compute the smallest column number past the ends of all the lines.
- (if makefile-backslash-align
- (progn
- (if (not delete-flag)
- (while (< (point) to)
- (end-of-line)
- (if (= (preceding-char) ?\\)
- (progn (forward-char -1)
- (skip-chars-backward " \t")))
- (setq column (max column (1+ (current-column))))
- (forward-line 1)))
- ;; Adjust upward to a tab column, if that doesn't push
- ;; past the margin.
- (if (> (% column tab-width) 0)
- (let ((adjusted (* (/ (+ column tab-width -1) tab-width)
- tab-width)))
- (if (< adjusted (window-width))
- (setq column adjusted))))))
+ (when (and makefile-backslash-align (not delete-flag))
+ (while (< (point) to)
+ (end-of-line)
+ (if (= (preceding-char) ?\\)
+ (progn (forward-char -1)
+ (skip-chars-backward " \t")))
+ (setq column (max column (1+ (current-column))))
+ (forward-line 1))
+ ;; Adjust upward to a tab column, if that doesn't push
+ ;; past the margin.
+ (if (> (% column tab-width) 0)
+ (let ((adjusted (* (/ (+ column tab-width -1) tab-width)
+ tab-width)))
+ (if (< adjusted (window-width))
+ (setq column adjusted)))))
;; Don't modify blank lines at start of region.
(goto-char from)
(while (and (< (point) endmark) (eolp))
;; Filling
-(defun makefile-fill-paragraph (_arg)
- ;; Fill comments, backslashed lines, and variable definitions
- ;; specially.
+(defun makefile-fill-paragraph (_justify)
+ "Function used for `fill-paragraph-function' in Makefile mode.
+Fill comments, backslashed lines, and variable definitions specially."
(save-excursion
(beginning-of-line)
(cond
((or (eq (char-before (line-end-position 1)) ?\\)
(eq (char-before (line-end-position 0)) ?\\))
;; A backslash region. Find beginning and end, remove
- ;; backslashes, fill, and then reapply backslahes.
+ ;; backslashes, fill, and then reapply backslashes.
(end-of-line)
(let ((beginning
(save-excursion
(end-of-line 0)
(while (= (preceding-char) ?\\)
(end-of-line 0))
- (forward-char)
- (point)))
+ ;; Maybe we hit bobp, in which case we are not at EOL.
+ (if (eolp)
+ (1+ (point))
+ (point))))
(end
(save-excursion
- (while (= (preceding-char) ?\\)
+ (while (and (= (preceding-char) ?\\)
+ (not (eobp)))
(end-of-line 2))
(point))))
(save-restriction
(narrow-to-region beginning end)
(makefile-backslash-region (point-min) (point-max) t)
+ ;; Backslashed newlines are marked as punctuation, so when
+ ;; fill-delete-newlines turns the LF into SPC, we end up with spaces
+ ;; which back-to-indentation (called via fill-newline ->
+ ;; fill-indent-to-left-margin -> indent-line-to) thinks are real code
+ ;; (bug#13179).
+ (remove-text-properties (point-min) (point-max) '(syntax-table))
(let ((fill-paragraph-function nil)
;; Adjust fill-column to allow space for the backslash.
(fill-column (- fill-column 1)))
(defun makefile-browser-insert-continuation ()
"Insert a makefile continuation.
-In the makefile buffer, go to (end-of-line), insert a \'\\\'
+In the makefile buffer, go to (end-of-line), insert a `\\'
character, insert a new blank line, go to that line and indent by one TAB.
This is most useful in the process of creating continued lines when copying
large dependencies from the browser to the client buffer.
(setq buffer-read-only t))
(defun makefile-browse (targets macros)
- (interactive)
(if (zerop (+ (length targets) (length macros)))
(progn
(beep)
- (message "No macros or targets to browse! Consider running 'makefile-pickup-everything\'"))
+ (message "No macros or targets to browse! Consider running `makefile-pickup-everything'"))
(let ((browser-buffer (get-buffer-create makefile-browser-buffer-name)))
(pop-to-buffer browser-buffer)
(makefile-browser-fill targets macros)
(shrink-window-if-larger-than-buffer)
- (set (make-local-variable 'makefile-browser-selection-vector)
- (make-vector (+ (length targets) (length macros)) nil))
+ (setq-local makefile-browser-selection-vector
+ (make-vector (+ (length targets) (length macros)) nil))
(makefile-browser-start-interaction))))
(defun makefile-switch-to-browser ()
;; FIXME forward-sexp or somesuch would be better?
(if (setq s (cond ((string= s "(") ")")
((string= s "{") "}")
+ ((string= s "[") "]")
((string= s "((") "))")
- ((string= s "{{") "}}")))
+ ((string= s "{{") "}}")
+ ((string= s "[[") "]]")))
(re-search-forward (concat "\\(.*\\)[ \t]*" s) (line-end-position) t))))
(defun makefile-match-dependency (bound)