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 ? "&" : "&"));
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 ? "<" : "<"));
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 ? ">" : 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