1 /*
2  * The code generator module for SIP.
3  *
4  * Copyright (c) 2020 Riverbank Computing Limited <info@riverbankcomputing.com>
5  *
6  * This file is part of SIP.
7  *
8  * This copy of SIP is licensed for use under the terms of the SIP License
9  * Agreement.  See the file LICENSE for more details.
10  *
11  * This copy of SIP may also used under the terms of the GNU General Public
12  * License v2 or v3 as published by the Free Software Foundation which can be
13  * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
14  *
15  * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17  */
18 
19 
20 #include <stdio.h>
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <string.h>
25 
26 #include "sip.h"
27 
28 
29 /* Return the base (ie. C/C++) name of a super-type or meta-type. */
30 #define smtypeName(sm)          (strrchr((sm)->name->text, '.') + 1)
31 
32 /* Return TRUE if a wrapped variable can be set. */
33 #define canSetVariable(vd)      (!noSetter(vd) && ((vd)->type.nrderefs != 0 || !isConstArg(&(vd)->type)))
34 
35 /* Return TRUE if a module implements Qt support. */
36 #define moduleSupportsQt(pt, mod)   ((pt)->qobject_cd != NULL && (pt)->qobject_cd->iff->module == (mod))
37 
38 
39 /* Control what generateCalledArgs() actually generates. */
40 typedef enum {
41     Declaration,
42     Definition
43 } funcArgType;
44 
45 
46 typedef enum {
47     StripNone,
48     StripGlobal,
49     StripScope
50 } StripAction;
51 
52 
53 /* An entry in the sorted array of methods. */
54 typedef struct {
55     memberDef *md;                      /* The method. */
56 } sortedMethTab;
57 
58 
59 static int currentLineNr;               /* Current output line number. */
60 static const char *currentFileName;     /* Current output file name. */
61 static int previousLineNr;              /* Previous output line number. */
62 static const char *previousFileName;    /* Previous output file name. */
63 static int exceptions;                  /* Set if exceptions are enabled. */
64 static int tracing;                     /* Set if tracing is enabled. */
65 static int generating_c;                /* Set if generating C. */
66 static int release_gil;                 /* Set if always releasing the GIL. */
67 static const char *prcode_last = NULL;  /* The last prcode format string. */
68 static int prcode_xml = FALSE;          /* Set if prcode is XML aware. */
69 static int docstrings;                  /* Set if generating docstrings. */
70 
71 
72 static const char *generateInternalAPIHeader(sipSpec *pt, moduleDef *mod,
73         const char *codeDir, stringList *needed_qualifiers, stringList *xsl,
74         int py_debug);
75 static const char *generateCpp(sipSpec *pt, moduleDef *mod,
76         const char *codeDir, stringList **generated, const char *srcSuffix,
77         int parts, stringList *needed_qualifiers, stringList *xsl,
78         int py_debug, const char *sipName);
79 static void generateCompositeCpp(sipSpec *pt, const char *codeDir,
80         stringList **generated, int py_debug);
81 static void generateSipAPI(moduleDef *mod, const char *sipName, FILE *fp);
82 static void generateSipImportVariables(FILE *fp);
83 static void generateModInitStart(moduleDef *mod, int gen_c, FILE *fp);
84 static void generateModDefinition(moduleDef *mod, const char *methods,
85         FILE *fp);
86 static void generateModDocstring(moduleDef *mod, FILE *fp);
87 static void generateIfaceCpp(sipSpec *, stringList **generated, int,
88         ifaceFileDef *, int, const char *, const char *, FILE *);
89 static void generateMappedTypeCpp(mappedTypeDef *mtd, sipSpec *pt, FILE *fp);
90 static void generateImportedMappedTypeAPI(mappedTypeDef *mtd, moduleDef *mod,
91         FILE *fp);
92 static void generateMappedTypeAPI(sipSpec *pt, mappedTypeDef *mtd, FILE *fp);
93 static void generateClassCpp(classDef *cd, sipSpec *pt, int py_debug,
94         FILE *fp);
95 static void generateImportedClassAPI(classDef *cd, moduleDef *mod, FILE *fp);
96 static void generateClassAPI(classDef *cd, sipSpec *pt, FILE *fp);
97 static void generateClassFunctions(sipSpec *pt, moduleDef *mod, classDef *cd,
98         int py_debug, FILE *fp);
99 static void generateShadowCode(sipSpec *pt, moduleDef *mod, classDef *cd,
100         FILE *fp);
101 static void generateFunction(sipSpec *, memberDef *, overDef *, classDef *,
102         classDef *, moduleDef *, FILE *);
103 static void generateFunctionBody(overDef *, classDef *, mappedTypeDef *,
104         classDef *, int deref, moduleDef *, FILE *);
105 static void generatePyObjects(sipSpec *pt, moduleDef *mod, FILE *fp);
106 static void generateTypeDefinition(sipSpec *pt, classDef *cd, int py_debug,
107         FILE *fp);
108 static void generateTypeInit(classDef *, moduleDef *, FILE *);
109 static void generateCppCodeBlock(codeBlockList *cbl, FILE *fp);
110 static void generateUsedIncludes(ifaceFileList *iffl, FILE *fp);
111 static void generateModuleAPI(sipSpec *pt, moduleDef *mod, FILE *fp);
112 static void generateImportedModuleAPI(sipSpec *pt, moduleDef *mod,
113         moduleDef *immod, FILE *fp);
114 static void generateShadowClassDeclaration(sipSpec *, classDef *, FILE *);
115 static int hasConvertToCode(argDef *ad);
116 static void deleteOuts(moduleDef *mod, signatureDef *sd, FILE *fp);
117 static void deleteTemps(moduleDef *mod, signatureDef *sd, FILE *fp);
118 static void gc_ellipsis(signatureDef *sd, FILE *fp);
119 static void generateCallArgs(moduleDef *, signatureDef *, signatureDef *,
120         FILE *);
121 static void generateCalledArgs(moduleDef *, ifaceFileDef *, signatureDef *,
122         funcArgType, FILE *);
123 static void generateVariable(moduleDef *, ifaceFileDef *, argDef *, int,
124         FILE *);
125 static void generateNamedValueType(ifaceFileDef *, argDef *, char *, FILE *);
126 static void generateOverloadDecl(FILE *fp, ifaceFileDef *scope, overDef *od);
127 static void generateNamedBaseType(ifaceFileDef *, argDef *, const char *, int,
128         int, FILE *);
129 static void generateTupleBuilder(moduleDef *, signatureDef *, FILE *);
130 static void generatePyQt5Emitters(classDef *cd, FILE *fp);
131 static void generateVirtualHandler(moduleDef *mod, virtHandlerDef *vhd,
132         FILE *fp);
133 static void generateDefaultInstanceReturn(argDef *res, const char *indent,
134         FILE *fp);
135 static void generateVirtualCatcher(moduleDef *mod, classDef *cd, int virtNr,
136         virtOverDef *vod, FILE *fp);
137 static void generateVirtHandlerCall(moduleDef *mod, classDef *cd,
138         virtOverDef *vod, argDef *res, const char *indent, FILE *fp);
139 static void generateProtectedEnums(sipSpec *, classDef *, FILE *);
140 static void generateProtectedDeclarations(classDef *, FILE *);
141 static void generateProtectedDefinitions(moduleDef *, classDef *, FILE *);
142 static void generateProtectedCallArgs(moduleDef *mod, signatureDef *sd,
143         FILE *fp);
144 static void generateConstructorCall(classDef *, ctorDef *, int, int,
145         moduleDef *, FILE *);
146 static void generateHandleResult(moduleDef *, overDef *, int, int, char *,
147         FILE *);
148 static void generateOrdinaryFunction(sipSpec *pt, moduleDef *mod,
149         classDef *c_scope, mappedTypeDef *mt_scope, memberDef *md, FILE *fp);
150 static void generateSimpleFunctionCall(fcallDef *, int, FILE *);
151 static int generateResultVar(ifaceFileDef *scope, overDef *od, argDef *res,
152         const char *indent, FILE *fp);
153 static void generateFunctionCall(classDef *c_scope, mappedTypeDef *mt_scope,
154         ifaceFileDef *o_scope, overDef *od, int deref, moduleDef *mod,
155         FILE *fp);
156 static void generateCppFunctionCall(moduleDef *mod, ifaceFileDef *scope,
157         ifaceFileDef *o_scope, overDef *od, FILE *fp);
158 static void generateSlotArg(moduleDef *mod, signatureDef *sd, int argnr,
159         FILE *fp);
160 static void generateComparisonSlotCall(moduleDef *mod, ifaceFileDef *scope,
161         overDef *od, const char *op, const char *cop, int deref, FILE *fp);
162 static void generateBinarySlotCall(moduleDef *mod, ifaceFileDef *scope,
163         overDef *od, const char *op, int deref, FILE *fp);
164 static void generateNumberSlotCall(moduleDef *mod, overDef *od, char *op,
165         FILE *fp);
166 static void generateVariableGetter(ifaceFileDef *, varDef *, FILE *);
167 static void generateVariableSetter(ifaceFileDef *, varDef *, FILE *);
168 static int generateObjToCppConversion(argDef *, FILE *);
169 static void generateVarMember(varDef *vd, FILE *fp);
170 static int generateVoidPointers(sipSpec *pt, moduleDef *mod, classDef *cd,
171         FILE *fp);
172 static int generateChars(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
173 static int generateStrings(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
174 static sortedMethTab *createFunctionTable(memberDef *, int *);
175 static sortedMethTab *createMethodTable(classDef *, int *);
176 static int generateMappedTypeMethodTable(sipSpec *pt, mappedTypeDef *mtd,
177         FILE *fp);
178 static int generateClassMethodTable(sipSpec *pt, classDef *cd, FILE *fp);
179 static void prMethodTable(sipSpec *pt, sortedMethTab *mtable, int nr,
180         ifaceFileDef *iff, overDef *overs, FILE *fp);
181 static void generateEnumMacros(sipSpec *pt, moduleDef *mod, classDef *cd,
182         mappedTypeDef *mtd, FILE *fp);
183 static int generateEnumMemberTable(sipSpec *pt, moduleDef *mod, classDef *cd,
184         mappedTypeDef *mtd, FILE *fp);
185 static int generateInts(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
186 static int generateLongs(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
187 static int generateUnsignedLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
188         FILE *fp);
189 static int generateLongLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
190         FILE *fp);
191 static int generateUnsignedLongLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
192         FILE *fp);
193 static int generateVariableType(sipSpec *pt, moduleDef *mod, classDef *cd,
194         argType atype, const char *eng, const char *s1, const char *s2,
195         FILE *fp);
196 static int generateDoubles(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
197 static int generateClasses(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
198 static void generateTypesInline(sipSpec *pt, moduleDef *mod, FILE *fp);
199 static void generateAccessFunctions(sipSpec *pt, moduleDef *mod, classDef *cd,
200         FILE *fp);
201 static void generateConvertToDefinitions(mappedTypeDef *, classDef *, FILE *);
202 static void generateEncodedType(moduleDef *mod, classDef *cd, int last,
203         FILE *fp);
204 static void generateArgParser(moduleDef *mod, signatureDef *sd,
205         classDef *c_scope, mappedTypeDef *mt_scope, ctorDef *ct, overDef *od,
206         FILE *fp);
207 static void generateTry(throwArgs *, FILE *);
208 static void generateCatch(throwArgs *ta, signatureDef *sd, moduleDef *mod,
209         FILE *fp, int rgil);
210 static void generateCatchBlock(moduleDef *mod, exceptionDef *xd,
211         signatureDef *sd, FILE *fp, int rgil);
212 static void generateThrowSpecifier(throwArgs *, FILE *);
213 static void generateSlot(moduleDef *mod, classDef *cd, enumDef *ed,
214         memberDef *md, FILE *fp);
215 static void generateCastZero(argDef *ad, FILE *fp);
216 static void generateCallDefaultCtor(ctorDef *ct, FILE *fp);
217 static void generateVoidPtrCast(argDef *ad, FILE *fp);
218 static int countVirtuals(classDef *);
219 static int skipOverload(overDef *, memberDef *, classDef *, classDef *, int);
220 static int compareMethTab(const void *, const void *);
221 static int compareEnumMembers(const void *, const void *);
222 static char *getSubFormatChar(char, argDef *);
223 static char *createIfaceFileName(const char *, ifaceFileDef *, const char *);
224 static FILE *createCompilationUnit(moduleDef *mod, stringList **generated,
225         const char *fname, const char *description);
226 static FILE *createFile(moduleDef *mod, const char *fname,
227         const char *description);
228 static void closeFile(FILE *);
229 static void prScopedName(FILE *fp, scopedNameDef *snd, char *sep);
230 static void prTypeName(FILE *fp, argDef *ad);
231 static void prScopedClassName(FILE *fp, ifaceFileDef *scope, classDef *cd,
232         int strip);
233 static int isMultiArgSlot(memberDef *md);
234 static int isIntArgSlot(memberDef *md);
235 static int isInplaceSequenceSlot(memberDef *md);
236 static int needErrorFlag(codeBlockList *cbl);
237 static int needOldErrorFlag(codeBlockList *cbl);
238 static int needNewInstance(argDef *ad);
239 static int needDealloc(classDef *cd);
240 static const char *getBuildResultFormat(argDef *ad);
241 static const char *getParseResultFormat(argDef *ad, int res_isref, int xfervh);
242 static void generateParseResultExtraArgs(moduleDef *mod, argDef *ad, int argnr,
243         FILE *fp);
244 static char *makePartName(const char *codeDir, const char *mname, int part,
245         const char *srcSuffix);
246 static void fakeProtectedArgs(signatureDef *sd);
247 static const char *slotName(slotType st);
248 static void ints_intro(classDef *cd, FILE *fp);
249 static const char *argName(const char *name, codeBlockList *cbl);
250 static int usedInCode(codeBlockList *cbl, const char *str);
251 static void generateDefaultValue(moduleDef *mod, argDef *ad, int argnr,
252         FILE *fp);
253 static void generateClassFromVoid(classDef *cd, const char *cname,
254         const char *vname, FILE *fp);
255 static void generateMappedTypeFromVoid(mappedTypeDef *mtd, const char *cname,
256         const char *vname, FILE *fp);
257 static int generateSubClassConvertors(sipSpec *pt, moduleDef *mod, FILE *fp);
258 static void generateNameCache(sipSpec *pt, FILE *fp);
259 static const char *resultOwner(overDef *od);
260 static void prCachedName(FILE *fp, nameDef *nd, const char *prefix);
261 static void generateSignalTableEntry(sipSpec *pt, classDef *cd, overDef *sig,
262         int membernr, int optional_args, FILE *fp);
263 static void generateTypesTable(moduleDef *mod, FILE *fp);
264 static int keepPyReference(argDef *ad);
265 static int isDuplicateProtected(classDef *cd, overDef *target);
266 static char getEncoding(argDef *ad);
267 static void generateTypeDefName(ifaceFileDef *iff, FILE *fp);
268 static void generateTypeDefLink(ifaceFileDef *iff, FILE *fp);
269 static int overloadHasAutoDocstring(sipSpec *pt, overDef *od);
270 static int hasMemberDocstring(sipSpec *pt, overDef *overs, memberDef *md,
271         ifaceFileDef *scope);
272 static int generateMemberDocstring(sipSpec *pt, overDef *overs, memberDef *md,
273         int is_method, FILE *fp);
274 static void generateMemberAutoDocstring(sipSpec *pt, overDef *od,
275         int is_method, FILE *fp);
276 static int ctorHasAutoDocstring(sipSpec *pt, ctorDef *ct);
277 static int hasClassDocstring(sipSpec *pt, classDef *cd);
278 static void generateClassDocstring(sipSpec *pt, classDef *cd, FILE *fp);
279 static void generateCtorAutoDocstring(sipSpec *pt, classDef *cd, ctorDef *ct,
280         FILE *fp);
281 static void generateDocstringText(docstringDef *docstring, FILE *fp);
282 static int needsHeapCopy(argDef *ad, int usingCopyCtor);
283 static void generatePreprocLine(int linenr, const char *fname, FILE *fp);
284 static int hasOptionalArgs(overDef *od);
285 static int emptyIfaceFile(sipSpec *pt, ifaceFileDef *iff);
286 static void declareLimitedAPI(int py_debug, moduleDef *mod, FILE *fp);
287 static int generatePluginSignalsTable(sipSpec *pt, classDef *cd, FILE *fp);
288 static int generatePyQt5ClassPlugin(sipSpec *pt, classDef *cd, FILE *fp);
289 static void generateGlobalFunctionTableEntries(sipSpec *pt, moduleDef *mod,
290         memberDef *members, FILE *fp);
291 static void prTemplateType(FILE *fp, ifaceFileDef *scope, templateDef *td,
292         int strip);
293 static int isString(argDef *ad);
294 static scopedNameDef *stripScope(scopedNameDef *snd, int strip);
295 static void prEnumMemberScope(enumMemberDef *emd, FILE *fp);
296 static void normaliseSignalArg(argDef *ad);
297 static void generate_include_sip_h(FILE *fp);
298 
299 
300 /*
301  * Generate the code from a specification and return a list of generated files.
302  */
generateCode(sipSpec * pt,char * codeDir,const char * srcSuffix,int except,int trace,int releaseGIL,int parts,stringList * needed_qualifiers,stringList * xsl,int docs,int py_debug,const char * sipName,const char ** api_header)303 stringList *generateCode(sipSpec *pt, char *codeDir, const char *srcSuffix,
304         int except, int trace, int releaseGIL, int parts,
305         stringList *needed_qualifiers, stringList *xsl, int docs, int py_debug,
306         const char *sipName, const char **api_header)
307 {
308     stringList *generated = NULL;
309 
310     exceptions = except;
311     tracing = trace;
312     release_gil = releaseGIL;
313     generating_c = pt->genc;
314     docstrings = docs;
315 
316     if (srcSuffix == NULL)
317         srcSuffix = (generating_c ? ".c" : ".cpp");
318 
319     if (isComposite(pt->module))
320     {
321         generateCompositeCpp(pt, codeDir, &generated, py_debug);
322         *api_header = NULL;
323     }
324     else
325     {
326         *api_header = generateCpp(pt, pt->module, codeDir, &generated,
327                 srcSuffix, parts, needed_qualifiers, xsl, py_debug, sipName);
328     }
329 
330     return generated;
331 }
332 
333 
334 /*
335  * Generate an expression in C++.
336  */
generateExpression(valueDef * vd,int in_str,FILE * fp)337 void generateExpression(valueDef *vd, int in_str, FILE *fp)
338 {
339     while (vd != NULL)
340     {
341         if (vd->cast != NULL)
342             prcode(fp, "(%S)", vd->cast);
343 
344         if (vd->vunop != '\0')
345             prcode(fp,"%c",vd->vunop);
346 
347         switch (vd->vtype)
348         {
349         case qchar_value:
350             if (vd->u.vqchar == '"' && in_str)
351                 prcode(fp, "'\\\"'");
352             else
353                 prcode(fp, "'%c'", vd->u.vqchar);
354 
355             break;
356 
357         case string_value:
358             {
359                 const char *cp, *quote = (in_str ? "\\\"" : "\"");
360 
361                 prcode(fp, "%s", quote);
362 
363                 for (cp = vd->u.vstr; *cp != '\0'; ++cp)
364                 {
365                     char ch = *cp;
366                     int escape;
367 
368                     if (strchr("\\\"", ch) != NULL)
369                     {
370                         escape = TRUE;
371                     }
372                     else if (ch == '\n')
373                     {
374                         escape = TRUE;
375                         ch = 'n';
376                     }
377                     else if (ch == '\r')
378                     {
379                         escape = TRUE;
380                         ch = 'r';
381                     }
382                     else if (ch == '\t')
383                     {
384                         escape = TRUE;
385                         ch = 't';
386                     }
387                     else
388                     {
389                         escape = FALSE;
390                     }
391 
392                     prcode(fp, "%s%c", (escape ? "\\" : ""), ch);
393                 }
394 
395                 prcode(fp, "%s", quote);
396             }
397 
398             break;
399 
400         case numeric_value:
401             prcode(fp,"%l",vd->u.vnum);
402             break;
403 
404         case real_value:
405             prcode(fp,"%g",vd->u.vreal);
406             break;
407 
408         case scoped_value:
409             if (prcode_xml)
410                 prScopedName(fp, removeGlobalScope(vd->u.vscp), ".");
411             else
412                 prcode(fp, "%S", vd->u.vscp);
413 
414             break;
415 
416         case fcall_value:
417             generateSimpleFunctionCall(vd->u.fcd, in_str, fp);
418             break;
419 
420         case empty_value:
421             prcode(fp, "{}");
422             break;
423         }
424 
425         if (vd->vbinop != '\0')
426             prcode(fp,"%c",vd->vbinop);
427 
428         vd = vd->next;
429     }
430 }
431 
432 
433 /*
434  * Generate the C++ internal module API header file and return its path name on
435  * the heap.
436  */
generateInternalAPIHeader(sipSpec * pt,moduleDef * mod,const char * codeDir,stringList * needed_qualifiers,stringList * xsl,int py_debug)437 static const char *generateInternalAPIHeader(sipSpec *pt, moduleDef *mod,
438         const char *codeDir, stringList *needed_qualifiers, stringList *xsl,
439         int py_debug)
440 {
441     char *hfile;
442     const char *mname = mod->name;
443     int noIntro;
444     FILE *fp;
445     nameDef *nd;
446     moduleDef *imp;
447     moduleListDef *mld;
448 
449     hfile = concat(codeDir, "/sipAPI", mname, ".h", NULL);
450     fp = createFile(mod, hfile, "Internal module API header file.");
451 
452     /* Include files. */
453 
454     prcode(fp,
455 "\n"
456 "#ifndef _%sAPI_H\n"
457 "#define _%sAPI_H\n"
458         , mname
459         , mname);
460 
461     declareLimitedAPI(py_debug, mod, fp);
462 
463     generate_include_sip_h(fp);
464 
465     if (pluginPyQt5(pt))
466         prcode(fp,
467 "\n"
468 "#include <QMetaType>\n"
469 "#include <QThread>\n"
470             );
471 
472     /* Define the qualifiers. */
473     noIntro = TRUE;
474 
475     for (imp = pt->modules; imp != NULL; imp = imp->next)
476     {
477         qualDef *qd;
478 
479         for (qd = imp->qualifiers; qd != NULL; qd = qd->next)
480         {
481             const char *qtype = NULL;
482 
483             switch (qd->qtype)
484             {
485             case time_qualifier:
486                 if (selectedQualifier(needed_qualifiers, qd))
487                     qtype = "TIMELINE";
488 
489                 break;
490 
491             case platform_qualifier:
492                 if (selectedQualifier(needed_qualifiers, qd))
493                     qtype = "PLATFORM";
494 
495                 break;
496 
497             case feature_qualifier:
498                 if (!excludedFeature(xsl, qd))
499                     qtype = "FEATURE";
500 
501                 break;
502             }
503 
504             if (qtype != NULL)
505             {
506                 if (noIntro)
507                 {
508                     prcode(fp,
509 "\n"
510 "/* These are the qualifiers that are enabled. */\n"
511                         );
512 
513                     noIntro = FALSE;
514                 }
515 
516                 prcode(fp,
517 "#define SIP_%s_%s\n"
518                     , qtype, qd->name);
519             }
520         }
521     }
522 
523     if (!noIntro)
524         prcode(fp,
525 "\n"
526             );
527 
528     /* Shortcuts that hide the messy detail of the APIs. */
529     noIntro = TRUE;
530 
531     for (nd = pt->namecache; nd != NULL; nd = nd->next)
532     {
533         if (!isUsedName(nd))
534             continue;
535 
536         if (noIntro)
537         {
538             prcode(fp,
539 "\n"
540 "/*\n"
541 " * Convenient names to refer to various strings defined in this module.\n"
542 " * Only the class names are part of the public API.\n"
543 " */\n"
544                 );
545 
546             noIntro = FALSE;
547         }
548 
549         prcode(fp,
550 "#define %n %d\n"
551 "#define %N &sipStrings_%s[%d]\n"
552             , nd, (int)nd->offset
553             , nd, pt->module->name, (int)nd->offset);
554     }
555 
556     prcode(fp,
557 "\n"
558 "#define sipMalloc                   sipAPI_%s->api_malloc\n"
559 "#define sipFree                     sipAPI_%s->api_free\n"
560 "#define sipBuildResult              sipAPI_%s->api_build_result\n"
561 "#define sipCallMethod               sipAPI_%s->api_call_method\n"
562 "#define sipCallProcedureMethod      sipAPI_%s->api_call_procedure_method\n"
563 "#define sipCallErrorHandler         sipAPI_%s->api_call_error_handler\n"
564 "#define sipParseResultEx            sipAPI_%s->api_parse_result_ex\n"
565 "#define sipParseResult              sipAPI_%s->api_parse_result\n"
566 "#define sipParseArgs                sipAPI_%s->api_parse_args\n"
567 "#define sipParseKwdArgs             sipAPI_%s->api_parse_kwd_args\n"
568 "#define sipParsePair                sipAPI_%s->api_parse_pair\n"
569 "#define sipInstanceDestroyed        sipAPI_%s->api_instance_destroyed\n"
570 "#define sipInstanceDestroyedEx      sipAPI_%s->api_instance_destroyed_ex\n"
571 "#define sipConvertFromSequenceIndex sipAPI_%s->api_convert_from_sequence_index\n"
572 "#define sipConvertFromSliceObject   sipAPI_%s->api_convert_from_slice_object\n"
573 "#define sipConvertFromVoidPtr       sipAPI_%s->api_convert_from_void_ptr\n"
574 "#define sipConvertToVoidPtr         sipAPI_%s->api_convert_to_void_ptr\n"
575 "#define sipAddException             sipAPI_%s->api_add_exception\n"
576 "#define sipNoFunction               sipAPI_%s->api_no_function\n"
577 "#define sipNoMethod                 sipAPI_%s->api_no_method\n"
578 "#define sipAbstractMethod           sipAPI_%s->api_abstract_method\n"
579 "#define sipBadClass                 sipAPI_%s->api_bad_class\n"
580 "#define sipBadCatcherResult         sipAPI_%s->api_bad_catcher_result\n"
581 "#define sipBadCallableArg           sipAPI_%s->api_bad_callable_arg\n"
582 "#define sipBadOperatorArg           sipAPI_%s->api_bad_operator_arg\n"
583 "#define sipTrace                    sipAPI_%s->api_trace\n"
584 "#define sipTransferBack             sipAPI_%s->api_transfer_back\n"
585 "#define sipTransferTo               sipAPI_%s->api_transfer_to\n"
586 "#define sipSimpleWrapper_Type       sipAPI_%s->api_simplewrapper_type\n"
587 "#define sipWrapper_Type             sipAPI_%s->api_wrapper_type\n"
588 "#define sipWrapperType_Type         sipAPI_%s->api_wrappertype_type\n"
589 "#define sipVoidPtr_Type             sipAPI_%s->api_voidptr_type\n"
590 "#define sipGetPyObject              sipAPI_%s->api_get_pyobject\n"
591 "#define sipGetAddress               sipAPI_%s->api_get_address\n"
592 "#define sipGetMixinAddress          sipAPI_%s->api_get_mixin_address\n"
593 "#define sipGetCppPtr                sipAPI_%s->api_get_cpp_ptr\n"
594 "#define sipGetComplexCppPtr         sipAPI_%s->api_get_complex_cpp_ptr\n"
595 "#define sipIsPyMethod               sipAPI_%s->api_is_py_method\n"
596 "#define sipIsPyMethod_12_8          sipAPI_%s->api_is_py_method_12_8\n"
597 "#define sipCallHook                 sipAPI_%s->api_call_hook\n"
598 "#define sipEndThread                sipAPI_%s->api_end_thread\n"
599 "#define sipConnectRx                sipAPI_%s->api_connect_rx\n"
600 "#define sipDisconnectRx             sipAPI_%s->api_disconnect_rx\n"
601 "#define sipRaiseUnknownException    sipAPI_%s->api_raise_unknown_exception\n"
602 "#define sipRaiseTypeException       sipAPI_%s->api_raise_type_exception\n"
603 "#define sipBadLengthForSlice        sipAPI_%s->api_bad_length_for_slice\n"
604 "#define sipAddTypeInstance          sipAPI_%s->api_add_type_instance\n"
605 "#define sipFreeSipslot              sipAPI_%s->api_free_sipslot\n"
606 "#define sipSameSlot                 sipAPI_%s->api_same_slot\n"
607 "#define sipPySlotExtend             sipAPI_%s->api_pyslot_extend\n"
608 "#define sipConvertRx                sipAPI_%s->api_convert_rx\n"
609 "#define sipAddDelayedDtor           sipAPI_%s->api_add_delayed_dtor\n"
610 "#define sipCanConvertToType         sipAPI_%s->api_can_convert_to_type\n"
611 "#define sipConvertToType            sipAPI_%s->api_convert_to_type\n"
612 "#define sipForceConvertToType       sipAPI_%s->api_force_convert_to_type\n"
613 "#define sipConvertToEnum            sipAPI_%s->api_convert_to_enum\n"
614 "#define sipConvertToBool            sipAPI_%s->api_convert_to_bool\n"
615 "#define sipReleaseType              sipAPI_%s->api_release_type\n"
616 "#define sipConvertFromType          sipAPI_%s->api_convert_from_type\n"
617 "#define sipConvertFromNewType       sipAPI_%s->api_convert_from_new_type\n"
618 "#define sipConvertFromNewPyType     sipAPI_%s->api_convert_from_new_pytype\n"
619 "#define sipConvertFromEnum          sipAPI_%s->api_convert_from_enum\n"
620 "#define sipGetState                 sipAPI_%s->api_get_state\n"
621 "#define sipExportSymbol             sipAPI_%s->api_export_symbol\n"
622 "#define sipImportSymbol             sipAPI_%s->api_import_symbol\n"
623 "#define sipFindType                 sipAPI_%s->api_find_type\n"
624 "#define sipBytes_AsChar             sipAPI_%s->api_bytes_as_char\n"
625 "#define sipBytes_AsString           sipAPI_%s->api_bytes_as_string\n"
626 "#define sipString_AsASCIIChar       sipAPI_%s->api_string_as_ascii_char\n"
627 "#define sipString_AsASCIIString     sipAPI_%s->api_string_as_ascii_string\n"
628 "#define sipString_AsLatin1Char      sipAPI_%s->api_string_as_latin1_char\n"
629 "#define sipString_AsLatin1String    sipAPI_%s->api_string_as_latin1_string\n"
630 "#define sipString_AsUTF8Char        sipAPI_%s->api_string_as_utf8_char\n"
631 "#define sipString_AsUTF8String      sipAPI_%s->api_string_as_utf8_string\n"
632 "#define sipUnicode_AsWChar          sipAPI_%s->api_unicode_as_wchar\n"
633 "#define sipUnicode_AsWString        sipAPI_%s->api_unicode_as_wstring\n"
634 "#define sipConvertFromConstVoidPtr  sipAPI_%s->api_convert_from_const_void_ptr\n"
635 "#define sipConvertFromVoidPtrAndSize    sipAPI_%s->api_convert_from_void_ptr_and_size\n"
636 "#define sipConvertFromConstVoidPtrAndSize   sipAPI_%s->api_convert_from_const_void_ptr_and_size\n"
637 "#define sipInvokeSlot               sipAPI_%s->api_invoke_slot\n"
638 "#define sipInvokeSlotEx             sipAPI_%s->api_invoke_slot_ex\n"
639 "#define sipSaveSlot                 sipAPI_%s->api_save_slot\n"
640 "#define sipClearAnySlotReference    sipAPI_%s->api_clear_any_slot_reference\n"
641 "#define sipVisitSlot                sipAPI_%s->api_visit_slot\n"
642 "#define sipWrappedTypeName(wt)      ((wt)->wt_td->td_cname)\n"
643 "#define sipDeprecated               sipAPI_%s->api_deprecated\n"
644 "#define sipGetReference             sipAPI_%s->api_get_reference\n"
645 "#define sipKeepReference            sipAPI_%s->api_keep_reference\n"
646 "#define sipRegisterProxyResolver    sipAPI_%s->api_register_proxy_resolver\n"
647 "#define sipRegisterPyType           sipAPI_%s->api_register_py_type\n"
648 "#define sipTypeFromPyTypeObject     sipAPI_%s->api_type_from_py_type_object\n"
649 "#define sipTypeScope                sipAPI_%s->api_type_scope\n"
650 "#define sipResolveTypedef           sipAPI_%s->api_resolve_typedef\n"
651 "#define sipRegisterAttributeGetter  sipAPI_%s->api_register_attribute_getter\n"
652 "#define sipIsAPIEnabled             sipAPI_%s->api_is_api_enabled\n"
653 "#define sipSetDestroyOnExit         sipAPI_%s->api_set_destroy_on_exit\n"
654 "#define sipEnableAutoconversion     sipAPI_%s->api_enable_autoconversion\n"
655 "#define sipEnableOverflowChecking   sipAPI_%s->api_enable_overflow_checking\n"
656 "#define sipInitMixin                sipAPI_%s->api_init_mixin\n"
657 "#define sipExportModule             sipAPI_%s->api_export_module\n"
658 "#define sipInitModule               sipAPI_%s->api_init_module\n"
659 "#define sipGetInterpreter           sipAPI_%s->api_get_interpreter\n"
660 "#define sipSetNewUserTypeHandler    sipAPI_%s->api_set_new_user_type_handler\n"
661 "#define sipSetTypeUserData          sipAPI_%s->api_set_type_user_data\n"
662 "#define sipGetTypeUserData          sipAPI_%s->api_get_type_user_data\n"
663 "#define sipPyTypeDict               sipAPI_%s->api_py_type_dict\n"
664 "#define sipPyTypeName               sipAPI_%s->api_py_type_name\n"
665 "#define sipGetCFunction             sipAPI_%s->api_get_c_function\n"
666 "#define sipGetMethod                sipAPI_%s->api_get_method\n"
667 "#define sipFromMethod               sipAPI_%s->api_from_method\n"
668 "#define sipGetDate                  sipAPI_%s->api_get_date\n"
669 "#define sipFromDate                 sipAPI_%s->api_from_date\n"
670 "#define sipGetDateTime              sipAPI_%s->api_get_datetime\n"
671 "#define sipFromDateTime             sipAPI_%s->api_from_datetime\n"
672 "#define sipGetTime                  sipAPI_%s->api_get_time\n"
673 "#define sipFromTime                 sipAPI_%s->api_from_time\n"
674 "#define sipIsUserType               sipAPI_%s->api_is_user_type\n"
675 "#define sipGetFrame                 sipAPI_%s->api_get_frame\n"
676 "#define sipCheckPluginForType       sipAPI_%s->api_check_plugin_for_type\n"
677 "#define sipUnicodeNew               sipAPI_%s->api_unicode_new\n"
678 "#define sipUnicodeWrite             sipAPI_%s->api_unicode_write\n"
679 "#define sipUnicodeData              sipAPI_%s->api_unicode_data\n"
680 "#define sipGetBufferInfo            sipAPI_%s->api_get_buffer_info\n"
681 "#define sipReleaseBufferInfo        sipAPI_%s->api_release_buffer_info\n"
682 "#define sipIsOwnedByPython          sipAPI_%s->api_is_owned_by_python\n"
683 "#define sipIsDerivedClass           sipAPI_%s->api_is_derived_class\n"
684 "#define sipGetUserObject            sipAPI_%s->api_get_user_object\n"
685 "#define sipSetUserObject            sipAPI_%s->api_set_user_object\n"
686 "#define sipRegisterEventHandler     sipAPI_%s->api_register_event_handler\n"
687 "#define sipConvertToArray           sipAPI_%s->api_convert_to_array\n"
688 "#define sipConvertToTypedArray      sipAPI_%s->api_convert_to_typed_array\n"
689 "#define sipEnableGC                 sipAPI_%s->api_enable_gc\n"
690 "#define sipPrintObject              sipAPI_%s->api_print_object\n"
691 "#define sipLong_AsChar              sipAPI_%s->api_long_as_char\n"
692 "#define sipLong_AsSignedChar        sipAPI_%s->api_long_as_signed_char\n"
693 "#define sipLong_AsUnsignedChar      sipAPI_%s->api_long_as_unsigned_char\n"
694 "#define sipLong_AsShort             sipAPI_%s->api_long_as_short\n"
695 "#define sipLong_AsUnsignedShort     sipAPI_%s->api_long_as_unsigned_short\n"
696 "#define sipLong_AsInt               sipAPI_%s->api_long_as_int\n"
697 "#define sipLong_AsUnsignedInt       sipAPI_%s->api_long_as_unsigned_int\n"
698 "#define sipLong_AsLong              sipAPI_%s->api_long_as_long\n"
699 "#define sipLong_AsUnsignedLong      sipAPI_%s->api_long_as_unsigned_long\n"
700 "#define sipLong_AsLongLong          sipAPI_%s->api_long_as_long_long\n"
701 "#define sipLong_AsUnsignedLongLong  sipAPI_%s->api_long_as_unsigned_long_long\n"
702 "#define sipLong_AsSizeT             sipAPI_%s->api_long_as_size_t\n"
703 "#define sipVisitWrappers            sipAPI_%s->api_visit_wrappers\n"
704 "#define sipRegisterExitNotifier     sipAPI_%s->api_register_exit_notifier\n"
705         ,mname
706         ,mname
707         ,mname
708         ,mname
709         ,mname
710         ,mname
711         ,mname
712         ,mname
713         ,mname
714         ,mname
715         ,mname
716         ,mname
717         ,mname
718         ,mname
719         ,mname
720         ,mname
721         ,mname
722         ,mname
723         ,mname
724         ,mname
725         ,mname
726         ,mname
727         ,mname
728         ,mname
729         ,mname
730         ,mname
731         ,mname
732         ,mname
733         ,mname
734         ,mname
735         ,mname
736         ,mname
737         ,mname
738         ,mname
739         ,mname
740         ,mname
741         ,mname
742         ,mname
743         ,mname
744         ,mname
745         ,mname
746         ,mname
747         ,mname
748         ,mname
749         ,mname
750         ,mname
751         ,mname
752         ,mname
753         ,mname
754         ,mname
755         ,mname
756         ,mname
757         ,mname
758         ,mname
759         ,mname
760         ,mname
761         ,mname
762         ,mname
763         ,mname
764         ,mname
765         ,mname
766         ,mname
767         ,mname
768         ,mname
769         ,mname
770         ,mname
771         ,mname
772         ,mname
773         ,mname
774         ,mname
775         ,mname
776         ,mname
777         ,mname
778         ,mname
779         ,mname
780         ,mname
781         ,mname
782         ,mname
783         ,mname
784         ,mname
785         ,mname
786         ,mname
787         ,mname
788         ,mname
789         ,mname
790         ,mname
791         ,mname
792         ,mname
793         ,mname
794         ,mname
795         ,mname
796         ,mname
797         ,mname
798         ,mname
799         ,mname
800         ,mname
801         ,mname
802         ,mname
803         ,mname
804         ,mname
805         ,mname
806         ,mname
807         ,mname
808         ,mname
809         ,mname
810         ,mname
811         ,mname
812         ,mname
813         ,mname
814         ,mname
815         ,mname
816         ,mname
817         ,mname
818         ,mname
819         ,mname
820         ,mname
821         ,mname
822         ,mname
823         ,mname
824         ,mname
825         ,mname
826         ,mname
827         ,mname
828         ,mname
829         ,mname
830         ,mname
831         ,mname
832         ,mname
833         ,mname
834         ,mname
835         ,mname
836         ,mname
837         ,mname
838         ,mname
839         ,mname
840         ,mname
841         ,mname
842         ,mname
843         ,mname
844         ,mname
845         ,mname
846         ,mname
847         ,mname
848         ,mname
849         ,mname
850         ,mname);
851 
852     /* The name strings. */
853     prcode(fp,
854 "\n"
855 "/* The strings used by this module. */\n"
856 "extern const char sipStrings_%s[];\n"
857         , pt->module->name);
858 
859     generateModuleAPI(pt, mod, fp);
860 
861     prcode(fp,
862 "\n"
863 "/* The SIP API, this module's API and the APIs of any imported modules. */\n"
864 "extern const sipAPIDef *sipAPI_%s;\n"
865 "extern sipExportedModuleDef sipModuleAPI_%s;\n"
866         , mname
867         , mname, mname);
868 
869     if (mod->nr_needed_types > 0)
870         prcode(fp,
871 "extern sipTypeDef *sipExportedTypes_%s[];\n"
872             , mname);
873 
874     for (mld = mod->allimports; mld != NULL; mld = mld->next)
875     {
876         generateImportedModuleAPI(pt, mod, mld->module, fp);
877 
878         if (mld->module->nr_needed_types > 0)
879             prcode(fp,
880 "extern sipImportedTypeDef sipImportedTypes_%s_%s[];\n"
881                 , mname, mld->module->name);
882 
883         if (mld->module->nrvirterrorhandlers > 0)
884             prcode(fp,
885 "extern sipImportedVirtErrorHandlerDef sipImportedVirtErrorHandlers_%s_%s[];\n"
886                 , mname, mld->module->name);
887 
888         if (mld->module->nrexceptions > 0)
889             prcode(fp,
890 "extern sipImportedExceptionDef sipImportedExceptions_%s_%s[];\n"
891                 , mname, mld->module->name);
892     }
893 
894     if (pluginPyQt5(pt))
895     {
896         prcode(fp,
897 "\n"
898 "typedef const QMetaObject *(*sip_qt_metaobject_func)(sipSimpleWrapper *,sipTypeDef *);\n"
899 "extern sip_qt_metaobject_func sip_%s_qt_metaobject;\n"
900 "\n"
901 "typedef int (*sip_qt_metacall_func)(sipSimpleWrapper *,sipTypeDef *,QMetaObject::Call,int,void **);\n"
902 "extern sip_qt_metacall_func sip_%s_qt_metacall;\n"
903 "\n"
904             , mname
905             , mname);
906 
907         if (pluginPyQt5(pt))
908             prcode(fp,
909 "typedef bool (*sip_qt_metacast_func)(sipSimpleWrapper *, const sipTypeDef *, const char *, void **);\n"
910                 );
911         else
912             prcode(fp,
913 "typedef int (*sip_qt_metacast_func)(sipSimpleWrapper *, sipTypeDef *, const char *);\n"
914                 );
915 
916         prcode(fp,
917 "extern sip_qt_metacast_func sip_%s_qt_metacast;\n"
918             , mname);
919     }
920 
921     /* Handwritten code. */
922     generateCppCodeBlock(pt->exphdrcode, fp);
923     generateCppCodeBlock(mod->hdrcode, fp);
924 
925     /*
926      * Make sure any header code needed by the default exception is included.
927      */
928     if (mod->defexception != NULL)
929         generateCppCodeBlock(mod->defexception->iff->hdrcode, fp);
930 
931     /*
932      * Note that we don't forward declare the virtual handlers.  This is
933      * because we would need to #include everything needed for their argument
934      * types.
935      */
936     prcode(fp,
937 "\n"
938 "#endif\n"
939         );
940 
941     closeFile(fp);
942 
943     return hfile;
944 }
945 
946 
947 /*
948  * Return the filename of a source code part on the heap.
949  */
makePartName(const char * codeDir,const char * mname,int part,const char * srcSuffix)950 static char *makePartName(const char *codeDir, const char *mname, int part,
951         const char *srcSuffix)
952 {
953     char buf[50];
954 
955     sprintf(buf, "part%d", part);
956 
957     return concat(codeDir, "/sip", mname, buf, srcSuffix, NULL);
958 }
959 
960 
961 /*
962  * Generate the C code for a composite module.
963  */
generateCompositeCpp(sipSpec * pt,const char * codeDir,stringList ** generated,int py_debug)964 static void generateCompositeCpp(sipSpec *pt, const char *codeDir,
965         stringList **generated, int py_debug)
966 {
967     char *cppfile;
968     moduleDef *mod;
969     FILE *fp;
970 
971     cppfile = concat(codeDir, "/sip", pt->module->name, "cmodule.c", NULL);
972     fp = createCompilationUnit(pt->module, generated, cppfile,
973             "Composite module code.");
974 
975     declareLimitedAPI(py_debug, NULL, fp);
976 
977     generate_include_sip_h(fp);
978 
979     prcode(fp,
980 "\n"
981 "\n"
982 "static void sip_import_component_module(PyObject *d, const char *name)\n"
983 "{\n"
984 "    PyObject *mod;\n"
985 "\n"
986 "    PyErr_Clear();\n"
987 "\n"
988 "    mod = PyImport_ImportModule(name);\n"
989 "\n"
990 "    /*\n"
991 "     * Note that we don't complain if the module can't be imported.  This\n"
992 "     * is a favour to Linux distro packagers who like to split PyQt into\n"
993 "     * different sub-packages.\n"
994 "     */\n"
995 "    if (mod)\n"
996 "    {\n"
997 "        PyDict_Merge(d, PyModule_GetDict(mod), 0);\n"
998 "        Py_DECREF(mod);\n"
999 "    }\n"
1000 "}\n"
1001         );
1002 
1003     generateModDocstring(pt->module, fp);
1004     generateModInitStart(pt->module, TRUE, fp);
1005     generateModDefinition(pt->module, "SIP_NULLPTR", fp);
1006 
1007     prcode(fp,
1008 "\n"
1009 "    PyObject *sipModule, *sipModuleDict;\n"
1010 "\n"
1011 "    if ((sipModule = PyModule_Create(&sip_module_def)) == SIP_NULLPTR)\n"
1012 "        return SIP_NULLPTR;\n"
1013 "\n"
1014 "    sipModuleDict = PyModule_GetDict(sipModule);\n"
1015 "\n"
1016         );
1017 
1018     for (mod = pt->modules; mod != NULL; mod = mod->next)
1019         if (mod->container == pt->module)
1020             prcode(fp,
1021 "    sip_import_component_module(sipModuleDict, \"%s\");\n"
1022                 , mod->fullname->text);
1023 
1024     prcode(fp,
1025 "\n"
1026 "    PyErr_Clear();\n"
1027 "\n"
1028 "    return sipModule;\n"
1029 "}\n"
1030         );
1031 
1032     closeFile(fp);
1033     free(cppfile);
1034 }
1035 
1036 
1037 /*
1038  * Generate the name cache definition.
1039  */
generateNameCache(sipSpec * pt,FILE * fp)1040 static void generateNameCache(sipSpec *pt, FILE *fp)
1041 {
1042     nameDef *nd;
1043 
1044     prcode(fp,
1045 "\n"
1046 "/* Define the strings used by this module. */\n"
1047         );
1048 
1049     if (isConsolidated(pt->module))
1050         prcode(fp,
1051 "extern const char sipStrings_%s[];\n"
1052             , pt->module->name);
1053 
1054     prcode(fp,
1055 "const char sipStrings_%s[] = {\n"
1056         , pt->module->name);
1057 
1058     for (nd = pt->namecache; nd != NULL; nd = nd->next)
1059     {
1060         const char *cp;
1061 
1062         if (!isUsedName(nd) || isSubstring(nd))
1063             continue;
1064 
1065         prcode(fp, "    ");
1066 
1067         for (cp = nd->text; *cp != '\0'; ++cp)
1068             prcode(fp, "'%c', ", *cp);
1069 
1070         prcode(fp, "0,\n");
1071     }
1072 
1073     prcode(fp, "};\n");
1074 }
1075 
1076 
1077 /*
1078  * Generate the C/C++ code.
1079  */
generateCpp(sipSpec * pt,moduleDef * mod,const char * codeDir,stringList ** generated,const char * srcSuffix,int parts,stringList * needed_qualifiers,stringList * xsl,int py_debug,const char * sipName)1080 static const char *generateCpp(sipSpec *pt, moduleDef *mod,
1081         const char *codeDir, stringList **generated, const char *srcSuffix,
1082         int parts, stringList *needed_qualifiers, stringList *xsl,
1083         int py_debug, const char *sipName)
1084 {
1085     char *cppfile;
1086     const char *mname = mod->name;
1087     int nrSccs = 0, files_in_part, max_per_part, this_part, enum_idx;
1088     int is_inst_class, is_inst_voidp, is_inst_char, is_inst_string;
1089     int is_inst_int, is_inst_long, is_inst_ulong, is_inst_longlong;
1090     int is_inst_ulonglong, is_inst_double, nr_enummembers, is_api_versions;
1091     int is_versioned_functions;
1092     int hasexternal = FALSE, slot_extenders = FALSE, ctor_extenders = FALSE;
1093     int hasvirterrorhandlers = FALSE;
1094     FILE *fp;
1095     moduleListDef *mld;
1096     classDef *cd;
1097     memberDef *md;
1098     enumDef *ed;
1099     ifaceFileDef *iff;
1100     virtHandlerDef *vhd;
1101     virtErrorHandler *veh;
1102     exceptionDef *xd;
1103 
1104     /* Calculate the number of files in each part. */
1105     if (parts)
1106     {
1107         int nr_files = 1;
1108 
1109         for (iff = pt->ifacefiles; iff != NULL; iff = iff->next)
1110             if (iff->module == mod && iff->type != exception_iface)
1111                 ++nr_files;
1112 
1113         max_per_part = (nr_files + parts - 1) / parts;
1114         files_in_part = 1;
1115         this_part = 0;
1116 
1117         cppfile = makePartName(codeDir, mname, 0, srcSuffix);
1118     }
1119     else
1120         cppfile = concat(codeDir, "/sip", mname, "cmodule", srcSuffix, NULL);
1121 
1122     fp = createCompilationUnit(mod, generated, cppfile, "Module code.");
1123 
1124     prcode(fp,
1125 "\n"
1126 "#include \"sipAPI%s.h\"\n"
1127         , mname);
1128 
1129     /*
1130      * Include the library headers for types used by virtual handlers, module
1131      * level functions, module level variables and Qt meta types.
1132      */
1133     generateUsedIncludes(mod->used, fp);
1134 
1135     generateCppCodeBlock(mod->unitpostinccode, fp);
1136 
1137     /*
1138      * If there should be a Qt support API then generate stubs values for the
1139      * optional parts.  These should be undefined in %ModuleCode if a C++
1140      * implementation is provided.
1141      */
1142     if (moduleSupportsQt(pt, mod))
1143         prcode(fp,
1144 "\n"
1145 "#define sipQtCreateUniversalSignal          0\n"
1146 "#define sipQtFindUniversalSignal            0\n"
1147 "#define sipQtEmitSignal                     0\n"
1148 "#define sipQtConnectPySignal                0\n"
1149 "#define sipQtDisconnectPySignal             0\n"
1150             );
1151 
1152     /* Define the names. */
1153     if (mod->container == NULL)
1154         generateNameCache(pt, fp);
1155 
1156     /* Generate the C++ code blocks. */
1157     generateCppCodeBlock(mod->cppcode, fp);
1158 
1159     /* Generate any virtual handlers. */
1160     for (vhd = pt->virthandlers; vhd != NULL; vhd = vhd->next)
1161         generateVirtualHandler(mod, vhd, fp);
1162 
1163     /* Generate any virtual error handlers. */
1164     for (veh = pt->errorhandlers; veh != NULL; veh = veh->next)
1165     {
1166         if (veh->mod == mod)
1167         {
1168             prcode(fp,
1169 "\n"
1170 "\n"
1171 "void sipVEH_%s_%s(sipSimpleWrapper *%s, sip_gilstate_t%s)\n"
1172 "{\n"
1173                 , mname, veh->name, (usedInCode(veh->code, "sipPySelf") ? "sipPySelf" : ""), (usedInCode(veh->code, "sipGILState") ? " sipGILState" : ""));
1174 
1175             generateCppCodeBlock(veh->code, fp);
1176 
1177             prcode(fp,
1178 "}\n"
1179                 );
1180         }
1181     }
1182 
1183     /* Generate the global functions. */
1184     for (md = mod->othfuncs; md != NULL; md = md->next)
1185     {
1186         if (md->slot == no_slot)
1187         {
1188             generateOrdinaryFunction(pt, mod, NULL, NULL, md, fp);
1189         }
1190         else
1191         {
1192             overDef *od;
1193 
1194             /*
1195              * Make sure that there is still an overload and we haven't moved
1196              * them all to classes.
1197              */
1198             for (od = mod->overs; od != NULL; od = od->next)
1199             {
1200                 if (od->common == md)
1201                 {
1202                     generateSlot(mod, NULL, NULL, md, fp);
1203                     slot_extenders = TRUE;
1204                     break;
1205                 }
1206             }
1207         }
1208     }
1209 
1210     /* Generate the global functions for any hidden namespaces. */
1211     for (cd = pt->classes; cd != NULL; cd = cd->next)
1212     {
1213         if (cd->iff->module == mod && isHiddenNamespace(cd))
1214         {
1215             for (md = cd->members; md != NULL; md = md->next)
1216             {
1217                 if (md->slot == no_slot)
1218                     generateOrdinaryFunction(pt, mod, cd, NULL, md, fp);
1219             }
1220         }
1221     }
1222 
1223     /* Generate any class specific ctor or slot extenders. */
1224     for (cd = mod->proxies; cd != NULL; cd = cd->next)
1225     {
1226         if (cd->ctors != NULL)
1227         {
1228             generateTypeInit(cd, mod, fp);
1229             ctor_extenders = TRUE;
1230         }
1231 
1232         for (md = cd->members; md != NULL; md = md->next)
1233         {
1234             generateSlot(mod, cd, NULL, md, fp);
1235             slot_extenders = TRUE;
1236         }
1237     }
1238 
1239     /* Generate any ctor extender table. */
1240     if (ctor_extenders)
1241     {
1242         prcode(fp,
1243 "\n"
1244 "static sipInitExtenderDef initExtenders[] = {\n"
1245             );
1246 
1247         for (cd = mod->proxies; cd != NULL; cd = cd->next)
1248             if (cd->ctors != NULL)
1249             {
1250                 prcode(fp,
1251 "    {%P, init_type_%L, ", cd->iff->api_range, cd->iff);
1252 
1253                 generateEncodedType(mod, cd, 0, fp);
1254 
1255                 prcode(fp, ", SIP_NULLPTR},\n"
1256                     );
1257             }
1258 
1259         prcode(fp,
1260 "    {-1, SIP_NULLPTR, {0, 0, 0}, SIP_NULLPTR}\n"
1261 "};\n"
1262             );
1263     }
1264 
1265     /* Generate any slot extender table. */
1266     if (slot_extenders)
1267     {
1268         prcode(fp,
1269 "\n"
1270 "static sipPySlotExtenderDef slotExtenders[] = {\n"
1271             );
1272 
1273         for (md = mod->othfuncs; md != NULL; md = md->next)
1274         {
1275             overDef *od;
1276 
1277             if (md->slot == no_slot)
1278                 continue;
1279 
1280             for (od = mod->overs; od != NULL; od = od->next)
1281                 if (od->common == md)
1282                 {
1283                     prcode(fp,
1284 "    {(void *)slot_%s, %s, {0, 0, 0}},\n"
1285                         , md->pyname->text, slotName(md->slot));
1286 
1287                     break;
1288                 }
1289         }
1290 
1291         for (cd = mod->proxies; cd != NULL; cd = cd->next)
1292             for (md = cd->members; md != NULL; md = md->next)
1293             {
1294                 prcode(fp,
1295 "    {(void *)slot_%L_%s, %s, ", cd->iff, md->pyname->text, slotName(md->slot));
1296 
1297                 generateEncodedType(mod, cd, 0, fp);
1298 
1299                 prcode(fp, "},\n"
1300                     );
1301             }
1302 
1303         prcode(fp,
1304 "    {SIP_NULLPTR, (sipPySlotType)0, {0, 0, 0}}\n"
1305 "};\n"
1306             );
1307     }
1308 
1309     /* Generate the global access functions. */
1310     generateAccessFunctions(pt, mod, NULL, fp);
1311 
1312     /* Generate any sub-class convertors. */
1313     nrSccs = generateSubClassConvertors(pt, mod, fp);
1314 
1315     /* Generate the external classes table if needed. */
1316     for (cd = pt->classes; cd != NULL; cd = cd->next)
1317     {
1318         if (!isExternal(cd))
1319             continue;
1320 
1321         if (cd->iff->module != mod)
1322             continue;
1323 
1324         if (!hasexternal)
1325         {
1326             prcode(fp,
1327 "\n"
1328 "\n"
1329 "/* This defines each external type declared in this module, */\n"
1330 "static sipExternalTypeDef externalTypesTable[] = {\n"
1331                 );
1332 
1333             hasexternal = TRUE;
1334         }
1335 
1336         prcode(fp,
1337 "    {%d, \"", cd->iff->ifacenr);
1338         prScopedName(fp, removeGlobalScope(classFQCName(cd)), ".");
1339         prcode(fp,"\"},\n"
1340             );
1341     }
1342 
1343     if (hasexternal)
1344         prcode(fp,
1345 "    {-1, SIP_NULLPTR}\n"
1346 "};\n"
1347             );
1348 
1349     /* Generate any enum slot tables. */
1350     for (ed = pt->enums; ed != NULL; ed = ed->next)
1351     {
1352         memberDef *slot;
1353 
1354         if (ed->module != mod || ed->fqcname == NULL)
1355             continue;
1356 
1357         if (ed->slots == NULL)
1358             continue;
1359 
1360         for (slot = ed->slots; slot != NULL; slot = slot->next)
1361             generateSlot(mod, NULL, ed, slot, fp);
1362 
1363         prcode(fp,
1364 "\n"
1365 "static sipPySlotDef slots_%C[] = {\n"
1366             , ed->fqcname);
1367 
1368         for (slot = ed->slots; slot != NULL; slot = slot->next)
1369         {
1370             const char *stype;
1371 
1372             if ((stype = slotName(slot->slot)) != NULL)
1373                 prcode(fp,
1374 "    {(void *)slot_%C_%s, %s},\n"
1375                     , ed->fqcname, slot->pyname->text, stype);
1376         }
1377 
1378         prcode(fp,
1379 "    {0, (sipPySlotType)0}\n"
1380 "};\n"
1381 "\n"
1382             );
1383     }
1384 
1385     /* Generate the enum type structures. */
1386     enum_idx = 0;
1387 
1388     for (ed = pt->enums; ed != NULL; ed = ed->next)
1389     {
1390         int type_nr = -1;
1391         apiVersionRangeDef *avr = NULL;
1392 
1393         if (ed->module != mod || ed->fqcname == NULL)
1394             continue;
1395 
1396         if (ed->ecd != NULL)
1397         {
1398             if (isTemplateClass(ed->ecd))
1399                 continue;
1400 
1401             type_nr = ed->ecd->iff->first_alt->ifacenr;
1402             avr = ed->ecd->iff->api_range;
1403         }
1404         else if (ed->emtd != NULL)
1405         {
1406             type_nr = ed->emtd->iff->first_alt->ifacenr;
1407             avr = ed->emtd->iff->api_range;
1408         }
1409 
1410         if (enum_idx == 0)
1411         {
1412             prcode(fp,
1413 "static sipEnumTypeDef enumTypes[] = {\n"
1414                 );
1415         }
1416 
1417         ed->enum_idx = enum_idx++;
1418 
1419         prcode(fp,
1420 "    {{%P, ", avr);
1421 
1422         if (ed->next_alt != NULL)
1423             prcode(fp, "&enumTypes[%d].etd_base", ed->next_alt->enum_idx);
1424         else
1425             prcode(fp, "0");
1426 
1427         prcode(fp, ", 0, SIP_TYPE_%s, %n, SIP_NULLPTR, 0}, %n, %d, ", (isScopedEnum(ed) ? "SCOPED_ENUM" : "ENUM"), ed->cname, ed->pyname, type_nr);
1428 
1429         if (ed->slots != NULL)
1430             prcode(fp, "slots_%C", ed->fqcname);
1431         else
1432             prcode(fp, "SIP_NULLPTR");
1433 
1434         prcode(fp, "},\n"
1435             );
1436     }
1437 
1438     if (enum_idx != 0)
1439         prcode(fp,
1440 "};\n"
1441             );
1442 
1443     nr_enummembers = generateEnumMemberTable(pt, mod, NULL, NULL, fp);
1444 
1445     /* Generate the types table. */
1446     if (mod->nr_needed_types > 0)
1447         generateTypesTable(mod, fp);
1448 
1449     if (mod->nrtypedefs > 0)
1450     {
1451         typedefDef *td;
1452 
1453         prcode(fp,
1454 "\n"
1455 "\n"
1456 "/*\n"
1457 " * These define each typedef in this module.\n"
1458 " */\n"
1459 "static sipTypedefDef typedefsTable[] = {\n"
1460             );
1461 
1462         for (td = pt->typedefs; td != NULL; td = td->next)
1463         {
1464             if (td->module != mod)
1465                 continue;
1466 
1467             prcode(fp,
1468 "    {\"%V\", \"", td->fqname);
1469 
1470             /* The default behaviour isn't right in a couple of cases. */
1471             if (td->type.atype == longlong_type)
1472                 prcode(fp, "long long");
1473             else if (td->type.atype == ulonglong_type)
1474                 prcode(fp, "unsigned long long");
1475             else
1476                 generateBaseType(NULL, &td->type, FALSE, STRIP_GLOBAL, fp);
1477 
1478             prcode(fp, "\"},\n"
1479                 );
1480         }
1481 
1482         prcode(fp,
1483 "};\n"
1484             );
1485     }
1486 
1487     for (veh = pt->errorhandlers; veh != NULL; veh = veh->next)
1488     {
1489         if (veh->mod == mod)
1490         {
1491             if (!hasvirterrorhandlers)
1492             {
1493                 hasvirterrorhandlers = TRUE;
1494 
1495                 prcode(fp,
1496 "\n"
1497 "\n"
1498 "/*\n"
1499 " * This defines the virtual error handlers that this module implements and\n"
1500 " * can be used by other modules.\n"
1501 " */\n"
1502 "static sipVirtErrorHandlerDef virtErrorHandlersTable[] = {\n"
1503                     );
1504             }
1505 
1506             prcode(fp,
1507 "    {\"%s\", sipVEH_%s_%s},\n"
1508                 , veh->name, mname, veh->name);
1509         }
1510     }
1511 
1512     if (hasvirterrorhandlers)
1513         prcode(fp,
1514 "    {SIP_NULLPTR, SIP_NULLPTR}\n"
1515 "};\n"
1516             );
1517 
1518     if (mod->allimports != NULL)
1519     {
1520         for (mld = mod->allimports; mld != NULL; mld = mld->next)
1521         {
1522             int i;
1523 
1524             if (mld->module->nr_needed_types > 0)
1525             {
1526                 prcode(fp,
1527 "\n"
1528 "\n"
1529 "/* This defines the types that this module needs to import from %s. */\n"
1530 "sipImportedTypeDef sipImportedTypes_%s_%s[] = {\n"
1531                     , mld->module->name
1532                     , mname, mld->module->name);
1533 
1534                 for (i = 0; i < mld->module->nr_needed_types; ++i)
1535                 {
1536                     argDef *ad = &mld->module->needed_types[i];
1537 
1538                     if (ad->atype == mapped_type)
1539                         prcode(fp,
1540 "    {\"%s\"},\n"
1541                             , ad->u.mtd->cname->text);
1542                     else
1543                         prcode(fp,
1544 "    {\"%V\"},\n"
1545                             , getFQCNameOfType(ad));
1546                 }
1547 
1548                 prcode(fp,
1549 "    {SIP_NULLPTR}\n"
1550 "};\n"
1551                     );
1552             }
1553 
1554             if (mld->module->nrvirterrorhandlers > 0)
1555             {
1556                 int i;
1557 
1558                 prcode(fp,
1559 "\n"
1560 "\n"
1561 "/*\n"
1562 " * This defines the virtual error handlers that this module needs to import\n"
1563 " * from %s.\n"
1564 " */\n"
1565 "sipImportedVirtErrorHandlerDef sipImportedVirtErrorHandlers_%s_%s[] = {\n"
1566                     , mld->module->name
1567                     , mname, mld->module->name);
1568 
1569                 /*
1570                  * The handlers are unordered so search for each in turn.
1571                  * There will probably be only one so speed isn't an issue.
1572                  */
1573                 for (i = 0; i < mld->module->nrvirterrorhandlers; ++i)
1574                 {
1575                     virtErrorHandler *veh;
1576 
1577                     for (veh = pt->errorhandlers; veh != NULL; veh = veh->next)
1578                     {
1579                         if (veh->mod == mld->module && veh->index == i)
1580                         {
1581                             prcode(fp,
1582 "    {\"%s\"},\n"
1583                                 , veh->name);
1584                         }
1585                     }
1586                 }
1587 
1588                 prcode(fp,
1589 "    {SIP_NULLPTR}\n"
1590 "};\n"
1591                     );
1592             }
1593 
1594             if (mld->module->nrexceptions > 0)
1595             {
1596                 int i;
1597 
1598                 prcode(fp,
1599 "\n"
1600 "\n"
1601 "/*\n"
1602 " * This defines the exception objects that this module needs to import from\n"
1603 " * %s.\n"
1604 " */\n"
1605 "sipImportedExceptionDef sipImportedExceptions_%s_%s[] = {\n"
1606                     , mld->module->name
1607                     , mname, mld->module->name);
1608 
1609                 /*
1610                  * The exceptions are unordered so search for each in turn.
1611                  * There will probably be very few so speed isn't an issue.
1612                  */
1613                 for (i = 0; i < mld->module->nrexceptions; ++i)
1614                 {
1615                     exceptionDef *xd;
1616 
1617                     for (xd = pt->exceptions; xd != NULL; xd = xd->next)
1618                     {
1619                         if (xd->iff->module == mld->module && xd->exceptionnr == i)
1620                         {
1621                             prcode(fp,
1622 "    {\"%s\"},\n"
1623                                 , xd->pyname);
1624                         }
1625                     }
1626                 }
1627 
1628                 prcode(fp,
1629 "    {SIP_NULLPTR}\n"
1630 "};\n"
1631                     );
1632             }
1633         }
1634 
1635         prcode(fp,
1636 "\n"
1637 "\n"
1638 "/* This defines the modules that this module needs to import. */\n"
1639 "static sipImportedModuleDef importsTable[] = {\n"
1640             );
1641 
1642         for (mld = mod->allimports; mld != NULL; mld = mld->next)
1643         {
1644             prcode(fp,
1645 "    {\"%s\", ", mld->module->fullname->text);
1646 
1647             if (mld->module->nr_needed_types > 0)
1648                 prcode(fp, "sipImportedTypes_%s_%s, ", mname, mld->module->name);
1649             else
1650                 prcode(fp, "SIP_NULLPTR, ");
1651 
1652             if (mld->module->nrvirterrorhandlers > 0)
1653                 prcode(fp, "sipImportedVirtErrorHandlers_%s_%s, ", mname, mld->module->name);
1654             else
1655                 prcode(fp, "SIP_NULLPTR, ");
1656 
1657             if (mld->module->nrexceptions > 0)
1658                 prcode(fp, "sipImportedExceptions_%s_%s", mname, mld->module->name);
1659             else
1660                 prcode(fp, "SIP_NULLPTR");
1661 
1662             prcode(fp, "},\n"
1663                 );
1664         }
1665 
1666         prcode(fp,
1667 "    {SIP_NULLPTR, SIP_NULLPTR, SIP_NULLPTR, SIP_NULLPTR}\n"
1668 "};\n"
1669             );
1670     }
1671 
1672     if (nrSccs > 0)
1673     {
1674         prcode(fp,
1675 "\n"
1676 "\n"
1677 "/* This defines the class sub-convertors that this module defines. */\n"
1678 "static sipSubClassConvertorDef convertorsTable[] = {\n"
1679             );
1680 
1681         for (cd = pt->classes; cd != NULL; cd = cd->next)
1682         {
1683             if (cd->iff->module != mod)
1684                 continue;
1685 
1686             if (cd->convtosubcode == NULL)
1687                 continue;
1688 
1689             prcode(fp,
1690 "    {sipSubClass_%C, ",classFQCName(cd));
1691 
1692             generateEncodedType(mod, cd->subbase, 0, fp);
1693 
1694             prcode(fp,", SIP_NULLPTR},\n");
1695         }
1696 
1697         prcode(fp,
1698 "    {SIP_NULLPTR, {0, 0, 0}, SIP_NULLPTR}\n"
1699 "};\n"
1700             );
1701     }
1702 
1703     /* Generate any license information. */
1704     if (mod->license != NULL)
1705     {
1706         licenseDef *ld = mod->license;
1707 
1708         prcode(fp,
1709 "\n"
1710 "\n"
1711 "/* Define the module's license. */\n"
1712 "static sipLicenseDef module_license = {\n"
1713             );
1714 
1715         prcode(fp,
1716 "    \"%s\",\n"
1717             , ld->type);
1718 
1719         if (ld->licensee != NULL)
1720             prcode(fp,
1721 "    \"%s\",\n"
1722                 , ld->licensee);
1723         else
1724             prcode(fp,
1725 "    SIP_NULLPTR,\n"
1726                 );
1727 
1728         if (ld->timestamp != NULL)
1729             prcode(fp,
1730 "    \"%s\",\n"
1731                 , ld->timestamp);
1732         else
1733             prcode(fp,
1734 "    SIP_NULLPTR,\n"
1735                 );
1736 
1737         if (ld->sig != NULL)
1738             prcode(fp,
1739 "    \"%s\"\n"
1740                 , ld->sig);
1741         else
1742             prcode(fp,
1743 "    SIP_NULLPTR\n"
1744                 );
1745 
1746         prcode(fp,
1747 "};\n"
1748             );
1749     }
1750 
1751     /* Generate each instance table. */
1752     is_inst_class = generateClasses(pt, mod, NULL, fp);
1753     is_inst_voidp = generateVoidPointers(pt, mod, NULL, fp);
1754     is_inst_char = generateChars(pt, mod, NULL, fp);
1755     is_inst_string = generateStrings(pt, mod, NULL, fp);
1756     is_inst_int = generateInts(pt, mod, NULL, fp);
1757     is_inst_long = generateLongs(pt, mod, NULL, fp);
1758     is_inst_ulong = generateUnsignedLongs(pt, mod, NULL, fp);
1759     is_inst_longlong = generateLongLongs(pt, mod, NULL, fp);
1760     is_inst_ulonglong = generateUnsignedLongLongs(pt, mod, NULL, fp);
1761     is_inst_double = generateDoubles(pt, mod, NULL, fp);
1762 
1763     /* Generate any exceptions table. */
1764     if (mod->nrexceptions > 0)
1765         prcode(fp,
1766 "\n"
1767 "\n"
1768 "PyObject *sipExportedExceptions_%s[%d];\n"
1769             , mname, mod->nrexceptions + 1);
1770 
1771     /* Generate any API versions table. */
1772     if (mod->api_ranges != NULL || mod->api_versions != NULL)
1773     {
1774         apiVersionRangeDef *avr;
1775 
1776         is_api_versions = TRUE;
1777 
1778         prcode(fp,
1779 "\n"
1780 "\n"
1781 "/* This defines the API versions and ranges in use. */\n"
1782 "static int apiVersions[] = {");
1783 
1784         for (avr = mod->api_ranges; avr != NULL; avr = avr->next)
1785             prcode(fp, "%n, %d, %d, ", avr->api_name, avr->from, avr->to);
1786 
1787         for (avr = mod->api_versions; avr != NULL; avr = avr->next)
1788             prcode(fp, "%n, %d, -1, ", avr->api_name, avr->from);
1789 
1790         prcode(fp, "-1};\n"
1791             );
1792     }
1793     else
1794         is_api_versions = FALSE;
1795 
1796     /* Generate any versioned global functions. */
1797     is_versioned_functions = FALSE;
1798 
1799     for (md = mod->othfuncs; md != NULL; md = md->next)
1800         if (md->slot == no_slot)
1801         {
1802             overDef *od;
1803             int has_docstring;
1804 
1805             if (notVersioned(md))
1806                 continue;
1807 
1808             if (!is_versioned_functions)
1809             {
1810                 prcode(fp,
1811 "\n"
1812 "\n"
1813 "/* This defines the global functions where all overloads are versioned. */\n"
1814 "static sipVersionedFunctionDef versionedFunctions[] = {\n"
1815                     );
1816 
1817                 is_versioned_functions = TRUE;
1818             }
1819 
1820             has_docstring = hasMemberDocstring(pt, mod->overs, md, NULL);
1821 
1822             /*
1823              * Every overload has an entry to capture all the version ranges.
1824              */
1825             for (od = mod->overs; od != NULL; od = od->next)
1826             {
1827                 if (od->common != md)
1828                     continue;
1829 
1830                 prcode(fp,
1831 "    {%n, ", md->pyname);
1832 
1833                 if (noArgParser(md) || useKeywordArgs(md))
1834                     prcode(fp, "(PyCFunction)func_%s, METH_VARARGS|METH_KEYWORDS", md->pyname->text);
1835                 else
1836                     prcode(fp, "func_%s, METH_VARARGS", md->pyname->text);
1837 
1838                 if (has_docstring)
1839                     prcode(fp, ", doc_%s", md->pyname->text);
1840                 else
1841                     prcode(fp, ", SIP_NULLPTR");
1842 
1843                 prcode(fp, ", %P},\n"
1844                         , od->api_range);
1845             }
1846         }
1847 
1848     if (is_versioned_functions)
1849         prcode(fp,
1850 "    {-1, 0, 0, 0, -1}\n"
1851 "};\n"
1852             );
1853 
1854     /* Generate any Qt support API. */
1855     if (moduleSupportsQt(pt, mod))
1856         prcode(fp,
1857 "\n"
1858 "\n"
1859 "/* This defines the Qt support API. */\n"
1860 "\n"
1861 "static sipQtAPI qtAPI = {\n"
1862 "    &sipExportedTypes_%s[%d],\n"
1863 "    sipQtCreateUniversalSignal,\n"
1864 "    sipQtFindUniversalSignal,\n"
1865 "    sipQtCreateUniversalSlot,\n"
1866 "    sipQtDestroyUniversalSlot,\n"
1867 "    sipQtFindSlot,\n"
1868 "    sipQtConnect,\n"
1869 "    sipQtDisconnect,\n"
1870 "    sipQtSameSignalSlotName,\n"
1871 "    sipQtFindSipslot,\n"
1872 "    sipQtEmitSignal,\n"
1873 "    sipQtConnectPySignal,\n"
1874 "    sipQtDisconnectPySignal\n"
1875 "};\n"
1876             , mname, pt->qobject_cd->iff->ifacenr);
1877 
1878     prcode(fp,
1879 "\n"
1880 "\n"
1881 "/* This defines this module. */\n"
1882 "sipExportedModuleDef sipModuleAPI_%s = {\n"
1883 "    0,\n"
1884 "    SIP_ABI_MINOR_VERSION,\n"
1885 "    %n,\n"
1886 "    0,\n"
1887 "    sipStrings_%s,\n"
1888 "    %s,\n"
1889 "    %s,\n"
1890 "    %d,\n"
1891         , mname
1892         , mod->fullname
1893         , pt->module->name
1894         , mod->allimports != NULL ? "importsTable" : "SIP_NULLPTR"
1895         , moduleSupportsQt(pt, mod) ? "&qtAPI" : "SIP_NULLPTR"
1896         , mod->nr_needed_types);
1897 
1898     if (mod->nr_needed_types > 0)
1899         prcode(fp,
1900 "    sipExportedTypes_%s,\n"
1901             , mname);
1902     else
1903         prcode(fp,
1904 "    SIP_NULLPTR,\n"
1905             );
1906 
1907     prcode(fp,
1908 "    %s,\n"
1909 "    %d,\n"
1910 "    %s,\n"
1911 "    %d,\n"
1912 "    %s,\n"
1913 "    %s,\n"
1914 "    %s,\n"
1915 "    {%s, %s, %s, %s, %s, %s, %s, %s, %s, %s},\n"
1916 "    %s,\n"
1917         , hasexternal ? "externalTypesTable" : "SIP_NULLPTR"
1918         , nr_enummembers
1919         , nr_enummembers > 0 ? "enummembers" : "SIP_NULLPTR"
1920         , mod->nrtypedefs
1921         , mod->nrtypedefs > 0 ? "typedefsTable" : "SIP_NULLPTR"
1922         , hasvirterrorhandlers ? "virtErrorHandlersTable" : "SIP_NULLPTR"
1923         , nrSccs > 0 ? "convertorsTable" : "SIP_NULLPTR"
1924         , is_inst_class ? "typeInstances" : "SIP_NULLPTR"
1925         , is_inst_voidp ? "voidPtrInstances" : "SIP_NULLPTR"
1926         , is_inst_char ? "charInstances" : "SIP_NULLPTR"
1927         , is_inst_string ? "stringInstances" : "SIP_NULLPTR"
1928         , is_inst_int ? "intInstances" : "SIP_NULLPTR"
1929         , is_inst_long ? "longInstances" : "SIP_NULLPTR"
1930         , is_inst_ulong ? "unsignedLongInstances" : "SIP_NULLPTR"
1931         , is_inst_longlong ? "longLongInstances" : "SIP_NULLPTR"
1932         , is_inst_ulonglong ? "unsignedLongLongInstances" : "SIP_NULLPTR"
1933         , is_inst_double ? "doubleInstances" : "SIP_NULLPTR"
1934         , mod->license != NULL ? "&module_license" : "SIP_NULLPTR");
1935 
1936     if (mod->nrexceptions > 0)
1937         prcode(fp,
1938 "    sipExportedExceptions_%s,\n"
1939             , mname);
1940     else
1941         prcode(fp,
1942 "    SIP_NULLPTR,\n"
1943             );
1944 
1945     prcode(fp,
1946 "    %s,\n"
1947 "    %s,\n"
1948 "    %s,\n"
1949 "    SIP_NULLPTR,\n"
1950 "    %s,\n"
1951 "    %s\n"
1952 "};\n"
1953         , slot_extenders ? "slotExtenders" : "SIP_NULLPTR"
1954         , ctor_extenders ? "initExtenders" : "SIP_NULLPTR"
1955         , hasDelayedDtors(mod) ? "sipDelayedDtors" : "SIP_NULLPTR"
1956         , is_api_versions ? "apiVersions" : "SIP_NULLPTR"
1957         , is_versioned_functions ? "versionedFunctions" : "SIP_NULLPTR");
1958 
1959     generateModDocstring(mod, fp);
1960 
1961     /* Generate the storage for the external API pointers. */
1962     prcode(fp,
1963 "\n"
1964 "\n"
1965 "/* The SIP API and the APIs of any imported modules. */\n"
1966 "const sipAPIDef *sipAPI_%s;\n"
1967         , mname);
1968 
1969     if (pluginPyQt5(pt))
1970         prcode(fp,
1971 "\n"
1972 "sip_qt_metaobject_func sip_%s_qt_metaobject;\n"
1973 "sip_qt_metacall_func sip_%s_qt_metacall;\n"
1974 "sip_qt_metacast_func sip_%s_qt_metacast;\n"
1975             , mname
1976             , mname
1977             , mname);
1978 
1979     /* Generate the Python module initialisation function. */
1980 
1981     if (mod->container == pt->module)
1982         prcode(fp,
1983 "\n"
1984 "PyObject *sip_init_%s()\n"
1985 "{\n"
1986             , mname);
1987     else
1988         generateModInitStart(pt->module, generating_c, fp);
1989 
1990     /* Generate the global functions. */
1991 
1992     prcode(fp,
1993 "    static PyMethodDef sip_methods[] = {\n"
1994         );
1995 
1996     generateGlobalFunctionTableEntries(pt, mod, mod->othfuncs, fp);
1997 
1998     /* Generate the global functions for any hidden namespaces. */
1999     for (cd = pt->classes; cd != NULL; cd = cd->next)
2000         if (cd->iff->module == mod && isHiddenNamespace(cd))
2001             generateGlobalFunctionTableEntries(pt, mod, cd->members, fp);
2002 
2003     prcode(fp,
2004 "        {SIP_NULLPTR, SIP_NULLPTR, 0, SIP_NULLPTR}\n"
2005 "    };\n"
2006         );
2007 
2008     generateModDefinition(mod, "sip_methods", fp);
2009 
2010     prcode(fp,
2011 "\n"
2012 "    PyObject *sipModule, *sipModuleDict;\n"
2013         );
2014 
2015     if (sipName != NULL)
2016         generateSipImportVariables(fp);
2017 
2018     /* Generate any pre-initialisation code. */
2019     generateCppCodeBlock(mod->preinitcode, fp);
2020 
2021     prcode(fp,
2022 "    /* Initialise the module and get it's dictionary. */\n"
2023 "    if ((sipModule = PyModule_Create(&sip_module_def)) == SIP_NULLPTR)\n"
2024 "        return SIP_NULLPTR;\n"
2025 "\n"
2026 "    sipModuleDict = PyModule_GetDict(sipModule);\n"
2027 "\n"
2028         );
2029 
2030     generateSipAPI(mod, sipName, fp);
2031 
2032     /* Generate any initialisation code. */
2033     generateCppCodeBlock(mod->initcode, fp);
2034 
2035     prcode(fp,
2036 "    /* Export the module and publish it's API. */\n"
2037 "    if (sipExportModule(&sipModuleAPI_%s, SIP_ABI_MAJOR_VERSION, SIP_ABI_MINOR_VERSION, 0) < 0)\n"
2038 "    {\n"
2039 "        Py_DECREF(sipModule);\n"
2040 "        return SIP_NULLPTR;\n"
2041 "    }\n"
2042         , mname);
2043 
2044     if (pluginPyQt5(pt))
2045     {
2046         /* Import the helpers. */
2047         prcode(fp,
2048 "\n"
2049 "    sip_%s_qt_metaobject = (sip_qt_metaobject_func)sipImportSymbol(\"qtcore_qt_metaobject\");\n"
2050 "    sip_%s_qt_metacall = (sip_qt_metacall_func)sipImportSymbol(\"qtcore_qt_metacall\");\n"
2051 "    sip_%s_qt_metacast = (sip_qt_metacast_func)sipImportSymbol(\"qtcore_qt_metacast\");\n"
2052 "\n"
2053 "    if (!sip_%s_qt_metacast)\n"
2054 "        Py_FatalError(\"Unable to import qtcore_qt_metacast\");\n"
2055 "\n"
2056             , mname
2057             , mname
2058             , mname
2059             , mname);
2060     }
2061 
2062     prcode(fp,
2063 "    /* Initialise the module now all its dependencies have been set up. */\n"
2064 "    if (sipInitModule(&sipModuleAPI_%s,sipModuleDict) < 0)\n"
2065 "    {\n"
2066 "        Py_DECREF(sipModule);\n"
2067 "        return SIP_NULLPTR;\n"
2068 "    }\n"
2069         , mname);
2070 
2071     generateTypesInline(pt, mod, fp);
2072 
2073     generatePyObjects(pt, mod, fp);
2074 
2075     /* Create any exception objects. */
2076     for (xd = pt->exceptions; xd != NULL; xd = xd->next)
2077     {
2078         if (xd->iff->module != mod)
2079             continue;
2080 
2081         if (xd->exceptionnr < 0)
2082             continue;
2083 
2084         prcode(fp,
2085 "\n"
2086 "    if ((sipExportedExceptions_%s[%d] = PyErr_NewException(\n"
2087 "            \"%s.%s\",\n"
2088 "            "
2089             , xd->iff->module->name, xd->exceptionnr
2090             , xd->iff->module->name, xd->pyname);
2091 
2092         if (xd->bibase != NULL)
2093             prcode(fp, "PyExc_%s", xd->bibase);
2094         else
2095             prcode(fp, "sipException_%C", xd->base->iff->fqcname);
2096 
2097         prcode(fp, ", SIP_NULLPTR)) == SIP_NULLPTR || PyDict_SetItemString(sipModuleDict, \"%s\", sipExportedExceptions_%s[%d]) < 0)\n"
2098 "    {\n"
2099 "        Py_DECREF(sipModule);\n"
2100 "        return SIP_NULLPTR;\n"
2101 "    }\n"
2102             , xd->pyname, xd->iff->module->name, xd->exceptionnr);
2103     }
2104 
2105     if (mod->nrexceptions > 0)
2106         prcode(fp,
2107 "\n"
2108 "    sipExportedExceptions_%s[%d] = SIP_NULLPTR;\n"
2109             , mname, mod->nrexceptions);
2110 
2111     /* Generate the interface source files. */
2112 
2113     /* Generate any post-initialisation code. */
2114     generateCppCodeBlock(mod->postinitcode, fp);
2115 
2116     prcode(fp,
2117 "\n"
2118 "    return sipModule;\n"
2119 "}\n"
2120         );
2121 
2122     /* Generate the interface source files. */
2123     for (iff = pt->ifacefiles; iff != NULL; iff = iff->next)
2124         if (iff->module == mod && iff->type != exception_iface)
2125         {
2126             int need_postinc;
2127 
2128             if (parts && files_in_part++ == max_per_part)
2129             {
2130                 /* Close the old part. */
2131                 closeFile(fp);
2132                 free(cppfile);
2133 
2134                 /* Create a new one. */
2135                 files_in_part = 1;
2136                 ++this_part;
2137 
2138                 cppfile = makePartName(codeDir, mname, this_part, srcSuffix);
2139                 fp = createCompilationUnit(mod, generated, cppfile,
2140                         "Module code.");
2141 
2142                 prcode(fp,
2143 "\n"
2144 "#include \"sipAPI%s.h\"\n"
2145                     , mname);
2146 
2147                 need_postinc = TRUE;
2148             }
2149             else
2150             {
2151                 need_postinc = FALSE;
2152             }
2153 
2154             generateIfaceCpp(pt, generated, py_debug, iff, need_postinc,
2155                     codeDir, srcSuffix,
2156                     ((parts && iff->file_extension == NULL) ? fp : NULL));
2157         }
2158 
2159     closeFile(fp);
2160     free(cppfile);
2161 
2162     /* How many parts we actually generated. */
2163     if (parts)
2164         parts = this_part + 1;
2165 
2166     mod->parts = parts;
2167 
2168     return generateInternalAPIHeader(pt, mod, codeDir, needed_qualifiers, xsl,
2169             py_debug);
2170 }
2171 
2172 
2173 /*
2174  * Generate the types table for a module.
2175  */
generateTypesTable(moduleDef * mod,FILE * fp)2176 static void generateTypesTable(moduleDef *mod, FILE *fp)
2177 {
2178     int i;
2179     argDef *ad;
2180 
2181     prcode(fp,
2182 "\n"
2183 "\n"
2184 "/*\n"
2185 " * This defines each type in this module.\n"
2186 " */\n"
2187 "sipTypeDef *sipExportedTypes_%s[] = {\n"
2188         , mod->name);
2189 
2190     for (ad = mod->needed_types, i = 0; i < mod->nr_needed_types; ++i, ++ad)
2191     {
2192         switch (ad->atype)
2193         {
2194         case class_type:
2195             if (isExternal(ad->u.cd))
2196                 prcode(fp,
2197 "    0,\n"
2198                     );
2199             else if (!isHiddenNamespace(ad->u.cd))
2200                 prcode(fp,
2201 "    &sipTypeDef_%s_%L.ctd_base,\n"
2202                     , mod->name, ad->u.cd->iff);
2203 
2204             break;
2205 
2206         case mapped_type:
2207             prcode(fp,
2208 "    &sipTypeDef_%s_%L.mtd_base,\n"
2209                 , mod->name, ad->u.mtd->iff);
2210             break;
2211 
2212         case enum_type:
2213             prcode(fp,
2214 "    &enumTypes[%d].etd_base,\n"
2215                 , ad->u.ed->enum_idx);
2216             break;
2217 
2218         /* Supress a compiler warning. */
2219         default:
2220             ;
2221         }
2222     }
2223 
2224     prcode(fp,
2225 "};\n"
2226         );
2227 }
2228 
2229 
2230 /*
2231  * Generate the code to get the sip API.
2232  */
generateSipAPI(moduleDef * mod,const char * sipName,FILE * fp)2233 static void generateSipAPI(moduleDef *mod, const char *sipName, FILE *fp)
2234 {
2235     /*
2236      * If there is no sip module name then we are getting the API from a
2237      * non-shared sip module.
2238      */
2239     if (sipName == NULL)
2240     {
2241         prcode(fp,
2242 "    if ((sipAPI_%s = sip_init_library(sipModuleDict)) == SIP_NULLPTR)\n"
2243 "        return SIP_NULLPTR;\n"
2244 "\n"
2245             , mod->name);
2246 
2247         return;
2248     }
2249 
2250     /*
2251      * Note that we don't use PyCapsule_Import() because it doesn't handle
2252      * package.module.attribute.
2253      */
2254 
2255     prcode(fp,
2256 "    /* Get the SIP module's API. */\n"
2257 "    if ((sip_sipmod = PyImport_ImportModule(\"%s\")) == SIP_NULLPTR)\n"
2258 "    {\n"
2259 "        Py_DECREF(sipModule);\n"
2260 "        return SIP_NULLPTR;\n"
2261 "    }\n"
2262 "\n"
2263 "    sip_capiobj = PyDict_GetItemString(PyModule_GetDict(sip_sipmod), \"_C_API\");\n"
2264 "    Py_DECREF(sip_sipmod);\n"
2265 "\n"
2266 "    if (sip_capiobj == SIP_NULLPTR || !PyCapsule_CheckExact(sip_capiobj))\n"
2267 "    {\n"
2268 "        PyErr_SetString(PyExc_AttributeError, \"%s._C_API is missing or has the wrong type\");\n"
2269 "        Py_DECREF(sipModule);\n"
2270 "        return SIP_NULLPTR;\n"
2271 "    }\n"
2272 "\n"
2273         , sipName
2274         , sipName);
2275 
2276     if (generating_c)
2277         prcode(fp,
2278 "    sipAPI_%s = (const sipAPIDef *)PyCapsule_GetPointer(sip_capiobj, \"%s._C_API\");\n"
2279         , mod->name, sipName);
2280     else
2281         prcode(fp,
2282 "    sipAPI_%s = reinterpret_cast<const sipAPIDef *>(PyCapsule_GetPointer(sip_capiobj, \"%s._C_API\"));\n"
2283 "\n"
2284         , mod->name, sipName);
2285 
2286     prcode(fp,
2287 "    if (sipAPI_%s == SIP_NULLPTR)\n"
2288 "    {\n"
2289 "        Py_DECREF(sipModule);\n"
2290 "        return SIP_NULLPTR;\n"
2291 "    }\n"
2292 "\n"
2293         , mod->name);
2294 }
2295 
2296 
2297 /*
2298  * Generate the variables needed by generateSipImport().
2299  */
generateSipImportVariables(FILE * fp)2300 static void generateSipImportVariables(FILE *fp)
2301 {
2302     prcode(fp,
2303 "    PyObject *sip_sipmod, *sip_capiobj;\n"
2304 "\n"
2305         );
2306 }
2307 
2308 
2309 /*
2310  * Generate the start of the Python module initialisation function.
2311  */
generateModInitStart(moduleDef * mod,int gen_c,FILE * fp)2312 static void generateModInitStart(moduleDef *mod, int gen_c, FILE *fp)
2313 {
2314     prcode(fp,
2315 "\n"
2316 "\n"
2317 "/* The Python module initialisation function. */\n"
2318 "#if defined(SIP_STATIC_MODULE)\n"
2319 "%sPyObject *PyInit_%s(%s)\n"
2320 "#else\n"
2321 "PyMODINIT_FUNC PyInit_%s(%s)\n"
2322 "#endif\n"
2323 "{\n"
2324         , (gen_c ? "" : "extern \"C\" "), mod->name, (gen_c ? "void" : "")
2325         , mod->name, (gen_c ? "void" : ""));
2326 }
2327 
2328 
2329 /*
2330  * Generate the Python v3 module definition structure.
2331  */
generateModDefinition(moduleDef * mod,const char * methods,FILE * fp)2332 static void generateModDefinition(moduleDef *mod, const char *methods,
2333         FILE *fp)
2334 {
2335     prcode(fp,
2336 "\n"
2337 "    static PyModuleDef sip_module_def = {\n"
2338 "        PyModuleDef_HEAD_INIT,\n"
2339 "        \"%s\",\n"
2340         , mod->fullname->text);
2341 
2342     if (mod->docstring == NULL)
2343         prcode(fp,
2344 "        SIP_NULLPTR,\n"
2345             );
2346     else
2347         prcode(fp,
2348 "        doc_mod_%s,\n"
2349             , mod->name);
2350 
2351     prcode(fp,
2352 "        -1,\n"
2353 "        %s,\n"
2354 "        SIP_NULLPTR,\n"
2355 "        SIP_NULLPTR,\n"
2356 "        SIP_NULLPTR,\n"
2357 "        SIP_NULLPTR\n"
2358 "    };\n"
2359         , methods);
2360 }
2361 
2362 
2363 /*
2364  * Generate all the sub-class convertors for a module.
2365  */
generateSubClassConvertors(sipSpec * pt,moduleDef * mod,FILE * fp)2366 static int generateSubClassConvertors(sipSpec *pt, moduleDef *mod, FILE *fp)
2367 {
2368     int nrSccs = 0;
2369     classDef *cd;
2370 
2371     for (cd = pt->classes; cd != NULL; cd = cd->next)
2372     {
2373         int needs_sipClass;
2374 
2375         if (cd->iff->module != mod)
2376             continue;
2377 
2378         if (cd->convtosubcode == NULL)
2379             continue;
2380 
2381         prcode(fp,
2382 "\n"
2383 "\n"
2384 "/* Convert to a sub-class if possible. */\n"
2385             );
2386 
2387         if (!generating_c)
2388             prcode(fp,
2389 "extern \"C\" {static const sipTypeDef *sipSubClass_%C(void **);}\n"
2390                 , classFQCName(cd));
2391 
2392         /* Allow the deprecated use of sipClass rather than sipType. */
2393         needs_sipClass = usedInCode(cd->convtosubcode, "sipClass");
2394 
2395         prcode(fp,
2396 "static const sipTypeDef *sipSubClass_%C(void **sipCppRet)\n"
2397 "{\n"
2398 "    %S *sipCpp = reinterpret_cast<%S *>(*sipCppRet);\n"
2399             , classFQCName(cd)
2400             , classFQCName(cd->subbase), classFQCName(cd->subbase));
2401 
2402         if (needs_sipClass)
2403             prcode(fp,
2404 "    sipWrapperType *sipClass;\n"
2405 "\n"
2406                 );
2407         else
2408             prcode(fp,
2409 "    const sipTypeDef *sipType;\n"
2410 "\n"
2411                 );
2412 
2413         generateCppCodeBlock(cd->convtosubcode, fp);
2414 
2415         if (needs_sipClass)
2416             prcode(fp,
2417 "\n"
2418 "    return (sipClass ? sipClass->wt_td : 0);\n"
2419 "}\n"
2420                 );
2421         else
2422             prcode(fp,
2423 "\n"
2424 "    return sipType;\n"
2425 "}\n"
2426                 );
2427 
2428         ++nrSccs;
2429     }
2430 
2431     return nrSccs;
2432 }
2433 
2434 
2435 /*
2436  * Generate the structure representing an encoded type.
2437  */
generateEncodedType(moduleDef * mod,classDef * cd,int last,FILE * fp)2438 static void generateEncodedType(moduleDef *mod, classDef *cd, int last,
2439         FILE *fp)
2440 {
2441     moduleDef *cmod = cd->iff->module;
2442 
2443     prcode(fp, "{%u, ", cd->iff->first_alt->ifacenr);
2444 
2445     if (cmod == mod)
2446         prcode(fp, "255");
2447     else
2448     {
2449         int mod_nr = 0;
2450         moduleListDef *mld;
2451 
2452         for (mld = mod->allimports; mld != NULL; mld = mld->next)
2453         {
2454             if (mld->module == cmod)
2455             {
2456                 prcode(fp, "%u", mod_nr);
2457                 break;
2458             }
2459 
2460             ++mod_nr;
2461         }
2462     }
2463 
2464     prcode(fp, ", %u}", last);
2465 }
2466 
2467 
2468 /*
2469  * Generate an ordinary function.
2470  */
generateOrdinaryFunction(sipSpec * pt,moduleDef * mod,classDef * c_scope,mappedTypeDef * mt_scope,memberDef * md,FILE * fp)2471 static void generateOrdinaryFunction(sipSpec *pt, moduleDef *mod,
2472         classDef *c_scope, mappedTypeDef *mt_scope, memberDef *md, FILE *fp)
2473 {
2474     overDef *od;
2475     int need_intro, has_auto_docstring;
2476     ifaceFileDef *scope;
2477     const char *kw_fw_decl, *kw_decl;
2478 
2479     if (mt_scope != NULL)
2480     {
2481         scope = mt_scope->iff;
2482         od = mt_scope->overs;
2483     }
2484     else if (c_scope != NULL)
2485     {
2486         scope = (isHiddenNamespace(c_scope) ? NULL : c_scope->iff);
2487         od = c_scope->overs;
2488     }
2489     else
2490     {
2491         scope = NULL;
2492         od = mod->overs;
2493     }
2494 
2495     prcode(fp,
2496 "\n"
2497 "\n"
2498         );
2499 
2500     /* Generate the docstrings. */
2501     if (hasMemberDocstring(pt, od, md, scope))
2502     {
2503         if (scope != NULL)
2504             prcode(fp,
2505 "PyDoc_STRVAR(doc_%L_%s, \"", scope, md->pyname->text);
2506         else
2507             prcode(fp,
2508 "PyDoc_STRVAR(doc_%s, \"" , md->pyname->text);
2509 
2510         has_auto_docstring = generateMemberDocstring(pt, od, md, FALSE, fp);
2511 
2512         prcode(fp, "\");\n"
2513 "\n"
2514             );
2515     }
2516     else
2517     {
2518         has_auto_docstring = FALSE;
2519     }
2520 
2521     if (noArgParser(md) || useKeywordArgs(md))
2522     {
2523         kw_fw_decl = ", PyObject *";
2524         kw_decl = ", PyObject *sipKwds";
2525     }
2526     else
2527     {
2528         kw_fw_decl = "";
2529         kw_decl = "";
2530     }
2531 
2532     if (scope != NULL)
2533     {
2534         if (!generating_c)
2535             prcode(fp,
2536 "extern \"C\" {static PyObject *meth_%L_%s(PyObject *, PyObject *%s);}\n"
2537                 , scope, md->pyname->text, kw_fw_decl);
2538 
2539         prcode(fp,
2540 "static PyObject *meth_%L_%s(PyObject *, PyObject *sipArgs%s)\n"
2541             , scope, md->pyname->text, kw_decl);
2542     }
2543     else
2544     {
2545         const char *self = (generating_c ? "sipSelf" : "");
2546 
2547         if (!generating_c)
2548             prcode(fp,
2549 "extern \"C\" {static PyObject *func_%s(PyObject *,PyObject *%s);}\n"
2550                 , md->pyname->text, kw_fw_decl);
2551 
2552         prcode(fp,
2553 "static PyObject *func_%s(PyObject *%s,PyObject *sipArgs%s)\n"
2554             , md->pyname->text, self, kw_decl);
2555     }
2556 
2557     prcode(fp,
2558 "{\n"
2559         );
2560 
2561     need_intro = TRUE;
2562 
2563     while (od != NULL)
2564     {
2565         if (od->common == md)
2566         {
2567             if (noArgParser(md))
2568             {
2569                 generateCppCodeBlock(od->methodcode, fp);
2570                 break;
2571             }
2572 
2573             if (need_intro)
2574             {
2575                 prcode(fp,
2576 "    PyObject *sipParseErr = SIP_NULLPTR;\n"
2577                     );
2578 
2579                 need_intro = FALSE;
2580             }
2581 
2582             generateFunctionBody(od, c_scope, mt_scope, c_scope, TRUE, mod, fp);
2583         }
2584 
2585         od = od->next;
2586     }
2587 
2588     if (!need_intro)
2589     {
2590         prcode(fp,
2591 "\n"
2592 "    /* Raise an exception if the arguments couldn't be parsed. */\n"
2593 "    sipNoFunction(sipParseErr, %N, ", md->pyname);
2594 
2595         if (has_auto_docstring)
2596         {
2597             if (scope != NULL)
2598                 prcode(fp, "doc_%L_%s", scope, md->pyname->text);
2599             else
2600                 prcode(fp, "doc_%s", md->pyname->text);
2601         }
2602         else
2603         {
2604             prcode(fp, "SIP_NULLPTR");
2605         }
2606 
2607         prcode(fp, ");\n"
2608 "\n"
2609 "    return SIP_NULLPTR;\n"
2610             );
2611     }
2612 
2613     prcode(fp,
2614 "}\n"
2615         );
2616 }
2617 
2618 
2619 /*
2620  * Generate the table of enum members for a scope.  Return the number of them.
2621  */
generateEnumMemberTable(sipSpec * pt,moduleDef * mod,classDef * cd,mappedTypeDef * mtd,FILE * fp)2622 static int generateEnumMemberTable(sipSpec *pt, moduleDef *mod, classDef *cd,
2623         mappedTypeDef *mtd, FILE *fp)
2624 {
2625     int i, nr_members;
2626     enumDef *ed;
2627     enumMemberDef **etab, **et;
2628 
2629     /* First we count how many. */
2630 
2631     nr_members = 0;
2632 
2633     for (ed = pt->enums; ed != NULL; ed = ed->next)
2634     {
2635         enumMemberDef *emd;
2636         classDef *ps = pyScope(ed->ecd);
2637 
2638         if (ed->module != mod)
2639             continue;
2640 
2641         if (cd != NULL)
2642         {
2643             if (ps != cd || (isProtectedEnum(ed) && !hasShadow(cd)))
2644                 continue;
2645         }
2646         else if (mtd != NULL)
2647         {
2648             if (ed->emtd != mtd)
2649                 continue;
2650         }
2651         else if (ps != NULL || ed->emtd != NULL || ed->fqcname == NULL)
2652         {
2653             continue;
2654         }
2655 
2656         for (emd = ed->members; emd != NULL; emd = emd->next)
2657             ++nr_members;
2658     }
2659 
2660     if (nr_members == 0)
2661         return 0;
2662 
2663     /* Create a table so they can be sorted. */
2664 
2665     etab = sipCalloc(nr_members, sizeof (enumMemberDef *));
2666 
2667     et = etab;
2668 
2669     for (ed = pt->enums; ed != NULL; ed = ed->next)
2670     {
2671         enumMemberDef *emd;
2672         classDef *ps = pyScope(ed->ecd);
2673 
2674         if (ed->module != mod)
2675             continue;
2676 
2677         if (cd != NULL)
2678         {
2679             if (ps != cd)
2680                 continue;
2681         }
2682         else if (mtd != NULL)
2683         {
2684             if (ed->emtd != mtd)
2685                 continue;
2686         }
2687         else if (ps != NULL || ed->emtd != NULL || ed->fqcname == NULL)
2688         {
2689             continue;
2690         }
2691 
2692         for (emd = ed->members; emd != NULL; emd = emd->next)
2693             *et++ = emd;
2694     }
2695 
2696     qsort(etab, nr_members, sizeof (enumMemberDef *), compareEnumMembers);
2697 
2698     /* Now generate the table. */
2699 
2700     if (cd == NULL && mtd == NULL)
2701     {
2702         prcode(fp,
2703 "\n"
2704 "/* These are the enum members of all global enums. */\n"
2705 "static sipEnumMemberDef enummembers[] = {\n"
2706         );
2707     }
2708     else
2709     {
2710         ifaceFileDef *iff = (cd != NULL ? cd->iff : mtd->iff);
2711 
2712         prcode(fp,
2713 "\n"
2714 "static sipEnumMemberDef enummembers_%L[] = {\n"
2715             , iff);
2716     }
2717 
2718     for (i = 0; i < nr_members; ++i)
2719     {
2720         enumMemberDef *emd;
2721 
2722         emd = etab[i];
2723 
2724         prcode(fp,
2725 "    {%N, ", emd->pyname);
2726 
2727         if (!generating_c)
2728             prcode(fp, "static_cast<int>(");
2729 
2730         if (!isNoScope(emd->ed))
2731         {
2732             if (isScopedEnum(emd->ed))
2733                 prcode(fp, "::%s", emd->ed->cname->text);
2734             else if (emd->ed->ecd != NULL)
2735                 prEnumMemberScope(emd, fp);
2736             else if (mtd != NULL)
2737                 prcode(fp, "%S", mtd->iff->fqcname);
2738 
2739             prcode(fp, "::");
2740         }
2741 
2742         prcode(fp, "%s%s, %d},\n", emd->cname, (generating_c ? "" : ")"), emd->ed->first_alt->enumnr);
2743     }
2744 
2745     prcode(fp,
2746 "};\n"
2747         );
2748 
2749     return nr_members;
2750 }
2751 
2752 
2753 /*
2754  * The qsort helper to compare two enumMemberDef structures based on the name
2755  * of the enum member.
2756  */
compareEnumMembers(const void * m1,const void * m2)2757 static int compareEnumMembers(const void *m1,const void *m2)
2758 {
2759     return strcmp((*(enumMemberDef **)m1)->pyname->text,
2760               (*(enumMemberDef **)m2)->pyname->text);
2761 }
2762 
2763 
2764 /*
2765  * Generate the access functions for the variables.
2766  */
generateAccessFunctions(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)2767 static void generateAccessFunctions(sipSpec *pt, moduleDef *mod, classDef *cd,
2768         FILE *fp)
2769 {
2770     varDef *vd;
2771 
2772     for (vd = pt->vars; vd != NULL; vd = vd->next)
2773     {
2774         if (vd->accessfunc == NULL)
2775             continue;
2776 
2777         if (vd->ecd != cd || vd->module != mod)
2778             continue;
2779 
2780         prcode(fp,
2781 "\n"
2782 "\n"
2783 "/* Access function. */\n"
2784             );
2785 
2786         if (!generating_c)
2787             prcode(fp,
2788 "extern \"C\" {static void *access_%C();}\n"
2789             , vd->fqcname);
2790 
2791         prcode(fp,
2792 "static void *access_%C()\n"
2793 "{\n"
2794             , vd->fqcname);
2795 
2796         generateCppCodeBlock(vd->accessfunc, fp);
2797 
2798         prcode(fp,
2799 "}\n"
2800             );
2801     }
2802 }
2803 
2804 
2805 /*
2806  * Generate the inline code to add a set of Python objects to a module
2807  * dictionary.  Note that we should add these via a table (like int, etc) but
2808  * that will require a major API version change so this will do for now.
2809  */
generatePyObjects(sipSpec * pt,moduleDef * mod,FILE * fp)2810 static void generatePyObjects(sipSpec *pt, moduleDef *mod, FILE *fp)
2811 {
2812     int noIntro;
2813     varDef *vd;
2814 
2815     noIntro = TRUE;
2816 
2817     for (vd = pt->vars; vd != NULL; vd = vd->next)
2818     {
2819         if (vd->module != mod)
2820             continue;
2821 
2822         if (vd->type.atype != pyobject_type &&
2823             vd->type.atype != pytuple_type &&
2824             vd->type.atype != pylist_type &&
2825             vd->type.atype != pydict_type &&
2826             vd->type.atype != pycallable_type &&
2827             vd->type.atype != pyslice_type &&
2828             vd->type.atype != pytype_type &&
2829             vd->type.atype != pybuffer_type)
2830             continue;
2831 
2832         if (needsHandler(vd))
2833             continue;
2834 
2835         if (noIntro)
2836         {
2837             prcode(fp,
2838 "\n"
2839 "    /* Define the Python objects wrapped as such. */\n"
2840                 );
2841 
2842             noIntro = FALSE;
2843         }
2844 
2845         prcode(fp,
2846 "    PyDict_SetItemString(sipModuleDict, %N, %S);\n"
2847                 , vd->pyname, vd->fqcname);
2848     }
2849 }
2850 
2851 
2852 /*
2853  * Generate the inline code to add a set of generated type instances to a
2854  * dictionary.
2855  */
generateTypesInline(sipSpec * pt,moduleDef * mod,FILE * fp)2856 static void generateTypesInline(sipSpec *pt, moduleDef *mod, FILE *fp)
2857 {
2858     int noIntro;
2859     varDef *vd;
2860 
2861     noIntro = TRUE;
2862 
2863     for (vd = pt->vars; vd != NULL; vd = vd->next)
2864     {
2865         if (vd->module != mod)
2866             continue;
2867 
2868         if (vd->type.atype != class_type && vd->type.atype != mapped_type && vd->type.atype != enum_type)
2869             continue;
2870 
2871         if (needsHandler(vd))
2872             continue;
2873 
2874         /* Skip classes that don't need inline code. */
2875         if (generating_c || vd->accessfunc != NULL || vd->type.nrderefs != 0)
2876             continue;
2877 
2878         if (noIntro)
2879         {
2880             prcode(fp,
2881 "\n"
2882 "    /*\n"
2883 "     * Define the class, mapped type and enum instances that have to be\n"
2884 "     * added inline.\n"
2885 "     */\n"
2886                 );
2887 
2888             noIntro = FALSE;
2889         }
2890 
2891         prcode(fp,
2892 "    sipAddTypeInstance(");
2893 
2894         if (pyScope(vd->ecd) == NULL)
2895             prcode(fp, "sipModuleDict");
2896         else
2897             prcode(fp, "(PyObject *)sipTypeAsPyTypeObject(sipType_%C)", classFQCName(vd->ecd));
2898 
2899         prcode(fp, ",%N,", vd->pyname);
2900 
2901         if (isConstArg(&vd->type))
2902             prcode(fp, "const_cast<%b *>(&%S)", &vd->type, vd->fqcname);
2903         else
2904             prcode(fp, "&%S", vd->fqcname);
2905 
2906         if (vd->type.atype == class_type)
2907             prcode(fp, ",sipType_%C);\n"
2908                 , classFQCName(vd->type.u.cd));
2909         else if (vd->type.atype == enum_type)
2910             prcode(fp, ",sipType_%C);\n"
2911                 , vd->type.u.ed->fqcname);
2912         else
2913             prcode(fp, ",sipType_%T);\n"
2914                 , &vd->type);
2915     }
2916 }
2917 
2918 
2919 /*
2920  * Generate the code to add a set of class instances to a dictionary.  Return
2921  * TRUE if there was at least one.
2922  */
generateClasses(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)2923 static int generateClasses(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
2924 {
2925     int noIntro;
2926     varDef *vd;
2927 
2928     noIntro = TRUE;
2929 
2930     for (vd = pt->vars; vd != NULL; vd = vd->next)
2931     {
2932         if (pyScope(vd->ecd) != cd || vd->module != mod)
2933             continue;
2934 
2935         if (vd->type.atype != class_type && (vd->type.atype != enum_type || vd->type.u.ed->fqcname == NULL))
2936             continue;
2937 
2938         if (needsHandler(vd))
2939             continue;
2940 
2941         /*
2942          * Skip ordinary C++ class instances which need to be done with inline
2943          * code rather than through a static table.  This is because C++ does
2944          * not guarantee the order in which the table and the instance will be
2945          * created.  So far this has only been seen to be a problem when
2946          * statically linking SIP generated modules on Windows.
2947          */
2948         if (!generating_c && vd->accessfunc == NULL && vd->type.nrderefs == 0)
2949             continue;
2950 
2951         if (noIntro)
2952         {
2953             if (cd != NULL)
2954                 prcode(fp,
2955 "\n"
2956 "\n"
2957 "/* Define the class and enum instances to be added to this type dictionary. */\n"
2958 "static sipTypeInstanceDef typeInstances_%C[] = {\n"
2959                     , classFQCName(cd));
2960             else
2961                 prcode(fp,
2962 "\n"
2963 "\n"
2964 "/* Define the class and enum instances to be added to this module dictionary. */\n"
2965 "static sipTypeInstanceDef typeInstances[] = {\n"
2966                     );
2967 
2968             noIntro = FALSE;
2969         }
2970 
2971         prcode(fp,
2972 "    {%N, ", vd->pyname);
2973 
2974         if (vd->type.atype == class_type)
2975         {
2976             scopedNameDef *vcname = classFQCName(vd->type.u.cd);
2977 
2978             if (vd->accessfunc != NULL)
2979             {
2980                 prcode(fp, "(void *)access_%C, &sipType_%C, SIP_ACCFUNC|SIP_NOT_IN_MAP", vd->fqcname, vcname);
2981             }
2982             else if (vd->type.nrderefs != 0)
2983             {
2984                 /* This may be a bit heavy handed. */
2985                 if (isConstArg(&vd->type))
2986                     prcode(fp, "(void *)");
2987 
2988                 prcode(fp, "&%S, &sipType_%C, SIP_INDIRECT", vd->fqcname, vcname);
2989             }
2990             else if (isConstArg(&vd->type))
2991             {
2992                 prcode(fp, "const_cast<%b *>(&%S), &sipType_%C, 0", &vd->type, vd->fqcname, vcname);
2993             }
2994             else
2995             {
2996                 prcode(fp, "&%S, &sipType_%C, 0", vd->fqcname, vcname);
2997             }
2998         }
2999         else
3000         {
3001             prcode(fp, "&%S, &sipType_%C, 0", vd->fqcname, vd->type.u.ed->fqcname);
3002         }
3003 
3004         prcode(fp, "},\n"
3005             );
3006     }
3007 
3008     if (!noIntro)
3009         prcode(fp,
3010 "    {0, 0, 0, 0}\n"
3011 "};\n"
3012             );
3013 
3014     return !noIntro;
3015 }
3016 
3017 
3018 /*
3019  * Generate the code to add a set of void pointers to a dictionary.  Return
3020  * TRUE if there was at least one.
3021  */
generateVoidPointers(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)3022 static int generateVoidPointers(sipSpec *pt, moduleDef *mod, classDef *cd,
3023         FILE *fp)
3024 {
3025     int noIntro;
3026     varDef *vd;
3027 
3028     noIntro = TRUE;
3029 
3030     for (vd = pt->vars; vd != NULL; vd = vd->next)
3031     {
3032         if (pyScope(vd->ecd) != cd || vd->module != mod)
3033             continue;
3034 
3035         if (vd->type.atype != void_type && vd->type.atype != struct_type)
3036             continue;
3037 
3038         if (needsHandler(vd))
3039             continue;
3040 
3041         if (noIntro)
3042         {
3043             if (cd != NULL)
3044                 prcode(fp,
3045 "\n"
3046 "\n"
3047 "/* Define the void pointers to be added to this type dictionary. */\n"
3048 "static sipVoidPtrInstanceDef voidPtrInstances_%C[] = {\n"
3049                     , classFQCName(cd));
3050             else
3051                 prcode(fp,
3052 "\n"
3053 "\n"
3054 "/* Define the void pointers to be added to this module dictionary. */\n"
3055 "static sipVoidPtrInstanceDef voidPtrInstances[] = {\n"
3056                     );
3057 
3058             noIntro = FALSE;
3059         }
3060 
3061         if (isConstArg(&vd->type))
3062             prcode(fp,
3063 "    {%N, const_cast<%b *>(%S)},\n"
3064                 , vd->pyname, &vd->type, vd->fqcname);
3065         else
3066             prcode(fp,
3067 "    {%N, %S},\n"
3068                 , vd->pyname, vd->fqcname);
3069     }
3070 
3071     if (!noIntro)
3072         prcode(fp,
3073 "    {0, 0}\n"
3074 "};\n"
3075             );
3076 
3077     return !noIntro;
3078 }
3079 
3080 
3081 /*
3082  * Generate the code to add a set of characters to a dictionary.  Return TRUE
3083  * if there was at least one.
3084  */
generateChars(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)3085 static int generateChars(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
3086 {
3087     int noIntro;
3088     varDef *vd;
3089 
3090     noIntro = TRUE;
3091 
3092     for (vd = pt->vars; vd != NULL; vd = vd->next)
3093     {
3094         argType vtype = vd->type.atype;
3095 
3096         if (pyScope(vd->ecd) != cd || vd->module != mod)
3097             continue;
3098 
3099         if (!((vtype == ascii_string_type || vtype == latin1_string_type || vtype == utf8_string_type || vtype == sstring_type || vtype == ustring_type || vtype == string_type) && vd->type.nrderefs == 0))
3100             continue;
3101 
3102         if (needsHandler(vd))
3103             continue;
3104 
3105         if (noIntro)
3106         {
3107             if (cd != NULL)
3108                 prcode(fp,
3109 "\n"
3110 "\n"
3111 "/* Define the chars to be added to this type dictionary. */\n"
3112 "static sipCharInstanceDef charInstances_%C[] = {\n"
3113                     , classFQCName(cd));
3114             else
3115                 prcode(fp,
3116 "\n"
3117 "\n"
3118 "/* Define the chars to be added to this module dictionary. */\n"
3119 "static sipCharInstanceDef charInstances[] = {\n"
3120                     );
3121 
3122             noIntro = FALSE;
3123         }
3124 
3125         prcode(fp,
3126 "    {%N, %S, '%c'},\n"
3127             , vd->pyname, (cd != NULL ? vd->fqcname : vd->fqcname->next), getEncoding(&vd->type));
3128     }
3129 
3130     if (!noIntro)
3131         prcode(fp,
3132 "    {0, 0, 0}\n"
3133 "};\n"
3134             );
3135 
3136     return !noIntro;
3137 }
3138 
3139 
3140 /*
3141  * Generate the code to add a set of strings to a dictionary.  Return TRUE if
3142  * there is at least one.
3143  */
generateStrings(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)3144 static int generateStrings(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
3145 {
3146     int noIntro;
3147     varDef *vd;
3148 
3149     noIntro = TRUE;
3150 
3151     for (vd = pt->vars; vd != NULL; vd = vd->next)
3152     {
3153         argType vtype = vd->type.atype;
3154         const char *cast;
3155         char encoding;
3156 
3157         if (pyScope(vd->ecd) != cd || vd->module != mod)
3158             continue;
3159 
3160         if (!(((vtype == ascii_string_type || vtype == latin1_string_type || vtype == utf8_string_type || vtype == sstring_type || vtype == ustring_type || vtype == string_type) && vd->type.nrderefs != 0) || vtype == wstring_type))
3161             continue;
3162 
3163         if (needsHandler(vd))
3164             continue;
3165 
3166         if (noIntro)
3167         {
3168             if (cd != NULL)
3169                 prcode(fp,
3170 "\n"
3171 "\n"
3172 "/* Define the strings to be added to this type dictionary. */\n"
3173 "static sipStringInstanceDef stringInstances_%C[] = {\n"
3174                     , classFQCName(cd));
3175             else
3176                 prcode(fp,
3177 "\n"
3178 "\n"
3179 "/* Define the strings to be added to this module dictionary. */\n"
3180 "static sipStringInstanceDef stringInstances[] = {\n"
3181                     );
3182 
3183             noIntro = FALSE;
3184         }
3185 
3186         /* This is the hack for handling wchar_t and wchar_t*. */
3187         encoding = getEncoding(&vd->type);
3188 
3189         if (encoding == 'w')
3190             cast = "(const char *)&";
3191         else if (encoding == 'W')
3192             cast = "(const char *)";
3193         else
3194             cast = "";
3195 
3196         prcode(fp,
3197 "    {%N, %s%S, '%c'},\n"
3198             , vd->pyname, cast, (cd != NULL ? vd->fqcname : vd->fqcname->next), encoding);
3199     }
3200 
3201     if (!noIntro)
3202         prcode(fp,
3203 "    {0, 0, 0}\n"
3204 "};\n"
3205             );
3206 
3207     return !noIntro;
3208 }
3209 
3210 
3211 /*
3212  * Generate the code to add a set of ints to a dictionary.  Return TRUE if
3213  * there was at least one.
3214  */
generateInts(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)3215 static int generateInts(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
3216 {
3217     int noIntro;
3218     varDef *vd;
3219     enumDef *ed;
3220 
3221     noIntro = TRUE;
3222 
3223     for (vd = pt->vars; vd != NULL; vd = vd->next)
3224     {
3225         argType vtype = vd->type.atype;
3226 
3227         if (pyScope(vd->ecd) != cd || vd->module != mod)
3228             continue;
3229 
3230         if (!(vtype == enum_type || vtype == byte_type ||
3231               vtype == sbyte_type || vtype == ubyte_type ||
3232               vtype == ushort_type || vtype == short_type ||
3233               vtype == cint_type || vtype == int_type ||
3234               vtype == bool_type || vtype == cbool_type))
3235             continue;
3236 
3237         if (needsHandler(vd))
3238             continue;
3239 
3240         /* Named enums are handled elsewhere. */
3241         if (vtype == enum_type && vd->type.u.ed->fqcname != NULL)
3242             continue;
3243 
3244         if (noIntro)
3245         {
3246             ints_intro(cd, fp);
3247             noIntro = FALSE;
3248         }
3249 
3250         prcode(fp,
3251 "    {%N, %S},\n"
3252             , vd->pyname, (cd != NULL ? vd->fqcname : vd->fqcname->next));
3253     }
3254 
3255     /* Now do global anonymous enums. */
3256     if (cd == NULL)
3257         for (ed = pt->enums; ed != NULL; ed = ed->next)
3258         {
3259             enumMemberDef *em;
3260 
3261             if (ed->ecd != cd || ed->module != mod)
3262                 continue;
3263 
3264             if (ed->fqcname != NULL)
3265                 continue;
3266 
3267             for (em = ed->members; em != NULL; em = em->next)
3268             {
3269                 if (noIntro)
3270                 {
3271                     ints_intro(cd, fp);
3272                     noIntro = FALSE;
3273                 }
3274 
3275                 prcode(fp,
3276 "    {%N, %s},\n"
3277                     , em->pyname, em->cname);
3278             }
3279         }
3280 
3281     if (!noIntro)
3282         prcode(fp,
3283 "    {0, 0}\n"
3284 "};\n"
3285             );
3286 
3287     return !noIntro;
3288 }
3289 
3290 
3291 /*
3292  * Generate the intro for a table of int instances.
3293  */
ints_intro(classDef * cd,FILE * fp)3294 static void ints_intro(classDef *cd, FILE *fp)
3295 {
3296     if (cd != NULL)
3297         prcode(fp,
3298 "\n"
3299 "\n"
3300 "/* Define the ints to be added to this type dictionary. */\n"
3301 "static sipIntInstanceDef intInstances_%C[] = {\n"
3302             ,classFQCName(cd));
3303     else
3304         prcode(fp,
3305 "\n"
3306 "\n"
3307 "/* Define the ints to be added to this module dictionary. */\n"
3308 "static sipIntInstanceDef intInstances[] = {\n"
3309             );
3310 }
3311 
3312 
3313 /*
3314  * Generate the code to add a set of longs to a dictionary.  Return TRUE if
3315  * there was at least one.
3316  */
generateLongs(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)3317 static int generateLongs(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
3318 {
3319     return generateVariableType(pt, mod, cd, long_type, "long", "Long", "long", fp);
3320 }
3321 
3322 
3323 /*
3324  * Generate the code to add a set of unsigned longs to a dictionary.  Return
3325  * TRUE if there was at least one.
3326  */
generateUnsignedLongs(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)3327 static int generateUnsignedLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
3328         FILE *fp)
3329 {
3330     return generateVariableType(pt, mod, cd, ulong_type, "unsigned long", "UnsignedLong", "unsignedLong", fp);
3331 }
3332 
3333 
3334 /*
3335  * Generate the code to add a set of long longs to a dictionary.  Return TRUE
3336  * if there was at least one.
3337  */
generateLongLongs(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)3338 static int generateLongLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
3339         FILE *fp)
3340 {
3341     return generateVariableType(pt, mod, cd, longlong_type, "long long", "LongLong", "longLong", fp);
3342 }
3343 
3344 
3345 /*
3346  * Generate the code to add a set of unsigned long longs to a dictionary.
3347  * Return TRUE if there was at least one.
3348  */
generateUnsignedLongLongs(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)3349 static int generateUnsignedLongLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
3350         FILE *fp)
3351 {
3352     return generateVariableType(pt, mod, cd, ulonglong_type, "unsigned long long", "UnsignedLongLong", "unsignedLongLong", fp);
3353 }
3354 
3355 
3356 /*
3357  * Generate the code to add a set of a particular type to a dictionary.  Return
3358  * TRUE if there was at least one.
3359  */
generateVariableType(sipSpec * pt,moduleDef * mod,classDef * cd,argType atype,const char * eng,const char * s1,const char * s2,FILE * fp)3360 static int generateVariableType(sipSpec *pt, moduleDef *mod, classDef *cd,
3361         argType atype, const char *eng, const char *s1, const char *s2,
3362         FILE *fp)
3363 {
3364     int noIntro;
3365     varDef *vd;
3366 
3367     noIntro = TRUE;
3368 
3369     for (vd = pt->vars; vd != NULL; vd = vd->next)
3370     {
3371         argType vtype = vd->type.atype;
3372 
3373         /*
3374          * We treat unsigned and size_t as unsigned long as we don't (currently
3375          * anyway) generate a separate table for them.
3376          */
3377         if ((vtype == uint_type || vtype == size_type) && atype == ulong_type)
3378             vtype = ulong_type;
3379 
3380         if (pyScope(vd->ecd) != cd || vd->module != mod)
3381             continue;
3382 
3383         if (vtype != atype)
3384             continue;
3385 
3386         if (needsHandler(vd))
3387             continue;
3388 
3389         if (noIntro)
3390         {
3391             if (cd != NULL)
3392                 prcode(fp,
3393 "\n"
3394 "\n"
3395 "/* Define the %ss to be added to this type dictionary. */\n"
3396 "static sip%sInstanceDef %sInstances_%C[] = {\n"
3397                     , eng
3398                     , s1, s2, classFQCName(cd));
3399             else
3400                 prcode(fp,
3401 "\n"
3402 "\n"
3403 "/* Define the %ss to be added to this module dictionary. */\n"
3404 "static sip%sInstanceDef %sInstances[] = {\n"
3405                     , eng
3406                     , s1, s2);
3407 
3408             noIntro = FALSE;
3409         }
3410 
3411         prcode(fp,
3412 "    {%N, %S},\n"
3413             , vd->pyname, (cd != NULL ? vd->fqcname : vd->fqcname->next));
3414     }
3415 
3416     if (!noIntro)
3417         prcode(fp,
3418 "    {0, 0}\n"
3419 "};\n"
3420             );
3421 
3422     return !noIntro;
3423 }
3424 
3425 
3426 /*
3427  * Generate the code to add a set of doubles to a dictionary.  Return TRUE if
3428  * there was at least one.
3429  */
generateDoubles(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)3430 static int generateDoubles(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
3431 {
3432     int noIntro;
3433     varDef *vd;
3434 
3435     noIntro = TRUE;
3436 
3437     for (vd = pt->vars; vd != NULL; vd = vd->next)
3438     {
3439         argType vtype = vd->type.atype;
3440 
3441         if (pyScope(vd->ecd) != cd || vd->module != mod)
3442             continue;
3443 
3444         if (!(vtype == float_type || vtype == cfloat_type || vtype == double_type || vtype == cdouble_type))
3445             continue;
3446 
3447         if (needsHandler(vd))
3448             continue;
3449 
3450         if (noIntro)
3451         {
3452             if (cd != NULL)
3453                 prcode(fp,
3454 "\n"
3455 "\n"
3456 "/* Define the doubles to be added to this type dictionary. */\n"
3457 "static sipDoubleInstanceDef doubleInstances_%C[] = {\n"
3458                     , classFQCName(cd));
3459             else
3460                 prcode(fp,
3461 "\n"
3462 "\n"
3463 "/* Define the doubles to be added to this module dictionary. */\n"
3464 "static sipDoubleInstanceDef doubleInstances[] = {\n"
3465                     );
3466 
3467             noIntro = FALSE;
3468         }
3469 
3470         prcode(fp,
3471 "    {%N, %S},\n"
3472             , vd->pyname, (cd != NULL ? vd->fqcname : vd->fqcname->next));
3473     }
3474 
3475     if (!noIntro)
3476         prcode(fp,
3477 "    {0, 0}\n"
3478 "};\n"
3479             );
3480 
3481     return !noIntro;
3482 }
3483 
3484 
3485 /*
3486  * See if an interface file has any content.
3487  */
emptyIfaceFile(sipSpec * pt,ifaceFileDef * iff)3488 static int emptyIfaceFile(sipSpec *pt, ifaceFileDef *iff)
3489 {
3490     classDef *cd;
3491     mappedTypeDef *mtd;
3492 
3493     for (cd = pt->classes; cd != NULL; cd = cd->next)
3494         if (!isHiddenNamespace(cd) && !isProtectedClass(cd) && !isExternal(cd) && cd->iff == iff)
3495             return FALSE;
3496 
3497     for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
3498         if (mtd->iff == iff)
3499             return FALSE;
3500 
3501     return TRUE;
3502 }
3503 
3504 
3505 /*
3506  * Generate the C/C++ code for an interface.
3507  */
generateIfaceCpp(sipSpec * pt,stringList ** generated,int py_debug,ifaceFileDef * iff,int need_postinc,const char * codeDir,const char * srcSuffix,FILE * master)3508 static void generateIfaceCpp(sipSpec *pt, stringList **generated, int py_debug,
3509         ifaceFileDef *iff, int need_postinc, const char *codeDir,
3510         const char *srcSuffix, FILE *master)
3511 {
3512     char *cppfile;
3513     const char *cmname = iff->module->name;
3514     classDef *cd;
3515     mappedTypeDef *mtd;
3516     FILE *fp;
3517 
3518     /*
3519      * Check that there will be something in the file so that we don't get
3520      * warning messages from ranlib.
3521      */
3522     if (emptyIfaceFile(pt, iff))
3523         return;
3524 
3525     if (master == NULL)
3526     {
3527         cppfile = createIfaceFileName(codeDir,iff,srcSuffix);
3528         fp = createCompilationUnit(iff->module, generated, cppfile,
3529                 "Interface wrapper code.");
3530 
3531         prcode(fp,
3532 "\n"
3533 "#include \"sipAPI%s.h\"\n"
3534             , cmname);
3535 
3536         need_postinc = TRUE;
3537     }
3538     else
3539     {
3540         fp = master;
3541 
3542         /* Suppress a compiler warning. */
3543         cppfile = NULL;
3544     }
3545 
3546     prcode(fp,
3547 "\n"
3548             );
3549 
3550     generateCppCodeBlock(iff->hdrcode, fp);
3551     generateUsedIncludes(iff->used, fp);
3552 
3553     if (need_postinc)
3554         generateCppCodeBlock(iff->module->unitpostinccode, fp);
3555 
3556     for (cd = pt->classes; cd != NULL; cd = cd->next)
3557     {
3558         /*
3559          * Protected classes must be generated in the interface file of the
3560          * enclosing scope.
3561          */
3562         if (isProtectedClass(cd))
3563             continue;
3564 
3565         if (isExternal(cd))
3566             continue;
3567 
3568         if (cd->iff == iff)
3569         {
3570             classDef *pcd;
3571 
3572             generateClassCpp(cd, pt, py_debug, fp);
3573 
3574             /* Generate any enclosed protected classes. */
3575             for (pcd = pt->classes; pcd != NULL; pcd = pcd->next)
3576                 if (isProtectedClass(pcd) && pcd->ecd == cd)
3577                     generateClassCpp(pcd, pt, py_debug, fp);
3578         }
3579     }
3580 
3581     for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
3582         if (mtd->iff == iff)
3583             generateMappedTypeCpp(mtd, pt, fp);
3584 
3585     if (master == NULL)
3586     {
3587         closeFile(fp);
3588         free(cppfile);
3589     }
3590 }
3591 
3592 
3593 /*
3594  * Return a filename for an interface C++ or header file on the heap.
3595  */
createIfaceFileName(const char * codeDir,ifaceFileDef * iff,const char * suffix)3596 static char *createIfaceFileName(const char *codeDir, ifaceFileDef *iff,
3597         const char *suffix)
3598 {
3599     char *fn;
3600     scopedNameDef *snd;
3601 
3602     fn = concat(codeDir,"/sip",iff->module->name,NULL);
3603 
3604     for (snd = iff->fqcname; snd != NULL; snd = snd->next)
3605         append(&fn,snd->name);
3606 
3607     if (iff->api_range != NULL)
3608     {
3609         char buf[50];
3610 
3611         sprintf(buf, "_%d", iff->api_range->index);
3612         append(&fn, buf);
3613     }
3614 
3615     if (iff->file_extension != NULL)
3616         suffix = iff->file_extension;
3617 
3618     append(&fn,suffix);
3619 
3620     return fn;
3621 }
3622 
3623 
3624 /*
3625  * Generate the C++ code for a mapped type version.
3626  */
generateMappedTypeCpp(mappedTypeDef * mtd,sipSpec * pt,FILE * fp)3627 static void generateMappedTypeCpp(mappedTypeDef *mtd, sipSpec *pt, FILE *fp)
3628 {
3629     int need_xfer, nr_methods, nr_enums;
3630     memberDef *md;
3631 
3632     generateCppCodeBlock(mtd->typecode, fp);
3633 
3634     if (!noRelease(mtd))
3635     {
3636         /*
3637          * Generate the assignment helper.  Note that the source pointer is not
3638          * const.  This is to allow the source instance to be modified as a
3639          * consequence of the assignment, eg. if it is implementing some sort
3640          * of reference counting scheme.
3641          */
3642         prcode(fp,
3643 "\n"
3644 "\n"
3645             );
3646 
3647         if (!generating_c)
3648             prcode(fp,
3649 "extern \"C\" {static void assign_%L(void *, Py_ssize_t, void *);}\n"
3650                 , mtd->iff);
3651 
3652         prcode(fp,
3653 "static void assign_%L(void *sipDst, Py_ssize_t sipDstIdx, void *sipSrc)\n"
3654 "{\n"
3655             , mtd->iff);
3656 
3657         if (generating_c)
3658             prcode(fp,
3659 "    ((%b *)sipDst)[sipDstIdx] = *((%b *)sipSrc);\n"
3660                 , &mtd->type, &mtd->type);
3661         else
3662             prcode(fp,
3663 "    reinterpret_cast<%b *>(sipDst)[sipDstIdx] = *reinterpret_cast<%b *>(sipSrc);\n"
3664                 , &mtd->type, &mtd->type);
3665 
3666         prcode(fp,
3667 "}\n"
3668             );
3669 
3670         /* Generate the array allocation helper. */
3671         prcode(fp,
3672 "\n"
3673 "\n"
3674             );
3675 
3676         if (!generating_c)
3677             prcode(fp,
3678 "extern \"C\" {static void *array_%L(Py_ssize_t);}\n"
3679                 , mtd->iff);
3680 
3681         prcode(fp,
3682 "static void *array_%L(Py_ssize_t sipNrElem)\n"
3683 "{\n"
3684             , mtd->iff);
3685 
3686         if (generating_c)
3687             prcode(fp,
3688 "    return sipMalloc(sizeof (%b) * sipNrElem);\n"
3689                 , &mtd->type);
3690         else
3691             prcode(fp,
3692 "    return new %b[sipNrElem];\n"
3693                 , &mtd->type);
3694 
3695         prcode(fp,
3696 "}\n"
3697             );
3698 
3699         /* Generate the copy helper. */
3700         prcode(fp,
3701 "\n"
3702 "\n"
3703             );
3704 
3705         if (!generating_c)
3706             prcode(fp,
3707 "extern \"C\" {static void *copy_%L(const void *, Py_ssize_t);}\n"
3708                 , mtd->iff);
3709 
3710         prcode(fp,
3711 "static void *copy_%L(const void *sipSrc, Py_ssize_t sipSrcIdx)\n"
3712 "{\n"
3713             , mtd->iff);
3714 
3715         if (generating_c)
3716             prcode(fp,
3717 "    %b *sipPtr = sipMalloc(sizeof (%b));\n"
3718 "    *sipPtr = ((const %b *)sipSrc)[sipSrcIdx];\n"
3719 "\n"
3720 "    return sipPtr;\n"
3721                 , &mtd->type, &mtd->type
3722                 , &mtd->type);
3723         else
3724             prcode(fp,
3725 "    return new %b(reinterpret_cast<const %b *>(sipSrc)[sipSrcIdx]);\n"
3726                 , &mtd->type, &mtd->type);
3727 
3728         prcode(fp,
3729 "}\n"
3730             );
3731 
3732         prcode(fp,
3733 "\n"
3734 "\n"
3735 "/* Call the mapped type's destructor. */\n"
3736             );
3737 
3738         if (!generating_c)
3739             prcode(fp,
3740 "extern \"C\" {static void release_%L(void *, int);}\n"
3741                 , mtd->iff);
3742 
3743         prcode(fp,
3744 "static void release_%L(void *ptr, int%s)\n"
3745 "{\n"
3746             , mtd->iff, (generating_c ? " status" : ""));
3747 
3748         if (release_gil)
3749             prcode(fp,
3750 "    Py_BEGIN_ALLOW_THREADS\n"
3751                 );
3752 
3753         if (generating_c)
3754             prcode(fp,
3755 "    sipFree(ptr);\n"
3756                 );
3757         else
3758             prcode(fp,
3759 "    delete reinterpret_cast<%b *>(ptr);\n"
3760                 , &mtd->type);
3761 
3762         if (release_gil)
3763             prcode(fp,
3764 "    Py_END_ALLOW_THREADS\n"
3765                 );
3766 
3767         prcode(fp,
3768 "}\n"
3769 "\n"
3770             );
3771     }
3772 
3773     generateConvertToDefinitions(mtd,NULL,fp);
3774 
3775     /* Generate the from type convertor. */
3776     need_xfer = (generating_c || usedInCode(mtd->convfromcode, "sipTransferObj"));
3777 
3778     prcode(fp,
3779 "\n"
3780 "\n"
3781         );
3782 
3783     if (!generating_c)
3784         prcode(fp,
3785 "extern \"C\" {static PyObject *convertFrom_%L(void *, PyObject *);}\n"
3786             , mtd->iff);
3787 
3788     prcode(fp,
3789 "static PyObject *convertFrom_%L(void *sipCppV, PyObject *%s)\n"
3790 "{\n"
3791 "   ", mtd->iff, (need_xfer ? "sipTransferObj" : ""));
3792 
3793     generateMappedTypeFromVoid(mtd, "sipCpp", "sipCppV", fp);
3794 
3795     prcode(fp, ";\n"
3796 "\n"
3797         );
3798 
3799     generateCppCodeBlock(mtd->convfromcode,fp);
3800 
3801     prcode(fp,
3802 "}\n"
3803         );
3804 
3805     /* Generate the static methods. */
3806     for (md = mtd->members; md != NULL; md = md->next)
3807         generateOrdinaryFunction(pt, mtd->iff->module, NULL, mtd, md, fp);
3808 
3809     nr_methods = generateMappedTypeMethodTable(pt, mtd, fp);
3810 
3811     nr_enums = generateEnumMemberTable(pt, mtd->iff->module, NULL, mtd, fp);
3812 
3813     prcode(fp,
3814 "\n"
3815 "\n"
3816 "sipMappedTypeDef ");
3817 
3818     generateTypeDefName(mtd->iff, fp);
3819 
3820     prcode(fp, " = {\n"
3821 "    {\n"
3822 "        %P,\n"
3823 "        "
3824         , mtd->iff->api_range);
3825 
3826     generateTypeDefLink(mtd->iff, fp);
3827 
3828     prcode(fp, ",\n"
3829 "        0,\n"
3830 "        %sSIP_TYPE_MAPPED,\n"
3831 "        %n,     /* %s */\n"
3832 "        SIP_NULLPTR,\n"
3833 "        0\n"
3834 "    },\n"
3835 "    {\n"
3836         , (handlesNone(mtd) ? "SIP_TYPE_ALLOW_NONE|" : "")
3837         , mtd->cname, mtd->cname->text);
3838 
3839     if (nr_enums == 0)
3840         prcode(fp,
3841 "        -1,\n"
3842             );
3843     else
3844         prcode(fp,
3845 "        %n,\n"
3846             , mtd->pyname);
3847 
3848     prcode(fp,
3849 "        {0, 0, 1},\n"
3850         );
3851 
3852     if (nr_methods == 0)
3853         prcode(fp,
3854 "        0, 0,\n"
3855             );
3856     else
3857         prcode(fp,
3858 "        %d, methods_%L,\n"
3859             , nr_methods, mtd->iff);
3860 
3861     if (nr_enums == 0)
3862         prcode(fp,
3863 "        0, 0,\n"
3864             );
3865     else
3866         prcode(fp,
3867 "        %d, enummembers_%L,\n"
3868             , nr_enums, mtd->iff);
3869 
3870     prcode(fp,
3871 "        0, 0,\n"
3872 "        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}\n"
3873 "    },\n"
3874         );
3875 
3876     if (noRelease(mtd))
3877         prcode(fp,
3878 "    0,\n"
3879 "    0,\n"
3880 "    0,\n"
3881 "    0,\n"
3882             );
3883     else
3884         prcode(fp,
3885 "    assign_%L,\n"
3886 "    array_%L,\n"
3887 "    copy_%L,\n"
3888 "    release_%L,\n"
3889             , mtd->iff
3890             , mtd->iff
3891             , mtd->iff
3892             , mtd->iff);
3893 
3894     prcode(fp,
3895 "    convertTo_%L,\n"
3896 "    convertFrom_%L\n"
3897         , mtd->iff
3898         , mtd->iff);
3899 
3900     prcode(fp,
3901 "};\n"
3902         );
3903 }
3904 
3905 
3906 /*
3907  * Generate the name of the type structure for a class or mapped type.
3908  */
generateTypeDefName(ifaceFileDef * iff,FILE * fp)3909 static void generateTypeDefName(ifaceFileDef *iff, FILE *fp)
3910 {
3911     prcode(fp, "sipTypeDef_%s_%L", iff->module->name, iff);
3912 }
3913 
3914 
3915 /*
3916  * Generate the link to a type structure implementing an alternate API.
3917  */
generateTypeDefLink(ifaceFileDef * iff,FILE * fp)3918 static void generateTypeDefLink(ifaceFileDef *iff, FILE *fp)
3919 {
3920     if (iff->next_alt != NULL)
3921     {
3922         prcode(fp, "&");
3923         generateTypeDefName(iff->next_alt, fp);
3924 
3925         if (iff->next_alt->type == mappedtype_iface)
3926             prcode(fp, ".mtd_base");
3927         else
3928             prcode(fp, ".ctd_base");
3929     }
3930     else
3931         prcode(fp, "SIP_NULLPTR");
3932 }
3933 
3934 
3935 /*
3936  * Generate the C++ code for a class.
3937  */
generateClassCpp(classDef * cd,sipSpec * pt,int py_debug,FILE * fp)3938 static void generateClassCpp(classDef *cd, sipSpec *pt, int py_debug, FILE *fp)
3939 {
3940     moduleDef *mod = cd->iff->module;
3941 
3942     /* Generate any local class code. */
3943 
3944     generateCppCodeBlock(cd->cppcode, fp);
3945 
3946     generateClassFunctions(pt, mod, cd, py_debug, fp);
3947 
3948     generateAccessFunctions(pt, mod, cd, fp);
3949 
3950     if (cd->iff->type != namespace_iface)
3951     {
3952         generateConvertToDefinitions(NULL,cd,fp);
3953 
3954         /* Generate the optional from type convertor. */
3955         if (cd->convfromcode != NULL)
3956         {
3957             int need_xfer;
3958 
3959             need_xfer = (generating_c || usedInCode(cd->convfromcode, "sipTransferObj"));
3960 
3961             prcode(fp,
3962 "\n"
3963 "\n"
3964                 );
3965 
3966             if (!generating_c)
3967                 prcode(fp,
3968 "extern \"C\" {static PyObject *convertFrom_%L(void *, PyObject *);}\n"
3969                     , cd->iff);
3970 
3971             prcode(fp,
3972 "static PyObject *convertFrom_%L(void *sipCppV, PyObject *%s)\n"
3973 "{\n"
3974 "   ", cd->iff, (need_xfer ? "sipTransferObj" : ""));
3975 
3976             generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
3977 
3978             prcode(fp, ";\n"
3979 "\n"
3980                 );
3981 
3982             generateCppCodeBlock(cd->convfromcode, fp);
3983 
3984             prcode(fp,
3985 "}\n"
3986                 );
3987         }
3988     }
3989 
3990     /* The type definition structure. */
3991     generateTypeDefinition(pt, cd, py_debug, fp);
3992 }
3993 
3994 
3995 /*
3996  * Return a sorted array of relevant functions for a namespace.
3997  */
3998 
createFunctionTable(memberDef * members,int * nrp)3999 static sortedMethTab *createFunctionTable(memberDef *members, int *nrp)
4000 {
4001     int nr;
4002     sortedMethTab *mtab, *mt;
4003     memberDef *md;
4004 
4005     /* First we need to count the number of applicable functions. */
4006     nr = 0;
4007 
4008     for (md = members; md != NULL; md = md->next)
4009         ++nr;
4010 
4011     if ((*nrp = nr) == 0)
4012         return NULL;
4013 
4014     /* Create the table of methods. */
4015     mtab = sipCalloc(nr, sizeof (sortedMethTab));
4016 
4017     /* Initialise the table. */
4018     mt = mtab;
4019 
4020     for (md = members; md != NULL; md = md->next)
4021     {
4022         mt->md = md;
4023         ++mt;
4024     }
4025 
4026     /* Finally, sort the table. */
4027     qsort(mtab,nr,sizeof (sortedMethTab),compareMethTab);
4028 
4029     return mtab;
4030 }
4031 
4032 
4033 /*
4034  * Return a sorted array of relevant methods (either lazy or non-lazy) for a
4035  * class.
4036  */
createMethodTable(classDef * cd,int * nrp)4037 static sortedMethTab *createMethodTable(classDef *cd, int *nrp)
4038 {
4039     int nr;
4040     visibleList *vl;
4041     sortedMethTab *mtab, *mt;
4042 
4043     /*
4044      * First we need to count the number of applicable methods.  Only provide
4045      * an entry point if there is at least one overload that is defined in this
4046      * class and is a non-abstract function or slot.  We allow private (even
4047      * though we don't actually generate code) because we need to intercept the
4048      * name before it reaches a more public version further up the class
4049      * hierarchy.  We add the ctor and any variable handlers as special
4050      * entries.
4051      */
4052     nr = 0;
4053 
4054     for (vl = cd->visible; vl != NULL; vl = vl->next)
4055     {
4056         overDef *od;
4057 
4058         if (vl->m->slot != no_slot)
4059             continue;
4060 
4061         for (od = vl->cd->overs; od != NULL; od = od->next)
4062         {
4063             /*
4064              * Skip protected methods if we don't have the means to handle
4065              * them.
4066              */
4067             if (isProtected(od) && !hasShadow(cd))
4068                 continue;
4069 
4070             if (skipOverload(od,vl->m,cd,vl->cd,TRUE))
4071                 continue;
4072 
4073             ++nr;
4074 
4075             break;
4076         }
4077     }
4078 
4079     if ((*nrp = nr) == 0)
4080         return NULL;
4081 
4082     /* Create the table of methods. */
4083 
4084     mtab = sipCalloc(nr, sizeof (sortedMethTab));
4085 
4086     /* Initialise the table. */
4087 
4088     mt = mtab;
4089 
4090     for (vl = cd->visible; vl != NULL; vl = vl->next)
4091     {
4092         int need_method;
4093         overDef *od;
4094 
4095         if (vl->m->slot != no_slot)
4096             continue;
4097 
4098         need_method = FALSE;
4099 
4100         for (od = vl->cd->overs; od != NULL; od = od->next)
4101         {
4102             /*
4103              * Skip protected methods if we don't have the means to handle
4104              * them.
4105              */
4106             if (isProtected(od) && !hasShadow(cd))
4107                 continue;
4108 
4109             if (!skipOverload(od,vl->m,cd,vl->cd,TRUE))
4110                 need_method = TRUE;
4111         }
4112 
4113         if (need_method)
4114         {
4115             mt->md = vl->m;
4116             ++mt;
4117         }
4118     }
4119 
4120     /* Finally sort the table. */
4121 
4122     qsort(mtab,nr,sizeof (sortedMethTab),compareMethTab);
4123 
4124     return mtab;
4125 }
4126 
4127 
4128 /*
4129  * The qsort helper to compare two sortedMethTab structures based on the Python
4130  * name of the method.
4131  */
4132 
compareMethTab(const void * m1,const void * m2)4133 static int compareMethTab(const void *m1,const void *m2)
4134 {
4135     return strcmp(((sortedMethTab *)m1)->md->pyname->text,
4136               ((sortedMethTab *)m2)->md->pyname->text);
4137 }
4138 
4139 
4140 /*
4141  * Generate the sorted table of static methods for a mapped type and return
4142  * the number of entries.
4143  */
generateMappedTypeMethodTable(sipSpec * pt,mappedTypeDef * mtd,FILE * fp)4144 static int generateMappedTypeMethodTable(sipSpec *pt, mappedTypeDef *mtd,
4145         FILE *fp)
4146 {
4147     int nr;
4148     sortedMethTab *mtab;
4149 
4150     mtab = createFunctionTable(mtd->members, &nr);
4151 
4152     if (mtab != NULL)
4153     {
4154         prMethodTable(pt, mtab, nr, mtd->iff, mtd->overs, fp);
4155         free(mtab);
4156     }
4157 
4158     return nr;
4159 }
4160 
4161 
4162 /*
4163  * Generate the sorted table of methods for a class and return the number of
4164  * entries.
4165  */
generateClassMethodTable(sipSpec * pt,classDef * cd,FILE * fp)4166 static int generateClassMethodTable(sipSpec *pt, classDef *cd, FILE *fp)
4167 {
4168     int nr;
4169     sortedMethTab *mtab;
4170 
4171     mtab = (cd->iff->type == namespace_iface) ?
4172             createFunctionTable(cd->members, &nr) :
4173             createMethodTable(cd, &nr);
4174 
4175     if (mtab != NULL)
4176     {
4177         prMethodTable(pt, mtab, nr, cd->iff, cd->overs, fp);
4178         free(mtab);
4179     }
4180 
4181     return nr;
4182 }
4183 
4184 
4185 /*
4186  * Generate a method table for a class or mapped type.
4187  */
prMethodTable(sipSpec * pt,sortedMethTab * mtable,int nr,ifaceFileDef * iff,overDef * overs,FILE * fp)4188 static void prMethodTable(sipSpec *pt, sortedMethTab *mtable, int nr,
4189         ifaceFileDef *iff, overDef *overs, FILE *fp)
4190 {
4191     int i;
4192 
4193     prcode(fp,
4194 "\n"
4195 "\n"
4196 "static PyMethodDef methods_%L[] = {\n"
4197         , iff);
4198 
4199     for (i = 0; i < nr; ++i)
4200     {
4201         memberDef *md = mtable[i].md;
4202         const char *cast, *cast_suffix, *flags;
4203 
4204         if (noArgParser(md) || useKeywordArgs(md))
4205         {
4206             cast = "SIP_MLMETH_CAST(";
4207             cast_suffix = ")";
4208             flags = "|METH_KEYWORDS";
4209         }
4210         else
4211         {
4212             cast = "";
4213             cast_suffix = "";
4214             flags = "";
4215         }
4216 
4217         /* Save the index in the table. */
4218         md->membernr = i;
4219 
4220         prcode(fp,
4221 "    {%N, %smeth_%L_%s%s, METH_VARARGS%s, ", md->pyname, cast, iff, md->pyname->text, cast_suffix, flags);
4222 
4223         if (hasMemberDocstring(pt, overs, md, iff))
4224             prcode(fp, "doc_%L_%s", iff, md->pyname->text);
4225         else
4226             prcode(fp, "SIP_NULLPTR");
4227 
4228         prcode(fp, "}%s\n"
4229             , ((i + 1) < nr) ? "," : "");
4230     }
4231 
4232     prcode(fp,
4233 "};\n"
4234         );
4235 }
4236 
4237 
4238 /*
4239  * Generate the "to type" convertor definitions.
4240  */
4241 
generateConvertToDefinitions(mappedTypeDef * mtd,classDef * cd,FILE * fp)4242 static void generateConvertToDefinitions(mappedTypeDef *mtd,classDef *cd,
4243                      FILE *fp)
4244 {
4245     codeBlockList *convtocode;
4246     ifaceFileDef *iff;
4247     argDef type;
4248 
4249     memset(&type, 0, sizeof (argDef));
4250 
4251     if (cd != NULL)
4252     {
4253         convtocode = cd->convtocode;
4254         iff = cd->iff;
4255 
4256         type.atype = class_type;
4257         type.u.cd = cd;
4258     }
4259     else
4260     {
4261         convtocode = mtd->convtocode;
4262         iff = mtd->iff;
4263 
4264         type.atype = mapped_type;
4265         type.u.mtd = mtd;
4266     }
4267 
4268     /* Generate the type convertors. */
4269 
4270     if (convtocode != NULL)
4271     {
4272         int need_py, need_ptr, need_iserr, need_xfer;
4273 
4274         /*
4275          * Sometimes type convertors are just stubs that set the error flag, so
4276          * check if we actually need everything so that we can avoid compiler
4277          * warnings.
4278          */
4279         need_py = (generating_c || usedInCode(convtocode, "sipPy"));
4280         need_ptr = (generating_c || usedInCode(convtocode, "sipCppPtr"));
4281         need_iserr = (generating_c || usedInCode(convtocode, "sipIsErr"));
4282         need_xfer = (generating_c || usedInCode(convtocode, "sipTransferObj"));
4283 
4284         prcode(fp,
4285 "\n"
4286 "\n"
4287             );
4288 
4289         if (!generating_c)
4290             prcode(fp,
4291 "extern \"C\" {static int convertTo_%L(PyObject *, void **, int *, PyObject *);}\n"
4292                 , iff);
4293 
4294         prcode(fp,
4295 "static int convertTo_%L(PyObject *%s,void **%s,int *%s,PyObject *%s)\n"
4296 "{\n"
4297             , iff, (need_py ? "sipPy" : ""), (need_ptr ? "sipCppPtrV" : ""), (need_iserr ? "sipIsErr" : ""), (need_xfer ? "sipTransferObj" : ""));
4298 
4299         if (need_ptr)
4300         {
4301             if (generating_c)
4302                 prcode(fp,
4303 "    %b **sipCppPtr = (%b **)sipCppPtrV;\n"
4304 "\n"
4305                     , &type, &type);
4306             else
4307                 prcode(fp,
4308 "    %b **sipCppPtr = reinterpret_cast<%b **>(sipCppPtrV);\n"
4309 "\n"
4310                     , &type, &type);
4311         }
4312 
4313         generateCppCodeBlock(convtocode,fp);
4314 
4315         prcode(fp,
4316 "}\n"
4317             );
4318     }
4319 }
4320 
4321 
4322 /*
4323  * Generate a variable getter.
4324  */
generateVariableGetter(ifaceFileDef * scope,varDef * vd,FILE * fp)4325 static void generateVariableGetter(ifaceFileDef *scope, varDef *vd, FILE *fp)
4326 {
4327     argType atype = vd->type.atype;
4328     const char *first_arg, *second_arg, *last_arg;
4329     int needsNew, var_key, self_key;
4330 
4331     if (generating_c || !isStaticVar(vd))
4332         first_arg = "sipSelf";
4333     else
4334         first_arg = "";
4335 
4336     last_arg = (generating_c || usedInCode(vd->getcode, "sipPyType")) ? "sipPyType" : "";
4337 
4338     needsNew = ((atype == class_type || atype == mapped_type) && vd->type.nrderefs == 0 && isConstArg(&vd->type));
4339 
4340     /*
4341      * If the variable is itself a non-const instance of a wrapped class then
4342      * two things must happen.  Firstly, the getter must return the same Python
4343      * object each time - it must not re-wrap the the instance.  This is
4344      * because the Python object can contain important state information that
4345      * must not be lost (specifically references to other Python objects that
4346      * it owns).  Therefore the Python object wrapping the containing class
4347      * must cache a reference to the Python object wrapping the variable.
4348      * Secondly, the Python object wrapping the containing class must not be
4349      * garbage collected before the Python object wrapping the variable is
4350      * (because the latter references memory, ie. the variable itself, that is
4351      * managed by the former).  Therefore the Python object wrapping the
4352      * variable must keep a reference to the Python object wrapping the
4353      * containing class (but only if the latter is non-static).
4354      */
4355     var_key = self_key = 0;
4356 
4357     if (atype == class_type && vd->type.nrderefs == 0 && !isConstArg(&vd->type))
4358     {
4359         var_key = vd->type.u.cd->iff->module->next_key--;
4360 
4361         if (!isStaticVar(vd))
4362             self_key = vd->module->next_key--;
4363     }
4364 
4365     second_arg = (generating_c || var_key < 0 ) ? "sipPySelf" : "";
4366 
4367     prcode(fp,
4368 "\n"
4369 "\n"
4370         );
4371 
4372     if (!generating_c)
4373         prcode(fp,
4374 "extern \"C\" {static PyObject *varget_%C(void *, PyObject *, PyObject *);}\n"
4375             , vd->fqcname);
4376 
4377     prcode(fp,
4378 "static PyObject *varget_%C(void *%s, PyObject *%s, PyObject *%s)\n"
4379 "{\n"
4380         , vd->fqcname, first_arg, second_arg, last_arg);
4381 
4382     if (vd->getcode != NULL)
4383     {
4384         prcode(fp,
4385 "    PyObject *sipPy;\n"
4386             );
4387     }
4388     else if (var_key < 0)
4389     {
4390         if (isStaticVar(vd))
4391             prcode(fp,
4392 "    static PyObject *sipPy = SIP_NULLPTR;\n"
4393                 );
4394         else
4395             prcode(fp,
4396 "    PyObject *sipPy;\n"
4397                 );
4398     }
4399 
4400     if (vd->getcode == NULL)
4401     {
4402         prcode(fp,
4403 "    ");
4404 
4405         generateNamedValueType(scope, &vd->type, "sipVal", fp);
4406 
4407         prcode(fp, ";\n"
4408             );
4409     }
4410 
4411     if (!isStaticVar(vd))
4412     {
4413         if (generating_c)
4414             prcode(fp,
4415 "    struct %S *sipCpp = (struct %S *)sipSelf;\n"
4416                 , classFQCName(vd->ecd), classFQCName(vd->ecd));
4417         else
4418             prcode(fp,
4419 "    %S *sipCpp = reinterpret_cast<%S *>(sipSelf);\n"
4420                 , classFQCName(vd->ecd), classFQCName(vd->ecd));
4421     }
4422 
4423     prcode(fp,
4424 "\n"
4425         );
4426 
4427     /* Handle any handwritten getter. */
4428     if (vd->getcode != NULL)
4429     {
4430         generateCppCodeBlock(vd->getcode, fp);
4431 
4432         prcode(fp,
4433 "\n"
4434 "    return sipPy;\n"
4435 "}\n"
4436             );
4437 
4438         return;
4439     }
4440 
4441     /* Get any previously wrapped cached object. */
4442     if (var_key < 0)
4443     {
4444         if (isStaticVar(vd))
4445             prcode(fp,
4446 "    if (sipPy)\n"
4447 "    {\n"
4448 "        Py_INCREF(sipPy);\n"
4449 "        return sipPy;\n"
4450 "    }\n"
4451 "\n"
4452                 );
4453         else
4454             prcode(fp,
4455 "    sipPy = sipGetReference(sipPySelf, %d);\n"
4456 "\n"
4457 "    if (sipPy)\n"
4458 "        return sipPy;\n"
4459 "\n"
4460                 , self_key);
4461     }
4462 
4463     if (needsNew)
4464     {
4465         if (generating_c)
4466             prcode(fp,
4467 "    *sipVal = ");
4468         else
4469             prcode(fp,
4470 "    sipVal = new %b(", &vd->type);
4471     }
4472     else
4473     {
4474         prcode(fp,
4475 "    sipVal = ");
4476 
4477         if ((atype == class_type || atype == mapped_type) && vd->type.nrderefs == 0)
4478             prcode(fp, "&");
4479     }
4480 
4481     generateVarMember(vd, fp);
4482 
4483     prcode(fp, "%s;\n"
4484 "\n"
4485         , ((needsNew && !generating_c) ? ")" : ""));
4486 
4487     switch (atype)
4488     {
4489     case mapped_type:
4490     case class_type:
4491         {
4492             ifaceFileDef *iff;
4493 
4494             if (atype == mapped_type)
4495                 iff = vd->type.u.mtd->iff;
4496             else
4497                 iff = vd->type.u.cd->iff;
4498 
4499             prcode(fp,
4500 "    %s sipConvertFrom%sType(", (var_key < 0 ? "sipPy =" : "return"), (needsNew ? "New" : ""));
4501 
4502             if (isConstArg(&vd->type))
4503                 prcode(fp, "const_cast<%b *>(sipVal)", &vd->type);
4504             else
4505                 prcode(fp, "sipVal");
4506 
4507             prcode(fp, ", sipType_%C, SIP_NULLPTR);\n"
4508                 , iff->fqcname);
4509 
4510             if (var_key < 0)
4511             {
4512                 prcode(fp,
4513 "\n"
4514 "    if (sipPy)\n"
4515 "    {\n"
4516 "        sipKeepReference(sipPy, %d, sipPySelf);\n"
4517                     , var_key);
4518 
4519                 if (isStaticVar(vd))
4520                     prcode(fp,
4521 "        Py_INCREF(sipPy);\n"
4522                         );
4523                 else
4524                     prcode(fp,
4525 "        sipKeepReference(sipPySelf, %d, sipPy);\n"
4526                         , self_key);
4527 
4528                 prcode(fp,
4529 "    }\n"
4530 "\n"
4531 "    return sipPy;\n"
4532                     );
4533             }
4534         }
4535 
4536         break;
4537 
4538     case bool_type:
4539     case cbool_type:
4540         prcode(fp,
4541 "    return PyBool_FromLong(sipVal);\n"
4542             );
4543 
4544         break;
4545 
4546     case ascii_string_type:
4547         if (vd->type.nrderefs == 0)
4548             prcode(fp,
4549 "    return PyUnicode_DecodeASCII(&sipVal, 1, SIP_NULLPTR);\n"
4550                 );
4551         else
4552             prcode(fp,
4553 "    if (sipVal == SIP_NULLPTR)\n"
4554 "    {\n"
4555 "        Py_INCREF(Py_None);\n"
4556 "        return Py_None;\n"
4557 "    }\n"
4558 "\n"
4559 "    return PyUnicode_DecodeASCII(sipVal, strlen(sipVal), SIP_NULLPTR);\n"
4560                 );
4561 
4562         break;
4563 
4564     case latin1_string_type:
4565         if (vd->type.nrderefs == 0)
4566             prcode(fp,
4567 "    return PyUnicode_DecodeLatin1(&sipVal, 1, SIP_NULLPTR);\n"
4568                 );
4569         else
4570             prcode(fp,
4571 "    if (sipVal == SIP_NULLPTR)\n"
4572 "    {\n"
4573 "        Py_INCREF(Py_None);\n"
4574 "        return Py_None;\n"
4575 "    }\n"
4576 "\n"
4577 "    return PyUnicode_DecodeLatin1(sipVal, strlen(sipVal), SIP_NULLPTR);\n"
4578                 );
4579 
4580         break;
4581 
4582     case utf8_string_type:
4583         if (vd->type.nrderefs == 0)
4584             prcode(fp,
4585 "    return PyUnicode_FromStringAndSize(&sipVal, 1);\n"
4586                 );
4587         else
4588             prcode(fp,
4589 "    if (sipVal == SIP_NULLPTR)\n"
4590 "    {\n"
4591 "        Py_INCREF(Py_None);\n"
4592 "        return Py_None;\n"
4593 "    }\n"
4594 "\n"
4595 "    return PyUnicode_FromString(sipVal);\n"
4596                 );
4597 
4598         break;
4599 
4600     case sstring_type:
4601     case ustring_type:
4602     case string_type:
4603         {
4604             const char *cast = ((atype != string_type) ? "(char *)" : "");
4605 
4606             if (vd->type.nrderefs == 0)
4607                 prcode(fp,
4608 "    return PyBytes_FromStringAndSize(%s&sipVal, 1);\n"
4609                     , cast);
4610             else
4611                 prcode(fp,
4612 "    if (sipVal == SIP_NULLPTR)\n"
4613 "    {\n"
4614 "        Py_INCREF(Py_None);\n"
4615 "        return Py_None;\n"
4616 "    }\n"
4617 "\n"
4618 "    return PyBytes_FromString(%ssipVal);\n"
4619                     , cast);
4620         }
4621 
4622         break;
4623 
4624     case wstring_type:
4625         if (vd->type.nrderefs == 0)
4626             prcode(fp,
4627 "    return PyUnicode_FromWideChar(&sipVal, 1);\n"
4628                 );
4629         else
4630             prcode(fp,
4631 "    if (sipVal == SIP_NULLPTR)\n"
4632 "    {\n"
4633 "        Py_INCREF(Py_None);\n"
4634 "        return Py_None;\n"
4635 "    }\n"
4636 "\n"
4637 "    return PyUnicode_FromWideChar(sipVal, (Py_ssize_t)wcslen(sipVal));\n"
4638                 );
4639 
4640         break;
4641 
4642     case float_type:
4643     case cfloat_type:
4644         prcode(fp,
4645 "    return PyFloat_FromDouble((double)sipVal);\n"
4646                 );
4647         break;
4648 
4649     case double_type:
4650     case cdouble_type:
4651         prcode(fp,
4652 "    return PyFloat_FromDouble(sipVal);\n"
4653             );
4654         break;
4655 
4656     case enum_type:
4657         if (vd->type.u.ed->fqcname != NULL)
4658         {
4659             const char *cast_prefix, *cast_suffix;
4660 
4661             if (generating_c)
4662             {
4663                 cast_prefix = cast_suffix = "";
4664             }
4665             else
4666             {
4667                 cast_prefix = "static_cast<int>(";
4668                 cast_suffix = ")";
4669             }
4670 
4671             prcode(fp,
4672 "    return sipConvertFromEnum(%ssipVal%s, sipType_%C);\n"
4673                 , cast_prefix, cast_suffix, vd->type.u.ed->fqcname);
4674 
4675             break;
4676         }
4677 
4678         /* Drop through. */
4679 
4680     case byte_type:
4681     case sbyte_type:
4682     case short_type:
4683     case cint_type:
4684     case int_type:
4685         prcode(fp,
4686 "    return PyLong_FromLong(sipVal);\n"
4687             );
4688         break;
4689 
4690     case long_type:
4691         prcode(fp,
4692 "    return PyLong_FromLong(sipVal);\n"
4693             );
4694         break;
4695 
4696     case ubyte_type:
4697     case ushort_type:
4698         prcode(fp,
4699 "    return PyLong_FromUnsignedLong(sipVal);\n"
4700             );
4701         break;
4702 
4703     case uint_type:
4704     case ulong_type:
4705     case size_type:
4706         prcode(fp,
4707 "    return PyLong_FromUnsignedLong(sipVal);\n"
4708             );
4709         break;
4710 
4711     case longlong_type:
4712         prcode(fp,
4713 "    return PyLong_FromLongLong(sipVal);\n"
4714             );
4715         break;
4716 
4717     case ulonglong_type:
4718         prcode(fp,
4719 "    return PyLong_FromUnsignedLongLong(sipVal);\n"
4720             );
4721         break;
4722 
4723     case struct_type:
4724     case void_type:
4725         prcode(fp,
4726 "    return sipConvertFrom%sVoidPtr(", (isConstArg(&vd->type) ? "Const" : ""));
4727         generateVoidPtrCast(&vd->type, fp);
4728         prcode(fp, "sipVal);\n");
4729         break;
4730 
4731     case capsule_type:
4732         prcode(fp,
4733 "    return PyCapsule_New(");
4734         generateVoidPtrCast(&vd->type, fp);
4735         prcode(fp, "sipVal, \"%S\", SIP_NULLPTR);\n"
4736             , vd->type.u.cap);
4737         break;
4738 
4739     case pyobject_type:
4740     case pytuple_type:
4741     case pylist_type:
4742     case pydict_type:
4743     case pycallable_type:
4744     case pyslice_type:
4745     case pytype_type:
4746     case pybuffer_type:
4747         prcode(fp,
4748 "    Py_XINCREF(sipVal);\n"
4749 "    return sipVal;\n"
4750             );
4751         break;
4752 
4753     /* Supress a compiler warning. */
4754     default:
4755         ;
4756     }
4757 
4758     prcode(fp,
4759 "}\n"
4760         );
4761 }
4762 
4763 
4764 /*
4765  * Generate a variable setter.
4766  */
generateVariableSetter(ifaceFileDef * scope,varDef * vd,FILE * fp)4767 static void generateVariableSetter(ifaceFileDef *scope, varDef *vd, FILE *fp)
4768 {
4769     argType atype = vd->type.atype;
4770     const char *first_arg, *last_arg, *error_test;
4771     char *deref;
4772     int might_be_temp, keep, need_py, need_cpp;
4773 
4774     /*
4775      * We need to keep a reference to the original Python object if it
4776      * providing the memory that the C/C++ variable is pointing to.
4777      */
4778     keep = keepPyReference(&vd->type);
4779 
4780     if (generating_c || !isStaticVar(vd))
4781         first_arg = "sipSelf";
4782     else
4783         first_arg = "";
4784 
4785     if (generating_c || (!isStaticVar(vd) && keep))
4786         last_arg = "sipPySelf";
4787     else
4788         last_arg = "";
4789 
4790     need_py = (generating_c || vd->setcode == NULL || usedInCode(vd->setcode, "sipPy"));
4791     need_cpp = (generating_c || vd->setcode == NULL || usedInCode(vd->setcode, "sipCpp"));
4792 
4793     prcode(fp,
4794 "\n"
4795 "\n"
4796         );
4797 
4798     if (!generating_c)
4799         prcode(fp,
4800 "extern \"C\" {static int varset_%C(void *, PyObject *, PyObject *);}\n"
4801             , vd->fqcname);
4802 
4803     prcode(fp,
4804 "static int varset_%C(void *%s, PyObject *%s, PyObject *%s)\n"
4805 "{\n"
4806         , vd->fqcname, (need_cpp ? first_arg : ""), (need_py ? "sipPy" : ""), last_arg);
4807 
4808     if (vd->setcode == NULL)
4809     {
4810         prcode(fp,
4811 "    ");
4812 
4813         if (atype == bool_type)
4814             prcode(fp, "int sipVal");
4815         else
4816             generateNamedValueType(scope, &vd->type, "sipVal", fp);
4817 
4818         prcode(fp, ";\n"
4819             );
4820     }
4821 
4822     if (!isStaticVar(vd) && need_cpp)
4823     {
4824         if (generating_c)
4825             prcode(fp,
4826 "    struct %S *sipCpp = (struct %S *)sipSelf;\n"
4827                 , classFQCName(vd->ecd), classFQCName(vd->ecd));
4828         else
4829             prcode(fp,
4830 "    %S *sipCpp = reinterpret_cast<%S *>(sipSelf);\n"
4831                 , classFQCName(vd->ecd), classFQCName(vd->ecd));
4832 
4833         prcode(fp,
4834 "\n"
4835             );
4836     }
4837 
4838     /* Handle any handwritten setter. */
4839     if (vd->setcode != NULL)
4840     {
4841         prcode(fp,
4842 "   int sipErr = 0;\n"
4843 "\n"
4844             );
4845 
4846         generateCppCodeBlock(vd->setcode, fp);
4847 
4848         prcode(fp,
4849 "\n"
4850 "    return (sipErr ? -1 : 0);\n"
4851 "}\n"
4852             );
4853 
4854         return;
4855     }
4856 
4857     if (vd->type.nrderefs == 0 && (atype == mapped_type || (atype == class_type && vd->type.u.cd->convtocode != NULL)))
4858         prcode(fp,
4859 "    int sipValState;\n"
4860             );
4861 
4862     if (atype == class_type || atype == mapped_type)
4863         prcode(fp,
4864 "    int sipIsErr = 0;\n"
4865 "\n"
4866             );
4867 
4868     might_be_temp = generateObjToCppConversion(&vd->type, fp);
4869 
4870     deref = "";
4871 
4872     if (atype == class_type || atype == mapped_type)
4873     {
4874         if (vd->type.nrderefs == 0)
4875             deref = "*";
4876 
4877         error_test = "sipIsErr";
4878     }
4879     else if (atype == bool_type)
4880     {
4881         error_test = "sipVal < 0";
4882     }
4883     else
4884     {
4885         error_test = "PyErr_Occurred() != SIP_NULLPTR";
4886     }
4887 
4888     prcode(fp,
4889 "\n"
4890 "    if (%s)\n"
4891 "        return -1;\n"
4892 "\n"
4893         , error_test);
4894 
4895     if (atype == pyobject_type || atype == pytuple_type ||
4896         atype == pylist_type || atype == pydict_type ||
4897         atype == pycallable_type || atype == pyslice_type ||
4898         atype == pytype_type || atype == pybuffer_type)
4899     {
4900         prcode(fp,
4901 "    Py_XDECREF(");
4902 
4903         generateVarMember(vd, fp);
4904 
4905         prcode(fp, ");\n"
4906 "    Py_INCREF(sipVal);\n"
4907 "\n"
4908             );
4909     }
4910 
4911     prcode(fp,
4912 "    ");
4913 
4914     generateVarMember(vd, fp);
4915 
4916     if (atype == bool_type)
4917     {
4918         if (generating_c)
4919             prcode(fp, " = (bool)%ssipVal;\n"
4920                 , deref);
4921         else
4922             prcode(fp, " = static_cast<bool>(%ssipVal);\n"
4923                 , deref);
4924     }
4925     else
4926     {
4927         prcode(fp, " = %ssipVal;\n"
4928             , deref);
4929     }
4930 
4931     /* Note that wchar_t * leaks here. */
4932 
4933     if (might_be_temp)
4934         prcode(fp,
4935 "\n"
4936 "    sipReleaseType(sipVal, sipType_%C, sipValState);\n"
4937             , classFQCName(vd->type.u.cd));
4938     else if (vd->type.atype == mapped_type && vd->type.nrderefs == 0 && !noRelease(vd->type.u.mtd))
4939         prcode(fp,
4940 "\n"
4941 "    sipReleaseType(sipVal, sipType_%T, sipValState);\n"
4942             , &vd->type);
4943 
4944     /* Generate the code to keep the object alive while we use its data. */
4945     if (keep)
4946     {
4947         if (isStaticVar(vd))
4948         {
4949             prcode(fp,
4950 "\n"
4951 "    static PyObject *sipKeep = SIP_NULLPTR;\n"
4952 "\n"
4953 "    Py_XDECREF(sipKeep);\n"
4954 "    sipKeep = sipPy;\n"
4955 "    Py_INCREF(sipKeep);\n"
4956                 );
4957         }
4958         else
4959         {
4960             prcode(fp,
4961 "\n"
4962 "    sipKeepReference(sipPySelf, %d, sipPy);\n"
4963                 , scope->module->next_key--);
4964         }
4965     }
4966 
4967     prcode(fp,
4968 "\n"
4969 "    return 0;\n"
4970 "}\n"
4971         );
4972 }
4973 
4974 
4975 /*
4976  * Generate the member variable of a class.
4977  */
generateVarMember(varDef * vd,FILE * fp)4978 static void generateVarMember(varDef *vd, FILE *fp)
4979 {
4980     if (isStaticVar(vd))
4981         prcode(fp, "%S::", classFQCName(vd->ecd));
4982     else
4983         prcode(fp, "sipCpp->");
4984 
4985     prcode(fp, "%s", scopedNameTail(vd->fqcname));
4986 }
4987 
4988 
4989 /*
4990  * Generate the declaration of a variable that is initialised from a Python
4991  * object.  Return TRUE if the value might be a temporary on the heap.
4992  */
generateObjToCppConversion(argDef * ad,FILE * fp)4993 static int generateObjToCppConversion(argDef *ad,FILE *fp)
4994 {
4995     int might_be_temp = FALSE;
4996     char *rhs = NULL;
4997 
4998     prcode(fp,
4999 "    sipVal = ");
5000 
5001     switch (ad->atype)
5002     {
5003     case mapped_type:
5004         {
5005             const char *tail;
5006 
5007             if (generating_c)
5008             {
5009                 prcode(fp, "(%b *)", ad);
5010                 tail = "";
5011             }
5012             else
5013             {
5014                 prcode(fp, "reinterpret_cast<%b *>(", ad);
5015                 tail = ")";
5016             }
5017 
5018             /* Note that we don't support /Transfer/ but could do. */
5019 
5020             prcode(fp, "sipForceConvertToType(sipPy, sipType_%T, SIP_NULLPTR, %s, %s, &sipIsErr)", ad, (ad->nrderefs ? "0" : "SIP_NOT_NONE"), (ad->nrderefs ? "SIP_NULLPTR" : "&sipValState"));
5021 
5022             prcode(fp, "%s;\n"
5023                 , tail);
5024         }
5025         break;
5026 
5027     case class_type:
5028         {
5029             const char *tail;
5030 
5031             if (ad->nrderefs == 0 && ad->u.cd->convtocode != NULL)
5032                 might_be_temp = TRUE;
5033 
5034             if (generating_c)
5035             {
5036                 prcode(fp, "(%b *)", ad);
5037                 tail = "";
5038             }
5039             else
5040             {
5041                 prcode(fp, "reinterpret_cast<%b *>(", ad);
5042                 tail = ")";
5043             }
5044 
5045             /*
5046              * Note that we don't support /Transfer/ but could do.  We could
5047              * also support /Constrained/ (so long as we also supported it for
5048              * all types).
5049              */
5050 
5051             prcode(fp, "sipForceConvertToType(sipPy, sipType_%C, SIP_NULLPTR, %s, %s, &sipIsErr)", classFQCName(ad->u.cd), (ad->nrderefs ? "0" : "SIP_NOT_NONE"), (might_be_temp ? "&sipValState" : "SIP_NULLPTR"));
5052 
5053             prcode(fp, "%s;\n"
5054                 , tail);
5055         }
5056         break;
5057 
5058     case enum_type:
5059         prcode(fp, "(%E)sipConvertToEnum(sipPy, sipType_%C);\n"
5060             , ad->u.ed, ad->u.ed->fqcname);
5061         break;
5062 
5063     case sstring_type:
5064         if (ad->nrderefs == 0)
5065             rhs = "(signed char)sipBytes_AsChar(sipPy)";
5066         else if (isConstArg(ad))
5067             rhs = "(const signed char *)sipBytes_AsString(sipPy)";
5068         else
5069             rhs = "(signed char *)sipBytes_AsString(sipPy)";
5070         break;
5071 
5072     case ustring_type:
5073         if (ad->nrderefs == 0)
5074             rhs = "(unsigned char)sipBytes_AsChar(sipPy)";
5075         else if (isConstArg(ad))
5076             rhs = "(const unsigned char *)sipBytes_AsString(sipPy)";
5077         else
5078             rhs = "(unsigned char *)sipBytes_AsString(sipPy)";
5079         break;
5080 
5081     case ascii_string_type:
5082         if (ad->nrderefs == 0)
5083             rhs = "sipString_AsASCIIChar(sipPy)";
5084         else if (isConstArg(ad))
5085             rhs = "sipString_AsASCIIString(&sipPy)";
5086         else
5087             rhs = "(char *)sipString_AsASCIIString(&sipPy)";
5088         break;
5089 
5090     case latin1_string_type:
5091         if (ad->nrderefs == 0)
5092             rhs = "sipString_AsLatin1Char(sipPy)";
5093         else if (isConstArg(ad))
5094             rhs = "sipString_AsLatin1String(&sipPy)";
5095         else
5096             rhs = "(char *)sipString_AsLatin1String(&sipPy)";
5097         break;
5098 
5099     case utf8_string_type:
5100         if (ad->nrderefs == 0)
5101             rhs = "sipString_AsUTF8Char(sipPy)";
5102         else if (isConstArg(ad))
5103             rhs = "sipString_AsUTF8String(&sipPy)";
5104         else
5105             rhs = "(char *)sipString_AsUTF8String(&sipPy)";
5106         break;
5107 
5108     case string_type:
5109         if (ad->nrderefs == 0)
5110             rhs = "sipBytes_AsChar(sipPy)";
5111         else if (isConstArg(ad))
5112             rhs = "sipBytes_AsString(sipPy)";
5113         else
5114             rhs = "(char *)sipBytes_AsString(sipPy)";
5115         break;
5116 
5117     case wstring_type:
5118         if (ad->nrderefs == 0)
5119             rhs = "sipUnicode_AsWChar(sipPy)";
5120         else
5121             rhs = "sipUnicode_AsWString(sipPy)";
5122         break;
5123 
5124     case float_type:
5125     case cfloat_type:
5126         rhs = "(float)PyFloat_AsDouble(sipPy)";
5127         break;
5128 
5129     case double_type:
5130     case cdouble_type:
5131         rhs = "PyFloat_AsDouble(sipPy)";
5132         break;
5133 
5134     case bool_type:
5135     case cbool_type:
5136         rhs = "sipConvertToBool(sipPy)";
5137         break;
5138 
5139     case byte_type:
5140         rhs = "sipLong_AsChar(sipPy)";
5141         break;
5142 
5143     case sbyte_type:
5144         rhs = "sipLong_AsSignedChar(sipPy)";
5145         break;
5146 
5147     case ubyte_type:
5148         rhs = "sipLong_AsUnsignedChar(sipPy)";
5149         break;
5150 
5151     case ushort_type:
5152         rhs = "sipLong_AsUnsignedShort(sipPy)";
5153         break;
5154 
5155     case short_type:
5156         rhs = "sipLong_AsShort(sipPy)";
5157         break;
5158 
5159     case uint_type:
5160         rhs = "sipLong_AsUnsignedInt(sipPy)";
5161         break;
5162 
5163     case size_type:
5164         rhs = "sipLong_AsSizeT(sipPy)";
5165         break;
5166 
5167     case int_type:
5168     case cint_type:
5169         rhs = "sipLong_AsInt(sipPy)";
5170         break;
5171 
5172     case ulong_type:
5173         rhs = "sipLong_AsUnsignedLong(sipPy)";
5174         break;
5175 
5176     case long_type:
5177         rhs = "sipLong_AsLong(sipPy)";
5178         break;
5179 
5180     case ulonglong_type:
5181         rhs = "sipLong_AsUnsignedLongLong(sipPy)";
5182         break;
5183 
5184     case longlong_type:
5185         rhs = "sipLong_AsLongLong(sipPy)";
5186         break;
5187 
5188     case struct_type:
5189         prcode(fp, "(struct %S *)sipConvertToVoidPtr(sipPy);\n"
5190             , ad->u.sname);
5191         break;
5192 
5193     case void_type:
5194         rhs = "sipConvertToVoidPtr(sipPy)";
5195         break;
5196 
5197     case capsule_type:
5198         prcode(fp, "PyCapsule_GetPointer(sipPy, \"%S\");\n"
5199             , ad->u.cap);
5200         break;
5201 
5202     case pyobject_type:
5203     case pytuple_type:
5204     case pylist_type:
5205     case pydict_type:
5206     case pycallable_type:
5207     case pyslice_type:
5208     case pytype_type:
5209     case pybuffer_type:
5210         rhs = "sipPy";
5211         break;
5212 
5213     /* Supress a compiler warning. */
5214     default:
5215         ;
5216     }
5217 
5218     if (rhs != NULL)
5219         prcode(fp, "%s;\n"
5220             , rhs);
5221 
5222     return might_be_temp;
5223 }
5224 
5225 
5226 /*
5227  * Returns TRUE if the given method is a slot that takes zero arguments.
5228  */
isZeroArgSlot(memberDef * md)5229 int isZeroArgSlot(memberDef *md)
5230 {
5231     slotType st = md->slot;
5232 
5233     return (st == str_slot || st == int_slot || st == float_slot ||
5234         st == invert_slot || st == neg_slot || st == len_slot ||
5235         st == bool_slot || st == pos_slot || st == abs_slot ||
5236         st == repr_slot || st == hash_slot || st == index_slot ||
5237         st == iter_slot || st == next_slot || st == await_slot ||
5238         st == aiter_slot || st == anext_slot);
5239 }
5240 
5241 
5242 /*
5243  * Returns TRUE if the given method is a slot that takes more than one
5244  * argument.
5245  */
isMultiArgSlot(memberDef * md)5246 static int isMultiArgSlot(memberDef *md)
5247 {
5248     slotType st = md->slot;
5249 
5250     return (st == setitem_slot || st == call_slot);
5251 }
5252 
5253 
5254 /*
5255  * Returns TRUE if the given method is a slot that returns void (ie. nothing
5256  * other than an error indicator).
5257  */
isVoidReturnSlot(memberDef * md)5258 int isVoidReturnSlot(memberDef *md)
5259 {
5260     slotType st = md->slot;
5261 
5262     return (st == setitem_slot || st == delitem_slot || st == setattr_slot);
5263 }
5264 
5265 
5266 /*
5267  * Returns TRUE if the given method is a slot that returns int.
5268  */
isIntReturnSlot(memberDef * md)5269 int isIntReturnSlot(memberDef *md)
5270 {
5271     slotType st = md->slot;
5272 
5273     return (st == bool_slot || st == contains_slot || st == cmp_slot);
5274 }
5275 
5276 
5277 /*
5278  * Returns TRUE if the given method is a slot that returns Py_ssize_t.
5279  */
isSSizeReturnSlot(memberDef * md)5280 int isSSizeReturnSlot(memberDef *md)
5281 {
5282     slotType st = md->slot;
5283 
5284     return (st == len_slot);
5285 }
5286 
5287 
5288 /*
5289  * Returns TRUE if the given method is a slot that returns long.
5290  */
isLongReturnSlot(memberDef * md)5291 int isLongReturnSlot(memberDef *md)
5292 {
5293     slotType st = md->slot;
5294 
5295     return (st == hash_slot);
5296 }
5297 
5298 
5299 /*
5300  * Returns TRUE if the given method is a slot that takes an int argument.
5301  */
isIntArgSlot(memberDef * md)5302 static int isIntArgSlot(memberDef *md)
5303 {
5304     slotType st = md->slot;
5305 
5306     return (st == repeat_slot || st == irepeat_slot);
5307 }
5308 
5309 
5310 /*
5311  * Returns TRUE if the given method is an inplace number slot.
5312  */
isInplaceNumberSlot(memberDef * md)5313 int isInplaceNumberSlot(memberDef *md)
5314 {
5315     slotType st = md->slot;
5316 
5317     return (st == iadd_slot || st == isub_slot || st == imul_slot ||
5318         st == imod_slot || st == ifloordiv_slot || st == itruediv_slot ||
5319         st == ior_slot || st == ixor_slot || st == iand_slot ||
5320         st == ilshift_slot || st == irshift_slot || st == imatmul_slot);
5321 }
5322 
5323 
5324 /*
5325  * Returns TRUE if the given method is an inplace sequence slot.
5326  */
isInplaceSequenceSlot(memberDef * md)5327 static int isInplaceSequenceSlot(memberDef *md)
5328 {
5329     slotType st = md->slot;
5330 
5331     return (st == iconcat_slot || st == irepeat_slot);
5332 }
5333 
5334 
5335 /*
5336  * Returns TRUE if the given method is a number slot.
5337  */
isNumberSlot(memberDef * md)5338 int isNumberSlot(memberDef *md)
5339 {
5340     slotType st = md->slot;
5341 
5342     return (st == add_slot || st == sub_slot || st == mul_slot ||
5343         st == mod_slot || st == floordiv_slot || st == truediv_slot ||
5344         st == and_slot || st == or_slot || st == xor_slot ||
5345         st == lshift_slot || st == rshift_slot || st == matmul_slot);
5346 }
5347 
5348 
5349 /*
5350  * Returns TRUE if the given method is a rich compare slot.
5351  */
isRichCompareSlot(memberDef * md)5352 int isRichCompareSlot(memberDef *md)
5353 {
5354     slotType st = md->slot;
5355 
5356     return (st == lt_slot || st == le_slot || st == eq_slot ||
5357         st == ne_slot || st == gt_slot || st == ge_slot);
5358 }
5359 
5360 
5361 /*
5362  * Generate a Python slot handler for either a class, an enum or an extender.
5363  */
generateSlot(moduleDef * mod,classDef * cd,enumDef * ed,memberDef * md,FILE * fp)5364 static void generateSlot(moduleDef *mod, classDef *cd, enumDef *ed,
5365         memberDef *md, FILE *fp)
5366 {
5367     char *arg_str, *decl_arg_str, *prefix, *ret_type, *ret_value;
5368     int has_args;
5369     overDef *od, *overs;
5370     scopedNameDef *fqcname;
5371     nameDef *pyname;
5372 
5373     if (ed != NULL)
5374     {
5375         prefix = "Type";
5376         pyname = ed->pyname;
5377         fqcname = ed->fqcname;
5378         overs = ed->overs;
5379     }
5380     else if (cd != NULL)
5381     {
5382         prefix = "Type";
5383         pyname = cd->pyname;
5384         fqcname = classFQCName(cd);
5385         overs = cd->overs;
5386     }
5387     else
5388     {
5389         prefix = NULL;
5390         pyname = NULL;
5391         fqcname = NULL;
5392         overs = mod->overs;
5393     }
5394 
5395     if (isVoidReturnSlot(md) || isIntReturnSlot(md))
5396     {
5397         ret_type = "int ";
5398         ret_value = "-1";
5399     }
5400     else if (isSSizeReturnSlot(md))
5401     {
5402         ret_type = "Py_ssize_t ";
5403         ret_value = "0";
5404     }
5405     else if (isLongReturnSlot(md))
5406     {
5407         ret_type = "long ";
5408         ret_value = "0L";
5409     }
5410     else
5411     {
5412         ret_type = "PyObject *";
5413         ret_value = "SIP_NULLPTR";
5414     }
5415 
5416     has_args = TRUE;
5417 
5418     if (isIntArgSlot(md))
5419     {
5420         has_args = FALSE;
5421         arg_str = "PyObject *sipSelf,int a0";
5422         decl_arg_str = "PyObject *,int";
5423     }
5424     else if (md->slot == call_slot)
5425     {
5426         if (generating_c || useKeywordArgs(md) || noArgParser(md))
5427             arg_str = "PyObject *sipSelf,PyObject *sipArgs,PyObject *sipKwds";
5428         else
5429             arg_str = "PyObject *sipSelf,PyObject *sipArgs,PyObject *";
5430 
5431         decl_arg_str = "PyObject *,PyObject *,PyObject *";
5432     }
5433     else if (isMultiArgSlot(md))
5434     {
5435         arg_str = "PyObject *sipSelf,PyObject *sipArgs";
5436         decl_arg_str = "PyObject *,PyObject *";
5437     }
5438     else if (isZeroArgSlot(md))
5439     {
5440         has_args = FALSE;
5441         arg_str = "PyObject *sipSelf";
5442         decl_arg_str = "PyObject *";
5443     }
5444     else if (isNumberSlot(md))
5445     {
5446         arg_str = "PyObject *sipArg0,PyObject *sipArg1";
5447         decl_arg_str = "PyObject *,PyObject *";
5448     }
5449     else if (md->slot == setattr_slot)
5450     {
5451         arg_str = "PyObject *sipSelf,PyObject *sipName,PyObject *sipValue";
5452         decl_arg_str = "PyObject *,PyObject *,PyObject *";
5453     }
5454     else
5455     {
5456         arg_str = "PyObject *sipSelf,PyObject *sipArg";
5457         decl_arg_str = "PyObject *,PyObject *";
5458     }
5459 
5460     prcode(fp,
5461 "\n"
5462 "\n"
5463         );
5464 
5465     if (!generating_c)
5466     {
5467         prcode(fp,
5468 "extern \"C\" {static %sslot_", ret_type);
5469 
5470         if (cd != NULL)
5471             prcode(fp, "%L_", cd->iff);
5472         else if (fqcname != NULL)
5473             prcode(fp, "%C_", fqcname);
5474 
5475         prcode(fp, "%s(%s);}\n"
5476             , md->pyname->text, decl_arg_str);
5477     }
5478 
5479     prcode(fp,
5480 "static %sslot_", ret_type);
5481 
5482     if (cd != NULL)
5483         prcode(fp, "%L_", cd->iff);
5484     else if (fqcname != NULL)
5485         prcode(fp, "%C_", fqcname);
5486 
5487     prcode(fp, "%s(%s)\n"
5488 "{\n"
5489         , md->pyname->text, arg_str);
5490 
5491     if (md->slot == call_slot && noArgParser(md))
5492     {
5493         for (od = overs; od != NULL; od = od->next)
5494             if (od->common == md)
5495                 generateCppCodeBlock(od->methodcode, fp);
5496     }
5497     else
5498     {
5499         if (isInplaceNumberSlot(md))
5500             prcode(fp,
5501 "    if (!PyObject_TypeCheck(sipSelf, sipTypeAsPyTypeObject(sip%s_%C)))\n"
5502 "    {\n"
5503 "        Py_INCREF(Py_NotImplemented);\n"
5504 "        return Py_NotImplemented;\n"
5505 "    }\n"
5506 "\n"
5507                 , prefix, fqcname);
5508 
5509         if (!isNumberSlot(md))
5510         {
5511             if (cd != NULL)
5512                 prcode(fp,
5513 "    %S *sipCpp = reinterpret_cast<%S *>(sipGetCppPtr((sipSimpleWrapper *)sipSelf,sipType_%C));\n"
5514 "\n"
5515 "    if (!sipCpp)\n"
5516                     , fqcname, fqcname, fqcname);
5517             else
5518                 prcode(fp,
5519 "    %S sipCpp = static_cast<%S>(sipConvertToEnum(sipSelf, sipType_%C));\n"
5520 "\n"
5521 "    if (PyErr_Occurred())\n"
5522                     , fqcname, fqcname, fqcname);
5523 
5524             prcode(fp,
5525 "        return %s;\n"
5526 "\n"
5527                 , (md->slot == cmp_slot ? "-2" : ret_value));
5528         }
5529 
5530         if (has_args)
5531             prcode(fp,
5532 "    PyObject *sipParseErr = SIP_NULLPTR;\n"
5533                 );
5534 
5535         for (od = overs; od != NULL; od = od->next)
5536             if (od->common == md && isAbstract(od))
5537             {
5538                 prcode(fp,
5539 "    PyObject *sipOrigSelf = sipSelf;\n"
5540                     );
5541 
5542                 break;
5543             }
5544 
5545         for (od = overs; od != NULL; od = od->next)
5546             if (od->common == md)
5547                 generateFunctionBody(od, cd, NULL, cd, (ed == NULL && !dontDerefSelf(od)), mod, fp);
5548 
5549         if (has_args)
5550         {
5551             switch (md->slot)
5552             {
5553             case cmp_slot:
5554                 prcode(fp,
5555 "\n"
5556 "    return 2;\n"
5557                     );
5558                 break;
5559 
5560             case concat_slot:
5561             case iconcat_slot:
5562             case repeat_slot:
5563             case irepeat_slot:
5564                 prcode(fp,
5565 "\n"
5566 "    /* Raise an exception if the argument couldn't be parsed. */\n"
5567 "    sipBadOperatorArg(sipSelf,sipArg,%s);\n"
5568 "\n"
5569 "    return SIP_NULLPTR;\n"
5570                     ,slotName(md->slot));
5571                 break;
5572 
5573             default:
5574                 if (isNumberSlot(md) || isRichCompareSlot(md) || isInplaceNumberSlot(md))
5575                 {
5576                     prcode(fp,
5577 "\n"
5578 "    Py_XDECREF(sipParseErr);\n"
5579 "\n"
5580 "    if (sipParseErr == Py_None)\n"
5581 "        return SIP_NULLPTR;\n"
5582                         );
5583                 }
5584 
5585                 if (isNumberSlot(md) || isRichCompareSlot(md))
5586                 {
5587                     /* We can't extend enum slots. */
5588                     if (cd == NULL)
5589                         prcode(fp,
5590 "\n"
5591 "    Py_INCREF(Py_NotImplemented);\n"
5592 "    return Py_NotImplemented;\n"
5593                             );
5594                     else if (isNumberSlot(md))
5595                         prcode(fp,
5596 "\n"
5597 "    return sipPySlotExtend(&sipModuleAPI_%s, %s, SIP_NULLPTR, sipArg0, sipArg1);\n"
5598                             , mod->name, slotName(md->slot));
5599                     else
5600                         prcode(fp,
5601 "\n"
5602 "    return sipPySlotExtend(&sipModuleAPI_%s, %s, sipType_%C, sipSelf, sipArg);\n"
5603                             , mod->name, slotName(md->slot), fqcname);
5604                 }
5605                 else if (isInplaceNumberSlot(md))
5606                 {
5607                     prcode(fp,
5608 "\n"
5609 "    PyErr_Clear();\n"
5610 "\n"
5611 "    Py_INCREF(Py_NotImplemented);\n"
5612 "    return Py_NotImplemented;\n"
5613                         );
5614                 }
5615                 else
5616                 {
5617                     prcode(fp,
5618 "\n"
5619 "    sipNoMethod(sipParseErr, %N, ", pyname);
5620 
5621                     if (md->slot == setattr_slot)
5622                         prcode(fp, "(sipValue != SIP_NULLPTR ? sipName___setattr__ : sipName___delattr__)");
5623                     else
5624                         prcode(fp, "%N", md->pyname);
5625 
5626                     prcode(fp, ", SIP_NULLPTR);\n"
5627 "\n"
5628 "    return %s;\n"
5629                         , ret_value);
5630                 }
5631             }
5632         }
5633         else
5634         {
5635             prcode(fp,
5636 "\n"
5637 "    return 0;\n"
5638                 );
5639         }
5640     }
5641 
5642     prcode(fp,
5643 "}\n"
5644         );
5645 }
5646 
5647 
5648 /*
5649  * Generate the member functions for a class.
5650  */
generateClassFunctions(sipSpec * pt,moduleDef * mod,classDef * cd,int py_debug,FILE * fp)5651 static void generateClassFunctions(sipSpec *pt, moduleDef *mod, classDef *cd,
5652         int py_debug, FILE *fp)
5653 {
5654     visibleList *vl;
5655     memberDef *md;
5656 
5657     /* Any shadow code. */
5658     if (hasShadow(cd))
5659     {
5660         if (!isExportDerived(cd))
5661             generateShadowClassDeclaration(pt, cd, fp);
5662 
5663         generateShadowCode(pt, mod, cd, fp);
5664     }
5665 
5666     /* The member functions. */
5667     for (vl = cd->visible; vl != NULL; vl = vl->next)
5668         if (vl->m->slot == no_slot)
5669             generateFunction(pt, vl->m, vl->cd->overs, cd, vl->cd, mod, fp);
5670 
5671     /* The slot functions. */
5672     for (md = cd->members; md != NULL; md = md->next)
5673         if (cd->iff->type == namespace_iface)
5674             generateOrdinaryFunction(pt, mod, cd, NULL, md, fp);
5675         else if (md->slot != no_slot)
5676             generateSlot(mod, cd, NULL, md, fp);
5677 
5678     /*
5679      * The cast function.  Note that we used to try and work out if the cast
5680      * function was really needed (eg. only for multiple inheritance) but there
5681      * are subtle cases where, even for single inheritance, it is needed.  We
5682      * take the conservative approach and generate it for all derived classes.
5683      */
5684     if (cd->supers != NULL)
5685     {
5686         mroDef *mro;
5687 
5688         prcode(fp,
5689 "\n"
5690 "\n"
5691 "/* Cast a pointer to a type somewhere in its inheritance hierarchy. */\n"
5692 "extern \"C\" {static void *cast_%L(void *, const sipTypeDef *);}\n"
5693 "static void *cast_%L(void *sipCppV, const sipTypeDef *targetType)\n"
5694 "{\n"
5695 "    "
5696             , cd->iff
5697             , cd->iff);
5698 
5699         generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
5700 
5701         prcode(fp, ";\n"
5702 "\n"
5703             );
5704 
5705         /* Skip the the class itself. */
5706         for (mro = cd->mro->next; mro != NULL; mro = mro->next)
5707         {
5708             /*
5709              * If the class appears more than once in the hierarchy then we
5710              * choose to ignore it (rather than pick a copy to use).  Note that
5711              * we should support the concept of virtual inheritance if it used
5712              * to ensure there is only one copy of the class in the hierarchy.
5713              */
5714             if (inADiamond(mro))
5715                 continue;
5716 
5717             prcode(fp,
5718 "    if (targetType == sipType_%C)\n"
5719 "        return static_cast<%U *>(sipCpp);\n"
5720 "\n"
5721                 , classFQCName(mro->cd)
5722                 , mro->cd);
5723         }
5724 
5725         prcode(fp,
5726 "    return sipCppV;\n"
5727 "}\n"
5728             );
5729     }
5730 
5731     if (cd->iff->type != namespace_iface && !generating_c)
5732     {
5733         int need_ptr = FALSE, need_cast_ptr = FALSE, need_state = FALSE;
5734 
5735         /* Generate the release function without compiler warnings. */
5736 
5737         if (cd->dealloccode != NULL)
5738             need_ptr = need_cast_ptr = usedInCode(cd->dealloccode, "sipCpp");
5739 
5740         if (canCreate(cd) || isPublicDtor(cd))
5741         {
5742             if (pluginPyQt5(pt) && isQObjectSubClass(cd) && isPublicDtor(cd))
5743                 need_ptr = need_cast_ptr = TRUE;
5744             else if (hasShadow(cd))
5745                 need_ptr = need_state = TRUE;
5746             else if (isPublicDtor(cd))
5747                 need_ptr = TRUE;
5748         }
5749 
5750         prcode(fp,
5751 "\n"
5752 "\n"
5753 "/* Call the instance's destructor. */\n"
5754             );
5755 
5756         if (!generating_c)
5757             prcode(fp,
5758 "extern \"C\" {static void release_%L(void *, int);}\n"
5759                 , cd->iff);
5760 
5761         prcode(fp,
5762 "static void release_%L(void *%s, int%s)\n"
5763 "{\n"
5764             , cd->iff, (need_ptr ? "sipCppV" : ""), (need_state ? " sipState" : ""));
5765 
5766         if (need_cast_ptr)
5767         {
5768             prcode(fp,
5769 "    ");
5770 
5771             generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
5772 
5773             prcode(fp, ";\n"
5774 "\n"
5775                 );
5776         }
5777 
5778         if (cd->dealloccode != NULL)
5779         {
5780             generateCppCodeBlock(cd->dealloccode, fp);
5781 
5782             prcode(fp,
5783 "\n"
5784                 );
5785         }
5786 
5787         if (canCreate(cd) || isPublicDtor(cd))
5788         {
5789             int rgil = ((release_gil || isReleaseGILDtor(cd)) && !isHoldGILDtor(cd));
5790 
5791             /*
5792              * If there is an explicit public dtor then assume there is some
5793              * way to call it which we haven't worked out (because we don't
5794              * fully understand C++).
5795              */
5796 
5797             if (rgil)
5798                 prcode(fp,
5799 "    Py_BEGIN_ALLOW_THREADS\n"
5800 "\n"
5801                     );
5802 
5803             if (pluginPyQt5(pt) && isQObjectSubClass(cd) && isPublicDtor(cd))
5804             {
5805                 /*
5806                  * QObjects should only be deleted in the threads that they
5807                  * belong to.
5808                  */
5809                 prcode(fp,
5810 "    if (QThread::currentThread() == sipCpp->thread())\n"
5811 "        delete sipCpp;\n"
5812 "    else\n"
5813 "        sipCpp->deleteLater();\n"
5814                         );
5815             }
5816             else if (hasShadow(cd))
5817             {
5818                 prcode(fp,
5819 "    if (sipState & SIP_DERIVED_CLASS)\n"
5820 "        delete reinterpret_cast<sip%C *>(sipCppV);\n"
5821                     , classFQCName(cd));
5822 
5823                 if (isPublicDtor(cd))
5824                     prcode(fp,
5825 "    else\n"
5826 "        delete reinterpret_cast<%U *>(sipCppV);\n"
5827                         , cd);
5828             }
5829             else if (isPublicDtor(cd))
5830                 prcode(fp,
5831 "    delete reinterpret_cast<%U *>(sipCppV);\n"
5832                     , cd);
5833 
5834             if (rgil)
5835                 prcode(fp,
5836 "\n"
5837 "    Py_END_ALLOW_THREADS\n"
5838                     );
5839         }
5840 
5841         prcode(fp,
5842 "}\n"
5843             );
5844     }
5845 
5846     /* The traverse function. */
5847     if (cd->travcode != NULL)
5848     {
5849         prcode(fp,
5850 "\n"
5851 "\n"
5852             );
5853 
5854         if (!generating_c)
5855             prcode(fp,
5856 "extern \"C\" {static int traverse_%C(void *, visitproc, void *);}\n"
5857                 , classFQCName(cd));
5858 
5859         prcode(fp,
5860 "static int traverse_%C(void *sipCppV,visitproc sipVisit,void *sipArg)\n"
5861 "{\n"
5862 "    ", classFQCName(cd));
5863 
5864         generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
5865 
5866         prcode(fp, ";\n"
5867 "    int sipRes;\n"
5868 "\n"
5869             );
5870 
5871         generateCppCodeBlock(cd->travcode, fp);
5872 
5873         prcode(fp,
5874 "\n"
5875 "    return sipRes;\n"
5876 "}\n"
5877             );
5878     }
5879 
5880     /* The clear function. */
5881     if (cd->clearcode != NULL)
5882     {
5883         prcode(fp,
5884 "\n"
5885 "\n"
5886             );
5887 
5888         if (!generating_c)
5889             prcode(fp,
5890 "extern \"C\" {static int clear_%C(void *);}\n"
5891                 , classFQCName(cd));
5892 
5893         prcode(fp,
5894 "static int clear_%C(void *sipCppV)\n"
5895 "{\n"
5896 "    ", classFQCName(cd));
5897 
5898         generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
5899 
5900         prcode(fp, ";\n"
5901 "    int sipRes;\n"
5902 "\n"
5903             );
5904 
5905         generateCppCodeBlock(cd->clearcode, fp);
5906 
5907         prcode(fp,
5908 "\n"
5909 "    return sipRes;\n"
5910 "}\n"
5911             );
5912     }
5913 
5914     /* The buffer interface functions. */
5915     if (cd->getbufcode != NULL)
5916     {
5917         int need_cpp = usedInCode(cd->getbufcode, "sipCpp");
5918 
5919         prcode(fp,
5920 "\n"
5921 "\n"
5922             );
5923 
5924         if (!py_debug && useLimitedAPI(mod))
5925         {
5926             if (!generating_c)
5927                 prcode(fp,
5928 "extern \"C\" {static int getbuffer_%C(PyObject *, void *, sipBufferDef *);}\n"
5929                     , classFQCName(cd));
5930 
5931             prcode(fp,
5932 "static int getbuffer_%C(PyObject *%s, void *%s, sipBufferDef *sipBuffer)\n"
5933                 , classFQCName(cd), argName("sipSelf", cd->getbufcode), (generating_c || need_cpp ? "sipCppV" : ""));
5934         }
5935         else
5936         {
5937             if (!generating_c)
5938                 prcode(fp,
5939 "extern \"C\" {static int getbuffer_%C(PyObject *, void *, Py_buffer *, int);}\n"
5940                     , classFQCName(cd));
5941 
5942             prcode(fp,
5943 "static int getbuffer_%C(PyObject *%s, void *%s, Py_buffer *sipBuffer, int %s)\n"
5944                 , classFQCName(cd), argName("sipSelf", cd->getbufcode), (generating_c || need_cpp ? "sipCppV" : ""), argName("sipFlags", cd->getbufcode));
5945         }
5946 
5947         prcode(fp,
5948 "{\n"
5949             );
5950 
5951         if (need_cpp)
5952         {
5953             prcode(fp, "    ");
5954             generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
5955             prcode(fp, ";\n"
5956                 );
5957         }
5958 
5959         prcode(fp,
5960 "    int sipRes;\n"
5961 "\n"
5962             );
5963 
5964         generateCppCodeBlock(cd->getbufcode, fp);
5965 
5966         prcode(fp,
5967 "\n"
5968 "    return sipRes;\n"
5969 "}\n"
5970             );
5971     }
5972 
5973     if (cd->releasebufcode != NULL)
5974     {
5975         int need_cpp = usedInCode(cd->releasebufcode, "sipCpp");
5976 
5977         prcode(fp,
5978 "\n"
5979 "\n"
5980             );
5981 
5982         if (!py_debug && useLimitedAPI(mod))
5983         {
5984             if (!generating_c)
5985                 prcode(fp,
5986 "extern \"C\" {static void releasebuffer_%C(PyObject *, void *);}\n"
5987                     , classFQCName(cd));
5988 
5989             prcode(fp,
5990 "static void releasebuffer_%C(PyObject *%s, void *%s)\n"
5991 "#else\n"
5992                 , classFQCName(cd), argName("sipSelf", cd->releasebufcode), (generating_c || need_cpp ? "sipCppV" : ""));
5993         }
5994         else
5995         {
5996             if (!generating_c)
5997                 prcode(fp,
5998 "extern \"C\" {static void releasebuffer_%C(PyObject *, void *, Py_buffer *);}\n"
5999                     , classFQCName(cd));
6000 
6001             prcode(fp,
6002 "static void releasebuffer_%C(PyObject *%s, void *%s, Py_buffer *%s)\n"
6003                 , classFQCName(cd), argName("sipSelf", cd->releasebufcode), (generating_c || need_cpp ? "sipCppV" : ""), argName("sipBuffer", cd->releasebufcode));
6004         }
6005 
6006         prcode(fp,
6007 "{\n"
6008             );
6009 
6010         if (need_cpp)
6011         {
6012             prcode(fp, "    ");
6013             generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
6014             prcode(fp, ";\n"
6015                 );
6016         }
6017 
6018         generateCppCodeBlock(cd->releasebufcode, fp);
6019 
6020         prcode(fp,
6021 "}\n"
6022             );
6023     }
6024 
6025     /* The pickle function. */
6026     if (cd->picklecode != NULL)
6027     {
6028         prcode(fp,
6029 "\n"
6030 "\n"
6031             );
6032 
6033         if (!generating_c)
6034             prcode(fp,
6035 "extern \"C\" {static PyObject *pickle_%C(void *);}\n"
6036                 , classFQCName(cd));
6037 
6038         prcode(fp,
6039 "static PyObject *pickle_%C(void *sipCppV)\n"
6040 "{\n"
6041 "    ", classFQCName(cd));
6042 
6043         generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
6044 
6045         prcode(fp, ";\n"
6046 "    PyObject *sipRes;\n"
6047 "\n"
6048             );
6049 
6050         generateCppCodeBlock(cd->picklecode, fp);
6051 
6052         prcode(fp,
6053 "\n"
6054 "    return sipRes;\n"
6055 "}\n"
6056             );
6057     }
6058 
6059     /* The finalisation function. */
6060     if (cd->finalcode != NULL)
6061     {
6062         int need_cpp = usedInCode(cd->finalcode, "sipCpp");
6063 
6064         prcode(fp,
6065 "\n"
6066 "\n"
6067             );
6068 
6069         if (!generating_c)
6070             prcode(fp,
6071 "extern \"C\" {static int final_%C(PyObject *, void *, PyObject *, PyObject **);}\n"
6072                 , classFQCName(cd));
6073 
6074         prcode(fp,
6075 "static int final_%C(PyObject *%s, void *%s, PyObject *%s, PyObject **%s)\n"
6076 "{\n"
6077             , classFQCName(cd), (usedInCode(cd->finalcode, "sipSelf") ? "sipSelf" : ""), (need_cpp ? "sipCppV" : ""), (usedInCode(cd->finalcode, "sipKwds") ? "sipKwds" : ""), (usedInCode(cd->finalcode, "sipUnused") ? "sipUnused" : ""));
6078 
6079         if (need_cpp)
6080         {
6081             prcode(fp,
6082 "    ");
6083             generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
6084             prcode(fp, ";\n"
6085 "\n"
6086                 );
6087         }
6088 
6089         generateCppCodeBlock(cd->finalcode, fp);
6090 
6091         prcode(fp,
6092 "}\n"
6093             );
6094     }
6095 
6096     /* The mixin initialisation function. */
6097     if (isMixin(cd))
6098     {
6099         prcode(fp,
6100 "\n"
6101 "\n"
6102             );
6103 
6104         if (!generating_c)
6105             prcode(fp,
6106 "extern \"C\" {static int mixin_%C(PyObject *, PyObject *, PyObject *);}\n"
6107                 , classFQCName(cd));
6108 
6109         prcode(fp,
6110 "static int mixin_%C(PyObject *sipSelf, PyObject *sipArgs, PyObject *sipKwds)\n"
6111 "{\n"
6112 "    return sipInitMixin(sipSelf, sipArgs, sipKwds, (sipClassTypeDef *)&"
6113             , classFQCName(cd));
6114 
6115         generateTypeDefName(cd->iff, fp);
6116 
6117         prcode(fp, ");\n"
6118 "}\n"
6119             );
6120     }
6121 
6122     /* The array allocation helper. */
6123     if (generating_c || arrayHelper(cd))
6124     {
6125         prcode(fp,
6126 "\n"
6127 "\n"
6128             );
6129 
6130         if (!generating_c)
6131             prcode(fp,
6132 "extern \"C\" {static void *array_%L(Py_ssize_t);}\n"
6133                 , cd->iff);
6134 
6135         prcode(fp,
6136 "static void *array_%L(Py_ssize_t sipNrElem)\n"
6137 "{\n"
6138             , cd->iff);
6139 
6140         if (generating_c)
6141             prcode(fp,
6142 "    return sipMalloc(sizeof (struct %U) * sipNrElem);\n"
6143                 , cd);
6144         else
6145             prcode(fp,
6146 "    return new %U[sipNrElem];\n"
6147                 , cd);
6148 
6149         prcode(fp,
6150 "}\n"
6151             );
6152     }
6153 
6154     /* The copy and assignment helpers. */
6155     if (generating_c || copyHelper(cd))
6156     {
6157         /*
6158          * The assignment helper.  We assume that there will be a valid
6159          * assigment operator if there is a a copy ctor.  Note that the source
6160          * pointer is not const.  This is to allow the source instance to be
6161          * modified as a consequence of the assignment, eg. if it is
6162          * implementing some sort of reference counting scheme.
6163          */
6164         prcode(fp,
6165 "\n"
6166 "\n"
6167             );
6168 
6169         if (!generating_c)
6170             prcode(fp,
6171 "extern \"C\" {static void assign_%L(void *, Py_ssize_t, void *);}\n"
6172                 , cd->iff);
6173 
6174         prcode(fp,
6175 "static void assign_%L(void *sipDst, Py_ssize_t sipDstIdx, void *sipSrc)\n"
6176 "{\n"
6177             , cd->iff);
6178 
6179         if (generating_c)
6180             prcode(fp,
6181 "    ((struct %U *)sipDst)[sipDstIdx] = *((struct %U *)sipSrc);\n"
6182                 , cd, cd);
6183         else
6184             prcode(fp,
6185 "    reinterpret_cast<%U *>(sipDst)[sipDstIdx] = *reinterpret_cast<%U *>(sipSrc);\n"
6186                 , cd, cd);
6187 
6188         prcode(fp,
6189 "}\n"
6190             );
6191 
6192         /* The copy helper. */
6193         prcode(fp,
6194 "\n"
6195 "\n"
6196             );
6197 
6198         if (!generating_c)
6199             prcode(fp,
6200 "extern \"C\" {static void *copy_%L(const void *, Py_ssize_t);}\n"
6201                 , cd->iff);
6202 
6203         prcode(fp,
6204 "static void *copy_%L(const void *sipSrc, Py_ssize_t sipSrcIdx)\n"
6205 "{\n"
6206             , cd->iff);
6207 
6208         if (generating_c)
6209             prcode(fp,
6210 "    struct %U *sipPtr = sipMalloc(sizeof (struct %U));\n"
6211 "    *sipPtr = ((const struct %U *)sipSrc)[sipSrcIdx];\n"
6212 "\n"
6213 "    return sipPtr;\n"
6214                 , cd, cd
6215                 , cd);
6216         else
6217             prcode(fp,
6218 "    return new %U(reinterpret_cast<const %U *>(sipSrc)[sipSrcIdx]);\n"
6219                 , cd, cd);
6220 
6221         prcode(fp,
6222 "}\n"
6223             );
6224     }
6225 
6226     /* The dealloc function. */
6227     if (needDealloc(cd))
6228     {
6229         prcode(fp,
6230 "\n"
6231 "\n"
6232             );
6233 
6234         if (!generating_c)
6235             prcode(fp,
6236 "extern \"C\" {static void dealloc_%L(sipSimpleWrapper *);}\n"
6237                 , cd->iff);
6238 
6239         prcode(fp,
6240 "static void dealloc_%L(sipSimpleWrapper *sipSelf)\n"
6241 "{\n"
6242             , cd->iff);
6243 
6244         if (tracing)
6245             prcode(fp,
6246 "    sipTrace(SIP_TRACE_DEALLOCS,\"dealloc_%L()\\n\");\n"
6247 "\n"
6248                 , cd->iff);
6249 
6250         /* Disable the virtual handlers. */
6251         if (hasShadow(cd))
6252             prcode(fp,
6253 "    if (sipIsDerivedClass(sipSelf))\n"
6254 "        reinterpret_cast<sip%C *>(sipGetAddress(sipSelf))->sipPySelf = SIP_NULLPTR;\n"
6255 "\n"
6256                 ,classFQCName(cd));
6257 
6258         if (generating_c || isPublicDtor(cd) || (hasShadow(cd) && isProtectedDtor(cd)))
6259         {
6260             prcode(fp,
6261 "    if (sipIsOwnedByPython(sipSelf))\n"
6262 "    {\n"
6263                 );
6264 
6265             if (isDelayedDtor(cd))
6266             {
6267                 prcode(fp,
6268 "        sipAddDelayedDtor(sipSelf);\n"
6269                     );
6270             }
6271             else if (generating_c)
6272             {
6273                 if (cd->dealloccode != NULL)
6274                     generateCppCodeBlock(cd->dealloccode, fp);
6275 
6276                 prcode(fp,
6277 "        sipFree(sipGetAddress(sipSelf));\n"
6278                     );
6279             }
6280             else
6281             {
6282                 prcode(fp,
6283 "        release_%L(sipGetAddress(sipSelf), %s);\n"
6284                     , cd->iff, (hasShadow(cd) ? "sipIsDerivedClass(sipSelf)" : "0"));
6285             }
6286 
6287             prcode(fp,
6288 "    }\n"
6289                 );
6290         }
6291 
6292         prcode(fp,
6293 "}\n"
6294             );
6295     }
6296 
6297     /* The type initialisation function. */
6298     if (canCreate(cd))
6299         generateTypeInit(cd, mod, fp);
6300 }
6301 
6302 
6303 /*
6304  * Generate the shadow (derived) class code.
6305  */
generateShadowCode(sipSpec * pt,moduleDef * mod,classDef * cd,FILE * fp)6306 static void generateShadowCode(sipSpec *pt, moduleDef *mod, classDef *cd,
6307         FILE *fp)
6308 {
6309     int nrVirts, virtNr;
6310     virtOverDef *vod;
6311     ctorDef *ct;
6312 
6313     nrVirts = countVirtuals(cd);
6314 
6315     /* Generate the wrapper class constructors. */
6316 
6317     for (ct = cd->ctors; ct != NULL; ct = ct->next)
6318     {
6319         ctorDef *dct;
6320 
6321         if (isPrivateCtor(ct))
6322             continue;
6323 
6324         if (ct->cppsig == NULL)
6325             continue;
6326 
6327         /* Check we haven't already handled this C++ signature. */
6328         for (dct = cd->ctors; dct != ct; dct = dct->next)
6329             if (dct->cppsig != NULL && sameSignature(dct->cppsig, ct->cppsig, TRUE))
6330                 break;
6331 
6332         if (dct != ct)
6333             continue;
6334 
6335         prcode(fp,
6336 "\n"
6337 "sip%C::sip%C(",classFQCName(cd),classFQCName(cd));
6338 
6339         generateCalledArgs(mod, cd->iff, ct->cppsig, Definition, fp);
6340 
6341         prcode(fp, ")%X: %U(", ct->exceptions, cd);
6342 
6343         generateProtectedCallArgs(mod, ct->cppsig, fp);
6344 
6345         prcode(fp,"), sipPySelf(SIP_NULLPTR)\n"
6346 "{\n"
6347             );
6348 
6349         if (tracing)
6350         {
6351             prcode(fp,
6352 "    sipTrace(SIP_TRACE_CTORS,\"sip%C::sip%C(",classFQCName(cd),classFQCName(cd));
6353             generateCalledArgs(NULL, cd->iff, ct->cppsig, Declaration, fp);
6354             prcode(fp,")%X (this=0x%%08x)\\n\",this);\n"
6355 "\n"
6356                 ,ct->exceptions);
6357         }
6358 
6359         if (nrVirts > 0)
6360             prcode(fp,
6361 "    memset(sipPyMethods, 0, sizeof (sipPyMethods));\n"
6362                 );
6363 
6364         prcode(fp,
6365 "}\n"
6366             );
6367     }
6368 
6369     /* The destructor. */
6370 
6371     if (!isPrivateDtor(cd))
6372     {
6373         prcode(fp,
6374 "\n"
6375 "sip%C::~sip%C()%X\n"
6376 "{\n"
6377             ,classFQCName(cd),classFQCName(cd),cd->dtorexceptions);
6378 
6379         if (tracing)
6380             prcode(fp,
6381 "    sipTrace(SIP_TRACE_DTORS,\"sip%C::~sip%C()%X (this=0x%%08x)\\n\",this);\n"
6382 "\n"
6383                 ,classFQCName(cd),classFQCName(cd),cd->dtorexceptions);
6384 
6385         if (cd->dtorcode != NULL)
6386             generateCppCodeBlock(cd->dtorcode,fp);
6387 
6388         prcode(fp,
6389 "    sipInstanceDestroyedEx(&sipPySelf);\n"
6390 "}\n"
6391             );
6392     }
6393 
6394     /* The meta methods if required. */
6395     if (pluginPyQt5(pt) && isQObjectSubClass(cd))
6396     {
6397         if (!noPyQtQMetaObject(cd))
6398         {
6399             prcode(fp,
6400 "\n"
6401 "const QMetaObject *sip%C::metaObject() const\n"
6402 "{\n"
6403                 , classFQCName(cd));
6404 
6405             if (pluginPyQt5(pt))
6406                 prcode(fp,
6407 "    if (sipGetInterpreter())\n"
6408 "        return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : sip_%s_qt_metaobject(sipPySelf,sipType_%C);\n"
6409 "\n"
6410 "    return %S::metaObject();\n"
6411                     , mod->name, classFQCName(cd)
6412                     , classFQCName(cd));
6413             else
6414                 prcode(fp,
6415 "    return sip_%s_qt_metaobject(sipPySelf,sipType_%C);\n"
6416                     , mod->name, classFQCName(cd));
6417 
6418             prcode(fp,
6419 "}\n"
6420                 );
6421         }
6422 
6423         prcode(fp,
6424 "\n"
6425 "int sip%C::qt_metacall(QMetaObject::Call _c,int _id,void **_a)\n"
6426 "{\n"
6427 "    _id = %S::qt_metacall(_c,_id,_a);\n"
6428 "\n"
6429 "    if (_id >= 0)\n"
6430 "    {\n"
6431 "        SIP_BLOCK_THREADS\n"
6432 "        _id = sip_%s_qt_metacall(sipPySelf,sipType_%C,_c,_id,_a);\n"
6433 "        SIP_UNBLOCK_THREADS\n"
6434 "    }\n"
6435 "\n"
6436 "    return _id;\n"
6437 "}\n"
6438 "\n"
6439 "void *sip%C::qt_metacast(const char *_clname)\n"
6440 "{\n"
6441             , classFQCName(cd)
6442             , classFQCName(cd)
6443             , mod->name, classFQCName(cd)
6444             , classFQCName(cd));
6445 
6446         if (pluginPyQt5(pt))
6447             prcode(fp,
6448 "    void *sipCpp;\n"
6449 "\n"
6450 "    return (sip_%s_qt_metacast(sipPySelf, sipType_%C, _clname, &sipCpp) ? sipCpp : %S::qt_metacast(_clname));\n"
6451                 , mod->name, classFQCName(cd), classFQCName(cd));
6452         else
6453             prcode(fp,
6454 "    return (sip_%s_qt_metacast(sipPySelf, sipType_%C, _clname)) ? this : %S::qt_metacast(_clname);\n"
6455                 , mod->name, classFQCName(cd), classFQCName(cd));
6456 
6457         prcode(fp,
6458 "}\n"
6459                 );
6460     }
6461 
6462     /* Generate the virtual catchers. */
6463 
6464     virtNr = 0;
6465 
6466     for (vod = cd->vmembers; vod != NULL; vod = vod->next)
6467     {
6468         overDef *od = vod->od;
6469         virtOverDef *dvod;
6470 
6471         if (isPrivate(od))
6472             continue;
6473 
6474         /*
6475          * Check we haven't already handled this C++ signature.  The same C++
6476          * signature should only appear more than once for overloads that are
6477          * enabled for different APIs and that differ in their /In/ and/or
6478          * /Out/ annotations.
6479          */
6480         for (dvod = cd->vmembers; dvod != vod; dvod = dvod->next)
6481             if (strcmp(dvod->od->cppname, od->cppname) == 0 && sameSignature(dvod->od->cppsig, od->cppsig, TRUE))
6482                 break;
6483 
6484         if (dvod == vod)
6485             generateVirtualCatcher(mod, cd, virtNr++, vod, fp);
6486     }
6487 
6488     /* Generate the wrapper around each protected member function. */
6489     generateProtectedDefinitions(mod, cd, fp);
6490 }
6491 
6492 
6493 /*
6494  * Generate the protected enums for a class.
6495  */
generateProtectedEnums(sipSpec * pt,classDef * cd,FILE * fp)6496 static void generateProtectedEnums(sipSpec *pt,classDef *cd,FILE *fp)
6497 {
6498     enumDef *ed;
6499 
6500     for (ed = pt->enums; ed != NULL; ed = ed->next)
6501     {
6502         char *eol;
6503         mroDef *mro;
6504         enumMemberDef *emd;
6505 
6506         if (!isProtectedEnum(ed))
6507             continue;
6508 
6509         /* See if the class defining the enum is in our class hierachy. */
6510         for (mro = cd->mro; mro != NULL; mro = mro->next)
6511             if (mro->cd == ed->ecd)
6512                 break;
6513 
6514         if (mro == NULL)
6515             continue;
6516 
6517         prcode(fp,
6518 "\n"
6519 "    /* Expose this protected enum. */\n"
6520 "    enum");
6521 
6522         if (ed->fqcname != NULL)
6523             prcode(fp," sip%s",scopedNameTail(ed->fqcname));
6524 
6525         prcode(fp," {");
6526 
6527         eol = "\n";
6528 
6529         for (emd = ed->members; emd != NULL; emd = emd->next)
6530         {
6531             prcode(fp,"%s"
6532 "        %s = %S::%s",eol,emd->cname,classFQCName(ed->ecd),emd->cname);
6533 
6534             eol = ",\n";
6535         }
6536 
6537         prcode(fp,"\n"
6538 "    };\n"
6539             );
6540     }
6541 }
6542 
6543 
6544 /*
6545  * Generate the catcher for a virtual function.
6546  */
generateVirtualCatcher(moduleDef * mod,classDef * cd,int virtNr,virtOverDef * vod,FILE * fp)6547 static void generateVirtualCatcher(moduleDef *mod, classDef *cd, int virtNr,
6548         virtOverDef *vod, FILE *fp)
6549 {
6550     overDef *od = vod->od;
6551     argDef *res;
6552     apiVersionRangeDef *avr;
6553 
6554     normaliseArgs(od->cppsig);
6555 
6556     res = &od->cppsig->result;
6557 
6558     if (res->atype == void_type && res->nrderefs == 0)
6559         res = NULL;
6560 
6561     prcode(fp,
6562 "\n");
6563 
6564     generateBaseType(cd->iff, &od->cppsig->result, TRUE, STRIP_NONE, fp);
6565 
6566     prcode(fp," sip%C::%O(",classFQCName(cd),od);
6567     generateCalledArgs(mod, cd->iff, od->cppsig, Definition, fp);
6568     prcode(fp,")%s%X\n"
6569 "{\n"
6570         ,(isConst(od) ? " const" : ""),od->exceptions);
6571 
6572     if (tracing)
6573     {
6574         prcode(fp,
6575 "    sipTrace(SIP_TRACE_CATCHERS,\"");
6576 
6577         generateBaseType(cd->iff, &od->cppsig->result, TRUE, STRIP_GLOBAL, fp);
6578         prcode(fp," sip%C::%O(",classFQCName(cd),od);
6579         generateCalledArgs(NULL, cd->iff, od->cppsig, Declaration, fp);
6580         prcode(fp,")%s%X (this=0x%%08x)\\n\",this);\n"
6581 "\n"
6582             ,(isConst(od) ? " const" : ""),od->exceptions);
6583     }
6584 
6585     restoreArgs(od->cppsig);
6586 
6587     prcode(fp,
6588 "    sip_gilstate_t sipGILState;\n"
6589 "    PyObject *sipMeth;\n");
6590 
6591     /* For the module ABI v12.8 and later. */
6592     prcode(fp,
6593 "\n"
6594 "#if SIP_ABI_MAJOR_VERSION >= 12 && SIP_ABI_MINOR_VERSION >= 8\n"
6595 "    sipMeth = sipIsPyMethod_12_8(&sipGILState, ");
6596 
6597     if (isConst(od))
6598         prcode(fp, "const_cast<char *>(&sipPyMethods[%d]), const_cast<sipSimpleWrapper **>(&sipPySelf), ",virtNr);
6599     else
6600         prcode(fp, "&sipPyMethods[%d], &sipPySelf, ",virtNr);
6601 
6602     if (isAbstract(od))
6603         prcode(fp, "%N", cd->pyname);
6604     else
6605         prcode(fp, "SIP_NULLPTR");
6606 
6607     prcode(fp,", %N);\n"
6608         ,od->common->pyname);
6609 
6610     /* For the module ABI v12.7 and earlier. */
6611     prcode(fp,
6612 "\n"
6613 "#else\n"
6614 "    sipMeth = sipIsPyMethod(&sipGILState, ");
6615 
6616     if (isConst(od))
6617         prcode(fp, "const_cast<char *>(");
6618 
6619     prcode(fp,"&sipPyMethods[%d]",virtNr);
6620 
6621     if (isConst(od))
6622         prcode(fp, ")");
6623 
6624     prcode(fp,", sipPySelf, ");
6625 
6626     if (isAbstract(od))
6627         prcode(fp, "%N", cd->pyname);
6628     else
6629         prcode(fp, "SIP_NULLPTR");
6630 
6631     prcode(fp,", %N);\n"
6632 "#endif\n"
6633 "\n"
6634         ,od->common->pyname);
6635 
6636     /* The rest of the common code. */
6637     prcode(fp,
6638 "    if (!sipMeth)\n"
6639         );
6640 
6641     if (od->virtcallcode != NULL)
6642     {
6643         argDef *res = &od->cppsig->result;
6644 
6645         prcode(fp,
6646 "    {\n");
6647 
6648         if (res->atype != void_type || res->nrderefs != 0)
6649         {
6650             prcode(fp,
6651 "        ");
6652 
6653             generateNamedBaseType(cd->iff, res, "sipRes", TRUE, STRIP_NONE,
6654                     fp);
6655 
6656             prcode(fp, ";\n"
6657                 );
6658         }
6659         else
6660         {
6661             res = NULL;
6662         }
6663 
6664         prcode(fp,
6665 "\n"
6666             );
6667 
6668         generateCppCodeBlock(od->virtcallcode, fp);
6669 
6670         prcode(fp,
6671 "\n"
6672 "        return%s;\n"
6673 "    }\n"
6674             , (res != NULL ? " sipRes" : ""));
6675     }
6676     else if (isAbstract(od))
6677     {
6678         generateDefaultInstanceReturn(res, "    ", fp);
6679     }
6680     else
6681     {
6682         int a;
6683 
6684         if (res == NULL)
6685             prcode(fp,
6686 "    {\n"
6687 "        ");
6688         else
6689             prcode(fp,
6690 "        return ");
6691 
6692         prcode(fp, "%S::%O(", classFQCName(cd), od);
6693 
6694         for (a = 0; a < od->cppsig->nrArgs; ++a)
6695         {
6696             argDef *ad = &od->cppsig->args[a];
6697 
6698             prcode(fp, "%s%a", (a == 0 ? "" : ","), mod, ad, a);
6699         }
6700 
6701         prcode(fp,");\n"
6702             );
6703 
6704         if (res == NULL)
6705         {
6706             /*
6707              * Note that we should also generate this if the function returns a
6708              * value, but we are lazy and this is all that is needed by PyQt.
6709              */
6710             if (isNewThread(od))
6711                 prcode(fp,
6712 "        sipEndThread();\n"
6713                     );
6714 
6715             prcode(fp,
6716 "        return;\n"
6717 "    }\n"
6718                 );
6719         }
6720     }
6721 
6722     /*
6723      * If this overload doesn't have an API version assume that there are none
6724      * that do.
6725      */
6726     avr = od->api_range;
6727 
6728     if (avr == NULL)
6729     {
6730         prcode(fp,
6731 "\n"
6732             );
6733 
6734         generateVirtHandlerCall(mod, cd, vod, res, "    ", fp);
6735     }
6736     else
6737     {
6738         virtOverDef *versioned_vod = vod;
6739 
6740         do
6741         {
6742             prcode(fp,
6743 "\n"
6744 "    if (sipIsAPIEnabled(%N, %d, %d))\n"
6745 "    {\n"
6746                 , avr->api_name, avr->from, avr->to);
6747 
6748             generateVirtHandlerCall(mod, cd, versioned_vod, res, "        ", fp);
6749 
6750             if (res == NULL)
6751                 prcode(fp,
6752 "        return;\n"
6753                     );
6754 
6755             prcode(fp,
6756 "    }\n"
6757                 );
6758 
6759             /* Find the next overload. */
6760             while ((versioned_vod = versioned_vod->next) != NULL)
6761             {
6762                 if (strcmp(versioned_vod->od->cppname, od->cppname) == 0 && sameSignature(versioned_vod->od->cppsig, od->cppsig, TRUE))
6763                 {
6764                     avr = versioned_vod->od->api_range;
6765 
6766                     /* Check that it has an API specified. */
6767                     if (avr == NULL)
6768                     {
6769                         fatalScopedName(classFQCName(cd));
6770                         fatalAppend("::");
6771                         prOverloadName(NULL, od);
6772                         fatal(" has versioned and unversioned overloads\n");
6773                     }
6774 
6775                     break;
6776                 }
6777             }
6778         }
6779         while (versioned_vod != NULL);
6780 
6781         prcode(fp,
6782 "\n"
6783             );
6784 
6785         /* Generate a default result in case no API is enabled. */
6786         if (isAbstract(od))
6787             generateDefaultInstanceReturn(res, "", fp);
6788         else
6789         {
6790             int a;
6791 
6792             prcode(fp, "    %s%S::%O(", (res != NULL ? "return " : ""), classFQCName(cd), od);
6793 
6794             for (a = 0; a < od->cppsig->nrArgs; ++a)
6795             {
6796                 argDef *ad = &od->cppsig->args[a];
6797 
6798                 prcode(fp, "%s%a", (a == 0 ? "" : ","), mod, ad, a);
6799             }
6800 
6801             prcode(fp,");\n"
6802                 );
6803         }
6804     }
6805 
6806     prcode(fp,
6807 "}\n"
6808         );
6809 }
6810 
6811 
6812 /*
6813  * Generate a call to a single virtual handler.
6814  */
generateVirtHandlerCall(moduleDef * mod,classDef * cd,virtOverDef * vod,argDef * res,const char * indent,FILE * fp)6815 static void generateVirtHandlerCall(moduleDef *mod, classDef *cd,
6816         virtOverDef *vod, argDef *res, const char *indent, FILE *fp)
6817 {
6818     overDef *od = vod->od;
6819     virtHandlerDef *vhd = vod->virthandler;
6820     virtErrorHandler *veh;
6821     signatureDef saved;
6822     argDef *ad;
6823     int a, args_keep = FALSE, result_keep = FALSE;
6824 
6825     saved = *vhd->cppsig;
6826     fakeProtectedArgs(vhd->cppsig);
6827 
6828     prcode(fp,
6829 "%sextern ", indent);
6830 
6831     generateBaseType(cd->iff, &od->cppsig->result, TRUE, STRIP_NONE, fp);
6832 
6833     prcode(fp, " sipVH_%s_%d(sip_gilstate_t, sipVirtErrorHandlerFunc, sipSimpleWrapper *, PyObject *", mod->name, vhd->virthandlernr);
6834 
6835     if (vhd->cppsig->nrArgs > 0)
6836     {
6837         prcode(fp, ", ");
6838         generateCalledArgs(NULL, cd->iff, vhd->cppsig, Declaration, fp);
6839     }
6840 
6841     *vhd->cppsig = saved;
6842 
6843     /* Add extra arguments for all the references we need to keep. */
6844     if (res != NULL && keepPyReference(res))
6845     {
6846         result_keep = TRUE;
6847         res->key = mod->next_key--;
6848         prcode(fp, ", int");
6849     }
6850 
6851     for (ad = od->cppsig->args, a = 0; a < od->cppsig->nrArgs; ++a, ++ad)
6852         if (isOutArg(ad) && keepPyReference(ad))
6853         {
6854             args_keep = TRUE;
6855             ad->key = mod->next_key--;
6856             prcode(fp, ", int");
6857         }
6858 
6859     prcode(fp,");\n"
6860         );
6861 
6862     prcode(fp,
6863 "\n"
6864 "%s", indent);
6865 
6866     if (!isNewThread(od) && res != NULL)
6867         prcode(fp, "return ");
6868 
6869     prcode(fp, "sipVH_%s_%d(sipGILState, ", mod->name, vhd->virthandlernr);
6870 
6871     veh = vhd->veh;
6872 
6873     if (veh == NULL)
6874         prcode(fp, "0");
6875     else if (veh->mod == mod)
6876         prcode(fp, "sipVEH_%s_%s" , mod->name, veh->name);
6877     else
6878         prcode(fp, "sipImportedVirtErrorHandlers_%s_%s[%d].iveh_handler", mod->name, veh->mod->name, veh->index);
6879 
6880     prcode(fp, ", sipPySelf, sipMeth");
6881 
6882     for (ad = od->cppsig->args, a = 0; a < od->cppsig->nrArgs; ++a, ++ad)
6883     {
6884         if (ad->atype == class_type && isProtectedClass(ad->u.cd))
6885             prcode(fp, ", %s%a", ((isReference(ad) || ad->nrderefs == 0) ? "&" : ""), mod, ad, a);
6886         else if (ad->atype == enum_type && isProtectedEnum(ad->u.ed))
6887             prcode(fp, ", (%E)%a", ad->u.ed, mod, ad, a);
6888         else
6889             prcode(fp, ", %a", mod, ad, a);
6890     }
6891 
6892     /* Pass the keys to maintain the kept references. */
6893     if (result_keep)
6894         prcode(fp, ", %d", res->key);
6895 
6896     if (args_keep)
6897         for (ad = od->cppsig->args, a = 0; a < od->cppsig->nrArgs; ++a, ++ad)
6898             if (isOutArg(ad) && keepPyReference(ad))
6899                 prcode(fp, ", %d", ad->key);
6900 
6901     prcode(fp,");\n"
6902         );
6903 
6904     if (isNewThread(od))
6905         prcode(fp,
6906 "\n"
6907 "%ssipEndThread();\n"
6908             , indent);
6909 }
6910 
6911 
6912 /*
6913  * Generate a cast to zero.
6914  */
generateCastZero(argDef * ad,FILE * fp)6915 static void generateCastZero(argDef *ad, FILE *fp)
6916 {
6917     switch (ad->atype)
6918     {
6919     case enum_type:
6920         {
6921             enumDef *ed = ad->u.ed;
6922 
6923             if (ed->members != NULL)
6924             {
6925                 if (isScopedEnum(ed))
6926                     prcode(fp, "%E", ed);
6927                 else if (ed->ecd != NULL)
6928                     prEnumMemberScope(ed->members, fp);
6929 
6930                 prcode(fp, "::%s", ed->members->cname);
6931 
6932                 return;
6933             }
6934 
6935             prcode(fp, "(%E)0", ed);
6936         }
6937 
6938     case pyobject_type:
6939     case pytuple_type:
6940     case pylist_type:
6941     case pydict_type:
6942     case pycallable_type:
6943     case pyslice_type:
6944     case pytype_type:
6945     case pybuffer_type:
6946     case ellipsis_type:
6947         prcode(fp, "SIP_NULLPTR");
6948         break;
6949 
6950     default:
6951         prcode(fp, "0");
6952     }
6953 }
6954 
6955 
6956 /*
6957  * Generate a statement to return the default instance of a type typically on
6958  * error (ie. when there is nothing sensible to return).
6959  */
generateDefaultInstanceReturn(argDef * res,const char * indent,FILE * fp)6960 static void generateDefaultInstanceReturn(argDef *res, const char *indent,
6961         FILE *fp)
6962 {
6963     codeBlockList *instance_code;
6964 
6965     /* Handle the trivial case. */
6966     if (res == NULL)
6967     {
6968         prcode(fp,
6969 "%s    return;\n"
6970             , indent);
6971 
6972         return;
6973     }
6974 
6975     /* Handle any %InstanceCode. */
6976     instance_code = NULL;
6977 
6978     if (res->nrderefs == 0)
6979     {
6980         if (res->atype == mapped_type)
6981             instance_code = res->u.mtd->instancecode;
6982         else if (res->atype == class_type)
6983             instance_code = res->u.cd->instancecode;
6984     }
6985 
6986     if (instance_code != NULL)
6987     {
6988         argDef res_noconstref;
6989 
6990         res_noconstref = *res;
6991         resetIsConstArg(&res_noconstref);
6992         resetIsReference(&res_noconstref);
6993 
6994         prcode(fp,
6995 "%s{\n"
6996 "%s    static %B *sipCpp = SIP_NULLPTR;\n"
6997 "\n"
6998 "%s    if (!sipCpp)\n"
6999 "%s    {\n"
7000             , indent
7001             , indent, &res_noconstref
7002             , indent
7003             , indent);
7004 
7005         generateCppCodeBlock(instance_code, fp);
7006 
7007         prcode(fp,
7008 "%s    }\n"
7009 "\n"
7010 "%s    return *sipCpp;\n"
7011 "%s}\n"
7012             , indent
7013             , indent
7014             , indent);
7015 
7016         return;
7017     }
7018 
7019     prcode(fp,
7020 "%s    return ", indent);
7021 
7022     if (res->atype == mapped_type && res->nrderefs == 0)
7023     {
7024         argDef res_noconstref;
7025 
7026         /*
7027          * We don't know anything about the mapped type so we just hope is has
7028          * a default ctor.
7029          */
7030 
7031         if (isReference(res))
7032             prcode(fp,"*new ");
7033 
7034         res_noconstref = *res;
7035         resetIsConstArg(&res_noconstref);
7036         resetIsReference(&res_noconstref);
7037         prcode(fp,"%B()",&res_noconstref);
7038     }
7039     else if (res->atype == class_type && res->nrderefs == 0)
7040     {
7041         ctorDef *ct = res->u.cd->defctor;
7042 
7043         /*
7044          * If we don't have a suitable ctor then the generated code will issue
7045          * an error message.
7046          */
7047         if (ct != NULL && isPublicCtor(ct) && ct->cppsig != NULL)
7048         {
7049             argDef res_noconstref;
7050 
7051             /*
7052              * If this is a badly designed class.  We can only generate correct
7053              * code by leaking memory.
7054              */
7055             if (isReference(res))
7056                 prcode(fp,"*new ");
7057 
7058             res_noconstref = *res;
7059             resetIsConstArg(&res_noconstref);
7060             resetIsReference(&res_noconstref);
7061             prcode(fp,"%B",&res_noconstref);
7062 
7063             generateCallDefaultCtor(ct,fp);
7064         }
7065         else
7066         {
7067             fatalScopedName(classFQCName(res->u.cd));
7068             fatal(" must have a default constructor\n");
7069         }
7070     }
7071     else
7072         generateCastZero(res,fp);
7073 
7074     prcode(fp,";\n"
7075         );
7076 }
7077 
7078 
7079 /*
7080  * Generate the call to a default ctor.
7081  */
generateCallDefaultCtor(ctorDef * ct,FILE * fp)7082 static void generateCallDefaultCtor(ctorDef *ct, FILE *fp)
7083 {
7084     int a;
7085 
7086     prcode(fp, "(");
7087 
7088     for (a = 0; a < ct->cppsig->nrArgs; ++a)
7089     {
7090         argDef *ad = &ct->cppsig->args[a];
7091         argType atype = ad->atype;
7092 
7093         if (ad->defval != NULL)
7094             break;
7095 
7096         if (a > 0)
7097             prcode(fp, ",");
7098 
7099         /* Do what we can to provide type information to the compiler. */
7100         if (atype == class_type && ad->nrderefs > 0 && !isReference(ad))
7101             prcode(fp, "static_cast<%B>(0)", ad);
7102         else if (atype == enum_type)
7103             prcode(fp, "static_cast<%E>(0)", ad->u.ed);
7104         else if (atype == float_type || atype == cfloat_type)
7105             prcode(fp, "0.0F");
7106         else if (atype == double_type || atype == cdouble_type)
7107             prcode(fp, "0.0");
7108         else if (atype == uint_type || atype == size_type)
7109             prcode(fp, "0U");
7110         else if (atype == long_type || atype == longlong_type)
7111             prcode(fp, "0L");
7112         else if (atype == ulong_type || atype == ulonglong_type)
7113             prcode(fp, "0UL");
7114         else if ((atype == ascii_string_type || atype == latin1_string_type || atype == utf8_string_type || atype == ustring_type || atype == sstring_type || atype == string_type) && ad->nrderefs == 0)
7115             prcode(fp, "'\\0'");
7116         else if (atype == wstring_type && ad->nrderefs == 0)
7117             prcode(fp, "L'\\0'");
7118         else
7119             prcode(fp, "0");
7120     }
7121 
7122     prcode(fp, ")");
7123 }
7124 
7125 
7126 /*
7127  * Generate the declarations of the protected wrapper functions for a class.
7128  */
generateProtectedDeclarations(classDef * cd,FILE * fp)7129 static void generateProtectedDeclarations(classDef *cd,FILE *fp)
7130 {
7131     int noIntro;
7132     visibleList *vl;
7133 
7134     noIntro = TRUE;
7135 
7136     for (vl = cd->visible; vl != NULL; vl = vl->next)
7137     {
7138         overDef *od;
7139 
7140         if (vl->m->slot != no_slot)
7141             continue;
7142 
7143         for (od = vl->cd->overs; od != NULL; od = od->next)
7144         {
7145             if (od->common != vl->m || !isProtected(od))
7146                 continue;
7147 
7148             /*
7149              * Check we haven't already handled this signature (eg. if we have
7150              * specified the same method with different Python names.
7151              */
7152             if (isDuplicateProtected(cd, od))
7153                 continue;
7154 
7155             if (noIntro)
7156             {
7157                 prcode(fp,
7158 "\n"
7159 "    /*\n"
7160 "     * There is a public method for every protected method visible from\n"
7161 "     * this class.\n"
7162 "     */\n"
7163                     );
7164 
7165                 noIntro = FALSE;
7166             }
7167 
7168             prcode(fp,
7169 "    ");
7170 
7171             if (isStatic(od))
7172                 prcode(fp,"static ");
7173 
7174             generateBaseType(cd->iff, &od->cppsig->result, TRUE, STRIP_NONE,
7175                     fp);
7176 
7177             if (!isStatic(od) && !isAbstract(od) && (isVirtual(od) || isVirtualReimp(od)))
7178             {
7179                 prcode(fp, " sipProtectVirt_%s(bool", od->cppname);
7180 
7181                 if (od->cppsig->nrArgs > 0)
7182                     prcode(fp, ",");
7183             }
7184             else
7185                 prcode(fp, " sipProtect_%s(", od->cppname);
7186 
7187             generateCalledArgs(NULL, cd->iff, od->cppsig, Declaration, fp);
7188             prcode(fp,")%s;\n"
7189                 ,(isConst(od) ? " const" : ""));
7190         }
7191     }
7192 }
7193 
7194 
7195 /*
7196  * Generate the definitions of the protected wrapper functions for a class.
7197  */
generateProtectedDefinitions(moduleDef * mod,classDef * cd,FILE * fp)7198 static void generateProtectedDefinitions(moduleDef *mod, classDef *cd, FILE *fp)
7199 {
7200     visibleList *vl;
7201 
7202     for (vl = cd->visible; vl != NULL; vl = vl->next)
7203     {
7204         overDef *od;
7205 
7206         if (vl->m->slot != no_slot)
7207             continue;
7208 
7209         for (od = vl->cd->overs; od != NULL; od = od->next)
7210         {
7211             const char *mname = od->cppname;
7212             int parens;
7213             argDef *res;
7214 
7215             if (od->common != vl->m || !isProtected(od))
7216                 continue;
7217 
7218             /*
7219              * Check we haven't already handled this signature (eg. if we have
7220              * specified the same method with different Python names.
7221              */
7222             if (isDuplicateProtected(cd, od))
7223                 continue;
7224 
7225             prcode(fp,
7226 "\n"
7227                 );
7228 
7229             generateBaseType(cd->iff, &od->cppsig->result, TRUE, STRIP_NONE,
7230                     fp);
7231 
7232             if (!isStatic(od) && !isAbstract(od) && (isVirtual(od) || isVirtualReimp(od)))
7233             {
7234                 prcode(fp, " sip%C::sipProtectVirt_%s(bool sipSelfWasArg", classFQCName(cd), mname);
7235 
7236                 if (od->cppsig->nrArgs > 0)
7237                     prcode(fp, ",");
7238             }
7239             else
7240                 prcode(fp, " sip%C::sipProtect_%s(", classFQCName(cd), mname);
7241 
7242             generateCalledArgs(mod, cd->iff, od->cppsig, Definition, fp);
7243             prcode(fp,")%s\n"
7244 "{\n"
7245                 ,(isConst(od) ? " const" : ""));
7246 
7247             parens = 1;
7248 
7249             res = &od->cppsig->result;
7250 
7251             if (res->atype == void_type && res->nrderefs == 0)
7252                 prcode(fp,
7253 "    ");
7254             else
7255             {
7256                 prcode(fp,
7257 "    return ");
7258 
7259                 if (res->atype == class_type && isProtectedClass(res->u.cd))
7260                 {
7261                     prcode(fp,"static_cast<%U *>(",res->u.cd);
7262                     ++parens;
7263                 }
7264                 else if (res->atype == enum_type && isProtectedEnum(res->u.ed))
7265                 {
7266                     /*
7267                      * One or two older compilers can't handle a static_cast
7268                      * here so we revert to a C-style cast.
7269                      */
7270                     prcode(fp,"(%E)",res->u.ed);
7271                 }
7272             }
7273 
7274             if (!isAbstract(od))
7275             {
7276                 if (isVirtual(od) || isVirtualReimp(od))
7277                 {
7278                     prcode(fp, "(sipSelfWasArg ? %U::%s(", vl->cd, mname);
7279 
7280                     generateProtectedCallArgs(mod, od->cppsig, fp);
7281 
7282                     prcode(fp, ") : ");
7283                     ++parens;
7284                 }
7285                 else
7286                 {
7287                     prcode(fp, "%U::", vl->cd);
7288                 }
7289             }
7290 
7291             prcode(fp,"%s(",mname);
7292 
7293             generateProtectedCallArgs(mod, od->cppsig, fp);
7294 
7295             while (parens--)
7296                 prcode(fp,")");
7297 
7298             prcode(fp,";\n"
7299 "}\n"
7300                 );
7301         }
7302     }
7303 }
7304 
7305 
7306 /*
7307  * Return TRUE if a protected method is a duplicate.
7308  */
isDuplicateProtected(classDef * cd,overDef * target)7309 static int isDuplicateProtected(classDef *cd, overDef *target)
7310 {
7311     visibleList *vl;
7312 
7313     for (vl = cd->visible; vl != NULL; vl = vl->next)
7314     {
7315         overDef *od;
7316 
7317         if (vl->m->slot != no_slot)
7318             continue;
7319 
7320         for (od = vl->cd->overs; od != NULL; od = od->next)
7321         {
7322             if (od->common != vl->m || !isProtected(od))
7323                 continue;
7324 
7325             if (od == target)
7326                 return FALSE;
7327 
7328             if (strcmp(od->cppname, target->cppname) == 0 && sameSignature(od->cppsig, target->cppsig, TRUE))
7329                 return TRUE;
7330         }
7331     }
7332 
7333     /* We should never actually get here. */
7334     return FALSE;
7335 }
7336 
7337 
7338 /*
7339  * Generate the arguments for a call to a protected method.
7340  */
generateProtectedCallArgs(moduleDef * mod,signatureDef * sd,FILE * fp)7341 static void generateProtectedCallArgs(moduleDef *mod, signatureDef *sd,
7342         FILE *fp)
7343 {
7344     int a;
7345 
7346     for (a = 0; a < sd->nrArgs; ++a)
7347     {
7348         argDef *ad = &sd->args[a];
7349 
7350         if (a > 0)
7351             prcode(fp, ",");
7352 
7353         if (ad->atype == enum_type && isProtectedEnum(ad->u.ed))
7354             prcode(fp, "(%S)", ad->u.ed->fqcname);
7355 
7356         prcode(fp, "%a", mod, ad, a);
7357     }
7358 }
7359 
7360 
7361 /*
7362  * Generate the function that does most of the work to handle a particular
7363  * virtual function.
7364  */
generateVirtualHandler(moduleDef * mod,virtHandlerDef * vhd,FILE * fp)7365 static void generateVirtualHandler(moduleDef *mod, virtHandlerDef *vhd,
7366         FILE *fp)
7367 {
7368     int a, nrvals, res_isref;
7369     argDef *res, res_noconstref, *ad;
7370     signatureDef saved;
7371     codeBlockList *res_instancecode;
7372 
7373     res = &vhd->cppsig->result;
7374 
7375     res_isref = FALSE;
7376     res_instancecode = NULL;
7377 
7378     if (res->atype == void_type && res->nrderefs == 0)
7379     {
7380         res = NULL;
7381     }
7382     else
7383     {
7384         /*
7385          * If we are returning a reference to an instance then we take care to
7386          * handle Python errors but still return a valid C++ instance.
7387          */
7388         if ((res->atype == class_type || res->atype == mapped_type) && res->nrderefs == 0)
7389         {
7390             if (isReference(res))
7391                 res_isref = TRUE;
7392             else if (res->atype == class_type)
7393                 res_instancecode = res->u.cd->instancecode;
7394             else
7395                 res_instancecode = res->u.mtd->instancecode;
7396         }
7397 
7398         res_noconstref = *res;
7399         resetIsConstArg(&res_noconstref);
7400         resetIsReference(&res_noconstref);
7401     }
7402 
7403     prcode(fp,
7404 "\n"
7405         );
7406 
7407     saved = *vhd->cppsig;
7408     fakeProtectedArgs(vhd->cppsig);
7409 
7410     generateBaseType(NULL, &vhd->cppsig->result, TRUE, STRIP_NONE, fp);
7411 
7412     prcode(fp," sipVH_%s_%d(sip_gilstate_t sipGILState, sipVirtErrorHandlerFunc sipErrorHandler, sipSimpleWrapper *sipPySelf, PyObject *sipMethod"
7413         , mod->name, vhd->virthandlernr);
7414 
7415     if (vhd->cppsig->nrArgs > 0)
7416     {
7417         prcode(fp,", ");
7418         generateCalledArgs(mod, NULL, vhd->cppsig, Definition, fp);
7419     }
7420 
7421     *vhd->cppsig = saved;
7422 
7423     /* Declare the extra arguments for kept references. */
7424     if (res != NULL && keepPyReference(res))
7425     {
7426         prcode(fp, ", int");
7427 
7428         if (vhd->virtcode == NULL || usedInCode(vhd->virtcode, "sipResKey"))
7429             prcode(fp, " sipResKey");
7430     }
7431 
7432     for (ad = vhd->cppsig->args, a = 0; a < vhd->cppsig->nrArgs; ++a, ++ad)
7433         if (isOutArg(ad) && keepPyReference(ad))
7434             prcode(fp, ", int %aKey", mod, ad, a);
7435 
7436     prcode(fp,")\n"
7437 "{\n"
7438         );
7439 
7440     if (res != NULL)
7441     {
7442         if (res_instancecode != NULL)
7443         {
7444             prcode(fp,
7445 "    static %B *sipCpp = SIP_NULLPTR;\n"
7446 "\n"
7447 "    if (!sipCpp)\n"
7448 "    {\n"
7449                 , &res_noconstref);
7450 
7451             generateCppCodeBlock(res_instancecode, fp);
7452 
7453             prcode(fp,
7454 "    }\n"
7455 "\n"
7456                 );
7457         }
7458 
7459         prcode(fp, "    ");
7460 
7461         /*
7462          * wchar_t * return values are always on the heap.  To reduce memory
7463          * leaks we keep the last result around until we have a new one.  This
7464          * means that ownership of the return value stays with the function
7465          * returning it - which is consistent with how other types work, even
7466          * thought it may not be what's required in all cases.  Note that we
7467          * should do this in the code that calls the handler instead of here
7468          * (as we do with strings) so that it doesn't get shared between all
7469          * callers.
7470          */
7471         if (res->atype == wstring_type && res->nrderefs == 1)
7472             prcode(fp, "static ");
7473 
7474         generateBaseType(NULL, &res_noconstref, TRUE, STRIP_NONE, fp);
7475 
7476         prcode(fp," %ssipRes",(res_isref ? "*" : ""));
7477 
7478         if ((res->atype == class_type || res->atype == mapped_type || res->atype == template_type) && res->nrderefs == 0)
7479         {
7480             if (res_instancecode != NULL)
7481             {
7482                 prcode(fp, " = *sipCpp");
7483             }
7484             else if (res->atype == class_type)
7485             {
7486                 ctorDef *ct = res->u.cd->defctor;
7487 
7488                 if (ct != NULL && isPublicCtor(ct) && ct->cppsig != NULL && ct->cppsig->nrArgs > 0 && ct->cppsig->args[0].defval == NULL)
7489                     generateCallDefaultCtor(ct,fp);
7490             }
7491         }
7492         else
7493         {
7494             /*
7495              * We initialise the result to try and suppress a compiler warning.
7496              */
7497             prcode(fp," = ");
7498             generateCastZero(res,fp);
7499         }
7500 
7501         prcode(fp,";\n"
7502             );
7503 
7504         if (res->atype == wstring_type && res->nrderefs == 1)
7505             prcode(fp,
7506 "\n"
7507 "    if (sipRes)\n"
7508 "    {\n"
7509 "        // Return any previous result to the heap.\n"
7510 "        sipFree(%s);\n"
7511 "        sipRes = SIP_NULLPTR;\n"
7512 "    }\n"
7513 "\n"
7514                 , (isConstArg(res) ? "const_cast<wchar_t *>(sipRes)" : "sipRes"));
7515     }
7516 
7517     if (vhd->virtcode != NULL)
7518     {
7519         int error_flag = needErrorFlag(vhd->virtcode);
7520         int old_error_flag = needOldErrorFlag(vhd->virtcode);
7521 
7522         if (error_flag)
7523             prcode(fp,
7524 "    sipErrorState sipError = sipErrorNone;\n"
7525                 );
7526         else if (old_error_flag)
7527             prcode(fp,
7528 "    int sipIsErr = 0;\n"
7529                 );
7530 
7531         prcode(fp,
7532 "\n"
7533             );
7534 
7535         generateCppCodeBlock(vhd->virtcode,fp);
7536 
7537         prcode(fp,
7538 "\n"
7539 "    Py_DECREF(sipMethod);\n"
7540             );
7541 
7542         if (error_flag || old_error_flag)
7543             prcode(fp,
7544 "\n"
7545 "    if (%s)\n"
7546 "        sipCallErrorHandler(sipErrorHandler, sipPySelf, sipGILState);\n"
7547                 , (error_flag ? "sipError != sipErrorNone" : "sipIsErr"));
7548 
7549         prcode(fp,
7550 "\n"
7551 "    SIP_RELEASE_GIL(sipGILState)\n"
7552             );
7553 
7554         if (res != NULL)
7555             prcode(fp,
7556 "\n"
7557 "    return sipRes;\n"
7558                 );
7559 
7560         prcode(fp,
7561 "}\n"
7562             );
7563 
7564         return;
7565     }
7566 
7567     /* See how many values we expect. */
7568     nrvals = (res != NULL ? 1 : 0);
7569 
7570     for (a = 0; a < vhd->pysig->nrArgs; ++a)
7571         if (isOutArg(&vhd->pysig->args[a]))
7572             ++nrvals;
7573 
7574     /* Call the method. */
7575     if (nrvals == 0)
7576         prcode(fp,
7577 "    sipCallProcedureMethod(sipGILState, sipErrorHandler, sipPySelf, sipMethod, ");
7578     else
7579         prcode(fp,
7580 "    PyObject *sipResObj = sipCallMethod(SIP_NULLPTR, sipMethod, ");
7581 
7582     saved = *vhd->pysig;
7583     fakeProtectedArgs(vhd->pysig);
7584     generateTupleBuilder(mod, vhd->pysig, fp);
7585     *vhd->pysig = saved;
7586 
7587     if (nrvals == 0)
7588     {
7589         prcode(fp, ");\n"
7590 "}\n"
7591             );
7592 
7593         return;
7594     }
7595 
7596     prcode(fp, ");\n"
7597 "\n"
7598 "    %ssipParseResultEx(sipGILState, sipErrorHandler, sipPySelf, sipMethod, sipResObj, \"", ((res_isref || abortOnExceptionVH(vhd)) ? "int sipRc = " : ""));
7599 
7600     /* Build the format string. */
7601     if (nrvals == 0)
7602         prcode(fp,"Z");
7603     else
7604     {
7605         if (nrvals > 1)
7606             prcode(fp,"(");
7607 
7608         if (res != NULL)
7609             prcode(fp, "%s", getParseResultFormat(res, res_isref, isTransferVH(vhd)));
7610 
7611         for (a = 0; a < vhd->pysig->nrArgs; ++a)
7612         {
7613             argDef *ad = &vhd->pysig->args[a];
7614 
7615             if (isOutArg(ad))
7616                 prcode(fp, "%s", getParseResultFormat(ad, FALSE, FALSE));
7617         }
7618 
7619         if (nrvals > 1)
7620             prcode(fp,")");
7621     }
7622 
7623     prcode(fp,"\"");
7624 
7625     /* Pass the destination pointers. */
7626     if (res != NULL)
7627     {
7628         generateParseResultExtraArgs(NULL, res, -1, fp);
7629         prcode(fp, ", &sipRes");
7630     }
7631 
7632     for (a = 0; a < vhd->pysig->nrArgs; ++a)
7633     {
7634         argDef *ad = &vhd->pysig->args[a];
7635 
7636         if (isOutArg(ad))
7637         {
7638             generateParseResultExtraArgs(mod, ad, a, fp);
7639             prcode(fp, ", %s%a", (isReference(ad) ? "&" : ""), mod, ad, a);
7640         }
7641     }
7642 
7643     prcode(fp, ");\n"
7644         );
7645 
7646     if (res != NULL)
7647     {
7648         if (res_isref || abortOnExceptionVH(vhd))
7649         {
7650             prcode(fp,
7651 "\n"
7652 "    if (sipRc < 0)\n"
7653                 );
7654 
7655             if (abortOnExceptionVH(vhd))
7656                 prcode(fp,
7657 "        abort();\n"
7658                     );
7659             else
7660                 generateDefaultInstanceReturn(res, "    ", fp);
7661         }
7662 
7663         prcode(fp,
7664 "\n"
7665 "    return %ssipRes;\n"
7666             , (res_isref ? "*" : ""));
7667     }
7668 
7669     prcode(fp,
7670 "}\n"
7671         );
7672 }
7673 
7674 
7675 /*
7676  * Generate the extra arguments needed by sipParseResultEx() for a particular
7677  * type.
7678  */
generateParseResultExtraArgs(moduleDef * mod,argDef * ad,int argnr,FILE * fp)7679 static void generateParseResultExtraArgs(moduleDef *mod, argDef *ad, int argnr,
7680         FILE *fp)
7681 {
7682     switch (ad->atype)
7683     {
7684     case mapped_type:
7685         prcode(fp, ", sipType_%T", ad);
7686         break;
7687 
7688     case class_type:
7689         prcode(fp, ", sipType_%C", classFQCName(ad->u.cd));
7690         break;
7691 
7692     case pytuple_type:
7693         prcode(fp,", &PyTuple_Type");
7694         break;
7695 
7696     case pylist_type:
7697         prcode(fp,", &PyList_Type");
7698         break;
7699 
7700     case pydict_type:
7701         prcode(fp,", &PyDict_Type");
7702         break;
7703 
7704     case pyslice_type:
7705         prcode(fp,", &PySlice_Type");
7706         break;
7707 
7708     case pytype_type:
7709         prcode(fp,", &PyType_Type");
7710         break;
7711 
7712     case enum_type:
7713         if (ad->u.ed->fqcname != NULL)
7714             prcode(fp, ", sipType_%C", ad->u.ed->fqcname);
7715         break;
7716 
7717     case capsule_type:
7718         prcode(fp,", \"%S\"", ad->u.cap);
7719         break;
7720 
7721     default:
7722         if (keepPyReference(ad))
7723         {
7724             if (argnr < 0)
7725                 prcode(fp, ", sipResKey");
7726             else
7727                 prcode(fp, ", %aKey", mod, ad, argnr);
7728         }
7729     }
7730 }
7731 
7732 
7733 /*
7734  * Return the format characters used by sipParseResultEx() for a particular
7735  * type.
7736  */
getParseResultFormat(argDef * ad,int res_isref,int xfervh)7737 static const char *getParseResultFormat(argDef *ad, int res_isref, int xfervh)
7738 {
7739     switch (ad->atype)
7740     {
7741     case mapped_type:
7742     case fake_void_type:
7743     case class_type:
7744         {
7745             static const char *type_formats[] = {
7746                 "H0", "H1", "H2", "H3", "H4", "H5", "H6", "H7"
7747             };
7748 
7749             int f = 0x00;
7750 
7751             if (ad->nrderefs == 0)
7752             {
7753                 f |= 0x01;
7754 
7755                 if (!res_isref)
7756                     f |= 0x04;
7757             }
7758             else if (ad->nrderefs == 1)
7759             {
7760                 if (isOutArg(ad))
7761                     f |= 0x04;
7762                 else if (isDisallowNone(ad))
7763                     f |= 0x01;
7764             }
7765 
7766             if (xfervh)
7767                 f |= 0x02;
7768 
7769             return type_formats[f];
7770         }
7771 
7772     case bool_type:
7773     case cbool_type:
7774         return "b";
7775 
7776     case ascii_string_type:
7777         return ((ad->nrderefs == 0) ? "aA" : "AA");
7778 
7779     case latin1_string_type:
7780         return ((ad->nrderefs == 0) ? "aL" : "AL");
7781 
7782     case utf8_string_type:
7783         return ((ad->nrderefs == 0) ? "a8" : "A8");
7784 
7785     case sstring_type:
7786     case ustring_type:
7787     case string_type:
7788         return ((ad->nrderefs == 0) ? "c" : "B");
7789 
7790     case wstring_type:
7791         return ((ad->nrderefs == 0) ? "w" : "x");
7792 
7793     case enum_type:
7794         return ((ad->u.ed->fqcname != NULL) ? "F" : "e");
7795 
7796     case byte_type:
7797         /*
7798          * Note that this assumes that char is signed.  We should not make that
7799          * assumption.
7800          */
7801 
7802     case sbyte_type:
7803         return "L";
7804 
7805     case ubyte_type:
7806         return "M";
7807 
7808     case ushort_type:
7809         return "t";
7810 
7811     case short_type:
7812         return "h";
7813 
7814     case int_type:
7815     case cint_type:
7816         return "i";
7817 
7818     case uint_type:
7819         return "u";
7820 
7821     case size_type:
7822         return "=";
7823 
7824     case long_type:
7825         return "l";
7826 
7827     case ulong_type:
7828         return "m";
7829 
7830     case longlong_type:
7831         return "n";
7832 
7833     case ulonglong_type:
7834         return "o";
7835 
7836     case void_type:
7837     case struct_type:
7838         return "V";
7839 
7840     case capsule_type:
7841         return "z";
7842 
7843     case float_type:
7844     case cfloat_type:
7845         return "f";
7846 
7847     case double_type:
7848     case cdouble_type:
7849         return "d";
7850 
7851     case pyobject_type:
7852         return "O";
7853 
7854     case pytuple_type:
7855     case pylist_type:
7856     case pydict_type:
7857     case pyslice_type:
7858     case pytype_type:
7859         return (isAllowNone(ad) ? "N" : "T");
7860 
7861     case pybuffer_type:
7862         return (isAllowNone(ad) ? "$" : "!");
7863 
7864     /* Supress a compiler warning. */
7865     default:
7866         ;
7867     }
7868 
7869     /* We should never get here. */
7870     return " ";
7871 }
7872 
7873 
7874 /*
7875  * Generate the code to build a tuple of Python arguments.
7876  */
generateTupleBuilder(moduleDef * mod,signatureDef * sd,FILE * fp)7877 static void generateTupleBuilder(moduleDef *mod, signatureDef *sd,FILE *fp)
7878 {
7879     int a, arraylenarg;
7880 
7881     /* Suppress a compiler warning. */
7882     arraylenarg = 0;
7883 
7884     prcode(fp,"\"");
7885 
7886     for (a = 0; a < sd->nrArgs; ++a)
7887     {
7888         char *fmt = "";
7889         argDef *ad = &sd->args[a];
7890 
7891         if (!isInArg(ad))
7892             continue;
7893 
7894         switch (ad->atype)
7895         {
7896         case ascii_string_type:
7897         case latin1_string_type:
7898         case utf8_string_type:
7899             if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad)))
7900                 fmt = "a";
7901             else
7902                 fmt = "A";
7903 
7904             break;
7905 
7906         case sstring_type:
7907         case ustring_type:
7908         case string_type:
7909             if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad)))
7910                 fmt = "c";
7911             else if (isArray(ad))
7912                 fmt = "g";
7913             else
7914                 fmt = "s";
7915 
7916             break;
7917 
7918         case wstring_type:
7919             if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad)))
7920                 fmt = "w";
7921             else if (isArray(ad))
7922                 fmt = "G";
7923             else
7924                 fmt = "x";
7925 
7926             break;
7927 
7928         case bool_type:
7929         case cbool_type:
7930             fmt = "b";
7931             break;
7932 
7933         case enum_type:
7934             fmt = (ad->u.ed->fqcname != NULL) ? "F" : "e";
7935             break;
7936 
7937         case cint_type:
7938             fmt = "i";
7939             break;
7940 
7941         case uint_type:
7942             if (isArraySize(ad))
7943                 arraylenarg = a;
7944             else
7945                 fmt = "u";
7946 
7947             break;
7948 
7949         case int_type:
7950             if (isArraySize(ad))
7951                 arraylenarg = a;
7952             else
7953                 fmt = "i";
7954 
7955             break;
7956 
7957         case size_type:
7958             if (isArraySize(ad))
7959                 arraylenarg = a;
7960             else
7961                 fmt = "=";
7962 
7963             break;
7964 
7965         case byte_type:
7966         case sbyte_type:
7967             if (isArraySize(ad))
7968                 arraylenarg = a;
7969             else
7970                 fmt = "L";
7971 
7972             break;
7973 
7974         case ubyte_type:
7975             if (isArraySize(ad))
7976                 arraylenarg = a;
7977             else
7978                 fmt = "M";
7979 
7980             break;
7981 
7982         case ushort_type:
7983             if (isArraySize(ad))
7984                 arraylenarg = a;
7985             else
7986                 fmt = "t";
7987 
7988             break;
7989 
7990         case short_type:
7991             if (isArraySize(ad))
7992                 arraylenarg = a;
7993             else
7994                 fmt = "h";
7995 
7996             break;
7997 
7998         case long_type:
7999             if (isArraySize(ad))
8000                 arraylenarg = a;
8001             else
8002                 fmt = "l";
8003 
8004             break;
8005 
8006         case ulong_type:
8007             if (isArraySize(ad))
8008                 arraylenarg = a;
8009             else
8010                 fmt = "m";
8011 
8012             break;
8013 
8014         case longlong_type:
8015             if (isArraySize(ad))
8016                 arraylenarg = a;
8017             else
8018                 fmt = "n";
8019 
8020             break;
8021 
8022         case ulonglong_type:
8023             if (isArraySize(ad))
8024                 arraylenarg = a;
8025             else
8026                 fmt = "o";
8027 
8028             break;
8029 
8030         case struct_type:
8031         case void_type:
8032             fmt = "V";
8033             break;
8034 
8035         case capsule_type:
8036             fmt = "z";
8037             break;
8038 
8039         case float_type:
8040         case cfloat_type:
8041             fmt = "f";
8042             break;
8043 
8044         case double_type:
8045         case cdouble_type:
8046             fmt = "d";
8047             break;
8048 
8049         case mapped_type:
8050         case class_type:
8051             if (isArray(ad))
8052             {
8053                 fmt = "r";
8054                 break;
8055             }
8056 
8057             if (needsHeapCopy(ad, TRUE))
8058             {
8059                 fmt = "N";
8060                 break;
8061             }
8062 
8063             /* Drop through. */
8064 
8065         case fake_void_type:
8066             fmt = "D";
8067             break;
8068 
8069         case pyobject_type:
8070         case pytuple_type:
8071         case pylist_type:
8072         case pydict_type:
8073         case pycallable_type:
8074         case pyslice_type:
8075         case pytype_type:
8076         case pybuffer_type:
8077             fmt = "S";
8078             break;
8079 
8080         /* Suppress a compiler warning. */
8081         default:
8082             ;
8083         }
8084 
8085         prcode(fp,fmt);
8086     }
8087 
8088     prcode(fp,"\"");
8089 
8090     for (a = 0; a < sd->nrArgs; ++a)
8091     {
8092         int derefs;
8093         argDef *ad = &sd->args[a];
8094 
8095         if (!isInArg(ad))
8096             continue;
8097 
8098         derefs = ad->nrderefs;
8099 
8100         switch (ad->atype)
8101         {
8102         case ascii_string_type:
8103         case latin1_string_type:
8104         case utf8_string_type:
8105         case sstring_type:
8106         case ustring_type:
8107         case string_type:
8108         case wstring_type:
8109             if (!(ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad))))
8110                 --derefs;
8111 
8112             break;
8113 
8114         case mapped_type:
8115         case fake_void_type:
8116         case class_type:
8117             if (ad->nrderefs > 0)
8118                 --derefs;
8119 
8120             break;
8121 
8122         case struct_type:
8123         case void_type:
8124             --derefs;
8125             break;
8126 
8127         /* Supress a compiler warning. */
8128         default:
8129             ;
8130         }
8131 
8132         if (ad->atype == mapped_type || ad->atype == class_type ||
8133             ad->atype == fake_void_type)
8134         {
8135             int copy = needsHeapCopy(ad, TRUE);
8136 
8137             prcode(fp,", ");
8138 
8139             if (copy)
8140             {
8141                 prcode(fp,"new %b(",ad);
8142             }
8143             else
8144             {
8145                 if (isConstArg(ad))
8146                     prcode(fp, "const_cast<%D *>(", ad);
8147 
8148                 if (ad->nrderefs == 0)
8149                     prcode(fp,"&");
8150                 else
8151                     while (derefs-- != 0)
8152                         prcode(fp,"*");
8153             }
8154 
8155             prcode(fp, "%a", mod, ad, a);
8156 
8157             if (copy || isConstArg(ad))
8158                 prcode(fp,")");
8159 
8160             if (isArray(ad))
8161                 prcode(fp, ", (Py_ssize_t)%a", mod, &sd->args[arraylenarg], arraylenarg);
8162 
8163             if (ad->atype == mapped_type)
8164                 prcode(fp, ", sipType_%T", ad);
8165             else if (ad->atype == fake_void_type || ad->atype == class_type)
8166                 prcode(fp, ", sipType_%C", classFQCName(ad->u.cd));
8167             else
8168                 prcode(fp,", sipType_QObject");
8169 
8170             if (!isArray(ad))
8171                 prcode(fp, ", SIP_NULLPTR");
8172         }
8173         else if (ad->atype == capsule_type)
8174         {
8175             prcode(fp, ", \"%S\"", ad->u.cap);
8176         }
8177         else
8178         {
8179             if (!isArraySize(ad))
8180             {
8181                 prcode(fp, ", ");
8182 
8183                 while (derefs-- != 0)
8184                     prcode(fp, "*");
8185 
8186                 prcode(fp, "%a", mod, ad, a);
8187             }
8188 
8189             if (isArray(ad))
8190                 prcode(fp, ", (Py_ssize_t)%a", mod, &sd->args[arraylenarg], arraylenarg);
8191             else if (ad->atype == enum_type && ad->u.ed->fqcname != NULL)
8192                 prcode(fp, ", sipType_%C", ad->u.ed->fqcname);
8193         }
8194     }
8195 }
8196 
8197 
8198 /*
8199  * Generate the library header #include directives required by either a class
8200  * or a module.
8201  */
generateUsedIncludes(ifaceFileList * iffl,FILE * fp)8202 static void generateUsedIncludes(ifaceFileList *iffl, FILE *fp)
8203 {
8204     prcode(fp,
8205 "\n"
8206         );
8207 
8208     while (iffl != NULL)
8209     {
8210         generateCppCodeBlock(iffl->iff->hdrcode, fp);
8211         iffl = iffl->next;
8212     }
8213 }
8214 
8215 
8216 /*
8217  * Generate the API details for a module.
8218  */
generateModuleAPI(sipSpec * pt,moduleDef * mod,FILE * fp)8219 static void generateModuleAPI(sipSpec *pt, moduleDef *mod, FILE *fp)
8220 {
8221     int no_exceptions = TRUE;
8222     classDef *cd;
8223     mappedTypeDef *mtd;
8224     exceptionDef *xd;
8225     virtErrorHandler *veh;
8226 
8227     for (cd = pt->classes; cd != NULL; cd = cd->next)
8228         if (cd->iff->module == mod)
8229             generateClassAPI(cd, pt, fp);
8230 
8231     for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
8232         if (mtd->iff->module == mod)
8233             generateMappedTypeAPI(pt, mtd, fp);
8234 
8235     for (xd = pt->exceptions; xd != NULL; xd = xd->next)
8236         if (xd->iff->module == mod && xd->exceptionnr >= 0)
8237         {
8238             if (no_exceptions)
8239             {
8240                 prcode(fp,
8241 "\n"
8242 "/* The exceptions defined in this module. */\n"
8243 "extern PyObject *sipExportedExceptions_%s[];\n"
8244 "\n"
8245                     , mod->name);
8246             }
8247 
8248             prcode(fp,
8249 "#define sipException_%C sipExportedExceptions_%s[%d]\n"
8250                 , xd->iff->fqcname, mod->name, xd->exceptionnr);
8251         }
8252 
8253     generateEnumMacros(pt, mod, NULL, NULL, fp);
8254 
8255     for (veh = pt->errorhandlers; veh != NULL; veh = veh->next)
8256         if (veh->mod == mod)
8257             prcode(fp,
8258 "\n"
8259 "void sipVEH_%s_%s(sipSimpleWrapper *, sip_gilstate_t);\n"
8260                 , mod->name, veh->name);
8261 }
8262 
8263 
8264 /*
8265  * Generate the API details for an imported module.
8266  */
generateImportedModuleAPI(sipSpec * pt,moduleDef * mod,moduleDef * immod,FILE * fp)8267 static void generateImportedModuleAPI(sipSpec *pt, moduleDef *mod,
8268         moduleDef *immod, FILE *fp)
8269 {
8270     classDef *cd;
8271     mappedTypeDef *mtd;
8272     exceptionDef *xd;
8273 
8274     for (cd = pt->classes; cd != NULL; cd = cd->next)
8275         if (cd->iff->module == immod)
8276         {
8277             if (cd->iff->needed)
8278                 generateImportedClassAPI(cd, mod, fp);
8279 
8280             generateEnumMacros(pt, mod, cd, NULL, fp);
8281         }
8282 
8283     for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
8284         if (mtd->iff->module == immod)
8285         {
8286             if (mtd->iff->needed)
8287                 generateImportedMappedTypeAPI(mtd, mod, fp);
8288 
8289             generateEnumMacros(pt, mod, NULL, mtd, fp);
8290         }
8291 
8292     for (xd = pt->exceptions; xd != NULL; xd = xd->next)
8293         if (xd->iff->module == immod && xd->exceptionnr >= 0)
8294                 prcode(fp,
8295 "\n"
8296 "#define sipException_%C sipImportedExceptions_%s_%s[%d].iexc_object\n"
8297                     , xd->iff->fqcname, mod->name, xd->iff->module->name, xd->exceptionnr);
8298 
8299     generateEnumMacros(pt, mod, NULL, NULL, fp);
8300 }
8301 
8302 
8303 /*
8304  * Generate the API details for an imported mapped type.  This will only be
8305  * called for the first API implementation.
8306  */
generateImportedMappedTypeAPI(mappedTypeDef * mtd,moduleDef * mod,FILE * fp)8307 static void generateImportedMappedTypeAPI(mappedTypeDef *mtd, moduleDef *mod,
8308         FILE *fp)
8309 {
8310     const char *mname = mod->name;
8311     const char *imname = mtd->iff->module->name;
8312     argDef type;
8313 
8314     memset(&type, 0, sizeof (argDef));
8315 
8316     type.atype = mapped_type;
8317     type.u.mtd = mtd;
8318 
8319     prcode(fp,
8320 "\n"
8321 "#define sipType_%T sipImportedTypes_%s_%s[%d].it_td\n"
8322         , &type, mname, imname, mtd->iff->ifacenr);
8323 }
8324 
8325 
8326 /*
8327  * Generate the API details for a mapped type.
8328  */
generateMappedTypeAPI(sipSpec * pt,mappedTypeDef * mtd,FILE * fp)8329 static void generateMappedTypeAPI(sipSpec *pt, mappedTypeDef *mtd, FILE *fp)
8330 {
8331     argDef type;
8332 
8333     memset(&type, 0, sizeof (argDef));
8334 
8335     type.atype = mapped_type;
8336     type.u.mtd = mtd;
8337 
8338     if (mtd->iff->first_alt == mtd->iff)
8339         prcode(fp,
8340 "\n"
8341 "#define sipType_%T sipExportedTypes_%s[%d]\n"
8342             , &type, mtd->iff->module->name, mtd->iff->ifacenr);
8343 
8344     prcode(fp,
8345 "\n"
8346 "extern sipMappedTypeDef sipTypeDef_%s_%L;\n"
8347         , mtd->iff->module->name, mtd->iff);
8348 
8349     generateEnumMacros(pt, mtd->iff->module, NULL, mtd, fp);
8350 }
8351 
8352 
8353 /*
8354  * Generate the API details for an imported class.  This will only be called
8355  * for the first API implementation.
8356  */
generateImportedClassAPI(classDef * cd,moduleDef * mod,FILE * fp)8357 static void generateImportedClassAPI(classDef *cd, moduleDef *mod, FILE *fp)
8358 {
8359     const char *mname = mod->name;
8360     const char *imname = cd->iff->module->name;
8361 
8362     prcode(fp,
8363 "\n"
8364         );
8365 
8366     if (cd->iff->type == namespace_iface)
8367         prcode(fp,
8368 "#if !defined(sipType_%L)\n"
8369             , cd->iff);
8370 
8371     prcode(fp,
8372 "#define sipType_%C sipImportedTypes_%s_%s[%d].it_td\n"
8373         , classFQCName(cd), mname, imname, cd->iff->ifacenr);
8374 
8375     if (cd->iff->type == namespace_iface)
8376         prcode(fp,
8377 "#endif\n"
8378             );
8379 }
8380 
8381 
8382 /*
8383  * Generate the C++ API for a class.
8384  */
generateClassAPI(classDef * cd,sipSpec * pt,FILE * fp)8385 static void generateClassAPI(classDef *cd, sipSpec *pt, FILE *fp)
8386 {
8387     const char *mname = cd->iff->module->name;
8388 
8389     prcode(fp,
8390 "\n"
8391             );
8392 
8393     if (cd->real == NULL && cd->iff->first_alt == cd->iff && !isHiddenNamespace(cd))
8394         prcode(fp,
8395 "#define sipType_%C sipExportedTypes_%s[%d]\n"
8396             , classFQCName(cd), mname, cd->iff->ifacenr);
8397 
8398     generateEnumMacros(pt, cd->iff->module, cd, NULL, fp);
8399 
8400     if (!isExternal(cd) && !isHiddenNamespace(cd))
8401     {
8402         prcode(fp,
8403 "\n"
8404 "extern sipClassTypeDef sipTypeDef_%s_%L;\n"
8405             , mname, cd->iff);
8406 
8407         if (isExportDerived(cd))
8408         {
8409             generateCppCodeBlock(cd->iff->hdrcode, fp);
8410             generateShadowClassDeclaration(pt, cd, fp);
8411         }
8412     }
8413 }
8414 
8415 
8416 /*
8417  * Generate the type macros for enums.
8418  */
generateEnumMacros(sipSpec * pt,moduleDef * mod,classDef * cd,mappedTypeDef * mtd,FILE * fp)8419 static void generateEnumMacros(sipSpec *pt, moduleDef *mod, classDef *cd,
8420         mappedTypeDef *mtd, FILE *fp)
8421 {
8422     enumDef *ed;
8423 
8424     for (ed = pt->enums; ed != NULL; ed = ed->next)
8425     {
8426         if (ed->fqcname == NULL)
8427             continue;
8428 
8429         if (ed->first_alt != ed)
8430             continue;
8431 
8432         if (cd != NULL)
8433         {
8434             if (ed->ecd != cd)
8435                 continue;
8436         }
8437         else if (mtd != NULL)
8438         {
8439             if (ed->emtd != mtd)
8440                 continue;
8441         }
8442         else if (ed->ecd != NULL || ed->emtd != NULL)
8443         {
8444             continue;
8445         }
8446 
8447         if (mod == ed->module)
8448             prcode(fp,
8449 "\n"
8450 "#define sipType_%C sipExportedTypes_%s[%d]\n"
8451                 , ed->fqcname, mod->name, ed->enumnr);
8452         else if (needsEnum(ed))
8453             prcode(fp,
8454 "\n"
8455 "#define sipType_%C sipImportedTypes_%s_%s[%d].it_td\n"
8456                 , ed->fqcname, mod->name, ed->module->name, ed->enumnr);
8457     }
8458 }
8459 
8460 
8461 /*
8462  * Generate the shadow class declaration.
8463  */
generateShadowClassDeclaration(sipSpec * pt,classDef * cd,FILE * fp)8464 static void generateShadowClassDeclaration(sipSpec *pt,classDef *cd,FILE *fp)
8465 {
8466     int noIntro, nrVirts;
8467     ctorDef *ct;
8468     virtOverDef *vod;
8469     classDef *pcd;
8470 
8471     prcode(fp,
8472 "\n"
8473 "\n"
8474 "class sip%C : public %U\n"
8475 "{\n"
8476 "public:\n"
8477         , classFQCName(cd), cd);
8478 
8479     /* Define a shadow class for any protected classes we have. */
8480 
8481     for (pcd = pt->classes; pcd != NULL; pcd = pcd->next)
8482     {
8483         mroDef *mro;
8484 
8485         if (!isProtectedClass(pcd))
8486             continue;
8487 
8488         /* See if the class defining the class is in our class hierachy. */
8489         for (mro = cd->mro; mro != NULL; mro = mro->next)
8490             if (mro->cd == pcd->ecd)
8491                 break;
8492 
8493         if (mro == NULL)
8494             continue;
8495 
8496         prcode(fp,
8497 "    class sip%s : public %s {\n"
8498 "    public:\n"
8499                 , classBaseName(pcd), classBaseName(pcd));
8500 
8501         generateProtectedEnums(pt, pcd, fp);
8502 
8503         prcode(fp,
8504 "    };\n"
8505 "\n"
8506                 );
8507     }
8508 
8509     /* The constructor declarations. */
8510 
8511     for (ct = cd->ctors; ct != NULL; ct = ct->next)
8512     {
8513         ctorDef *dct;
8514 
8515         if (isPrivateCtor(ct))
8516             continue;
8517 
8518         if (ct->cppsig == NULL)
8519             continue;
8520 
8521         /* Check we haven't already handled this C++ signature. */
8522         for (dct = cd->ctors; dct != ct; dct = dct->next)
8523             if (dct->cppsig != NULL && sameSignature(dct->cppsig, ct->cppsig, TRUE))
8524                 break;
8525 
8526         if (dct != ct)
8527             continue;
8528 
8529         prcode(fp,
8530 "    sip%C(",classFQCName(cd));
8531 
8532         generateCalledArgs(NULL, cd->iff, ct->cppsig, Declaration, fp);
8533 
8534         prcode(fp,")%X;\n"
8535             ,ct->exceptions);
8536     }
8537 
8538     /* The destructor. */
8539 
8540     if (!isPrivateDtor(cd))
8541         prcode(fp,
8542 "    %s~sip%C()%X;\n"
8543             ,(cd->vmembers != NULL ? "virtual " : ""),classFQCName(cd),cd->dtorexceptions);
8544 
8545     /* The metacall methods if required. */
8546     if (pluginPyQt5(pt) && isQObjectSubClass(cd))
8547     {
8548         prcode(fp,
8549 "\n"
8550 "    int qt_metacall(QMetaObject::Call, int, void **) SIP_OVERRIDE;\n"
8551 "    void *qt_metacast(const char *) SIP_OVERRIDE;\n"
8552             );
8553 
8554         if (!noPyQtQMetaObject(cd))
8555             prcode(fp,
8556 "    const QMetaObject *metaObject() const SIP_OVERRIDE;\n"
8557                 );
8558     }
8559 
8560     /* The exposure of protected enums. */
8561 
8562     generateProtectedEnums(pt,cd,fp);
8563 
8564     /* The wrapper around each protected member function. */
8565 
8566     generateProtectedDeclarations(cd,fp);
8567 
8568     /* The catcher around each virtual function in the hierarchy. */
8569     noIntro = TRUE;
8570 
8571     for (vod = cd->vmembers; vod != NULL; vod = vod->next)
8572     {
8573         overDef *od = vod->od;
8574         virtOverDef *dvod;
8575 
8576         if (isPrivate(od))
8577             continue;
8578 
8579         /* Check we haven't already handled this C++ signature. */
8580         for (dvod = cd->vmembers; dvod != vod; dvod = dvod->next)
8581             if (strcmp(dvod->od->cppname,od->cppname) == 0 && sameSignature(dvod->od->cppsig,od->cppsig,TRUE))
8582                 break;
8583 
8584         if (dvod != vod)
8585             continue;
8586 
8587         if (noIntro)
8588         {
8589             prcode(fp,
8590 "\n"
8591 "    /*\n"
8592 "     * There is a protected method for every virtual method visible from\n"
8593 "     * this class.\n"
8594 "     */\n"
8595 "protected:\n"
8596                 );
8597 
8598             noIntro = FALSE;
8599         }
8600 
8601         prcode(fp,
8602 "    ");
8603 
8604         generateOverloadDecl(fp, cd->iff, od);
8605         prcode(fp, ";\n");
8606     }
8607 
8608     prcode(fp,
8609 "\n"
8610 "public:\n"
8611 "    sipSimpleWrapper *sipPySelf;\n"
8612         );
8613 
8614     /* The private declarations. */
8615 
8616     prcode(fp,
8617 "\n"
8618 "private:\n"
8619 "    sip%C(const sip%C &);\n"
8620 "    sip%C &operator = (const sip%C &);\n"
8621         ,classFQCName(cd),classFQCName(cd)
8622         ,classFQCName(cd),classFQCName(cd));
8623 
8624     if ((nrVirts = countVirtuals(cd)) > 0)
8625         prcode(fp,
8626 "\n"
8627 "    char sipPyMethods[%d];\n"
8628             ,nrVirts);
8629 
8630     prcode(fp,
8631 "};\n"
8632         );
8633 }
8634 
8635 
8636 /*
8637  * Generate the C++ declaration for an overload.
8638  */
generateOverloadDecl(FILE * fp,ifaceFileDef * scope,overDef * od)8639 static void generateOverloadDecl(FILE *fp, ifaceFileDef *scope, overDef *od)
8640 {
8641     int a;
8642 
8643     normaliseArgs(od->cppsig);
8644 
8645     generateBaseType(scope, &od->cppsig->result, TRUE, STRIP_NONE, fp);
8646 
8647     prcode(fp, " %O(", od);
8648 
8649     for (a = 0; a < od->cppsig->nrArgs; ++a)
8650     {
8651         argDef *ad = &od->cppsig->args[a];
8652 
8653         if (a > 0)
8654             prcode(fp, ",");
8655 
8656         generateBaseType(scope, ad, TRUE, STRIP_NONE, fp);
8657     }
8658 
8659     prcode(fp, ")%s%X SIP_OVERRIDE", (isConst(od) ? " const" : ""), od->exceptions);
8660 
8661     restoreArgs(od->cppsig);
8662 }
8663 
8664 
8665 /*
8666  * Generate typed arguments for a declaration or a definition.
8667  */
generateCalledArgs(moduleDef * mod,ifaceFileDef * scope,signatureDef * sd,funcArgType ftype,FILE * fp)8668 static void generateCalledArgs(moduleDef *mod, ifaceFileDef *scope,
8669         signatureDef *sd, funcArgType ftype, FILE *fp)
8670 {
8671     const char *name;
8672     char buf[50];
8673     int a;
8674 
8675     for (a = 0; a < sd->nrArgs; ++a)
8676     {
8677         argDef *ad = &sd->args[a];
8678 
8679         if (a > 0)
8680             prcode(fp,",");
8681 
8682         name = buf;
8683 
8684         if (ftype == Definition)
8685         {
8686             if (mod != NULL && useArgNames(mod) && ad->name != NULL)
8687                 name = ad->name->text;
8688             else
8689                 sprintf(buf, "a%d", a);
8690         }
8691         else
8692         {
8693             buf[0] = '\0';
8694         }
8695 
8696         generateNamedBaseType(scope, ad, name, TRUE, STRIP_NONE, fp);
8697     }
8698 }
8699 
8700 
8701 /*
8702  * Generate typed arguments for a call.
8703  */
generateCallArgs(moduleDef * mod,signatureDef * sd,signatureDef * py_sd,FILE * fp)8704 static void generateCallArgs(moduleDef *mod, signatureDef *sd,
8705         signatureDef *py_sd, FILE *fp)
8706 {
8707     int a;
8708 
8709     for (a = 0; a < sd->nrArgs; ++a)
8710     {
8711         char *ind = NULL;
8712         argDef *ad, *py_ad;
8713 
8714         if (a > 0)
8715             prcode(fp,",");
8716 
8717         ad = &sd->args[a];
8718 
8719         /* See if the argument needs dereferencing or it's address taking. */
8720         switch (ad->atype)
8721         {
8722         case ascii_string_type:
8723         case latin1_string_type:
8724         case utf8_string_type:
8725         case sstring_type:
8726         case ustring_type:
8727         case string_type:
8728         case wstring_type:
8729             if (ad->nrderefs > (isOutArg(ad) ? 0 : 1) && !isReference(ad))
8730                 ind = "&";
8731 
8732             break;
8733 
8734         case mapped_type:
8735         case class_type:
8736             if (ad->nrderefs == 2)
8737                 ind = "&";
8738             else if (ad->nrderefs == 0)
8739                 ind = "*";
8740 
8741             break;
8742 
8743         case struct_type:
8744         case void_type:
8745             if (ad->nrderefs == 2)
8746                 ind = "&";
8747 
8748             break;
8749 
8750         default:
8751             if (ad->nrderefs == 1)
8752                 ind = "&";
8753         }
8754 
8755         /*
8756          * See if we need to cast a Python void * to the correct C/C++ pointer
8757          * type.
8758          */
8759         if (py_sd != sd)
8760         {
8761             py_ad = &py_sd->args[a];
8762 
8763             if ((py_ad->atype != void_type && py_ad->atype != capsule_type) || ad->atype == void_type || ad->atype == capsule_type || py_ad->nrderefs != ad->nrderefs)
8764                 py_ad = NULL;
8765         }
8766         else
8767             py_ad = NULL;
8768 
8769         if (py_ad == NULL)
8770         {
8771             if (ind != NULL)
8772                 prcode(fp, ind);
8773 
8774             if (isArraySize(ad))
8775                 prcode(fp, "(%b)", ad);
8776 
8777             prcode(fp, "%a", mod, ad, a);
8778         }
8779         else if (generating_c)
8780             prcode(fp, "(%b *)%a", ad, mod, ad, a);
8781         else
8782             prcode(fp, "reinterpret_cast<%b *>(%a)", ad, mod, ad, a);
8783     }
8784 }
8785 
8786 
8787 /*
8788  * Generate the declaration of a named variable to hold a result from a C++
8789  * function call.
8790  */
generateNamedValueType(ifaceFileDef * scope,argDef * ad,char * name,FILE * fp)8791 static void generateNamedValueType(ifaceFileDef *scope, argDef *ad,
8792         char *name, FILE *fp)
8793 {
8794     argDef mod = *ad;
8795 
8796     if (ad->nrderefs == 0)
8797     {
8798         if (ad->atype == class_type || ad->atype == mapped_type)
8799             mod.nrderefs = 1;
8800         else
8801             resetIsConstArg(&mod);
8802     }
8803 
8804     resetIsReference(&mod);
8805     generateNamedBaseType(scope, &mod, name, TRUE, STRIP_NONE, fp);
8806 }
8807 
8808 
8809 /*
8810  * Generate a C++ type.
8811  */
generateBaseType(ifaceFileDef * scope,argDef * ad,int use_typename,int strip,FILE * fp)8812 void generateBaseType(ifaceFileDef *scope, argDef *ad, int use_typename,
8813         int strip, FILE *fp)
8814 {
8815     generateNamedBaseType(scope, ad, "", use_typename, strip, fp);
8816 }
8817 
8818 
8819 /*
8820  * Generate a C++ type and name.
8821  */
generateNamedBaseType(ifaceFileDef * scope,argDef * ad,const char * name,int use_typename,int strip,FILE * fp)8822 static void generateNamedBaseType(ifaceFileDef *scope, argDef *ad,
8823         const char *name, int use_typename, int strip, FILE *fp)
8824 {
8825     typedefDef *td = ad->original_type;
8826     int nr_derefs = ad->nrderefs;
8827     int is_reference = isReference(ad);
8828     int i, space_before_name;
8829 
8830     if (use_typename && td != NULL && !noTypeName(td) && !isArraySize(ad))
8831     {
8832         if (isConstArg(ad) && !isConstArg(&td->type))
8833             prcode(fp, "const ");
8834 
8835         nr_derefs -= td->type.nrderefs;
8836 
8837         if (isReference(&td->type))
8838             is_reference = FALSE;
8839 
8840         prcode(fp, "%S", stripScope(td->fqname, strip));
8841     }
8842     else
8843     {
8844         /*
8845          * A function type is handled differently because of the position of
8846          * the name.
8847          */
8848         if (ad->atype == function_type)
8849         {
8850             signatureDef *sig = ad->u.sa;
8851 
8852             generateBaseType(scope, &sig->result, TRUE, strip, fp);
8853 
8854             prcode(fp," (");
8855 
8856             for (i = 0; i < nr_derefs; ++i)
8857                 prcode(fp, "*");
8858 
8859             prcode(fp, "%s)(",name);
8860             generateCalledArgs(NULL, scope, sig, Declaration, fp);
8861             prcode(fp, ")");
8862 
8863             return;
8864         }
8865 
8866         if (isConstArg(ad))
8867             prcode(fp, "const ");
8868 
8869         switch (ad->atype)
8870         {
8871         case sbyte_type:
8872         case sstring_type:
8873             prcode(fp, "signed char");
8874             break;
8875 
8876         case ubyte_type:
8877         case ustring_type:
8878             prcode(fp, "unsigned char");
8879             break;
8880 
8881         case wstring_type:
8882             prcode(fp, "wchar_t");
8883             break;
8884 
8885         case byte_type:
8886         case ascii_string_type:
8887         case latin1_string_type:
8888         case utf8_string_type:
8889         case string_type:
8890             prcode(fp, "char");
8891             break;
8892 
8893         case ushort_type:
8894             prcode(fp, "unsigned short");
8895             break;
8896 
8897         case short_type:
8898             prcode(fp, "short");
8899             break;
8900 
8901         case uint_type:
8902             /*
8903              * Qt4 moc uses "uint" in signal signatures.  We do all the time
8904              * and hope it is always defined.
8905              */
8906             prcode(fp, "uint");
8907             break;
8908 
8909         case int_type:
8910         case cint_type:
8911             prcode(fp, "int");
8912             break;
8913 
8914         case ssize_type:
8915             prcode(fp, "Py_ssize_t");
8916             break;
8917 
8918         case size_type:
8919             prcode(fp, "size_t");
8920             break;
8921 
8922         case ulong_type:
8923             prcode(fp, "unsigned long");
8924             break;
8925 
8926         case long_type:
8927             prcode(fp, "long");
8928             break;
8929 
8930         case ulonglong_type:
8931             prcode(fp, "unsigned PY_LONG_LONG");
8932             break;
8933 
8934         case longlong_type:
8935             prcode(fp, "PY_LONG_LONG");
8936             break;
8937 
8938         case struct_type:
8939             prcode(fp, "struct %S", ad->u.sname);
8940             break;
8941 
8942         case capsule_type:
8943             nr_derefs = 1;
8944 
8945             /* Drop through. */
8946 
8947         case fake_void_type:
8948         case void_type:
8949             prcode(fp, "void");
8950             break;
8951 
8952         case bool_type:
8953         case cbool_type:
8954             prcode(fp, "bool");
8955             break;
8956 
8957         case float_type:
8958         case cfloat_type:
8959             prcode(fp, "float");
8960             break;
8961 
8962         case double_type:
8963         case cdouble_type:
8964             prcode(fp, "double");
8965             break;
8966 
8967         case defined_type:
8968             /*
8969              * The only defined types still remaining are arguments to
8970              * templates and default values.
8971              */
8972             if (prcode_xml)
8973             {
8974                 prScopedName(fp, removeGlobalScope(ad->u.snd), ".");
8975             }
8976             else
8977             {
8978                 if (generating_c)
8979                     fprintf(fp, "struct ");
8980 
8981                 prScopedName(fp, stripScope(ad->u.snd, strip), "::");
8982             }
8983 
8984             break;
8985 
8986         case mapped_type:
8987             generateBaseType(scope, &ad->u.mtd->type, TRUE, strip, fp);
8988             break;
8989 
8990         case class_type:
8991             prScopedClassName(fp, scope, ad->u.cd, strip);
8992             break;
8993 
8994         case template_type:
8995 			prTemplateType(fp, scope, ad->u.td, strip);
8996 			break;
8997 
8998         case enum_type:
8999             {
9000                 enumDef *ed = ad->u.ed;
9001 
9002                 if (ed->fqcname == NULL || isProtectedEnum(ed))
9003                     fprintf(fp,"int");
9004                 else
9005                     prScopedName(fp, stripScope(ed->fqcname, strip), "::");
9006 
9007                 break;
9008             }
9009 
9010         case pyobject_type:
9011         case pytuple_type:
9012         case pylist_type:
9013         case pydict_type:
9014         case pycallable_type:
9015         case pyslice_type:
9016         case pytype_type:
9017         case pybuffer_type:
9018         case ellipsis_type:
9019             prcode(fp, "PyObject *");
9020             break;
9021 
9022         /* Supress a compiler warning. */
9023         default:
9024             ;
9025         }
9026     }
9027 
9028     space_before_name = TRUE;
9029 
9030     for (i = 0; i < nr_derefs; ++i)
9031     {
9032         /*
9033          * Note that we don't put a space before the '*' so that Qt normalised
9034          * signal signatures are correct.
9035          */
9036         prcode(fp, "*");
9037         space_before_name = FALSE;
9038 
9039         if (ad->derefs[i])
9040         {
9041             prcode(fp, " const");
9042             space_before_name = TRUE;
9043         }
9044     }
9045 
9046     if (is_reference)
9047         prcode(fp, (prcode_xml ? "&amp;" : "&"));
9048 
9049     if (*name != '\0')
9050     {
9051         if (space_before_name)
9052             prcode(fp, " ");
9053 
9054         prcode(fp, name);
9055     }
9056 }
9057 
9058 
9059 /*
9060  * Generate the definition of an argument variable and any supporting
9061  * variables.
9062  */
generateVariable(moduleDef * mod,ifaceFileDef * scope,argDef * ad,int argnr,FILE * fp)9063 static void generateVariable(moduleDef *mod, ifaceFileDef *scope, argDef *ad,
9064         int argnr, FILE *fp)
9065 {
9066     argType atype = ad->atype;
9067     argDef orig;
9068 
9069     if (isInArg(ad) && ad->defval != NULL &&
9070         (atype == class_type || atype == mapped_type) &&
9071         (ad->nrderefs == 0 || isReference(ad)))
9072     {
9073         /*
9074          * Generate something to hold the default value as it cannot be
9075          * assigned straight away.
9076          */
9077         prcode(fp,
9078 "        %A %adef = ", scope, ad, mod, ad, argnr);
9079 
9080         generateExpression(ad->defval, FALSE, fp);
9081 
9082         prcode(fp,";\n"
9083             );
9084     }
9085 
9086     /* Adjust the type so we have the type that will really handle it. */
9087 
9088     orig = *ad;
9089 
9090     switch (atype)
9091     {
9092     case ascii_string_type:
9093     case latin1_string_type:
9094     case utf8_string_type:
9095     case sstring_type:
9096     case ustring_type:
9097     case string_type:
9098     case wstring_type:
9099         if (!isReference(ad))
9100         {
9101             if (ad->nrderefs == 2)
9102                 ad->nrderefs = 1;
9103             else if (ad->nrderefs == 1 && isOutArg(ad))
9104                 ad->nrderefs = 0;
9105         }
9106 
9107         break;
9108 
9109     case mapped_type:
9110     case class_type:
9111     case void_type:
9112     case struct_type:
9113         ad->nrderefs = 1;
9114         break;
9115 
9116     default:
9117         ad->nrderefs = 0;
9118     }
9119 
9120     /* Array sizes are always Py_ssize_t. */
9121     if (isArraySize(ad))
9122         ad->atype = ssize_type;
9123 
9124     resetIsReference(ad);
9125 
9126     if (ad->nrderefs == 0)
9127         resetIsConstArg(ad);
9128 
9129     prcode(fp,
9130 "        %A %a", scope, ad, mod, ad, argnr);
9131 
9132     *ad = orig;
9133 
9134     generateDefaultValue(mod, ad, argnr, fp);
9135 
9136     prcode(fp,";\n"
9137         );
9138 
9139     /* Some types have supporting variables. */
9140     if (isInArg(ad))
9141     {
9142         if (isGetWrapper(ad))
9143             prcode(fp,
9144 "        PyObject *%aWrapper%s;\n"
9145                 , mod, ad, argnr, (ad->defval != NULL ? " = 0" : ""));
9146         else if (keepReference(ad))
9147             prcode(fp,
9148 "        PyObject *%aKeep%s;\n"
9149                 , mod, ad, argnr, (ad->defval != NULL ? " = 0" : ""));
9150 
9151         switch (atype)
9152         {
9153         case class_type:
9154             if (!isArray(ad) && ad->u.cd->convtocode != NULL && !isConstrained(ad))
9155                 prcode(fp,
9156 "        int %aState = 0;\n"
9157                     , mod, ad, argnr);
9158 
9159             break;
9160 
9161         case mapped_type:
9162             if (!noRelease(ad->u.mtd) && !isConstrained(ad))
9163                 prcode(fp,
9164 "        int %aState = 0;\n"
9165                     , mod, ad, argnr);
9166 
9167             break;
9168 
9169         case ascii_string_type:
9170         case latin1_string_type:
9171         case utf8_string_type:
9172             if (!keepReference(ad) && ad->nrderefs == 1)
9173                 prcode(fp,
9174 "        PyObject *%aKeep%s;\n"
9175                     , mod, ad, argnr, (ad->defval != NULL ? " = 0" : ""));
9176 
9177             break;
9178 
9179         /* Supress a compiler warning. */
9180         default:
9181             ;
9182         }
9183     }
9184 }
9185 
9186 
9187 /*
9188  * Generate a default value.
9189  */
generateDefaultValue(moduleDef * mod,argDef * ad,int argnr,FILE * fp)9190 static void generateDefaultValue(moduleDef *mod, argDef *ad, int argnr,
9191         FILE *fp)
9192 {
9193     if (isInArg(ad) && ad->defval != NULL)
9194     {
9195         prcode(fp," = ");
9196 
9197         if ((ad->atype == class_type || ad->atype == mapped_type) &&
9198                 (ad->nrderefs == 0 || isReference(ad)))
9199             prcode(fp, "&%adef", mod, ad, argnr);
9200         else
9201             generateExpression(ad->defval, FALSE, fp);
9202     }
9203 }
9204 
9205 
9206 /*
9207  * Generate a simple function call.
9208  */
generateSimpleFunctionCall(fcallDef * fcd,int in_str,FILE * fp)9209 static void generateSimpleFunctionCall(fcallDef *fcd, int in_str, FILE *fp)
9210 {
9211     int i;
9212 
9213     prcode(fp, "%B(", &fcd->type);
9214 
9215     for (i = 0; i < fcd->nrArgs; ++i)
9216     {
9217         if (i > 0)
9218             prcode(fp,",");
9219 
9220         generateExpression(fcd->args[i], in_str, fp);
9221     }
9222 
9223     prcode(fp,")");
9224 }
9225 
9226 
9227 /*
9228  * Generate the type structure that contains all the information needed by the
9229  * meta-type.  A sub-set of this is used to extend namespaces.
9230  */
generateTypeDefinition(sipSpec * pt,classDef * cd,int py_debug,FILE * fp)9231 static void generateTypeDefinition(sipSpec *pt, classDef *cd, int py_debug,
9232         FILE *fp)
9233 {
9234     const char *sep;
9235     int is_slots, nr_methods, nr_enums, nr_vars, plugin;
9236     int is_inst_class, is_inst_voidp, is_inst_char, is_inst_string;
9237     int is_inst_int, is_inst_long, is_inst_ulong, is_inst_longlong;
9238     int is_inst_ulonglong, is_inst_double, has_docstring;
9239     memberDef *md;
9240     moduleDef *mod;
9241     propertyDef *pd;
9242 
9243     mod = cd->iff->module;
9244 
9245     if (cd->supers != NULL)
9246     {
9247         classList *cl;
9248 
9249         prcode(fp,
9250 "\n"
9251 "\n"
9252 "/* Define this type's super-types. */\n"
9253 "static sipEncodedTypeDef supers_%C[] = {", classFQCName(cd));
9254 
9255         for (cl = cd->supers; cl != NULL; cl = cl->next)
9256         {
9257             if (cl != cd->supers)
9258                 prcode(fp, ", ");
9259 
9260             generateEncodedType(mod, cl->cd, (cl->next == NULL), fp);
9261         }
9262 
9263         prcode(fp,"};\n"
9264             );
9265     }
9266 
9267     /* Generate the slots table. */
9268     is_slots = FALSE;
9269 
9270     for (md = cd->members; md != NULL; md = md->next)
9271     {
9272         const char *stype;
9273 
9274         if (md->slot == no_slot)
9275             continue;
9276 
9277         if (!is_slots)
9278         {
9279             prcode(fp,
9280 "\n"
9281 "\n"
9282 "/* Define this type's Python slots. */\n"
9283 "static sipPySlotDef slots_%L[] = {\n"
9284                 , cd->iff);
9285 
9286             is_slots = TRUE;
9287         }
9288 
9289         if ((stype = slotName(md->slot)) != NULL)
9290         {
9291             prcode(fp,
9292 "    {(void *)slot_%L_%s, %s},\n"
9293                 , cd->iff, md->pyname->text, stype);
9294         }
9295     }
9296 
9297     if (is_slots)
9298         prcode(fp,
9299 "    {0, (sipPySlotType)0}\n"
9300 "};\n"
9301             );
9302 
9303     /* Generate the attributes tables. */
9304     nr_methods = generateClassMethodTable(pt, cd, fp);
9305     nr_enums = generateEnumMemberTable(pt, mod, cd, NULL, fp);
9306 
9307     /* Generate the property and variable handlers. */
9308     nr_vars = 0;
9309 
9310     if (hasVarHandlers(cd))
9311     {
9312         varDef *vd;
9313 
9314         for (vd = pt->vars; vd != NULL; vd = vd->next)
9315             if (vd->ecd == cd && needsHandler(vd))
9316             {
9317                 ++nr_vars;
9318 
9319                 generateVariableGetter(cd->iff, vd, fp);
9320 
9321                 if (canSetVariable(vd))
9322                     generateVariableSetter(cd->iff, vd, fp);
9323             }
9324     }
9325 
9326     /* Generate any docstrings. */
9327     for (pd = cd->properties; pd != NULL; pd = pd->next)
9328     {
9329         ++nr_vars;
9330 
9331         if (pd->docstring != NULL)
9332         {
9333             prcode(fp,
9334 "\n"
9335 "PyDoc_STRVAR(doc_%L_%s, \"" , cd->iff, pd->name->text);
9336 
9337             generateDocstringText(pd->docstring, fp);
9338 
9339             prcode(fp, "\");\n"
9340                 );
9341         }
9342     }
9343 
9344     /* Generate the variables table. */
9345     if (nr_vars > 0)
9346         prcode(fp,
9347 "\n"
9348 "sipVariableDef variables_%L[] = {\n"
9349             , cd->iff);
9350 
9351     for (pd = cd->properties; pd != NULL; pd = pd->next)
9352     {
9353         prcode(fp,
9354 "    {PropertyVariable, %N, &methods_%L[%d], ", pd->name, cd->iff, findMethod(cd, pd->get)->membernr);
9355 
9356         if (pd->set != NULL)
9357             prcode(fp, "&methods_%L[%d], ", cd->iff, findMethod(cd, pd->set)->membernr);
9358         else
9359             prcode(fp, "SIP_NULLPTR, ");
9360 
9361         /* We don't support a deleter yet. */
9362         prcode(fp, "SIP_NULLPTR, ");
9363 
9364         if (pd->docstring != NULL)
9365             prcode(fp, "doc_%L_%s", cd->iff, pd->name->text);
9366         else
9367             prcode(fp, "SIP_NULLPTR");
9368 
9369         prcode(fp, "},\n"
9370             );
9371     }
9372 
9373     if (hasVarHandlers(cd))
9374     {
9375         varDef *vd;
9376 
9377         for (vd = pt->vars; vd != NULL; vd = vd->next)
9378             if (vd->ecd == cd && needsHandler(vd))
9379             {
9380                 prcode(fp,
9381 "    {%s, %N, (PyMethodDef *)varget_%C, ", (isStaticVar(vd) ? "ClassVariable" : "InstanceVariable"), vd->pyname, vd->fqcname);
9382 
9383                 if (canSetVariable(vd))
9384                     prcode(fp, "(PyMethodDef *)varset_%C", vd->fqcname);
9385                 else
9386                     prcode(fp, "SIP_NULLPTR");
9387 
9388                 prcode(fp, ", SIP_NULLPTR, SIP_NULLPTR},\n"
9389                     );
9390             }
9391     }
9392 
9393     if (nr_vars > 0)
9394         prcode(fp,
9395 "};\n"
9396             );
9397 
9398     /* Generate each instance table. */
9399     is_inst_class = generateClasses(pt, mod, cd, fp);
9400     is_inst_voidp = generateVoidPointers(pt, mod, cd, fp);
9401     is_inst_char = generateChars(pt, mod, cd, fp);
9402     is_inst_string = generateStrings(pt, mod, cd, fp);
9403     is_inst_int = generateInts(pt, mod, cd, fp);
9404     is_inst_long = generateLongs(pt, mod, cd, fp);
9405     is_inst_ulong = generateUnsignedLongs(pt, mod, cd, fp);
9406     is_inst_longlong = generateLongLongs(pt, mod, cd, fp);
9407     is_inst_ulonglong = generateUnsignedLongLongs(pt, mod, cd, fp);
9408     is_inst_double = generateDoubles(pt, mod, cd, fp);
9409 
9410     /* Generate the docstrings. */
9411     if (hasClassDocstring(pt, cd))
9412     {
9413         prcode(fp,
9414 "\n"
9415 "PyDoc_STRVAR(doc_%L, \"", cd->iff);
9416 
9417         generateClassDocstring(pt, cd, fp);
9418 
9419         prcode(fp, "\");\n"
9420             );
9421 
9422         has_docstring = TRUE;
9423     }
9424     else
9425     {
9426         has_docstring = FALSE;
9427     }
9428 
9429     /* Generate any plugin-specific data structures. */
9430     if (pluginPyQt5(pt))
9431         plugin = generatePyQt5ClassPlugin(pt, cd, fp);
9432     else
9433         plugin = FALSE;
9434 
9435     prcode(fp,
9436 "\n"
9437 "\n"
9438 "sipClassTypeDef ");
9439 
9440     generateTypeDefName(cd->iff, fp);
9441 
9442     prcode(fp, " = {\n"
9443 "    {\n"
9444 "        %P,\n"
9445 "        "
9446         , cd->iff->api_range);
9447 
9448     generateTypeDefLink(cd->iff, fp);
9449 
9450     prcode(fp, ",\n"
9451 "        SIP_NULLPTR,\n"
9452 "        ");
9453 
9454     sep = "";
9455 
9456     if (isAbstractClass(cd))
9457     {
9458         prcode(fp, "%sSIP_TYPE_ABSTRACT", sep);
9459         sep = "|";
9460     }
9461 
9462     if (cd->subbase != NULL)
9463     {
9464         prcode(fp, "%sSIP_TYPE_SCC", sep);
9465         sep = "|";
9466     }
9467 
9468     if (classHandlesNone(cd))
9469     {
9470         prcode(fp, "%sSIP_TYPE_ALLOW_NONE", sep);
9471         sep = "|";
9472     }
9473 
9474     if (hasNonlazyMethod(cd))
9475     {
9476         prcode(fp, "%sSIP_TYPE_NONLAZY", sep);
9477         sep = "|";
9478     }
9479 
9480     if (isCallSuperInitYes(mod))
9481     {
9482         prcode(fp, "%sSIP_TYPE_SUPER_INIT", sep);
9483         sep = "|";
9484     }
9485 
9486     if (!py_debug && useLimitedAPI(mod))
9487     {
9488         prcode(fp, "%sSIP_TYPE_LIMITED_API", sep);
9489         sep = "|";
9490     }
9491 
9492     if (cd->iff->type == namespace_iface)
9493     {
9494         prcode(fp, "%sSIP_TYPE_NAMESPACE", sep);
9495         sep = "|";
9496     }
9497     else
9498     {
9499         prcode(fp, "%sSIP_TYPE_CLASS", sep);
9500         sep = "|";
9501     }
9502 
9503     if (*sep == '\0')
9504         prcode(fp, "0");
9505 
9506     prcode(fp, ",\n");
9507 
9508     prcode(fp,
9509 "        %n,\n"
9510 "        SIP_NULLPTR,\n"
9511         , cd->iff->name);
9512 
9513     if (plugin)
9514         prcode(fp,
9515 "        &plugin_%L\n"
9516             , cd->iff);
9517     else
9518         prcode(fp,
9519 "        SIP_NULLPTR\n"
9520             );
9521 
9522     prcode(fp,
9523 "    },\n"
9524 "    {\n"
9525         );
9526 
9527     if (cd->real == NULL)
9528         prcode(fp,
9529 "        %n,\n"
9530             , cd->pyname);
9531     else
9532         prcode(fp,
9533 "        -1,\n"
9534             );
9535 
9536     prcode(fp, "        ");
9537 
9538     if (cd->real != NULL)
9539         generateEncodedType(mod, cd->real, 0, fp);
9540     else if (pyScope(cd->ecd) != NULL)
9541         generateEncodedType(mod, cd->ecd, 0, fp);
9542     else
9543         prcode(fp, "{0, 0, 1}");
9544 
9545     prcode(fp, ",\n"
9546         );
9547 
9548     if (nr_methods == 0)
9549         prcode(fp,
9550 "        0, SIP_NULLPTR,\n"
9551             );
9552     else
9553         prcode(fp,
9554 "        %d, methods_%L,\n"
9555             , nr_methods, cd->iff);
9556 
9557     if (nr_enums == 0)
9558         prcode(fp,
9559 "        0, SIP_NULLPTR,\n"
9560             );
9561     else
9562         prcode(fp,
9563 "        %d, enummembers_%L,\n"
9564             , nr_enums, cd->iff);
9565 
9566     if (nr_vars == 0)
9567         prcode(fp,
9568 "        0, SIP_NULLPTR,\n"
9569             );
9570     else
9571         prcode(fp,
9572 "        %d, variables_%L,\n"
9573             , nr_vars, cd->iff);
9574 
9575     prcode(fp,
9576 "        {");
9577 
9578     if (is_inst_class)
9579         prcode(fp, "typeInstances_%C, ", classFQCName(cd));
9580     else
9581         prcode(fp, "SIP_NULLPTR, ");
9582 
9583     if (is_inst_voidp)
9584         prcode(fp, "voidPtrInstances_%C, ", classFQCName(cd));
9585     else
9586         prcode(fp, "SIP_NULLPTR, ");
9587 
9588     if (is_inst_char)
9589         prcode(fp, "charInstances_%C, ", classFQCName(cd));
9590     else
9591         prcode(fp, "SIP_NULLPTR, ");
9592 
9593     if (is_inst_string)
9594         prcode(fp, "stringInstances_%C, ", classFQCName(cd));
9595     else
9596         prcode(fp, "SIP_NULLPTR, ");
9597 
9598     if (is_inst_int)
9599         prcode(fp, "intInstances_%C, ", classFQCName(cd));
9600     else
9601         prcode(fp, "SIP_NULLPTR, ");
9602 
9603     if (is_inst_long)
9604         prcode(fp, "longInstances_%C, ", classFQCName(cd));
9605     else
9606         prcode(fp, "SIP_NULLPTR, ");
9607 
9608     if (is_inst_ulong)
9609         prcode(fp, "unsignedLongInstances_%C, ", classFQCName(cd));
9610     else
9611         prcode(fp, "SIP_NULLPTR, ");
9612 
9613     if (is_inst_longlong)
9614         prcode(fp, "longLongInstances_%C, ", classFQCName(cd));
9615     else
9616         prcode(fp, "SIP_NULLPTR, ");
9617 
9618     if (is_inst_ulonglong)
9619         prcode(fp, "unsignedLongLongInstances_%C, ", classFQCName(cd));
9620     else
9621         prcode(fp, "SIP_NULLPTR, ");
9622 
9623     if (is_inst_double)
9624         prcode(fp, "doubleInstances_%C", classFQCName(cd));
9625     else
9626         prcode(fp, "SIP_NULLPTR");
9627 
9628     prcode(fp,"},\n"
9629 "    },\n"
9630         );
9631 
9632     if (has_docstring)
9633         prcode(fp,
9634 "    doc_%L,\n"
9635             , cd->iff);
9636     else
9637         prcode(fp,
9638 "    SIP_NULLPTR,\n"
9639             );
9640 
9641     if (cd->metatype != NULL)
9642         prcode(fp,
9643 "    %n,\n"
9644             , cd->metatype);
9645     else
9646         prcode(fp,
9647 "    -1,\n"
9648             );
9649 
9650     if (cd->supertype != NULL)
9651         prcode(fp,
9652 "    %n,\n"
9653             , cd->supertype);
9654     else
9655         prcode(fp,
9656 "    -1,\n"
9657             );
9658 
9659     if (cd->supers != NULL)
9660         prcode(fp,
9661 "    supers_%C,\n"
9662             , classFQCName(cd));
9663     else
9664         prcode(fp,
9665 "    SIP_NULLPTR,\n"
9666             );
9667 
9668     if (is_slots)
9669         prcode(fp,
9670 "    slots_%L,\n"
9671             , cd->iff);
9672     else
9673         prcode(fp,
9674 "    SIP_NULLPTR,\n"
9675             );
9676 
9677     if (canCreate(cd))
9678         prcode(fp,
9679 "    init_type_%L,\n"
9680             , cd->iff);
9681     else
9682         prcode(fp,
9683 "    SIP_NULLPTR,\n"
9684             );
9685 
9686     if (cd->travcode != NULL)
9687         prcode(fp,
9688 "    traverse_%C,\n"
9689             , classFQCName(cd));
9690     else
9691         prcode(fp,
9692 "    SIP_NULLPTR,\n"
9693             );
9694 
9695     if (cd->clearcode != NULL)
9696         prcode(fp,
9697 "    clear_%C,\n"
9698             , classFQCName(cd));
9699     else
9700         prcode(fp,
9701 "    SIP_NULLPTR,\n"
9702             );
9703 
9704     if (cd->getbufcode != NULL)
9705         prcode(fp,
9706 "    getbuffer_%C,\n"
9707             , classFQCName(cd));
9708     else
9709         prcode(fp,
9710 "    SIP_NULLPTR,\n"
9711             );
9712 
9713     if (cd->releasebufcode != NULL)
9714         prcode(fp,
9715 "    releasebuffer_%C,\n"
9716             , classFQCName(cd));
9717     else
9718         prcode(fp,
9719 "    SIP_NULLPTR,\n"
9720             );
9721 
9722     if (needDealloc(cd))
9723         prcode(fp,
9724 "    dealloc_%L,\n"
9725             , cd->iff);
9726     else
9727         prcode(fp,
9728 "    SIP_NULLPTR,\n"
9729             );
9730 
9731     if (generating_c || copyHelper(cd))
9732         prcode(fp,
9733 "    assign_%L,\n"
9734             , cd->iff);
9735     else
9736         prcode(fp,
9737 "    SIP_NULLPTR,\n"
9738             );
9739 
9740     if (generating_c || arrayHelper(cd))
9741         prcode(fp,
9742 "    array_%L,\n"
9743             , cd->iff);
9744     else
9745         prcode(fp,
9746 "    SIP_NULLPTR,\n"
9747             );
9748 
9749     if (generating_c || copyHelper(cd))
9750         prcode(fp,
9751 "    copy_%L,\n"
9752             , cd->iff);
9753     else
9754         prcode(fp,
9755 "    SIP_NULLPTR,\n"
9756             );
9757 
9758     if (cd->iff->type == namespace_iface || generating_c)
9759         prcode(fp,
9760 "    SIP_NULLPTR,\n"
9761             );
9762     else
9763         prcode(fp,
9764 "    release_%L,\n"
9765             , cd->iff);
9766 
9767     if (cd->supers != NULL)
9768         prcode(fp,
9769 "    cast_%L,\n"
9770             , cd->iff);
9771     else
9772         prcode(fp,
9773 "    SIP_NULLPTR,\n"
9774             );
9775 
9776     if (cd->iff->type == namespace_iface)
9777     {
9778         prcode(fp,
9779 "    SIP_NULLPTR,\n"
9780             );
9781     }
9782     else
9783     {
9784         if (cd->convtocode != NULL)
9785             prcode(fp,
9786 "    convertTo_%L,\n"
9787                 , cd->iff);
9788         else
9789             prcode(fp,
9790 "    SIP_NULLPTR,\n"
9791                 );
9792     }
9793 
9794     if (cd->iff->type == namespace_iface)
9795     {
9796         prcode(fp,
9797 "    SIP_NULLPTR,\n"
9798             );
9799     }
9800     else
9801     {
9802         if (cd->convfromcode != NULL)
9803             prcode(fp,
9804 "    convertFrom_%L,\n"
9805                 , cd->iff);
9806         else
9807             prcode(fp,
9808 "    SIP_NULLPTR,\n"
9809                 );
9810     }
9811 
9812     prcode(fp,
9813 "    SIP_NULLPTR,\n"
9814         );
9815 
9816     if (cd->picklecode != NULL)
9817         prcode(fp,
9818 "    pickle_%C,\n"
9819             , classFQCName(cd));
9820     else
9821         prcode(fp,
9822 "    SIP_NULLPTR,\n"
9823             );
9824 
9825     if (cd->finalcode != NULL)
9826         prcode(fp,
9827 "    final_%C,\n"
9828             , classFQCName(cd));
9829     else
9830         prcode(fp,
9831 "    SIP_NULLPTR,\n"
9832             );
9833 
9834     if (isMixin(cd))
9835         prcode(fp,
9836 "    mixin_%C\n"
9837             , classFQCName(cd));
9838     else
9839         prcode(fp,
9840 "    SIP_NULLPTR\n"
9841             );
9842 
9843     prcode(fp,
9844 "};\n"
9845         );
9846 }
9847 
9848 
9849 /*
9850  * See if an overload has optional arguments.
9851  */
hasOptionalArgs(overDef * od)9852 static int hasOptionalArgs(overDef *od)
9853 {
9854     return (od->cppsig->nrArgs > 0 && od->cppsig->args[od->cppsig->nrArgs - 1].defval != NULL);
9855 }
9856 
9857 
9858 /*
9859  * Generate the PyQt5 emitters for a class.
9860  */
generatePyQt5Emitters(classDef * cd,FILE * fp)9861 static void generatePyQt5Emitters(classDef *cd, FILE *fp)
9862 {
9863     moduleDef *mod = cd->iff->module;
9864     memberDef *md;
9865 
9866     for (md = cd->members; md != NULL; md = md->next)
9867     {
9868         int in_emitter = FALSE;
9869         overDef *od;
9870 
9871         for (od = cd->overs; od != NULL; od = od->next)
9872         {
9873             if (od->common != md || !isSignal(od) || !hasOptionalArgs(od))
9874                 continue;
9875 
9876             if (!in_emitter)
9877             {
9878                 in_emitter = TRUE;
9879 
9880                 prcode(fp,
9881 "\n"
9882 "\n"
9883                     );
9884 
9885                 if (!generating_c)
9886                     prcode(fp,
9887 "extern \"C\" {static int emit_%L_%s(void *, PyObject *);}\n"
9888 "\n"
9889                         , cd->iff, od->cppname);
9890 
9891                 prcode(fp,
9892 "static int emit_%L_%s(void *sipCppV, PyObject *sipArgs)\n"
9893 "{\n"
9894 "    PyObject *sipParseErr = SIP_NULLPTR;\n"
9895 "    %V *sipCpp = reinterpret_cast<%V *>(sipCppV);\n"
9896                     , cd->iff, od->cppname
9897                     , classFQCName(cd), classFQCName(cd));
9898             }
9899 
9900             /*
9901              * Generate the code that parses the args and emits the appropriate
9902              * overloaded signal.
9903              */
9904             prcode(fp,
9905 "\n"
9906 "    {\n"
9907                 );
9908 
9909             generateArgParser(mod, &od->pysig, cd, NULL, NULL, NULL, fp);
9910 
9911             prcode(fp,
9912 "        {\n"
9913 "            Py_BEGIN_ALLOW_THREADS\n"
9914 "            sipCpp->%s("
9915                 , od->cppname);
9916 
9917             generateCallArgs(mod, od->cppsig, &od->pysig, fp);
9918 
9919             prcode(fp, ");\n"
9920 "            Py_END_ALLOW_THREADS\n"
9921 "\n"
9922                 );
9923 
9924             deleteTemps(mod, &od->pysig, fp);
9925 
9926             prcode(fp,
9927 "\n"
9928 "            return 0;\n"
9929 "        }\n"
9930 "    }\n"
9931             );
9932         }
9933 
9934         if (in_emitter)
9935         {
9936             prcode(fp,
9937 "\n"
9938 "    sipNoMethod(sipParseErr, %N, %N, SIP_NULLPTR);\n"
9939 "\n"
9940 "    return -1;\n"
9941 "}\n"
9942                 , cd->pyname, md->pyname);
9943         }
9944     }
9945 }
9946 
9947 
9948 /*
9949  * Generate an entry in the PyQt5 signal table.
9950  */
generateSignalTableEntry(sipSpec * pt,classDef * cd,overDef * sig,int membernr,int optional_args,FILE * fp)9951 static void generateSignalTableEntry(sipSpec *pt, classDef *cd, overDef *sig,
9952         int membernr, int optional_args, FILE *fp)
9953 {
9954     int a, stripped;
9955 
9956     prcode(fp,
9957 "    {\"%s(", sig->cppname);
9958 
9959     stripped = FALSE;
9960 
9961     for (a = 0; a < sig->cppsig->nrArgs; ++a)
9962     {
9963         argDef arg = sig->cppsig->args[a];
9964 
9965         if (a > 0)
9966             prcode(fp,",");
9967 
9968         normaliseSignalArg(&arg);
9969 
9970         if (arg.scopes_stripped)
9971         {
9972             generateNamedBaseType(cd->iff, &arg, "", TRUE, arg.scopes_stripped,
9973                     fp);
9974             stripped = TRUE;
9975         }
9976         else
9977         {
9978             generateNamedBaseType(cd->iff, &arg, "", TRUE, STRIP_GLOBAL, fp);
9979         }
9980     }
9981 
9982     prcode(fp, ")");
9983 
9984     /*
9985      * If a scope was stripped then append an unstripped version which can be
9986      * parsed by PyQt.
9987      */
9988     if (stripped)
9989     {
9990         prcode(fp, "|(");
9991 
9992         for (a = 0; a < sig->cppsig->nrArgs; ++a)
9993         {
9994             argDef arg = sig->cppsig->args[a];
9995 
9996             if (a > 0)
9997                 prcode(fp,",");
9998 
9999             normaliseSignalArg(&arg);
10000 
10001             generateNamedBaseType(cd->iff, &arg, "", TRUE, STRIP_GLOBAL, fp);
10002         }
10003 
10004         prcode(fp, ")");
10005     }
10006 
10007     prcode(fp, "\", ");
10008 
10009     if (docstrings)
10010     {
10011         prcode(fp, "\"");
10012 
10013         if (sig->docstring != NULL)
10014         {
10015             if (sig->docstring->signature == prepended)
10016             {
10017                 dsOverload(pt, sig, TRUE, fp);
10018                 prcode(fp, "\\n");
10019             }
10020 
10021             generateDocstringText(sig->docstring, fp);
10022 
10023             if (sig->docstring->signature == appended)
10024             {
10025                 prcode(fp, "\\n");
10026                 dsOverload(pt, sig, TRUE, fp);
10027             }
10028         }
10029         else
10030         {
10031             fprintf(fp, "\\1");
10032             dsOverload(pt, sig, TRUE, fp);
10033         }
10034 
10035         fprintf(fp, "\", ");
10036     }
10037     else
10038     {
10039         prcode(fp, "SIP_NULLPTR, ");
10040     }
10041 
10042     if (membernr >= 0)
10043         prcode(fp, "&methods_%L[%d], ", cd->iff, membernr);
10044     else
10045         prcode(fp, "SIP_NULLPTR, ");
10046 
10047     if (optional_args)
10048         prcode(fp, "emit_%L_%s", cd->iff, sig->cppname);
10049     else
10050         prcode(fp, "SIP_NULLPTR");
10051 
10052     prcode(fp,"},\n"
10053         );
10054 }
10055 
10056 
10057 /*
10058  * Do some signal argument normalisation so that Qt doesn't have to.
10059  */
normaliseSignalArg(argDef * ad)10060 static void normaliseSignalArg(argDef *ad)
10061 {
10062     if (isConstArg(ad) && (isReference(ad) || ad->nrderefs == 0))
10063     {
10064         resetIsConstArg(ad);
10065         resetIsReference(ad);
10066     }
10067 }
10068 
10069 
10070 /*
10071  * Return the sip module's string equivalent of a slot.
10072  */
slotName(slotType st)10073 static const char *slotName(slotType st)
10074 {
10075     const char *sn;
10076 
10077     switch (st)
10078     {
10079     case str_slot:
10080         sn = "str_slot";
10081         break;
10082 
10083     case int_slot:
10084         sn = "int_slot";
10085         break;
10086 
10087     case float_slot:
10088         sn = "float_slot";
10089         break;
10090 
10091     case len_slot:
10092         sn = "len_slot";
10093         break;
10094 
10095     case contains_slot:
10096         sn = "contains_slot";
10097         break;
10098 
10099     case add_slot:
10100         sn = "add_slot";
10101         break;
10102 
10103     case concat_slot:
10104         sn = "concat_slot";
10105         break;
10106 
10107     case sub_slot:
10108         sn = "sub_slot";
10109         break;
10110 
10111     case mul_slot:
10112         sn = "mul_slot";
10113         break;
10114 
10115     case repeat_slot:
10116         sn = "repeat_slot";
10117         break;
10118 
10119     case mod_slot:
10120         sn = "mod_slot";
10121         break;
10122 
10123     case floordiv_slot:
10124         sn = "floordiv_slot";
10125         break;
10126 
10127     case truediv_slot:
10128         sn = "truediv_slot";
10129         break;
10130 
10131     case and_slot:
10132         sn = "and_slot";
10133         break;
10134 
10135     case or_slot:
10136         sn = "or_slot";
10137         break;
10138 
10139     case xor_slot:
10140         sn = "xor_slot";
10141         break;
10142 
10143     case lshift_slot:
10144         sn = "lshift_slot";
10145         break;
10146 
10147     case rshift_slot:
10148         sn = "rshift_slot";
10149         break;
10150 
10151     case iadd_slot:
10152         sn = "iadd_slot";
10153         break;
10154 
10155     case iconcat_slot:
10156         sn = "iconcat_slot";
10157         break;
10158 
10159     case isub_slot:
10160         sn = "isub_slot";
10161         break;
10162 
10163     case imul_slot:
10164         sn = "imul_slot";
10165         break;
10166 
10167     case irepeat_slot:
10168         sn = "irepeat_slot";
10169         break;
10170 
10171     case imod_slot:
10172         sn = "imod_slot";
10173         break;
10174 
10175     case ifloordiv_slot:
10176         sn = "ifloordiv_slot";
10177         break;
10178 
10179     case itruediv_slot:
10180         sn = "itruediv_slot";
10181         break;
10182 
10183     case iand_slot:
10184         sn = "iand_slot";
10185         break;
10186 
10187     case ior_slot:
10188         sn = "ior_slot";
10189         break;
10190 
10191     case ixor_slot:
10192         sn = "ixor_slot";
10193         break;
10194 
10195     case ilshift_slot:
10196         sn = "ilshift_slot";
10197         break;
10198 
10199     case irshift_slot:
10200         sn = "irshift_slot";
10201         break;
10202 
10203     case invert_slot:
10204         sn = "invert_slot";
10205         break;
10206 
10207     case call_slot:
10208         sn = "call_slot";
10209         break;
10210 
10211     case getitem_slot:
10212         sn = "getitem_slot";
10213         break;
10214 
10215     case setitem_slot:
10216         sn = "setitem_slot";
10217         break;
10218 
10219     case delitem_slot:
10220         sn = "delitem_slot";
10221         break;
10222 
10223     case lt_slot:
10224         sn = "lt_slot";
10225         break;
10226 
10227     case le_slot:
10228         sn = "le_slot";
10229         break;
10230 
10231     case eq_slot:
10232         sn = "eq_slot";
10233         break;
10234 
10235     case ne_slot:
10236         sn = "ne_slot";
10237         break;
10238 
10239     case gt_slot:
10240         sn = "gt_slot";
10241         break;
10242 
10243     case ge_slot:
10244         sn = "ge_slot";
10245         break;
10246 
10247     case cmp_slot:
10248         sn = "cmp_slot";
10249         break;
10250 
10251     case bool_slot:
10252         sn = "bool_slot";
10253         break;
10254 
10255     case neg_slot:
10256         sn = "neg_slot";
10257         break;
10258 
10259     case pos_slot:
10260         sn = "pos_slot";
10261         break;
10262 
10263     case abs_slot:
10264         sn = "abs_slot";
10265         break;
10266 
10267     case repr_slot:
10268         sn = "repr_slot";
10269         break;
10270 
10271     case hash_slot:
10272         sn = "hash_slot";
10273         break;
10274 
10275     case index_slot:
10276         sn = "index_slot";
10277         break;
10278 
10279     case iter_slot:
10280         sn = "iter_slot";
10281         break;
10282 
10283     case next_slot:
10284         sn = "next_slot";
10285         break;
10286 
10287     case setattr_slot:
10288         sn = "setattr_slot";
10289         break;
10290 
10291     case matmul_slot:
10292         sn = "matmul_slot";
10293         break;
10294 
10295     case imatmul_slot:
10296         sn = "imatmul_slot";
10297         break;
10298 
10299     case await_slot:
10300         sn = "await_slot";
10301         break;
10302 
10303     case aiter_slot:
10304         sn = "aiter_slot";
10305         break;
10306 
10307     case anext_slot:
10308         sn = "anext_slot";
10309         break;
10310 
10311     default:
10312         sn = NULL;
10313     }
10314 
10315     return sn;
10316 }
10317 
10318 
10319 /*
10320  * Generate the initialisation function or cast operators for the type.
10321  */
generateTypeInit(classDef * cd,moduleDef * mod,FILE * fp)10322 static void generateTypeInit(classDef *cd, moduleDef *mod, FILE *fp)
10323 {
10324     ctorDef *ct;
10325     int need_self, need_owner;
10326 
10327     /*
10328      * See if we need to name the self and owner arguments so that we can avoid
10329      * a compiler warning about an unused argument.
10330      */
10331     need_self = (generating_c || hasShadow(cd));
10332     need_owner = generating_c;
10333 
10334     for (ct = cd->ctors; ct != NULL; ct = ct->next)
10335     {
10336         if (usedInCode(ct->methodcode, "sipSelf"))
10337             need_self = TRUE;
10338 
10339         if (isResultTransferredCtor(ct))
10340             need_owner = TRUE;
10341         else
10342         {
10343             int a;
10344 
10345             for (a = 0; a < ct->pysig.nrArgs; ++a)
10346             {
10347                 argDef *ad = &ct->pysig.args[a];
10348 
10349                 if (!isInArg(ad))
10350                     continue;
10351 
10352                 if (keepReference(ad))
10353                     need_self = TRUE;
10354 
10355                 if (isTransferred(ad))
10356                     need_self = TRUE;
10357 
10358                 if (isThisTransferred(ad))
10359                     need_owner = TRUE;
10360             }
10361         }
10362     }
10363 
10364     prcode(fp,
10365 "\n"
10366 "\n"
10367         );
10368 
10369     if (!generating_c)
10370         prcode(fp,
10371 "extern \"C\" {static void *init_type_%L(sipSimpleWrapper *, PyObject *, PyObject *, PyObject **, PyObject **, PyObject **);}\n"
10372             , cd->iff);
10373 
10374     prcode(fp,
10375 "static void *init_type_%L(sipSimpleWrapper *%s, PyObject *sipArgs, PyObject *sipKwds, PyObject **sipUnused, PyObject **%s, PyObject **sipParseErr)\n"
10376 "{\n"
10377         , cd->iff, (need_self ? "sipSelf" : ""), (need_owner ? "sipOwner" : ""));
10378 
10379     if (hasShadow(cd))
10380         prcode(fp,
10381 "    sip%C *sipCpp = SIP_NULLPTR;\n"
10382             ,classFQCName(cd));
10383     else
10384         prcode(fp,
10385 "    %U *sipCpp = SIP_NULLPTR;\n"
10386             ,cd);
10387 
10388     if (tracing)
10389         prcode(fp,
10390 "\n"
10391 "    sipTrace(SIP_TRACE_INITS,\"init_type_%L()\\n\");\n"
10392             , cd->iff);
10393 
10394     /*
10395      * Generate the code that parses the Python arguments and calls the correct
10396      * constructor.
10397      */
10398     for (ct = cd->ctors; ct != NULL; ct = ct->next)
10399     {
10400         int error_flag, old_error_flag;
10401         apiVersionRangeDef *avr;
10402 
10403         if (isPrivateCtor(ct))
10404             continue;
10405 
10406         avr = ct->api_range;
10407 
10408         prcode(fp,
10409 "\n"
10410             );
10411 
10412         if (avr != NULL)
10413             prcode(fp,
10414 "    if (sipIsAPIEnabled(%N, %d, %d))\n"
10415                 , avr->api_name, avr->from, avr->to);
10416 
10417         prcode(fp,
10418 "    {\n"
10419             );
10420 
10421         if (ct->methodcode != NULL)
10422         {
10423             error_flag = needErrorFlag(ct->methodcode);
10424             old_error_flag = needOldErrorFlag(ct->methodcode);
10425         }
10426         else
10427         {
10428             error_flag = old_error_flag = FALSE;
10429         }
10430 
10431         generateArgParser(mod, &ct->pysig, cd, NULL, ct, NULL, fp);
10432         generateConstructorCall(cd, ct, error_flag, old_error_flag, mod, fp);
10433 
10434         prcode(fp,
10435 "    }\n"
10436             );
10437     }
10438 
10439     prcode(fp,
10440 "\n"
10441 "    return SIP_NULLPTR;\n"
10442 "}\n"
10443         );
10444 }
10445 
10446 
10447 /*
10448  * Count the number of virtual members in a class.
10449  */
countVirtuals(classDef * cd)10450 static int countVirtuals(classDef *cd)
10451 {
10452     int nrvirts;
10453     virtOverDef *vod;
10454 
10455     nrvirts = 0;
10456 
10457     for (vod = cd->vmembers; vod != NULL; vod = vod->next)
10458         if (!isPrivate(vod->od))
10459             ++nrvirts;
10460 
10461     return nrvirts;
10462 }
10463 
10464 
10465 /*
10466  * Generate the try block for a call.
10467  */
generateTry(throwArgs * ta,FILE * fp)10468 static void generateTry(throwArgs *ta,FILE *fp)
10469 {
10470     /*
10471      * Generate the block if there was no throw specifier, or a non-empty
10472      * throw specifier.
10473      */
10474     if (exceptions && (ta == NULL || ta->nrArgs > 0))
10475         prcode(fp,
10476 "            try\n"
10477 "            {\n"
10478             );
10479 }
10480 
10481 
10482 /*
10483  * Generate the catch blocks for a call.
10484  */
generateCatch(throwArgs * ta,signatureDef * sd,moduleDef * mod,FILE * fp,int rgil)10485 static void generateCatch(throwArgs *ta, signatureDef *sd, moduleDef *mod,
10486         FILE *fp, int rgil)
10487 {
10488     /*
10489      * Generate the block if there was no throw specifier, or a non-empty
10490      * throw specifier.
10491      */
10492     if (exceptions && (ta == NULL || ta->nrArgs > 0))
10493     {
10494         prcode(fp,
10495 "            }\n"
10496             );
10497 
10498         if (ta != NULL)
10499         {
10500             int a;
10501 
10502             for (a = 0; a < ta->nrArgs; ++a)
10503                 generateCatchBlock(mod, ta->args[a], sd, fp, rgil);
10504         }
10505         else if (mod->defexception != NULL)
10506         {
10507             generateCatchBlock(mod, mod->defexception, sd, fp, rgil);
10508         }
10509 
10510         prcode(fp,
10511 "            catch (...)\n"
10512 "            {\n"
10513             );
10514 
10515         if (rgil)
10516             prcode(fp,
10517 "                Py_BLOCK_THREADS\n"
10518 "\n"
10519                 );
10520 
10521         deleteOuts(mod, sd, fp);
10522         deleteTemps(mod, sd, fp);
10523 
10524         prcode(fp,
10525 "                sipRaiseUnknownException();\n"
10526 "                return SIP_NULLPTR;\n"
10527 "            }\n"
10528             );
10529     }
10530 }
10531 
10532 
10533 /*
10534  * Generate a single catch block.
10535  */
generateCatchBlock(moduleDef * mod,exceptionDef * xd,signatureDef * sd,FILE * fp,int rgil)10536 static void generateCatchBlock(moduleDef *mod, exceptionDef *xd,
10537         signatureDef *sd, FILE *fp, int rgil)
10538 {
10539     scopedNameDef *ename = xd->iff->fqcname;
10540 
10541     prcode(fp,
10542 "            catch (%S &%s)\n"
10543 "            {\n"
10544         ,ename,(xd->cd != NULL || usedInCode(xd->raisecode, "sipExceptionRef")) ? "sipExceptionRef" : "");
10545 
10546     if (rgil)
10547         prcode(fp,
10548 "\n"
10549 "                Py_BLOCK_THREADS\n"
10550             );
10551 
10552     deleteOuts(mod, sd, fp);
10553     deleteTemps(mod, sd, fp);
10554 
10555     /* See if the exception is a wrapped class. */
10556     if (xd->cd != NULL)
10557         prcode(fp,
10558 "                /* Hope that there is a valid copy ctor. */\n"
10559 "                %S *sipExceptionCopy = new %S(sipExceptionRef);\n"
10560 "\n"
10561 "                sipRaiseTypeException(sipType_%C,sipExceptionCopy);\n"
10562             , ename, ename
10563             , ename);
10564     else
10565         generateCppCodeBlock(xd->raisecode, fp);
10566 
10567     prcode(fp,
10568 "\n"
10569 "                return SIP_NULLPTR;\n"
10570 "            }\n"
10571         );
10572 }
10573 
10574 
10575 /*
10576  * Generate a throw specifier.
10577  */
generateThrowSpecifier(throwArgs * ta,FILE * fp)10578 static void generateThrowSpecifier(throwArgs *ta,FILE *fp)
10579 {
10580     if (exceptions && ta != NULL)
10581     {
10582         int a;
10583 
10584         prcode(fp," throw(");
10585 
10586         for (a = 0; a < ta->nrArgs; ++a)
10587         {
10588             if (a > 0)
10589                 prcode(fp,",");
10590 
10591             prcode(fp,"%S",ta->args[a]->iff->fqcname);
10592         }
10593 
10594         prcode(fp,")");
10595     }
10596 }
10597 
10598 
10599 /*
10600  * Generate a single constructor call.
10601  */
generateConstructorCall(classDef * cd,ctorDef * ct,int error_flag,int old_error_flag,moduleDef * mod,FILE * fp)10602 static void generateConstructorCall(classDef *cd, ctorDef *ct, int error_flag,
10603         int old_error_flag, moduleDef *mod, FILE *fp)
10604 {
10605     prcode(fp,
10606 "        {\n"
10607         );
10608 
10609     if (ct->premethodcode != NULL)
10610     {
10611         prcode(fp, "\n");
10612         generateCppCodeBlock(ct->premethodcode,fp);
10613         prcode(fp, "\n");
10614     }
10615 
10616     if (error_flag)
10617         prcode(fp,
10618 "            sipErrorState sipError = sipErrorNone;\n"
10619 "\n"
10620             );
10621     else if (old_error_flag)
10622         prcode(fp,
10623 "            int sipIsErr = 0;\n"
10624 "\n"
10625             );
10626 
10627     if (isDeprecatedCtor(ct))
10628         /* Note that any temporaries will leak if an exception is raised. */
10629         prcode(fp,
10630 "            if (sipDeprecated(%N, SIP_NULLPTR) < 0)\n"
10631 "                return SIP_NULLPTR;\n"
10632 "\n"
10633             , cd->pyname);
10634 
10635     /* Call any pre-hook. */
10636     if (ct->prehook != NULL)
10637         prcode(fp,
10638 "            sipCallHook(\"%s\");\n"
10639 "\n"
10640             ,ct->prehook);
10641 
10642     if (ct->methodcode != NULL)
10643         generateCppCodeBlock(ct->methodcode,fp);
10644     else if (generating_c)
10645         prcode(fp,
10646 "            sipCpp = sipMalloc(sizeof (struct %S));\n"
10647             ,classFQCName(cd));
10648     else
10649     {
10650         int a;
10651         int rgil = ((release_gil || isReleaseGILCtor(ct)) && !isHoldGILCtor(ct));
10652 
10653         if (raisesPyExceptionCtor(ct))
10654             prcode(fp,
10655 "            PyErr_Clear();\n"
10656 "\n"
10657                 );
10658 
10659         if (rgil)
10660             prcode(fp,
10661 "            Py_BEGIN_ALLOW_THREADS\n"
10662                 );
10663 
10664         generateTry(ct->exceptions,fp);
10665 
10666         if (hasShadow(cd))
10667             prcode(fp,
10668 "            sipCpp = new sip%C(",classFQCName(cd));
10669         else
10670             prcode(fp,
10671 "            sipCpp = new %U(",cd);
10672 
10673         if (isCastCtor(ct))
10674         {
10675             classDef *ocd;
10676 
10677             /* We have to fiddle the type to generate the correct code. */
10678             ocd = ct->pysig.args[0].u.cd;
10679             ct->pysig.args[0].u.cd = cd;
10680             prcode(fp, "a0->operator %B()", &ct->pysig.args[0]);
10681             ct->pysig.args[0].u.cd = ocd;
10682         }
10683         else
10684             generateCallArgs(mod, ct->cppsig, &ct->pysig, fp);
10685 
10686         prcode(fp,");\n"
10687             );
10688 
10689         generateCatch(ct->exceptions, &ct->pysig, mod, fp, rgil);
10690 
10691         if (rgil)
10692             prcode(fp,
10693 "            Py_END_ALLOW_THREADS\n"
10694                 );
10695 
10696         /* Handle any /KeepReference/ and /Transfer/ arguments. */
10697         for (a = 0; a < ct->pysig.nrArgs; ++a)
10698         {
10699             argDef *ad = &ct->pysig.args[a];
10700 
10701             if (!isInArg(ad))
10702                 continue;
10703 
10704             if (keepReference(ad))
10705             {
10706                 prcode(fp,
10707 "\n"
10708 "            sipKeepReference((PyObject *)sipSelf, %d, %a%s);\n"
10709                     , ad->key, mod, ad, a, (((ad->atype == ascii_string_type || ad->atype == latin1_string_type || ad->atype == utf8_string_type) && ad->nrderefs == 1) || !isGetWrapper(ad) ? "Keep" : "Wrapper"));
10710             }
10711 
10712             if (isTransferred(ad))
10713             {
10714                 prcode(fp,
10715 "\n"
10716 "            sipTransferTo(%aWrapper, (PyObject *)sipSelf);\n" , mod, ad, a);
10717             }
10718         }
10719 
10720         /*
10721          * This is a bit of a hack to say we want the result transferred.  We
10722          * don't simply call sipTransferTo() because the wrapper object hasn't
10723          * been fully initialised yet.
10724          */
10725         if (isResultTransferredCtor(ct))
10726             prcode(fp,
10727 "\n"
10728 "            *sipOwner = Py_None;\n"
10729                 );
10730     }
10731 
10732     gc_ellipsis(&ct->pysig, fp);
10733 
10734     deleteTemps(mod, &ct->pysig, fp);
10735 
10736     prcode(fp,
10737 "\n"
10738         );
10739 
10740     if (raisesPyExceptionCtor(ct))
10741     {
10742         prcode(fp,
10743 "            if (PyErr_Occurred())\n"
10744 "            {\n"
10745 "                delete sipCpp;\n"
10746 "                return SIP_NULLPTR;\n"
10747 "            }\n"
10748 "\n"
10749                 );
10750     }
10751 
10752     if (error_flag)
10753     {
10754         prcode(fp,
10755 "            if (sipError == sipErrorNone)\n"
10756             );
10757 
10758         if (hasShadow(cd) || ct->posthook != NULL)
10759             prcode(fp,
10760 "            {\n"
10761                 );
10762 
10763         if (hasShadow(cd))
10764             prcode(fp,
10765 "                sipCpp->sipPySelf = sipSelf;\n"
10766 "\n"
10767                 );
10768 
10769         /* Call any post-hook. */
10770         if (ct->posthook != NULL)
10771             prcode(fp,
10772 "            sipCallHook(\"%s\");\n"
10773 "\n"
10774                 , ct->posthook);
10775 
10776         prcode(fp,
10777 "                return sipCpp;\n"
10778             );
10779 
10780         if (hasShadow(cd) || ct->posthook != NULL)
10781             prcode(fp,
10782 "            }\n"
10783                 );
10784 
10785         prcode(fp,
10786 "\n"
10787 "            if (sipUnused)\n"
10788 "            {\n"
10789 "                Py_XDECREF(*sipUnused);\n"
10790 "            }\n"
10791 "\n"
10792 "            sipAddException(sipError, sipParseErr);\n"
10793 "\n"
10794 "            if (sipError == sipErrorFail)\n"
10795 "                return SIP_NULLPTR;\n"
10796             );
10797     }
10798     else
10799     {
10800         if (old_error_flag)
10801         {
10802             prcode(fp,
10803 "            if (sipIsErr)\n"
10804 "            {\n"
10805 "                if (sipUnused)\n"
10806 "                {\n"
10807 "                    Py_XDECREF(*sipUnused);\n"
10808 "                }\n"
10809 "\n"
10810 "                sipAddException(sipErrorFail, sipParseErr);\n"
10811 "                return SIP_NULLPTR;\n"
10812 "            }\n"
10813 "\n"
10814                 );
10815         }
10816 
10817         if (hasShadow(cd))
10818             prcode(fp,
10819 "            sipCpp->sipPySelf = sipSelf;\n"
10820 "\n"
10821                 );
10822 
10823         /* Call any post-hook. */
10824         if (ct->posthook != NULL)
10825             prcode(fp,
10826 "            sipCallHook(\"%s\");\n"
10827 "\n"
10828                 , ct->posthook);
10829 
10830         prcode(fp,
10831 "            return sipCpp;\n"
10832             );
10833     }
10834 
10835     prcode(fp,
10836 "        }\n"
10837         );
10838 }
10839 
10840 
10841 /*
10842  * See if a member overload should be skipped.
10843  */
skipOverload(overDef * od,memberDef * md,classDef * cd,classDef * ccd,int want_local)10844 static int skipOverload(overDef *od,memberDef *md,classDef *cd,classDef *ccd,
10845             int want_local)
10846 {
10847     /* Skip if it's not the right name. */
10848     if (od->common != md)
10849         return TRUE;
10850 
10851     /* Skip if it's a signal. */
10852     if (isSignal(od))
10853         return TRUE;
10854 
10855     /* Skip if it's a private abstract. */
10856     if (isAbstract(od) && isPrivate(od))
10857         return TRUE;
10858 
10859     /*
10860      * If we are disallowing them, skip if it's not in the current class unless
10861      * it is protected.
10862      */
10863     if (want_local && !isProtected(od) && ccd != cd)
10864         return TRUE;
10865 
10866     return FALSE;
10867 }
10868 
10869 
10870 /*
10871  * Generate a class member function.
10872  */
generateFunction(sipSpec * pt,memberDef * md,overDef * overs,classDef * cd,classDef * ocd,moduleDef * mod,FILE * fp)10873 static void generateFunction(sipSpec *pt, memberDef *md, overDef *overs,
10874         classDef *cd, classDef *ocd, moduleDef *mod, FILE *fp)
10875 {
10876     overDef *od;
10877     int need_method, need_self, need_args, need_selfarg, need_orig_self;
10878 
10879     /*
10880      * Check that there is at least one overload that needs to be handled.  See
10881      * if we can avoid naming the "self" argument (and suppress a compiler
10882      * warning).  See if we need to remember if "self" was explicitly passed as
10883      * an argument.  See if we need to handle keyword arguments.
10884      */
10885     need_method = need_self = need_args = need_selfarg = need_orig_self = FALSE;
10886 
10887     for (od = overs; od != NULL; od = od->next)
10888     {
10889         /* Skip protected methods if we don't have the means to handle them. */
10890         if (isProtected(od) && !hasShadow(cd))
10891             continue;
10892 
10893         if (!skipOverload(od,md,cd,ocd,TRUE))
10894         {
10895             need_method = TRUE;
10896 
10897             if (!isPrivate(od))
10898             {
10899                 need_args = TRUE;
10900 
10901                 if (!isStatic(od))
10902                 {
10903                     need_self = TRUE;
10904 
10905                     if (isAbstract(od))
10906                         need_orig_self = TRUE;
10907                     else if (isVirtual(od) || isVirtualReimp(od) || usedInCode(od->methodcode, "sipSelfWasArg"))
10908                         need_selfarg = TRUE;
10909                 }
10910             }
10911         }
10912     }
10913 
10914     if (need_method)
10915     {
10916         const char *pname = md->pyname->text;
10917         int has_auto_docstring;
10918 
10919         prcode(fp,
10920 "\n"
10921 "\n"
10922             );
10923 
10924         /* Generate the docstrings. */
10925         if (hasMemberDocstring(pt, overs, md, cd->iff))
10926         {
10927             prcode(fp,
10928 "PyDoc_STRVAR(doc_%L_%s, \"" , cd->iff, pname);
10929 
10930             has_auto_docstring = generateMemberDocstring(pt, overs, md, TRUE,
10931                     fp);
10932 
10933             prcode(fp, "\");\n"
10934 "\n"
10935                 );
10936         }
10937         else
10938         {
10939             has_auto_docstring = FALSE;
10940         }
10941 
10942         if (!generating_c)
10943             prcode(fp,
10944 "extern \"C\" {static PyObject *meth_%L_%s(PyObject *, PyObject *%s);}\n"
10945             , cd->iff, pname, (noArgParser(md) || useKeywordArgs(md) ? ", PyObject *" : ""));
10946 
10947         prcode(fp,
10948 "static PyObject *meth_%L_%s(PyObject *%s, PyObject *%s%s)\n"
10949 "{\n"
10950             , cd->iff, pname, (need_self ? "sipSelf" : ""), (need_args ? "sipArgs" : ""), (noArgParser(md) || useKeywordArgs(md) ? ", PyObject *sipKwds" : ""));
10951 
10952         if (tracing)
10953             prcode(fp,
10954 "    sipTrace(SIP_TRACE_METHODS,\"meth_%L_%s()\\n\");\n"
10955 "\n"
10956                 , cd->iff, pname);
10957 
10958         if (!noArgParser(md))
10959         {
10960             if (need_args)
10961                 prcode(fp,
10962 "    PyObject *sipParseErr = SIP_NULLPTR;\n"
10963                     );
10964 
10965             if (need_selfarg)
10966             {
10967                 /*
10968                  * This determines if we call the explicitly scoped version or
10969                  * the unscoped version (which will then go via the vtable).
10970                  *
10971                  * - If the call was unbound and self was passed as the first
10972                  *   argument (ie. Foo.meth(self)) then we always want to call
10973                  *   the explicitly scoped version.
10974                  *
10975                  * - If the call was bound then we only call the unscoped
10976                  *   version in case there is a C++ sub-class reimplementation
10977                  *   that Python knows nothing about.  Otherwise, if the call
10978                  *   was invoked by super() within a Python reimplementation
10979                  *   then the Python reimplementation would be called
10980                  *   recursively.
10981                  *
10982                  * Note that we would like to rename 'sipSelfWasArg' to
10983                  * 'sipExplicitScope' but it is part of the public API.
10984                  */
10985                 prcode(fp,
10986 "    bool sipSelfWasArg = (!sipSelf || sipIsDerivedClass((sipSimpleWrapper *)sipSelf));\n"
10987                     );
10988             }
10989 
10990             if (need_orig_self)
10991             {
10992                 /*
10993                  * This is similar to the above but for abstract methods.  We
10994                  * allow the (potential) recursion because it means that the
10995                  * concrete implementation can be put in a mixin and it will
10996                  * all work.
10997                  */
10998                 prcode(fp,
10999 "    PyObject *sipOrigSelf = sipSelf;\n"
11000                     );
11001             }
11002         }
11003 
11004         for (od = overs; od != NULL; od = od->next)
11005         {
11006             /* If we are handling one variant then we must handle them all. */
11007             if (skipOverload(od, md, cd, ocd, FALSE))
11008                 continue;
11009 
11010             if (isPrivate(od))
11011                 continue;
11012 
11013             if (noArgParser(md))
11014             {
11015                 generateCppCodeBlock(od->methodcode, fp);
11016                 break;
11017             }
11018 
11019             generateFunctionBody(od, cd, NULL, ocd, TRUE, mod, fp);
11020         }
11021 
11022         if (!noArgParser(md))
11023         {
11024             prcode(fp,
11025 "\n"
11026 "    sipNoMethod(%s, %N, %N, ", (need_args ? "sipParseErr" : "SIP_NULLPTR"), cd->pyname, md->pyname);
11027 
11028             if (has_auto_docstring)
11029                 prcode(fp, "doc_%L_%s", cd->iff, pname);
11030             else
11031                 prcode(fp, "SIP_NULLPTR");
11032 
11033             prcode(fp, ");\n"
11034 "\n"
11035 "    return SIP_NULLPTR;\n"
11036                 );
11037         }
11038 
11039         prcode(fp,
11040 "}\n"
11041             );
11042     }
11043 }
11044 
11045 
11046 /*
11047  * Generate the function calls for a particular overload.
11048  */
generateFunctionBody(overDef * od,classDef * c_scope,mappedTypeDef * mt_scope,classDef * ocd,int deref,moduleDef * mod,FILE * fp)11049 static void generateFunctionBody(overDef *od, classDef *c_scope,
11050         mappedTypeDef *mt_scope, classDef *ocd, int deref, moduleDef *mod,
11051         FILE *fp)
11052 {
11053     signatureDef saved;
11054     ifaceFileDef *o_scope;
11055     apiVersionRangeDef *avr;
11056 
11057     if (mt_scope != NULL)
11058         o_scope = mt_scope->iff;
11059     else if (ocd != NULL)
11060         o_scope = ocd->iff;
11061     else
11062         o_scope = NULL;
11063 
11064     if (o_scope != NULL)
11065         avr = od->api_range;
11066     else
11067         avr = NULL;
11068 
11069     if (avr != NULL)
11070         prcode(fp,
11071 "\n"
11072 "    if (sipIsAPIEnabled(%N, %d, %d))\n"
11073 "    {\n"
11074             , avr->api_name, avr->from, avr->to);
11075     else
11076         prcode(fp,
11077 "\n"
11078 "    {\n"
11079             );
11080 
11081     /* In case we have to fiddle with it. */
11082     saved = od->pysig;
11083 
11084     if (isNumberSlot(od->common))
11085     {
11086         /*
11087          * Number slots must have two arguments because we parse them slightly
11088          * differently.
11089          */
11090         if (od->pysig.nrArgs == 1)
11091         {
11092             od->pysig.nrArgs = 2;
11093             od->pysig.args[1] = od->pysig.args[0];
11094 
11095             /* Insert self in the right place. */
11096             od->pysig.args[0].atype = class_type;
11097             od->pysig.args[0].name = NULL;
11098             od->pysig.args[0].argflags = ARG_IS_REF|ARG_IN;
11099             od->pysig.args[0].nrderefs = 0;
11100             od->pysig.args[0].defval = NULL;
11101             od->pysig.args[0].original_type = NULL;
11102             od->pysig.args[0].u.cd = ocd;
11103         }
11104 
11105         generateArgParser(mod, &od->pysig, c_scope, mt_scope, NULL, od, fp);
11106     }
11107     else if (!isIntArgSlot(od->common) && !isZeroArgSlot(od->common))
11108     {
11109         generateArgParser(mod, &od->pysig, c_scope, mt_scope, NULL, od, fp);
11110     }
11111 
11112     generateFunctionCall(c_scope, mt_scope, o_scope, od, deref, mod, fp);
11113 
11114     prcode(fp,
11115 "    }\n"
11116         );
11117 
11118     od->pysig = saved;
11119 }
11120 
11121 
11122 /*
11123  * Generate the code to handle the result of a call to a member function.
11124  */
generateHandleResult(moduleDef * mod,overDef * od,int isNew,int result_size,char * prefix,FILE * fp)11125 static void generateHandleResult(moduleDef *mod, overDef *od, int isNew,
11126         int result_size, char *prefix, FILE *fp)
11127 {
11128     const char *vname;
11129     char vnamebuf[50];
11130     int a, nrvals, only, has_owner;
11131     argDef *res, *ad;
11132 
11133     res = &od->pysig.result;
11134 
11135     if (res->atype == void_type && res->nrderefs == 0)
11136         res = NULL;
11137 
11138     /* See if we are returning 0, 1 or more values. */
11139     nrvals = 0;
11140 
11141     if (res != NULL)
11142     {
11143         only = -1;
11144         ++nrvals;
11145     }
11146 
11147     has_owner = FALSE;
11148 
11149     for (a = 0; a < od->pysig.nrArgs; ++a)
11150     {
11151         if (isOutArg(&od->pysig.args[a]))
11152         {
11153             only = a;
11154             ++nrvals;
11155         }
11156 
11157         if (isThisTransferred(&od->pysig.args[a]))
11158             has_owner = TRUE;
11159     }
11160 
11161     /* Handle the trivial case. */
11162     if (nrvals == 0)
11163     {
11164         prcode(fp,
11165 "            Py_INCREF(Py_None);\n"
11166 "            %s Py_None;\n"
11167             ,prefix);
11168 
11169         return;
11170     }
11171 
11172     /* Handle results that are classes or mapped types separately. */
11173     if (res != NULL)
11174     {
11175         ifaceFileDef *iff;
11176 
11177         if (res->atype == mapped_type)
11178             iff = res->u.mtd->iff;
11179         else if (res->atype == class_type)
11180             iff = res->u.cd->iff;
11181         else
11182             iff = NULL;
11183 
11184         if (iff != NULL)
11185         {
11186             if (isNew || isFactory(od))
11187             {
11188                 prcode(fp,
11189 "            %s sipConvertFromNewType(",(nrvals == 1 ? prefix : "PyObject *sipResObj ="));
11190 
11191                 if (isConstArg(res))
11192                     prcode(fp,"const_cast<%b *>(sipRes)",res);
11193                 else
11194                     prcode(fp,"sipRes");
11195 
11196                 prcode(fp,",sipType_%C,%s);\n"
11197                     , iff->fqcname, ((has_owner && isFactory(od)) ? "(PyObject *)sipOwner" : resultOwner(od)));
11198 
11199                 /*
11200                  * Shortcut if this is the only value returned.
11201                  */
11202                 if (nrvals == 1)
11203                     return;
11204             }
11205             else
11206             {
11207                 int need_xfer = (isResultTransferred(od) && isStatic(od));
11208 
11209                 prcode(fp,
11210 "            %s sipConvertFromType(", (nrvals > 1 || need_xfer ? "PyObject *sipResObj =" : prefix));
11211 
11212                 if (isConstArg(res))
11213                     prcode(fp,"const_cast<%b *>(sipRes)",res);
11214                 else
11215                     prcode(fp,"sipRes");
11216 
11217                 prcode(fp, ",sipType_%C,%s);\n"
11218                     , iff->fqcname, (need_xfer ? "SIP_NULLPTR" : resultOwner(od)));
11219 
11220                 /*
11221                  * Transferring the result of a static overload needs an
11222                  * explicit call to sipTransferTo().
11223                  */
11224                 if (need_xfer)
11225                     prcode(fp,
11226 "\n"
11227 "           sipTransferTo(sipResObj, Py_None);\n"
11228                         );
11229 
11230                 /*
11231                  * Shortcut if this is the only value returned.
11232                  */
11233                 if (nrvals == 1)
11234                 {
11235                     if (need_xfer)
11236                         prcode(fp,
11237 "\n"
11238 "           return sipResObj;\n"
11239                         );
11240 
11241                     return;
11242                 }
11243             }
11244         }
11245     }
11246 
11247     /* If there are multiple values then build a tuple. */
11248     if (nrvals > 1)
11249     {
11250         prcode(fp,
11251 "            %s sipBuildResult(0,\"(",prefix);
11252 
11253         /* Build the format string. */
11254         if (res != NULL)
11255             prcode(fp, "%s", ((res->atype == mapped_type || res->atype == class_type) ? "R" : getBuildResultFormat(res)));
11256 
11257         for (a = 0; a < od->pysig.nrArgs; ++a)
11258         {
11259             argDef *ad = &od->pysig.args[a];
11260 
11261             if (isOutArg(ad))
11262                 prcode(fp, "%s", getBuildResultFormat(ad));
11263         }
11264 
11265         prcode(fp,")\"");
11266 
11267         /* Pass the values for conversion. */
11268         if (res != NULL)
11269         {
11270             prcode(fp, ",sipRes");
11271 
11272             if (res->atype == mapped_type || res->atype == class_type)
11273                 prcode(fp, "Obj");
11274             else if (res->atype == enum_type && res->u.ed->fqcname != NULL)
11275                 prcode(fp, ",sipType_%C", res->u.ed->fqcname);
11276         }
11277 
11278         for (a = 0; a < od->pysig.nrArgs; ++a)
11279         {
11280             argDef *ad = &od->pysig.args[a];
11281 
11282             if (isOutArg(ad))
11283             {
11284                 prcode(fp, ",%a", mod, ad, a);
11285 
11286                 if (ad->atype == mapped_type)
11287                     prcode(fp, ",sipType_%T,%s", ad, (isTransferredBack(ad) ? "Py_None" : "SIP_NULLPTR"));
11288                 else if (ad->atype == class_type)
11289                     prcode(fp, ",sipType_%C,%s", classFQCName(ad->u.cd), (isTransferredBack(ad) ? "Py_None" : "SIP_NULLPTR"));
11290                 else if (ad->atype == enum_type && ad->u.ed->fqcname != NULL)
11291                     prcode(fp,",sipType_%C", ad->u.ed->fqcname);
11292             }
11293         }
11294 
11295         prcode(fp,");\n"
11296             );
11297 
11298         /* All done for multiple values. */
11299         return;
11300     }
11301 
11302     /* Deal with the only returned value. */
11303     if (only < 0)
11304     {
11305         ad = res;
11306         vname = "sipRes";
11307     }
11308     else
11309     {
11310         ad = &od->pysig.args[only];
11311 
11312         if (useArgNames(mod) && ad->name != NULL)
11313         {
11314             vname = ad->name->text;
11315         }
11316         else
11317         {
11318             sprintf(vnamebuf, "a%d", only);
11319             vname = vnamebuf;
11320         }
11321     }
11322 
11323     switch (ad->atype)
11324     {
11325     case mapped_type:
11326     case class_type:
11327         {
11328             int needNew = needNewInstance(ad);
11329             ifaceFileDef *iff;
11330 
11331             if (ad->atype == mapped_type)
11332                 iff = ad->u.mtd->iff;
11333             else
11334                 iff = ad->u.cd->iff;
11335 
11336             prcode(fp,
11337 "            %s sipConvertFrom%sType(", prefix, (needNew ? "New" : ""));
11338 
11339             if (isConstArg(ad))
11340                 prcode(fp,"const_cast<%b *>(%s)",ad,vname);
11341             else
11342                 prcode(fp,"%s",vname);
11343 
11344             prcode(fp, ",sipType_%C,", iff->fqcname);
11345 
11346             if (needNew || !isTransferredBack(ad))
11347                 prcode(fp, "SIP_NULLPTR);\n");
11348             else
11349                 prcode(fp, "Py_None);\n");
11350         }
11351 
11352         break;
11353 
11354     case bool_type:
11355     case cbool_type:
11356         prcode(fp,
11357 "            %s PyBool_FromLong(%s);\n"
11358             ,prefix,vname);
11359 
11360         break;
11361 
11362     case ascii_string_type:
11363         if (ad->nrderefs == 0)
11364             prcode(fp,
11365 "            %s PyUnicode_DecodeASCII(&%s, 1, SIP_NULLPTR);\n"
11366                 , prefix, vname);
11367         else
11368             prcode(fp,
11369 "            if (%s == SIP_NULLPTR)\n"
11370 "            {\n"
11371 "                Py_INCREF(Py_None);\n"
11372 "                return Py_None;\n"
11373 "            }\n"
11374 "\n"
11375 "            %s PyUnicode_DecodeASCII(%s, strlen(%s), SIP_NULLPTR);\n"
11376             , vname
11377             , prefix, vname, vname);
11378 
11379         break;
11380 
11381     case latin1_string_type:
11382         if (ad->nrderefs == 0)
11383             prcode(fp,
11384 "            %s PyUnicode_DecodeLatin1(&%s, 1, SIP_NULLPTR);\n"
11385                 , prefix, vname);
11386         else
11387             prcode(fp,
11388 "            if (%s == SIP_NULLPTR)\n"
11389 "            {\n"
11390 "                Py_INCREF(Py_None);\n"
11391 "                return Py_None;\n"
11392 "            }\n"
11393 "\n"
11394 "            %s PyUnicode_DecodeLatin1(%s, strlen(%s), SIP_NULLPTR);\n"
11395             , vname
11396             , prefix, vname, vname);
11397 
11398         break;
11399 
11400     case utf8_string_type:
11401         if (ad->nrderefs == 0)
11402             prcode(fp,
11403 "            %s PyUnicode_FromStringAndSize(&%s, 1);\n"
11404                 , prefix, vname);
11405         else
11406             prcode(fp,
11407 "            if (%s == SIP_NULLPTR)\n"
11408 "            {\n"
11409 "                Py_INCREF(Py_None);\n"
11410 "                return Py_None;\n"
11411 "            }\n"
11412 "\n"
11413 "            %s PyUnicode_FromString(%s);\n"
11414             , vname
11415             , prefix, vname);
11416 
11417         break;
11418 
11419     case sstring_type:
11420     case ustring_type:
11421     case string_type:
11422         if (ad->nrderefs == 0)
11423             prcode(fp,
11424 "            %s PyBytes_FromStringAndSize(%s&%s,1);\n"
11425                 ,prefix,(ad->atype != string_type) ? "(char *)" : "",vname);
11426         else
11427             prcode(fp,
11428 "            if (%s == SIP_NULLPTR)\n"
11429 "            {\n"
11430 "                Py_INCREF(Py_None);\n"
11431 "                return Py_None;\n"
11432 "            }\n"
11433 "\n"
11434 "            %s PyBytes_FromString(%s%s);\n"
11435             ,vname
11436             ,prefix,(ad->atype != string_type) ? "(char *)" : "",vname);
11437 
11438         break;
11439 
11440     case wstring_type:
11441         if (ad->nrderefs == 0)
11442             prcode(fp,
11443 "            %s PyUnicode_FromWideChar(&%s,1);\n"
11444                 , prefix, vname);
11445         else
11446             prcode(fp,
11447 "            if (%s == SIP_NULLPTR)\n"
11448 "            {\n"
11449 "                Py_INCREF(Py_None);\n"
11450 "                return Py_None;\n"
11451 "            }\n"
11452 "\n"
11453 "            %s PyUnicode_FromWideChar(%s,(Py_ssize_t)wcslen(%s));\n"
11454             , vname
11455             , prefix, vname, vname);
11456 
11457         break;
11458 
11459     case enum_type:
11460         if (ad->u.ed->fqcname != NULL)
11461         {
11462             const char *cast_prefix, *cast_suffix;
11463 
11464             if (generating_c)
11465             {
11466                 cast_prefix = cast_suffix = "";
11467             }
11468             else
11469             {
11470                 cast_prefix = "static_cast<int>(";
11471                 cast_suffix = ")";
11472             }
11473 
11474             prcode(fp,
11475 "            %s sipConvertFromEnum(%s%s%s, sipType_%C);\n"
11476                 , prefix, cast_prefix, vname, cast_suffix, ad->u.ed->fqcname);
11477 
11478             break;
11479         }
11480 
11481         /* Drop through. */
11482 
11483     case byte_type:
11484     case sbyte_type:
11485     case short_type:
11486     case int_type:
11487     case cint_type:
11488         prcode(fp,
11489 "            %s PyLong_FromLong(%s);\n"
11490             ,prefix,vname);
11491 
11492         break;
11493 
11494     case long_type:
11495         prcode(fp,
11496 "            %s PyLong_FromLong(%s);\n"
11497             ,prefix,vname);
11498 
11499         break;
11500 
11501     case ubyte_type:
11502     case ushort_type:
11503         prcode(fp,
11504 "            %s PyLong_FromUnsignedLong(%s);\n"
11505             , prefix, vname);
11506 
11507         break;
11508 
11509     case uint_type:
11510     case ulong_type:
11511     case size_type:
11512         prcode(fp,
11513 "            %s PyLong_FromUnsignedLong(%s);\n"
11514             , prefix, vname);
11515 
11516         break;
11517 
11518     case ssize_type:
11519         prcode(fp,
11520 "            %s PyLong_FromSsize_t(%s);\n"
11521             , prefix, vname);
11522 
11523         break;
11524 
11525     case longlong_type:
11526         prcode(fp,
11527 "            %s PyLong_FromLongLong(%s);\n"
11528             ,prefix,vname);
11529 
11530         break;
11531 
11532     case ulonglong_type:
11533         prcode(fp,
11534 "            %s PyLong_FromUnsignedLongLong(%s);\n"
11535             ,prefix,vname);
11536 
11537         break;
11538 
11539     case void_type:
11540         {
11541             prcode(fp,
11542 "            %s sipConvertFrom%sVoidPtr", prefix, (isConstArg(ad) ? "Const" : ""));
11543 
11544             if (result_size < 0)
11545             {
11546                 prcode(fp, "(");
11547                 generateVoidPtrCast(ad, fp);
11548                 prcode(fp, "%s", vname);
11549             }
11550             else
11551             {
11552                 prcode(fp, "AndSize(");
11553                 generateVoidPtrCast(ad, fp);
11554                 prcode(fp, "%s,%a", vname, mod, &od->pysig.args[result_size], result_size);
11555             }
11556 
11557             prcode(fp, ");\n"
11558                     );
11559         }
11560 
11561         break;
11562 
11563     case capsule_type:
11564         prcode(fp,
11565 "            %s PyCapsule_New(%s, \"%S\", SIP_NULLPTR);\n"
11566             , prefix, vname, ad->u.cap);
11567         break;
11568 
11569     case struct_type:
11570         prcode(fp,
11571 "            %s sipConvertFrom%sVoidPtr(%s);\n"
11572             , prefix, (isConstArg(ad) ? "Const" : ""), vname);
11573         break;
11574 
11575     case float_type:
11576     case cfloat_type:
11577         prcode(fp,
11578 "            %s PyFloat_FromDouble((double)%s);\n"
11579             ,prefix,vname);
11580 
11581         break;
11582 
11583     case double_type:
11584     case cdouble_type:
11585         prcode(fp,
11586 "            %s PyFloat_FromDouble(%s);\n"
11587             ,prefix,vname);
11588 
11589         break;
11590 
11591     case pyobject_type:
11592     case pytuple_type:
11593     case pylist_type:
11594     case pydict_type:
11595     case pycallable_type:
11596     case pyslice_type:
11597     case pytype_type:
11598     case pybuffer_type:
11599         prcode(fp,
11600 "            %s %s;\n"
11601             ,prefix,vname);
11602 
11603         break;
11604 
11605     /* Supress a compiler warning. */
11606     default:
11607         ;
11608     }
11609 }
11610 
11611 
11612 /*
11613  * Return the owner of a method result.
11614  */
resultOwner(overDef * od)11615 static const char *resultOwner(overDef *od)
11616 {
11617     if (isResultTransferredBack(od))
11618         return "Py_None";
11619 
11620     if (isResultTransferred(od))
11621         return "sipSelf";
11622 
11623     return "SIP_NULLPTR";
11624 }
11625 
11626 
11627 /*
11628  * Check if an argument is a string rather than a char type.
11629  */
isString(argDef * ad)11630 static int isString(argDef *ad)
11631 {
11632     int nrderefs = ad->nrderefs;
11633 
11634     if (isOutArg(ad) && !isReference(ad))
11635         --nrderefs;
11636 
11637     return nrderefs > 0;
11638 }
11639 
11640 
11641 /*
11642  * Return the format string used by sipBuildResult() for a particular type.
11643  */
getBuildResultFormat(argDef * ad)11644 static const char *getBuildResultFormat(argDef *ad)
11645 {
11646     switch (ad->atype)
11647     {
11648     case fake_void_type:
11649     case mapped_type:
11650     case class_type:
11651         if (needNewInstance(ad))
11652             return "N";
11653 
11654         return "D";
11655 
11656     case bool_type:
11657     case cbool_type:
11658         return "b";
11659 
11660     case ascii_string_type:
11661     case latin1_string_type:
11662     case utf8_string_type:
11663         return isString(ad) ? "A" : "a";
11664 
11665     case sstring_type:
11666     case ustring_type:
11667     case string_type:
11668         return isString(ad) ? "s" : "c";
11669 
11670     case wstring_type:
11671         return isString(ad) ? "x" : "w";
11672 
11673     case enum_type:
11674         return (ad->u.ed->fqcname != NULL) ? "F" : "e";
11675 
11676     case byte_type:
11677     case sbyte_type:
11678         return "L";
11679 
11680     case ubyte_type:
11681         return "M";
11682 
11683     case short_type:
11684         return "h";
11685 
11686     case ushort_type:
11687         return "t";
11688 
11689     case int_type:
11690     case cint_type:
11691         return "i";
11692 
11693     case uint_type:
11694         return "u";
11695 
11696     case size_type:
11697         return "=";
11698 
11699     case long_type:
11700         return "l";
11701 
11702     case ulong_type:
11703         return "m";
11704 
11705     case longlong_type:
11706         return "n";
11707 
11708     case ulonglong_type:
11709         return "o";
11710 
11711     case void_type:
11712     case struct_type:
11713         return "V";
11714 
11715     case capsule_type:
11716         return "z";
11717 
11718     case float_type:
11719     case cfloat_type:
11720         return "f";
11721 
11722     case double_type:
11723     case cdouble_type:
11724         return "d";
11725 
11726     case pyobject_type:
11727     case pytuple_type:
11728     case pylist_type:
11729     case pydict_type:
11730     case pycallable_type:
11731     case pyslice_type:
11732     case pytype_type:
11733     case pybuffer_type:
11734         return "R";
11735 
11736     /* Supress a compiler warning. */
11737     default:
11738         ;
11739     }
11740 
11741     /* We should never get here. */
11742     return "";
11743 }
11744 
11745 
11746 /*
11747  * Return TRUE if an argument (or result) needs to be copied to the heap.
11748  */
needsHeapCopy(argDef * ad,int usingCopyCtor)11749 static int needsHeapCopy(argDef *ad, int usingCopyCtor)
11750 {
11751     /* The type is a class or mapped type and not a pointer. */
11752     if (!noCopy(ad) && (ad->atype == class_type || ad->atype == mapped_type) && ad->nrderefs == 0)
11753     {
11754         /* We need a copy unless it is a non-const reference. */
11755         if (!isReference(ad) || isConstArg(ad))
11756         {
11757             /* We assume we can copy a mapped type. */
11758             if (ad->atype != class_type)
11759                 return TRUE;
11760 
11761             /* We can't copy an abstract class. */
11762             if (isAbstractClass(ad->u.cd))
11763                 return FALSE;
11764 
11765             /* We can copy if we have a public copy ctor. */
11766             if (!cannotCopy(ad->u.cd))
11767                 return TRUE;
11768 
11769             /* We can't copy if we must use a copy ctor. */
11770             if (usingCopyCtor)
11771                 return FALSE;
11772 
11773             /* We can copy if we have a public assignment operator. */
11774             return !cannotAssign(ad->u.cd);
11775         }
11776     }
11777 
11778     return FALSE;
11779 }
11780 
11781 
11782 /*
11783  * Generate a variable to hold the result of a function call if one is needed.
11784  */
generateResultVar(ifaceFileDef * scope,overDef * od,argDef * res,const char * indent,FILE * fp)11785 static int generateResultVar(ifaceFileDef *scope, overDef *od, argDef *res,
11786         const char *indent, FILE *fp)
11787 {
11788     int is_result;
11789 
11790     /* See if sipRes is needed. */
11791     is_result = (!isInplaceNumberSlot(od->common) &&
11792              !isInplaceSequenceSlot(od->common) &&
11793              (res->atype != void_type || res->nrderefs != 0));
11794 
11795     if (is_result)
11796     {
11797         prcode(fp, "%s", indent);
11798 
11799         generateNamedValueType(scope, res, "sipRes", fp);
11800 
11801         /*
11802          * The typical %MethodCode usually causes a compiler warning, so we
11803          * initialise the result in that case to try and suppress it.
11804          */
11805         if (od->methodcode != NULL)
11806         {
11807             prcode(fp," = ");
11808 
11809             generateCastZero(res, fp);
11810         }
11811 
11812         prcode(fp,";\n"
11813             );
11814     }
11815 
11816     return is_result;
11817 }
11818 
11819 
11820 /*
11821  * Generate a function call.
11822  */
generateFunctionCall(classDef * c_scope,mappedTypeDef * mt_scope,ifaceFileDef * o_scope,overDef * od,int deref,moduleDef * mod,FILE * fp)11823 static void generateFunctionCall(classDef *c_scope, mappedTypeDef *mt_scope,
11824         ifaceFileDef *o_scope, overDef *od, int deref, moduleDef *mod,
11825         FILE *fp)
11826 {
11827     int needsNew, error_flag, old_error_flag, newline, is_result, result_size,
11828             a, deltemps, post_process, static_factory;
11829     const char *error_value;
11830     argDef *res = &od->pysig.result, orig_res;
11831     ifaceFileDef *scope;
11832     nameDef *pyname;
11833 
11834     if (mt_scope != NULL)
11835     {
11836         scope = mt_scope->iff;
11837         pyname = mt_scope->pyname;
11838     }
11839     else if (c_scope != NULL)
11840     {
11841         scope = c_scope->iff;
11842         pyname = c_scope->pyname;
11843     }
11844     else
11845     {
11846         scope = NULL;
11847         pyname = NULL;
11848     }
11849 
11850     static_factory = ((scope == NULL || isStatic(od)) && isFactory(od));
11851 
11852     prcode(fp,
11853 "        {\n"
11854         );
11855 
11856     /*
11857      * If there is no shadow class then protected methods can never be called.
11858      */
11859     if (isProtected(od) && !hasShadow(c_scope))
11860     {
11861         prcode(fp,
11862 "            /* Never reached. */\n"
11863 "        }\n"
11864             );
11865 
11866         return;
11867     }
11868 
11869     /* Save the full result type as we may want to fiddle with it. */
11870     orig_res = *res;
11871 
11872     /* See if we need to make a copy of the result on the heap. */
11873     needsNew = needsHeapCopy(res, FALSE);
11874 
11875     if (needsNew)
11876         resetIsConstArg(res);
11877 
11878     is_result = newline = generateResultVar(scope, od, res, "            ",
11879             fp);
11880 
11881     result_size = -1;
11882     deltemps = TRUE;
11883     post_process = FALSE;
11884 
11885     /* See if we want to keep a reference to the result. */
11886     if (keepReference(res))
11887         post_process = TRUE;
11888 
11889     for (a = 0; a < od->pysig.nrArgs; ++a)
11890     {
11891         argDef *ad = &od->pysig.args[a];
11892 
11893         if (isResultSize(ad))
11894             result_size = a;
11895 
11896         if (static_factory && keepReference(ad))
11897             post_process = TRUE;
11898 
11899         /*
11900          * If we have an In,Out argument that has conversion code then we delay
11901          * the destruction of any temporary variables until after we have
11902          * converted the outputs.
11903          */
11904         if (isInArg(ad) && isOutArg(ad) && hasConvertToCode(ad))
11905         {
11906             deltemps = FALSE;
11907             post_process = TRUE;
11908         }
11909 
11910         /*
11911          * If we are returning a class via an output only reference or pointer
11912          * then we need an instance on the heap.
11913          */
11914         if (needNewInstance(ad))
11915         {
11916             prcode(fp,
11917 "            %a = new %b();\n"
11918                 , mod, ad, a, ad);
11919 
11920             newline = TRUE;
11921         }
11922     }
11923 
11924     if (post_process)
11925     {
11926         prcode(fp,
11927 "            PyObject *sipResObj;\n"
11928                 );
11929 
11930         newline = TRUE;
11931     }
11932 
11933     if (od->premethodcode != NULL)
11934     {
11935         prcode(fp, "\n");
11936         generateCppCodeBlock(od->premethodcode,fp);
11937     }
11938 
11939     error_flag = old_error_flag = FALSE;
11940 
11941     if (od->methodcode != NULL)
11942     {
11943         /* See if the handwritten code seems to be using the error flag. */
11944         if (needErrorFlag(od->methodcode))
11945         {
11946             prcode(fp,
11947 "            sipErrorState sipError = sipErrorNone;\n"
11948                 );
11949 
11950             newline = TRUE;
11951             error_flag = TRUE;
11952         }
11953         else if (needOldErrorFlag(od->methodcode))
11954         {
11955             prcode(fp,
11956 "            int sipIsErr = 0;\n"
11957                 );
11958 
11959             newline = TRUE;
11960             old_error_flag = TRUE;
11961         }
11962     }
11963 
11964     if (newline)
11965         prcode(fp,
11966 "\n"
11967             );
11968 
11969     /* If it is abstract make sure that self was bound. */
11970     if (isAbstract(od))
11971         prcode(fp,
11972 "            if (!sipOrigSelf)\n"
11973 "            {\n"
11974 "                sipAbstractMethod(%N, %N);\n"
11975 "                return SIP_NULLPTR;\n"
11976 "            }\n"
11977 "\n"
11978             , c_scope->pyname, od->common->pyname);
11979 
11980     if (isDeprecated(od))
11981     {
11982         /* Note that any temporaries will leak if an exception is raised. */
11983         if (pyname != NULL)
11984             prcode(fp,
11985 "            if (sipDeprecated(%N,%N) < 0)\n"
11986                 , pyname, od->common->pyname);
11987         else
11988             prcode(fp,
11989 "            if (sipDeprecated(SIP_NULLPTR,%N) < 0)\n"
11990                 , od->common->pyname);
11991 
11992         prcode(fp,
11993 "                return %s;\n"
11994 "\n"
11995             , ((isVoidReturnSlot(od->common) || isIntReturnSlot(od->common) || isSSizeReturnSlot(od->common) || isLongReturnSlot(od->common)) ? "-1" : "SIP_NULLPTR"));
11996     }
11997 
11998     /* Call any pre-hook. */
11999     if (od->prehook != NULL)
12000         prcode(fp,
12001 "            sipCallHook(\"%s\");\n"
12002 "\n"
12003             ,od->prehook);
12004 
12005     if (od->methodcode != NULL)
12006         generateCppCodeBlock(od->methodcode,fp);
12007     else
12008     {
12009         int rgil = ((release_gil || isReleaseGIL(od)) && !isHoldGIL(od));
12010         int closing_paren = FALSE;
12011 
12012         if (needsNew && generating_c)
12013         {
12014             prcode(fp,
12015 "            if ((sipRes = (%b *)sipMalloc(sizeof (%b))) == SIP_NULLPTR)\n"
12016 "        {\n"
12017                 ,res,res);
12018 
12019             gc_ellipsis(&od->pysig, fp);
12020 
12021             prcode(fp,
12022 "                return SIP_NULLPTR;\n"
12023 "            }\n"
12024 "\n"
12025                 );
12026         }
12027 
12028         if (raisesPyException(od))
12029             prcode(fp,
12030 "            PyErr_Clear();\n"
12031 "\n"
12032                 );
12033 
12034         if (rgil)
12035             prcode(fp,
12036 "            Py_BEGIN_ALLOW_THREADS\n"
12037                 );
12038 
12039         generateTry(od->exceptions,fp);
12040 
12041         prcode(fp,
12042 "            ");
12043 
12044         if (od->common->slot != cmp_slot && is_result)
12045         {
12046             /* Construct a copy on the heap if needed. */
12047             if (needsNew)
12048             {
12049                 if (generating_c)
12050                 {
12051                     prcode(fp,"*sipRes = ");
12052                 }
12053                 else if (res->atype == class_type && cannotCopy(res->u.cd))
12054                 {
12055                     prcode(fp, "sipRes = reinterpret_cast<%b *>(::operator new(sizeof (%b)));\n"
12056 "            *sipRes = ", res, res);
12057                 }
12058                 else
12059                 {
12060                     prcode(fp,"sipRes = new %b(",res);
12061                     closing_paren = TRUE;
12062                 }
12063             }
12064             else
12065             {
12066                 prcode(fp,"sipRes = ");
12067 
12068                 /*
12069                  * See if we need the address of the result.  Any reference
12070                  * will be non-const.
12071                  */
12072                 if ((res->atype == class_type || res->atype == mapped_type) && (res->nrderefs == 0 || isReference(res)))
12073                     prcode(fp,"&");
12074             }
12075         }
12076 
12077         switch (od->common->slot)
12078         {
12079         case no_slot:
12080             generateCppFunctionCall(mod, scope, o_scope, od, fp);
12081             break;
12082 
12083         case getitem_slot:
12084             prcode(fp, "(*sipCpp)[");
12085             generateSlotArg(mod, &od->pysig, 0, fp);
12086             prcode(fp,"]");
12087             break;
12088 
12089         case call_slot:
12090             prcode(fp, "(*sipCpp)(");
12091             generateCallArgs(mod, od->cppsig, &od->pysig, fp);
12092             prcode(fp,")");
12093             break;
12094 
12095         case int_slot:
12096         case float_slot:
12097             prcode(fp, "*sipCpp");
12098             break;
12099 
12100         case add_slot:
12101             generateNumberSlotCall(mod, od, "+", fp);
12102             break;
12103 
12104         case concat_slot:
12105             generateBinarySlotCall(mod, scope, od, "+", deref, fp);
12106             break;
12107 
12108         case sub_slot:
12109             generateNumberSlotCall(mod, od, "-", fp);
12110             break;
12111 
12112         case mul_slot:
12113         case matmul_slot:
12114             generateNumberSlotCall(mod, od, "*", fp);
12115             break;
12116 
12117         case repeat_slot:
12118             generateBinarySlotCall(mod, scope, od, "*", deref, fp);
12119             break;
12120 
12121         case truediv_slot:
12122             generateNumberSlotCall(mod, od, "/", fp);
12123             break;
12124 
12125         case mod_slot:
12126             generateNumberSlotCall(mod, od, "%", fp);
12127             break;
12128 
12129         case and_slot:
12130             generateNumberSlotCall(mod, od, "&", fp);
12131             break;
12132 
12133         case or_slot:
12134             generateNumberSlotCall(mod, od, "|", fp);
12135             break;
12136 
12137         case xor_slot:
12138             generateNumberSlotCall(mod, od, "^", fp);
12139             break;
12140 
12141         case lshift_slot:
12142             generateNumberSlotCall(mod, od, "<<", fp);
12143             break;
12144 
12145         case rshift_slot:
12146             generateNumberSlotCall(mod, od, ">>", fp);
12147             break;
12148 
12149         case iadd_slot:
12150         case iconcat_slot:
12151             generateBinarySlotCall(mod, scope, od, "+=", deref, fp);
12152             break;
12153 
12154         case isub_slot:
12155             generateBinarySlotCall(mod, scope, od, "-=", deref, fp);
12156             break;
12157 
12158         case imul_slot:
12159         case irepeat_slot:
12160         case imatmul_slot:
12161             generateBinarySlotCall(mod, scope, od, "*=", deref, fp);
12162             break;
12163 
12164         case itruediv_slot:
12165             generateBinarySlotCall(mod, scope, od, "/=", deref, fp);
12166             break;
12167 
12168         case imod_slot:
12169             generateBinarySlotCall(mod, scope, od, "%=", deref, fp);
12170             break;
12171 
12172         case iand_slot:
12173             generateBinarySlotCall(mod, scope, od, "&=", deref, fp);
12174             break;
12175 
12176         case ior_slot:
12177             generateBinarySlotCall(mod, scope, od, "|=", deref, fp);
12178             break;
12179 
12180         case ixor_slot:
12181             generateBinarySlotCall(mod, scope, od, "^=", deref, fp);
12182             break;
12183 
12184         case ilshift_slot:
12185             generateBinarySlotCall(mod, scope, od, "<<=", deref, fp);
12186             break;
12187 
12188         case irshift_slot:
12189             generateBinarySlotCall(mod, scope, od, ">>=", deref, fp);
12190             break;
12191 
12192         case invert_slot:
12193             prcode(fp, "~(*sipCpp)");
12194             break;
12195 
12196         case lt_slot:
12197             generateComparisonSlotCall(mod, scope, od, "<", ">=", deref, fp);
12198             break;
12199 
12200         case le_slot:
12201             generateComparisonSlotCall(mod, scope, od, "<=", ">", deref, fp);
12202             break;
12203 
12204         case eq_slot:
12205             generateComparisonSlotCall(mod, scope, od, "==", "!=", deref, fp);
12206             break;
12207 
12208         case ne_slot:
12209             generateComparisonSlotCall(mod, scope, od, "!=", "==", deref, fp);
12210             break;
12211 
12212         case gt_slot:
12213             generateComparisonSlotCall(mod, scope, od, ">", "<=", deref, fp);
12214             break;
12215 
12216         case ge_slot:
12217             generateComparisonSlotCall(mod, scope, od, ">=", "<", deref, fp);
12218             break;
12219 
12220         case neg_slot:
12221             prcode(fp, "-(*sipCpp)");
12222             break;
12223 
12224         case pos_slot:
12225             prcode(fp, "+(*sipCpp)");
12226             break;
12227 
12228         case cmp_slot:
12229             prcode(fp,"if ");
12230             generateBinarySlotCall(mod, scope, od, "<", deref, fp);
12231             prcode(fp,"\n"
12232 "                sipRes = -1;\n"
12233 "            else if ");
12234             generateBinarySlotCall(mod, scope, od, ">", deref, fp);
12235             prcode(fp,"\n"
12236 "                sipRes = 1;\n"
12237 "            else\n"
12238 "                sipRes = 0");
12239 
12240             break;
12241 
12242         /* Supress a compiler warning. */
12243         default:
12244             ;
12245         }
12246 
12247         if (closing_paren)
12248             prcode(fp,")");
12249 
12250         prcode(fp,";\n"
12251             );
12252 
12253         generateCatch(od->exceptions, &od->pysig, mod, fp, rgil);
12254 
12255         if (rgil)
12256             prcode(fp,
12257 "            Py_END_ALLOW_THREADS\n"
12258                 );
12259     }
12260 
12261     for (a = 0; a < od->pysig.nrArgs; ++a)
12262     {
12263         argDef *ad = &od->pysig.args[a];
12264 
12265         if (!isInArg(ad))
12266             continue;
12267 
12268         /* Handle any /KeepReference/ arguments except for static factories. */
12269         if (!static_factory && keepReference(ad))
12270         {
12271             prcode(fp,
12272 "\n"
12273 "            sipKeepReference(%s, %d, %a%s);\n"
12274                 , (scope == NULL || isStatic(od) ? "SIP_NULLPTR" : "sipSelf"), ad->key, mod, ad, a, (((ad->atype == ascii_string_type || ad->atype == latin1_string_type || ad->atype == utf8_string_type) && ad->nrderefs == 1) || !isGetWrapper(ad) ? "Keep" : "Wrapper"));
12275         }
12276 
12277         /* Handle /TransferThis/ for non-factory methods. */
12278         if (!isFactory(od) && isThisTransferred(ad))
12279         {
12280             prcode(fp,
12281 "\n"
12282 "            if (sipOwner)\n"
12283 "                sipTransferTo(sipSelf, (PyObject *)sipOwner);\n"
12284 "            else\n"
12285 "                sipTransferBack(sipSelf);\n"
12286                     );
12287         }
12288     }
12289 
12290     if (isThisTransferredMeth(od))
12291         prcode(fp,
12292 "\n"
12293 "            sipTransferTo(sipSelf, SIP_NULLPTR);\n"
12294                 );
12295 
12296     gc_ellipsis(&od->pysig, fp);
12297 
12298     if (deltemps && !isZeroArgSlot(od->common))
12299         deleteTemps(mod, &od->pysig, fp);
12300 
12301     prcode(fp,
12302 "\n"
12303         );
12304 
12305     /* Handle the error flag if it was used. */
12306     error_value = ((isVoidReturnSlot(od->common) || isIntReturnSlot(od->common) || isSSizeReturnSlot(od->common) || isLongReturnSlot(od->common)) ? "-1" : "0");
12307 
12308     if (raisesPyException(od))
12309     {
12310         prcode(fp,
12311 "            if (PyErr_Occurred())\n"
12312 "                return %s;\n"
12313 "\n"
12314                 , error_value);
12315     }
12316     else if (error_flag)
12317     {
12318         if (!isZeroArgSlot(od->common))
12319             prcode(fp,
12320 "            if (sipError == sipErrorFail)\n"
12321 "                return %s;\n"
12322 "\n"
12323                 , error_value);
12324 
12325         prcode(fp,
12326 "            if (sipError == sipErrorNone)\n"
12327 "            {\n"
12328             );
12329     }
12330     else if (old_error_flag)
12331     {
12332         prcode(fp,
12333 "            if (sipIsErr)\n"
12334 "                return %s;\n"
12335 "\n"
12336             , error_value);
12337     }
12338 
12339     /* Call any post-hook. */
12340     if (od->posthook != NULL)
12341         prcode(fp,
12342 "\n"
12343 "            sipCallHook(\"%s\");\n"
12344             ,od->posthook);
12345 
12346     if (isVoidReturnSlot(od->common))
12347         prcode(fp,
12348 "            return 0;\n"
12349             );
12350     else if (isInplaceNumberSlot(od->common) || isInplaceSequenceSlot(od->common))
12351         prcode(fp,
12352 "            Py_INCREF(sipSelf);\n"
12353 "            return sipSelf;\n"
12354             );
12355     else if (isIntReturnSlot(od->common) || isSSizeReturnSlot(od->common) || isLongReturnSlot(od->common))
12356         prcode(fp,
12357 "            return sipRes;\n"
12358             );
12359     else
12360     {
12361         generateHandleResult(mod, od, needsNew, result_size,
12362                 (post_process ? "sipResObj =" : "return"), fp);
12363 
12364         /* Delete the temporaries now if we haven't already done so. */
12365         if (!deltemps)
12366             deleteTemps(mod, &od->pysig, fp);
12367 
12368         /*
12369          * Keep a reference to a pointer to a class if it isn't owned by
12370          * Python.
12371          */
12372         if (keepReference(res))
12373             prcode(fp,
12374 "\n"
12375 "            sipKeepReference(%s, %d, sipResObj);\n"
12376                 , (isStatic(od) ? "SIP_NULLPTR" : "sipSelf"), res->key);
12377 
12378         /*
12379          * Keep a reference to any argument with the result if the function is
12380          * a static factory.
12381          */
12382         if (static_factory)
12383         {
12384             for (a = 0; a < od->pysig.nrArgs; ++a)
12385             {
12386                 argDef *ad = &od->pysig.args[a];
12387 
12388                 if (!isInArg(ad))
12389                     continue;
12390 
12391                 if (keepReference(ad))
12392                 {
12393                     prcode(fp,
12394 "\n"
12395 "            sipKeepReference(sipResObj, %d, %a%s);\n"
12396                         , ad->key, mod, ad, a, (((ad->atype == ascii_string_type || ad->atype == latin1_string_type || ad->atype == utf8_string_type) && ad->nrderefs == 1) || !isGetWrapper(ad) ? "Keep" : "Wrapper"));
12397                 }
12398             }
12399         }
12400 
12401         if (post_process)
12402             prcode(fp,
12403 "\n"
12404 "            return sipResObj;\n"
12405                 );
12406     }
12407 
12408     if (error_flag)
12409     {
12410         prcode(fp,
12411 "            }\n"
12412             );
12413 
12414         if (!isZeroArgSlot(od->common))
12415             prcode(fp,
12416 "\n"
12417 "            sipAddException(sipError, &sipParseErr);\n"
12418                 );
12419     }
12420 
12421     prcode(fp,
12422 "        }\n"
12423         );
12424 
12425     /* Restore the full type of the result. */
12426     *res = orig_res;
12427 }
12428 
12429 
12430 /*
12431  * Generate a call to a C++ function.
12432  */
generateCppFunctionCall(moduleDef * mod,ifaceFileDef * scope,ifaceFileDef * o_scope,overDef * od,FILE * fp)12433 static void generateCppFunctionCall(moduleDef *mod, ifaceFileDef *scope,
12434         ifaceFileDef *o_scope, overDef *od, FILE *fp)
12435 {
12436     const char *mname = od->cppname;
12437     int parens = 1;
12438 
12439     /*
12440      * If the function is protected then call the public wrapper.  If it is
12441      * virtual then call the explicit scoped function if "self" was passed as
12442      * the first argument.
12443      */
12444 
12445     if (scope == NULL)
12446         prcode(fp, "%s(", mname);
12447     else if (scope->type == namespace_iface)
12448         prcode(fp, "%S::%s(", scope->fqcname, mname);
12449     else if (isStatic(od))
12450     {
12451         if (isProtected(od))
12452             prcode(fp, "sip%C::sipProtect_%s(", scope->fqcname, mname);
12453         else
12454             prcode(fp, "%S::%s(", o_scope->fqcname, mname);
12455     }
12456     else if (isProtected(od))
12457     {
12458         if (!isAbstract(od) && (isVirtual(od) || isVirtualReimp(od)))
12459         {
12460             prcode(fp, "sipCpp->sipProtectVirt_%s(sipSelfWasArg", mname);
12461 
12462             if (od->cppsig->nrArgs > 0)
12463                 prcode(fp, ",");
12464         }
12465         else
12466             prcode(fp, "sipCpp->sipProtect_%s(", mname);
12467     }
12468     else if (!isAbstract(od) && (isVirtual(od) || isVirtualReimp(od)))
12469     {
12470         prcode(fp, "(sipSelfWasArg ? sipCpp->%S::%s(", o_scope->fqcname, mname);
12471         generateCallArgs(mod, od->cppsig, &od->pysig, fp);
12472         prcode(fp, ") : sipCpp->%s(", mname);
12473         ++parens;
12474     }
12475     else
12476         prcode(fp, "sipCpp->%s(", mname);
12477 
12478     generateCallArgs(mod, od->cppsig, &od->pysig, fp);
12479 
12480     while (parens--)
12481         prcode(fp, ")");
12482 }
12483 
12484 
12485 /*
12486  * Generate argument to a slot.
12487  */
generateSlotArg(moduleDef * mod,signatureDef * sd,int argnr,FILE * fp)12488 static void generateSlotArg(moduleDef *mod, signatureDef *sd, int argnr,
12489         FILE *fp)
12490 {
12491     argDef *ad;
12492     int deref;
12493 
12494     ad = &sd->args[argnr];
12495     deref = ((ad->atype == class_type || ad->atype == mapped_type) && ad->nrderefs == 0);
12496 
12497     prcode(fp, "%s%a", (deref ? "*" : ""), mod, ad, argnr);
12498 }
12499 
12500 
12501 /*
12502  * Generate the call to a comparison slot method.
12503  */
generateComparisonSlotCall(moduleDef * mod,ifaceFileDef * scope,overDef * od,const char * op,const char * cop,int deref,FILE * fp)12504 static void generateComparisonSlotCall(moduleDef *mod, ifaceFileDef *scope,
12505         overDef *od, const char *op, const char *cop, int deref, FILE *fp)
12506 {
12507     if (isComplementary(od))
12508     {
12509         op = cop;
12510         prcode(fp, "!");
12511     }
12512 
12513     if (!isGlobal(od))
12514     {
12515         const char *deref_s = (deref ? "->" : ".");
12516 
12517         if (isAbstract(od))
12518             prcode(fp, "sipCpp%soperator%s(", deref_s, op);
12519         else
12520             prcode(fp, "sipCpp%s%S::operator%s(", deref_s, scope->fqcname, op);
12521     }
12522     else
12523     {
12524         /* If it has been moved from a namespace then get the C++ scope. */
12525         if (od->common->ns_scope != NULL)
12526             prcode(fp, "%S::", od->common->ns_scope->fqcname);
12527 
12528         if (deref)
12529             prcode(fp, "operator%s((*sipCpp), ", op);
12530         else
12531             prcode(fp, "operator%s(sipCpp, ", op);
12532     }
12533 
12534     generateSlotArg(mod, &od->pysig, 0, fp);
12535     prcode(fp, ")");
12536 }
12537 
12538 
12539 /*
12540  * Generate the call to a binary (non-number) slot method.
12541  */
generateBinarySlotCall(moduleDef * mod,ifaceFileDef * scope,overDef * od,const char * op,int deref,FILE * fp)12542 static void generateBinarySlotCall(moduleDef *mod, ifaceFileDef *scope,
12543         overDef *od, const char *op, int deref, FILE *fp)
12544 {
12545     generateComparisonSlotCall(mod, scope, od, op, "", deref, fp);
12546 }
12547 
12548 
12549 /*
12550  * Generate the call to a binary number slot method.
12551  */
generateNumberSlotCall(moduleDef * mod,overDef * od,char * op,FILE * fp)12552 static void generateNumberSlotCall(moduleDef *mod, overDef *od, char *op,
12553         FILE *fp)
12554 {
12555     prcode(fp, "(");
12556     generateSlotArg(mod, &od->pysig, 0, fp);
12557     prcode(fp, " %s ", op);
12558     generateSlotArg(mod, &od->pysig, 1, fp);
12559     prcode(fp, ")");
12560 }
12561 
12562 
12563 /*
12564  * Generate the argument variables for a member function/constructor/operator.
12565  */
generateArgParser(moduleDef * mod,signatureDef * sd,classDef * c_scope,mappedTypeDef * mt_scope,ctorDef * ct,overDef * od,FILE * fp)12566 static void generateArgParser(moduleDef *mod, signatureDef *sd,
12567         classDef *c_scope, mappedTypeDef *mt_scope, ctorDef *ct, overDef *od,
12568         FILE *fp)
12569 {
12570     int a, optargs, arraylenarg, handle_self, single_arg, need_owner;
12571     ifaceFileDef *scope;
12572     argDef *arraylenarg_ad;
12573 
12574     /* Suppress compiler warnings. */
12575     arraylenarg = 0;
12576     arraylenarg_ad = NULL;
12577 
12578     if (mt_scope != NULL)
12579         scope = mt_scope->iff;
12580     else if (c_scope != NULL)
12581     {
12582         /* If the class is just a namespace, then ignore it. */
12583         if (c_scope->iff->type == namespace_iface)
12584         {
12585             c_scope = NULL;
12586             scope = NULL;
12587         }
12588         else
12589             scope = c_scope->iff;
12590     }
12591     else
12592         scope = NULL;
12593 
12594     handle_self = (od != NULL && od->common->slot == no_slot && !isStatic(od) && c_scope != NULL);
12595 
12596     /*
12597      * Generate the local variables that will hold the parsed arguments and
12598      * values returned via arguments.
12599      */
12600     need_owner = FALSE;
12601 
12602     for (a = 0; a < sd->nrArgs; ++a)
12603     {
12604         argDef *ad = &sd->args[a];
12605 
12606         if (isArraySize(ad))
12607         {
12608             arraylenarg_ad = ad;
12609             arraylenarg = a;
12610         }
12611 
12612         generateVariable(mod, scope, ad, a, fp);
12613 
12614         if (isThisTransferred(ad))
12615             need_owner = TRUE;
12616     }
12617 
12618     if (od != NULL && need_owner)
12619         prcode(fp,
12620 "        sipWrapper *sipOwner = SIP_NULLPTR;\n"
12621             );
12622 
12623     if (handle_self)
12624     {
12625         const char *const_str = (isConst(od) ? "const " : "");
12626 
12627         if (isProtected(od) && hasShadow(c_scope))
12628             prcode(fp,
12629 "        %ssip%C *sipCpp;\n"
12630                 , const_str, classFQCName(c_scope));
12631         else
12632             prcode(fp,
12633 "        %s%U *sipCpp;\n"
12634                 , const_str, c_scope);
12635 
12636         prcode(fp,
12637 "\n"
12638             );
12639     }
12640     else if (sd->nrArgs != 0)
12641         prcode(fp,
12642 "\n"
12643             );
12644 
12645     /* Generate the call to the parser function. */
12646     single_arg = FALSE;
12647 
12648     if (od != NULL && isNumberSlot(od->common))
12649     {
12650         prcode(fp,
12651 "        if (sipParsePair(&sipParseErr, sipArg0, sipArg1, \"");
12652     }
12653     else if (od != NULL && od->common->slot == setattr_slot)
12654     {
12655         /*
12656          * We don't even try to invoke the parser if there is a value and there
12657          * shouldn't be (or vice versa) so that the list of errors doesn't get
12658          * poluted with signatures that can never apply.
12659          */
12660         prcode(fp,
12661 "        if (sipValue %s SIP_NULLPTR && sipParsePair(&sipParseErr, sipName, %s, \"", (isDelattr(od) ? "==" : "!="), (isDelattr(od) ? "SIP_NULLPTR" : "sipValue"));
12662     }
12663     else if ((od != NULL && useKeywordArgs(od->common)) || ct != NULL)
12664     {
12665         KwArgs kwargs;
12666         int is_ka_list;
12667 
12668         /*
12669          * We handle keywords if we might have been passed some (because one of
12670          * the overloads uses them or we are a ctor).  However this particular
12671          * overload might not have any.
12672          */
12673         if (od != NULL)
12674             kwargs = od->kwargs;
12675         else if (ct != NULL)
12676             kwargs = ct->kwargs;
12677         else
12678             kwargs = NoKwArgs;
12679 
12680         /*
12681          * The above test isn't good enough because when the flags were set in
12682          * the parser we couldn't know for sure if an argument was an output
12683          * pointer.  Therefore we check here.  The drawback is that we may
12684          * generate the name string for the argument but never use it, or we
12685          * might have an empty keyword name array or one that contains only
12686          * NULLs.
12687          */
12688         is_ka_list = FALSE;
12689 
12690         if (kwargs != NoKwArgs)
12691         {
12692             int a;
12693 
12694             for (a = 0; a < sd->nrArgs; ++a)
12695             {
12696                 argDef *ad = &sd->args[a];
12697 
12698                 if (isInArg(ad))
12699                 {
12700                     if (!is_ka_list)
12701                     {
12702                         prcode(fp,
12703 "        static const char *sipKwdList[] = {\n"
12704                             );
12705 
12706                         is_ka_list = TRUE;
12707                     }
12708 
12709                     if (ad->name != NULL && (kwargs == AllKwArgs || ad->defval != NULL))
12710                         prcode(fp,
12711 "            %N,\n"
12712                             , ad->name);
12713                     else
12714                         prcode(fp,
12715 "            SIP_NULLPTR,\n"
12716                             );
12717                 }
12718             }
12719 
12720             if (is_ka_list)
12721                 prcode(fp,
12722     "        };\n"
12723     "\n"
12724                     );
12725         }
12726 
12727         prcode(fp,
12728 "        if (sipParseKwdArgs(%ssipParseErr, sipArgs, sipKwds, %s, %s, \"", (ct != NULL ? "" : "&"), (is_ka_list ? "sipKwdList" : "SIP_NULLPTR"), (ct != NULL ? "sipUnused" : "SIP_NULLPTR"));
12729     }
12730     else
12731     {
12732         single_arg = (od != NULL && od->common->slot != no_slot && !isMultiArgSlot(od->common));
12733 
12734         prcode(fp,
12735 "        if (sipParseArgs(%ssipParseErr, sipArg%s, \"", (ct != NULL ? "" : "&"), (single_arg ? "" : "s"));
12736     }
12737 
12738     /* Generate the format string. */
12739     optargs = FALSE;
12740 
12741     if (single_arg)
12742         prcode(fp, "1");
12743 
12744     if (handle_self)
12745         prcode(fp,"%c",(isReallyProtected(od) ? 'p' : 'B'));
12746 
12747     for (a = 0; a < sd->nrArgs; ++a)
12748     {
12749         char *fmt = "";
12750         argDef *ad = &sd->args[a];
12751 
12752         if (!isInArg(ad))
12753             continue;
12754 
12755         if (ad->defval != NULL && !optargs)
12756         {
12757             prcode(fp,"|");
12758             optargs = TRUE;
12759         }
12760 
12761         switch (ad->atype)
12762         {
12763         case ascii_string_type:
12764             if (isString(ad))
12765                 fmt = "AA";
12766             else
12767                 fmt = "aA";
12768 
12769             break;
12770 
12771         case latin1_string_type:
12772             if (isString(ad))
12773                 fmt = "AL";
12774             else
12775                 fmt = "aL";
12776 
12777             break;
12778 
12779         case utf8_string_type:
12780             if (isString(ad))
12781                 fmt = "A8";
12782             else
12783                 fmt = "a8";
12784 
12785             break;
12786 
12787         case sstring_type:
12788         case ustring_type:
12789         case string_type:
12790             if (isArray(ad))
12791                 fmt = "k";
12792             else if (isString(ad))
12793                 fmt = "s";
12794             else
12795                 fmt = "c";
12796 
12797             break;
12798 
12799         case wstring_type:
12800             if (isArray(ad))
12801                 fmt = "K";
12802             else if (isString(ad))
12803                 fmt = "x";
12804             else
12805                 fmt = "w";
12806 
12807             break;
12808 
12809         case enum_type:
12810             if (ad->u.ed->fqcname == NULL)
12811                 fmt = "e";
12812             else if (isConstrained(ad))
12813                 fmt = "XE";
12814             else
12815                 fmt = "E";
12816             break;
12817 
12818         case bool_type:
12819             fmt = "b";
12820             break;
12821 
12822         case cbool_type:
12823             fmt = "Xb";
12824             break;
12825 
12826         case int_type:
12827             if (!isArraySize(ad))
12828                 fmt = "i";
12829 
12830             break;
12831 
12832         case uint_type:
12833             if (!isArraySize(ad))
12834                 fmt = "u";
12835 
12836             break;
12837 
12838         case size_type:
12839             if (!isArraySize(ad))
12840                 fmt = "=";
12841 
12842             break;
12843 
12844         case cint_type:
12845             fmt = "Xi";
12846             break;
12847 
12848         case byte_type:
12849         case sbyte_type:
12850             if (!isArraySize(ad))
12851                 fmt = "L";
12852 
12853             break;
12854 
12855         case ubyte_type:
12856             if (!isArraySize(ad))
12857                 fmt = "M";
12858 
12859             break;
12860 
12861         case short_type:
12862             if (!isArraySize(ad))
12863                 fmt = "h";
12864 
12865             break;
12866 
12867         case ushort_type:
12868             if (!isArraySize(ad))
12869                 fmt = "t";
12870 
12871             break;
12872 
12873         case long_type:
12874             if (!isArraySize(ad))
12875                 fmt = "l";
12876 
12877             break;
12878 
12879         case ulong_type:
12880             if (!isArraySize(ad))
12881                 fmt = "m";
12882 
12883             break;
12884 
12885         case longlong_type:
12886             if (!isArraySize(ad))
12887                 fmt = "n";
12888 
12889             break;
12890 
12891         case ulonglong_type:
12892             if (!isArraySize(ad))
12893                 fmt = "o";
12894 
12895             break;
12896 
12897         case struct_type:
12898         case void_type:
12899             fmt = "v";
12900             break;
12901 
12902         case capsule_type:
12903             fmt = "z";
12904             break;
12905 
12906         case float_type:
12907             fmt = "f";
12908             break;
12909 
12910         case cfloat_type:
12911             fmt = "Xf";
12912             break;
12913 
12914         case double_type:
12915             fmt = "d";
12916             break;
12917 
12918         case cdouble_type:
12919             fmt = "Xd";
12920             break;
12921 
12922         case mapped_type:
12923         case class_type:
12924             if (isArray(ad))
12925             {
12926                 if (ad->nrderefs != 1 || !isInArg(ad) || isReference(ad))
12927                     fatal("Mapped type or class with /Array/ is not a pointer\n");
12928 
12929                 if (ad->atype == mapped_type && noRelease(ad->u.mtd))
12930                     fatal("Mapped type does not support /Array/\n");
12931 
12932                 if (ad->atype == class_type && !(generating_c || arrayHelper(ad->u.cd)))
12933                 {
12934                     fatalScopedName(classFQCName(ad->u.cd));
12935                     fatal(" does not support /Array/\n");
12936                 }
12937 
12938                 fmt = "r";
12939             }
12940             else
12941             {
12942                 int saved_flags = ad->argflags;
12943 
12944                 /* /Transfer/ for ctor arguments is handled separately. */
12945                 if (ct != NULL)
12946                     resetIsTransferred(ad);
12947 
12948                 fmt = getSubFormatChar('J', ad);
12949 
12950                 ad->argflags = saved_flags;
12951             }
12952 
12953             break;
12954 
12955         case pyobject_type:
12956             fmt = getSubFormatChar('P',ad);
12957             break;
12958 
12959         case pytuple_type:
12960         case pylist_type:
12961         case pydict_type:
12962         case pyslice_type:
12963         case pytype_type:
12964             fmt = (isAllowNone(ad) ? "N" : "T");
12965             break;
12966 
12967         case pycallable_type:
12968             fmt = (isAllowNone(ad) ? "H" : "F");
12969             break;
12970 
12971         case pybuffer_type:
12972             fmt = (isAllowNone(ad) ? "$" : "!");
12973             break;
12974 
12975         case ellipsis_type:
12976             fmt = "W";
12977             break;
12978 
12979         /* Supress a compiler warning. */
12980         default:
12981             ;
12982         }
12983 
12984         /*
12985          * Get the wrapper if explicitly asked for or we are going to keep a
12986          * reference to.  However if it is an encoded string then we will get
12987          * the actual wrapper from the format character.
12988          */
12989         if (isGetWrapper(ad) || (keepReference(ad) && ad->atype != ascii_string_type && ad->atype != latin1_string_type && ad->atype != utf8_string_type) || (keepReference(ad) && ad->nrderefs != 1))
12990             prcode(fp, "@");
12991 
12992         prcode(fp,fmt);
12993     }
12994 
12995     prcode(fp,"\"");
12996 
12997     /* Generate the parameters corresponding to the format string. */
12998 
12999     if (handle_self)
13000         prcode(fp,", &sipSelf, sipType_%C, &sipCpp",classFQCName(c_scope));
13001 
13002     for (a = 0; a < sd->nrArgs; ++a)
13003     {
13004         argDef *ad = &sd->args[a];
13005 
13006         if (!isInArg(ad))
13007             continue;
13008 
13009         /* Use the wrapper name if it was explicitly asked for. */
13010         if (isGetWrapper(ad))
13011             prcode(fp, ", &%aWrapper", mod, ad, a);
13012         else if (keepReference(ad))
13013             prcode(fp, ", &%aKeep", mod, ad, a);
13014 
13015         switch (ad->atype)
13016         {
13017         case mapped_type:
13018             prcode(fp, ", sipType_%T,&%a", ad, mod, ad, a);
13019 
13020             if (isArray(ad))
13021             {
13022                 prcode(fp, ", &%a", mod, arraylenarg_ad, arraylenarg);
13023             }
13024             else if (!isConstrained(ad))
13025             {
13026                 if (noRelease(ad->u.mtd))
13027                     prcode(fp, ",SIP_NULLPTR");
13028                 else
13029                     prcode(fp, ", &%aState", mod, ad, a);
13030             }
13031 
13032             break;
13033 
13034         case class_type:
13035             prcode(fp, ", sipType_%T, &%a", ad, mod, ad, a);
13036 
13037             if (isArray(ad))
13038             {
13039                 prcode(fp, ", &%a", mod, arraylenarg_ad, arraylenarg);
13040             }
13041             else
13042             {
13043                 if (isThisTransferred(ad))
13044                     prcode(fp, ", %ssipOwner", (ct != NULL ? "" : "&"));
13045 
13046                 if (ad->u.cd->convtocode != NULL && !isConstrained(ad))
13047                     prcode(fp, ", &%aState", mod, ad, a);
13048             }
13049 
13050             break;
13051 
13052         case ascii_string_type:
13053             if (!keepReference(ad) && ad->nrderefs == 1)
13054                 prcode(fp, ", &%aKeep", mod, ad, a);
13055 
13056             prcode(fp, ", &%a", mod, ad, a);
13057             break;
13058 
13059         case latin1_string_type:
13060             if (!keepReference(ad) && ad->nrderefs == 1)
13061                 prcode(fp, ", &%aKeep", mod, ad, a);
13062 
13063             prcode(fp, ", &%a", mod, ad, a);
13064             break;
13065 
13066         case utf8_string_type:
13067             if (!keepReference(ad) && ad->nrderefs == 1)
13068                 prcode(fp, ", &%aKeep", mod, ad, a);
13069 
13070             prcode(fp, ", &%a", mod, ad, a);
13071             break;
13072 
13073         case pytuple_type:
13074             prcode(fp, ", &PyTuple_Type, &%a", mod, ad, a);
13075             break;
13076 
13077         case pylist_type:
13078             prcode(fp, ", &PyList_Type, &%a", mod, ad, a);
13079             break;
13080 
13081         case pydict_type:
13082             prcode(fp, ", &PyDict_Type, &%a", mod, ad, a);
13083             break;
13084 
13085         case pyslice_type:
13086             prcode(fp, ", &PySlice_Type, &%a", mod, ad, a);
13087             break;
13088 
13089         case pytype_type:
13090             prcode(fp, ", &PyType_Type, &%a", mod, ad, a);
13091             break;
13092 
13093         case enum_type:
13094             if (ad->u.ed->fqcname != NULL)
13095                 prcode(fp, ", sipType_%C", ad->u.ed->fqcname);
13096 
13097             prcode(fp, ", &%a", mod, ad, a);
13098             break;
13099 
13100         case capsule_type:
13101             prcode(fp, ", \"%S\", &%a", ad->u.cap, mod, ad, a);
13102             break;
13103 
13104         default:
13105             if (!isArraySize(ad))
13106                 prcode(fp, ", &%a", mod, ad, a);
13107 
13108             if (isArray(ad))
13109                 prcode(fp, ", &%a", mod, arraylenarg_ad, arraylenarg);
13110         }
13111     }
13112 
13113     prcode(fp,"))\n");
13114 }
13115 
13116 
13117 /*
13118  * Get the format character string for something that has sub-formats.
13119  */
13120 
getSubFormatChar(char fc,argDef * ad)13121 static char *getSubFormatChar(char fc, argDef *ad)
13122 {
13123     static char fmt[3];
13124     char flags;
13125 
13126     flags = 0;
13127 
13128     if (isTransferred(ad))
13129         flags |= 0x02;
13130 
13131     if (isTransferredBack(ad))
13132         flags |= 0x04;
13133 
13134     if (ad->atype == class_type || ad->atype == mapped_type)
13135     {
13136         if (ad->nrderefs == 0 || isDisallowNone(ad))
13137             flags |= 0x01;
13138 
13139         if (isThisTransferred(ad))
13140             flags |= 0x10;
13141 
13142         if (isConstrained(ad) || (ad->atype == class_type && ad->u.cd->convtocode == NULL))
13143             flags |= 0x08;
13144     }
13145 
13146     fmt[0] = fc;
13147     fmt[1] = '0' + flags;
13148     fmt[2] = '\0';
13149 
13150     return fmt;
13151 }
13152 
13153 
13154 /*
13155  * Return TRUE if a type has %ConvertToTypeCode.
13156  */
hasConvertToCode(argDef * ad)13157 static int hasConvertToCode(argDef *ad)
13158 {
13159     codeBlockList *convtocode;
13160 
13161     if (ad->atype == class_type && !isConstrained(ad))
13162         convtocode = ad->u.cd->convtocode;
13163     else if (ad->atype == mapped_type && !isConstrained(ad))
13164         convtocode = ad->u.mtd->convtocode;
13165     else
13166         convtocode = NULL;
13167 
13168     return (convtocode != NULL);
13169 }
13170 
13171 
13172 /*
13173  * Garbage collect any ellipsis argument.
13174  */
gc_ellipsis(signatureDef * sd,FILE * fp)13175 static void gc_ellipsis(signatureDef *sd, FILE *fp)
13176 {
13177     if (sd->nrArgs > 0 && sd->args[sd->nrArgs - 1].atype == ellipsis_type)
13178         prcode(fp,
13179 "\n"
13180 "            Py_DECREF(a%d);\n"
13181             , sd->nrArgs - 1);
13182 }
13183 
13184 
13185 /*
13186  * Delete any instances created to hold /Out/ arguments.
13187  */
deleteOuts(moduleDef * mod,signatureDef * sd,FILE * fp)13188 static void deleteOuts(moduleDef *mod, signatureDef *sd, FILE *fp)
13189 {
13190     int a;
13191 
13192     for (a = 0; a < sd->nrArgs; ++a)
13193     {
13194         argDef *ad = &sd->args[a];
13195 
13196         if (needNewInstance(ad))
13197             prcode(fp,
13198 "                delete %a;\n"
13199                 , mod, ad, a);
13200     }
13201 }
13202 
13203 
13204 
13205 /*
13206  * Delete any temporary variables on the heap created by type convertors.
13207  */
deleteTemps(moduleDef * mod,signatureDef * sd,FILE * fp)13208 static void deleteTemps(moduleDef *mod, signatureDef *sd, FILE *fp)
13209 {
13210     int a;
13211 
13212     for (a = 0; a < sd->nrArgs; ++a)
13213     {
13214         argDef *ad = &sd->args[a];
13215 
13216         if (isArray(ad) && (ad->atype == mapped_type || ad->atype == class_type))
13217         {
13218             if (!isTransferred(ad))
13219             {
13220                 if (generating_c)
13221                     prcode(fp,
13222 "            sipFree(%a);\n"
13223                         , mod, ad, a);
13224                 else
13225                     prcode(fp,
13226 "            delete[] %a;\n"
13227                         , mod, ad, a);
13228             }
13229 
13230             continue;
13231         }
13232 
13233         if (!isInArg(ad))
13234             continue;
13235 
13236         if ((ad->atype == ascii_string_type || ad->atype == latin1_string_type || ad->atype == utf8_string_type) && ad->nrderefs == 1)
13237         {
13238             prcode(fp,
13239 "            Py_%sDECREF(%aKeep);\n"
13240                 , (ad->defval != NULL ? "X" : ""), mod, ad, a);
13241         }
13242         else if (ad->atype == wstring_type && ad->nrderefs == 1)
13243         {
13244             if (generating_c || !isConstArg(ad))
13245                 prcode(fp,
13246 "            sipFree(%a);\n"
13247                     , mod, ad, a);
13248             else
13249                 prcode(fp,
13250 "            sipFree(const_cast<wchar_t *>(%a));\n"
13251                     , mod, ad, a);
13252         }
13253         else if (hasConvertToCode(ad))
13254         {
13255             if (ad->atype == mapped_type && noRelease(ad->u.mtd))
13256                 continue;
13257 
13258             if (generating_c || !isConstArg(ad))
13259                 prcode(fp,
13260 "            sipReleaseType(%a,sipType_%T,%aState);\n"
13261                     , mod, ad, a, ad, mod, ad, a);
13262             else
13263                 prcode(fp,
13264 "            sipReleaseType(const_cast<%b *>(%a),sipType_%T,%aState);\n"
13265                     , ad, mod, ad, a, ad, mod, ad, a);
13266         }
13267     }
13268 }
13269 
13270 
13271 /*
13272  * Generate a list of C++ code blocks.
13273  */
generateCppCodeBlock(codeBlockList * cbl,FILE * fp)13274 static void generateCppCodeBlock(codeBlockList *cbl, FILE *fp)
13275 {
13276     int reset_line = FALSE;
13277 
13278     while (cbl != NULL)
13279     {
13280         codeBlock *cb = cbl->block;
13281 
13282         /*
13283          * Fragmented fragments (possibly created when applying template types)
13284          * don't have a filename.
13285          */
13286         if (cb->filename != NULL)
13287         {
13288             generatePreprocLine(cb->linenr, cb->filename, fp);
13289             reset_line = TRUE;
13290         }
13291 
13292         prcode(fp, "%s", cb->frag);
13293 
13294         cbl = cbl->next;
13295     }
13296 
13297     if (reset_line)
13298         generatePreprocLine(currentLineNr + 1, currentFileName, fp);
13299 }
13300 
13301 
13302 /*
13303  * Generate a #line preprocessor directive.
13304  */
generatePreprocLine(int linenr,const char * fname,FILE * fp)13305 static void generatePreprocLine(int linenr, const char *fname, FILE *fp)
13306 {
13307     prcode(fp,
13308 "#line %d \"", linenr);
13309 
13310     while (*fname != '\0')
13311     {
13312         prcode(fp, "%c", *fname);
13313 
13314         if (*fname == '\\')
13315             prcode(fp, "\\");
13316 
13317         ++fname;
13318     }
13319 
13320     prcode(fp, "\"\n"
13321         );
13322 }
13323 
13324 
13325 /*
13326  * Create a source file.
13327  */
createCompilationUnit(moduleDef * mod,stringList ** generated,const char * fname,const char * description)13328 static FILE *createCompilationUnit(moduleDef *mod, stringList **generated,
13329         const char *fname, const char *description)
13330 {
13331     FILE *fp = createFile(mod, fname, description);
13332 
13333     appendString(generated, sipStrdup(fname));
13334 
13335     generateCppCodeBlock(mod->unitcode, fp);
13336 
13337     return fp;
13338 }
13339 
13340 
13341 /*
13342  * Create a file with an optional standard header.
13343  */
createFile(moduleDef * mod,const char * fname,const char * description)13344 static FILE *createFile(moduleDef *mod, const char *fname,
13345         const char *description)
13346 {
13347     FILE *fp;
13348 
13349     /* Create the file. */
13350     if ((fp = fopen(fname, "w")) == NULL)
13351         fatal("Unable to create file \"%s\"\n",fname);
13352 
13353     /* The "stack" doesn't have to be very deep. */
13354     previousLineNr = currentLineNr;
13355     currentLineNr = 1;
13356     previousFileName = currentFileName;
13357     currentFileName = fname;
13358 
13359     if (description != NULL)
13360     {
13361         /* Write the header. */
13362         prcode(fp,
13363 "/*\n"
13364 " * %s\n"
13365 " *\n"
13366 " * Generated by SIP %s\n"
13367             , description
13368             , sipVersionStr);
13369 
13370         prCopying(fp, mod, " *");
13371 
13372         prcode(fp,
13373 " */\n"
13374             );
13375     }
13376 
13377     return fp;
13378 }
13379 
13380 
13381 /*
13382  * Generate any copying (ie. licensing) text as a comment.
13383  */
prCopying(FILE * fp,moduleDef * mod,const char * comment)13384 void prCopying(FILE *fp, moduleDef *mod, const char *comment)
13385 {
13386     int needComment = TRUE;
13387     codeBlockList *cbl;
13388 
13389     if (mod->copying != NULL)
13390         prcode(fp, "%s\n", comment);
13391 
13392     for (cbl = mod->copying; cbl != NULL; cbl = cbl->next)
13393     {
13394         const char *cp;
13395 
13396         for (cp = cbl->block->frag; *cp != '\0'; ++cp)
13397         {
13398             if (needComment)
13399             {
13400                 needComment = FALSE;
13401                 prcode(fp, "%s ", comment);
13402             }
13403 
13404             prcode(fp, "%c", *cp);
13405 
13406             if (*cp == '\n')
13407                 needComment = TRUE;
13408         }
13409     }
13410 }
13411 
13412 
13413 /*
13414  * Close a file and report any errors.
13415  */
closeFile(FILE * fp)13416 static void closeFile(FILE *fp)
13417 {
13418     if (ferror(fp))
13419         fatal("Error writing to \"%s\"\n",currentFileName);
13420 
13421     if (fclose(fp))
13422         fatal("Error closing \"%s\"\n",currentFileName);
13423 
13424     currentLineNr = previousLineNr;
13425     currentFileName = previousFileName;
13426 }
13427 
13428 
13429 /*
13430  * Print formatted code.
13431  */
prcode(FILE * fp,const char * fmt,...)13432 void prcode(FILE *fp, const char *fmt, ...)
13433 {
13434     char ch;
13435     va_list ap;
13436 
13437     prcode_last = fmt;
13438 
13439     va_start(ap,fmt);
13440 
13441     while ((ch = *fmt++) != '\0')
13442         if (ch == '%')
13443         {
13444             ch = *fmt++;
13445 
13446             switch (ch)
13447             {
13448             case 'a':
13449                 {
13450                     moduleDef *mod = va_arg(ap, moduleDef *);
13451                     argDef *ad = va_arg(ap, argDef *);
13452                     int argnr = va_arg(ap, int);
13453 
13454                     if (useArgNames(mod) && ad->name != NULL)
13455                         fprintf(fp, "%s", ad->name->text);
13456                     else
13457                         fprintf(fp, "a%d", argnr);
13458 
13459                     break;
13460                 }
13461 
13462             case 'A':
13463                 {
13464                     ifaceFileDef *scope = va_arg(ap, ifaceFileDef *);
13465                     argDef *ad = va_arg(ap, argDef *);
13466 
13467                     generateBaseType(scope, ad, TRUE, STRIP_NONE, fp);
13468                     break;
13469                 }
13470 
13471             case 'b':
13472                 {
13473                     argDef *ad, orig;
13474 
13475                     ad = va_arg(ap,argDef *);
13476                     orig = *ad;
13477 
13478                     resetIsConstArg(ad);
13479                     resetIsReference(ad);
13480                     ad->nrderefs = 0;
13481 
13482                     generateBaseType(NULL, ad, TRUE, STRIP_NONE, fp);
13483 
13484                     *ad = orig;
13485 
13486                     break;
13487                 }
13488 
13489             case 'B':
13490                 generateBaseType(NULL, va_arg(ap,argDef *), TRUE, STRIP_NONE,
13491                         fp);
13492                 break;
13493 
13494             case 'c':
13495                 {
13496                     char c = (char)va_arg(ap,int);
13497 
13498                     if (c == '\n')
13499                         ++currentLineNr;
13500 
13501                     fputc(c,fp);
13502                     break;
13503                 }
13504 
13505             case 'C':
13506                 prScopedName(fp,
13507                         removeGlobalScope(va_arg(ap,scopedNameDef *)), "_");
13508                 break;
13509 
13510             case 'd':
13511                 fprintf(fp,"%d",va_arg(ap,int));
13512                 break;
13513 
13514             case 'D':
13515                 {
13516                     /*
13517                      * This is the same as 'b' but never uses a typedef's name.
13518                      */
13519                     argDef *ad, orig;
13520 
13521                     ad = va_arg(ap,argDef *);
13522                     orig = *ad;
13523 
13524                     resetIsConstArg(ad);
13525                     resetIsReference(ad);
13526                     ad->nrderefs = 0;
13527 
13528                     generateBaseType(NULL, ad, FALSE, STRIP_NONE, fp);
13529 
13530                     *ad = orig;
13531 
13532                     break;
13533                 }
13534 
13535             case 'E':
13536                 {
13537                     enumDef *ed = va_arg(ap,enumDef *);
13538 
13539                     if (ed->fqcname == NULL || isProtectedEnum(ed))
13540                         fprintf(fp,"int");
13541                     else
13542                         prScopedName(fp, ed->fqcname, "::");
13543 
13544                     break;
13545                 }
13546 
13547             case 'F':
13548                 prScopedName(fp,
13549                         removeGlobalScope(va_arg(ap,scopedNameDef *)), "");
13550                 break;
13551 
13552             case 'g':
13553                 fprintf(fp,"%g",va_arg(ap,double));
13554                 break;
13555 
13556             case 'I':
13557                 {
13558                     int indent = va_arg(ap,int);
13559 
13560                     while (indent-- > 0)
13561                         fputc('\t',fp);
13562 
13563                     break;
13564                 }
13565 
13566             case 'l':
13567                 fprintf(fp,"%ld",va_arg(ap,long));
13568                 break;
13569 
13570             case 'L':
13571                 {
13572                     ifaceFileDef *iff = va_arg(ap, ifaceFileDef *);
13573 
13574                     prScopedName(fp, removeGlobalScope(iff->fqcname), "_");
13575 
13576                     if (iff->api_range != NULL)
13577                         fprintf(fp, "_%d", iff->api_range->index);
13578 
13579                     break;
13580                 }
13581 
13582             case 'M':
13583                 prcode_xml = !prcode_xml;
13584                 break;
13585 
13586             case 'n':
13587                 {
13588                     nameDef *nd = va_arg(ap,nameDef *);
13589 
13590                     prCachedName(fp, nd, "sipNameNr_");
13591                     break;
13592                 }
13593 
13594             case 'N':
13595                 {
13596                     nameDef *nd = va_arg(ap,nameDef *);
13597 
13598                     prCachedName(fp, nd, "sipName_");
13599                     break;
13600                 }
13601 
13602             case 'O':
13603                 prOverloadName(fp, va_arg(ap, overDef *));
13604                 break;
13605 
13606             case 'P':
13607                 {
13608                     apiVersionRangeDef *avr = va_arg(ap, apiVersionRangeDef *);
13609 
13610                     fprintf(fp, "%d", (avr != NULL ? avr->index : -1));
13611 
13612                     break;
13613                 }
13614 
13615             case 's':
13616                 {
13617                     const char *cp = va_arg(ap,const char *);
13618 
13619                     while (*cp != '\0')
13620                     {
13621                         if (*cp == '\n')
13622                             ++currentLineNr;
13623 
13624                         fputc(*cp,fp);
13625                         ++cp;
13626                     }
13627 
13628                     break;
13629                 }
13630 
13631             case 'S':
13632                 prScopedName(fp, va_arg(ap, scopedNameDef *), "::");
13633                 break;
13634 
13635             case 'T':
13636                 prTypeName(fp, va_arg(ap,argDef *));
13637                 break;
13638 
13639             case 'u':
13640                 fprintf(fp,"%u",va_arg(ap,unsigned));
13641                 break;
13642 
13643             case 'U':
13644                 {
13645                     classDef *cd = va_arg(ap, classDef *);
13646 
13647                     if (generating_c)
13648                         fprintf(fp,"struct ");
13649 
13650                     prScopedClassName(fp, cd->iff, cd, STRIP_NONE);
13651                     break;
13652                 }
13653 
13654             case 'V':
13655                 prScopedName(fp,
13656                         removeGlobalScope(va_arg(ap, scopedNameDef *)), "::");
13657                 break;
13658 
13659             case 'x':
13660                 fprintf(fp,"0x%08x",va_arg(ap,unsigned));
13661                 break;
13662 
13663             case 'X':
13664                 generateThrowSpecifier(va_arg(ap,throwArgs *),fp);
13665                 break;
13666 
13667             case '\n':
13668                 fputc('\n',fp);
13669                 ++currentLineNr;
13670                 break;
13671 
13672             case '\0':
13673                 fputc('%',fp);
13674                 --fmt;
13675                 break;
13676 
13677             default:
13678                 fputc(ch,fp);
13679             }
13680         }
13681         else if (ch == '\n')
13682         {
13683             fputc('\n',fp);
13684             ++currentLineNr;
13685         }
13686         else
13687             fputc(ch,fp);
13688 
13689     va_end(ap);
13690 }
13691 
13692 
13693 /*
13694  * Generate the symbolic name of a cached name.
13695  */
prCachedName(FILE * fp,nameDef * nd,const char * prefix)13696 static void prCachedName(FILE *fp, nameDef *nd, const char *prefix)
13697 {
13698     prcode(fp, "%s", prefix);
13699 
13700     /*
13701      * If the name seems to be a template then just use the offset to ensure
13702      * that it is unique.
13703      */
13704     if (strchr(nd->text, '<') != NULL)
13705         prcode(fp, "%d", nd->offset);
13706     else
13707     {
13708         const char *cp;
13709 
13710         /* Handle C++ and Python scopes. */
13711         for (cp = nd->text; *cp != '\0'; ++cp)
13712         {
13713             char ch = *cp;
13714 
13715             if (ch == ':' || ch == '.')
13716                 ch = '_';
13717 
13718             prcode(fp, "%c", ch);
13719         }
13720     }
13721 }
13722 
13723 
13724 /*
13725  * Generate the C++ name of an overloaded function.
13726  */
prOverloadName(FILE * fp,overDef * od)13727 void prOverloadName(FILE *fp, overDef *od)
13728 {
13729     const char *pt1, *pt2;
13730 
13731     pt1 = "operator";
13732 
13733     switch (od->common->slot)
13734     {
13735     case add_slot:
13736         pt2 = "+";
13737         break;
13738 
13739     case sub_slot:
13740         pt2 = "-";
13741         break;
13742 
13743     case mul_slot:
13744         pt2 = "*";
13745         break;
13746 
13747     case truediv_slot:
13748         pt2 = "/";
13749         break;
13750 
13751     case mod_slot:
13752         pt2 = "%";
13753         break;
13754 
13755     case and_slot:
13756         pt2 = "&";
13757         break;
13758 
13759     case or_slot:
13760         pt2 = "|";
13761         break;
13762 
13763     case xor_slot:
13764         pt2 = "^";
13765         break;
13766 
13767     case lshift_slot:
13768         pt2 = "<<";
13769         break;
13770 
13771     case rshift_slot:
13772         pt2 = ">>";
13773         break;
13774 
13775     case iadd_slot:
13776         pt2 = "+=";
13777         break;
13778 
13779     case isub_slot:
13780         pt2 = "-=";
13781         break;
13782 
13783     case imul_slot:
13784         pt2 = "*=";
13785         break;
13786 
13787     case itruediv_slot:
13788         pt2 = "/=";
13789         break;
13790 
13791     case imod_slot:
13792         pt2 = "%=";
13793         break;
13794 
13795     case iand_slot:
13796         pt2 = "&=";
13797         break;
13798 
13799     case ior_slot:
13800         pt2 = "|=";
13801         break;
13802 
13803     case ixor_slot:
13804         pt2 = "^=";
13805         break;
13806 
13807     case ilshift_slot:
13808         pt2 = "<<=";
13809         break;
13810 
13811     case irshift_slot:
13812         pt2 = ">>=";
13813         break;
13814 
13815     case invert_slot:
13816         pt2 = "~";
13817         break;
13818 
13819     case call_slot:
13820         pt2 = "()";
13821         break;
13822 
13823     case getitem_slot:
13824         pt2 = "[]";
13825         break;
13826 
13827     case lt_slot:
13828         pt2 = "<";
13829         break;
13830 
13831     case le_slot:
13832         pt2 = "<=";
13833         break;
13834 
13835     case eq_slot:
13836         pt2 = "==";
13837         break;
13838 
13839     case ne_slot:
13840         pt2 = "!=";
13841         break;
13842 
13843     case gt_slot:
13844         pt2 = ">";
13845         break;
13846 
13847     case ge_slot:
13848         pt2 = ">=";
13849         break;
13850 
13851     default:
13852         pt1 = "";
13853         pt2 = od->cppname;
13854     }
13855 
13856     if (fp != NULL)
13857         fprintf(fp, "%s%s", pt1, pt2);
13858     else
13859         fatalAppend("%s%s", pt1, pt2);
13860 }
13861 
13862 
13863 /*
13864  * Generate a scoped name with the given separator string.
13865  */
prScopedName(FILE * fp,scopedNameDef * snd,char * sep)13866 static void prScopedName(FILE *fp, scopedNameDef *snd, char *sep)
13867 {
13868     while (snd != NULL)
13869     {
13870         /* Precede an explicit global scope with a space to avoid '<::'. */
13871         fprintf(fp, "%s", (snd->name[0] != '\0' ? snd->name : " "));
13872 
13873         if ((snd = snd->next) != NULL)
13874             fprintf(fp, "%s", sep);
13875     }
13876 }
13877 
13878 
13879 /*
13880  * Generate a scoped class name.  Protected classes have to be explicitly
13881  * scoped.
13882  */
prScopedClassName(FILE * fp,ifaceFileDef * scope,classDef * cd,int strip)13883 static void prScopedClassName(FILE *fp, ifaceFileDef *scope, classDef *cd,
13884         int strip)
13885 {
13886     if (useTemplateName(cd))
13887     {
13888         prTemplateType(fp, scope, cd->td, strip);
13889     }
13890     else if (isProtectedClass(cd))
13891     {
13892         /* This should never happen. */
13893         if (scope == NULL)
13894             scope = cd->iff;
13895 
13896         prcode(fp, "sip%C::sip%s", scope->fqcname, classBaseName(cd));
13897     }
13898     else
13899     {
13900         prScopedName(fp, stripScope(classFQCName(cd), strip), "::");
13901     }
13902 }
13903 
13904 
13905 /*
13906  * Generate a type name to be used as part of an identifier name.
13907  */
prTypeName(FILE * fp,argDef * ad)13908 static void prTypeName(FILE *fp, argDef *ad)
13909 {
13910     scopedNameDef *snd;
13911 
13912     switch (ad->atype)
13913     {
13914     case struct_type:
13915         snd = ad->u.sname;
13916         break;
13917 
13918     case defined_type:
13919         snd = ad->u.snd;
13920         break;
13921 
13922     case enum_type:
13923         snd = ad->u.ed->fqcname;
13924         break;
13925 
13926     case mapped_type:
13927         snd = ad->u.mtd->iff->fqcname;
13928         break;
13929 
13930     case class_type:
13931         snd = classFQCName(ad->u.cd);
13932         break;
13933 
13934     default:
13935         /* This should never happen. */
13936         snd = NULL;
13937     }
13938 
13939     if (snd != NULL)
13940         prcode(fp, "%C", snd);
13941 }
13942 
13943 
13944 /*
13945  * Return TRUE if handwritten code uses the error flag.
13946  */
needErrorFlag(codeBlockList * cbl)13947 static int needErrorFlag(codeBlockList *cbl)
13948 {
13949     return usedInCode(cbl, "sipError");
13950 }
13951 
13952 
13953 /*
13954  * Return TRUE if handwritten code uses the deprecated error flag.
13955  */
needOldErrorFlag(codeBlockList * cbl)13956 static int needOldErrorFlag(codeBlockList *cbl)
13957 {
13958     return usedInCode(cbl, "sipIsErr");
13959 }
13960 
13961 
13962 /*
13963  * Return TRUE if the argument type means an instance needs to be created on
13964  * the heap to pass back to Python.
13965  */
needNewInstance(argDef * ad)13966 static int needNewInstance(argDef *ad)
13967 {
13968     return ((ad->atype == mapped_type || ad->atype == class_type) &&
13969         ((isReference(ad) && ad->nrderefs == 0) || (!isReference(ad) && ad->nrderefs == 1)) &&
13970         !isInArg(ad) && isOutArg(ad));
13971 }
13972 
13973 
13974 /*
13975  * Convert any protected arguments (ie. those whose type is unavailable outside
13976  * of a shadow class) to a fundamental type to be used instead (with suitable
13977  * casts).
13978  */
fakeProtectedArgs(signatureDef * sd)13979 static void fakeProtectedArgs(signatureDef *sd)
13980 {
13981     int a;
13982     argDef *ad = sd->args;
13983 
13984     for (a = 0; a < sd->nrArgs; ++a)
13985     {
13986         if (ad->atype == class_type && isProtectedClass(ad->u.cd))
13987         {
13988             ad->atype = fake_void_type;
13989             ad->nrderefs = 1;
13990             resetIsReference(ad);
13991         }
13992         else if (ad->atype == enum_type && isProtectedEnum(ad->u.ed))
13993             ad->atype = int_type;
13994 
13995         ++ad;
13996     }
13997 }
13998 
13999 
14000 /*
14001  * Reset and save any argument flags so that the signature will be rendered
14002  * exactly as defined in C++.
14003  */
normaliseArgs(signatureDef * sd)14004 void normaliseArgs(signatureDef *sd)
14005 {
14006     int a;
14007     argDef *ad = sd->args;
14008 
14009     for (a = 0; a < sd->nrArgs; ++a)
14010     {
14011         if (ad->atype == class_type && isProtectedClass(ad->u.cd))
14012         {
14013             resetIsProtectedClass(ad->u.cd);
14014             setWasProtectedClass(ad->u.cd);
14015         }
14016         else if (ad->atype == enum_type && isProtectedEnum(ad->u.ed))
14017         {
14018             resetIsProtectedEnum(ad->u.ed);
14019             setWasProtectedEnum(ad->u.ed);
14020         }
14021 
14022         ++ad;
14023     }
14024 }
14025 
14026 
14027 /*
14028  * Restore any argument flags modified by normaliseArgs().
14029  */
restoreArgs(signatureDef * sd)14030 void restoreArgs(signatureDef *sd)
14031 {
14032     int a;
14033     argDef *ad = sd->args;
14034 
14035     for (a = 0; a < sd->nrArgs; ++a)
14036     {
14037         if (ad->atype == class_type && wasProtectedClass(ad->u.cd))
14038         {
14039             resetWasProtectedClass(ad->u.cd);
14040             setIsProtectedClass(ad->u.cd);
14041         }
14042         else if (ad->atype == enum_type && wasProtectedEnum(ad->u.ed))
14043         {
14044             resetWasProtectedEnum(ad->u.ed);
14045             setIsProtectedEnum(ad->u.ed);
14046         }
14047 
14048         ++ad;
14049     }
14050 }
14051 
14052 
14053 /*
14054  * Return TRUE if a dealloc function is needed for a class.
14055  */
needDealloc(classDef * cd)14056 static int needDealloc(classDef *cd)
14057 {
14058     if (cd->iff->type == namespace_iface)
14059         return FALSE;
14060 
14061     /* All of these conditions cause some code to be generated. */
14062 
14063     if (tracing)
14064         return TRUE;
14065 
14066     if (generating_c)
14067         return TRUE;
14068 
14069     if (cd->dealloccode != NULL)
14070         return TRUE;
14071 
14072     if (isPublicDtor(cd))
14073         return TRUE;
14074 
14075     if (hasShadow(cd))
14076         return TRUE;
14077 
14078     return FALSE;
14079 }
14080 
14081 
14082 /*
14083  * Return the argument name to use in a function definition for handwritten
14084  * code.
14085  */
argName(const char * name,codeBlockList * cbl)14086 static const char *argName(const char *name, codeBlockList *cbl)
14087 {
14088     static const char noname[] = "";
14089 
14090     /* Always use the name in C code. */
14091     if (generating_c)
14092         return name;
14093 
14094     /* Use the name if it is used in the handwritten code. */
14095     if (usedInCode(cbl, name))
14096         return name;
14097 
14098     /* Don't use the name and avoid a compiler warning. */
14099     return noname;
14100 }
14101 
14102 
14103 /*
14104  * Returns TRUE if a string is used in code.
14105  */
usedInCode(codeBlockList * cbl,const char * str)14106 static int usedInCode(codeBlockList *cbl, const char *str)
14107 {
14108     while (cbl != NULL)
14109     {
14110         if (strstr(cbl->block->frag, str) != NULL)
14111             return TRUE;
14112 
14113         cbl = cbl->next;
14114     }
14115 
14116     return FALSE;
14117 }
14118 
14119 
14120 /*
14121  * Generate an assignment statement from a void * variable to a class instance
14122  * variable.
14123  */
generateClassFromVoid(classDef * cd,const char * cname,const char * vname,FILE * fp)14124 static void generateClassFromVoid(classDef *cd, const char *cname,
14125         const char *vname, FILE *fp)
14126 {
14127     if (generating_c)
14128         prcode(fp, "struct %S *%s = (struct %S *)%s", classFQCName(cd), cname, classFQCName(cd), vname);
14129     else
14130         prcode(fp, "%S *%s = reinterpret_cast<%S *>(%s)", classFQCName(cd), cname, classFQCName(cd), vname);
14131 }
14132 
14133 
14134 /*
14135  * Generate an assignment statement from a void * variable to a mapped type
14136  * variable.
14137  */
generateMappedTypeFromVoid(mappedTypeDef * mtd,const char * cname,const char * vname,FILE * fp)14138 static void generateMappedTypeFromVoid(mappedTypeDef *mtd, const char *cname,
14139         const char *vname, FILE *fp)
14140 {
14141     if (generating_c)
14142         prcode(fp, "%b *%s = (%b *)%s", &mtd->type, cname, &mtd->type, vname);
14143     else
14144         prcode(fp, "%b *%s = reinterpret_cast<%b *>(%s)", &mtd->type, cname, &mtd->type, vname);
14145 }
14146 
14147 
14148 /*
14149  * Returns TRUE if the argument has a type that requires an extra reference to
14150  * the originating object to be kept.
14151  */
keepPyReference(argDef * ad)14152 static int keepPyReference(argDef *ad)
14153 {
14154     if (ad->atype == ascii_string_type || ad->atype == latin1_string_type ||
14155             ad->atype == utf8_string_type || ad->atype == ustring_type ||
14156             ad->atype == sstring_type || ad->atype == string_type)
14157     {
14158         if (!isReference(ad) && ad->nrderefs > 0)
14159             return TRUE;
14160     }
14161 
14162     return FALSE;
14163 }
14164 
14165 
14166 /*
14167  * Return the encoding character for the given type.
14168  */
getEncoding(argDef * ad)14169 static char getEncoding(argDef *ad)
14170 {
14171     char encoding;
14172 
14173     switch (ad->atype)
14174     {
14175     case ascii_string_type:
14176         encoding = 'A';
14177         break;
14178 
14179     case latin1_string_type:
14180         encoding = 'L';
14181         break;
14182 
14183     case utf8_string_type:
14184         encoding = '8';
14185         break;
14186 
14187     case wstring_type:
14188         encoding = ((ad->nrderefs == 0) ? 'w' : 'W');
14189         break;
14190 
14191     default:
14192         encoding = 'N';
14193     }
14194 
14195     return encoding;
14196 }
14197 
14198 
14199 /*
14200  * Return TRUE if a docstring can be automatically generated for a function
14201  * overload.
14202  */
overloadHasAutoDocstring(sipSpec * pt,overDef * od)14203 static int overloadHasAutoDocstring(sipSpec *pt, overDef *od)
14204 {
14205     if (!docstrings)
14206         return FALSE;
14207 
14208     /* If it is versioned then make sure it is the default API. */
14209     return inDefaultAPI(pt, od->api_range);
14210 }
14211 
14212 
14213 /*
14214  * Return TRUE if a function/method has a docstring.
14215  */
hasMemberDocstring(sipSpec * pt,overDef * overs,memberDef * md,ifaceFileDef * scope)14216 static int hasMemberDocstring(sipSpec *pt, overDef *overs, memberDef *md,
14217         ifaceFileDef *scope)
14218 {
14219     int auto_docstring = FALSE;
14220     overDef *od;
14221 
14222     /*
14223      * Check for any explicit docstrings and remember if there were any that
14224      * could be automatically generated.
14225      */
14226     for (od = overs; od != NULL; od = od->next)
14227     {
14228         if (od->common != md)
14229             continue;
14230 
14231         if (isPrivate(od) || isSignal(od))
14232             continue;
14233 
14234         if (od->docstring != NULL)
14235             return TRUE;
14236 
14237         if (overloadHasAutoDocstring(pt, od))
14238             auto_docstring = TRUE;
14239     }
14240 
14241     if (noArgParser(md))
14242         return FALSE;
14243 
14244     if (scope != NULL && !inDefaultAPI(pt, scope->api_range))
14245         return FALSE;
14246 
14247     return auto_docstring;
14248 }
14249 
14250 
14251 /*
14252  * Generate the docstring for all overloads of a function/method.  Return TRUE
14253  * if the docstring was entirely automatically generated.
14254  */
generateMemberDocstring(sipSpec * pt,overDef * overs,memberDef * md,int is_method,FILE * fp)14255 static int generateMemberDocstring(sipSpec *pt, overDef *overs, memberDef *md,
14256         int is_method, FILE *fp)
14257 {
14258     int auto_docstring = TRUE;
14259     int is_first, all_auto, any_implied;
14260     static const char *newline = "\\n\"\n\"";
14261     overDef *od;
14262 
14263     /* See if all the docstrings are automatically generated. */
14264     all_auto = TRUE;
14265     any_implied = FALSE;
14266 
14267     for (od = overs; od != NULL; od = od->next)
14268     {
14269         if (od->common != md)
14270             continue;
14271 
14272         if (isPrivate(od) || isSignal(od))
14273             continue;
14274 
14275         if (od->docstring != NULL)
14276         {
14277             all_auto = FALSE;
14278 
14279             if (od->docstring->signature != discarded)
14280                 any_implied = TRUE;
14281         }
14282     }
14283 
14284     /* Generate the docstring. */
14285     is_first = TRUE;
14286 
14287     for (od = overs; od != NULL; od = od->next)
14288     {
14289         if (od->common != md)
14290             continue;
14291 
14292         if (isPrivate(od) || isSignal(od))
14293             continue;
14294 
14295         if (!is_first)
14296         {
14297             prcode(fp, newline);
14298 
14299             /*
14300              * Insert a blank line if any explicit docstring wants to include a
14301              * signature.  This maintains compatibility with previous versions.
14302              */
14303             if (any_implied)
14304                 prcode(fp, newline);
14305         }
14306 
14307         if (od->docstring != NULL)
14308         {
14309             if (od->docstring->signature == prepended)
14310             {
14311                 generateMemberAutoDocstring(pt, od, is_method, fp);
14312                 prcode(fp, newline);
14313             }
14314 
14315             generateDocstringText(od->docstring, fp);
14316 
14317             if (od->docstring->signature == appended)
14318             {
14319                 prcode(fp, newline);
14320                 generateMemberAutoDocstring(pt, od, is_method, fp);
14321             }
14322 
14323             auto_docstring = FALSE;
14324         }
14325         else if (all_auto || any_implied)
14326         {
14327             generateMemberAutoDocstring(pt, od, is_method, fp);
14328         }
14329 
14330         is_first = FALSE;
14331     }
14332 
14333     return auto_docstring;
14334 }
14335 
14336 
14337 /*
14338  * Generate the automatic docstring for a function/method.
14339  */
generateMemberAutoDocstring(sipSpec * pt,overDef * od,int is_method,FILE * fp)14340 static void generateMemberAutoDocstring(sipSpec *pt, overDef *od,
14341         int is_method, FILE *fp)
14342 {
14343     if (overloadHasAutoDocstring(pt, od))
14344     {
14345         dsOverload(pt, od, is_method, fp);
14346         ++currentLineNr;
14347     }
14348 }
14349 
14350 
14351 /*
14352  * Return TRUE if a docstring can be automatically generated for a ctor.
14353  */
ctorHasAutoDocstring(sipSpec * pt,ctorDef * ct)14354 static int ctorHasAutoDocstring(sipSpec *pt, ctorDef *ct)
14355 {
14356     if (!docstrings)
14357         return FALSE;
14358 
14359     /* If it is versioned then make sure it is the default API. */
14360     return inDefaultAPI(pt, ct->api_range);
14361 }
14362 
14363 
14364 /*
14365  * Return TRUE if a class has a docstring.
14366  */
hasClassDocstring(sipSpec * pt,classDef * cd)14367 static int hasClassDocstring(sipSpec *pt, classDef *cd)
14368 {
14369     int auto_docstring = FALSE;
14370     ctorDef *ct;
14371 
14372     /*
14373      * Check for any explicit docstrings and remember if there were any that
14374      * could be automatically generated.
14375      */
14376     if (cd->docstring != NULL)
14377         return TRUE;
14378 
14379     for (ct = cd->ctors; ct != NULL; ct = ct->next)
14380     {
14381         if (isPrivateCtor(ct))
14382             continue;
14383 
14384         if (ct->docstring != NULL)
14385             return TRUE;
14386 
14387         if (ctorHasAutoDocstring(pt, ct))
14388             auto_docstring = TRUE;
14389     }
14390 
14391     if (!canCreate(cd))
14392         return FALSE;
14393 
14394     if (!inDefaultAPI(pt, cd->iff->api_range))
14395         return FALSE;
14396 
14397     return auto_docstring;
14398 }
14399 
14400 
14401 /*
14402  * Generate the docstring for a class.
14403  */
generateClassDocstring(sipSpec * pt,classDef * cd,FILE * fp)14404 static void generateClassDocstring(sipSpec *pt, classDef *cd, FILE *fp)
14405 {
14406     int is_first, all_auto, any_implied;
14407     static const char *newline = "\\n\"\n\"";
14408     ctorDef *ct;
14409 
14410     /* See if all the docstrings are automatically generated. */
14411     all_auto = (cd->docstring == NULL);
14412     any_implied = FALSE;
14413 
14414     for (ct = cd->ctors; ct != NULL; ct = ct->next)
14415     {
14416         if (isPrivateCtor(ct))
14417             continue;
14418 
14419         if (ct->docstring != NULL)
14420         {
14421             all_auto = FALSE;
14422 
14423             if (ct->docstring->signature != discarded)
14424                 any_implied = TRUE;
14425         }
14426     }
14427 
14428     /* Generate the docstring. */
14429     if (all_auto)
14430         prcode(fp, "\\1");
14431 
14432     if (cd->docstring != NULL && cd->docstring->signature != prepended)
14433     {
14434         generateDocstringText(cd->docstring, fp);
14435         is_first = FALSE;
14436     }
14437     else
14438     {
14439         is_first = TRUE;
14440     }
14441 
14442     if (cd->docstring == NULL || cd->docstring->signature != discarded)
14443     {
14444         for (ct = cd->ctors; ct != NULL; ct = ct->next)
14445         {
14446             if (isPrivateCtor(ct))
14447                 continue;
14448 
14449             if (!is_first)
14450             {
14451                 prcode(fp, newline);
14452 
14453                 /*
14454                  * Insert a blank line if any explicit docstring wants to
14455                  * include a signature.  This maintains compatibility with
14456                  * previous versions.
14457                  */
14458                 if (any_implied)
14459                     prcode(fp, newline);
14460             }
14461 
14462             if (ct->docstring != NULL)
14463             {
14464                 if (ct->docstring->signature == prepended)
14465                 {
14466                     generateCtorAutoDocstring(pt, cd, ct, fp);
14467                     prcode(fp, newline);
14468                 }
14469 
14470                 generateDocstringText(ct->docstring, fp);
14471 
14472                 if (ct->docstring->signature == appended)
14473                 {
14474                     prcode(fp, newline);
14475                     generateCtorAutoDocstring(pt, cd, ct, fp);
14476                 }
14477             }
14478             else if (all_auto || any_implied)
14479             {
14480                 generateCtorAutoDocstring(pt, cd, ct, fp);
14481             }
14482 
14483             is_first = FALSE;
14484         }
14485     }
14486 
14487     if (cd->docstring != NULL && cd->docstring->signature == prepended)
14488     {
14489         if (!is_first)
14490         {
14491             prcode(fp, newline);
14492             prcode(fp, newline);
14493         }
14494 
14495         generateDocstringText(cd->docstring, fp);
14496     }
14497 }
14498 
14499 
14500 /*
14501  * Generate the automatic docstring for a ctor.
14502  */
generateCtorAutoDocstring(sipSpec * pt,classDef * cd,ctorDef * ct,FILE * fp)14503 static void generateCtorAutoDocstring(sipSpec *pt, classDef *cd, ctorDef *ct,
14504         FILE *fp)
14505 {
14506     if (ctorHasAutoDocstring(pt, ct))
14507     {
14508         dsCtor(pt, cd, ct, fp);
14509         ++currentLineNr;
14510     }
14511 }
14512 
14513 
14514 /*
14515  * Generate the text of a docstring.
14516  */
generateDocstringText(docstringDef * docstring,FILE * fp)14517 static void generateDocstringText(docstringDef *docstring, FILE *fp)
14518 {
14519     const char *cp;
14520 
14521     for (cp = docstring->text; *cp != '\0'; ++cp)
14522     {
14523         if (*cp == '\n')
14524         {
14525             /* Ignore if this is the last character. */
14526             if (cp[1] != '\0')
14527                 prcode(fp, "\\n\"\n\"");
14528         }
14529         else
14530         {
14531             if (*cp == '\\' || *cp == '\"')
14532                 prcode(fp, "\\");
14533 
14534             prcode(fp, "%c", *cp);
14535         }
14536     }
14537 }
14538 
14539 
14540 /*
14541  * Generate the definition of a module's optional docstring.
14542  */
generateModDocstring(moduleDef * mod,FILE * fp)14543 static void generateModDocstring(moduleDef *mod, FILE *fp)
14544 {
14545     if (mod->docstring != NULL)
14546     {
14547         prcode(fp,
14548 "\n"
14549 "PyDoc_STRVAR(doc_mod_%s, \"", mod->name);
14550 
14551         generateDocstringText(mod->docstring, fp);
14552 
14553         prcode(fp, "\");\n"
14554             );
14555     }
14556 }
14557 
14558 
14559 /*
14560  * Generate a void* cast for an argument if needed.
14561  */
generateVoidPtrCast(argDef * ad,FILE * fp)14562 static void generateVoidPtrCast(argDef *ad, FILE *fp)
14563 {
14564     /*
14565      * Generate a cast if the argument's type was a typedef.  This allows us to
14566      * use typedef's to void* to hide something more complex that we don't
14567      * handle.
14568      */
14569     if (ad->original_type != NULL)
14570         prcode(fp, "(%svoid *)", (isConstArg(ad) ? "const " : ""));
14571 }
14572 
14573 
14574 /*
14575  * Declare the use of the limited API.
14576  */
declareLimitedAPI(int py_debug,moduleDef * mod,FILE * fp)14577 static void declareLimitedAPI(int py_debug, moduleDef *mod, FILE *fp)
14578 {
14579     if (!py_debug && (mod == NULL || useLimitedAPI(mod)))
14580         prcode(fp,
14581 "\n"
14582 "#if !defined(Py_LIMITED_API)\n"
14583 "#define Py_LIMITED_API\n"
14584 "#endif\n"
14585             );
14586 }
14587 
14588 
14589 /*
14590  * Generate the PyQt5 signals table.
14591  */
generatePluginSignalsTable(sipSpec * pt,classDef * cd,FILE * fp)14592 static int generatePluginSignalsTable(sipSpec *pt, classDef *cd, FILE *fp)
14593 {
14594     int is_signals = FALSE;
14595 
14596     if (isQObjectSubClass(cd))
14597     {
14598         memberDef *md;
14599 
14600         /* The signals must be grouped by name. */
14601         for (md = cd->members; md != NULL; md = md->next)
14602         {
14603             overDef *od;
14604             int membernr = md->membernr;
14605 
14606             for (od = cd->overs; od != NULL; od = od->next)
14607             {
14608                 if (od->common != md || !isSignal(od))
14609                     continue;
14610 
14611                 if (membernr >= 0)
14612                 {
14613                     /* See if there is a non-signal overload. */
14614 
14615                     overDef *nsig;
14616 
14617                     for (nsig = cd->overs; nsig != NULL; nsig = nsig->next)
14618                         if (nsig != od && nsig->common == md && !isSignal(nsig))
14619                             break;
14620 
14621                     if (nsig == NULL)
14622                         membernr = -1;
14623                 }
14624 
14625                 if (!is_signals)
14626                 {
14627                     is_signals = TRUE;
14628 
14629                     if (pluginPyQt5(pt))
14630                         generatePyQt5Emitters(cd, fp);
14631 
14632                     prcode(fp,
14633 "\n"
14634 "\n"
14635 "/* Define this type's signals. */\n"
14636 "static const pyqt5QtSignal signals_%C[] = {\n"
14637                         , classFQCName(cd));
14638                 }
14639 
14640                 /*
14641                  * We enable a hack that supplies any missing optional
14642                  * arguments.  We only include the version with all arguments
14643                  * and provide an emitter function which handles the optional
14644                  * arguments.
14645                  */
14646                 generateSignalTableEntry(pt, cd, od, membernr,
14647                         hasOptionalArgs(od), fp);
14648 
14649                 membernr = -1;
14650             }
14651         }
14652 
14653         if (is_signals)
14654             prcode(fp,
14655 "    {SIP_NULLPTR, SIP_NULLPTR, SIP_NULLPTR, SIP_NULLPTR}\n"
14656 "};\n"
14657                 );
14658     }
14659 
14660     return is_signals;
14661 }
14662 
14663 
14664 /*
14665  * Generate any extended class definition data for PyQt5.  Return TRUE if there
14666  * was something generated.
14667  */
generatePyQt5ClassPlugin(sipSpec * pt,classDef * cd,FILE * fp)14668 static int generatePyQt5ClassPlugin(sipSpec *pt, classDef *cd, FILE *fp)
14669 {
14670     int is_signals = generatePluginSignalsTable(pt, cd, fp);
14671 
14672     prcode(fp,
14673 "\n"
14674 "\n"
14675 "static pyqt5ClassPluginDef plugin_%L = {\n"
14676         , cd->iff);
14677 
14678     if (isQObjectSubClass(cd) && !noPyQtQMetaObject(cd))
14679         prcode(fp,
14680 "    &%U::staticMetaObject,\n"
14681             , cd);
14682     else
14683         prcode(fp,
14684 "    SIP_NULLPTR,\n"
14685             );
14686 
14687     prcode(fp,
14688 "    %u,\n"
14689         , cd->pyqt_flags);
14690 
14691     if (is_signals)
14692         prcode(fp,
14693 "    signals_%C,\n"
14694             , classFQCName(cd));
14695     else
14696         prcode(fp,
14697 "    SIP_NULLPTR,\n"
14698             );
14699 
14700     if (cd->pyqt_interface != NULL)
14701         prcode(fp,
14702 "    \"%s\"\n"
14703             , cd->pyqt_interface);
14704     else
14705         prcode(fp,
14706 "    SIP_NULLPTR\n"
14707             );
14708 
14709     prcode(fp,
14710 "};\n"
14711         );
14712 
14713     return TRUE;
14714 }
14715 
14716 
14717 /*
14718  * Generate the entries in a table of PyMethodDef for global functions.
14719  */
generateGlobalFunctionTableEntries(sipSpec * pt,moduleDef * mod,memberDef * members,FILE * fp)14720 static void generateGlobalFunctionTableEntries(sipSpec *pt, moduleDef *mod,
14721         memberDef *members, FILE *fp)
14722 {
14723     memberDef *md;
14724 
14725     for (md = members; md != NULL; md = md->next)
14726     {
14727         if (md->slot == no_slot && notVersioned(md))
14728         {
14729             prcode(fp,
14730 "        {%N, ", md->pyname);
14731 
14732             if (noArgParser(md) || useKeywordArgs(md))
14733                 prcode(fp, "SIP_MLMETH_CAST(func_%s), METH_VARARGS|METH_KEYWORDS", md->pyname->text);
14734             else
14735                 prcode(fp, "func_%s, METH_VARARGS", md->pyname->text);
14736 
14737             if (hasMemberDocstring(pt, mod->overs, md, NULL))
14738                 prcode(fp, ", doc_%s},\n"
14739                     , md->pyname->text);
14740             else
14741                 prcode(fp, ", SIP_NULLPTR},\n"
14742                     );
14743         }
14744     }
14745 }
14746 
14747 
14748 /*
14749  * Generate a template type.
14750  */
prTemplateType(FILE * fp,ifaceFileDef * scope,templateDef * td,int strip)14751 static void prTemplateType(FILE *fp, ifaceFileDef *scope, templateDef *td,
14752         int strip)
14753 {
14754     static const char tail[] = ">";
14755     int a;
14756 
14757     if (prcode_xml)
14758         strip = STRIP_GLOBAL;
14759 
14760     prcode(fp, "%S%s", stripScope(td->fqname, strip),
14761             (prcode_xml ? "&lt;" : "<"));
14762 
14763     for (a = 0; a < td->types.nrArgs; ++a)
14764     {
14765         if (a > 0)
14766             prcode(fp, ",");
14767 
14768         generateBaseType(scope, &td->types.args[a], TRUE, strip, fp);
14769     }
14770 
14771     if (prcode_last == tail)
14772         prcode(fp, " ");
14773 
14774     prcode(fp, (prcode_xml ? "&gt;" : tail));
14775 }
14776 
14777 
14778 /*
14779  * Strip the leading scopes from a scoped name as required.
14780  */
stripScope(scopedNameDef * snd,int strip)14781 static scopedNameDef *stripScope(scopedNameDef *snd, int strip)
14782 {
14783     if (strip != STRIP_NONE)
14784     {
14785         snd = removeGlobalScope(snd);
14786 
14787         while (strip-- > 0 && snd->next != NULL)
14788             snd = snd->next;
14789     }
14790 
14791     return snd;
14792 }
14793 
14794 
14795 /*
14796  * Generate the scope of a member of an unscoped enum.
14797  */
prEnumMemberScope(enumMemberDef * emd,FILE * fp)14798 static void prEnumMemberScope(enumMemberDef *emd, FILE *fp)
14799 {
14800     classDef *ecd = emd->ed->ecd;
14801 
14802     if (isProtectedEnum(emd->ed))
14803         prcode(fp, "sip%C", classFQCName(ecd));
14804     else if (isProtectedClass(ecd))
14805         prcode(fp, "%U", ecd);
14806     else
14807         prcode(fp, "%S", classFQCName(ecd));
14808 }
14809 
14810 
14811 /*
14812  * Generate the inclusion of sip.h.
14813  */
generate_include_sip_h(FILE * fp)14814 static void generate_include_sip_h(FILE *fp)
14815 {
14816     prcode(fp,
14817 "\n"
14818 "#include \"sip.h\"\n"
14819         );
14820 }
14821