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

View File

@ -2349,21 +2349,23 @@ enum:
;
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);
}
| 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);
current_enum = new CPPEnumType($1, NULL, $3, current_scope, NULL, @1.file);
}
| 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 ','
{
assert(current_enum != NULL);
CPPInstance *inst = current_enum->add_element($2->get_simple_name());
current_scope->add_enum_value(inst, current_lexer, @2);
current_enum->add_element($2->get_simple_name(), NULL, current_lexer, @2);
}
| enum_body_trailing_comma name '=' const_expr ','
{
assert(current_enum != NULL);
CPPInstance *inst = current_enum->add_element($2->get_simple_name(), $4);
current_scope->add_enum_value(inst, current_lexer, @2);
current_enum->add_element($2->get_simple_name(), $4, current_lexer, @2);
};
enum_body:
@ -2398,14 +2398,12 @@ enum_body:
| enum_body_trailing_comma name
{
assert(current_enum != NULL);
CPPInstance *inst = current_enum->add_element($2->get_simple_name());
current_scope->add_enum_value(inst, current_lexer, @2);
current_enum->add_element($2->get_simple_name(), NULL, current_lexer, @2);
}
| enum_body_trailing_comma name '=' const_expr
{
assert(current_enum != NULL);
CPPInstance *inst = current_enum->add_element($2->get_simple_name(), $4);
current_scope->add_enum_value(inst, current_lexer, @2);
current_enum->add_element($2->get_simple_name(), $4, current_lexer, @2);
}
;
@ -2413,6 +2411,14 @@ enum_keyword:
KW_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
{
$$ = 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"
/**
* Creates an untyped, unscoped enum.
* Creates an untyped enum.
*/
CPPEnumType::
CPPEnumType(CPPIdentifier *ident, CPPScope *current_scope,
const CPPFile &file) :
CPPExtensionType(T_enum, ident, current_scope, file),
_parent_scope(current_scope),
CPPEnumType(Type type, CPPIdentifier *ident, CPPScope *current_scope,
CPPScope *scope, const CPPFile &file) :
CPPExtensionType(type, ident, current_scope, file),
_scope(scope),
_element_type(NULL),
_last_value(NULL)
{
_parent_scope = (type == T_enum) ? current_scope : scope;
if (ident != NULL) {
ident->_native_scope = current_scope;
}
}
/**
* Creates a typed but unscoped enum.
* Creates a typed enum.
*/
CPPEnumType::
CPPEnumType(CPPIdentifier *ident, CPPType *element_type,
CPPScope *current_scope, const CPPFile &file) :
CPPExtensionType(T_enum, ident, current_scope, file),
_parent_scope(current_scope),
CPPEnumType(Type type, CPPIdentifier *ident, CPPType *element_type,
CPPScope *current_scope, CPPScope *scope, const CPPFile &file) :
CPPExtensionType(type, ident, current_scope, file),
_scope(scope),
_element_type(element_type),
_last_value(NULL)
{
_parent_scope = (type == T_enum) ? current_scope : scope;
if (ident != NULL) {
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.
*/
CPPType *CPPEnumType::
get_element_type() {
get_underlying_type() {
if (_element_type == NULL) {
// This enum is untyped. Use a suitable default, ie. 'int'. In the
// future, we might want to check whether it fits in an int.
@ -78,11 +89,18 @@ get_element_type() {
*
*/
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);
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;
_elements.push_back(inst);
@ -104,6 +122,41 @@ add_element(const string &name, CPPExpression *value) {
}
inst->_initializer = 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;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -124,34 +124,9 @@ add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
*
*/
void CPPScope::
add_enum_value(CPPInstance *inst, CPPPreprocessor *preprocessor,
const cppyyltype &pos) {
add_enum_value(CPPInstance *inst) {
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();
if (!name.empty()) {
_enum_values[name] = inst;
@ -183,6 +158,8 @@ define_extension_type(CPPExtensionType *type, CPPPreprocessor *error_sink) {
break;
case CPPExtensionType::T_enum:
case CPPExtensionType::T_enum_struct:
case CPPExtensionType::T_enum_class:
_enums[name] = type;
break;
}
@ -606,6 +583,11 @@ find_scope(const string &name, bool recurse) const {
if (st != NULL) {
return st->_scope;
}
CPPEnumType *et = type->as_enum_type();
if (et != NULL) {
return et->_scope;
}
}
Using::const_iterator ui;
@ -645,11 +627,16 @@ find_scope(const string &name, CPPDeclaration::SubstDecl &subst,
}
CPPStructType *st = type->as_struct_type();
if (st == NULL) {
return NULL;
if (st != 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,
CPPPreprocessor *preprocessor,
const cppyyltype &pos);
virtual void add_enum_value(CPPInstance *inst,
CPPPreprocessor *preprocessor,
const cppyyltype &pos);
virtual void add_enum_value(CPPInstance *inst);
virtual void define_extension_type(CPPExtensionType *type,
CPPPreprocessor *error_sink = NULL);
virtual void define_namespace(CPPNamespace *scope);

View File

@ -43,11 +43,10 @@ add_declaration(CPPDeclaration *decl, CPPScope *global_scope,
*
*/
void CPPTemplateScope::
add_enum_value(CPPInstance *inst, CPPPreprocessor *preprocessor,
const cppyyltype &pos) {
add_enum_value(CPPInstance *inst) {
inst->_template_scope = this;
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,
CPPPreprocessor *preprocessor,
const cppyyltype &pos);
virtual void add_enum_value(CPPInstance *inst,
CPPPreprocessor *preprocessor,
const cppyyltype &pos);
virtual void add_enum_value(CPPInstance *inst);
virtual void define_extension_type(CPPExtensionType *type,
CPPPreprocessor *error_sink = NULL);
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_code << "//********************************************************************\n";
out_code << "//*** prototypes for .. Global\n";
out_code << "//********************************************************************\n";
/*
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 << "//*** prototypes for .. External Objects\n";
out_code << "//********************************************************************\n";
out_code << "/**\n";
out_code << " * Extern declarations for imported classes\n";
out_code << " */\n";
for (std::set<CPPType *>::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ii++) {
CPPType *type = (*ii);
@ -897,9 +893,9 @@ write_prototypes_class_external(ostream &out, Object *obj) {
std::string preferred_name = obj->_itype.get_name();
out << "//********************************************************************\n";
out << "//*** prototypes for external.. " << class_name << "\n";
out << "//********************************************************************\n";
out << "/**\n";
out << " * Forward declaration of class " << class_name << "\n";
out << " */\n";
// This typedef is necessary for class templates since we can't pass a comma
// 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());
Functions::iterator fi;
out_code << "//********************************************************************\n";
out_code << "//*** prototypes for .. " << ClassName << "\n";
out_code << "//********************************************************************\n";
out_code << "/**\n";
out_code << " * Forward declarations for top-level class " << ClassName << "\n";
out_code << " */\n";
/*
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::
write_functions(ostream &out) {
out << "//********************************************************************\n";
out << "//*** Functions for .. Global\n" ;
out << "//********************************************************************\n";
out << "/**\n";
out << " * Python wrappers for global functions\n" ;
out << " */\n";
FunctionsByIndex::iterator fi;
for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
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 cClassName = obj->_itype.get_true_name();
out << "//********************************************************************\n";
out << "//*** Functions for .. " << cClassName << "\n" ;
out << "//********************************************************************\n";
out << "/**\n";
out << " * Python wrappers for functions of class " << cClassName << "\n" ;
out << " */\n";
// First write out all the wrapper functions for the methods.
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] ;
string class_name = make_safe_name(obj->_itype.get_scoped_name());
string class_ptr;
out << " // Module init upcall for " << obj->_itype.get_scoped_name() << "\n";
if (!obj->_itype.is_typedef()) {
out << " // " << *(obj->_itype._cpptype) << "\n";
@ -1242,9 +1237,9 @@ write_sub_module(ostream &out, Object *obj) {
*/
void InterfaceMakerPythonNative::
write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
out << "//********************************************************************\n";
out << "//*** Module Object Linker ..\n";
out << "//********************************************************************\n";
out << "/**\n";
out << " * Module Object Linker ..\n";
out << " */\n";
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() &&
isExportThisRun(object->_itype._cpptype)) {
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);
string name2 = classNameFromCppName(object->_itype.get_enum_value_name(xx), true);
string enum_value = "::" + object->_itype.get_enum_value_name(xx);
out << " PyModule_AddIntConstant(module, \"" << name1 << "\", " << enum_value << ");\n";
if (name1 != name2) {
// Also write the mangled name, for historical purposes.
out << " PyModule_AddIntConstant(module, \"" << name2 << "\", " << enum_value << ");\n";
if (object->_itype.is_scoped_enum()) {
// Convert as Python 3.4 enum.
CPPType *underlying_type = TypeManager::unwrap_const(object->_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 " << object->_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(\""
<< 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";
@ -1435,9 +1450,9 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
InterfaceMakerPython::write_module(out, out_h, def);
Objects::iterator oi;
out << "//********************************************************************\n";
out << "//*** Py Init Code For .. GlobalScope\n" ;
out << "//********************************************************************\n";
out << "/**\n";
out << " * Module initialization functions for Python module \"" << def->module_name << "\"\n";
out << " */\n";
out << "#if PY_MAJOR_VERSION >= 3\n"
<< "static struct PyModuleDef python_native_module = {\n"
@ -1452,14 +1467,16 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
<< "#ifdef _WIN32\n"
<< "extern \"C\" __declspec(dllexport) PyObject *PyInit_" << def->module_name << "();\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"
<< "extern \"C\" PyObject *PyInit_" << def->module_name << "();\n"
<< "#endif\n"
<< "\n"
<< "PyObject *PyInit_" << def->module_name << "() {\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"
<< "#else // Python 2 case\n"
@ -1467,14 +1484,15 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
<< "#ifdef _WIN32\n"
<< "extern \"C\" __declspec(dllexport) void init" << def->module_name << "();\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"
<< "extern \"C\" void init" << def->module_name << "();\n"
<< "#endif\n"
<< "\n"
<< "void init" << def->module_name << "() {\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"
<< "#endif\n"
@ -1520,9 +1538,9 @@ write_module_class(ostream &out, Object *obj) {
}
Functions::iterator fi;
out << "//********************************************************************\n";
out << "//*** Py Init Code For .. " << ClassName << " | " << export_class_name << "\n" ;
out << "//********************************************************************\n";
out << "/**\n";
out << " * Python method tables for " << ClassName << " (" << export_class_name << ")\n" ;
out << " */\n";
out << "static PyMethodDef Dtool_Methods_" << ClassName << "[] = {\n";
SlottedFunctions slots;
@ -2449,11 +2467,7 @@ write_module_class(ostream &out, Object *obj) {
<< classNameFromCppName(ClassName, false) << "\");\n";
}
out << " std::string ss = os.str();\n";
out << "#if PY_MAJOR_VERSION >= 3\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 << " return Dtool_WrapValue(ss);\n";
out << "}\n\n";
has_local_repr = true;
}
@ -2479,11 +2493,7 @@ write_module_class(ostream &out, Object *obj) {
out << " local_this->write(os);\n";
}
out << " std::string ss = os.str();\n";
out << "#if PY_MAJOR_VERSION >= 3\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 << " return Dtool_WrapValue(ss);\n";
out << "}\n\n";
has_local_str = true;
}
@ -3037,7 +3047,7 @@ write_module_class(ostream &out, Object *obj) {
} else if (nested_obj->_itype.is_typedef()) {
++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();
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
// 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()) {
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::Elements::const_iterator 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;
}
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) {
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;
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) {
remap = (*ri);
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";
@ -6033,164 +6068,16 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
CPPType *orig_type = return_type->get_orig_type();
CPPType *type = return_type->get_new_type();
if (return_type->new_type_is_atomic_string()) {
if (TypeManager::is_char_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";
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(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)) {
if (return_type->new_type_is_atomic_string() ||
TypeManager::is_simple(type) ||
TypeManager::is_char_pointer(type) ||
TypeManager::is_wchar_pointer(type) ||
TypeManager::is_pointer_to_PyObject(type) ||
TypeManager::is_pointer_to_Py_buffer(type)) {
// Most types are now handled by the many overloads of Dtool_WrapValue,
// defined in py_panda.h.
indent(out, indent_level)
<< "return PyBool_FromLong(" << 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";
<< "return Dtool_WrapValue(" << return_expr << ");\n";
} else if (TypeManager::is_pointer(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 {
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 {
// Return None.
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"
"\n"
" for (Py_ssize_t i = 0; i < count; ++i) {\n"
"#if PY_MAJOR_VERSION >= 3\n"
" PyObject *index = PyLong_FromSsize_t(i);\n"
"#else\n"
" PyObject *index = PyInt_FromSsize_t(i);\n"
"#endif\n";
" PyObject *index = Dtool_WrapValue(i);\n";
switch (elem_getter->_args_type) {
case AT_keyword_args:

View File

@ -2838,6 +2838,10 @@ define_enum_type(InterrogateType &itype, CPPEnumType *cpptype) {
return;
}
if (cpptype->is_scoped()) {
itype._flags |= InterrogateType::F_scoped_enum;
}
int next_value = 0;
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.
switch (cpptype->_type) {
case CPPExtensionType::T_enum:
case CPPExtensionType::T_enum_class:
case CPPExtensionType::T_enum_struct:
itype._flags |= InterrogateType::F_enum;
break;

View File

@ -205,6 +205,14 @@ is_enum() const {
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 bool is_enum() const;
INLINE bool is_scoped_enum() const;
INLINE int number_of_enum_values() const;
INLINE const string &get_enum_value_name(int n) const;
INLINE const string &get_enum_value_scoped_name(int n) const;
@ -136,6 +137,7 @@ private:
F_unpublished = 0x100000,
F_typedef = 0x200000,
F_array = 0x400000,
F_scoped_enum = 0x800000,
};
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;
}
/**
* 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 *)"()");
}
/**
* 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

View File

@ -103,10 +103,6 @@ inline PyObject* doPy_RETURN_FALSE()
#define nb_inplace_divide nb_inplace_true_divide
#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 PyInt_Check PyLong_Check
#define PyInt_AsLong PyLong_AsLong
@ -114,9 +110,6 @@ inline PyObject* doPy_RETURN_FALSE()
#else
#define PyLongOrInt_Check(x) (PyInt_Check(x) || PyLong_Check(x))
// 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
// For more portably defining hash functions.
@ -159,9 +152,6 @@ typedef void *(*DowncastFunction)(void *, Dtool_PyTypedObject *);
typedef void *(*CoerceFunction)(PyObject *, void *);
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....
struct Dtool_PyInstDef {
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,
void **answer, const char *method_name);
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;
}
template<class T> INLINE bool DTOOL_Call_ExtractThisPointer(PyObject *self, T *&into);
// Functions related to error reporting.
EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
@ -348,6 +328,12 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
#define Dtool_Return(value) _Dtool_Return(value)
#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.
// 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) {
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());
}
template<class T> INLINE PyObject *DTool_CreatePyInstance(const T *obj, bool memory_rules);
template<class T> INLINE PyObject *DTool_CreatePyInstance(T *obj, bool memory_rules);
template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules);
template<class T> INLINE PyObject *DTool_CreatePyInstanceTyped(T *obj, bool memory_rules);
// Macro(s) class definition .. Used to allocate storage and init some values
// for a Dtool Py Type object.
@ -474,11 +441,32 @@ copy_from_copy_constructor(PyObject *self, PyObject *noargs);
EXPCL_INTERROGATEDB PyObject *
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
// file.
EXPCL_INTERROGATEDB PyObject *
PyLongOrInt_FromUnsignedLong(unsigned long value);
/**
* These functions convert a C++ value into the corresponding Python object.
* This used to be generated by the code generator, but it seems more reliable
* and maintainable to define these as overloads and have the compiler sort
* 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
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)
#include "py_panda.I"
#endif // HAVE_PYTHON && !CPPPARSER
#endif // PY_PANDA_H_

View File

@ -25,14 +25,7 @@ match_files(const Filename &cwd) const {
PyObject *result = PyList_New(contents.size());
for (size_t i = 0; i < contents.size(); ++i) {
const string &filename = 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);
PyList_SET_ITEM(result, i, Dtool_WrapValue(contents[i]));
}
return result;

View File

@ -11,16 +11,6 @@
* @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()) {
case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x'));
return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: {
FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2);
@ -89,5 +79,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase2.
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
*/
#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()) {
case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x'));
return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: {
FLOATNAME(LPoint2) *vec = new FLOATNAME(LPoint2);
@ -90,5 +80,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase2.
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
*/
#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()) {
case 1:
if (attr_name[0] == 'w') {
return PY_FROM_FLOATTYPE(_this->_v(3));
return Dtool_WrapValue(_this->_v(3));
} else {
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x'));
return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
}
case 2: {
@ -95,5 +85,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase4.
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
#if PY_MAJOR_VERSION >= 3
#define PYNUMBER_FLOATTYPE PyNumber_Long
#define PY_FROM_FLOATTYPE PyLong_FromLong
#define PY_AS_FLOATTYPE PyLong_AS_LONG
#else
#define PYNUMBER_FLOATTYPE PyNumber_Int
#define PY_FROM_FLOATTYPE PyInt_FromLong
#define PY_AS_FLOATTYPE PyInt_AS_LONG
#endif
#else
#define PYNUMBER_FLOATTYPE PyNumber_Float
#define PY_FROM_FLOATTYPE PyFloat_FromDouble
#define PY_AS_FLOATTYPE (FLOATTYPE)PyFloat_AsDouble
#endif
@ -88,7 +85,7 @@ __getattr__(PyObject *self, const string &attr_name) const {
switch (attr_name.size()) {
case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x'));
return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: {
FLOATNAME(LVecBase2) *vec = new FLOATNAME(LVecBase2);
@ -222,5 +219,4 @@ __ipow__(PyObject *self, FLOATTYPE exponent) {
}
#undef PYNUMBER_FLOATTYPE
#undef PY_FROM_FLOATTYPE
#undef PY_AS_FLOATTYPE

View File

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

View File

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

View File

@ -11,16 +11,6 @@
* @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()) {
case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x'));
return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: {
FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2);
@ -89,5 +79,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase2.
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
*/
#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()) {
case 1:
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x'));
return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
case 2: {
FLOATNAME(LVector2) *vec = new FLOATNAME(LVector2);
@ -90,5 +80,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase3.
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
*/
#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()) {
case 1:
if (attr_name[0] == 'w') {
return PY_FROM_FLOATTYPE(_this->_v(3));
return Dtool_WrapValue(_this->_v(3));
} else {
return PY_FROM_FLOATTYPE(_this->_v(attr_name[0] - 'x'));
return Dtool_WrapValue(_this->_v(attr_name[0] - 'x'));
}
case 2: {
@ -95,5 +85,3 @@ __setattr__(PyObject *self, const string &attr_name, PyObject *assign) {
// Upcall to LVecBase4.
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;
_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) {
const string &tag_name = 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);
PyTuple_SET_ITEM(result, i, Dtool_WrapValue(keys[i]));
}
return result;
@ -209,15 +203,9 @@ get_python_tag_keys() const {
vector_string 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) {
const string &tag_name = 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);
PyTuple_SET_ITEM(result, i, Dtool_WrapValue(keys[i]));
}
return result;