Index: trunk/ppSim/src/Makefile.am
===================================================================
--- trunk/ppSim/src/Makefile.am	(revision 22718)
+++ trunk/ppSim/src/Makefile.am	(revision 23139)
@@ -1,5 +1,14 @@
 bin_PROGRAMS = ppSim ppSimSequence
 
-ppSim_CPPFLAGS = $(PSLIB_CFLAGS) $(PSMODULE_CFLAGS) $(PSPHOT_CFLAGS) $(PSASTRO_CFLAGS) $(ppSim_CFLAGS)
+PPSIM_VERSION=`if [ -e ../../VERSION ]; then cat ../../VERSION; else svnversion; fi`
+PPSIM_BRANCH=`if [ -e ../../BRANCH ]; then cat ../../BRANCH; else svn info | sed -n -e '/URL:/ h' -e '/Repository Root:/ { x; H; x; s|Repository Root: \(.*\)\nURL: \1\(.*\)|\2| ; s|^/|| ; s|/[a-zA-Z]*/src.*|| ; p }'; fi`
+PPSIM_SOURCE=`if [ -e ../../SOURCE ]; then cat ../../SOURCE; else svn info | sed -n -e 's/Repository UUID: // p'; fi`
+
+# Force recompilation of ppSimVersion.c, since it gets the version information
+ppSimVersion.c: FORCE
+	touch ppSimVersion.c
+FORCE: ;
+
+ppSim_CPPFLAGS = $(PSLIB_CFLAGS) $(PSMODULE_CFLAGS) $(PSPHOT_CFLAGS) $(PSASTRO_CFLAGS) $(ppSim_CFLAGS) -DPPSIM_VERSION=\"$(PPSIM_VERSION)\" -DPPSIM_BRANCH=\"$(PPSIM_BRANCH)\" -DPPSIM_SOURCE=\"$(PPSIM_SOURCE)\"
 ppSim_LDFLAGS = $(PSLIB_LIBS) $(PSMODULE_LIBS) $(PSPHOT_LIBS) $(PSASTRO_LIBS)
 ppSim_SOURCES = \
@@ -35,5 +44,6 @@
 	ppSimMosaicChip.c	  \
 	ppSimRandomGaussian.c	  \
-	ppSimBadPixels.c
+	ppSimBadPixels.c          \
+	ppSimVersion.c
 
 ppSimSequence_CPPFLAGS = $(PSLIB_CFLAGS) $(PSMODULE_CFLAGS) $(PSASTRO_CFLAGS) $(ppSim_CFLAGS)
Index: trunk/ppSim/src/ppSim.h
===================================================================
--- trunk/ppSim/src/ppSim.h	(revision 22718)
+++ trunk/ppSim/src/ppSim.h	(revision 23139)
@@ -19,7 +19,7 @@
 
 // Compare a value with minimum and maximum values, replacing where required.
-#define COMPARE(VALUE,MIN,MAX) {		\
-        if (VALUE < MIN) { MIN = VALUE; }	\
-        if (VALUE > MAX) { MAX = VALUE; }	\
+#define COMPARE(VALUE,MIN,MAX) {                \
+        if (VALUE < MIN) { MIN = VALUE; }       \
+        if (VALUE > MAX) { MAX = VALUE; }       \
     }
 
@@ -147,30 +147,30 @@
 float ppSimMagToFlux (float mag, float zp);
 
-float ppSimArgToRecipeF32(bool *status, 
-			  psMetadata *options,    // Target to which to add value
-			  const char *recipeName, // Name for value in the recipe
-			  psMetadata *arguments,  // Command-line arguments
-			  const char *argName	 // Argument name in the command-line arguments
+float ppSimArgToRecipeF32(bool *status,
+                          psMetadata *options,    // Target to which to add value
+                          const char *recipeName, // Name for value in the recipe
+                          psMetadata *arguments,  // Command-line arguments
+                          const char *argName    // Argument name in the command-line arguments
     );
 
 int ppSimArgToRecipeS32(bool *status,
-			psMetadata *options,    // Target to which to add value
-			const char *recipeName, // Name for value in the recipe
-			psMetadata *arguments,  // Command-line arguments
-			const char *argName	 // Argument name in the command-line arguments
+                        psMetadata *options,    // Target to which to add value
+                        const char *recipeName, // Name for value in the recipe
+                        psMetadata *arguments,  // Command-line arguments
+                        const char *argName      // Argument name in the command-line arguments
     );
 
 char *ppSimArgToRecipeStr(bool *status,
-			  psMetadata *options,    // Target to which to add value
-			  const char *recipeName, // Name for value in the recipe
-			  psMetadata *arguments,  // Command-line arguments
-			  const char *argName	 // Argument name in the command-line arguments
+                          psMetadata *options,    // Target to which to add value
+                          const char *recipeName, // Name for value in the recipe
+                          psMetadata *arguments,  // Command-line arguments
+                          const char *argName    // Argument name in the command-line arguments
     );
 
 bool ppSimArgToRecipeBool(bool *status,
-			  psMetadata *options,    // Target to which to add value
-			  const char *recipeName, // Name for value in the recipe
-			  psMetadata *arguments,  // Command-line arguments
-			  const char *argName	    // Argument name in the command-line arguments
+                          psMetadata *options,    // Target to which to add value
+                          const char *recipeName, // Name for value in the recipe
+                          psMetadata *arguments,  // Command-line arguments
+                          const char *argName       // Argument name in the command-line arguments
     );
 
@@ -198,3 +198,12 @@
 bool ppSimDefinePixels (psArray *sources, pmReadout *readout, psMetadata *recipe);
 
+/// Return software version
+psString ppSimVersion(void);
+
+/// Return software source
+psString ppSimSource(void);
+
+/// Return long version information
+psString ppSimVersionLong(void);
+
 #endif
Index: trunk/ppSim/src/ppSimVersion.c
===================================================================
--- trunk/ppSim/src/ppSimVersion.c	(revision 23139)
+++ trunk/ppSim/src/ppSimVersion.c	(revision 23139)
@@ -0,0 +1,39 @@
+#include "ppSim.h"
+
+
+psString ppSimVersion(void)
+{
+#ifndef PPSIM_VERSION
+#error "PPSIM_VERSION is not set"
+#endif
+#ifndef PPSIM_BRANCH
+#error "PPSIM_BRANCH is not set"
+#endif
+    return psStringCopy(PPSIM_BRANCH "@" PPSIM_VERSION);
+}
+
+psString ppSimSource(void)
+{
+#ifndef PPSIM_SOURCE
+#error "PPSIM_SOURCE is not set"
+#endif
+    return psStringCopy(PPSIM_SOURCE);
+}
+
+psString ppSimVersionLong(void)
+{
+    psString version = ppSimVersion();  // Version, to return
+    psString source = ppSimSource();    // Source
+
+    psStringPrepend(&version, "ppSim ");
+    psStringAppend(&version, " from %s, built %s, %s", source, __DATE__, __TIME__);
+    psFree(source);
+
+#ifdef __OPTIMIZE__
+    psStringAppend(&version, " optimised");
+#else
+    psStringAppend(&version, " unoptimised");
+#endif
+
+    return version;
+};
