Interrogate enum class support (maps to Python 3.4 enums), sanify wrapper code

This commit is contained in:
rdb 2016-05-07 00:42:59 +02:00
parent aa5f2685ab
commit fb78fe6e2a
30 changed files with 4774 additions and 5109 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,19 @@
/* A Bison parser, made by GNU Bison 2.7. */ /* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison interface for Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
@ -26,13 +26,13 @@
special exception, which will cause the skeleton and the resulting special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public Bison output files to be licensed under the GNU General Public
License without this special exception. License without this special exception.
This special exception was added by the Free Software Foundation in This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ version 2.2 of Bison. */
#ifndef YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED #ifndef YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
# define YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED # define YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
/* Enabling traces. */ /* Debug traces. */
#ifndef YYDEBUG #ifndef YYDEBUG
# define YYDEBUG 0 # define YYDEBUG 0
#endif #endif
@ -40,134 +40,133 @@
extern int cppyydebug; extern int cppyydebug;
#endif #endif
/* Tokens. */ /* Token type. */
#ifndef YYTOKENTYPE #ifndef YYTOKENTYPE
# define YYTOKENTYPE # define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers enum yytokentype
know about them. */ {
enum yytokentype { REAL = 258,
REAL = 258, INTEGER = 259,
INTEGER = 259, CHAR_TOK = 260,
CHAR_TOK = 260, SIMPLE_STRING = 261,
SIMPLE_STRING = 261, SIMPLE_IDENTIFIER = 262,
SIMPLE_IDENTIFIER = 262, STRING_LITERAL = 263,
STRING_LITERAL = 263, CUSTOM_LITERAL = 264,
CUSTOM_LITERAL = 264, IDENTIFIER = 265,
IDENTIFIER = 265, TYPENAME_IDENTIFIER = 266,
TYPENAME_IDENTIFIER = 266, SCOPING = 267,
SCOPING = 267, TYPEDEFNAME = 268,
TYPEDEFNAME = 268, ELLIPSIS = 269,
ELLIPSIS = 269, OROR = 270,
OROR = 270, ANDAND = 271,
ANDAND = 271, EQCOMPARE = 272,
EQCOMPARE = 272, NECOMPARE = 273,
NECOMPARE = 273, LECOMPARE = 274,
LECOMPARE = 274, GECOMPARE = 275,
GECOMPARE = 275, LSHIFT = 276,
LSHIFT = 276, RSHIFT = 277,
RSHIFT = 277, POINTSAT_STAR = 278,
POINTSAT_STAR = 278, DOT_STAR = 279,
DOT_STAR = 279, UNARY = 280,
UNARY = 280, UNARY_NOT = 281,
UNARY_NOT = 281, UNARY_NEGATE = 282,
UNARY_NEGATE = 282, UNARY_MINUS = 283,
UNARY_MINUS = 283, UNARY_PLUS = 284,
UNARY_PLUS = 284, UNARY_STAR = 285,
UNARY_STAR = 285, UNARY_REF = 286,
UNARY_REF = 286, POINTSAT = 287,
POINTSAT = 287, SCOPE = 288,
SCOPE = 288, PLUSPLUS = 289,
PLUSPLUS = 289, MINUSMINUS = 290,
MINUSMINUS = 290, TIMESEQUAL = 291,
TIMESEQUAL = 291, DIVIDEEQUAL = 292,
DIVIDEEQUAL = 292, MODEQUAL = 293,
MODEQUAL = 293, PLUSEQUAL = 294,
PLUSEQUAL = 294, MINUSEQUAL = 295,
MINUSEQUAL = 295, OREQUAL = 296,
OREQUAL = 296, ANDEQUAL = 297,
ANDEQUAL = 297, XOREQUAL = 298,
XOREQUAL = 298, LSHIFTEQUAL = 299,
LSHIFTEQUAL = 299, RSHIFTEQUAL = 300,
RSHIFTEQUAL = 300, KW_ALIGNAS = 301,
KW_ALIGNAS = 301, KW_ALIGNOF = 302,
KW_ALIGNOF = 302, KW_AUTO = 303,
KW_AUTO = 303, KW_BEGIN_PUBLISH = 304,
KW_BEGIN_PUBLISH = 304, KW_BLOCKING = 305,
KW_BLOCKING = 305, KW_BOOL = 306,
KW_BOOL = 306, KW_CATCH = 307,
KW_CATCH = 307, KW_CHAR = 308,
KW_CHAR = 308, KW_CHAR16_T = 309,
KW_CHAR16_T = 309, KW_CHAR32_T = 310,
KW_CHAR32_T = 310, KW_CLASS = 311,
KW_CLASS = 311, KW_CONST = 312,
KW_CONST = 312, KW_CONSTEXPR = 313,
KW_CONSTEXPR = 313, KW_CONST_CAST = 314,
KW_CONST_CAST = 314, KW_DECLTYPE = 315,
KW_DECLTYPE = 315, KW_DEFAULT = 316,
KW_DEFAULT = 316, KW_DELETE = 317,
KW_DELETE = 317, KW_DOUBLE = 318,
KW_DOUBLE = 318, KW_DYNAMIC_CAST = 319,
KW_DYNAMIC_CAST = 319, KW_ELSE = 320,
KW_ELSE = 320, KW_END_PUBLISH = 321,
KW_END_PUBLISH = 321, KW_ENUM = 322,
KW_ENUM = 322, KW_EXTENSION = 323,
KW_EXTENSION = 323, KW_EXTERN = 324,
KW_EXTERN = 324, KW_EXPLICIT = 325,
KW_EXPLICIT = 325, KW_PUBLISHED = 326,
KW_PUBLISHED = 326, KW_FALSE = 327,
KW_FALSE = 327, KW_FINAL = 328,
KW_FINAL = 328, KW_FLOAT = 329,
KW_FLOAT = 329, KW_FRIEND = 330,
KW_FRIEND = 330, KW_FOR = 331,
KW_FOR = 331, KW_GOTO = 332,
KW_GOTO = 332, KW_IF = 333,
KW_IF = 333, KW_INLINE = 334,
KW_INLINE = 334, KW_INT = 335,
KW_INT = 335, KW_LONG = 336,
KW_LONG = 336, KW_MAKE_PROPERTY = 337,
KW_MAKE_PROPERTY = 337, KW_MAKE_PROPERTY2 = 338,
KW_MAKE_PROPERTY2 = 338, KW_MAKE_SEQ = 339,
KW_MAKE_SEQ = 339, KW_MUTABLE = 340,
KW_MUTABLE = 340, KW_NAMESPACE = 341,
KW_NAMESPACE = 341, KW_NEW = 342,
KW_NEW = 342, KW_NOEXCEPT = 343,
KW_NOEXCEPT = 343, KW_NULLPTR = 344,
KW_NULLPTR = 344, KW_OPERATOR = 345,
KW_OPERATOR = 345, KW_OVERRIDE = 346,
KW_OVERRIDE = 346, KW_PRIVATE = 347,
KW_PRIVATE = 347, KW_PROTECTED = 348,
KW_PROTECTED = 348, KW_PUBLIC = 349,
KW_PUBLIC = 349, KW_REGISTER = 350,
KW_REGISTER = 350, KW_REINTERPRET_CAST = 351,
KW_REINTERPRET_CAST = 351, KW_RETURN = 352,
KW_RETURN = 352, KW_SHORT = 353,
KW_SHORT = 353, KW_SIGNED = 354,
KW_SIGNED = 354, KW_SIZEOF = 355,
KW_SIZEOF = 355, KW_STATIC = 356,
KW_STATIC = 356, KW_STATIC_ASSERT = 357,
KW_STATIC_ASSERT = 357, KW_STATIC_CAST = 358,
KW_STATIC_CAST = 358, KW_STRUCT = 359,
KW_STRUCT = 359, KW_TEMPLATE = 360,
KW_TEMPLATE = 360, KW_THREAD_LOCAL = 361,
KW_THREAD_LOCAL = 361, KW_THROW = 362,
KW_THROW = 362, KW_TRUE = 363,
KW_TRUE = 363, KW_TRY = 364,
KW_TRY = 364, KW_TYPEDEF = 365,
KW_TYPEDEF = 365, KW_TYPEID = 366,
KW_TYPEID = 366, KW_TYPENAME = 367,
KW_TYPENAME = 367, KW_UNION = 368,
KW_UNION = 368, KW_UNSIGNED = 369,
KW_UNSIGNED = 369, KW_USING = 370,
KW_USING = 370, KW_VIRTUAL = 371,
KW_VIRTUAL = 371, KW_VOID = 372,
KW_VOID = 372, KW_VOLATILE = 373,
KW_VOLATILE = 373, KW_WCHAR_T = 374,
KW_WCHAR_T = 374, KW_WHILE = 375,
KW_WHILE = 375, START_CPP = 376,
START_CPP = 376, START_CONST_EXPR = 377,
START_CONST_EXPR = 377, START_TYPE = 378
START_TYPE = 378 };
};
#endif #endif
/* Tokens. */ /* Tokens. */
#define REAL 258 #define REAL 258
@ -292,40 +291,24 @@ extern int cppyydebug;
#define START_CONST_EXPR 377 #define START_CONST_EXPR 377
#define START_TYPE 378 #define START_TYPE 378
/* Value type. */
/* Location type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE typedef struct YYLTYPE YYLTYPE;
struct YYLTYPE
{ {
int first_line; int first_line;
int first_column; int first_column;
int last_line; int last_line;
int last_column; int last_column;
} YYLTYPE; };
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
# define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1 # define YYLTYPE_IS_TRIVIAL 1
#endif #endif
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int cppyyparse (void *YYPARSE_PARAM);
#else
int cppyyparse ();
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
int cppyyparse (void); int cppyyparse (void);
#else
int cppyyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED */ #endif /* !YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED */

View File

@ -2349,21 +2349,23 @@ enum:
; ;
enum_decl: enum_decl:
enum_keyword name_no_final ':' enum_element_type enum_keyword ':' enum_element_type
{ {
current_enum = new CPPEnumType($2, $4, current_scope, @1.file); current_enum = new CPPEnumType($1, NULL, $3, current_scope, NULL, @1.file);
}
| enum_keyword name_no_final
{
current_enum = new CPPEnumType($2, current_scope, @1.file);
}
| enum_keyword ':' enum_element_type
{
current_enum = new CPPEnumType(NULL, $3, current_scope, @1.file);
} }
| enum_keyword | enum_keyword
{ {
current_enum = new CPPEnumType(NULL, current_scope, @1.file); current_enum = new CPPEnumType($1, NULL, current_scope, NULL, @1.file);
}
| enum_keyword name_no_final ':' enum_element_type
{
CPPScope *new_scope = new CPPScope(current_scope, $2->_names.back(), V_public);
current_enum = new CPPEnumType($1, $2, $4, current_scope, new_scope, @1.file);
}
| enum_keyword name_no_final
{
CPPScope *new_scope = new CPPScope(current_scope, $2->_names.back(), V_public);
current_enum = new CPPEnumType($1, $2, current_scope, new_scope, @1.file);
} }
; ;
@ -2383,14 +2385,12 @@ enum_body_trailing_comma:
| enum_body_trailing_comma name ',' | enum_body_trailing_comma name ','
{ {
assert(current_enum != NULL); assert(current_enum != NULL);
CPPInstance *inst = current_enum->add_element($2->get_simple_name()); current_enum->add_element($2->get_simple_name(), NULL, current_lexer, @2);
current_scope->add_enum_value(inst, current_lexer, @2);
} }
| enum_body_trailing_comma name '=' const_expr ',' | enum_body_trailing_comma name '=' const_expr ','
{ {
assert(current_enum != NULL); assert(current_enum != NULL);
CPPInstance *inst = current_enum->add_element($2->get_simple_name(), $4); current_enum->add_element($2->get_simple_name(), $4, current_lexer, @2);
current_scope->add_enum_value(inst, current_lexer, @2);
}; };
enum_body: enum_body:
@ -2398,14 +2398,12 @@ enum_body:
| enum_body_trailing_comma name | enum_body_trailing_comma name
{ {
assert(current_enum != NULL); assert(current_enum != NULL);
CPPInstance *inst = current_enum->add_element($2->get_simple_name()); current_enum->add_element($2->get_simple_name(), NULL, current_lexer, @2);
current_scope->add_enum_value(inst, current_lexer, @2);
} }
| enum_body_trailing_comma name '=' const_expr | enum_body_trailing_comma name '=' const_expr
{ {
assert(current_enum != NULL); assert(current_enum != NULL);
CPPInstance *inst = current_enum->add_element($2->get_simple_name(), $4); current_enum->add_element($2->get_simple_name(), $4, current_lexer, @2);
current_scope->add_enum_value(inst, current_lexer, @2);
} }
; ;
@ -2413,6 +2411,14 @@ enum_keyword:
KW_ENUM KW_ENUM
{ {
$$ = CPPExtensionType::T_enum; $$ = CPPExtensionType::T_enum;
}
| KW_ENUM KW_CLASS
{
$$ = CPPExtensionType::T_enum_class;
}
| KW_ENUM KW_STRUCT
{
$$ = CPPExtensionType::T_enum_struct;
} }
; ;
@ -3495,6 +3501,24 @@ name:
| KW_OVERRIDE | KW_OVERRIDE
{ {
$$ = new CPPIdentifier("override", @1); $$ = new CPPIdentifier("override", @1);
}
| KW_SIGNED
{
// This is not a keyword in Python, so it is useful to be able to use this
// in MAKE_PROPERTY definitions, etc.
$$ = new CPPIdentifier("signed", @1);
}
| KW_FLOAT
{
$$ = new CPPIdentifier("float", @1);
}
| KW_PUBLIC
{
$$ = new CPPIdentifier("public", @1);
}
| KW_PRIVATE
{
$$ = new CPPIdentifier("private", @1);
} }
; ;

View File

@ -22,42 +22,53 @@
#include "indent.h" #include "indent.h"
/** /**
* Creates an untyped, unscoped enum. * Creates an untyped enum.
*/ */
CPPEnumType:: CPPEnumType::
CPPEnumType(CPPIdentifier *ident, CPPScope *current_scope, CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
const CPPFile &file) : CPPScope *scope, const CPPFile &file) :
CPPExtensionType(T_enum, ident, current_scope, file), CPPExtensionType(type, ident, current_scope, file),
_parent_scope(current_scope), _scope(scope),
_element_type(NULL), _element_type(NULL),
_last_value(NULL) _last_value(NULL)
{ {
_parent_scope = (type == T_enum) ? current_scope : scope;
if (ident != NULL) { if (ident != NULL) {
ident->_native_scope = current_scope; ident->_native_scope = current_scope;
} }
} }
/** /**
* Creates a typed but unscoped enum. * Creates a typed enum.
*/ */
CPPEnumType:: CPPEnumType::
CPPEnumType(CPPIdentifier *ident, CPPType *element_type, CPPEnumType(Type type, CPPIdentifier *ident, CPPType *element_type,
CPPScope *current_scope, const CPPFile &file) : CPPScope *current_scope, CPPScope *scope, const CPPFile &file) :
CPPExtensionType(T_enum, ident, current_scope, file), CPPExtensionType(type, ident, current_scope, file),
_parent_scope(current_scope), _scope(scope),
_element_type(element_type), _element_type(element_type),
_last_value(NULL) _last_value(NULL)
{ {
_parent_scope = (type == T_enum) ? current_scope : scope;
if (ident != NULL) { if (ident != NULL) {
ident->_native_scope = current_scope; ident->_native_scope = current_scope;
} }
} }
/**
* Returns true if this is a scoped enum.
*/
bool CPPEnumType::
is_scoped() const {
return (_type != T_enum);
}
/** /**
* Returns the integral type used to store enum values. * Returns the integral type used to store enum values.
*/ */
CPPType *CPPEnumType:: CPPType *CPPEnumType::
get_element_type() { get_underlying_type() {
if (_element_type == NULL) { if (_element_type == NULL) {
// This enum is untyped. Use a suitable default, ie. 'int'. In the // This enum is untyped. Use a suitable default, ie. 'int'. In the
// future, we might want to check whether it fits in an int. // future, we might want to check whether it fits in an int.
@ -78,11 +89,18 @@ get_element_type() {
* *
*/ */
CPPInstance *CPPEnumType:: CPPInstance *CPPEnumType::
add_element(const string &name, CPPExpression *value) { add_element(const string &name, CPPExpression *value, CPPPreprocessor *preprocessor, const cppyyltype &pos) {
CPPIdentifier *ident = new CPPIdentifier(name); CPPIdentifier *ident = new CPPIdentifier(name);
ident->_native_scope = _parent_scope; ident->_native_scope = _parent_scope;
CPPInstance *inst = new CPPInstance(get_element_type(), ident); CPPInstance *inst;
if (_type == T_enum) {
// Weakly typed enum.
inst = new CPPInstance(get_underlying_type(), ident);
} else {
// C++11-style strongly typed enum.
inst = new CPPInstance(this, ident);
}
inst->_storage_class |= CPPInstance::SC_constexpr; inst->_storage_class |= CPPInstance::SC_constexpr;
_elements.push_back(inst); _elements.push_back(inst);
@ -104,6 +122,41 @@ add_element(const string &name, CPPExpression *value) {
} }
inst->_initializer = value; inst->_initializer = value;
_last_value = value; _last_value = value;
if (preprocessor != (CPPPreprocessor *)NULL) {
// Same-line comment?
CPPCommentBlock *comment =
preprocessor->get_comment_on(pos.first_line, pos.file);
if (comment == (CPPCommentBlock *)NULL) {
// Nope. Check for a comment before this line.
comment =
preprocessor->get_comment_before(pos.first_line, pos.file);
if (comment != NULL) {
// This is a bit of a hack, but it prevents us from picking up a same-
// line comment from the previous line.
if (comment->_line_number != pos.first_line - 1 ||
comment->_col_number <= pos.first_column) {
inst->_leading_comment = comment;
}
}
} else {
inst->_leading_comment = comment;
}
}
// Add the value to the enum scope (as per C++11), assuming it's not anonymous.
if (_scope != NULL) {
_scope->add_enum_value(inst);
}
// Now add it to the containing scope as well if it's not an "enum class".
if (!is_scoped() && _parent_scope != NULL) {
_parent_scope->add_enum_value(inst);
}
return inst; return inst;
} }

View File

@ -30,15 +30,16 @@ class CPPScope;
*/ */
class CPPEnumType : public CPPExtensionType { class CPPEnumType : public CPPExtensionType {
public: public:
CPPEnumType(CPPIdentifier *ident, CPPScope *current_scope, CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
const CPPFile &file); CPPScope *scope, const CPPFile &file);
CPPEnumType(CPPIdentifier *ident, CPPType *element_type, CPPEnumType(Type type, CPPIdentifier *ident, CPPType *element_type,
CPPScope *current_scope, const CPPFile &file); CPPScope *current_scope, CPPScope *scope, const CPPFile &file);
CPPType *get_element_type(); bool is_scoped() const;
CPPType *get_underlying_type();
CPPInstance *add_element(const string &name, CPPInstance *add_element(const string &name, CPPExpression *value,
CPPExpression *value = (CPPExpression *)NULL); CPPPreprocessor *preprocessor, const cppyyltype &pos);
virtual bool is_incomplete() const; virtual bool is_incomplete() const;
@ -54,6 +55,7 @@ public:
virtual CPPEnumType *as_enum_type(); virtual CPPEnumType *as_enum_type();
CPPScope *_parent_scope; CPPScope *_parent_scope;
CPPScope *_scope;
CPPType *_element_type; CPPType *_element_type;
typedef vector<CPPInstance *> Elements; typedef vector<CPPInstance *> Elements;

View File

@ -949,7 +949,7 @@ determine_type() const {
case CPPDeclaration::ST_enum: case CPPDeclaration::ST_enum:
// Convert into integral type. // Convert into integral type.
return t1->as_enum_type()->get_element_type(); return t1->as_enum_type()->get_underlying_type();
case CPPDeclaration::ST_simple: case CPPDeclaration::ST_simple:
{ {

View File

@ -229,6 +229,12 @@ operator << (ostream &out, CPPExtensionType::Type type) {
case CPPExtensionType::T_union: case CPPExtensionType::T_union:
return out << "union"; return out << "union";
case CPPExtensionType::T_enum_class:
return out << "enum class";
case CPPExtensionType::T_enum_struct:
return out << "enum struct";
default: default:
return out << "***invalid extension type***"; return out << "***invalid extension type***";
} }

View File

@ -34,6 +34,8 @@ public:
T_class, T_class,
T_struct, T_struct,
T_union, T_union,
T_enum_class,
T_enum_struct,
}; };
CPPExtensionType(Type type, CPPIdentifier *ident, CPPScope *current_scope, CPPExtensionType(Type type, CPPIdentifier *ident, CPPScope *current_scope,

View File

@ -124,34 +124,9 @@ add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
* *
*/ */
void CPPScope:: void CPPScope::
add_enum_value(CPPInstance *inst, CPPPreprocessor *preprocessor, add_enum_value(CPPInstance *inst) {
const cppyyltype &pos) {
inst->_vis = _current_vis; inst->_vis = _current_vis;
if (inst->_leading_comment == (CPPCommentBlock *)NULL) {
// Same-line comment?
CPPCommentBlock *comment =
preprocessor->get_comment_on(pos.first_line, pos.file);
if (comment == (CPPCommentBlock *)NULL) {
// Nope. Check for a comment before this line.
comment =
preprocessor->get_comment_before(pos.first_line, pos.file);
if (comment != NULL) {
// This is a bit of a hack, but it prevents us from picking up a same-
// line comment from the previous line.
if (comment->_line_number != pos.first_line - 1 ||
comment->_col_number <= pos.first_column) {
inst->_leading_comment = comment;
}
}
} else {
inst->_leading_comment = comment;
}
}
string name = inst->get_simple_name(); string name = inst->get_simple_name();
if (!name.empty()) { if (!name.empty()) {
_enum_values[name] = inst; _enum_values[name] = inst;
@ -183,6 +158,8 @@ define_extension_type(CPPExtensionType *type, CPPPreprocessor *error_sink) {
break; break;
case CPPExtensionType::T_enum: case CPPExtensionType::T_enum:
case CPPExtensionType::T_enum_struct:
case CPPExtensionType::T_enum_class:
_enums[name] = type; _enums[name] = type;
break; break;
} }
@ -606,6 +583,11 @@ find_scope(const string &name, bool recurse) const {
if (st != NULL) { if (st != NULL) {
return st->_scope; return st->_scope;
} }
CPPEnumType *et = type->as_enum_type();
if (et != NULL) {
return et->_scope;
}
} }
Using::const_iterator ui; Using::const_iterator ui;
@ -645,11 +627,16 @@ find_scope(const string &name, CPPDeclaration::SubstDecl &subst,
} }
CPPStructType *st = type->as_struct_type(); CPPStructType *st = type->as_struct_type();
if (st == NULL) { if (st != NULL) {
return NULL; return st->_scope;
} }
return st->_scope; CPPEnumType *et = type->as_enum_type();
if (et != NULL) {
return et->_scope;
}
return NULL;
} }
/** /**

View File

@ -61,9 +61,7 @@ public:
virtual void add_declaration(CPPDeclaration *decl, CPPScope *global_scope, virtual void add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
CPPPreprocessor *preprocessor, CPPPreprocessor *preprocessor,
const cppyyltype &pos); const cppyyltype &pos);
virtual void add_enum_value(CPPInstance *inst, virtual void add_enum_value(CPPInstance *inst);
CPPPreprocessor *preprocessor,
const cppyyltype &pos);
virtual void define_extension_type(CPPExtensionType *type, virtual void define_extension_type(CPPExtensionType *type,
CPPPreprocessor *error_sink = NULL); CPPPreprocessor *error_sink = NULL);
virtual void define_namespace(CPPNamespace *scope); virtual void define_namespace(CPPNamespace *scope);

View File

@ -43,11 +43,10 @@ add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
* *
*/ */
void CPPTemplateScope:: void CPPTemplateScope::
add_enum_value(CPPInstance *inst, CPPPreprocessor *preprocessor, add_enum_value(CPPInstance *inst) {
const cppyyltype &pos) {
inst->_template_scope = this; inst->_template_scope = this;
assert(_parent_scope != NULL); assert(_parent_scope != NULL);
_parent_scope->add_enum_value(inst, preprocessor, pos); _parent_scope->add_enum_value(inst);
} }
/** /**

View File

@ -33,9 +33,7 @@ public:
virtual void add_declaration(CPPDeclaration *decl, CPPScope *global_scope, virtual void add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
CPPPreprocessor *preprocessor, CPPPreprocessor *preprocessor,
const cppyyltype &pos); const cppyyltype &pos);
virtual void add_enum_value(CPPInstance *inst, virtual void add_enum_value(CPPInstance *inst);
CPPPreprocessor *preprocessor,
const cppyyltype &pos);
virtual void define_extension_type(CPPExtensionType *type, virtual void define_extension_type(CPPExtensionType *type,
CPPPreprocessor *error_sink = NULL); CPPPreprocessor *error_sink = NULL);
virtual void define_namespace(CPPNamespace *scope); virtual void define_namespace(CPPNamespace *scope);

View File

@ -764,10 +764,6 @@ write_prototypes(ostream &out_code, ostream *out_h) {
*out_h << "#include \"py_panda.h\"\n\n"; *out_h << "#include \"py_panda.h\"\n\n";
} }
out_code << "//********************************************************************\n";
out_code << "//*** prototypes for .. Global\n";
out_code << "//********************************************************************\n";
/* /*
for (fi = _functions.begin(); fi != _functions.end(); ++fi) for (fi = _functions.begin(); fi != _functions.end(); ++fi)
{ {
@ -792,9 +788,9 @@ write_prototypes(ostream &out_code, ostream *out_h) {
} }
} }
out_code << "//********************************************************************\n"; out_code << "/**\n";
out_code << "//*** prototypes for .. External Objects\n"; out_code << " * Extern declarations for imported classes\n";
out_code << "//********************************************************************\n"; out_code << " */\n";
for (std::set<CPPType *>::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ii++) { for (std::set<CPPType *>::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ii++) {
CPPType *type = (*ii); CPPType *type = (*ii);
@ -897,9 +893,9 @@ write_prototypes_class_external(ostream &out, Object *obj) {
std::string preferred_name = obj->_itype.get_name(); std::string preferred_name = obj->_itype.get_name();
out << "//********************************************************************\n"; out << "/**\n";
out << "//*** prototypes for external.. " << class_name << "\n"; out << " * Forward declaration of class " << class_name << "\n";
out << "//********************************************************************\n"; out << " */\n";
// This typedef is necessary for class templates since we can't pass a comma // This typedef is necessary for class templates since we can't pass a comma
// to a macro function. // to a macro function.
@ -915,9 +911,9 @@ write_prototypes_class(ostream &out_code, ostream *out_h, Object *obj) {
std::string ClassName = make_safe_name(obj->_itype.get_scoped_name()); std::string ClassName = make_safe_name(obj->_itype.get_scoped_name());
Functions::iterator fi; Functions::iterator fi;
out_code << "//********************************************************************\n"; out_code << "/**\n";
out_code << "//*** prototypes for .. " << ClassName << "\n"; out_code << " * Forward declarations for top-level class " << ClassName << "\n";
out_code << "//********************************************************************\n"; out_code << " */\n";
/* /*
for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) { for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) {
@ -943,9 +939,9 @@ write_prototypes_class(ostream &out_code, ostream *out_h, Object *obj) {
*/ */
void InterfaceMakerPythonNative:: void InterfaceMakerPythonNative::
write_functions(ostream &out) { write_functions(ostream &out) {
out << "//********************************************************************\n"; out << "/**\n";
out << "//*** Functions for .. Global\n" ; out << " * Python wrappers for global functions\n" ;
out << "//********************************************************************\n"; out << " */\n";
FunctionsByIndex::iterator fi; FunctionsByIndex::iterator fi;
for (fi = _functions.begin(); fi != _functions.end(); ++fi) { for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
Function *func = (*fi).second; Function *func = (*fi).second;
@ -994,9 +990,9 @@ write_class_details(ostream &out, Object *obj) {
std::string ClassName = make_safe_name(obj->_itype.get_scoped_name()); std::string ClassName = make_safe_name(obj->_itype.get_scoped_name());
std::string cClassName = obj->_itype.get_true_name(); std::string cClassName = obj->_itype.get_true_name();
out << "//********************************************************************\n"; out << "/**\n";
out << "//*** Functions for .. " << cClassName << "\n" ; out << " * Python wrappers for functions of class " << cClassName << "\n" ;
out << "//********************************************************************\n"; out << " */\n";
// First write out all the wrapper functions for the methods. // First write out all the wrapper functions for the methods.
for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) { for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) {
@ -1183,7 +1179,6 @@ write_sub_module(ostream &out, Object *obj) {
// Object * obj = _objects[_embeded_index] ; // Object * obj = _objects[_embeded_index] ;
string class_name = make_safe_name(obj->_itype.get_scoped_name()); string class_name = make_safe_name(obj->_itype.get_scoped_name());
string class_ptr; string class_ptr;
out << " // Module init upcall for " << obj->_itype.get_scoped_name() << "\n";
if (!obj->_itype.is_typedef()) { if (!obj->_itype.is_typedef()) {
out << " // " << *(obj->_itype._cpptype) << "\n"; out << " // " << *(obj->_itype._cpptype) << "\n";
@ -1242,9 +1237,9 @@ write_sub_module(ostream &out, Object *obj) {
*/ */
void InterfaceMakerPythonNative:: void InterfaceMakerPythonNative::
write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
out << "//********************************************************************\n"; out << "/**\n";
out << "//*** Module Object Linker ..\n"; out << " * Module Object Linker ..\n";
out << "//********************************************************************\n"; out << " */\n";
Objects::iterator oi; Objects::iterator oi;
@ -1305,14 +1300,41 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
if (object->_itype.is_enum() && !object->_itype.is_nested() && if (object->_itype.is_enum() && !object->_itype.is_nested() &&
isExportThisRun(object->_itype._cpptype)) { isExportThisRun(object->_itype._cpptype)) {
int enum_count = object->_itype.number_of_enum_values(); int enum_count = object->_itype.number_of_enum_values();
for (int xx = 0; xx < enum_count; xx++) {
string name1 = classNameFromCppName(object->_itype.get_enum_value_name(xx), false); if (object->_itype.is_scoped_enum()) {
string name2 = classNameFromCppName(object->_itype.get_enum_value_name(xx), true); // Convert as Python 3.4 enum.
string enum_value = "::" + object->_itype.get_enum_value_name(xx); CPPType *underlying_type = TypeManager::unwrap_const(object->_itype._cpptype->as_enum_type()->get_underlying_type());
out << " PyModule_AddIntConstant(module, \"" << name1 << "\", " << enum_value << ");\n"; string cast_to = underlying_type->get_local_name(&parser);
if (name1 != name2) { out << "#if PY_VERSION_HEX >= 0x03040000\n\n";
// Also write the mangled name, for historical purposes. out << " // enum class " << object->_itype.get_scoped_name() << "\n";
out << " PyModule_AddIntConstant(module, \"" << name2 << "\", " << enum_value << ");\n"; out << " {\n";
out << " PyObject *members = PyTuple_New(" << enum_count << ");\n";
out << " PyObject *member;\n";
for (int xx = 0; xx < enum_count; xx++) {
out << " member = PyTuple_New(2);\n"
" PyTuple_SET_ITEM(member, 0, PyUnicode_FromString(\""
<< object->_itype.get_enum_value_name(xx) << "\"));\n"
" PyTuple_SET_ITEM(member, 1, Dtool_WrapValue(("
<< cast_to << ")" << object->_itype.get_scoped_name() << "::"
<< object->_itype.get_enum_value_name(xx) << "));\n"
" PyTuple_SET_ITEM(members, " << xx << ", member);\n";
}
out << " PyModule_AddObject(module, \"" << object->_itype.get_name()
<< "\", Dtool_EnumType_Create(\"" << object->_itype.get_name()
<< "\", members, \"" << _def->module_name << "\"));\n";
out << " }\n";
out << "#endif\n";
} else {
out << " // enum " << object->_itype.get_scoped_name() << "\n";
for (int xx = 0; xx < enum_count; xx++) {
string name1 = classNameFromCppName(object->_itype.get_enum_value_name(xx), false);
string name2 = classNameFromCppName(object->_itype.get_enum_value_name(xx), true);
string enum_value = "::" + object->_itype.get_enum_value_name(xx);
out << " PyModule_AddObject(module, \"" << name1 << "\", Dtool_WrapValue(" << enum_value << "));\n";
if (name1 != name2) {
// Also write the mangled name, for historical purposes.
out << " PyModule_AddObject(module, \"" << name2 << "\", Dtool_WrapValue(" << enum_value << "));\n";
}
} }
} }
} }
@ -1360,13 +1382,6 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
} }
} }
} }
out << "//********************************************************************\n";
out << "//*** Module Init Upcall .. Externally Defined Class\n";
out << "//********************************************************************\n";
// for (std::set< std::string >::iterator ii = _external_imports.begin(); ii
// != _external_imports.end(); ii++) out << "Dtool_" <<*ii <<
// "._Dtool_ClassInit(NULL);\n";
out << "}\n\n"; out << "}\n\n";
@ -1435,9 +1450,9 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
InterfaceMakerPython::write_module(out, out_h, def); InterfaceMakerPython::write_module(out, out_h, def);
Objects::iterator oi; Objects::iterator oi;
out << "//********************************************************************\n"; out << "/**\n";
out << "//*** Py Init Code For .. GlobalScope\n" ; out << " * Module initialization functions for Python module \"" << def->module_name << "\"\n";
out << "//********************************************************************\n"; out << " */\n";
out << "#if PY_MAJOR_VERSION >= 3\n" out << "#if PY_MAJOR_VERSION >= 3\n"
<< "static struct PyModuleDef python_native_module = {\n" << "static struct PyModuleDef python_native_module = {\n"
@ -1452,14 +1467,16 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
<< "#ifdef _WIN32\n" << "#ifdef _WIN32\n"
<< "extern \"C\" __declspec(dllexport) PyObject *PyInit_" << def->module_name << "();\n" << "extern \"C\" __declspec(dllexport) PyObject *PyInit_" << def->module_name << "();\n"
<< "#elif __GNUC__ >= 4\n" << "#elif __GNUC__ >= 4\n"
<< "extern \"C\" __attribute__((visibility(\"default\"))) PyInit_" << def->module_name << "();\n" << "extern \"C\" __attribute__((visibility(\"default\"))) PyObject *PyInit_" << def->module_name << "();\n"
<< "#else\n" << "#else\n"
<< "extern \"C\" PyObject *PyInit_" << def->module_name << "();\n" << "extern \"C\" PyObject *PyInit_" << def->module_name << "();\n"
<< "#endif\n" << "#endif\n"
<< "\n" << "\n"
<< "PyObject *PyInit_" << def->module_name << "() {\n" << "PyObject *PyInit_" << def->module_name << "() {\n"
<< " LibraryDef *refs[] = {&" << def->library_name << "_moddef, NULL};\n" << " LibraryDef *refs[] = {&" << def->library_name << "_moddef, NULL};\n"
<< " return Dtool_PyModuleInitHelper(refs, &python_native_module);\n" << " PyObject *module = Dtool_PyModuleInitHelper(refs, &python_native_module);\n"
<< " Dtool_" << def->library_name << "_BuildInstants(module);\n"
<< " return module;\n"
<< "}\n" << "}\n"
<< "\n" << "\n"
<< "#else // Python 2 case\n" << "#else // Python 2 case\n"
@ -1467,14 +1484,15 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
<< "#ifdef _WIN32\n" << "#ifdef _WIN32\n"
<< "extern \"C\" __declspec(dllexport) void init" << def->module_name << "();\n" << "extern \"C\" __declspec(dllexport) void init" << def->module_name << "();\n"
<< "#elif __GNUC__ >= 4\n" << "#elif __GNUC__ >= 4\n"
<< "extern \"C\" __attribute__((visibility(\"default\"))) init" << def->module_name << "();\n" << "extern \"C\" __attribute__((visibility(\"default\"))) void init" << def->module_name << "();\n"
<< "#else\n" << "#else\n"
<< "extern \"C\" void init" << def->module_name << "();\n" << "extern \"C\" void init" << def->module_name << "();\n"
<< "#endif\n" << "#endif\n"
<< "\n" << "\n"
<< "void init" << def->module_name << "() {\n" << "void init" << def->module_name << "() {\n"
<< " LibraryDef *refs[] = {&" << def->library_name << "_moddef, NULL};\n" << " LibraryDef *refs[] = {&" << def->library_name << "_moddef, NULL};\n"
<< " Dtool_PyModuleInitHelper(refs, \"" << def->module_name << "\");\n" << " PyObject *module = Dtool_PyModuleInitHelper(refs, \"" << def->module_name << "\");\n"
<< " Dtool_" << def->library_name << "_BuildInstants(module);\n"
<< "}\n" << "}\n"
<< "\n" << "\n"
<< "#endif\n" << "#endif\n"
@ -1520,9 +1538,9 @@ write_module_class(ostream &out, Object *obj) {
} }
Functions::iterator fi; Functions::iterator fi;
out << "//********************************************************************\n"; out << "/**\n";
out << "//*** Py Init Code For .. " << ClassName << " | " << export_class_name << "\n" ; out << " * Python method tables for " << ClassName << " (" << export_class_name << ")\n" ;
out << "//********************************************************************\n"; out << " */\n";
out << "static PyMethodDef Dtool_Methods_" << ClassName << "[] = {\n"; out << "static PyMethodDef Dtool_Methods_" << ClassName << "[] = {\n";
SlottedFunctions slots; SlottedFunctions slots;
@ -2449,11 +2467,7 @@ write_module_class(ostream &out, Object *obj) {
<< classNameFromCppName(ClassName, false) << "\");\n"; << classNameFromCppName(ClassName, false) << "\");\n";
} }
out << " std::string ss = os.str();\n"; out << " std::string ss = os.str();\n";
out << "#if PY_MAJOR_VERSION >= 3\n"; out << " return Dtool_WrapValue(ss);\n";
out << " return PyUnicode_FromStringAndSize(ss.data(), ss.length());\n";
out << "#else\n";
out << " return PyString_FromStringAndSize(ss.data(), ss.length());\n";
out << "#endif\n";
out << "}\n\n"; out << "}\n\n";
has_local_repr = true; has_local_repr = true;
} }
@ -2479,11 +2493,7 @@ write_module_class(ostream &out, Object *obj) {
out << " local_this->write(os);\n"; out << " local_this->write(os);\n";
} }
out << " std::string ss = os.str();\n"; out << " std::string ss = os.str();\n";
out << "#if PY_MAJOR_VERSION >= 3\n"; out << " return Dtool_WrapValue(ss);\n";
out << " return PyUnicode_FromStringAndSize(ss.data(), ss.length());\n";
out << "#else\n";
out << " return PyString_FromStringAndSize(ss.data(), ss.length());\n";
out << "#endif\n";
out << "}\n\n"; out << "}\n\n";
has_local_str = true; has_local_str = true;
} }
@ -3037,7 +3047,7 @@ write_module_class(ostream &out, Object *obj) {
} else if (nested_obj->_itype.is_typedef()) { } else if (nested_obj->_itype.is_typedef()) {
++num_dict_items; ++num_dict_items;
} else if (nested_obj->_itype.is_enum()) { } else if (nested_obj->_itype.is_enum() && !nested_obj->_itype.is_scoped_enum()) {
CPPEnumType *enum_type = nested_obj->_itype._cpptype->as_enum_type(); CPPEnumType *enum_type = nested_obj->_itype._cpptype->as_enum_type();
num_dict_items += 2 * enum_type->_elements.size(); num_dict_items += 2 * enum_type->_elements.size();
} }
@ -3095,8 +3105,33 @@ write_module_class(ostream &out, Object *obj) {
// No need to support mangled names for nested typedefs; we only added // No need to support mangled names for nested typedefs; we only added
// support recently. // support recently.
} else if (nested_obj->_itype.is_scoped_enum()) {
// Convert enum class as Python 3.4 enum.
int enum_count = nested_obj->_itype.number_of_enum_values();
CPPType *underlying_type = TypeManager::unwrap_const(nested_obj->_itype._cpptype->as_enum_type()->get_underlying_type());
string cast_to = underlying_type->get_local_name(&parser);
out << "#if PY_VERSION_HEX >= 0x03040000\n\n";
out << " // enum class " << nested_obj->_itype.get_scoped_name() << ";\n";
out << " {\n";
out << " PyObject *members = PyTuple_New(" << enum_count << ");\n";
out << " PyObject *member;\n";
for (int xx = 0; xx < enum_count; xx++) {
out << " member = PyTuple_New(2);\n"
" PyTuple_SET_ITEM(member, 0, PyUnicode_FromString(\""
<< nested_obj->_itype.get_enum_value_name(xx) << "\"));\n"
" PyTuple_SET_ITEM(member, 1, Dtool_WrapValue(("
<< cast_to << ")" << nested_obj->_itype.get_scoped_name() << "::"
<< nested_obj->_itype.get_enum_value_name(xx) << "));\n"
" PyTuple_SET_ITEM(members, " << xx << ", member);\n";
}
out << " PyDict_SetItemString(dict, \"" << nested_obj->_itype.get_name()
<< "\", Dtool_EnumType_Create(\"" << nested_obj->_itype.get_name()
<< "\", members, \"" << _def->module_name << "\"));\n";
out << " }\n";
out << "#endif\n";
} else if (nested_obj->_itype.is_enum()) { } else if (nested_obj->_itype.is_enum()) {
out << " // Enum " << nested_obj->_itype.get_scoped_name() << ";\n"; out << " // enum " << nested_obj->_itype.get_scoped_name() << ";\n";
CPPEnumType *enum_type = nested_obj->_itype._cpptype->as_enum_type(); CPPEnumType *enum_type = nested_obj->_itype._cpptype->as_enum_type();
CPPEnumType::Elements::const_iterator ei; CPPEnumType::Elements::const_iterator ei;
for (ei = enum_type->_elements.begin(); ei != enum_type->_elements.end(); ++ei) { for (ei = enum_type->_elements.begin(); ei != enum_type->_elements.end(); ++ei) {
@ -3111,9 +3146,9 @@ write_module_class(ostream &out, Object *obj) {
name2 = name1; name2 = name1;
} }
string enum_value = obj->_itype.get_scoped_name() + "::" + (*ei)->get_simple_name(); string enum_value = obj->_itype.get_scoped_name() + "::" + (*ei)->get_simple_name();
out << " PyDict_SetItemString(dict, \"" << name1 << "\", PyLongOrInt_FromLong(" << enum_value << "));\n"; out << " PyDict_SetItemString(dict, \"" << name1 << "\", Dtool_WrapValue(" << enum_value << "));\n";
if (name1 != name2) { if (name1 != name2) {
out << " PyDict_SetItemString(dict, \"" << name2 << "\", PyLongOrInt_FromLong(" << enum_value << "));\n"; out << " PyDict_SetItemString(dict, \"" << name2 << "\", Dtool_WrapValue(" << enum_value << "));\n";
} }
} }
} }
@ -3340,7 +3375,7 @@ write_function_for_name(ostream &out, Object *obj,
int max_required_args = 0; int max_required_args = 0;
bool all_nonconst = true; bool all_nonconst = true;
out << "/******************************************************************\n" << " * Python type method wrapper for\n"; out << "/**\n * Python function wrapper for:\n";
for (ri = remaps.begin(); ri != remaps.end(); ++ri) { for (ri = remaps.begin(); ri != remaps.end(); ++ri) {
remap = (*ri); remap = (*ri);
if (is_remap_legal(remap)) { if (is_remap_legal(remap)) {
@ -3369,7 +3404,7 @@ write_function_for_name(ostream &out, Object *obj,
} }
} }
out << " *******************************************************************/\n"; out << " */\n";
out << function_name << " {\n"; out << function_name << " {\n";
@ -6033,164 +6068,16 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
CPPType *orig_type = return_type->get_orig_type(); CPPType *orig_type = return_type->get_orig_type();
CPPType *type = return_type->get_new_type(); CPPType *type = return_type->get_new_type();
if (return_type->new_type_is_atomic_string()) { if (return_type->new_type_is_atomic_string() ||
if (TypeManager::is_char_pointer(orig_type)) { TypeManager::is_simple(type) ||
indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n"; TypeManager::is_char_pointer(type) ||
indent(out, indent_level) << " Py_INCREF(Py_None);\n"; TypeManager::is_wchar_pointer(type) ||
indent(out, indent_level) << " return Py_None;\n"; TypeManager::is_pointer_to_PyObject(type) ||
indent(out, indent_level) << "} else {\n"; TypeManager::is_pointer_to_Py_buffer(type)) {
// Most types are now handled by the many overloads of Dtool_WrapValue,
out << "#if PY_MAJOR_VERSION >= 3\n"; // defined in py_panda.h.
indent(out, indent_level) << " return "
<< "PyUnicode_FromString(" << return_expr << ");\n";
out << "#else\n";
indent(out, indent_level) << " return "
<< "PyString_FromString(" << return_expr << ");\n";
out << "#endif\n";
indent(out, indent_level) << "}\n";
} else if (TypeManager::is_wchar_pointer(orig_type)) {
indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
indent(out, indent_level) << " Py_INCREF(Py_None);\n";
indent(out, indent_level) << " return Py_None;\n";
indent(out, indent_level) << "} else {\n";
indent(out, indent_level+2)
<< "return PyUnicode_FromWideChar("
<< return_expr << ", wcslen(" << return_expr << "));\n";
indent(out, indent_level) << "}\n";
} else if (TypeManager::is_wstring(orig_type)) {
indent(out, indent_level)
<< "return PyUnicode_FromWideChar("
<< return_expr << ".data(), (int) " << return_expr << ".length());\n";
} else if (TypeManager::is_const_ptr_to_basic_string_wchar(orig_type)) {
indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
indent(out, indent_level) << " Py_INCREF(Py_None);\n";
indent(out, indent_level) << " return Py_None;\n";
indent(out, indent_level) << "} else {\n";
indent(out, indent_level) << " return "
<< "PyUnicode_FromWideChar("
<< return_expr << "->data(), (int) " << return_expr << "->length());\n";
indent(out, indent_level) << "}\n";
} else if (TypeManager::is_const_ptr_to_basic_string_char(orig_type)) {
indent(out, indent_level) << "if (" << return_expr<< " == NULL) {\n";
indent(out, indent_level) << " Py_INCREF(Py_None);\n";
indent(out, indent_level) << " return Py_None;\n";
indent(out, indent_level) << "} else {\n";
out << "#if PY_MAJOR_VERSION >= 3\n";
indent(out, indent_level) << " return "
<< "PyUnicode_FromStringAndSize("
<< return_expr << "->data(), (Py_ssize_t)" << return_expr << "->length());\n";
out << "#else\n";
indent(out, indent_level) << " return "
<< "PyString_FromStringAndSize("
<< return_expr << "->data(), (Py_ssize_t)" << return_expr << "->length());\n";
out << "#endif\n";
indent(out, indent_level) << "}\n";
} else {
out << "#if PY_MAJOR_VERSION >= 3\n";
indent(out, indent_level)
<< "return PyUnicode_FromStringAndSize("
<< return_expr << ".data(), (Py_ssize_t)" << return_expr << ".length());\n";
out << "#else\n";
indent(out, indent_level)
<< "return PyString_FromStringAndSize("
<< return_expr << ".data(), (Py_ssize_t)" << return_expr << ".length());\n";
out << "#endif\n";
}
} else if (TypeManager::is_bool(type)) {
indent(out, indent_level) indent(out, indent_level)
<< "return PyBool_FromLong(" << return_expr << ");\n"; << "return Dtool_WrapValue(" << return_expr << ");\n";
} else if (TypeManager::is_ssize(type)) {
indent(out, indent_level)
<< "return PyLongOrInt_FromSsize_t(" << return_expr << ");\n";
} else if (TypeManager::is_size(type)) {
indent(out, indent_level)
<< "return PyLongOrInt_FromSize_t(" << return_expr << ");\n";
} else if (TypeManager::is_char(type)) {
out << "#if PY_MAJOR_VERSION >= 3\n";
indent(out, indent_level)
<< "return PyUnicode_FromStringAndSize(&" << return_expr << ", 1);\n";
out << "#else\n";
indent(out, indent_level)
<< "return PyString_FromStringAndSize(&" << return_expr << ", 1);\n";
out << "#endif\n";
} else if (TypeManager::is_wchar(type)) {
indent(out, indent_level)
<< "return PyUnicode_FromWideChar(&" << return_expr << ", 1);\n";
} else if (TypeManager::is_unsigned_longlong(type)) {
indent(out, indent_level)
<< "return PyLong_FromUnsignedLongLong(" << return_expr << ");\n";
} else if (TypeManager::is_longlong(type)) {
indent(out, indent_level)
<< "return PyLong_FromLongLong(" << return_expr << ");\n";
} else if (TypeManager::is_unsigned_integer(type)){
indent(out, indent_level)
<< "return PyLongOrInt_FromUnsignedLong(" << return_expr << ");\n";
} else if (TypeManager::is_integer(type)) {
indent(out, indent_level)
<< "return PyLongOrInt_FromLong(" << return_expr << ");\n";
} else if (TypeManager::is_float(type)) {
indent(out, indent_level)
<< "return PyFloat_FromDouble(" << return_expr << ");\n";
} else if (TypeManager::is_char_pointer(type)) {
indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
indent(out, indent_level) << " Py_INCREF(Py_None);\n";
indent(out, indent_level) << " return Py_None;\n";
indent(out, indent_level) << "} else {\n";
out << "#if PY_MAJOR_VERSION >= 3\n";
indent(out, indent_level) << " return "
<< "PyUnicode_FromString(" << return_expr << ");\n";
out << "#else\n";
indent(out, indent_level) << " return "
<< "PyString_FromString(" << return_expr << ");\n";
out << "#endif\n";
indent(out, indent_level) << "}\n";
} else if (TypeManager::is_wchar_pointer(type)) {
indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
indent(out, indent_level) << " Py_INCREF(Py_None);\n";
indent(out, indent_level) << " return Py_None;\n";
indent(out, indent_level) << "} else {\n";
indent(out, indent_level) << " return "
<< "PyUnicode_FromWideChar("
<< return_expr << ", wcslen(" << return_expr << "));\n";
indent(out, indent_level) << "}\n";
} else if (TypeManager::is_pointer_to_PyObject(type)) {
indent(out, indent_level)
<< "return " << return_expr << ";\n";
} else if (TypeManager::is_pointer_to_Py_buffer(type)) {
indent(out, indent_level) << "if (" << return_expr << " == NULL) {\n";
indent(out, indent_level) << " Py_INCREF(Py_None);\n";
indent(out, indent_level) << " return Py_None;\n";
indent(out, indent_level) << "} else {\n";
indent(out, indent_level) << " return "
<< "PyMemoryView_FromBuffer(" << return_expr << ");\n";
indent(out, indent_level) << "}\n";
} else if (TypeManager::is_pointer(type)) { } else if (TypeManager::is_pointer(type)) {
bool is_const = TypeManager::is_const_pointer_to_anything(type); bool is_const = TypeManager::is_const_pointer_to_anything(type);
@ -6234,13 +6121,13 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
} else { } else {
indent(out, indent_level) << "Should Never Reach This InterfaceMakerPythonNative::pack_python_value"; indent(out, indent_level) << "Should Never Reach This InterfaceMakerPythonNative::pack_python_value";
// << "return PyLongOrInt_FromLong((int) " << return_expr << ");\n"; // << "return Dtool_Integer((int) " << return_expr << ");\n";
} }
} else { } else {
// Return None. // Return None.
indent(out, indent_level) indent(out, indent_level)
<< "return Py_BuildValue(\"\");\n"; << "return Py_BuildValue(\"\"); // Don't know how to wrap type.\n";
} }
} }
@ -6288,11 +6175,7 @@ write_make_seq(ostream &out, Object *obj, const std::string &ClassName,
" PyObject *tuple = PyTuple_New(count);\n" " PyObject *tuple = PyTuple_New(count);\n"
"\n" "\n"
" for (Py_ssize_t i = 0; i < count; ++i) {\n" " for (Py_ssize_t i = 0; i < count; ++i) {\n"
"#if PY_MAJOR_VERSION >= 3\n" " PyObject *index = Dtool_WrapValue(i);\n";
" PyObject *index = PyLong_FromSsize_t(i);\n"
"#else\n"
" PyObject *index = PyInt_FromSsize_t(i);\n"
"#endif\n";
switch (elem_getter->_args_type) { switch (elem_getter->_args_type) {
case AT_keyword_args: case AT_keyword_args:

View File

@ -2838,6 +2838,10 @@ define_enum_type(InterrogateType &itype, CPPEnumType *cpptype) {
return; return;
} }
if (cpptype->is_scoped()) {
itype._flags |= InterrogateType::F_scoped_enum;
}
int next_value = 0; int next_value = 0;
CPPEnumType::Elements::const_iterator ei; CPPEnumType::Elements::const_iterator ei;
@ -2919,6 +2923,8 @@ define_extension_type(InterrogateType &itype, CPPExtensionType *cpptype) {
// But we can at least indicate which of the various extension types it is. // But we can at least indicate which of the various extension types it is.
switch (cpptype->_type) { switch (cpptype->_type) {
case CPPExtensionType::T_enum: case CPPExtensionType::T_enum:
case CPPExtensionType::T_enum_class:
case CPPExtensionType::T_enum_struct:
itype._flags |= InterrogateType::F_enum; itype._flags |= InterrogateType::F_enum;
break; break;

View File

@ -205,6 +205,14 @@ is_enum() const {
return (_flags & F_enum) != 0; return (_flags & F_enum) != 0;
} }
/**
* Returns true if enum values are only available under a scope.
*/
INLINE bool InterrogateType::
is_scoped_enum() const {
return (_flags & F_scoped_enum) != 0;
}
/** /**
* *
*/ */

View File

@ -65,6 +65,7 @@ public:
INLINE int get_array_size() const; INLINE int get_array_size() const;
INLINE bool is_enum() const; INLINE bool is_enum() const;
INLINE bool is_scoped_enum() const;
INLINE int number_of_enum_values() const; INLINE int number_of_enum_values() const;
INLINE const string &get_enum_value_name(int n) const; INLINE const string &get_enum_value_name(int n) const;
INLINE const string &get_enum_value_scoped_name(int n) const; INLINE const string &get_enum_value_scoped_name(int n) const;
@ -136,6 +137,7 @@ private:
F_unpublished = 0x100000, F_unpublished = 0x100000,
F_typedef = 0x200000, F_typedef = 0x200000,
F_array = 0x400000, F_array = 0x400000,
F_scoped_enum = 0x800000,
}; };
public: public:

View File

@ -0,0 +1,203 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file py_panda.I
* @author rdb
* @date 2016-06-06
*/
/**
* Template function that can be used to extract any TypedObject pointer from
* a wrapped Python object.
*/
template<class T> INLINE bool
DTOOL_Call_ExtractThisPointer(PyObject *self, T *&into) {
if (DtoolCanThisBeAPandaInstance(self)) {
Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
if (target_class != NULL) {
into = (T*) ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, target_class);
return (into != NULL);
}
}
into = NULL;
return false;
}
/**
* These functions wrap a pointer for a class that defines get_type_handle().
*/
template<class T> INLINE PyObject *
DTool_CreatePyInstance(const T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
nassertr(known_class != NULL, NULL);
return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, true);
}
template<class T> INLINE PyObject *
DTool_CreatePyInstance(T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
nassertr(known_class != NULL, NULL);
return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, false);
}
template<class T> INLINE PyObject *
DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
nassertr(known_class != NULL, NULL);
return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, true, obj->get_type().get_index());
}
template<class T> INLINE PyObject *
DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
nassertr(known_class != NULL, NULL);
return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index());
}
/**
* The following functions wrap an arbitrary C++ value into a PyObject.
*/
ALWAYS_INLINE PyObject *Dtool_WrapValue(int value) {
#if PY_MAJOR_VERSION >= 3
return PyLong_FromLong((long)value);
#else
return PyInt_FromLong((long)value);
#endif
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(unsigned int value) {
#if PY_MAJOR_VERSION >= 3 && SIZEOF_INT < SIZEOF_LONG
return PyLong_FromLong((long)value);
#elif PY_MAJOR_VERSION >= 3
return PyLong_FromUnsignedLong((unsigned long)value);
#elif SIZEOF_INT < SIZEOF_LONG
return PyInt_FromLong((long)value);
#else
return (value > LONG_MAX)
? PyLong_FromUnsignedLong((unsigned long)value)
: PyInt_FromLong((long)value);
#endif
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(long value) {
#if PY_MAJOR_VERSION >= 3
return PyLong_FromLong(value);
#else
return PyInt_FromLong(value);
#endif
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(unsigned long value) {
#if PY_MAJOR_VERSION >= 3
return PyLong_FromUnsignedLong(value);
#else
return (value > LONG_MAX)
? PyLong_FromUnsignedLong(value)
: PyInt_FromLong((long)value);
#endif
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(long long value) {
return PyLong_FromLongLong(value);
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(unsigned long long value) {
return PyLong_FromUnsignedLongLong(value);
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(bool value) {
PyObject *result = (value ? Py_True : Py_False);
Py_INCREF(result);
return result;
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(double value) {
return PyFloat_FromDouble(value);
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(const char *value) {
if (value == (const char *)NULL) {
Py_INCREF(Py_None);
return Py_None;
} else {
#if PY_MAJOR_VERSION >= 3
return PyUnicode_FromString(value);
#else
return PyString_FromString(value);
#endif
}
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(const wchar_t *value) {
if (value == (const wchar_t *)NULL) {
Py_INCREF(Py_None);
return Py_None;
} else {
return PyUnicode_FromWideChar(value, (Py_ssize_t)wcslen(value));
}
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::string &value) {
#if PY_MAJOR_VERSION >= 3
return PyUnicode_FromStringAndSize(value.data(), (Py_ssize_t)value.length());
#else
return PyString_FromStringAndSize(value.data(), (Py_ssize_t)value.length());
#endif
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::wstring &value) {
return PyUnicode_FromWideChar(value.data(), (Py_ssize_t)value.length());
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::string *value) {
if (value == (const std::string *)NULL) {
Py_INCREF(Py_None);
return Py_None;
} else {
#if PY_MAJOR_VERSION >= 3
return PyUnicode_FromStringAndSize(value->data(), (Py_ssize_t)value->length());
#else
return PyString_FromStringAndSize(value->data(), (Py_ssize_t)value->length());
#endif
}
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::wstring *value) {
if (value == (const std::wstring *)NULL) {
Py_INCREF(Py_None);
return Py_None;
} else {
return PyUnicode_FromWideChar(value->data(), (Py_ssize_t)value->length());
}
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(char value) {
#if PY_MAJOR_VERSION >= 3
return PyUnicode_FromStringAndSize(&value, 1);
#else
return PyString_FromStringAndSize(&value, 1);
#endif
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(wchar_t value) {
return PyUnicode_FromWideChar(&value, 1);
}
ALWAYS_INLINE PyObject *Dtool_WrapValue(PyObject *value) {
return value;
}
#if PY_MAJOR_VERSION >= 0x02060000
ALWAYS_INLINE PyObject *Dtool_WrapValue(Py_buffer *value) {
if (value == (Py_buffer *)NULL) {
return value;
} else {
return PyMemoryView_FromBuffer(value);
}
}
#endif

View File

@ -335,6 +335,33 @@ PyObject *_Dtool_Return(PyObject *value) {
return value; return value;
} }
/**
* Creates a Python 3.4-style enum type. Steals reference to 'names'.
*/
PyObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module) {
static PyObject *enum_class = NULL;
static PyObject *enum_meta = NULL;
static PyObject *enum_create = NULL;
if (enum_meta == NULL) {
PyObject *enum_module = PyImport_ImportModule("enum");
nassertr_always(enum_module != NULL, NULL);
enum_class = PyObject_GetAttrString(enum_module, "Enum");
enum_meta = PyObject_GetAttrString(enum_module, "EnumMeta");
enum_create = PyObject_GetAttrString(enum_meta, "_create_");
nassertr(enum_meta != NULL, NULL);
}
PyObject *result = PyObject_CallFunction(enum_create, (char *)"OsN", enum_class, name, names);
nassertr(result != NULL, NULL);
if (module != NULL) {
PyObject *modstr = PyUnicode_FromString(module);
PyObject_SetAttrString(result, "__module__", modstr);
Py_DECREF(modstr);
}
return result;
}
/** /**
*/ */
@ -833,19 +860,4 @@ PyObject *map_deepcopy_to_copy(PyObject *self, PyObject *args) {
return PyObject_CallMethod(self, (char *)"__copy__", (char *)"()"); return PyObject_CallMethod(self, (char *)"__copy__", (char *)"()");
} }
/**
* Similar to PyLong_FromUnsignedLong(), but returns either a regular integer
* or a long integer, according to whether the indicated value will fit.
*/
#if PY_MAJOR_VERSION < 3
EXPCL_INTERROGATEDB PyObject *
PyLongOrInt_FromUnsignedLong(unsigned long value) {
if ((long)value < 0) {
return PyLong_FromUnsignedLong(value);
} else {
return PyInt_FromLong((long)value);
}
}
#endif
#endif // HAVE_PYTHON #endif // HAVE_PYTHON

View File

@ -103,10 +103,6 @@ inline PyObject* doPy_RETURN_FALSE()
#define nb_inplace_divide nb_inplace_true_divide #define nb_inplace_divide nb_inplace_true_divide
#define PyLongOrInt_Check(x) PyLong_Check(x) #define PyLongOrInt_Check(x) PyLong_Check(x)
#define PyLongOrInt_FromSize_t PyLong_FromSize_t
#define PyLongOrInt_FromSsize_t PyLong_FromSsize_t
#define PyLongOrInt_FromLong PyLong_FromLong
#define PyLongOrInt_FromUnsignedLong PyLong_FromUnsignedLong
#define PyLongOrInt_AS_LONG PyLong_AS_LONG #define PyLongOrInt_AS_LONG PyLong_AS_LONG
#define PyInt_Check PyLong_Check #define PyInt_Check PyLong_Check
#define PyInt_AsLong PyLong_AsLong #define PyInt_AsLong PyLong_AsLong
@ -114,9 +110,6 @@ inline PyObject* doPy_RETURN_FALSE()
#else #else
#define PyLongOrInt_Check(x) (PyInt_Check(x) || PyLong_Check(x)) #define PyLongOrInt_Check(x) (PyInt_Check(x) || PyLong_Check(x))
// PyInt_FromSize_t automatically picks the right type. // PyInt_FromSize_t automatically picks the right type.
#define PyLongOrInt_FromSize_t PyInt_FromSize_t
#define PyLongOrInt_FromSsize_t PyInt_FromSsize_t
#define PyLongOrInt_FromLong PyInt_FromLong
#define PyLongOrInt_AS_LONG PyInt_AsLong #define PyLongOrInt_AS_LONG PyInt_AsLong
// For more portably defining hash functions. // For more portably defining hash functions.
@ -159,9 +152,6 @@ typedef void *(*DowncastFunction)(void *, Dtool_PyTypedObject *);
typedef void *(*CoerceFunction)(PyObject *, void *); typedef void *(*CoerceFunction)(PyObject *, void *);
typedef void (*ModuleClassInitFunction)(PyObject *module); typedef void (*ModuleClassInitFunction)(PyObject *module);
// inline Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int
// type); inline void Dtool_Deallocate_General(PyObject * self); inline
// int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2); THIS IS THE
// INSTANCE CONTAINER FOR ALL panda py objects.... // INSTANCE CONTAINER FOR ALL panda py objects....
struct Dtool_PyInstDef { struct Dtool_PyInstDef {
PyObject_HEAD PyObject_HEAD
@ -300,17 +290,7 @@ EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyT
EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef, EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
void **answer, const char *method_name); void **answer, const char *method_name);
template<class T> INLINE bool DTOOL_Call_ExtractThisPointer(PyObject *self, T *&into) { template<class T> INLINE bool DTOOL_Call_ExtractThisPointer(PyObject *self, T *&into);
if (DtoolCanThisBeAPandaInstance(self)) {
Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
if (target_class != NULL) {
into = (T*) ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, target_class);
return (into != NULL);
}
}
into = NULL;
return false;
}
// Functions related to error reporting. // Functions related to error reporting.
EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred(); EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
@ -348,6 +328,12 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
#define Dtool_Return(value) _Dtool_Return(value) #define Dtool_Return(value) _Dtool_Return(value)
#endif #endif
/**
* Wrapper around Python 3.4's enum library, which does not have a C API.
*/
EXPCL_INTERROGATEDB PyObject *Dtool_EnumType_Create(const char *name, PyObject *names,
const char *module = NULL);
/** /**
*/ */
@ -359,29 +345,10 @@ EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyT
// These template methods allow use when the Dtool_PyTypedObject is not known. // These template methods allow use when the Dtool_PyTypedObject is not known.
// They require a get_class_type() to be defined for the class. // They require a get_class_type() to be defined for the class.
template<class T> INLINE PyObject *DTool_CreatePyInstance(const T *obj, bool memory_rules) { template<class T> INLINE PyObject *DTool_CreatePyInstance(const T *obj, bool memory_rules);
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); template<class T> INLINE PyObject *DTool_CreatePyInstance(T *obj, bool memory_rules);
nassertr(known_class != NULL, NULL); template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules);
return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, true); template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(T *obj, bool memory_rules);
}
template<class T> INLINE PyObject *DTool_CreatePyInstance(T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
nassertr(known_class != NULL, NULL);
return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, false);
}
template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
nassertr(known_class != NULL, NULL);
return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, true, obj->get_type().get_index());
}
template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) {
Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
nassertr(known_class != NULL, NULL);
return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index());
}
// Macro(s) class definition .. Used to allocate storage and init some values // Macro(s) class definition .. Used to allocate storage and init some values
// for a Dtool Py Type object. // for a Dtool Py Type object.
@ -474,11 +441,32 @@ copy_from_copy_constructor(PyObject *self, PyObject *noargs);
EXPCL_INTERROGATEDB PyObject * EXPCL_INTERROGATEDB PyObject *
map_deepcopy_to_copy(PyObject *self, PyObject *args); map_deepcopy_to_copy(PyObject *self, PyObject *args);
#if PY_MAJOR_VERSION < 3 /**
// In the Python 3 case, it is defined as a macro, at the beginning of this * These functions convert a C++ value into the corresponding Python object.
// file. * This used to be generated by the code generator, but it seems more reliable
EXPCL_INTERROGATEDB PyObject * * and maintainable to define these as overloads and have the compiler sort
PyLongOrInt_FromUnsignedLong(unsigned long value); * it out.
*/
ALWAYS_INLINE PyObject *Dtool_WrapValue(int value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(unsigned int value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(long value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(unsigned long value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(long long value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(unsigned long long value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(bool value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(double value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(const char *value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(const wchar_t *value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::string &value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::wstring &value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::string *value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::wstring *value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(char value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(wchar_t value);
ALWAYS_INLINE PyObject *Dtool_WrapValue(PyObject *value);
#if PY_MAJOR_VERSION >= 0x02060000
ALWAYS_INLINE PyObject *Dtool_WrapValue(Py_buffer *value);
#endif #endif
EXPCL_INTERROGATEDB extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE; EXPCL_INTERROGATEDB extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE;
@ -486,6 +474,8 @@ EXPCL_INTERROGATEDB extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObjec
#define Dtool_Ptr_DTOOL_SUPER_BASE (&Dtool_DTOOL_SUPER_BASE) #define Dtool_Ptr_DTOOL_SUPER_BASE (&Dtool_DTOOL_SUPER_BASE)
#include "py_panda.I"
#endif // HAVE_PYTHON && !CPPPARSER #endif // HAVE_PYTHON && !CPPPARSER
#endif // PY_PANDA_H_ #endif // PY_PANDA_H_

View File

@ -25,14 +25,7 @@ match_files(const Filename &cwd) const {
PyObject *result = PyList_New(contents.size()); PyObject *result = PyList_New(contents.size());
for (size_t i = 0; i < contents.size(); ++i) { for (size_t i = 0; i < contents.size(); ++i) {
const string &filename = contents[i]; PyList_SET_ITEM(result, i, Dtool_WrapValue(contents[i]));
#if PY_MAJOR_VERSION >= 3
// This function expects UTF-8.
PyObject *str = PyUnicode_FromStringAndSize(filename.data(), filename.size());
#else
PyObject *str = PyString_FromStringAndSize(filename.data(), filename.size());
#endif
PyList_SET_ITEM(result, i, str);
} }
return result; return result;

View File

@ -11,16 +11,6 @@
* @date 2011-01-02 * @date 2011-01-02
*/ */
#ifdef FLOATTYPE_IS_INT
#if PY_MAJOR_VERSION >= 3
#define PY_FROM_FLOATTYPE PyLong_FromLong
#else
#define PY_FROM_FLOATTYPE PyInt_FromLong
#endif
#else
#define PY_FROM_FLOATTYPE PyFloat_FromDouble
#endif
/** /**
* *
*/ */
@ -53,7 +43,7 @@ __getattr__(PyObject *self, const string &attr_name) const {
switch (attr_name.size()) { switch (attr_name.size()) {
case 1: case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x')); return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: { case 2: {
FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2); FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2);
@ -89,5 +79,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase2. // Upcall to LVecBase2.
return invoke_extension<FLOATNAME(LVecBase2)>(_this).__setattr__(self, attr_name, assign); return invoke_extension<FLOATNAME(LVecBase2)>(_this).__setattr__(self, attr_name, assign);
} }
#undef PY_FROM_FLOATTYPE

View File

@ -11,16 +11,6 @@
* @date 2011-01-02 * @date 2011-01-02
*/ */
#ifdef FLOATTYPE_IS_INT
#if PY_MAJOR_VERSION >= 3
#define PY_FROM_FLOATTYPE PyLong_FromLong
#else
#define PY_FROM_FLOATTYPE PyInt_FromLong
#endif
#else
#define PY_FROM_FLOATTYPE PyFloat_FromDouble
#endif
/** /**
* *
*/ */
@ -54,7 +44,7 @@ __getattr__(PyObject *self, const string &attr_name) const {
switch (attr_name.size()) { switch (attr_name.size()) {
case 1: case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x')); return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: { case 2: {
FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2); FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2);
@ -90,5 +80,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase2. // Upcall to LVecBase2.
return invoke_extension<FLOATNAME(LVecBase3)>(_this).__setattr__(self, attr_name, assign); return invoke_extension<FLOATNAME(LVecBase3)>(_this).__setattr__(self, attr_name, assign);
} }
#undef PY_FROM_FLOATTYPE

View File

@ -11,16 +11,6 @@
* @date 2011-01-02 * @date 2011-01-02
*/ */
#ifdef FLOATTYPE_IS_INT
#if PY_MAJOR_VERSION >= 3
#define PY_FROM_FLOATTYPE PyLong_FromLong
#else
#define PY_FROM_FLOATTYPE PyInt_FromLong
#endif
#else
#define PY_FROM_FLOATTYPE PyFloat_FromDouble
#endif
/** /**
* *
*/ */
@ -56,9 +46,9 @@ __getattr__(PyObject *self, const string &attr_name) const {
switch (attr_name.size()) { switch (attr_name.size()) {
case 1: case 1:
if (attr_name[0] == 'w') { if (attr_name[0] == 'w') {
return PY_FROM_FLOATTYPE(_this->_v(3)); return Dtool_WrapValue(_this->_v(3));
} else { } else {
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x')); return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
} }
case 2: { case 2: {
@ -95,5 +85,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase4. // Upcall to LVecBase4.
return invoke_extension<FLOATNAME(LVecBase4)>(_this).__setattr__(self, attr_name, assign); return invoke_extension<FLOATNAME(LVecBase4)>(_this).__setattr__(self, attr_name, assign);
} }
#undef PY_FROM_FLOATTYPE

View File

@ -14,16 +14,13 @@
#ifdef FLOATTYPE_IS_INT #ifdef FLOATTYPE_IS_INT
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
#define PYNUMBER_FLOATTYPE PyNumber_Long #define PYNUMBER_FLOATTYPE PyNumber_Long
#define PY_FROM_FLOATTYPE PyLong_FromLong
#define PY_AS_FLOATTYPE PyLong_AS_LONG #define PY_AS_FLOATTYPE PyLong_AS_LONG
#else #else
#define PYNUMBER_FLOATTYPE PyNumber_Int #define PYNUMBER_FLOATTYPE PyNumber_Int
#define PY_FROM_FLOATTYPE PyInt_FromLong
#define PY_AS_FLOATTYPE PyInt_AS_LONG #define PY_AS_FLOATTYPE PyInt_AS_LONG
#endif #endif
#else #else
#define PYNUMBER_FLOATTYPE PyNumber_Float #define PYNUMBER_FLOATTYPE PyNumber_Float
#define PY_FROM_FLOATTYPE PyFloat_FromDouble
#define PY_AS_FLOATTYPE (FLOATTYPE)PyFloat_AsDouble #define PY_AS_FLOATTYPE (FLOATTYPE)PyFloat_AsDouble
#endif #endif
@ -88,7 +85,7 @@ __getattr__(PyObject *self, const string &attr_name) const {
switch (attr_name.size()) { switch (attr_name.size()) {
case 1: case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x')); return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: { case 2: {
FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2); FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2);
@ -222,5 +219,4 @@ __ipow__(PyObject *self, FLOATTYPE exponent) {
} }
#undef PYNUMBER_FLOATTYPE #undef PYNUMBER_FLOATTYPE
#undef PY_FROM_FLOATTYPE
#undef PY_AS_FLOATTYPE #undef PY_AS_FLOATTYPE

View File

@ -14,16 +14,13 @@
#ifdef FLOATTYPE_IS_INT #ifdef FLOATTYPE_IS_INT
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
#define PYNUMBER_FLOATTYPE PyNumber_Long #define PYNUMBER_FLOATTYPE PyNumber_Long
#define PY_FROM_FLOATTYPE PyLong_FromLong
#define PY_AS_FLOATTYPE PyLong_AS_LONG #define PY_AS_FLOATTYPE PyLong_AS_LONG
#else #else
#define PYNUMBER_FLOATTYPE PyNumber_Int #define PYNUMBER_FLOATTYPE PyNumber_Int
#define PY_FROM_FLOATTYPE PyInt_FromLong
#define PY_AS_FLOATTYPE PyInt_AS_LONG #define PY_AS_FLOATTYPE PyInt_AS_LONG
#endif #endif
#else #else
#define PYNUMBER_FLOATTYPE PyNumber_Float #define PYNUMBER_FLOATTYPE PyNumber_Float
#define PY_FROM_FLOATTYPE PyFloat_FromDouble
#define PY_AS_FLOATTYPE (FLOATTYPE)PyFloat_AsDouble #define PY_AS_FLOATTYPE (FLOATTYPE)PyFloat_AsDouble
#endif #endif
@ -89,7 +86,7 @@ __getattr__(PyObject *self, const string &attr_name) const {
switch (attr_name.size()) { switch (attr_name.size()) {
case 1: case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x')); return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: { case 2: {
FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2); FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2);
@ -225,5 +222,4 @@ __ipow__(PyObject *self, FLOATTYPE exponent) {
} }
#undef PYNUMBER_FLOATTYPE #undef PYNUMBER_FLOATTYPE
#undef PY_FROM_FLOATTYPE
#undef PY_AS_FLOATTYPE #undef PY_AS_FLOATTYPE

View File

@ -14,16 +14,13 @@
#ifdef FLOATTYPE_IS_INT #ifdef FLOATTYPE_IS_INT
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
#define PYNUMBER_FLOATTYPE PyNumber_Long #define PYNUMBER_FLOATTYPE PyNumber_Long
#define PY_FROM_FLOATTYPE PyLong_FromLong
#define PY_AS_FLOATTYPE PyLong_AS_LONG #define PY_AS_FLOATTYPE PyLong_AS_LONG
#else #else
#define PYNUMBER_FLOATTYPE PyNumber_Int #define PYNUMBER_FLOATTYPE PyNumber_Int
#define PY_FROM_FLOATTYPE PyInt_FromLong
#define PY_AS_FLOATTYPE PyInt_AS_LONG #define PY_AS_FLOATTYPE PyInt_AS_LONG
#endif #endif
#else #else
#define PYNUMBER_FLOATTYPE PyNumber_Float #define PYNUMBER_FLOATTYPE PyNumber_Float
#define PY_FROM_FLOATTYPE PyFloat_FromDouble
#define PY_AS_FLOATTYPE (FLOATTYPE)PyFloat_AsDouble #define PY_AS_FLOATTYPE (FLOATTYPE)PyFloat_AsDouble
#endif #endif
@ -91,9 +88,9 @@ __getattr__(PyObject *self, const string &attr_name) const {
switch (attr_name.size()) { switch (attr_name.size()) {
case 1: case 1:
if (attr_name[0] == 'w') { if (attr_name[0] == 'w') {
return PY_FROM_FLOATTYPE(_this->_v(3)); return Dtool_WrapValue(_this->_v(3));
} else { } else {
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x')); return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
} }
case 2: { case 2: {
@ -233,5 +230,4 @@ __ipow__(PyObject *self, FLOATTYPE exponent) {
} }
#undef PYNUMBER_FLOATTYPE #undef PYNUMBER_FLOATTYPE
#undef PY_FROM_FLOATTYPE
#undef PY_AS_FLOATTYPE #undef PY_AS_FLOATTYPE

View File

@ -11,16 +11,6 @@
* @date 2011-01-02 * @date 2011-01-02
*/ */
#ifdef FLOATTYPE_IS_INT
#if PY_MAJOR_VERSION >= 3
#define PY_FROM_FLOATTYPE PyLong_FromLong
#else
#define PY_FROM_FLOATTYPE PyInt_FromLong
#endif
#else
#define PY_FROM_FLOATTYPE PyFloat_FromDouble
#endif
/** /**
* *
*/ */
@ -53,7 +43,7 @@ __getattr__(PyObject *self, const string &attr_name) const {
switch (attr_name.size()) { switch (attr_name.size()) {
case 1: case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x')); return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: { case 2: {
FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2); FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2);
@ -89,5 +79,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase2. // Upcall to LVecBase2.
return invoke_extension<FLOATNAME(LVecBase2)>(_this).__setattr__(self, attr_name, assign); return invoke_extension<FLOATNAME(LVecBase2)>(_this).__setattr__(self, attr_name, assign);
} }
#undef PY_FROM_FLOATTYPE

View File

@ -11,16 +11,6 @@
* @date 2011-01-02 * @date 2011-01-02
*/ */
#ifdef FLOATTYPE_IS_INT
#if PY_MAJOR_VERSION >= 3
#define PY_FROM_FLOATTYPE PyLong_FromLong
#else
#define PY_FROM_FLOATTYPE PyInt_FromLong
#endif
#else
#define PY_FROM_FLOATTYPE PyFloat_FromDouble
#endif
/** /**
* *
*/ */
@ -54,7 +44,7 @@ __getattr__(PyObject *self, const string &attr_name) const {
switch (attr_name.size()) { switch (attr_name.size()) {
case 1: case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x')); return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: { case 2: {
FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2); FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2);
@ -90,5 +80,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase3. // Upcall to LVecBase3.
return invoke_extension<FLOATNAME(LVecBase3)>(_this).__setattr__(self, attr_name, assign); return invoke_extension<FLOATNAME(LVecBase3)>(_this).__setattr__(self, attr_name, assign);
} }
#undef PY_FROM_FLOATTYPE

View File

@ -11,16 +11,6 @@
* @date 2011-01-02 * @date 2011-01-02
*/ */
#ifdef FLOATTYPE_IS_INT
#if PY_MAJOR_VERSION >= 3
#define PY_FROM_FLOATTYPE PyLong_FromLong
#else
#define PY_FROM_FLOATTYPE PyInt_FromLong
#endif
#else
#define PY_FROM_FLOATTYPE PyFloat_FromDouble
#endif
/** /**
* *
*/ */
@ -56,9 +46,9 @@ __getattr__(PyObject *self, const string &attr_name) const {
switch (attr_name.size()) { switch (attr_name.size()) {
case 1: case 1:
if (attr_name[0] == 'w') { if (attr_name[0] == 'w') {
return PY_FROM_FLOATTYPE(_this->_v(3)); return Dtool_WrapValue(_this->_v(3));
} else { } else {
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x')); return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
} }
case 2: { case 2: {
@ -95,5 +85,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase4. // Upcall to LVecBase4.
return invoke_extension<FLOATNAME(LVecBase4)>(_this).__setattr__(self, attr_name, assign); return invoke_extension<FLOATNAME(LVecBase4)>(_this).__setattr__(self, attr_name, assign);
} }
#undef PY_FROM_FLOATTYPE

View File

@ -187,15 +187,9 @@ get_tag_keys() const {
vector_string keys; vector_string keys;
_this->get_tag_keys(keys); _this->get_tag_keys(keys);
PyObject *result = PyList_New(keys.size()); PyObject *result = PyTuple_New(keys.size());
for (size_t i = 0; i < keys.size(); ++i) { for (size_t i = 0; i < keys.size(); ++i) {
const string &tag_name = keys[i]; PyTuple_SET_ITEM(result, i, Dtool_WrapValue(keys[i]));
#if PY_MAJOR_VERSION >= 3
PyObject *str = PyUnicode_FromStringAndSize(tag_name.data(), tag_name.size());
#else
PyObject *str = PyString_FromStringAndSize(tag_name.data(), tag_name.size());
#endif
PyList_SET_ITEM(result, i, str);
} }
return result; return result;
@ -209,15 +203,9 @@ get_python_tag_keys() const {
vector_string keys; vector_string keys;
get_python_tag_keys(keys); get_python_tag_keys(keys);
PyObject *result = PyList_New(keys.size()); PyObject *result = PyTuple_New(keys.size());
for (size_t i = 0; i < keys.size(); ++i) { for (size_t i = 0; i < keys.size(); ++i) {
const string &tag_name = keys[i]; PyTuple_SET_ITEM(result, i, Dtool_WrapValue(keys[i]));
#if PY_MAJOR_VERSION >= 3
PyObject *str = PyUnicode_FromStringAndSize(tag_name.data(), tag_name.size());
#else
PyObject *str = PyString_FromStringAndSize(tag_name.data(), tag_name.size());
#endif
PyList_SET_ITEM(result, i, str);
} }
return result; return result;