From 0b32f5976414e501d2fb95ddd21523e122b0f5b0 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 25 Dec 2019 17:12:10 +0100 Subject: [PATCH 01/12] Fix compilation warning in gnus-start.el * lisp/gnus/gnus-start.el (gnus-gnus-to-quick-newsrc-format): Fix compilation warning by not binding XEmacs-only variable. * lisp/gnus/gnus-util.el (gnus-bind-print-variables): Ditto. (gnus-prin1, gnus-prin1-to-string, gnus-pp, gnus-pp-to-string): Adjust doc string. --- lisp/gnus/gnus-start.el | 1 - lisp/gnus/gnus-util.el | 23 +++++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index 409fd442dd1..784a4e4195f 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -2871,7 +2871,6 @@ SPECIFIC-VARIABLES, or those in `gnus-variable-list'." (nth 1 (gethash g gnus-newsrc-hashtb))) (delete "dummy.group" gnus-group-list))) (let* ((print-quoted t) - (print-readably t) (print-escape-multibyte nil) (print-escape-nonascii t) (print-length nil) diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index 42021d30730..ce5b2a155f5 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -690,13 +690,12 @@ yield \"nnimap:yxa\"." (defmacro gnus-bind-print-variables (&rest forms) "Bind print-* variables and evaluate FORMS. -This macro is used with `prin1', `pp', etc. in order to ensure printed -Lisp objects are loadable. Bind `print-quoted' and `print-readably' -to t, and `print-escape-multibyte', `print-escape-newlines', +This macro is used with `prin1', `pp', etc. in order to ensure +printed Lisp objects are loadable. Bind `print-quoted' to t, and +`print-escape-multibyte', `print-escape-newlines', `print-escape-nonascii', `print-length', `print-level' and `print-string-length' to nil." `(let ((print-quoted t) - (print-readably t) ;;print-circle ;;print-continuous-numbering print-escape-multibyte @@ -710,26 +709,26 @@ to t, and `print-escape-multibyte', `print-escape-newlines', (defun gnus-prin1 (form) "Use `prin1' on FORM in the current buffer. -Bind `print-quoted' and `print-readably' to t, and `print-length' and -`print-level' to nil. See also `gnus-bind-print-variables'." +Bind `print-quoted' to t, and `print-length' and `print-level' to +nil. See also `gnus-bind-print-variables'." (gnus-bind-print-variables (prin1 form (current-buffer)))) (defun gnus-prin1-to-string (form) "The same as `prin1'. -Bind `print-quoted' and `print-readably' to t, and `print-length' and -`print-level' to nil. See also `gnus-bind-print-variables'." +Bind `print-quoted' to t, and `print-length' and `print-level' to +nil. See also `gnus-bind-print-variables'." (gnus-bind-print-variables (prin1-to-string form))) (defun gnus-pp (form &optional stream) "Use `pp' on FORM in the current buffer. -Bind `print-quoted' and `print-readably' to t, and `print-length' and -`print-level' to nil. See also `gnus-bind-print-variables'." +Bind `print-quoted' to t, and `print-length' and `print-level' to +nil. See also `gnus-bind-print-variables'." (gnus-bind-print-variables (pp form (or stream (current-buffer))))) (defun gnus-pp-to-string (form) "The same as `pp-to-string'. -Bind `print-quoted' and `print-readably' to t, and `print-length' and -`print-level' to nil. See also `gnus-bind-print-variables'." +Bind `print-quoted' to t, and `print-length' and `print-level' to +nil. See also `gnus-bind-print-variables'." (gnus-bind-print-variables (pp-to-string form))) (defun gnus-make-directory (directory) From 03f962a4863c986adbfc2787ea77c2e76056ed52 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 25 Dec 2019 12:01:07 -0800 Subject: [PATCH 02/12] Port x_get_monitor_attributes_fallback to !HAVE_GTK3 * src/xfns.c (x_get_net_workarea) [!HAVE_GTK3]: Define in this case too, since x_get_monitor_attributes_fallback contains a call to it regardless whether HAVE_GTK3 is defined. --- src/xfns.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/xfns.c b/src/xfns.c index 47aa19607f6..0ce1e73397f 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -4576,7 +4576,6 @@ On MS Windows, this just returns nil. */) Return false if and only if the workarea information cannot be obtained via the _NET_WORKAREA root window property. */ -#ifndef HAVE_GTK3 static bool x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect) { @@ -4634,7 +4633,6 @@ x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect) return result; } -#endif #ifndef USE_GTK From e1ce9f34239f0c0d1940223d135797d98f65672d Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Thu, 26 Dec 2019 11:08:56 +0100 Subject: [PATCH 03/12] Don't recommend using 'module-load' for loading modules. 'module-load' most likely doesn't do what users expect. Users should use 'load' and its wrappers, which do the right thing. * doc/lispref/loading.texi (Dynamic Modules): Document disadvantages of 'module-load' and recommend normal 'load' and its wrappers instead. * doc/lispref/internals.texi (Module Functions): Recommend 'load' over 'module-load'. --- doc/lispref/internals.texi | 4 ++-- doc/lispref/loading.texi | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index bccdca65e4e..c7b9e7286b3 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -1423,8 +1423,8 @@ following simple Lisp wrapper: @end lisp The Lisp package which goes with your module could then load the -module using the @code{module-load} primitive (@pxref{Dynamic -Modules}) when the package is loaded into Emacs. +module using the @code{load} primitive (@pxref{Dynamic Modules}) when +the package is loaded into Emacs. @node Module Values @subsection Conversion Between Lisp and Module Values diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi index 3261e6d1888..3ba5fea4ca6 100644 --- a/doc/lispref/loading.texi +++ b/doc/lispref/loading.texi @@ -1217,6 +1217,12 @@ during the initialization. If the initialization succeeds, @code{module-load} returns @code{t}. Note that @var{file} must already have the proper file-name extension, as this function doesn't try looking for files with known extensions, unlike @code{load}. + +Unlike @code{load}, @code{module-load} doesn't record the module in +@code{load-history}, doesn't print any messages, and doesn't protect +against recursive loads. Most users should therefore use @code{load}, +@code{load-file}, @code{load-library}, or @code{require} instead of +@code{module-load}. @end defun Loadable modules in Emacs are enabled by using the From 21c3020fcec0a32122d2680a391864a75393031b Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Thu, 26 Dec 2019 11:31:51 +0100 Subject: [PATCH 04/12] Document some restrictions for module functions. * doc/lispref/internals.texi (Module Functions): Document some restrictions for module functions. --- doc/lispref/internals.texi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index c7b9e7286b3..1d03cbd085b 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -1403,6 +1403,22 @@ the function to that symbol. Note that it is possible to use @code{fset} instead of @code{defalias}; the differences are described in @ref{Defining Functions, defalias}. +Module functions including the @code{emacs_module_init} function +(@pxref{module initialization function}) may only interact with Emacs +by calling environment functions from some live @code{emacs_env} +pointer while being called directly or indirectly from Emacs. In +other words, if a module function wants to call Lisp functions or +Emacs primitives, convert @code{emacs_value} objects to and from C +datatypes (@pxref{Module Values}), or interact with Emacs in any other +way, some call from Emacs to @code{emacs_module_init} or to a module +function must be in the callstack. Module function may not interact +with Emacs while garbage collection is running; @pxref{Garbage +Collection}. They may only interact with Emacs from Lisp interpreter +threads (including the main thread) created by Emacs; @pxref{Threads}. +The @kbd{--module-assertions} command-line option can detect some +violations of the above requirements. @xref{Initial Options,,,emacs, +The GNU Emacs Manual}. + Using the module @acronym{API}, it is possible to define more complex function and data types: interactive functions, inline functions, macros, etc. However, the resulting C code will be cumbersome and From be38e39fccab7c2f8e86c59ffb9c022d3d5b9382 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Thu, 26 Dec 2019 15:38:53 +0200 Subject: [PATCH 05/12] project--find-regexp-in-files: Support remote files * lisp/progmodes/project.el (project--find-regexp-in-files): Support remote files (bug#34343). --- lisp/progmodes/project.el | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index e45cb5db127..d5920d10fcf 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -450,6 +450,9 @@ pattern to search for." (status nil) (hits nil) (xrefs nil) + ;; Support for remote files. + (dir (file-name-directory (car files))) + (remote-id (file-remote-p dir)) ;; 'git ls-files' can output broken symlinks. (command (format "xargs -0 grep %s -snHE -e %s" (if (and case-fold-search @@ -457,10 +460,13 @@ pattern to search for." "-i" "") (shell-quote-argument (xref--regexp-to-extended regexp))))) + (when remote-id + (setq files (mapcar #'file-local-name files))) (with-current-buffer output (erase-buffer) (with-temp-buffer (insert (mapconcat #'identity files "\0")) + (setq default-directory dir) (setq status (project--process-file-region (point-min) (point-max) @@ -478,7 +484,7 @@ pattern to search for." (buffer-substring (point-min) (line-end-position)))) (while (re-search-forward grep-re nil t) (push (list (string-to-number (match-string line-group)) - (match-string file-group) + (concat remote-id (match-string file-group)) (buffer-substring-no-properties (point) (line-end-position))) hits))) (setq xrefs (xref--convert-hits (nreverse hits) regexp)) From 6ab40c1a5176b7bbe5d3f44890477e7b6d07858e Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Thu, 26 Dec 2019 17:31:11 +0200 Subject: [PATCH 06/12] ; Clarify the assumption --- lisp/progmodes/project.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index d5920d10fcf..e21600ffe09 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -450,7 +450,8 @@ pattern to search for." (status nil) (hits nil) (xrefs nil) - ;; Support for remote files. + ;; Support for remote files. The assumption is that, if the + ;; first file is remote, they all are, and on the same host. (dir (file-name-directory (car files))) (remote-id (file-remote-p dir)) ;; 'git ls-files' can output broken symlinks. From 7edb1f0773ddeade0f82630ab7697a3eb0f3bc4b Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Thu, 26 Dec 2019 17:32:30 +0200 Subject: [PATCH 07/12] ; Remove outdated declarations --- lisp/progmodes/elisp-mode.el | 2 -- 1 file changed, 2 deletions(-) diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 7705761365c..9cd852bcaee 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -630,9 +630,7 @@ functions are annotated with \"\" via the ;;; Xref backend -(declare-function xref-make-bogus-location "xref" (message)) (declare-function xref-make "xref" (summary location)) -(declare-function xref-collect-references "xref" (symbol dir)) (defun elisp--xref-backend () 'elisp) From ccd7cd2c51c8a3755b084f93ae3a66a3df8a42f0 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Thu, 26 Dec 2019 17:39:48 +0200 Subject: [PATCH 08/12] Speed up dired-do-find-regexp * lisp/dired-aux.el (dired-do-find-regexp): Speed up (bug#36857). Previously, 'find' was called for every marked file (for plain files and directories both). Now 'find' is only called for directories. --- lisp/dired-aux.el | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index fb1ad6266d6..ce967b0735f 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -2957,6 +2957,8 @@ with the command \\[tags-loop-continue]." (declare-function xref--show-xrefs "xref") (declare-function xref-query-replace-in-results "xref") +(declare-function project--files-in-directory "project") +(declare-function project--find-regexp-in-files "project") ;;;###autoload (defun dired-do-find-regexp (regexp) @@ -2975,19 +2977,24 @@ REGEXP should use constructs supported by your local `grep' command." (require 'xref) (defvar grep-find-ignored-files) (declare-function rgrep-find-ignored-directories "grep" (dir)) - (let* ((files (dired-get-marked-files nil nil nil nil t)) + (let* ((marks (dired-get-marked-files nil nil nil nil t)) (ignores (nconc (mapcar #'file-name-as-directory (rgrep-find-ignored-directories default-directory)) grep-find-ignored-files)) (fetcher (lambda () - (let ((xrefs (mapcan - (lambda (file) - (xref-collect-matches regexp "*" file - (and (file-directory-p file) - ignores))) - files))) + (let (files xrefs) + (mapc + (lambda (mark) + (if (file-directory-p mark) + (setq files (nconc + (project--files-in-directory mark ignores "*") + files)) + (push mark files))) + (nreverse marks)) + (setq xrefs + (project--find-regexp-in-files regexp files)) (unless xrefs (user-error "No matches for: %s" regexp)) xrefs)))) From e8aa6f19e99e5de9a3953fef8ae50e2363531b3d Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 26 Dec 2019 18:20:12 +0200 Subject: [PATCH 09/12] * doc/emacs/buffers.texi (Kill Buffer): Improve indexing. --- doc/emacs/buffers.texi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi index b5a17416d76..7b4e070d1b9 100644 --- a/doc/emacs/buffers.texi +++ b/doc/emacs/buffers.texi @@ -308,6 +308,8 @@ Offer to kill all buffers matching a regular expression. @findex kill-buffer @kindex C-x k +@cindex killing unsaved buffers +@cindex unsaved buffers, killing @kbd{C-x k} (@code{kill-buffer}) kills one buffer, whose name you specify in the minibuffer. The default, used if you type just @key{RET} in the minibuffer, is to kill the current buffer. If you From cd559841537726315d72a303447140f71e34f635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Thu, 26 Dec 2019 19:37:10 +0100 Subject: [PATCH 10/12] Calc: add missing dynamic variable declarations * lisp/calc/calc-alg.el (math-simplify-only, calc-simplify-mode) (math-expand-formulas, calc-poly-div-remainder) (math-living-dangerously, math-simplifying, calc-angle-mode) (calc-prefer-frac, math-poly-base-variable): Declare dynamic variables. * test/lisp/calc/calc-tests.el (calc-poly-div): Add test for at least one bug caused by missing declarations. --- lisp/calc/calc-alg.el | 15 +++++++++++++++ test/lisp/calc/calc-tests.el | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lisp/calc/calc-alg.el b/lisp/calc/calc-alg.el index c3efeeeb62c..4905a455aba 100644 --- a/lisp/calc/calc-alg.el +++ b/lisp/calc/calc-alg.el @@ -30,6 +30,8 @@ ;;; Algebra commands. +(defvar math-simplify-only) + (defun calc-alg-evaluate (arg) (interactive "p") (calc-slow-wrapper @@ -38,6 +40,8 @@ (calc-modify-simplify-mode arg) (calc-enter-result 1 "dsmp" (calc-top 1)))))) +(defvar calc-simplify-mode) + (defun calc-modify-simplify-mode (arg) (if (= (math-abs arg) 2) (setq calc-simplify-mode 'alg) @@ -67,6 +71,8 @@ (calc-with-default-simplification (calc-enter-result 1 "esmp" (math-simplify-extended (calc-top-n 1)))))) +(defvar math-expand-formulas) + (defun calc-expand-formula (arg) (interactive "p") (calc-slow-wrapper @@ -160,6 +166,8 @@ (calc-binary-op "pgcd" 'calcFunc-pgcd arg))) +(defvar calc-poly-div-remainder) + (defun calc-poly-div (arg) (interactive "P") (calc-slow-wrapper @@ -303,6 +311,7 @@ (math-beforep (car a) (car b))))) (t (string-lessp (car a) (car b))))) +(defvar math-living-dangerously) (defsubst math-simplify-extended (a) (let ((math-living-dangerously t)) @@ -363,6 +372,9 @@ ;; math-normalize-error is declared in calc.el. (defvar math-normalize-error) +(defvar math-simplifying) +(defvar calc-angle-mode) + (defun math-simplify (top-expr) (let ((math-simplifying t) (calc-angle-mode (if (calc-input-angle-units top-expr) @@ -677,6 +689,8 @@ and should return the simplified expression to use (or nil)." (math-make-frac (math-gcd (nth 1 a) (nth 1 b)) (math-gcd (nth 2 a) (nth 2 b))))))) +(defvar calc-prefer-frac) + (math-defsimplify % (and (Math-realp (nth 2 expr)) (Math-posp (nth 2 expr)) @@ -1671,6 +1685,7 @@ and should return the simplified expression to use (or nil)." (defvar math-is-poly-degree) (defvar math-is-poly-loose) (defvar math-var) +(defvar math-poly-base-variable) (defun math-is-polynomial (expr var &optional degree loose) (let* ((math-poly-base-variable (if loose diff --git a/test/lisp/calc/calc-tests.el b/test/lisp/calc/calc-tests.el index 3f5adceeff1..33e6b14827f 100644 --- a/test/lisp/calc/calc-tests.el +++ b/test/lisp/calc/calc-tests.el @@ -318,6 +318,21 @@ An existing calc stack is reused, otherwise a new one is created." '(vec (calcFunc-eq (var x var-x) 3) (calcFunc-eq (var y var-y) 0))))) +(ert-deftest calc-poly-div () + "Test polynomial division, and that the remainder is recorded in the trail." + (with-current-buffer (calc-trail-buffer) + (let ((inhibit-read-only t)) + (erase-buffer) + + (calc-eval "2x**3+1" 'push) + (calc-eval "x**2+2x" 'push) + (calc-poly-div nil) + (let ((tos (calc-top-n 1)) + (trail (buffer-string))) + (calc-pop 0) + (should (equal tos '(- (* 2 (var x var-x)) 4))) + (should (equal trail "pdiv 2 * x - 4\nprem 8 * x + 1\n")))))) + (provide 'calc-tests) ;;; calc-tests.el ends here From 47a73e3e142bc816872cf66c5e95b867d3ad49b7 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Thu, 26 Dec 2019 21:13:38 +0100 Subject: [PATCH 11/12] Update Windows build documentation * admin/nt/dist-build/README-scripts: Update with branch and snapshot information. --- admin/nt/dist-build/README-scripts | 53 +++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/admin/nt/dist-build/README-scripts b/admin/nt/dist-build/README-scripts index 1c62a866724..4c3554e8df5 100644 --- a/admin/nt/dist-build/README-scripts +++ b/admin/nt/dist-build/README-scripts @@ -68,7 +68,8 @@ uploaded. Build Process ------------- -For each major version: +For each major version +---------------------- The dependencies files need to be created. This can be around the time of the pre-tests, then used for all releases of that version, to @@ -78,9 +79,9 @@ To do this: Update msys to the latest version with `pacman -Syu`. -Then run build-dep-zips.py, in this directory. Three zips will be -created, containing the 64bit and 32bit dependencies, as well as the -source for these. +Then run build-dep-zips.py, in the ~/emacs-build/deps directory. Three +zips will be created, containing the 64bit and 32bit dependencies, as +well as the source for these. For emacs release or pre-test version: @@ -90,3 +91,47 @@ with the tag of the last version. Then run `build-zips.sh` in this worktree. Eventually, four new zip files will be created in ~/emacs-upload from where they can be signed and uploaded with `gnupload`. + + +For snapshots from Master +------------------------- + +Snapshots are generally created from master when there is a release +branch on which a release has already been created. At this point, +only pre-tests or full releases need to happen from the release +branch. + +To do this: + +Update msys to the latest version with `pacman -Syu`. + +Then run build-dep-zips.py, in ~/emacs-build/deps directory. Three +zips will be created, containing the 64bit and 32bit dependencies, as +well as the source for these. These deps files contain the date of +creation in their name. The deps file can be reused as desired, or a +new version created. Where multiple deps files exist, the most +recent will be used. + +Now, run `build-zips.sh -s` to build a snapshot release. + + +For snapshots from a Release Branch +----------------------------------- + +Snapshots can be built from a release branch; this is really only +useful before a pre-test has happened. + +The process is the same as for building from the master branch, except +that the release branch should already exist as a worktree, and the +version number must be added to the command line with `build-zips.sh +-V 27 -s`. The final zips will be named after the branch rather than +the version (e.g emacs-27-2019-12-26.zip) rather than than the Emacs +version (e.g emacs-27.0.50.zip). + +For snapshots from another branch +--------------------------------- + +Snapshots can be build from any other branch. There is rarely a need +to do this, except where some significant, wide-ranging feature is +being added on a feature branch. In this case, the branch can be +given using `build-zips.sh -b pdumper -s` for example. From 8aad80d6613576faa8910336863474d485e1c030 Mon Sep 17 00:00:00 2001 From: Phillip Lord Date: Thu, 26 Dec 2019 23:01:02 +0100 Subject: [PATCH 12/12] Fix installer build * admin/nt/dist-build/build-zips.sh: Ensure that NSIS build always uses the actual build number to locate its files. --- admin/nt/dist-build/build-zips.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/admin/nt/dist-build/build-zips.sh b/admin/nt/dist-build/build-zips.sh index cff6fdec3e0..d8cbee30754 100755 --- a/admin/nt/dist-build/build-zips.sh +++ b/admin/nt/dist-build/build-zips.sh @@ -160,23 +160,27 @@ while getopts "36gb:hnsiV:" opt; do esac done -if [ -z $VERSION ]; + +## ACTUAL_VERSION is the version declared by emacs +if [ -z $ACTUAL_VERSION ]; then - VERSION=` + ACTUAL_VERSION=` sed -n 's/^AC_INIT(GNU Emacs,[ ]*\([^ ,)]*\).*/\1/p' < ../../../configure.ac ` fi -if [ -z $VERSION ]; +if [ -z $ACTUAL_VERSION ]; then echo [build] Cannot determine Emacs version exit 1 fi +## VERSION is the version that we want to call Emacs +VERSION=$ACTUAL_VERSION + + MAJOR_VERSION="$(echo $VERSION | cut -d'.' -f1)" -## ACTUAL VERSION is the version declared by emacs -ACTUAL_VERSION=$VERSION ## VERSION includes the word snapshot if necessary VERSION=$VERSION$SNAPSHOT