cvsdist a8bb5f
;;; rpm-spec-mode.el --- RPM spec file editing commands for Emacs/XEmacs
cvsdist a8bb5f
cvsdist d31aa3
;; Copyright (C) 1997-2002 Stig Bjørlykke, <stigb@tihlde.org>
cvsdist a8bb5f
cvsdist a8bb5f
;; Author:   Stig Bjørlykke, <stigb@tihlde.org>
cvsdist 45b61e
;; Keywords: unix, languages, rpm
Charles Coldwell 40eeb8
;; Version:  0.12x
cvsdist a8bb5f
cvsdist d31aa3
;; This file is part of XEmacs.
cvsdist a8bb5f
cvsdist d31aa3
;; XEmacs is free software; you can redistribute it and/or modify
cvsdist a8bb5f
;; it under the terms of the GNU General Public License as published by
cvsdist a8bb5f
;; the Free Software Foundation; either version 2, or (at your option)
cvsdist a8bb5f
;; any later version.
cvsdist a8bb5f
cvsdist d31aa3
;; XEmacs is distributed in the hope that it will be useful,
cvsdist a8bb5f
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
cvsdist a8bb5f
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
cvsdist a8bb5f
;; General Public License for more details.
cvsdist a8bb5f
cvsdist a8bb5f
;; You should have received a copy of the GNU General Public License
cvsdist d31aa3
;; along with XEmacs; see the file COPYING.  If not, write to the
Charles Coldwell 40eeb8
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Charles Coldwell 40eeb8
;; Boston, MA 02110-1301 USA.
cvsdist a8bb5f
cvsdist d31aa3
;;; Synched up with: not in GNU Emacs.
cvsdist a8bb5f
cvsdist a8bb5f
;;; Thanx to:
cvsdist a8bb5f
cvsdist d31aa3
;;     Tore Olsen <toreo@tihlde.org> for some general fixes.
cvsdist a8bb5f
;;     Steve Sanbeg <sanbeg@dset.com> for navigation functions and
cvsdist a8bb5f
;;          some Emacs fixes.
cvsdist d31aa3
;;     Tim Powers <timp@redhat.com> and Trond Eivind Glomsrød
cvsdist d31aa3
;;          <teg@redhat.com> for Red Hat adaptions and some fixes.
cvsdist d31aa3
;;     Chmouel Boudjnah <chmouel@mandrakesoft.com> for Mandrake fixes.
cvsdist 45b61e
;;     Ville Skyttä  <scop@xemacs.org> for some fixes.
cvsdist a8bb5f
cvsdist a8bb5f
;;; ToDo:
cvsdist a8bb5f
cvsdist d31aa3
;; - rewrite function names.
cvsdist a8bb5f
;; - autofill changelog entries.
Charles Coldwell 40eeb8
;; - customize rpm-tags-list, rpm-obsolete-tags-list and rpm-group-tags-list.
cvsdist a8bb5f
;; - get values from `rpm --showrc'.
cvsdist a8bb5f
;; - ssh/rsh for compile.
cvsdist d31aa3
;; - finish integrating the new navigation functions in with existing stuff.
cvsdist d31aa3
;; - use a single prefix consistently (internal)
cvsdist a8bb5f
cvsdist a8bb5f
;;; Commentary:
cvsdist a8bb5f
cvsdist a8bb5f
;; This mode is used for editing spec files used for building RPM packages.
cvsdist a8bb5f
;;
cvsdist a8bb5f
;; Most recent version is available from:
cvsdist a8bb5f
;;  <URL:http://www.tihlde.org/~stigb/rpm-spec-mode.el>
cvsdist a8bb5f
;;
cvsdist a8bb5f
;; Put this in your .emacs file to enable autoloading of rpm-spec-mode,
cvsdist a8bb5f
;; and auto-recognition of ".spec" files:
cvsdist a8bb5f
;;
cvsdist a8bb5f
;;  (autoload 'rpm-spec-mode "rpm-spec-mode.el" "RPM spec mode." t)
cvsdist a8bb5f
;;  (setq auto-mode-alist (append '(("\\.spec" . rpm-spec-mode))
cvsdist a8bb5f
;;                                auto-mode-alist))
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
;;
cvsdist a8bb5f
cvsdist a8bb5f
;;; Code:
cvsdist a8bb5f
Charles Coldwell dcc57f
(defconst rpm-spec-mode-version "0.12.1x" "Version of `rpm-spec-mode'.")
cvsdist d31aa3
cvsdist a8bb5f
(defgroup rpm-spec nil
cvsdist d31aa3
  "RPM spec mode with Emacs/XEmacs enhancements."
cvsdist d31aa3
  :prefix "rpm-spec-"
cvsdist a8bb5f
  :group 'languages)
cvsdist a8bb5f
Jens Petersen 4c3846
(defcustom rpm-spec-build-command "rpmbuild"
Jens Petersen 4c3846
  "Command for building an RPM package."
Jens Petersen 4c3846
  :type 'string
Jens Petersen 4c3846
  :group 'rpm-spec)
Jens Petersen 4c3846
cvsdist a8bb5f
(defcustom rpm-spec-add-attr nil
cvsdist d31aa3
  "Add \"%attr\" entry for file listings or not."
cvsdist a8bb5f
  :type 'boolean
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist a8bb5f
(defcustom rpm-spec-short-circuit nil
cvsdist a8bb5f
  "Skip straight to specified stage.
cvsdist a8bb5f
(ie, skip all stages leading up to the specified stage).  Only valid
cvsdist a8bb5f
in \"%build\" and \"%install\" stage."
cvsdist a8bb5f
  :type 'boolean
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist a8bb5f
(defcustom rpm-spec-timecheck "0"
cvsdist a8bb5f
  "Set the \"timecheck\" age (0 to disable).
cvsdist a8bb5f
The timecheck value expresses, in seconds, the maximum age of a file
cvsdist a8bb5f
being packaged.  Warnings will be printed for all files beyond the
cvsdist a8bb5f
timecheck age."
cvsdist a8bb5f
  :type 'integer
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist a8bb5f
(defcustom rpm-spec-buildroot ""
cvsdist 45b61e
  "When building, override the BuildRoot tag with directory <dir>."
cvsdist a8bb5f
  :type 'string
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist a8bb5f
(defcustom rpm-spec-target ""
cvsdist a8bb5f
  "Interpret given string as `arch-vendor-os'.
cvsdist a8bb5f
Set the macros _target, _target_arch and _target_os accordingly"
cvsdist a8bb5f
  :type 'string
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist d31aa3
(define-obsolete-variable-alias
cvsdist d31aa3
  'rpm-completion-ignore-case 'rpm-spec-completion-ignore-case)
cvsdist d31aa3
cvsdist d31aa3
(defcustom rpm-spec-completion-ignore-case t
cvsdist 98a749
  "*Non-nil means that case differences are ignored during completion.
cvsdist 98a749
A value of nil means that case is significant.
cvsdist 98a749
This is used during Tempo template completion."
cvsdist 98a749
  :type 'boolean
cvsdist 98a749
  :group 'rpm-spec)
cvsdist 98a749
cvsdist a8bb5f
(defcustom rpm-spec-clean nil
cvsdist a8bb5f
  "Remove the build tree after the packages are made."
cvsdist a8bb5f
  :type 'boolean
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist a8bb5f
(defcustom rpm-spec-rmsource nil
cvsdist a8bb5f
  "Remove the source and spec file after the packages are made."
cvsdist a8bb5f
  :type 'boolean
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist 45b61e
(define-obsolete-variable-alias
cvsdist 45b61e
  'rpm-spec-test 'rpm-spec-nobuild)
cvsdist 45b61e
cvsdist d31aa3
(defcustom rpm-spec-nobuild nil
cvsdist a8bb5f
  "Do not execute any build stages.  Useful for testing out spec files."
cvsdist a8bb5f
  :type 'boolean
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist 45b61e
(defcustom rpm-spec-quiet nil
cvsdist 45b61e
  "Print as little as possible.
cvsdist 45b61e
Normally only error messages will be displayed."
cvsdist 45b61e
  :type 'boolean
cvsdist 45b61e
  :group 'rpm-spec)
cvsdist 45b61e
cvsdist a8bb5f
(defcustom rpm-spec-sign-gpg nil
cvsdist a8bb5f
  "Embed a GPG signature in the package.
cvsdist a8bb5f
This signature can be used to verify the integrity and the origin of
cvsdist a8bb5f
the package."
cvsdist a8bb5f
  :type 'boolean
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist d31aa3
(defcustom rpm-spec-nodeps nil
cvsdist d31aa3
  "Do not verify build dependencies."
cvsdist d31aa3
  :type 'boolean
cvsdist d31aa3
  :group 'rpm-spec)
cvsdist d31aa3
cvsdist d31aa3
(define-obsolete-variable-alias
cvsdist d31aa3
  'rpm-initialize-sections 'rpm-spec-initialize-sections)
cvsdist d31aa3
cvsdist d31aa3
(defcustom rpm-spec-initialize-sections t
cvsdist a8bb5f
  "Automatically add empty section headings to new spec files."
cvsdist a8bb5f
  :type 'boolean
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist d31aa3
(define-obsolete-variable-alias
cvsdist d31aa3
  'rpm-insert-version 'rpm-spec-insert-changelog-version)
cvsdist d31aa3
cvsdist d31aa3
(defcustom rpm-spec-insert-changelog-version t
cvsdist d31aa3
  "Automatically add version in a new change log entry."
cvsdist a8bb5f
  :type 'boolean
cvsdist a8bb5f
  :group 'rpm-spec)
cvsdist a8bb5f
cvsdist d31aa3
(defcustom rpm-spec-user-full-name nil
cvsdist d31aa3
  "*Full name of the user.
cvsdist d31aa3
This is used in the change log and the Packager tag.  It defaults to the
cvsdist d31aa3
value returned by function `user-full-name'."
cvsdist d31aa3
  :type '(choice (const :tag "Use `user-full-name'" nil)
cvsdist d31aa3
                 string)
cvsdist d31aa3
  :group 'rpm-spec)
cvsdist d31aa3
cvsdist d31aa3
(defcustom rpm-spec-user-mail-address nil
cvsdist d31aa3
  "*Email address of the user.
cvsdist d31aa3
This is used in the change log and the Packager tag.  It defaults to the
cvsdist d31aa3
value returned by function `user-mail-address'."
cvsdist d31aa3
  :type '(choice (const :tag "Use `user-mail-address'" nil)
cvsdist d31aa3
                 string)
cvsdist d31aa3
  :group 'rpm-spec)
cvsdist d31aa3
cvsdist 45b61e
(defcustom rpm-spec-indent-heading-values nil
cvsdist 45b61e
  "*Indent values for all tags in the \"heading\" of the spec file."
cvsdist 45b61e
  :type 'boolean
cvsdist 45b61e
  :group 'rpm-spec)
cvsdist 45b61e
cvsdist 45b61e
(defcustom rpm-spec-use-compilation-mode t
cvsdist 45b61e
  "*If non-nil, build in `compilation-mode' if it's available."
cvsdist 45b61e
  :type 'boolean
cvsdist 45b61e
  :group 'rpm-spec)
cvsdist 45b61e
cvsdist 45b61e
(defcustom rpm-spec-default-release "1"
cvsdist 45b61e
  "*Default value for the Release tag in new spec files."
cvsdist 45b61e
  :type 'string
cvsdist 45b61e
  :group 'rpm-spec)
cvsdist 45b61e
cvsdist 45b61e
(defcustom rpm-spec-default-epoch nil
cvsdist 45b61e
  "*If non-nil, default value for the Epoch tag in new spec files."
cvsdist 45b61e
  :type '(choice (const :tag "No Epoch" nil) integer)
cvsdist 45b61e
  :group 'rpm-spec)
cvsdist 45b61e
cvsdist 45b61e
(defcustom rpm-spec-default-buildroot
cvsdist 45b61e
  "%{_tmppath}/%{name}-%{version}-%{release}-root"
cvsdist 45b61e
  "*Default value for the BuildRoot tag in new spec files."
cvsdist 45b61e
  :type 'integer
cvsdist 45b61e
  :group 'rpm-spec)
cvsdist 45b61e
cvsdist 45b61e
(defcustom rpm-spec-default-build-section ""
cvsdist 45b61e
  "*Default %build section in new spec files."
cvsdist 45b61e
  :type 'string
cvsdist 45b61e
  :group 'rpm-spec)
cvsdist 45b61e
cvsdist 45b61e
(defcustom rpm-spec-default-install-section "rm -rf $RPM_BUILD_ROOT\n"
cvsdist 45b61e
  "*Default %install section in new spec files."
cvsdist 45b61e
  :type 'string
cvsdist 45b61e
  :group 'rpm-spec)
cvsdist 45b61e
cvsdist 45b61e
(defcustom rpm-spec-default-clean-section "rm -rf $RPM_BUILD_ROOT\n"
cvsdist 45b61e
  "*Default %clean section in new spec files."
cvsdist 45b61e
  :type 'string
cvsdist 45b61e
  :group 'rpm-spec)
cvsdist 45b61e
cvsdist a8bb5f
(defgroup rpm-spec-faces nil
cvsdist d31aa3
  "Font lock faces for `rpm-spec-mode'."
cvsdist 45b61e
  :prefix "rpm-spec-"
cvsdist a8bb5f
  :group 'rpm-spec
cvsdist a8bb5f
  :group 'faces)
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
;; variables used by navigation functions.
cvsdist a8bb5f
cvsdist d31aa3
(defconst rpm-sections
cvsdist 45b61e
  '("preamble" "description" "prep" "setup" "build" "install" "check" "clean"
cvsdist a8bb5f
    "changelog" "files")
cvsdist a8bb5f
  "Partial list of section names.")
cvsdist a8bb5f
(defvar rpm-section-list
cvsdist a8bb5f
  '(("preamble") ("description") ("prep") ("setup") ("build") ("install")
cvsdist 45b61e
    ("check") ("clean") ("changelog") ("files"))
cvsdist a8bb5f
  "Partial list of section names.")
cvsdist d31aa3
(defconst rpm-scripts
cvsdist d31aa3
  '("pre" "post" "preun" "postun"
Charles Coldwell 40eeb8
    "trigger" "triggerin" "triggerprein" "triggerun" "triggerpostun"
Charles Coldwell 40eeb8
    "pretrans" "posttrans")
cvsdist d31aa3
  "List of rpm scripts.")
cvsdist a8bb5f
(defconst rpm-section-seperate "^%\\(\\w+\\)\\s-")
cvsdist d31aa3
(defconst rpm-section-regexp
cvsdist d31aa3
  (eval-when-compile
cvsdist d31aa3
    (concat "^%"
cvsdist d31aa3
            (regexp-opt
Charles Coldwell 40eeb8
             ;; From RPM 4.4.9 sources, file build/parseSpec.c: partList[].
cvsdist 45b61e
             '("build" "changelog" "check" "clean" "description" "files"
Jens Petersen 4c3846
               "install" "package" "post" "postun" "pretrans" "posttrans"
Jens Petersen 4c3846
               "pre" "prep" "preun" "trigger" "triggerin" "triggerpostun"
Charles Coldwell 40eeb8
               "triggerprein" "triggerun" "verifyscript") t)
cvsdist d31aa3
            "\\b"))
cvsdist a8bb5f
  "Regular expression to match beginning of a section.")
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist a8bb5f
(defface rpm-spec-tag-face
cvsdist 45b61e
  '(( ((class color) (background light)) (:foreground "blue3") )
cvsdist d31aa3
    ( ((class color) (background dark)) (:foreground "blue") ))
cvsdist 45b61e
  "*Face for tags."
cvsdist a8bb5f
  :group 'rpm-spec-faces)
cvsdist a8bb5f
Charles Coldwell 40eeb8
(defface rpm-spec-obsolete-tag-face
Charles Coldwell 40eeb8
  '(( ((class color)) (:foreground "white" :background "red") ))
Charles Coldwell 40eeb8
  "*Face for obsolete tags."
Charles Coldwell 40eeb8
  :group 'rpm-spec-faces)
Charles Coldwell 40eeb8
cvsdist a8bb5f
(defface rpm-spec-macro-face
cvsdist d31aa3
  '(( ((class color) (background light)) (:foreground "purple") )
cvsdist d31aa3
    ( ((class color) (background dark)) (:foreground "yellow") ))
cvsdist 45b61e
  "*Face for RPM macros and variables."
cvsdist a8bb5f
  :group 'rpm-spec-faces)
cvsdist a8bb5f
cvsdist d31aa3
(defface rpm-spec-var-face
cvsdist d31aa3
  '(( ((class color) (background light)) (:foreground "maroon") )
cvsdist d31aa3
    ( ((class color) (background dark)) (:foreground "maroon") ))
cvsdist 45b61e
  "*Face for environment variables."
cvsdist d31aa3
  :group 'rpm-spec-faces)
cvsdist d31aa3
cvsdist a8bb5f
(defface rpm-spec-doc-face
cvsdist 45b61e
  '(( ((class color) (background light)) (:foreground "magenta3") )
cvsdist d31aa3
    ( ((class color) (background dark)) (:foreground "magenta") ))
cvsdist 45b61e
  "*Face for %doc entries in %files."
cvsdist a8bb5f
  :group 'rpm-spec-faces)
cvsdist a8bb5f
cvsdist a8bb5f
(defface rpm-spec-dir-face
cvsdist 45b61e
  '(( ((class color) (background light)) (:foreground "green4") )
cvsdist d31aa3
    ( ((class color) (background dark)) (:foreground "green") ))
cvsdist 45b61e
  "*Face for %dir entries in %files."
cvsdist a8bb5f
  :group 'rpm-spec-faces)
cvsdist a8bb5f
cvsdist a8bb5f
(defface rpm-spec-package-face
cvsdist 45b61e
  '(( ((class color) (background light)) (:foreground "red3") )
cvsdist d31aa3
    ( ((class color) (background dark)) (:foreground "red") ))
cvsdist 45b61e
  "*Face for package tag."
cvsdist a8bb5f
  :group 'rpm-spec-faces)
cvsdist a8bb5f
cvsdist a8bb5f
(defface rpm-spec-ghost-face
cvsdist 45b61e
  '(( ((class color) (background light)) (:foreground "gray50") )
cvsdist d31aa3
    ( ((class color) (background dark)) (:foreground "red") ))
cvsdist 45b61e
  "*Face for %ghost and %config entries in %files."
cvsdist 45b61e
  :group 'rpm-spec-faces)
cvsdist 45b61e
cvsdist 45b61e
(defface rpm-spec-section-face
cvsdist 45b61e
  '(( ((class color) (background light)) (:foreground "purple" :underline t) )
cvsdist 45b61e
    ( ((class color) (background dark)) (:foreground "yellow" :underline t) ))
cvsdist 45b61e
  "*Face for section markers."
cvsdist a8bb5f
  :group 'rpm-spec-faces)
cvsdist a8bb5f
cvsdist a8bb5f
;;; GNU emacs font-lock needs these...
cvsdist d31aa3
(defvar rpm-spec-macro-face
cvsdist 45b61e
  'rpm-spec-macro-face "*Face for RPM macros and variables.")
cvsdist d31aa3
(defvar rpm-spec-var-face
cvsdist d31aa3
  'rpm-spec-var-face "*Face for environment variables.")
cvsdist d31aa3
(defvar rpm-spec-tag-face
cvsdist d31aa3
  'rpm-spec-tag-face "*Face for tags.")
Charles Coldwell 40eeb8
(defvar rpm-spec-obsolete-tag-face
Charles Coldwell 40eeb8
  'rpm-spec-tag-face "*Face for obsolete tags.")
cvsdist d31aa3
(defvar rpm-spec-package-face
cvsdist d31aa3
  'rpm-spec-package-face "*Face for package tag.")
cvsdist d31aa3
(defvar rpm-spec-dir-face
cvsdist 45b61e
  'rpm-spec-dir-face "*Face for %dir entries in %files.")
cvsdist d31aa3
(defvar rpm-spec-doc-face
cvsdist 45b61e
  'rpm-spec-doc-face "*Face for %doc entries in %files.")
cvsdist d31aa3
(defvar rpm-spec-ghost-face
cvsdist 45b61e
  'rpm-spec-ghost-face "*Face for %ghost and %config entries in %files.")
cvsdist 45b61e
(defvar rpm-spec-section-face
cvsdist 45b61e
  'rpm-spec-section-face "*Face for section markers.")
cvsdist a8bb5f
cvsdist a8bb5f
(defvar rpm-default-umask "-"
cvsdist d31aa3
  "*Default umask for files, specified with \"%attr\".")
cvsdist d31aa3
(defvar rpm-default-owner "root"
cvsdist d31aa3
  "*Default owner for files, specified with \"%attr\".")
cvsdist d31aa3
(defvar rpm-default-group "root"
cvsdist d31aa3
  "*Default group for files, specified with \"%attr\".")
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist a8bb5f
(defvar rpm-no-gpg nil "Tell rpm not to sign package.")
cvsdist 45b61e
(defvar rpm-spec-nobuild-option "--nobuild" "Option for no build.")
cvsdist a8bb5f
cvsdist a8bb5f
(defvar rpm-tags-list
Charles Coldwell 40eeb8
  ;; From RPM 4.4.9 sources, file build/parsePreamble.c: preambleList[], and
Jens Petersen 4c3846
  ;; a few macros that aren't tags, but useful here.
cvsdist d31aa3
  '(("AutoProv")
cvsdist d31aa3
    ("AutoReq")
cvsdist d31aa3
    ("AutoReqProv")
cvsdist d31aa3
    ("BuildArch")
cvsdist d31aa3
    ("BuildArchitectures")
cvsdist d31aa3
    ("BuildConflicts")
Charles Coldwell 40eeb8
    ("BuildEnhances")
Charles Coldwell 40eeb8
    ("BuildPlatforms")
cvsdist d31aa3
    ("BuildPreReq")
cvsdist d31aa3
    ("BuildRequires")
cvsdist d31aa3
    ("BuildRoot")
Charles Coldwell 40eeb8
    ("BuildSuggests")
cvsdist a8bb5f
    ("Conflicts")
Charles Coldwell 40eeb8
    ("CVSId")
cvsdist a8bb5f
    ("%description")
cvsdist a8bb5f
    ("Distribution")
Jens Petersen 4c3846
    ("DistTag")
cvsdist d31aa3
    ("DistURL")
cvsdist d31aa3
    ("DocDir")
Charles Coldwell 40eeb8
    ("Enhances")
cvsdist d31aa3
    ("Epoch")
cvsdist d31aa3
    ("ExcludeArch")
cvsdist d31aa3
    ("ExcludeOS")
cvsdist d31aa3
    ("ExclusiveArch")
cvsdist d31aa3
    ("ExclusiveOS")
cvsdist a8bb5f
    ("%files")
cvsdist a8bb5f
    ("Group")
cvsdist a8bb5f
    ("Icon")
cvsdist a8bb5f
    ("%ifarch")
Charles Coldwell 40eeb8
    ("Keyword")
Charles Coldwell 40eeb8
    ("Keywords")
cvsdist d31aa3
    ("License")
cvsdist a8bb5f
    ("Name")
cvsdist d31aa3
    ("NoPatch")
cvsdist d31aa3
    ("NoSource")
cvsdist d31aa3
    ("Obsoletes")
cvsdist a8bb5f
    ("%package")
cvsdist a8bb5f
    ("Packager")
cvsdist a8bb5f
    ("Patch")
cvsdist a8bb5f
    ("Prefix")
cvsdist d31aa3
    ("Prefixes")
cvsdist d31aa3
    ("PreReq")
cvsdist a8bb5f
    ("Provides")
cvsdist a8bb5f
    ("Release")
cvsdist a8bb5f
    ("Requires")
Charles Coldwell 40eeb8
    ("RepoTag")
cvsdist a8bb5f
    ("Source")
Charles Coldwell 40eeb8
    ("Suggests")
cvsdist a8bb5f
    ("Summary")
Charles Coldwell 40eeb8
    ("SVNId")
cvsdist d31aa3
    ("URL")
Charles Coldwell 40eeb8
    ("Variant")
Charles Coldwell 40eeb8
    ("Variants")
cvsdist a8bb5f
    ("Vendor")
Charles Coldwell 40eeb8
    ("Version")
Charles Coldwell 40eeb8
    ("XMajor")
Charles Coldwell 40eeb8
    ("XMinor")
Charles Coldwell 40eeb8
    )
cvsdist d31aa3
  "List of elements that are valid tags.")
cvsdist a8bb5f
Charles Coldwell 40eeb8
(defvar rpm-tags-regexp
Charles Coldwell 40eeb8
  (concat "\\(\\<" (regexp-opt (mapcar 'car rpm-tags-list))
Charles Coldwell 40eeb8
	  "\\|\\(Patch\\|Source\\)[0-9]+\\>\\)")
Charles Coldwell 40eeb8
  "Regular expression for matching valid tags.")
Charles Coldwell 40eeb8
Charles Coldwell 40eeb8
(defvar rpm-obsolete-tags-list
Charles Coldwell 40eeb8
  ;; From RPM sources, file build/parsePreamble.c: preambleList[].
Charles Coldwell 40eeb8
  '(("Copyright")    ;; 4.4.2
Charles Coldwell 40eeb8
    ("RHNPlatform")  ;; 4.4.2, 4.4.9
Charles Coldwell 40eeb8
    ("Serial")       ;; 4.4.2, 4.4.9
Charles Coldwell 40eeb8
    )
Charles Coldwell 40eeb8
  "List of elements that are obsolete tags in some versions of rpm.")
Charles Coldwell 40eeb8
Charles Coldwell 40eeb8
(defvar rpm-obsolete-tags-regexp
Charles Coldwell 40eeb8
  (regexp-opt (mapcar 'car rpm-obsolete-tags-list) 'words)
Charles Coldwell 40eeb8
  "Regular expression for matching obsolete tags.")
Charles Coldwell 40eeb8
cvsdist a8bb5f
(defvar rpm-group-tags-list
Charles Coldwell 40eeb8
  ;; From RPM 4.4.9 sources, file GROUPS.
cvsdist a8bb5f
  '(("Amusements/Games")
cvsdist a8bb5f
    ("Amusements/Graphics")
cvsdist a8bb5f
    ("Applications/Archiving")
cvsdist a8bb5f
    ("Applications/Communications")
cvsdist a8bb5f
    ("Applications/Databases")
cvsdist a8bb5f
    ("Applications/Editors")
cvsdist a8bb5f
    ("Applications/Emulators")
cvsdist a8bb5f
    ("Applications/Engineering")
cvsdist a8bb5f
    ("Applications/File")
cvsdist a8bb5f
    ("Applications/Internet")
cvsdist a8bb5f
    ("Applications/Multimedia")
cvsdist a8bb5f
    ("Applications/Productivity")
cvsdist a8bb5f
    ("Applications/Publishing")
cvsdist a8bb5f
    ("Applications/System")
cvsdist a8bb5f
    ("Applications/Text")
cvsdist a8bb5f
    ("Development/Debuggers")
cvsdist a8bb5f
    ("Development/Languages")
cvsdist a8bb5f
    ("Development/Libraries")
cvsdist a8bb5f
    ("Development/System")
cvsdist a8bb5f
    ("Development/Tools")
cvsdist a8bb5f
    ("Documentation")
cvsdist a8bb5f
    ("System Environment/Base")
cvsdist a8bb5f
    ("System Environment/Daemons")
cvsdist a8bb5f
    ("System Environment/Kernel")
cvsdist a8bb5f
    ("System Environment/Libraries")
cvsdist a8bb5f
    ("System Environment/Shells")
cvsdist a8bb5f
    ("User Interface/Desktops")
cvsdist a8bb5f
    ("User Interface/X")
cvsdist a8bb5f
    ("User Interface/X Hardware Support")
cvsdist a8bb5f
    )
cvsdist d31aa3
  "List of elements that are valid group tags.")
cvsdist a8bb5f
cvsdist a8bb5f
(defvar rpm-spec-mode-syntax-table nil
cvsdist d31aa3
  "Syntax table in use in `rpm-spec-mode' buffers.")
cvsdist a8bb5f
(unless rpm-spec-mode-syntax-table
cvsdist a8bb5f
  (setq rpm-spec-mode-syntax-table (make-syntax-table))
cvsdist a8bb5f
  (modify-syntax-entry ?\\ "\\" rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?\n ">   " rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?\f ">   " rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?\# "<   " rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?/ "." rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?* "." rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?+ "." rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?- "." rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?= "." rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?% "_" rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?< "." rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?> "." rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?& "." rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?| "." rpm-spec-mode-syntax-table)
cvsdist a8bb5f
  (modify-syntax-entry ?\' "." rpm-spec-mode-syntax-table))
cvsdist a8bb5f
cvsdist a8bb5f
(defvar rpm-spec-mode-map nil
cvsdist d31aa3
  "Keymap used in `rpm-spec-mode'.")
cvsdist a8bb5f
(unless rpm-spec-mode-map
cvsdist a8bb5f
  (setq rpm-spec-mode-map (make-sparse-keymap))
cvsdist a8bb5f
  (and (functionp 'set-keymap-name)
cvsdist a8bb5f
       (set-keymap-name rpm-spec-mode-map 'rpm-spec-mode-map))
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-c"  'rpm-change-tag)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-e"  'rpm-add-change-log-entry)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-i"  'rpm-insert-tag)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-n"  'rpm-forward-section)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-o"  'rpm-goto-section)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-p"  'rpm-backward-section)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-r"  'rpm-increase-release-tag)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-u"  'rpm-insert-true-prefix)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-ba" 'rpm-build-all)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-bb" 'rpm-build-binary)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-bc" 'rpm-build-compile)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-bi" 'rpm-build-install)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-bl" 'rpm-list-check)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-bp" 'rpm-build-prepare)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-bs" 'rpm-build-source)
cvsdist a8bb5f
  (define-key rpm-spec-mode-map "\C-c\C-dd" 'rpm-insert-dir)
cvsdist a8bb5f
  (define-key rpm-spec-mode-map "\C-c\C-do" 'rpm-insert-docdir)
cvsdist a8bb5f
  (define-key rpm-spec-mode-map "\C-c\C-fc" 'rpm-insert-config)
cvsdist a8bb5f
  (define-key rpm-spec-mode-map "\C-c\C-fd" 'rpm-insert-doc)
cvsdist a8bb5f
  (define-key rpm-spec-mode-map "\C-c\C-ff" 'rpm-insert-file)
cvsdist a8bb5f
  (define-key rpm-spec-mode-map "\C-c\C-fg" 'rpm-insert-ghost)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xa" 'rpm-toggle-add-attr)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xb" 'rpm-change-buildroot-option)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xc" 'rpm-toggle-clean)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xd" 'rpm-toggle-nodeps)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xf" 'rpm-files-group)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xg" 'rpm-toggle-sign-gpg)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xi" 'rpm-change-timecheck-option)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xn" 'rpm-toggle-nobuild)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xo" 'rpm-files-owner)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xr" 'rpm-toggle-rmsource)
cvsdist 45b61e
  (define-key rpm-spec-mode-map "\C-c\C-xq" 'rpm-toggle-quiet)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xs" 'rpm-toggle-short-circuit)
cvsdist 45b61e
  (define-key rpm-spec-mode-map "\C-c\C-xt" 'rpm-change-target-option)
cvsdist d31aa3
  (define-key rpm-spec-mode-map "\C-c\C-xu" 'rpm-files-umask)
cvsdist d31aa3
  ;;(define-key rpm-spec-mode-map "\C-q" 'indent-spec-exp)
cvsdist d31aa3
  ;;(define-key rpm-spec-mode-map "\t" 'sh-indent-line)
cvsdist a8bb5f
  )
cvsdist a8bb5f
cvsdist a8bb5f
(defconst rpm-spec-mode-menu
cvsdist d31aa3
  (purecopy '("RPM spec"
cvsdist d31aa3
              ["Insert Tag..."           rpm-insert-tag                t]
cvsdist d31aa3
              ["Change Tag..."           rpm-change-tag                t]
cvsdist d31aa3
              "---"
cvsdist d31aa3
              ["Go to section..."        rpm-mouse-goto-section  :keys "C-c C-o"]
cvsdist d31aa3
              ["Forward section"         rpm-forward-section           t]
cvsdist d31aa3
              ["Backward section"        rpm-backward-section          t]
cvsdist d31aa3
              "---"
cvsdist d31aa3
              ["Add change log entry..." rpm-add-change-log-entry      t]
cvsdist d31aa3
              ["Increase release tag"    rpm-increase-release-tag      t]
cvsdist d31aa3
              "---"
cvsdist d31aa3
              ("Add file entry"
cvsdist d31aa3
               ["Regular file..."        rpm-insert-file               t]
cvsdist d31aa3
               ["Config file..."         rpm-insert-config             t]
cvsdist d31aa3
               ["Document file..."       rpm-insert-doc                t]
cvsdist d31aa3
               ["Ghost file..."          rpm-insert-ghost              t]
cvsdist d31aa3
               "---"
cvsdist d31aa3
               ["Directory..."           rpm-insert-dir                t]
cvsdist d31aa3
               ["Document directory..."  rpm-insert-docdir             t]
cvsdist d31aa3
               "---"
cvsdist d31aa3
               ["Insert %{prefix}"       rpm-insert-true-prefix        t]
cvsdist d31aa3
               "---"
cvsdist d31aa3
               ["Default add \"%attr\" entry" rpm-toggle-add-attr
cvsdist d31aa3
                :style toggle :selected rpm-spec-add-attr]
cvsdist d31aa3
               ["Change default umask for files..."  rpm-files-umask   t]
cvsdist d31aa3
               ["Change default owner for files..."  rpm-files-owner   t]
cvsdist d31aa3
               ["Change default group for files..."  rpm-files-group   t])
cvsdist d31aa3
              ("Build Options"
cvsdist d31aa3
               ["Short circuit" rpm-toggle-short-circuit
cvsdist d31aa3
                :style toggle :selected rpm-spec-short-circuit]
cvsdist d31aa3
               ["Remove source" rpm-toggle-rmsource
cvsdist d31aa3
                :style toggle :selected rpm-spec-rmsource]
cvsdist d31aa3
               ["Clean"         rpm-toggle-clean
cvsdist d31aa3
                :style toggle :selected rpm-spec-clean]
cvsdist d31aa3
               ["No build"      rpm-toggle-nobuild
cvsdist d31aa3
                :style toggle :selected rpm-spec-nobuild]
cvsdist 45b61e
               ["Quiet"         rpm-toggle-quiet
cvsdist 45b61e
                :style toggle :selected rpm-spec-quiet]
cvsdist d31aa3
               ["GPG sign"      rpm-toggle-sign-gpg
cvsdist d31aa3
                :style toggle :selected rpm-spec-sign-gpg]
cvsdist d31aa3
               ["Ignore dependencies" rpm-toggle-nodeps
cvsdist d31aa3
                :style toggle :selected rpm-spec-nodeps]
cvsdist d31aa3
               "---"
cvsdist d31aa3
               ["Change timecheck value..."  rpm-change-timecheck-option   t]
cvsdist d31aa3
               ["Change buildroot value..."  rpm-change-buildroot-option   t]
cvsdist d31aa3
               ["Change target value..."     rpm-change-target-option      t])
cvsdist d31aa3
              ("RPM Build"
cvsdist d31aa3
               ["Execute \"%prep\" stage"    rpm-build-prepare             t]
cvsdist d31aa3
               ["Do a \"list check\""        rpm-list-check                t]
cvsdist d31aa3
               ["Do the \"%build\" stage"    rpm-build-compile             t]
cvsdist d31aa3
               ["Do the \"%install\" stage"  rpm-build-install             t]
cvsdist d31aa3
               "---"
cvsdist d31aa3
               ["Build binary package"       rpm-build-binary              t]
cvsdist d31aa3
               ["Build source package"       rpm-build-source              t]
cvsdist d31aa3
               ["Build binary and source"    rpm-build-all                 t])
cvsdist d31aa3
              "---"
cvsdist d31aa3
              ["About rpm-spec-mode"         rpm-about-rpm-spec-mode       t]
cvsdist d31aa3
              )))
cvsdist a8bb5f
cvsdist a8bb5f
(defvar rpm-spec-font-lock-keywords
cvsdist 45b61e
  (list
cvsdist 45b61e
   (cons rpm-section-regexp rpm-spec-section-face)
cvsdist 45b61e
   '("%[a-zA-Z0-9_]+" 0 rpm-spec-macro-face)
Charles Coldwell 40eeb8
   (cons (concat "^" rpm-obsolete-tags-regexp "\\(\([a-zA-Z0-9,_]+\)\\)[ \t]*:")
Charles Coldwell 40eeb8
         '((1 'rpm-spec-obsolete-tag-face)
Charles Coldwell 40eeb8
           (2 'rpm-spec-ghost-face)))
Charles Coldwell 40eeb8
   (cons (concat "^" rpm-tags-regexp "\\(\([a-zA-Z0-9,_]+\)\\)[ \t]*:")
Charles Coldwell 40eeb8
         '((1 'rpm-spec-tag-face)
Charles Coldwell 40eeb8
           (3 'rpm-spec-ghost-face)))
Charles Coldwell 40eeb8
   (cons (concat "^" rpm-obsolete-tags-regexp "[ \t]*:")
Charles Coldwell 40eeb8
         '(1 'rpm-spec-obsolete-tag-face))
Charles Coldwell 40eeb8
   (cons (concat "^" rpm-tags-regexp "[ \t]*:")
Charles Coldwell 40eeb8
         '(1 'rpm-spec-tag-face))
Charles Coldwell 40eeb8
   '("%\\(de\\(fine\\|scription\\)\\|files\\|global\\|package\\)[ \t]+\\([^-][^ \t\n]*\\)"
cvsdist d31aa3
     (3 rpm-spec-package-face))
cvsdist 45b61e
   '("%p\\(ost\\|re\\)\\(un\\)?[ \t]+\\([^-][^ \t\n]*\\)"
cvsdist d31aa3
     (3 rpm-spec-package-face))
cvsdist 45b61e
   '("%configure " 0 rpm-spec-macro-face)
cvsdist 45b61e
   '("%dir[ \t]+\\([^ \t\n]+\\)[ \t]*" 1 rpm-spec-dir-face)
cvsdist 45b61e
   '("%doc\\(dir\\)?[ \t]+\\(.*\\)\n" 2 rpm-spec-doc-face)
cvsdist 45b61e
   '("%\\(ghost\\|config\\([ \t]*(.*)\\)?\\)[ \t]+\\(.*\\)\n"
cvsdist 45b61e
     3 rpm-spec-ghost-face)
cvsdist 45b61e
   '("^%.+-[a-zA-Z][ \t]+\\([a-zA-Z0-9\.-]+\\)" 1 rpm-spec-doc-face)
cvsdist 45b61e
   '("^\\(.+\\)(\\([a-zA-Z]\\{2,2\\}\\)):"
cvsdist a8bb5f
     (1 rpm-spec-tag-face)
cvsdist a8bb5f
     (2 rpm-spec-doc-face))
cvsdist 45b61e
   '("^\\*\\(.*[0-9] \\)\\(.*\\)<\\(.*\\)>\\(.*\\)\n"
cvsdist a8bb5f
     (1 rpm-spec-dir-face)
cvsdist a8bb5f
     (2 rpm-spec-package-face)
cvsdist a8bb5f
     (3 rpm-spec-tag-face)
cvsdist 45b61e
     (4 rpm-spec-ghost-face))
cvsdist 45b61e
   '("%{[^{}]*}" 0 rpm-spec-macro-face)
cvsdist 45b61e
   '("$[a-zA-Z0-9_]+" 0 rpm-spec-var-face)
cvsdist 45b61e
   '("${[a-zA-Z0-9_]+}" 0 rpm-spec-var-face)
cvsdist 45b61e
   )
cvsdist d31aa3
  "Additional expressions to highlight in `rpm-spec-mode'.")
cvsdist a8bb5f
cvsdist a8bb5f
;;Initialize font lock for xemacs
cvsdist a8bb5f
(put 'rpm-spec-mode 'font-lock-defaults '(rpm-spec-font-lock-keywords))
cvsdist a8bb5f
cvsdist a8bb5f
(defvar rpm-spec-mode-abbrev-table nil
cvsdist d31aa3
  "Abbrev table in use in `rpm-spec-mode' buffers.")
cvsdist a8bb5f
(define-abbrev-table 'rpm-spec-mode-abbrev-table ())
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist 45b61e
(add-hook 'rpm-spec-mode-new-file-hook 'rpm-spec-initialize)
cvsdist 45b61e
cvsdist a8bb5f
;;;###autoload
cvsdist a8bb5f
(defun rpm-spec-mode ()
cvsdist d31aa3
  "Major mode for editing RPM spec files.
cvsdist a8bb5f
This is much like C mode except for the syntax of comments.  It uses
cvsdist a8bb5f
the same keymap as C mode and has the same variables for customizing
cvsdist a8bb5f
indentation.  It has its own abbrev table and its own syntax table.
cvsdist a8bb5f
cvsdist d31aa3
Turning on RPM spec mode calls the value of the variable `rpm-spec-mode-hook'
cvsdist a8bb5f
with no args, if that value is non-nil."
cvsdist a8bb5f
  (interactive)
cvsdist a8bb5f
  (kill-all-local-variables)
cvsdist a8bb5f
  (condition-case nil
cvsdist a8bb5f
      (require 'shindent)
cvsdist a8bb5f
    (error
cvsdist a8bb5f
     (require 'sh-script)))
cvsdist a8bb5f
  (require 'cc-mode)
cvsdist a8bb5f
  (use-local-map rpm-spec-mode-map)
cvsdist a8bb5f
  (setq major-mode 'rpm-spec-mode)
cvsdist d31aa3
  (rpm-update-mode-name)
cvsdist a8bb5f
  (setq local-abbrev-table rpm-spec-mode-abbrev-table)
cvsdist a8bb5f
  (set-syntax-table rpm-spec-mode-syntax-table)
cvsdist a8bb5f
cvsdist a8bb5f
  (require 'easymenu)
cvsdist d31aa3
  (easy-menu-define rpm-spec-call-menu rpm-spec-mode-map
cvsdist d31aa3
                    "Post menu for `rpm-spec-mode'." rpm-spec-mode-menu)
cvsdist a8bb5f
  (easy-menu-add rpm-spec-mode-menu)
cvsdist a8bb5f
cvsdist 45b61e
  (if (and (= (buffer-size) 0) rpm-spec-initialize-sections)
cvsdist 45b61e
      (run-hooks 'rpm-spec-mode-new-file-hook))
cvsdist a8bb5f
cvsdist 45b61e
  (if (not (executable-find "rpmbuild"))
cvsdist 45b61e
      (progn
cvsdist 45b61e
	(setq rpm-spec-build-command "rpm")
cvsdist 45b61e
	(setq rpm-spec-nobuild-option "--test")))
cvsdist d31aa3
  
cvsdist a8bb5f
  (make-local-variable 'paragraph-start)
cvsdist a8bb5f
  (setq paragraph-start (concat "$\\|" page-delimiter))
cvsdist a8bb5f
  (make-local-variable 'paragraph-separate)
cvsdist a8bb5f
  (setq paragraph-separate paragraph-start)
cvsdist a8bb5f
  (make-local-variable 'paragraph-ignore-fill-prefix)
cvsdist a8bb5f
  (setq paragraph-ignore-fill-prefix t)
cvsdist a8bb5f
;  (make-local-variable 'indent-line-function)
cvsdist a8bb5f
;  (setq indent-line-function 'c-indent-line)
cvsdist a8bb5f
  (make-local-variable 'require-final-newline)
cvsdist a8bb5f
  (setq require-final-newline t)
cvsdist a8bb5f
  (make-local-variable 'comment-start)
cvsdist a8bb5f
  (setq comment-start "# ")
cvsdist a8bb5f
  (make-local-variable 'comment-end)
cvsdist a8bb5f
  (setq comment-end "")
cvsdist a8bb5f
  (make-local-variable 'comment-column)
cvsdist a8bb5f
  (setq comment-column 32)
cvsdist a8bb5f
  (make-local-variable 'comment-start-skip)
cvsdist a8bb5f
  (setq comment-start-skip "#+ *")
cvsdist a8bb5f
;  (make-local-variable 'comment-indent-function)
cvsdist a8bb5f
;  (setq comment-indent-function 'c-comment-indent)
cvsdist a8bb5f
  ;;Initialize font lock for GNU emacs.
cvsdist a8bb5f
  (make-local-variable 'font-lock-defaults)
cvsdist a8bb5f
  (setq font-lock-defaults '(rpm-spec-font-lock-keywords nil t))
cvsdist a8bb5f
  (run-hooks 'rpm-spec-mode-hook))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-command-filter (process string)
cvsdist a8bb5f
  "Filter to process normal output."
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (set-buffer (process-buffer process))
cvsdist a8bb5f
    (save-excursion
cvsdist a8bb5f
      (goto-char (process-mark process))
cvsdist a8bb5f
      (insert-before-markers string)
cvsdist a8bb5f
      (set-marker (process-mark process) (point)))))
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-add-change-log-entry (&optional change-log-entry)
cvsdist a8bb5f
  "Find change log and add an entry for today."
cvsdist d31aa3
  (interactive "sChange log entry: ")
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (rpm-goto-section "changelog")
Charles Coldwell 3525a1
    (let* ((address (rpm-spec-user-mail-address))
cvsdist d31aa3
           (fullname (or rpm-spec-user-full-name (user-full-name)))
cvsdist d31aa3
           (string (concat "* " (substring (current-time-string) 0 11)
cvsdist d31aa3
                           (substring (current-time-string) -4) " "
cvsdist d31aa3
                           fullname " <" address ">"
cvsdist d31aa3
                           (and rpm-spec-insert-changelog-version
cvsdist 45b61e
                                (concat " - " (rpm-find-spec-version t))))))
cvsdist a8bb5f
      (if (not (search-forward string nil t))
cvsdist d31aa3
          (insert "\n" string "\n")
cvsdist d31aa3
        (forward-line 2))
cvsdist a8bb5f
      (insert "- " change-log-entry "\n"))))
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert-f (&optional filetype filename)
cvsdist d31aa3
  "Insert new \"%files\" entry."
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (and (rpm-goto-section "files") (rpm-end-of-section))
cvsdist a8bb5f
    (if (or (eq filename 1) (not filename))
cvsdist a8bb5f
        (insert (read-file-name
cvsdist a8bb5f
                 (concat filetype "filename: ") "" "" nil) "\n")
cvsdist a8bb5f
      (insert filename "\n"))
cvsdist a8bb5f
    (forward-line -1)
cvsdist a8bb5f
    (if rpm-spec-add-attr
cvsdist a8bb5f
        (let ((rpm-default-mode rpm-default-umask))
cvsdist a8bb5f
          (insert "%attr(" rpm-default-mode ", " rpm-default-owner ", "
cvsdist a8bb5f
                  rpm-default-group ") ")))
cvsdist a8bb5f
    (insert filetype)))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert-file (&optional filename)
cvsdist a8bb5f
  "Insert regular file."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (rpm-insert-f "" filename))
cvsdist d31aa3
cvsdist a8bb5f
(defun rpm-insert-config (&optional filename)
cvsdist a8bb5f
  "Insert config file."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (rpm-insert-f "%config " filename))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert-doc (&optional filename)
cvsdist a8bb5f
  "Insert doc file."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (rpm-insert-f "%doc " filename))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert-ghost (&optional filename)
cvsdist a8bb5f
  "Insert ghost file."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (rpm-insert-f "%ghost " filename))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert-dir (&optional dirname)
cvsdist a8bb5f
  "Insert directory."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (rpm-insert-f "%dir " dirname))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert-docdir (&optional dirname)
cvsdist a8bb5f
  "Insert doc directory."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (rpm-insert-f "%docdir " dirname))
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist 98a749
(defun rpm-completing-read (prompt table &optional pred require init hist)
cvsdist 98a749
  "Read from the minibuffer, with completion.
cvsdist d31aa3
Like `completing-read', but the variable `rpm-spec-completion-ignore-case'
cvsdist 98a749
controls whether case is significant."
cvsdist d31aa3
  (let ((completion-ignore-case rpm-spec-completion-ignore-case))
cvsdist 98a749
    (completing-read prompt table pred require init hist)))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert (&optional what file-completion)
cvsdist a8bb5f
  "Insert given tag.  Use file-completion if argument is t."
cvsdist a8bb5f
  (beginning-of-line)
cvsdist a8bb5f
  (if (not what)
cvsdist 98a749
      (setq what (rpm-completing-read "Tag: " rpm-tags-list)))
cvsdist a8bb5f
  (if (string-match "^%" what)
cvsdist a8bb5f
      (setq read-text (concat "Packagename for " what ": ")
cvsdist a8bb5f
            insert-text (concat what " "))
cvsdist a8bb5f
    (setq read-text (concat what ": ")
cvsdist a8bb5f
          insert-text (concat what ": ")))
cvsdist a8bb5f
  (cond
cvsdist a8bb5f
   ((string-equal what "Group")
cvsdist a8bb5f
    (rpm-insert-group))
cvsdist a8bb5f
   ((string-equal what "Source")
cvsdist a8bb5f
    (rpm-insert-n "Source"))
cvsdist a8bb5f
   ((string-equal what "Patch")
cvsdist a8bb5f
    (rpm-insert-n "Patch"))
cvsdist a8bb5f
   (t
cvsdist a8bb5f
    (if file-completion
cvsdist a8bb5f
        (insert insert-text (read-file-name (concat read-text) "" "" nil) "\n")
cvsdist a8bb5f
      (insert insert-text (read-from-minibuffer (concat read-text)) "\n")))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-topdir ()
cvsdist a8bb5f
  (or
cvsdist a8bb5f
   (getenv "RPM")
cvsdist a8bb5f
   (getenv "rpm")
cvsdist a8bb5f
   (if (file-directory-p "~/rpm") "~/rpm/")
cvsdist a8bb5f
   (if (file-directory-p "~/RPM") "~/RPM/")
cvsdist d31aa3
   (if (file-directory-p "/usr/src/redhat/") "/usr/src/redhat/")
cvsdist a8bb5f
   "/usr/src/RPM"))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert-n (what &optional arg)
cvsdist a8bb5f
  "Insert given tag with possible number."
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (goto-char (point-max))
cvsdist a8bb5f
    (if (search-backward-regexp (concat "^" what "\\([0-9]*\\):") nil t)
cvsdist a8bb5f
        (let ((release (1+ (string-to-int (match-string 1)))))
cvsdist a8bb5f
          (forward-line 1)
cvsdist a8bb5f
          (let ((default-directory (concat (rpm-topdir) "/SOURCES/")))
cvsdist a8bb5f
            (insert what (int-to-string release) ": "
cvsdist a8bb5f
                    (read-file-name (concat what "file: ") "" "" nil) "\n")))
cvsdist a8bb5f
      (goto-char (point-min))
cvsdist a8bb5f
      (rpm-end-of-section)
cvsdist a8bb5f
      (insert what ": " (read-from-minibuffer (concat what "file: ")) "\n"))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-change (&optional what arg)
cvsdist a8bb5f
  "Update given tag."
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (if (not what)
cvsdist 98a749
        (setq what (rpm-completing-read "Tag: " rpm-tags-list)))
cvsdist a8bb5f
    (cond
cvsdist a8bb5f
     ((string-equal what "Group")
cvsdist a8bb5f
      (rpm-change-group))
cvsdist a8bb5f
     ((string-equal what "Source")
cvsdist a8bb5f
      (rpm-change-n "Source"))
cvsdist a8bb5f
     ((string-equal what "Patch")
cvsdist a8bb5f
      (rpm-change-n "Patch"))
cvsdist a8bb5f
     (t
cvsdist a8bb5f
      (goto-char (point-min))
cvsdist a8bb5f
      (if (search-forward-regexp (concat "^" what ":\\s-*\\(.*\\)$") nil t)
cvsdist a8bb5f
          (replace-match
cvsdist a8bb5f
           (concat what ": " (read-from-minibuffer
cvsdist a8bb5f
                              (concat "New " what ": ") (match-string 1))))
Charles Coldwell 40eeb8
        (message "%s tag not found..." what))))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-change-n (what &optional arg)
cvsdist a8bb5f
  "Change given tag with possible number."
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (goto-char (point-min))
cvsdist a8bb5f
    (let ((number (read-from-minibuffer (concat what " number: "))))
cvsdist a8bb5f
      (if (search-forward-regexp
cvsdist a8bb5f
           (concat "^" what number ":\\s-*\\(.*\\)") nil t)
cvsdist a8bb5f
          (let ((default-directory (concat (rpm-topdir) "/SOURCES/")))
cvsdist a8bb5f
            (replace-match
cvsdist a8bb5f
             (concat what number ": "
cvsdist a8bb5f
                     (read-file-name (concat "New " what number " file: ")
cvsdist a8bb5f
                                     "" "" nil (match-string 1)))))
Charles Coldwell 40eeb8
        (message "%s number \"%s\" not found..." what number)))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert-group (group)
cvsdist a8bb5f
  "Insert Group tag."
cvsdist 98a749
  (interactive (list (rpm-completing-read "Group: " rpm-group-tags-list)))
cvsdist a8bb5f
  (beginning-of-line)
cvsdist a8bb5f
  (insert "Group: " group "\n"))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-change-group (&optional arg)
cvsdist a8bb5f
  "Update Group tag."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (goto-char (point-min))
cvsdist a8bb5f
    (if (search-forward-regexp "^Group: \\(.*\\)$" nil t)
cvsdist a8bb5f
        (replace-match
cvsdist a8bb5f
         (concat "Group: "
cvsdist 98a749
                 (insert (rpm-completing-read "Group: " rpm-group-tags-list
cvsdist d31aa3
                                              nil nil (match-string 1)))))
cvsdist a8bb5f
      (message "Group tag not found..."))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert-tag (&optional arg)
cvsdist 98a749
  "Insert or change a tag."
cvsdist a8bb5f
  (interactive "p")
cvsdist 98a749
  (if current-prefix-arg
cvsdist 98a749
      (rpm-change)
cvsdist 98a749
    (rpm-insert)))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-change-tag (&optional arg)
cvsdist a8bb5f
  "Change a tag."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (rpm-change))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-insert-packager (&optional arg)
cvsdist a8bb5f
  "Insert Packager tag."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (beginning-of-line)
cvsdist d31aa3
  (insert "Packager: " (or rpm-spec-user-full-name (user-full-name))
Charles Coldwell 3525a1
          " <" (rpm-spec-user-mail-address) ">\n"))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-change-packager (&optional arg)
cvsdist a8bb5f
  "Update Packager tag."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (rpm-change "Packager"))
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-current-section nil
cvsdist a8bb5f
  (interactive)
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (rpm-forward-section)
cvsdist a8bb5f
    (rpm-backward-section)
cvsdist d31aa3
    (if (bobp) "preamble"
cvsdist a8bb5f
      (buffer-substring (match-beginning 1) (match-end 1)))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-backward-section nil
cvsdist a8bb5f
  "Move backward to the beginning of the previous section.
cvsdist a8bb5f
Go to beginning of previous section."
cvsdist a8bb5f
  (interactive)
cvsdist a8bb5f
  (or (re-search-backward rpm-section-regexp nil t)
cvsdist a8bb5f
      (goto-char (point-min))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-beginning-of-section nil
cvsdist a8bb5f
  "Move backward to the beginning of the current section.
cvsdist a8bb5f
Go to beginning of current section."
cvsdist a8bb5f
  (interactive)
cvsdist a8bb5f
  (or (and (looking-at rpm-section-regexp) (point))
cvsdist a8bb5f
      (re-search-backward rpm-section-regexp nil t)
cvsdist a8bb5f
      (goto-char (point-min))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-forward-section nil
cvsdist a8bb5f
  "Move forward to the beginning of the next section."
cvsdist a8bb5f
  (interactive)
cvsdist a8bb5f
  (forward-char)
cvsdist a8bb5f
  (if (re-search-forward rpm-section-regexp nil t)
cvsdist a8bb5f
      (progn (forward-line 0) (point))
cvsdist a8bb5f
    (goto-char (point-max))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-end-of-section nil
cvsdist a8bb5f
  "Move forward to the end of this section."
cvsdist a8bb5f
  (interactive)
cvsdist a8bb5f
  (forward-char)
cvsdist a8bb5f
  (if (re-search-forward rpm-section-regexp nil t)
cvsdist a8bb5f
      (forward-line -1)
cvsdist a8bb5f
    (goto-char (point-max)))
cvsdist a8bb5f
;;  (while (or (looking-at paragraph-separate) (looking-at "^\\s-*#"))
cvsdist a8bb5f
  (while (looking-at "^\\s-*\\($\\|#\\)")
cvsdist a8bb5f
    (forward-line -1))
cvsdist a8bb5f
  (forward-line 1)
cvsdist a8bb5f
  (point))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-goto-section (section)
cvsdist d31aa3
  "Move point to the beginning of the specified section;
cvsdist a8bb5f
leave point at previous location."
cvsdist 98a749
  (interactive (list (rpm-completing-read "Section: " rpm-section-list)))
cvsdist a8bb5f
  (push-mark)
cvsdist a8bb5f
  (goto-char (point-min))
cvsdist d31aa3
  (or
cvsdist a8bb5f
   (equal section "preamble")
cvsdist a8bb5f
   (re-search-forward (concat "^%" section "\\b") nil t)
cvsdist a8bb5f
   (let ((s (cdr rpm-sections)))
cvsdist a8bb5f
     (while (not (equal section (car s)))
cvsdist a8bb5f
       (re-search-forward (concat "^%" (car s) "\\b") nil t)
cvsdist a8bb5f
       (setq s (cdr s)))
cvsdist a8bb5f
     (if (re-search-forward rpm-section-regexp nil t)
cvsdist a8bb5f
         (forward-line -1) (goto-char (point-max)))
cvsdist a8bb5f
     (insert "\n%" section "\n"))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-mouse-goto-section (&optional section)
cvsdist d31aa3
  (interactive
cvsdist d31aa3
   (x-popup-menu
cvsdist d31aa3
    nil
cvsdist d31aa3
    (list "sections"
cvsdist a8bb5f
          (cons "Sections" (mapcar (lambda (e) (list e e)) rpm-sections))
cvsdist a8bb5f
          (cons "Scripts" (mapcar (lambda (e) (list e e)) rpm-scripts))
cvsdist a8bb5f
          )))
cvsdist d31aa3
  ;; If user doesn't pick a section, exit quietly.
cvsdist d31aa3
  (and section
cvsdist a8bb5f
       (if (member section rpm-sections)
cvsdist a8bb5f
           (rpm-goto-section section)
cvsdist a8bb5f
         (goto-char (point-min))
cvsdist a8bb5f
         (or (re-search-forward (concat "^%" section "\\b") nil t)
cvsdist a8bb5f
             (and (re-search-forward "^%files\\b" nil t) (forward-line -1))
cvsdist a8bb5f
             (goto-char (point-max))))))
cvsdist a8bb5f
cvsdist d31aa3
(defun rpm-insert-true-prefix ()
cvsdist a8bb5f
  (interactive)
cvsdist a8bb5f
  (insert "%{prefix}"))
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-build (buildoptions)
cvsdist d31aa3
  "Build this RPM package."
cvsdist 45b61e
  (if (and (buffer-modified-p)
cvsdist 45b61e
           (y-or-n-p (format "Buffer %s modified, save it? " (buffer-name))))
cvsdist 45b61e
      (save-buffer))
cvsdist a8bb5f
  (setq rpm-buffer-name
cvsdist d31aa3
        (concat "*" rpm-spec-build-command " " buildoptions " "
cvsdist a8bb5f
                (file-name-nondirectory buffer-file-name) "*"))
cvsdist a8bb5f
  (rpm-process-check rpm-buffer-name)
cvsdist a8bb5f
  (if (get-buffer rpm-buffer-name)
cvsdist a8bb5f
      (kill-buffer rpm-buffer-name))
cvsdist a8bb5f
  (create-file-buffer rpm-buffer-name)
cvsdist a8bb5f
  (display-buffer rpm-buffer-name)
cvsdist a8bb5f
  (setq buildoptions (list buildoptions buffer-file-name))
cvsdist d31aa3
  (if (or rpm-spec-short-circuit rpm-spec-nobuild)
cvsdist a8bb5f
      (setq rpm-no-gpg t))
cvsdist a8bb5f
  (if rpm-spec-rmsource
cvsdist a8bb5f
      (setq buildoptions (cons "--rmsource" buildoptions)))
cvsdist a8bb5f
  (if rpm-spec-clean
cvsdist a8bb5f
      (setq buildoptions (cons "--clean" buildoptions)))
cvsdist a8bb5f
  (if rpm-spec-short-circuit
cvsdist a8bb5f
      (setq buildoptions (cons "--short-circuit" buildoptions)))
cvsdist a8bb5f
  (if (and (not (equal rpm-spec-timecheck "0"))
cvsdist a8bb5f
           (not (equal rpm-spec-timecheck "")))
cvsdist a8bb5f
      (setq buildoptions (cons "--timecheck" (cons rpm-spec-timecheck
cvsdist a8bb5f
                                                   buildoptions))))
cvsdist a8bb5f
  (if (not (equal rpm-spec-buildroot ""))
cvsdist a8bb5f
      (setq buildoptions (cons "--buildroot" (cons rpm-spec-buildroot
cvsdist a8bb5f
                                                   buildoptions))))
cvsdist a8bb5f
  (if (not (equal rpm-spec-target ""))
cvsdist a8bb5f
      (setq buildoptions (cons "--target" (cons rpm-spec-target
cvsdist a8bb5f
                                                buildoptions))))
cvsdist d31aa3
  (if rpm-spec-nobuild
cvsdist 45b61e
      (setq buildoptions (cons rpm-spec-nobuild-option buildoptions)))
cvsdist 45b61e
  (if rpm-spec-quiet
cvsdist 45b61e
      (setq buildoptions (cons "--quiet" buildoptions)))
cvsdist d31aa3
  (if rpm-spec-nodeps
cvsdist d31aa3
      (setq buildoptions (cons "--nodeps" buildoptions)))
cvsdist a8bb5f
  (if (and rpm-spec-sign-gpg (not rpm-no-gpg))
cvsdist a8bb5f
      (setq buildoptions (cons "--sign" buildoptions)))
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (set-buffer (get-buffer rpm-buffer-name))
cvsdist 45b61e
    (and rpm-spec-use-compilation-mode
cvsdist 45b61e
         (fboundp 'compilation-mode)
cvsdist 45b61e
         (compilation-mode))
cvsdist a8bb5f
    (goto-char (point-max)))
cvsdist 45b61e
  (let* ((process-environment (cons "EMACS=t" process-environment))
cvsdist 45b61e
         (process
cvsdist 45b61e
          (apply 'start-process rpm-spec-build-command rpm-buffer-name
cvsdist 45b61e
                 rpm-spec-build-command buildoptions)))
cvsdist a8bb5f
    (if (and rpm-spec-sign-gpg (not rpm-no-gpg))
cvsdist a8bb5f
        (let ((rpm-passwd-cache (read-passwd "GPG passphrase: ")))
cvsdist a8bb5f
          (process-send-string process (concat rpm-passwd-cache "\n"))))
cvsdist a8bb5f
    (set-process-filter process 'rpm-command-filter)))
cvsdist a8bb5f
cvsdist d31aa3
(defun rpm-build-prepare (&optional arg)
cvsdist a9afeb
  "Run a `rpmbuild -bp'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (if rpm-spec-short-circuit
Charles Coldwell 40eeb8
      (message "Cannot run `%s -bp' with --short-circuit"
Charles Coldwell 40eeb8
	       rpm-spec-build-command)
cvsdist a8bb5f
    (setq rpm-no-gpg t)
cvsdist a8bb5f
    (rpm-build "-bp")))
cvsdist a8bb5f
cvsdist d31aa3
(defun rpm-list-check (&optional arg)
cvsdist a9afeb
  "Run a `rpmbuild -bl'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (if rpm-spec-short-circuit
Charles Coldwell 40eeb8
      (message "Cannot run `%s -bl' with --short-circuit"
Charles Coldwell 40eeb8
	       rpm-spec-build-command)
cvsdist a8bb5f
    (setq rpm-no-gpg t)
cvsdist a8bb5f
    (rpm-build "-bl")))
cvsdist a8bb5f
cvsdist d31aa3
(defun rpm-build-compile (&optional arg)
cvsdist a9afeb
  "Run a `rpmbuild -bc'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-no-gpg t)
cvsdist a8bb5f
  (rpm-build "-bc"))
cvsdist a8bb5f
cvsdist d31aa3
(defun rpm-build-install (&optional arg)
cvsdist a9afeb
  "Run a `rpmbuild -bi'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-no-gpg t)
cvsdist a8bb5f
  (rpm-build "-bi"))
cvsdist a8bb5f
cvsdist d31aa3
(defun rpm-build-binary (&optional arg)
cvsdist a9afeb
  "Run a `rpmbuild -bb'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (if rpm-spec-short-circuit
Charles Coldwell 40eeb8
      (message "Cannot run `%s -bb' with --short-circuit"
Charles Coldwell 40eeb8
	       rpm-spec-build-command)
cvsdist a8bb5f
    (setq rpm-no-gpg nil)
cvsdist a8bb5f
    (rpm-build "-bb")))
cvsdist a8bb5f
cvsdist d31aa3
(defun rpm-build-source (&optional arg)
cvsdist a9afeb
  "Run a `rpmbuild -bs'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (if rpm-spec-short-circuit
Charles Coldwell 40eeb8
      (message "Cannot run `%s -bs' with --short-circuit"
Charles Coldwell 40eeb8
	       rpm-spec-build-command)
cvsdist a8bb5f
    (setq rpm-no-gpg nil)
cvsdist a8bb5f
    (rpm-build "-bs")))
cvsdist a8bb5f
cvsdist d31aa3
(defun rpm-build-all (&optional arg)
cvsdist a9afeb
  "Run a `rpmbuild -ba'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (if rpm-spec-short-circuit
Charles Coldwell 40eeb8
      (message "Cannot run `%s -ba' with --short-circuit"
Charles Coldwell 40eeb8
	       rpm-spec-build-command)
cvsdist a8bb5f
    (setq rpm-no-gpg nil)
cvsdist a8bb5f
    (rpm-build "-ba")))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-process-check (buffer)
cvsdist a8bb5f
  "Check if BUFFER has a running process.
cvsdist a8bb5f
If so, give the user the choice of aborting the process or the current
cvsdist a8bb5f
command."
cvsdist a8bb5f
  (let ((process (get-buffer-process (get-buffer buffer))))
cvsdist a8bb5f
    (if (and process (eq (process-status process) 'run))
cvsdist a8bb5f
        (if (yes-or-no-p (concat "Process `" (process-name process)
cvsdist a8bb5f
                                 "' running.  Kill it? "))
cvsdist a8bb5f
            (delete-process process)
cvsdist a8bb5f
          (error "Cannot run two simultaneous processes ...")))))
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-toggle-short-circuit (&optional arg)
cvsdist d31aa3
  "Toggle `rpm-spec-short-circuit'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-spec-short-circuit (not rpm-spec-short-circuit))
cvsdist a8bb5f
  (rpm-update-mode-name)
cvsdist a8bb5f
  (message (concat "Turned `--short-circuit' "
cvsdist a8bb5f
                   (if rpm-spec-short-circuit "on" "off") ".")))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-toggle-rmsource (&optional arg)
cvsdist d31aa3
  "Toggle `rpm-spec-rmsource'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-spec-rmsource (not rpm-spec-rmsource))
cvsdist a8bb5f
  (rpm-update-mode-name)
cvsdist a8bb5f
  (message (concat "Turned `--rmsource' "
cvsdist a8bb5f
                   (if rpm-spec-rmsource "on" "off") ".")))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-toggle-clean (&optional arg)
cvsdist d31aa3
  "Toggle `rpm-spec-clean'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-spec-clean (not rpm-spec-clean))
cvsdist a8bb5f
  (rpm-update-mode-name)
cvsdist a8bb5f
  (message (concat "Turned `--clean' "
cvsdist a8bb5f
                   (if rpm-spec-clean "on" "off") ".")))
cvsdist a8bb5f
cvsdist d31aa3
(defun rpm-toggle-nobuild (&optional arg)
cvsdist d31aa3
  "Toggle `rpm-spec-nobuild'."
cvsdist a8bb5f
  (interactive "p")
cvsdist d31aa3
  (setq rpm-spec-nobuild (not rpm-spec-nobuild))
cvsdist a8bb5f
  (rpm-update-mode-name)
cvsdist 45b61e
  (message (concat "Turned `" rpm-spec-nobuild-option "' "
cvsdist d31aa3
                   (if rpm-spec-nobuild "on" "off") ".")))
cvsdist a8bb5f
cvsdist 45b61e
(defun rpm-toggle-quiet (&optional arg)
cvsdist 45b61e
  "Toggle `rpm-spec-quiet'."
cvsdist 45b61e
  (interactive "p")
cvsdist 45b61e
  (setq rpm-spec-quiet (not rpm-spec-quiet))
cvsdist 45b61e
  (rpm-update-mode-name)
cvsdist 45b61e
  (message (concat "Turned `--quiet' "
cvsdist 45b61e
                   (if rpm-spec-quiet "on" "off") ".")))
cvsdist 45b61e
cvsdist a8bb5f
(defun rpm-toggle-sign-gpg (&optional arg)
cvsdist d31aa3
  "Toggle `rpm-spec-sign-gpg'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-spec-sign-gpg (not rpm-spec-sign-gpg))
cvsdist a8bb5f
  (rpm-update-mode-name)
cvsdist a8bb5f
  (message (concat "Turned `--sign' "
cvsdist a8bb5f
                   (if rpm-spec-sign-gpg "on" "off") ".")))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-toggle-add-attr (&optional arg)
cvsdist d31aa3
  "Toggle `rpm-spec-add-attr'."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-spec-add-attr (not rpm-spec-add-attr))
cvsdist a8bb5f
  (rpm-update-mode-name)
cvsdist a8bb5f
  (message (concat "Default add \"attr\" entry turned "
cvsdist a8bb5f
                   (if rpm-spec-add-attr "on" "off") ".")))
cvsdist a8bb5f
cvsdist d31aa3
(defun rpm-toggle-nodeps (&optional arg)
cvsdist d31aa3
  "Toggle `rpm-spec-nodeps'."
cvsdist d31aa3
  (interactive "p")
cvsdist d31aa3
  (setq rpm-spec-nodeps (not rpm-spec-nodeps))
cvsdist d31aa3
  (rpm-update-mode-name)
cvsdist d31aa3
  (message (concat "Turned `--nodeps' "
cvsdist d31aa3
                   (if rpm-spec-nodeps "on" "off") ".")))
cvsdist d31aa3
cvsdist a8bb5f
(defun rpm-update-mode-name ()
cvsdist d31aa3
  "Update `mode-name' according to values set."
cvsdist a8bb5f
  (setq mode-name "RPM-SPEC")
cvsdist a8bb5f
  (setq modes (concat (if rpm-spec-add-attr      "A")
cvsdist d31aa3
                      (if rpm-spec-clean         "C")
cvsdist d31aa3
                      (if rpm-spec-nodeps        "D")
cvsdist d31aa3
                      (if rpm-spec-sign-gpg      "G")
cvsdist d31aa3
                      (if rpm-spec-nobuild       "N")
cvsdist d31aa3
                      (if rpm-spec-rmsource      "R")
cvsdist d31aa3
                      (if rpm-spec-short-circuit "S")
cvsdist 45b61e
		      (if rpm-spec-quiet         "Q")
cvsdist d31aa3
                      ))
cvsdist a8bb5f
  (if (not (equal modes ""))
cvsdist d31aa3
      (setq mode-name (concat mode-name ":" modes))))
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-change-timecheck-option (&optional arg)
cvsdist a8bb5f
  "Change the value for timecheck."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-spec-timecheck
cvsdist a8bb5f
        (read-from-minibuffer "New timecheck: " rpm-spec-timecheck)))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-change-buildroot-option (&optional arg)
cvsdist a8bb5f
  "Change the value for buildroot."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-spec-buildroot
cvsdist a8bb5f
        (read-from-minibuffer "New buildroot: " rpm-spec-buildroot)))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-change-target-option (&optional arg)
cvsdist a8bb5f
  "Change the value for target."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-spec-target
cvsdist a8bb5f
        (read-from-minibuffer "New target: " rpm-spec-target)))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-files-umask (&optional arg)
cvsdist a8bb5f
  "Change the default umask for files."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-default-umask
cvsdist a8bb5f
        (read-from-minibuffer "Default file umask: " rpm-default-umask)))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-files-owner (&optional arg)
cvsdist a8bb5f
  "Change the default owner for files."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-default-owner
cvsdist a8bb5f
        (read-from-minibuffer "Default file owner: " rpm-default-owner)))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-files-group (&optional arg)
cvsdist a8bb5f
  "Change the source directory."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (setq rpm-default-group
cvsdist a8bb5f
        (read-from-minibuffer "Default file group: " rpm-default-group)))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-increase-release-tag (&optional arg)
cvsdist a8bb5f
  "Increase the release tag by 1."
cvsdist a8bb5f
  (interactive "p")
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (goto-char (point-min))
Charles Coldwell 40eeb8
    (if (search-forward-regexp
Charles Coldwell dcc57f
         ;; Try to find the last digit-only group of a dot-separated release string
Charles Coldwell dcc57f
         (concat "^\\(Release[ \t]*:[ \t]*\\)"
Charles Coldwell dcc57f
                 "\\(.*[ \t\\.}]\\)\\([0-9]+\\)\\([ \t\\.%].*\\|$\\)") nil t)
Charles Coldwell dcc57f
        (let ((release (1+ (string-to-int (match-string 3)))))
Charles Coldwell dcc57f
          (setq release
Charles Coldwell dcc57f
                (concat (match-string 2) (int-to-string release) (match-string 4)))
Charles Coldwell 40eeb8
          (replace-match (concat (match-string 1) release))
Charles Coldwell 40eeb8
          (message "Release tag changed to %s." release))
Charles Coldwell 40eeb8
      (if (search-forward-regexp "^Release[ \t]*:[ \t]*%{?\\([^}]*\\)}?$" nil t)
cvsdist d31aa3
          (rpm-increase-release-with-macros)
Charles Coldwell dcc57f
        (message "No Release tag to increase found...")))))
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-spec-field-value (field max)
cvsdist d31aa3
  "Get the value of FIELD, searching up to buffer position MAX.
cvsdist d31aa3
See `search-forward-regexp'."
cvsdist a8bb5f
  (save-excursion
Charles Coldwell 40eeb8
    (condition-case nil
cvsdist d31aa3
      (let ((str
cvsdist d31aa3
             (progn
cvsdist d31aa3
               (goto-char (point-min))
Jens Petersen ecfa73
               (search-forward-regexp (concat "^"
cvsdist d31aa3
                                       field ":[ \t]*\\(.*?\\)[ \t]*$") max)
cvsdist d31aa3
               (match-string 1))))
Jens Petersen 4c3846
        ;; Try to expand macros
Jens Petersen 4c3846
        (if (string-match "\\(%{?\\(\\?\\)?\\)\\([a-zA-Z0-9_]*\\)\\(}?\\)" str)
Jens Petersen 4c3846
            (let ((start-string (substring str 0 (match-beginning 1)))
Jens Petersen 4c3846
                  (end-string (substring str (match-end 4))))
Jens Petersen 4c3846
              (if (progn
Jens Petersen 4c3846
                    (goto-char (point-min))
Jens Petersen 4c3846
                    (search-forward-regexp
Jens Petersen 4c3846
                     (concat "%\\(define\\|global\\)[ \t]+"
Jens Petersen 4c3846
                             (match-string 3 str)
Jens Petersen 4c3846
                             "[ \t]+\\(.*\\)") nil t))
Jens Petersen 4c3846
                  ;; Got it - replace.
Jens Petersen 4c3846
                  (concat start-string (match-string 2) end-string)
Jens Petersen 4c3846
                (if (match-string 2 str)
Jens Petersen 4c3846
                    ;; Conditionally evaluated macro - remove it.
Jens Petersen 4c3846
                    (concat start-string end-string)
Jens Petersen 4c3846
                  ;; Leave as is.
Jens Petersen 4c3846
                  str)))
Charles Coldwell 40eeb8
          str))
Charles Coldwell 40eeb8
      (error nil))))
cvsdist d31aa3
cvsdist d31aa3
(defun rpm-find-spec-version (&optional with-epoch)
cvsdist d31aa3
  "Get the version string.
cvsdist d31aa3
If WITH-EPOCH is non-nil, the string contains the Epoch/Serial value,
cvsdist d31aa3
if one is present in the file."
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (goto-char (point-min))
cvsdist a8bb5f
    (let* ((max (search-forward-regexp rpm-section-regexp))
cvsdist a8bb5f
           (version (rpm-spec-field-value "Version" max))
cvsdist d31aa3
           (release (rpm-spec-field-value "Release" max))
cvsdist d31aa3
           (epoch   (rpm-spec-field-value "Epoch"   max)) )
cvsdist d31aa3
      (when (and version (< 0 (length version)))
cvsdist d31aa3
        (unless epoch (setq epoch (rpm-spec-field-value "Serial" max)))
cvsdist d31aa3
        (concat (and with-epoch epoch (concat epoch ":"))
cvsdist d31aa3
                version
cvsdist d31aa3
                (and release (concat "-" release)))))))
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-increase-release-with-macros ()
cvsdist a8bb5f
  (save-excursion
cvsdist a8bb5f
    (let ((str
cvsdist a8bb5f
           (progn
cvsdist a8bb5f
             (goto-char (point-min))
Charles Coldwell 40eeb8
             (search-forward-regexp (concat "Release[ \t]*:[ \t]*\\(.+\\).*$") nil)
cvsdist a8bb5f
             (match-string 1))))
cvsdist a8bb5f
      (let ((inrel
cvsdist a8bb5f
             (if (string-match "%{?\\([^}]*\\)}?$" str)
cvsdist a8bb5f
                 (progn
cvsdist a8bb5f
                   (goto-char (point-min))
cvsdist a8bb5f
                   (setq macros (substring str (match-beginning 1)
cvsdist a8bb5f
                                           (match-end 1)))
cvsdist a8bb5f
                   (search-forward-regexp
cvsdist a8bb5f
                    (concat "%define[ \t]+" macros
cvsdist a8bb5f
                            "[ \t]+\\(\\([0-9]\\|\\.\\)+\\)\\(.*\\)"))
cvsdist a8bb5f
                   (concat macros " " (int-to-string (1+ (string-to-int
cvsdist a8bb5f
                                                          (match-string 1))))
cvsdist a8bb5f
                           (match-string 3)))
cvsdist a8bb5f
               str)))
cvsdist a8bb5f
        (setq dinrel inrel)
cvsdist a8bb5f
        (replace-match (concat "%define " dinrel))
Charles Coldwell 40eeb8
        (message "Release tag changed to %s." dinrel)))))
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
cvsdist a8bb5f
(defun rpm-spec-initialize ()
cvsdist a8bb5f
  "Create a default spec file if one does not exist or is empty."
cvsdist 45b61e
  (let (file name version (release rpm-spec-default-release))
cvsdist a8bb5f
    (setq file (if (buffer-file-name)
cvsdist a8bb5f
                   (file-name-nondirectory (buffer-file-name))
cvsdist a8bb5f
                 (buffer-name)))
cvsdist a8bb5f
    (cond
cvsdist a8bb5f
     ((eq (string-match "\\(.*\\)-\\([^-]*\\)-\\([^-]*\\).spec" file) 0)
cvsdist a8bb5f
      (setq name (match-string 1 file))
cvsdist a8bb5f
      (setq version (match-string 2 file))
cvsdist a8bb5f
      (setq release (match-string 3 file)))
cvsdist a8bb5f
     ((eq (string-match "\\(.*\\)-\\([^-]*\\).spec" file) 0)
cvsdist a8bb5f
      (setq name (match-string 1 file))
cvsdist a8bb5f
      (setq version (match-string 2 file)))
cvsdist a8bb5f
     ((eq (string-match "\\(.*\\).spec" file) 0)
cvsdist a8bb5f
      (setq name (match-string 1 file))))
cvsdist d31aa3
cvsdist 45b61e
    (if rpm-spec-indent-heading-values
cvsdist 45b61e
	(insert
cvsdist 45b61e
	 "Summary:        "
cvsdist 45b61e
	 "\nName:           " (or name "")
cvsdist 45b61e
	 "\nVersion:        " (or version "")
cvsdist 45b61e
	 "\nRelease:        " (or release "")
cvsdist 45b61e
	 (if rpm-spec-default-epoch
cvsdist 45b61e
	     (concat "\nEpoch:          "
cvsdist 45b61e
		     (int-to-string rpm-spec-default-epoch))
cvsdist 45b61e
	   "")
cvsdist 45b61e
	 "\nLicense:        "
cvsdist 45b61e
	 "\nGroup:          "
cvsdist 45b61e
	 "\nURL:            "
cvsdist 45b61e
	 "\nSource0:        %{name}-%{version}.tar.gz"
cvsdist 45b61e
	 "\nBuildRoot:      " rpm-spec-default-buildroot)
cvsdist 45b61e
      (insert
cvsdist 45b61e
       "Summary: "
cvsdist 45b61e
       "\nName: " (or name "")
cvsdist 45b61e
       "\nVersion: " (or version "")
cvsdist 45b61e
       "\nRelease: " (or release "")
cvsdist 45b61e
       (if rpm-spec-default-epoch
cvsdist 45b61e
	   (concat "\nEpoch: " (int-to-string rpm-spec-default-epoch))
cvsdist 45b61e
	 "")
cvsdist 45b61e
       "\nLicense: "
cvsdist 45b61e
       "\nGroup: "
cvsdist 45b61e
       "\nURL: "
cvsdist 45b61e
       "\nSource0: %{name}-%{version}.tar.gz"
cvsdist 45b61e
       "\nBuildRoot: " rpm-spec-default-buildroot))
cvsdist 45b61e
cvsdist a8bb5f
    (insert
cvsdist a8bb5f
     "\n\n%description\n"
cvsdist a8bb5f
     "\n%prep"
cvsdist a8bb5f
     "\n%setup -q"
cvsdist 45b61e
     "\n\n%build\n"
cvsdist 45b61e
     (or rpm-spec-default-build-section "")
cvsdist 45b61e
     "\n%install\n"
cvsdist 45b61e
     (or rpm-spec-default-install-section "")
cvsdist 45b61e
     "\n%clean\n"
cvsdist 45b61e
     (or rpm-spec-default-clean-section "")
cvsdist a8bb5f
     "\n\n%files"
cvsdist d31aa3
     "\n%defattr(-,root,root,-)"
cvsdist d31aa3
     "\n%doc\n"
cvsdist a8bb5f
     "\n\n%changelog\n")
cvsdist d31aa3
cvsdist 45b61e
    (end-of-line 1)
cvsdist 45b61e
    (rpm-add-change-log-entry "Initial build.")))
cvsdist a8bb5f
cvsdist a8bb5f
;;------------------------------------------------------------
cvsdist a8bb5f
Charles Coldwell 3525a1
(defun rpm-spec-user-mail-address ()
Charles Coldwell 3525a1
  "User mail address helper."
Charles Coldwell 3525a1
  (cond
Charles Coldwell 3525a1
   (rpm-spec-user-mail-address
Charles Coldwell 3525a1
    rpm-spec-user-mail-address)
Charles Coldwell 3525a1
   ((fboundp 'user-mail-address)
Charles Coldwell 3525a1
    (user-mail-address))
Charles Coldwell 3525a1
   (t
Charles Coldwell 3525a1
    user-mail-address)))
Charles Coldwell 3525a1
Charles Coldwell 3525a1
;;------------------------------------------------------------
Charles Coldwell 3525a1
cvsdist a8bb5f
(defun rpm-about-rpm-spec-mode (&optional arg)
cvsdist d31aa3
  "About `rpm-spec-mode'."
cvsdist a8bb5f
  (interactive "p")
cvsdist d31aa3
  (message
cvsdist d31aa3
   (concat "rpm-spec-mode version "
cvsdist d31aa3
           rpm-spec-mode-version
cvsdist d31aa3
           " by Stig Bjørlykke, <stigb@tihlde.org>")))
cvsdist d31aa3
cvsdist 45b61e
;;;###autoload(add-to-list 'auto-mode-alist '("\\.spec\\(\\.in\\)?$" . rpm-spec-mode))
cvsdist a8bb5f
cvsdist a8bb5f
(provide 'rpm-spec-mode)
cvsdist a8bb5f
cvsdist a8bb5f
;;; rpm-spec-mode.el ends here