X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/1bb9a689acfe821e0aa777ddf4e074556c7817a1..af7c7572ce8d87f51817d0f518d1b0aced074a41:/lisp/emacs-lisp/copyright.el diff --git a/lisp/emacs-lisp/copyright.el b/lisp/emacs-lisp/copyright.el index b7e8c84cf2..6f7a43af84 100644 --- a/lisp/emacs-lisp/copyright.el +++ b/lisp/emacs-lisp/copyright.el @@ -1,17 +1,17 @@ ;;; copyright.el --- update the copyright notice in current buffer ;; Copyright (C) 1991, 1992, 1993, 1994, 1995, 1998, 2001, 2002, 2003, -;; 2004, 2005, 2006, 2007 Free Software Foundation, Inc. +;; 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. ;; Author: Daniel Pfeiffer ;; Keywords: maint, tools ;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -19,9 +19,7 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: @@ -43,10 +41,18 @@ A value of nil means to search whole buffer." :type '(choice (integer :tag "Limit") (const :tag "No limit"))) +(defcustom copyright-at-end-flag nil + "Non-nil means to search backwards from the end of the buffer for copyright. +This is useful for ChangeLogs." + :group 'copyright + :type 'boolean + :version "23.1") + (defcustom copyright-regexp "\\(©\\|@copyright{}\\|[Cc]opyright\\s *:?\\s *\\(?:(C)\\)?\ \\|[Cc]opyright\\s *:?\\s *©\\)\ -\\s *\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)" +\\s *\\(?:[^0-9\n]*\\s *\\)?\ +\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)" "What your copyright notice looks like. The second \\( \\) construct must match the years." :group 'copyright @@ -55,7 +61,7 @@ The second \\( \\) construct must match the years." (defcustom copyright-names-regexp "" "Regexp matching the names which correspond to the user. Only copyright lines where the name matches this regexp will be updated. -This allows you to avoid adding yars to a copyright notice belonging to +This allows you to avoid adding years to a copyright notice belonging to someone else or to a group for which you do not work." :group 'copyright :type 'regexp) @@ -81,7 +87,8 @@ When this is `function', only ask when called non-interactively." (defconst copyright-current-gpl-version "3" "String representing the current version of the GPL or nil.") -(defvar copyright-update t) +(defvar copyright-update t + "The function `copyright-update' sets this to nil after updating a buffer.") ;; This is a defvar rather than a defconst, because the year can ;; change during the Emacs session. @@ -89,22 +96,46 @@ When this is `function', only ask when called non-interactively." "String representing the current year.") (defsubst copyright-limit () ; re-search-forward BOUND - (and copyright-limit (+ (point) copyright-limit))) + (and copyright-limit + (if copyright-at-end-flag + (- (point) copyright-limit) + (+ (point) copyright-limit)))) + +(defun copyright-re-search (regexp &optional bound noerror count) + "Re-search forward or backward depending on `copyright-at-end-flag'." + (if copyright-at-end-flag + (re-search-backward regexp bound noerror count) + (re-search-forward regexp bound noerror count))) + +(defun copyright-start-point () + "Return point-min or point-max, depending on `copyright-at-end-flag'." + (if copyright-at-end-flag + (point-max) + (point-min))) + +(defun copyright-offset-too-large-p () + "Return non-nil if point is too far from the edge of the buffer." + (when copyright-limit + (if copyright-at-end-flag + (< (point) (- (point-max) copyright-limit)) + (> (point) (+ (point-min) copyright-limit))))) (defun copyright-update-year (replace noquery) (when (condition-case err - (re-search-forward (concat "\\(" copyright-regexp - "\\)\\([ \t]*\n\\)?.*\\(?:" - copyright-names-regexp "\\)") - (copyright-limit) - t) + ;; (1) Need the extra \\( \\) around copyright-regexp because we + ;; goto (match-end 1) below. See note (2) below. + (copyright-re-search (concat "\\(" copyright-regexp + "\\)\\([ \t]*\n\\)?.*\\(?:" + copyright-names-regexp "\\)") + (copyright-limit) + t) ;; In case the regexp is rejected. This is useful because ;; copyright-update is typically called from before-save-hook where ;; such an error is very inconvenient for the user. (error (message "Can't update copyright: %s" err) nil)) (goto-char (match-end 1)) - ;; If the years are continued onto multiple lined + ;; If the years are continued onto multiple lines ;; that are marked as comments, skip to the end of the years anyway. (while (save-excursion (and (eq (following-char) ?,) @@ -115,24 +146,27 @@ When this is `function', only ask when called non-interactively." (forward-line 1) (and (looking-at comment-start-skip) (goto-char (match-end 0)))) - (save-match-data - (looking-at copyright-years-regexp)))) + (looking-at-p copyright-years-regexp))) (forward-line 1) (re-search-forward comment-start-skip) - (re-search-forward copyright-years-regexp)) + ;; (2) Need the extra \\( \\) so that the years are subexp 3, as + ;; they are at note (1) above. + (re-search-forward (format "\\(%s\\)" copyright-years-regexp))) ;; Note that `current-time-string' isn't locale-sensitive. (setq copyright-current-year (substring (current-time-string) -4)) (unless (string= (buffer-substring (- (match-end 3) 2) (match-end 3)) (substring copyright-current-year -2)) (if (or noquery - (y-or-n-p (if replace - (concat "Replace copyright year(s) by " - copyright-current-year "? ") - (concat "Add " copyright-current-year - " to copyright? ")))) + ;; Fixes some point-moving oddness (bug#2209). + (save-excursion + (y-or-n-p (if replace + (concat "Replace copyright year(s) by " + copyright-current-year "? ") + (concat "Add " copyright-current-year + " to copyright? "))))) (if replace - (replace-match copyright-current-year t t nil 2) + (replace-match copyright-current-year t t nil 3) (let ((size (save-excursion (skip-chars-backward "0-9")))) (if (and (eq (% (- (string-to-number copyright-current-year) (string-to-number (buffer-substring @@ -159,7 +193,7 @@ When this is `function', only ask when called non-interactively." ;;;###autoload (defun copyright-update (&optional arg interactivep) - "Update copyright notice at beginning of buffer to indicate the current year. + "Update copyright notice to indicate the current year. With prefix ARG, replace the years in the notice rather than adding the current year after them. If necessary, and `copyright-current-gpl-version' is set, any copying permissions @@ -173,21 +207,25 @@ interactively." (save-excursion (save-restriction (widen) - (goto-char (point-min)) + (goto-char (copyright-start-point)) (copyright-update-year arg noquery) - (goto-char (point-min)) + (goto-char (copyright-start-point)) (and copyright-current-gpl-version ;; match the GPL version comment in .el files, including the ;; bilingual Esperanto one in two-column, and in texinfo.tex - (re-search-forward + (copyright-re-search "\\(the Free Software Foundation;\ either \\|; a\\^u eldono \\([0-9]+\\)a, ? a\\^u (la\\^u via \\)\ version \\([0-9]+\\), or (at" (copyright-limit) t) - (not (string= (match-string 3) copyright-current-gpl-version)) + ;; Don't update if the file is already using a more recent + ;; version than the "current" one. + (< (string-to-number (match-string 3)) + (string-to-number copyright-current-gpl-version)) (or noquery - (y-or-n-p (concat "Replace GPL version by " - copyright-current-gpl-version "? "))) + (save-match-data + (y-or-n-p (format "Replace GPL version by %s? " + copyright-current-gpl-version)))) (progn (if (match-end 2) ;; Esperanto bilingual comment in two-column.el @@ -198,14 +236,15 @@ version \\([0-9]+\\), or (at" nil)) +;; FIXME should be within 50 years of present (cf calendar). ;;;###autoload (defun copyright-fix-years () "Convert 2 digit years to 4 digit years. Uses heuristic: year >= 50 means 19xx, < 50 means 20xx." (interactive) (widen) - (goto-char (point-min)) - (if (re-search-forward copyright-regexp (copyright-limit) t) + (goto-char (copyright-start-point)) + (if (copyright-re-search copyright-regexp (copyright-limit) t) (let ((s (match-beginning 2)) (e (copy-marker (1+ (match-end 2)))) (p (make-marker)) @@ -229,7 +268,7 @@ Uses heuristic: year >= 50 means 19xx, < 50 means 20xx." ;; Don't mess up whitespace after the years. (skip-chars-backward " \t") (save-restriction - (narrow-to-region (point-min) (point)) + (narrow-to-region (copyright-start-point) (point)) (let ((fill-prefix " ")) (fill-region s last)))) (set-marker e nil) @@ -245,10 +284,22 @@ Uses heuristic: year >= 50 means 19xx, < 50 means 20xx." "Copyright (C) " `(substring (current-time-string) -4) " by " (or (getenv "ORGANIZATION") str) - '(if (and copyright-limit (> (point) (+ (point-min) copyright-limit))) + '(if (copyright-offset-too-large-p) (message "Copyright extends beyond `copyright-limit' and won't be updated automatically.")) comment-end \n) +;;;###autoload +(defun copyright-update-directory (directory match) + "Update copyright notice for all files in DIRECTORY matching MATCH." + (interactive "DDirectory: \nMFilenames matching (regexp): ") + (dolist (file (directory-files directory t match nil)) + (message "Updating file `%s'" file) + (find-file file) + (let ((copyright-query nil)) + (copyright-update)) + (save-buffer) + (kill-buffer (current-buffer)))) + (provide 'copyright) ;; For the copyright sign: