[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
version.el v1.0
From: |
Vinicius Jose Latorre |
Subject: |
version.el v1.0 |
Date: |
Sun, 05 Jun 2005 13:53:03 -0300 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) Gecko/20050511 |
;;; version.el --- version string comparison
;; Copyright (C) 2005 Vinicius Jose Latorre
;; Author: Vinicius Jose Latorre <address@hidden>
;; Maintainer: Vinicius Jose Latorre <address@hidden>
;; Keywords: help, internal, maintenance, debug
;; Time-stamp: <2005/06/05 13:49:36 vinicius>
;; Version: 1.0
;; X-URL: http://www.cpqd.com.br/~vinicius/emacs/
;; This file is *NOT* (yet?) part of GNU Emacs.
;; This program 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 2, or (at your option)
;; any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; 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., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Introduction
;; ------------
;;
;; This package provides routines to compare string version and to convert
;; string version to an integer list.
;;
;; version was tested with GNU Emacs 22.0.50.1.
;;
;; I don't know if still is compatible with XEmacs.
;;
;;
;; Usage
;; -----
;;
;; To use version, insert in your Emacs Lisp code:
;;
;; (require 'version)
;;
;; So, you can compare versions in Emacs Lisp code like:
;;
;; (and (< (version-compare other-version "6.6pre4") 0)
;; (error "`my-pack' requires `other' package version 6.6pre4 or
later"))
;;
;;
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; User variables
(defgroup version nil
"Version group"
:link '(emacs-library-link :tag "Source Lisp File" "version.el")
:prefix "version-"
:group 'internal
:group 'maintenance
:group 'debug)
(defcustom version-separator "."
"*Specify the string used to separate the version elements.
Usually the separator is \".\", but it can any other string."
:type '(string :tag "Version Separator")
:group 'version)
(defcustom version-regexp-alist
'(("^a\\(lpha\\)?$" . 0)
("^b\\(eta\\)?$" . 1)
("^pre\\|rc$" . 2))
"*Specify association between non-numeric version part and a priority.
This association is used to handle version string like
\"1.0pre2\", \"0.9alpha1\", etc. It's used by
`version-to-list' (which see) to convert the non-numeric part to
an integer. For example:
ORIGINAL VERSION VERSION CONVERTED
1.0pre2 1.0.2.2
1.0PRE2 1.0.2.2
22.8beta3 22.8.1.3
22.8Beta3 22.8.1.3
0.9alpha1 0.9.0.1
0.9AlphA1 0.9.0.1
Each element has the following form:
(REGEXP . PRIORITY)
Where:
REGEXP regexp used to match non-numeric part of a version string.
PRIORITY integer which indicate the non-numeric priority."
:type '(repeat :tag "Version Regexp Alist"
(cons :tag ""
(string :tag "Version Regexp")
(integer :tag "Version Priority")))
:group 'version)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Functions
(defun version-to-list (ver)
"Convert version string VER into an integer list.
The version syntax is given by the following EBNF:
VERSION ::= NUMBER ( SEPARATOR NUMBER )*.
NUMBER ::= (0|1|2|3|4|5|6|7|8|9)+.
SEPARATOR ::= `version-separator' (which see)
| `version-regexp-alist' (which see).
As an example of valid version syntax:
1.0pre2 1.0.7.5 22.8beta3 0.9alpha1
As an example of invalid version syntax:
1.0prepre2 1.0..7.5 22.8X3
As an example of version convertion:
ORIGINAL VERSION VERSION CONVERTED
\"1.0.7.5\" (1 0 7 5)
\"1.0pre2\" (1 0 2 2)
\"1.0PRE2\" (1 0 2 2)
\"22.8beta3\" (22 8 1 3)
\"22.8Beta3\" (22 8 1 3)
\"0.9alpha1\" (0 9 0 1)
\"0.9AlphA1\" (0 9 0 1)
\"0.9alpha\" (0 9 0)
"
(or (and (stringp ver) (not (string= ver "")))
(error "Invalid version syntax: '%s'" ver))
(save-match-data
(let ((i 0)
case-fold-search ; ignore case in matching
lst s al)
(while (and (setq s (string-match "[0-9]+" ver i))
(= s i))
;; handle numeric part
(setq lst (cons (string-to-number (substring ver i (match-end 0)))
lst)
i (match-end 0))
;; handle non-numeric part
(when (and (setq s (string-match "[^0-9]+" ver i))
(= s i))
(setq s (substring ver i (match-end 0))
i (match-end 0))
;; handle alpha, beta, pre, etc. separator
(unless (string= s version-separator)
(setq al version-regexp-alist)
(while (and al (not (string-match (caar al) s)))
(setq al (cdr al)))
(or al (error "Invalid version syntax: '%s'" ver))
(setq lst (cons (cdar al) lst)))))
(if (null lst)
(error "Invalid version syntax: '%s'" ver)
(nreverse lst)))))
(defun version-compare (v1 v2)
"Compare version string V1 with V2.
If V1 = V2, return 0.
If V1 > V2, return 1.
If V1 < V2, return -1.
It is an error if V1 or V2 is not a valid string version.
It uses `version-to-list' (which see)."
(let ((l1 (version-to-string v1))
(l2 (version-to-string v2))
(r 0)
e1 e2)
(while (and (= r 0) l1 l2)
(setq e1 (car l1)
e2 (car l2)
l1 (cdr l1)
l2 (cdr l2)
r (cond ((= e1 e2) 0)
((> e1 e2) 1)
(t -1))))
(cond ((or (/= r 0) (and (null l1) (null l2)))
r)
;; r = 0 and l1 not null and l2 null ==> l1 length > l2 length
(l1 1)
;; r = 0 and l1 null and l2 not null ==> l2 length > l1 length
(t -1))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide 'version)
;;; version.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- version.el v1.0,
Vinicius Jose Latorre <=