
# HG changeset patch
# User Phil Thompson <phil@riverbankcomputing.com>
# Date 1400225095 -3600
# Node ID 8a3fb94329aac9c6b3bf456d95e691734295c72b
# Parent  61da788f455f12ff53d5c140a8b8a01189df315f
Changed the handling of timelines so that the latest version is enabled if no
known version is explicitly enabled.
Added the -B option to sip to allow timeline backstops to be defined.

diff -r 61da788f455f -r 8a3fb94329aa sipgen/main.c
--- a/sipgen/main.c	Thu May 15 09:03:14 2014 +0100
+++ b/sipgen/main.c	Fri May 16 08:24:55 2014 +0100
@@ -55,12 +55,13 @@
     KwArgs kwArgs;
     FILE *file;
     sipSpec spec;
-    stringList *versions, *xfeatures, *extracts;
+    stringList *versions, *backstops, *xfeatures, *extracts;
 
     /* Initialise. */
     sipVersion = SIP_VERSION_STR;
     includeDirList = NULL;
     versions = NULL;
+    backstops = NULL;
     xfeatures = NULL;
     buildFile = NULL;
     codeDir = NULL;
@@ -83,7 +84,7 @@
     /* Parse the command line. */
     optnr = 1;
 
-    while ((arg = parseopt(argc, argv, "hVa:b:ec:d:gI:j:km:op:Prs:t:Twx:X:z:", &flagFile, &optnr, &optarg)) != '\0')
+    while ((arg = parseopt(argc, argv, "hVa:b:B:ec:d:gI:j:km:op:Prs:t:Twx:X:z:", &flagFile, &optnr, &optarg)) != '\0')
         switch (arg)
         {
         case 'o':
@@ -116,6 +117,11 @@
             buildFile = optarg;
             break;
 
+        case 'B':
+            /* Define a backstop. */
+            appendString(&backstops, optarg);
+            break;
+
         case 'e':
             /* Enable exceptions. */
             exceptions = TRUE;
@@ -230,7 +236,8 @@
         warning(DeprecationWarning, "the -k flag is deprecated\n");
 
     /* Parse the input file. */
-    parse(&spec, file, filename, versions, xfeatures, kwArgs, protHack);
+    parse(&spec, file, filename, versions, backstops, xfeatures, kwArgs,
+            protHack);
 
     /* Verify and transform the parse tree. */
     transform(&spec);
@@ -513,12 +520,13 @@
 {
     printf(
 "Usage:\n"
-"    %s [-h] [-V] [-a file] [-b file] [-c dir] [-d file] [-e] [-g] [-I dir] [-j #] [-k] [-m file] [-o] [-p module] [-P] [-r] [-s suffix] [-t tag] [-T] [-w] [-x feature] [-X id:file] [-z file] [file]\n"
+"    %s [-h] [-V] [-a file] [-b file] [-B tag] [-c dir] [-d file] [-e] [-g] [-I dir] [-j #] [-k] [-m file] [-o] [-p module] [-P] [-r] [-s suffix] [-t tag] [-T] [-w] [-x feature] [-X id:file] [-z file] [file]\n"
 "where:\n"
 "    -h          display this help message\n"
 "    -V          display the %s version number\n"
 "    -a file     the name of the QScintilla API file [default not generated]\n"
 "    -b file     the name of the build file [default none generated]\n"
+"    -B tag      add tag to the list of timeline backstops\n"
 "    -c dir      the name of the code directory [default not generated]\n"
 "    -d file     the name of the documentation file (deprecated) [default not generated]\n"
 "    -e          enable support for exceptions [default disabled]\n"
@@ -550,5 +558,5 @@
  */
 static void usage(void)
 {
-    fatal("Usage: %s [-h] [-V] [-a file] [-b file] [-c dir] [-d file] [-e] [-g] [-I dir] [-j #] [-k] [-m file] [-o] [-p module] [-P] [-r] [-s suffix] [-t tag] [-T] [-w] [-x feature] [-X id:file] [-z file] [file]\n", sipPackage);
+    fatal("Usage: %s [-h] [-V] [-a file] [-b file] [-B tag] [-c dir] [-d file] [-e] [-g] [-I dir] [-j #] [-k] [-m file] [-o] [-p module] [-P] [-r] [-s suffix] [-t tag] [-T] [-w] [-x feature] [-X id:file] [-z file] [file]\n", sipPackage);
 }
diff -r 61da788f455f -r 8a3fb94329aa sipgen/metasrc/parser.y
--- a/sipgen/metasrc/parser.y	Thu May 15 09:03:14 2014 +0100
+++ b/sipgen/metasrc/parser.y	Fri May 16 08:24:55 2014 +0100
@@ -31,6 +31,7 @@
 
 
 static sipSpec *currentSpec;            /* The current spec being parsed. */
+static stringList *backstops;           /* The list of backstops. */
 static stringList *neededQualifiers;    /* The list of required qualifiers. */
 static stringList *excludedQualifiers;  /* The list of excluded qualifiers. */
 static moduleDef *currentModule;        /* The current module being parsed. */
@@ -174,6 +175,7 @@
 static void mappedTypeAnnos(mappedTypeDef *mtd, optFlags *optflgs);
 static void add_new_deref(argDef *new, argDef *orig, int isconst);
 static void add_derefs(argDef *dst, argDef *src);
+static int isBackstop(qualDef *qd);
 %}
 
 %union {
@@ -4386,7 +4388,7 @@
  * Parse the specification.
  */
 void parse(sipSpec *spec, FILE *fp, char *filename, stringList *tsl,
-        stringList *xfl, KwArgs kwArgs, int protHack)
+        stringList *bsl, stringList *xfl, KwArgs kwArgs, int protHack)
 {
     classTmplDef *tcd;
 
@@ -4396,6 +4398,7 @@
     spec->genc = -1;
 
     currentSpec = spec;
+    backstops = bsl;
     neededQualifiers = tsl;
     excludedQualifiers = xfl;
     currentModule = NULL;
@@ -7893,7 +7896,7 @@
  */
 static int timePeriod(const char *lname, const char *uname)
 {
-    int this, line;
+    int line;
     qualDef *qd, *lower, *upper;
     moduleDef *mod;
 
@@ -7938,40 +7941,59 @@
     /* Handle the SIP version number pseudo-timeline. */
     if (line < 0)
     {
-        if (lower != NULL && lower->order > SIP_VERSION)
+        if (lower != NULL && SIP_VERSION < lower->order)
             return FALSE;
 
-        if (upper != NULL && upper->order <= SIP_VERSION)
+        if (upper != NULL && SIP_VERSION >= upper->order)
             return FALSE;
 
         return TRUE;
     }
 
-    this = FALSE;
-
     for (qd = mod->qualifiers; qd != NULL; qd = qd->next)
     {
         if (qd->qtype != time_qualifier || qd->line != line)
             continue;
 
-        if (lower != NULL && qd->order < lower->order)
-            continue;
-
-        if (upper != NULL && qd->order >= upper->order)
-            continue;
-
-        /*
-         * This is within the required range so if it is also needed then the
-         * expression is true.
-         */
         if (selectedQualifier(neededQualifiers, qd))
         {
-            this = TRUE;
-            break;
-        }
-    }
-
-    return this;
+            if (lower != NULL && qd->order < lower->order)
+                return FALSE;
+
+            if (upper != NULL && qd->order >= upper->order)
+                return FALSE;
+
+            return TRUE;
+        }
+    }
+
+    /*
+     * If there is no upper bound then assume the expression is true unless
+     * the lower bound is a backstop.
+     */
+    if (upper == NULL)
+        return !isBackstop(lower);
+
+    /*
+     * If the upper limit corresponds to a backstop then assume the expression
+     * is true.
+     */
+    return isBackstop(upper);
+}
+
+
+/*
+ * See if a qualifier is a backstop.
+ */
+static int isBackstop(qualDef *qd)
+{
+    stringList *sl;
+
+    for (sl = backstops; sl != NULL; sl = sl->next)
+        if (strcmp(qd->name, sl->s) == 0)
+            return TRUE;
+
+    return FALSE;
 }
 
 
diff -r 61da788f455f -r 8a3fb94329aa sipgen/sip.h.in
--- a/sipgen/sip.h	Thu May 15 09:03:14 2014 +0100
+++ b/sipgen/sip.h	Fri May 16 08:24:55 2014 +0100
@@ -1255,7 +1255,8 @@
 extern stringList *includeDirList;      /* The include directory list for SIP files. */
 
 
-void parse(sipSpec *, FILE *, char *, stringList *, stringList *, KwArgs, int);
+void parse(sipSpec *, FILE *, char *, stringList *, stringList *, stringList *,
+        KwArgs, int);
 void parserEOF(const char *,parserContext *);
 void transform(sipSpec *);
 void generateCode(sipSpec *, char *, char *, char *, const char *, int, int,
diff -r 61da788f455f -r 8a3fb94329aa sphinx/command_line.rst
--- a/sphinx/command_line.rst	Thu May 15 09:03:14 2014 +0100
+++ b/sphinx/command_line.rst	Fri May 16 08:24:55 2014 +0100
@@ -37,6 +37,14 @@
     to generate a platform and compiler specific Makefile for the module.  By
     default the file is not generated.
 
+.. cmdoption:: -B <TAG>
+
+    .. versionadded:: 4.16
+
+    The tag is added to the list of *backstops*.  The option may be given more
+    than once if multiple timelines have been defined.  See the
+    :directive:`%Timeline` directive for more details.
+
 .. cmdoption:: -c <DIR>
 
     The name of the directory (which must exist) into which all of the
diff -r 61da788f455f -r 8a3fb94329aa sphinx/directives.rst
--- a/sphinx/directives.rst	Thu May 15 09:03:14 2014 +0100
+++ b/sphinx/directives.rst	Fri May 16 08:24:55 2014 +0100
@@ -2262,8 +2262,13 @@
 specification are processed or ignored.
 
 Versions are mutually exclusive - only one version can be enabled at a time.
-By default all versions are disabled.  The SIP :option:`-t <sip -t>` command
-line option is used to enable a version.
+The SIP :option:`-t <sip -t>` command line option is used to enable a version.
+If a timeline does not have a version explicitly enabled then the latest
+version will be enabled automatically.
+
+The :option:`-B <sip -B>` command line option may be used to define a
+*backstop* for a timeline.  Instead of automatically enabling the latest
+version, the version immediately preceeding the backstop is enabled instead.
 
 The :directive:`%Timeline` directive can be used any number of times in a
 module to allow multiple libraries to be wrapped in the same module.
diff -r 61da788f455f -r 8a3fb94329aa sphinx/incompatibilities.rst
--- a/sphinx/incompatibilities.rst	Thu May 15 09:03:14 2014 +0100
+++ b/sphinx/incompatibilities.rst	Fri May 16 08:24:55 2014 +0100
@@ -5,6 +5,20 @@
 SIP.  Normally these are the removal of previously deprecated features.
 
 
+SIP v4.16
+---------
+
+Prior to this version, if no valid version tag was specified using the
+:option:`-t <sip -t>` command line option to :program:`sip` then all versions
+of the corresponding timeline were considered disabled.
+
+Starting with this version SIP assumes that the latest version is enabled if no
+valid version tag was specified.  Exactly what is meant by the latest version
+can be changed by using the :option:`-B <sip -B>` command line option to
+define a *backstop* for a timeline.  See the :directive:`%Timeline` directive
+for more details.
+
+
 SIP v4.14.4
 -----------
 

