Added the 'py_ssize_t_clean' argument to '%Module' directive

This is based on an upstream changeset to SIP.  It was backported to
sip-4.19.23 and the parser must be regenerated with the following
commands:

  flex --outfile=sipgen/lexer.c sipgen/metasrc/lexer.l
  bison --yacc -Wcounterexamples --defines=sipgen/parser.h \
        --output=sipgen/parser.c sipgen/metasrc/parser.y

Signed-off-by: Rob Woolley <rob.woolley@windriver.com>

# GitHub Repository: https://github.com/Python-SIP/
# Commit ID 18e9e9c5a1fb7e19f7ea4d476eb3a99685fce629

Added the 'py_ssize_t_clean' argument to the '%Module' directive.

Index: sip-4.19.23/sipgen/gencode.c
===================================================================
--- sip-4.19.23.orig/sipgen/gencode.c
+++ sip-4.19.23/sipgen/gencode.c
@@ -593,6 +593,12 @@ static void generateInternalAPIHeader(si
 
     declareLimitedAPI(py_debug, mod, fp);
 
+    if (isPY_SSIZE_T_CLEAN(mod))
+        prcode(fp,
+"\n"
+"#define PY_SSIZE_T_CLEAN\n"
+            );
+
     prcode(fp,
 "\n"
 "#include <sip.h>\n"
@@ -1138,6 +1144,12 @@ static void generateCompositeCpp(sipSpec
 
     declareLimitedAPI(py_debug, NULL, fp);
 
+    if (isPY_SSIZE_T_CLEAN(pt->module))
+        prcode(fp,
+"\n"
+"#define PY_SSIZE_T_CLEAN\n"
+            );
+
     prcode(fp,
 "\n"
 "#include <Python.h>\n"
Index: sip-4.19.23/sipgen/metasrc/lexer.l
===================================================================
--- sip-4.19.23.orig/sipgen/metasrc/lexer.l
+++ sip-4.19.23/sipgen/metasrc/lexer.l
@@ -155,6 +155,7 @@ SIP_RXOBJ_DIS               {return TK_S
 SIP_SLOT_CON                {return TK_SIPSLOTCON;}
 SIP_SLOT_DIS                {return TK_SIPSLOTDIS;}
 SIP_SSIZE_T                 {return TK_SIPSSIZET;}
+Py_ssize_t                  {return TK_SIPSSIZET;}
 SIP_QOBJECT                 {return TK_QOBJECT;}
 \.\.\.                      {return TK_ELLIPSIS;}
 
@@ -173,6 +174,7 @@ SIP_QOBJECT                 {return TK_Q
 <directive>timestamp        {return TK_TIMESTAMP;}
 <directive>type             {return TK_TYPE;}
 <directive>use_argument_names   {return TK_USEARGNAMES;}
+<directive>py_ssize_t_clean {return TK_PYSSIZETCLEAN;}
 <directive>use_limited_api  {return TK_USELIMITEDAPI;}
 <directive>all_raise_py_exception   {return TK_ALLRAISEPYEXC;}
 <directive>call_super_init  {return TK_CALLSUPERINIT;}
Index: sip-4.19.23/sipgen/metasrc/parser.y
===================================================================
--- sip-4.19.23.orig/sipgen/metasrc/parser.y
+++ sip-4.19.23/sipgen/metasrc/parser.y
@@ -182,9 +182,9 @@ static void addProperty(sipSpec *pt, mod
         docstringDef *docstring);
 static moduleDef *configureModule(sipSpec *pt, moduleDef *module,
         const char *filename, const char *name, int c_module, KwArgs kwargs,
-        int use_arg_names, int use_limited_api, int call_super_init,
-        int all_raise_py_exc, const char *def_error_handler,
-        docstringDef *docstring);
+        int use_arg_names, int py_ssize_t_clean, int use_limited_api,
+        int call_super_init, int all_raise_py_exc,
+        const char *def_error_handler, docstringDef *docstring);
 static void addAutoPyName(moduleDef *mod, const char *remove_leading);
 static KwArgs convertKwArgs(const char *kwargs);
 static void checkAnnos(optFlags *annos, const char *valid[]);
@@ -389,6 +389,7 @@ static scopedNameDef *fullyQualifiedName
 %token          TK_TIMESTAMP
 %token          TK_TYPE
 %token          TK_USEARGNAMES
+%token          TK_PYSSIZETCLEAN
 %token          TK_USELIMITEDAPI
 %token          TK_ALLRAISEPYEXC
 %token          TK_CALLSUPERINIT
@@ -1908,9 +1909,10 @@ module: TK_MODULE module_args module_bod
             if (notSkipping())
                 currentModule = configureModule(currentSpec, currentModule,
                         currentContext.filename, $2.name, $2.c_module,
-                        $2.kwargs, $2.use_arg_names, $2.use_limited_api,
-                        $2.call_super_init, $2.all_raise_py_exc,
-                        $2.def_error_handler, $3.docstring);
+                        $2.kwargs, $2.use_arg_names, $2.py_ssize_t_clean,
+                        $2.use_limited_api, $2.call_super_init,
+                        $2.all_raise_py_exc, $2.def_error_handler,
+                        $3.docstring);
         }
     |   TK_CMODULE dottedname optnumber {
             deprecated("%CModule is deprecated, use %Module and the 'language' argument instead");
@@ -1918,7 +1920,7 @@ module: TK_MODULE module_args module_bod
             if (notSkipping())
                 currentModule = configureModule(currentSpec, currentModule,
                         currentContext.filename, $2, TRUE, defaultKwArgs,
-                        FALSE, FALSE, -1, FALSE, NULL, NULL);
+                        FALSE, FALSE, FALSE, -1, FALSE, NULL, NULL);
         }
     ;
 
@@ -1930,6 +1932,7 @@ module_args:    dottedname {resetLexerSt
             $$.kwargs = defaultKwArgs;
             $$.name = $1;
             $$.use_arg_names = FALSE;
+            $$.py_ssize_t_clean = FALSE;
             $$.use_limited_api = FALSE;
             $$.all_raise_py_exc = FALSE;
             $$.call_super_init = -1;
@@ -1950,6 +1953,7 @@ module_arg_list:    module_arg
             case TK_LANGUAGE: $$.c_module = $3.c_module; break;
             case TK_NAME: $$.name = $3.name; break;
             case TK_USEARGNAMES: $$.use_arg_names = $3.use_arg_names; break;
+            case TK_PYSSIZETCLEAN: $$.py_ssize_t_clean = $3.py_ssize_t_clean; break;
             case TK_USELIMITEDAPI: $$.use_limited_api = $3.use_limited_api; break;
             case TK_ALLRAISEPYEXC: $$.all_raise_py_exc = $3.all_raise_py_exc; break;
             case TK_CALLSUPERINIT: $$.call_super_init = $3.call_super_init; break;
@@ -1965,6 +1969,7 @@ module_arg: TK_KWARGS '=' TK_STRING_VALU
             $$.kwargs = convertKwArgs($3);
             $$.name = NULL;
             $$.use_arg_names = FALSE;
+            $$.py_ssize_t_clean = FALSE;
             $$.use_limited_api = FALSE;
             $$.all_raise_py_exc = FALSE;
             $$.call_super_init = -1;
@@ -1983,6 +1988,7 @@ module_arg: TK_KWARGS '=' TK_STRING_VALU
             $$.kwargs = defaultKwArgs;
             $$.name = NULL;
             $$.use_arg_names = FALSE;
+            $$.py_ssize_t_clean = FALSE;
             $$.use_limited_api = FALSE;
             $$.all_raise_py_exc = FALSE;
             $$.call_super_init = -1;
@@ -1995,6 +2001,7 @@ module_arg: TK_KWARGS '=' TK_STRING_VALU
             $$.kwargs = defaultKwArgs;
             $$.name = $3;
             $$.use_arg_names = FALSE;
+            $$.py_ssize_t_clean = FALSE;
             $$.use_limited_api = FALSE;
             $$.all_raise_py_exc = FALSE;
             $$.call_super_init = -1;
@@ -2007,6 +2014,20 @@ module_arg: TK_KWARGS '=' TK_STRING_VALU
             $$.kwargs = defaultKwArgs;
             $$.name = NULL;
             $$.use_arg_names = $3;
+            $$.py_ssize_t_clean = FALSE;
+            $$.use_limited_api = FALSE;
+            $$.all_raise_py_exc = FALSE;
+            $$.call_super_init = -1;
+            $$.def_error_handler = NULL;
+        }
+    |   TK_PYSSIZETCLEAN '=' bool_value {
+            $$.token = TK_PYSSIZETCLEAN;
+
+            $$.c_module = FALSE;
+            $$.kwargs = defaultKwArgs;
+            $$.name = NULL;
+            $$.use_arg_names = FALSE;
+            $$.py_ssize_t_clean = $3;
             $$.use_limited_api = FALSE;
             $$.all_raise_py_exc = FALSE;
             $$.call_super_init = -1;
@@ -2019,6 +2040,7 @@ module_arg: TK_KWARGS '=' TK_STRING_VALU
             $$.kwargs = defaultKwArgs;
             $$.name = NULL;
             $$.use_arg_names = FALSE;
+            $$.py_ssize_t_clean = FALSE;
             $$.use_limited_api = $3;
             $$.all_raise_py_exc = FALSE;
             $$.call_super_init = -1;
@@ -2031,6 +2053,7 @@ module_arg: TK_KWARGS '=' TK_STRING_VALU
             $$.kwargs = defaultKwArgs;
             $$.name = NULL;
             $$.use_arg_names = FALSE;
+            $$.py_ssize_t_clean = FALSE;
             $$.use_limited_api = FALSE;
             $$.all_raise_py_exc = $3;
             $$.call_super_init = -1;
@@ -2043,6 +2066,7 @@ module_arg: TK_KWARGS '=' TK_STRING_VALU
             $$.kwargs = defaultKwArgs;
             $$.name = NULL;
             $$.use_arg_names = FALSE;
+            $$.py_ssize_t_clean = FALSE;
             $$.use_limited_api = FALSE;
             $$.all_raise_py_exc = FALSE;
             $$.call_super_init = $3;
@@ -2055,6 +2079,7 @@ module_arg: TK_KWARGS '=' TK_STRING_VALU
             $$.kwargs = defaultKwArgs;
             $$.name = NULL;
             $$.use_arg_names = FALSE;
+            $$.py_ssize_t_clean = FALSE;
             $$.use_limited_api = FALSE;
             $$.all_raise_py_exc = FALSE;
             $$.call_super_init = -1;
@@ -2072,6 +2097,7 @@ module_arg: TK_KWARGS '=' TK_STRING_VALU
             $$.kwargs = defaultKwArgs;
             $$.name = NULL;
             $$.use_arg_names = FALSE;
+            $$.py_ssize_t_clean = FALSE;
             $$.use_limited_api = FALSE;
             $$.all_raise_py_exc = FALSE;
             $$.call_super_init = -1;
@@ -9513,9 +9539,9 @@ static void addProperty(sipSpec *pt, mod
  */
 static moduleDef *configureModule(sipSpec *pt, moduleDef *module,
         const char *filename, const char *name, int c_module, KwArgs kwargs,
-        int use_arg_names, int use_limited_api, int call_super_init,
-        int all_raise_py_exc, const char *def_error_handler,
-        docstringDef *docstring)
+        int use_arg_names, int py_ssize_t_clean, int use_limited_api,
+        int call_super_init, int all_raise_py_exc,
+        const char *def_error_handler, docstringDef *docstring)
 {
     moduleDef *mod;
 
@@ -9549,6 +9575,9 @@ static moduleDef *configureModule(sipSpe
     if (use_arg_names)
         setUseArgNames(module);
 
+    if (py_ssize_t_clean)
+        setPY_SSIZE_T_CLEAN(module);
+
     if (use_limited_api)
         setUseLimitedAPI(module);
 
Index: sip-4.19.23/sipgen/sip.h
===================================================================
--- sip-4.19.23.orig/sipgen/sip.h
+++ sip-4.19.23/sipgen/sip.h
@@ -93,6 +93,7 @@
 #define MOD_SUPER_INIT_UNDEF    0x0000  /* Calling super().__init__() is undefined. */
 #define MOD_SUPER_INIT_MASK     0x0180  /* The mask for the above flags. */
 #define MOD_SETTING_IMPORTS     0x0200  /* Imports are being set. */
+#define MOD_PY_SSIZE_T_CLEAN    0x0400  /* #define PY_SSIZE_T_CLEAN. */
 
 #define hasDelayedDtors(m)  ((m)->modflags & MOD_HAS_DELAYED_DTORS)
 #define setHasDelayedDtors(m)   ((m)->modflags |= MOD_HAS_DELAYED_DTORS)
@@ -116,6 +117,8 @@
 #define settingImports(m)   ((m)->modflags & MOD_SETTING_IMPORTS)
 #define setSettingImports(m)    ((m)->modflags |= MOD_SETTING_IMPORTS)
 #define resetSettingImports(m)  ((m)->modflags &= ~MOD_SETTING_IMPORTS)
+#define setPY_SSIZE_T_CLEAN(m)  ((m)->modflags |= MOD_PY_SSIZE_T_CLEAN)
+#define isPY_SSIZE_T_CLEAN(m)   ((m)->modflags & MOD_PY_SSIZE_T_CLEAN)
 
 
 /* Handle section flags. */
@@ -1630,6 +1633,7 @@ typedef struct _moduleCfg {
     KwArgs kwargs;
     const char *name;
     int use_arg_names;
+    int py_ssize_t_clean;
     int use_limited_api;
     int all_raise_py_exc;
     int call_super_init;
Index: sip-4.19.23/sphinx/directives.rst
===================================================================
--- sip-4.19.23.orig/sphinx/directives.rst
+++ sip-4.19.23/sphinx/directives.rst
@@ -1966,6 +1966,7 @@ then the pattern should instead be::
             [, default_VirtualErrorHandler = *name*]
             [, keyword_arguments = ["None" | "All" | "Optional"]]
             [, language = *string*]
+            [, py_ssize_t_clean = [True | False]]
             [, use_argument_names = [True | False]]
             [, use_limited_api = [True | False]]
             [, version = *integer*])
@@ -2004,6 +2005,9 @@ implied by the (deprecated) :option:`-k
 ``language`` specifies the implementation language of the library being
 wrapped.  Its value is either ``"C++"`` (the default) or ``"C"``.
 
+``py_ssize_t_clean`` specifies that the generated code should include ``#define
+PY_SSIZE_T_CLEAN`` before any ``#include <Python.h>``.
+
 When providing handwritten code as part of either the :directive:`%MethodCode`
 or :directive:`%VirtualCatcherCode` directives the names of the arguments of
 the function or method are based on the number of the argument, i.e. the first
