mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
Compare commits
32 Commits
0.3.4.15_1
...
nightly-0.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
19ddf62874 | ||
![]() |
f7e85fbe9f | ||
![]() |
05ccbc9cf8 | ||
![]() |
3b52c7e2e7 | ||
![]() |
77da379693 | ||
![]() |
8593004166 | ||
![]() |
0d94af2fd6 | ||
![]() |
59da9e7ab6 | ||
![]() |
eb2a66a109 | ||
![]() |
9b075a4c4b | ||
![]() |
3e65ce7284 | ||
![]() |
a4bf259c82 | ||
![]() |
1420f049ce | ||
![]() |
419f8a9ed4 | ||
![]() |
2a6dac9467 | ||
![]() |
0511f53462 | ||
![]() |
026376a13d | ||
![]() |
c9e13175f1 | ||
![]() |
c342479aed | ||
![]() |
44519f0f60 | ||
![]() |
f873361282 | ||
![]() |
a64b5853b5 | ||
![]() |
629caf9d7a | ||
![]() |
f86a28dfe2 | ||
![]() |
776f45c56a | ||
![]() |
7eaee83fa8 | ||
![]() |
19928a6a58 | ||
![]() |
c069186ca7 | ||
![]() |
f22048c87f | ||
![]() |
0f5fdf8131 | ||
![]() |
5a7f0b03ee | ||
![]() |
9c61860d6b |
18
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
18
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
[Description]
|
||||
Describe the reproduce step and symptom with details. If applicable, add attachment, code snippets or screenshots to help explain your problem.
|
||||
|
||||
[Configuration]
|
||||
- OS: (i.e Windows 11 24H2, 64bit)
|
||||
- WinDbg: (i.e. 10.0.26100.2454, AMD64)
|
||||
- Python: (i.e. 3.10.11, 64bit)
|
||||
- pykd: (i.e. 0.3.4.15, check with python -m pip list)
|
||||
- pykd.dll: (i.e. 2.0.0.25, check with windbg command ".chain")
|
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,2 +1,6 @@
|
||||
*.pyc
|
||||
.vs
|
||||
.vs
|
||||
Out/
|
||||
Obj/
|
||||
cmake/
|
||||
packages/
|
||||
*.vcxproj.user
|
||||
|
7
.gitmodules
vendored
7
.gitmodules
vendored
@ -1,3 +1,6 @@
|
||||
[submodule "kdlibcpp"]
|
||||
path = kdlibcpp
|
||||
[submodule "kdlibcpp"]
|
||||
path = kdlibcpp
|
||||
url = https://github.com/ivellioscolin/kdlibcpp.git
|
||||
[submodule "pykd_ext"]
|
||||
path = pykd_ext
|
||||
url = https://github.com/ivellioscolin/pykd-ext.git
|
||||
|
BIN
.nuget/nuget.exe
Normal file
BIN
.nuget/nuget.exe
Normal file
Binary file not shown.
19
CHANGELOG.md
Normal file
19
CHANGELOG.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to the pykd maintenance fork will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
### Changed
|
||||
### Deprecated
|
||||
### Removed
|
||||
### Fixed
|
||||
### Security
|
||||
|
||||
## [0.3.4.15_2] - 2023-02-27
|
||||
### Added
|
||||
- Support Python 3.11
|
||||
|
||||
## [0.3.4.15_1] - 2023-02-22
|
||||
### Added
|
||||
- Support Python 3.10.
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 pykd
|
||||
Copyright (c) 2025 pykd
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
83
README.md
83
README.md
@ -1,66 +1,17 @@
|
||||
# Pykd - not only python extension for WinDBG
|
||||
|
||||
## Purpose
|
||||
This project can help to automate debugging and crash dump analysis using Python. It allows one to take the best from both worlds: the expressiveness and convenience of Python with the power of WinDbg!
|
||||
|
||||
## Why do I need this?
|
||||
If you want to automate the debugger but dislike the WinDbg built-in script machine syntax it's time to try again using the handy and powerful Python language. Even if you don't want to create your own script, maybe some existing scripts will be of interest to you?
|
||||
|
||||
## Getting started
|
||||
* You should have installed python. Supported python: 2.7, 3.5 - 3.9
|
||||
* Install pykd with command: 'pip install pykd'
|
||||
* Use windbg extension (bootstrapper) to run pykd with windbg
|
||||
|
||||
## Windbg extension (bootstarpper)
|
||||
Use it to run pykd within windbg.
|
||||
[Home Page](https://githomelab.ru/pykd/pykd-ext)
|
||||
[Download](https://githomelab.ru/pykd/pykd-ext/wikis/Downloads)
|
||||
|
||||
## Releases
|
||||
Just run 'pip install pykd' to install or 'pip install pykd --upgrade' to upgrade to the last version
|
||||
[PyPi](https://pypi.org/project/pykd)
|
||||
[All Releases](/../wikis/All Releases)
|
||||
|
||||
## Documentation
|
||||
[Wiki Home](/../wikis/Home)
|
||||
[User Manual](/../wikis/User Manual rus)
|
||||
[API Reference](/../wikis/API Reference)
|
||||
|
||||
## Useful tools for pykd and WinDBG
|
||||
[windbg-pack](https://githomelab.ru/pykd/windbg-pack)
|
||||
Set of python scripts for WinDBG
|
||||
|
||||
[pykdwin](https://githomelab.ru/pykd/pykdwin)
|
||||
A library with auxiliary modules for writing small pykd scripts and daily use.
|
||||
|
||||
[windbg-kernel](https://githomelab.ru/pykd/windbg-kernel)
|
||||
Set of pykd script for kernel debugging
|
||||
|
||||
|
||||
## How to build ?
|
||||
* install VS 2017
|
||||
https://visualstudio.microsoft.com/downloads/
|
||||
|
||||
* install cmake
|
||||
https://cmake.org/
|
||||
|
||||
* install git
|
||||
https://git-scm.com/
|
||||
|
||||
* get sources:
|
||||
|
||||
```
|
||||
git clone --recurse-submodules https://githomelab.ru/pykd/pykd.git local_dir
|
||||
```
|
||||
* open pykd.sln
|
||||
* choose a python version and a target platform then build pykd projects
|
||||
|
||||
## Projects used pykd
|
||||
[mona.py](https://github.com/corelan/mona)
|
||||
the exploit writer's swiss army knife
|
||||
|
||||
[flare-dbg](https://github.com/fireeye/flare-dbg)
|
||||
flare-dbg is a project meant to aid malware reverse engineers in rapidly developing debugger scripts.
|
||||
|
||||
[voltron](https://github.com/snare/voltron)
|
||||
Voltron is an extensible debugger UI toolkit written in Python
|
||||
# pykd Maintenance
|
||||
|
||||
The repo is trying to continue the maintenance as the original project page is no longer accessible.
|
||||
|
||||
## [Links]
|
||||
- [Project Page](https://githomelab.ru/pykd/pykd)
|
||||
- [Web Archive](https://web.archive.org/web/20230321180029/https://githomelab.ru/pykd/pykd)
|
||||
|
||||
## [Maintenance Release]
|
||||
- 0.3.4.15_2 - 2023-02-27
|
||||
- 0.3.4.15_1 - 2023-02-22
|
||||
|
||||
## [Change log]
|
||||
Check [CHANGELOG](CHANGELOG.md) for the maintenance updates.
|
||||
|
||||
## [Read Me]
|
||||
Check the original [README](README_OLD.md) for more information about pykd.
|
66
README_OLD.md
Normal file
66
README_OLD.md
Normal file
@ -0,0 +1,66 @@
|
||||
# Pykd - not only python extension for WinDBG
|
||||
|
||||
## Purpose
|
||||
This project can help to automate debugging and crash dump analysis using Python. It allows one to take the best from both worlds: the expressiveness and convenience of Python with the power of WinDbg!
|
||||
|
||||
## Why do I need this?
|
||||
If you want to automate the debugger but dislike the WinDbg built-in script machine syntax it's time to try again using the handy and powerful Python language. Even if you don't want to create your own script, maybe some existing scripts will be of interest to you?
|
||||
|
||||
## Getting started
|
||||
* You should have installed python. Supported python: 2.7, 3.5 - 3.9
|
||||
* Install pykd with command: 'pip install pykd'
|
||||
* Use windbg extension (bootstrapper) to run pykd with windbg
|
||||
|
||||
## Windbg extension (bootstarpper)
|
||||
Use it to run pykd within windbg.
|
||||
[Home Page](https://githomelab.ru/pykd/pykd-ext)
|
||||
[Download](https://githomelab.ru/pykd/pykd-ext/wikis/Downloads)
|
||||
|
||||
## Releases
|
||||
Just run 'pip install pykd' to install or 'pip install pykd --upgrade' to upgrade to the last version
|
||||
[PyPi](https://pypi.org/project/pykd)
|
||||
[All Releases](/../wikis/All Releases)
|
||||
|
||||
## Documentation
|
||||
[Wiki Home](/../wikis/Home)
|
||||
[User Manual](/../wikis/User Manual rus)
|
||||
[API Reference](/../wikis/API Reference)
|
||||
|
||||
## Useful tools for pykd and WinDBG
|
||||
[windbg-pack](https://githomelab.ru/pykd/windbg-pack)
|
||||
Set of python scripts for WinDBG
|
||||
|
||||
[pykdwin](https://githomelab.ru/pykd/pykdwin)
|
||||
A library with auxiliary modules for writing small pykd scripts and daily use.
|
||||
|
||||
[windbg-kernel](https://githomelab.ru/pykd/windbg-kernel)
|
||||
Set of pykd script for kernel debugging
|
||||
|
||||
|
||||
## How to build ?
|
||||
* install VS 2017
|
||||
https://visualstudio.microsoft.com/downloads/
|
||||
|
||||
* install cmake
|
||||
https://cmake.org/
|
||||
|
||||
* install git
|
||||
https://git-scm.com/
|
||||
|
||||
* get sources:
|
||||
|
||||
```
|
||||
git clone --recurse-submodules https://githomelab.ru/pykd/pykd.git local_dir
|
||||
```
|
||||
* open pykd.sln
|
||||
* choose a python version and a target platform then build pykd projects
|
||||
|
||||
## Projects used pykd
|
||||
[mona.py](https://github.com/corelan/mona)
|
||||
the exploit writer's swiss army knife
|
||||
|
||||
[flare-dbg](https://github.com/fireeye/flare-dbg)
|
||||
flare-dbg is a project meant to aid malware reverse engineers in rapidly developing debugger scripts.
|
||||
|
||||
[voltron](https://github.com/snare/voltron)
|
||||
Voltron is an extensible debugger UI toolkit written in Python
|
1214
docs/en/documentation.md
Normal file
1214
docs/en/documentation.md
Normal file
File diff suppressed because it is too large
Load Diff
150
docs/en/tutorial.md
Normal file
150
docs/en/tutorial.md
Normal file
@ -0,0 +1,150 @@
|
||||
## Introduction
|
||||
|
||||
### Step 1: Getting Started
|
||||
It is best to use the automatic installer for installation. It will install pykd in the correct location and also install and register all necessary components.
|
||||
|
||||
If the installation completes without errors, it is time to get acquainted with pykd. To do this, start **WinDbg** and begin a debugging session (open a process, dump file, or establish a connection with a kernel debugger). Now, you can load pykd by running the following command:
|
||||
|
||||
```
|
||||
.load pykd.pyd
|
||||
```
|
||||
|
||||
If any errors occur during loading, WinDbg will display a message. The absence of any messages indicates that the extension has been successfully loaded.
|
||||
|
||||
Now, you can start working. Execute the following command:
|
||||
|
||||
```
|
||||
!pycmd
|
||||
```
|
||||
After running this command, the debugger will enter user input mode. All user input will be processed by the Python interpreter.
|
||||
|
||||
```
|
||||
0:000> !pycmd
|
||||
Python 2.6.6 (r266:84297, Aug 24 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)] on win32
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
(InteractiveConsole)
|
||||
>>> print "Hello world!"
|
||||
Hello world!
|
||||
>>>
|
||||
```
|
||||
|
||||
Now is a good time to get familiar with Python syntax if you haven’t already. Python is very easy to learn.
|
||||
|
||||
Let's recall some basic syntax of Python:
|
||||
|
||||
```
|
||||
>>> def printHello():
|
||||
... i = 0
|
||||
... while i < 4:
|
||||
... print "Hello #%d" % i
|
||||
... i += 1
|
||||
...
|
||||
>>> printHello()
|
||||
Hello #0
|
||||
Hello #1
|
||||
Hello #2
|
||||
Hello #3
|
||||
>>>
|
||||
```
|
||||
|
||||
Note: The indentation of blocks is determined by leading spaces, which is a "signature" feature of Python. For now, this knowledge will be sufficient. Let’s move on.
|
||||
|
||||
### Step 2: Accessing Registers
|
||||
|
||||
Any debugger should provide three basic capabilities: reading processor registers, reading memory, and controlling debugging mode. Let’s start with registers. With **pykd**, this is quite simple:
|
||||
|
||||
```
|
||||
>>> print hex(reg("eip"))
|
||||
0x778ecb60
|
||||
>>> print hex(reg("esp"))
|
||||
0x1ef0e0
|
||||
>>> print hex(reg("esp")+4)
|
||||
0x1ef0e4
|
||||
```
|
||||
|
||||
In this case, we use the **PYKD** function `reg`. It reads processor registers by name. A curious reader might ask: how do we use functions from **PYKD** without explicitly importing the module? In reality, the module must be imported. However, **PYKD** automatically does this when constructing the Python console.
|
||||
|
||||
Let's write a small example to check where the current instruction pointer is pointing:
|
||||
|
||||
```
|
||||
>>> print findSymbol(reg("eip"))
|
||||
ntdll!LdrpDoDebuggerBreak+30
|
||||
```
|
||||
|
||||
The `findSymbol` function attempts to find a debug symbol for a given address. In this case, we see that the instruction pointer is at offset `0x30` within the function `LdrpDoDebuggerBreak`, which is located in the **ntdll** module. We can determine this because we have debugging information for **ntdll.dll** (the corresponding **pdb** file). If symbols are not displaying for some reason, check your symbol path settings in **WinDbg**.
|
||||
|
||||
### Step 3: Accessing Memory
|
||||
|
||||
**PYKD** provides a large set of functions for accessing memory, which can be divided into three categories:
|
||||
|
||||
#### 1. Reading values from memory:
|
||||
- `ptrByte`
|
||||
- `ptrWord`
|
||||
- `ptrDWord`
|
||||
- `ptrQWord`
|
||||
|
||||
There are other functions as well; the full set can be found in the **PYKD 0.2 API Reference**. All functions take an address as a parameter and return the value stored at that address.
|
||||
|
||||
#### 2. Reading arrays
|
||||
- `loadBytes`
|
||||
- `loadWords`
|
||||
- `loadDWords`
|
||||
- `loadQWords`
|
||||
|
||||
All functions take a pointer to the beginning of an array and its length in elements as parameters. They return a **list** object containing the array elements.
|
||||
|
||||
#### 3. Reading strings
|
||||
- `loadCStr`
|
||||
- `loadWStr`
|
||||
|
||||
These functions read **null-terminated** strings from memory and return Python strings.
|
||||
|
||||
Let’s modify the previous example to display function arguments. We assume that the function follows the **stdcall** calling convention and that its parameters are addressed by the **ebp** register.
|
||||
|
||||
```
|
||||
>>> def printFunc():
|
||||
... print findSymbol( reg("eip") )
|
||||
... params = [ ptrDWord( reg("ebp") + 4*(i+1) ) for i in range(0,3) ]
|
||||
... print "var1: %x var2: %x var3: %x" % ( params[0], params[1], params[2] )
|
||||
...
|
||||
>>> print printFunc()
|
||||
ntdll32!LdrpDoDebuggerBreak+2c
|
||||
var1: 774b1383 var2: fffdd000 var3: fffde000
|
||||
None
|
||||
>>>
|
||||
```
|
||||
|
||||
Pay attention to this construct:
|
||||
|
||||
```
|
||||
params = [ ptrDWord( reg("ebp") + 4*(i+1) ) for i in range(0,3) ]
|
||||
```
|
||||
|
||||
This is a **list comprehension**—a special Python construct that simplifies list initialization. It is equivalent to:
|
||||
|
||||
```
|
||||
[ ptrDWord( reg("ebp") + 4) ), ptrDWord( reg("ebp") + 8) ), ptrDWord( reg("ebp") + 0xC) ) ]
|
||||
```
|
||||
|
||||
### Step 4: Accessing Memory with Type Information
|
||||
|
||||
When debugging programs, we often work with **typed variables**. **PYKD** has powerful capabilities for accessing variables while preserving type information. This is one of the key features of the project: accessing struct and class fields in a way similar to source code.
|
||||
|
||||
For example, consider the following **C** code:
|
||||
|
||||
```
|
||||
struct STRUCT_A {
|
||||
int field1;
|
||||
char field2;
|
||||
};
|
||||
|
||||
STRUCT_A a = { 100, 2 }
|
||||
```
|
||||
|
||||
Now, during debugging, we want to check the state of variable `a` using **PYKD**:
|
||||
|
||||
```
|
||||
a = typedVar( "module!STRUCT_A", getOffset("module!a") )
|
||||
if a.field1 != 100 or a.field2 != 2:
|
||||
print "ERROR! a is not properly initialized!"
|
||||
```
|
2
kdlibcpp
2
kdlibcpp
@ -1 +1 @@
|
||||
Subproject commit e54598d2f904acab23d340c93ce77c551a396ecb
|
||||
Subproject commit 8d27b5bbe0ab88408076b688f0794c42cdafdf21
|
310
pykd.sln
310
pykd.sln
@ -32,16 +32,21 @@ EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kdlib", "kdlibcpp\kdlib\source\kdlib.vcxproj", "{3E9C538F-F060-4E86-AB7D-D44439615B63}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pykd", "pykd\pykd.vcxproj", "{C4C45791-0201-4406-BC5C-A384B01E3BF5}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF} = {0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "targetapp", "kdlibcpp\kdlib\tests\targetapp\targetapp.vcxproj", "{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pykd_ext_2.0", "pykd_ext\sources\pykd_ext.vcxproj", "{583F9A6C-AF6D-45E0-A8F4-290D93611185}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug_2.7|Win32 = Debug_2.7|Win32
|
||||
Debug_2.7|x64 = Debug_2.7|x64
|
||||
Debug_3.10|Win32 = Debug_3.10|Win32
|
||||
Debug_3.10|x64 = Debug_3.10|x64
|
||||
Debug_3.11|Win32 = Debug_3.11|Win32
|
||||
Debug_3.11|x64 = Debug_3.11|x64
|
||||
Debug_3.12|Win32 = Debug_3.12|Win32
|
||||
Debug_3.12|x64 = Debug_3.12|x64
|
||||
Debug_3.13|Win32 = Debug_3.13|Win32
|
||||
Debug_3.13|x64 = Debug_3.13|x64
|
||||
Debug_3.5|Win32 = Debug_3.5|Win32
|
||||
Debug_3.5|x64 = Debug_3.5|x64
|
||||
Debug_3.6|Win32 = Debug_3.6|Win32
|
||||
@ -54,6 +59,14 @@ Global
|
||||
Debug_3.9|x64 = Debug_3.9|x64
|
||||
Release_2.7|Win32 = Release_2.7|Win32
|
||||
Release_2.7|x64 = Release_2.7|x64
|
||||
Release_3.10|Win32 = Release_3.10|Win32
|
||||
Release_3.10|x64 = Release_3.10|x64
|
||||
Release_3.11|Win32 = Release_3.11|Win32
|
||||
Release_3.11|x64 = Release_3.11|x64
|
||||
Release_3.12|Win32 = Release_3.12|Win32
|
||||
Release_3.12|x64 = Release_3.12|x64
|
||||
Release_3.13|Win32 = Release_3.13|Win32
|
||||
Release_3.13|x64 = Release_3.13|x64
|
||||
Release_3.5|Win32 = Release_3.5|Win32
|
||||
Release_3.5|x64 = Release_3.5|x64
|
||||
Release_3.6|Win32 = Release_3.6|Win32
|
||||
@ -69,6 +82,14 @@ Global
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_2.7|Win32.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_2.7|Win32.Build.0 = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_2.7|x64.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.10|Win32.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.10|x64.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.11|Win32.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.11|x64.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.12|Win32.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.12|x64.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.13|Win32.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.13|x64.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.5|Win32.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.5|x64.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.6|Win32.ActiveCfg = Debug|Any CPU
|
||||
@ -81,6 +102,14 @@ Global
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Debug_3.9|x64.ActiveCfg = Debug|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_2.7|Win32.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_2.7|x64.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.10|Win32.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.10|x64.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.11|Win32.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.11|x64.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.12|Win32.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.12|x64.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.13|Win32.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.13|x64.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.5|Win32.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.5|x64.ActiveCfg = Release|Any CPU
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.6|Win32.ActiveCfg = Release|Any CPU
|
||||
@ -93,6 +122,14 @@ Global
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8}.Release_3.9|x64.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_2.7|Win32.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_2.7|x64.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.10|Win32.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.10|x64.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.11|Win32.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.11|x64.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.12|Win32.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.12|x64.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.13|Win32.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.13|x64.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.5|Win32.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.5|x64.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.6|Win32.ActiveCfg = Debug|Any CPU
|
||||
@ -105,6 +142,14 @@ Global
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Debug_3.9|x64.ActiveCfg = Debug|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_2.7|Win32.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_2.7|x64.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.10|Win32.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.10|x64.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.11|Win32.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.11|x64.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.12|Win32.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.12|x64.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.13|Win32.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.13|x64.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.5|Win32.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.5|x64.ActiveCfg = Release|Any CPU
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.6|Win32.ActiveCfg = Release|Any CPU
|
||||
@ -117,6 +162,14 @@ Global
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC}.Release_3.9|x64.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_2.7|Win32.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_2.7|x64.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.10|Win32.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.10|x64.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.11|Win32.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.11|x64.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.12|Win32.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.12|x64.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.13|Win32.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.13|x64.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.5|Win32.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.5|x64.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.6|Win32.ActiveCfg = Debug|Any CPU
|
||||
@ -129,6 +182,14 @@ Global
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Debug_3.9|x64.ActiveCfg = Debug|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_2.7|Win32.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_2.7|x64.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.10|Win32.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.10|x64.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.11|Win32.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.11|x64.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.12|Win32.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.12|x64.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.13|Win32.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.13|x64.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.5|Win32.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.5|x64.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.6|Win32.ActiveCfg = Release|Any CPU
|
||||
@ -139,34 +200,66 @@ Global
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.8|x64.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.9|Win32.ActiveCfg = Release|Any CPU
|
||||
{D78837DC-BF31-4FC4-88A5-7F2FADAFA795}.Release_3.9|x64.ActiveCfg = Release|Any CPU
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_2.7|Win32.ActiveCfg = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_2.7|Win32.Build.0 = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_2.7|x64.ActiveCfg = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_2.7|x64.Build.0 = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.5|Win32.ActiveCfg = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.5|Win32.Build.0 = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.5|x64.ActiveCfg = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.5|x64.Build.0 = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.6|Win32.ActiveCfg = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.6|Win32.Build.0 = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.6|x64.ActiveCfg = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.6|x64.Build.0 = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.7|Win32.ActiveCfg = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.7|Win32.Build.0 = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.7|x64.ActiveCfg = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.7|x64.Build.0 = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.8|Win32.ActiveCfg = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.8|Win32.Build.0 = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.8|x64.ActiveCfg = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.8|x64.Build.0 = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.9|Win32.ActiveCfg = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.9|Win32.Build.0 = Debug|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.9|x64.ActiveCfg = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.9|x64.Build.0 = Debug|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_2.7|Win32.ActiveCfg = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_2.7|Win32.Build.0 = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_2.7|x64.ActiveCfg = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_2.7|x64.Build.0 = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.10|Win32.ActiveCfg = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.10|Win32.Build.0 = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.10|x64.ActiveCfg = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.10|x64.Build.0 = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.11|Win32.ActiveCfg = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.11|Win32.Build.0 = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.11|x64.ActiveCfg = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.11|x64.Build.0 = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.12|Win32.ActiveCfg = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.12|Win32.Build.0 = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.12|x64.ActiveCfg = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.12|x64.Build.0 = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.13|Win32.ActiveCfg = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.13|Win32.Build.0 = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.13|x64.ActiveCfg = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.13|x64.Build.0 = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.5|Win32.ActiveCfg = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.5|Win32.Build.0 = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.5|x64.ActiveCfg = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.5|x64.Build.0 = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.6|Win32.ActiveCfg = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.6|Win32.Build.0 = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.6|x64.ActiveCfg = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.6|x64.Build.0 = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.7|Win32.ActiveCfg = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.7|Win32.Build.0 = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.7|x64.ActiveCfg = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.7|x64.Build.0 = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.8|Win32.ActiveCfg = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.8|Win32.Build.0 = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.8|x64.ActiveCfg = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.8|x64.Build.0 = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.9|Win32.ActiveCfg = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.9|Win32.Build.0 = Debug_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.9|x64.ActiveCfg = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Debug_3.9|x64.Build.0 = Debug_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_2.7|Win32.ActiveCfg = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_2.7|Win32.Build.0 = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_2.7|x64.ActiveCfg = Release_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_2.7|x64.Build.0 = Release_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.10|Win32.ActiveCfg = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.10|Win32.Build.0 = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.10|x64.ActiveCfg = Release_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.10|x64.Build.0 = Release_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.11|Win32.ActiveCfg = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.11|Win32.Build.0 = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.11|x64.ActiveCfg = Release_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.11|x64.Build.0 = Release_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.12|Win32.ActiveCfg = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.12|Win32.Build.0 = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.12|x64.ActiveCfg = Release_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.12|x64.Build.0 = Release_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.13|Win32.ActiveCfg = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.13|Win32.Build.0 = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.13|x64.ActiveCfg = Release_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.13|x64.Build.0 = Release_Static|x64
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.5|Win32.ActiveCfg = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.5|Win32.Build.0 = Release_Static|Win32
|
||||
{3E9C538F-F060-4E86-AB7D-D44439615B63}.Release_3.5|x64.ActiveCfg = Release_Static|x64
|
||||
@ -191,6 +284,22 @@ Global
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_2.7|Win32.Build.0 = Debug_2.7|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_2.7|x64.ActiveCfg = Debug_2.7|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_2.7|x64.Build.0 = Debug_2.7|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.10|Win32.ActiveCfg = Debug_3.10|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.10|Win32.Build.0 = Debug_3.10|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.10|x64.ActiveCfg = Debug_3.10|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.10|x64.Build.0 = Debug_3.10|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.11|Win32.ActiveCfg = Debug_3.11|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.11|Win32.Build.0 = Debug_3.11|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.11|x64.ActiveCfg = Debug_3.11|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.11|x64.Build.0 = Debug_3.11|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.12|Win32.ActiveCfg = Debug_3.12|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.12|Win32.Build.0 = Debug_3.12|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.12|x64.ActiveCfg = Debug_3.12|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.12|x64.Build.0 = Debug_3.12|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.13|Win32.ActiveCfg = Debug_3.13|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.13|Win32.Build.0 = Debug_3.13|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.13|x64.ActiveCfg = Debug_3.13|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.13|x64.Build.0 = Debug_3.13|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.5|Win32.ActiveCfg = Debug_3.5|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.5|Win32.Build.0 = Debug_3.5|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Debug_3.5|x64.ActiveCfg = Debug_3.5|x64
|
||||
@ -215,6 +324,22 @@ Global
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_2.7|Win32.Build.0 = Release_2.7|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_2.7|x64.ActiveCfg = Release_2.7|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_2.7|x64.Build.0 = Release_2.7|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.10|Win32.ActiveCfg = Release_3.10|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.10|Win32.Build.0 = Release_3.10|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.10|x64.ActiveCfg = Release_3.10|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.10|x64.Build.0 = Release_3.10|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.11|Win32.ActiveCfg = Release_3.11|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.11|Win32.Build.0 = Release_3.11|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.11|x64.ActiveCfg = Release_3.11|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.11|x64.Build.0 = Release_3.11|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.12|Win32.ActiveCfg = Release_3.12|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.12|Win32.Build.0 = Release_3.12|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.12|x64.ActiveCfg = Release_3.12|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.12|x64.Build.0 = Release_3.12|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.13|Win32.ActiveCfg = Release_3.13|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.13|Win32.Build.0 = Release_3.13|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.13|x64.ActiveCfg = Release_3.13|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.13|x64.Build.0 = Release_3.13|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.5|Win32.ActiveCfg = Release_3.5|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.5|Win32.Build.0 = Release_3.5|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.5|x64.ActiveCfg = Release_3.5|x64
|
||||
@ -235,54 +360,86 @@ Global
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.9|Win32.Build.0 = Release_3.9|Win32
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.9|x64.ActiveCfg = Release_3.9|x64
|
||||
{C4C45791-0201-4406-BC5C-A384B01E3BF5}.Release_3.9|x64.Build.0 = Release_3.9|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_2.7|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_2.7|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_2.7|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_2.7|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.5|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.5|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.5|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.5|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.6|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.6|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.6|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.6|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.7|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.7|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.7|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.7|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.8|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.8|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.8|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.8|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.9|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.9|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.9|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Debug_3.9|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_2.7|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_2.7|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_2.7|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_2.7|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.5|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.5|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.5|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.5|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.6|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.6|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.6|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.6|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.7|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.7|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.7|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.7|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.8|Win32.ActiveCfg = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.8|Win32.Build.0 = Debug|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.8|x64.ActiveCfg = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.8|x64.Build.0 = Debug|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.9|Win32.ActiveCfg = Release|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.9|Win32.Build.0 = Release|Win32
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.9|x64.ActiveCfg = Release|x64
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF}.Release_3.9|x64.Build.0 = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_2.7|Win32.ActiveCfg = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_2.7|Win32.Build.0 = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_2.7|x64.ActiveCfg = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_2.7|x64.Build.0 = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.10|Win32.ActiveCfg = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.10|Win32.Build.0 = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.10|x64.ActiveCfg = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.10|x64.Build.0 = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.11|Win32.ActiveCfg = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.11|Win32.Build.0 = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.11|x64.ActiveCfg = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.11|x64.Build.0 = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.12|Win32.ActiveCfg = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.12|Win32.Build.0 = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.12|x64.ActiveCfg = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.12|x64.Build.0 = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.13|Win32.ActiveCfg = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.13|Win32.Build.0 = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.13|x64.ActiveCfg = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.13|x64.Build.0 = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.5|Win32.ActiveCfg = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.5|Win32.Build.0 = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.5|x64.ActiveCfg = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.5|x64.Build.0 = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.6|Win32.ActiveCfg = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.6|Win32.Build.0 = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.6|x64.ActiveCfg = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.6|x64.Build.0 = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.7|Win32.ActiveCfg = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.7|Win32.Build.0 = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.7|x64.ActiveCfg = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.7|x64.Build.0 = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.8|Win32.ActiveCfg = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.8|Win32.Build.0 = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.8|x64.ActiveCfg = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.8|x64.Build.0 = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.9|Win32.ActiveCfg = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.9|Win32.Build.0 = Debug|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.9|x64.ActiveCfg = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Debug_3.9|x64.Build.0 = Debug|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_2.7|Win32.ActiveCfg = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_2.7|Win32.Build.0 = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_2.7|x64.ActiveCfg = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_2.7|x64.Build.0 = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.10|Win32.ActiveCfg = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.10|Win32.Build.0 = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.10|x64.ActiveCfg = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.10|x64.Build.0 = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.11|Win32.ActiveCfg = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.11|Win32.Build.0 = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.11|x64.ActiveCfg = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.11|x64.Build.0 = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.12|Win32.ActiveCfg = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.12|Win32.Build.0 = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.12|x64.ActiveCfg = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.12|x64.Build.0 = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.13|Win32.ActiveCfg = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.13|Win32.Build.0 = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.13|x64.ActiveCfg = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.13|x64.Build.0 = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.5|Win32.ActiveCfg = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.5|Win32.Build.0 = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.5|x64.ActiveCfg = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.5|x64.Build.0 = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.6|Win32.ActiveCfg = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.6|Win32.Build.0 = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.6|x64.ActiveCfg = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.6|x64.Build.0 = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.7|Win32.ActiveCfg = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.7|Win32.Build.0 = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.7|x64.ActiveCfg = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.7|x64.Build.0 = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.8|Win32.ActiveCfg = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.8|Win32.Build.0 = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.8|x64.ActiveCfg = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.8|x64.Build.0 = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.9|Win32.ActiveCfg = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.9|Win32.Build.0 = Release|Win32
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.9|x64.ActiveCfg = Release|x64
|
||||
{583F9A6C-AF6D-45E0-A8F4-290D93611185}.Release_3.9|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -291,7 +448,6 @@ Global
|
||||
{EEFC9510-DFA7-439E-801E-48FCE72766AD} = {A7AF87D2-983B-4B3A-823F-5A2C6989672E}
|
||||
{3F0BE77E-19B0-4192-B432-44A25805BCB8} = {5A3C2DA6-AE91-4025-AC03-A58BD03CEBCD}
|
||||
{6471FEDC-3129-410F-BFFC-4BC89707E5EC} = {AAB21DD2-B0EE-493E-8415-5195F18879EB}
|
||||
{0E4CC688-F2F5-499F-9C07-0F2CAEE0D3EF} = {5A3C2DA6-AE91-4025-AC03-A58BD03CEBCD}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {23D3DF9E-C3F8-476E-8B59-440641E1B2D6}
|
||||
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "dict.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "errors.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "exec.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "import.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "list.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "long.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "module.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "object_operators.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "object_protocol.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "slice.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "str.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "tuple.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "wrapper.cpp"
|
@ -1,28 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/converter/arg_to_python_base.hpp>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <boost/python/refcount.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
arg_to_python_base::arg_to_python_base(
|
||||
void const volatile* source, registration const& converters)
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179
|
||||
: handle<>
|
||||
# else
|
||||
: m_ptr
|
||||
# endif
|
||||
(converters.to_python(source))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "arg_to_python_base.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "builtin_converters.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "from_python.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "registry.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "type_id.cpp"
|
@ -1,592 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <boost/python/type_id.hpp>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/refcount.hpp>
|
||||
|
||||
#include <boost/python/detail/config.hpp>
|
||||
#include <boost/python/detail/wrap_python.hpp>
|
||||
|
||||
#include <boost/python/converter/builtin_converters.hpp>
|
||||
#include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/python/converter/shared_ptr_deleter.hpp>
|
||||
#include <boost/python/converter/pytype_function.hpp>
|
||||
|
||||
#include <boost/cast.hpp>
|
||||
#include <string>
|
||||
#include <complex>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
shared_ptr_deleter::shared_ptr_deleter(handle<> owner)
|
||||
: owner(owner)
|
||||
{}
|
||||
|
||||
shared_ptr_deleter::~shared_ptr_deleter() {}
|
||||
|
||||
void shared_ptr_deleter::operator()(void const*)
|
||||
{
|
||||
owner.reset();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// An lvalue conversion function which extracts a char const* from a
|
||||
// Python String.
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
void* convert_to_cstring(PyObject* obj)
|
||||
{
|
||||
return PyString_Check(obj) ? PyString_AsString(obj) : 0;
|
||||
}
|
||||
#elif PY_VERSION_HEX < 0x03070000
|
||||
void* convert_to_cstring(PyObject* obj)
|
||||
{
|
||||
return PyUnicode_Check(obj) ? _PyUnicode_AsString(obj) : 0;
|
||||
}
|
||||
#else
|
||||
void* convert_to_cstring(PyObject* obj)
|
||||
{
|
||||
return PyUnicode_Check(obj) ? const_cast<void*>(reinterpret_cast<const void*>(_PyUnicode_AsString(obj))) : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Given a target type and a SlotPolicy describing how to perform a
|
||||
// given conversion, registers from_python converters which use the
|
||||
// SlotPolicy to extract the type.
|
||||
template <class T, class SlotPolicy>
|
||||
struct slot_rvalue_from_python
|
||||
{
|
||||
public:
|
||||
slot_rvalue_from_python()
|
||||
{
|
||||
registry::insert(
|
||||
&slot_rvalue_from_python<T,SlotPolicy>::convertible
|
||||
, &slot_rvalue_from_python<T,SlotPolicy>::construct
|
||||
, type_id<T>()
|
||||
, &SlotPolicy::get_pytype
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
static void* convertible(PyObject* obj)
|
||||
{
|
||||
unaryfunc* slot = SlotPolicy::get_slot(obj);
|
||||
return slot && *slot ? slot : 0;
|
||||
}
|
||||
|
||||
static void construct(PyObject* obj, rvalue_from_python_stage1_data* data)
|
||||
{
|
||||
// Get the (intermediate) source object
|
||||
unaryfunc creator = *static_cast<unaryfunc*>(data->convertible);
|
||||
handle<> intermediate(creator(obj));
|
||||
|
||||
// Get the location in which to construct
|
||||
void* storage = ((rvalue_from_python_storage<T>*)data)->storage.bytes;
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4244)
|
||||
# endif
|
||||
new (storage) T( SlotPolicy::extract(intermediate.get()) );
|
||||
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
// record successful construction
|
||||
data->convertible = storage;
|
||||
}
|
||||
};
|
||||
|
||||
// identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
|
||||
// "slot" which just returns its argument.
|
||||
extern "C" PyObject* identity_unaryfunc(PyObject* x)
|
||||
{
|
||||
Py_INCREF(x);
|
||||
return x;
|
||||
}
|
||||
unaryfunc py_object_identity = identity_unaryfunc;
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
// As in Python 3 there is only one integer type, we can have much
|
||||
// simplified logic.
|
||||
// XXX(bhy) maybe the code will work with 2.6 or even 2.5?
|
||||
struct int_rvalue_from_python_base
|
||||
{
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
return PyLong_Check(obj) ? &py_object_identity : 0;
|
||||
}
|
||||
static PyTypeObject const* get_pytype() {return &PyLong_Type;}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct signed_int_rvalue_from_python : int_rvalue_from_python_base
|
||||
{
|
||||
static T extract(PyObject* intermediate)
|
||||
{
|
||||
long x = PyLong_AsLong(intermediate);
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return numeric_cast<T>(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct unsigned_int_rvalue_from_python : int_rvalue_from_python_base
|
||||
{
|
||||
static T extract(PyObject* intermediate)
|
||||
{
|
||||
unsigned long x = PyLong_AsUnsignedLong(intermediate);
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return numeric_cast<T>(x);
|
||||
}
|
||||
};
|
||||
#else // PY_VERSION_HEX >= 0x03000000
|
||||
// A SlotPolicy for extracting signed integer types from Python objects
|
||||
struct signed_int_rvalue_from_python_base
|
||||
{
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
return (
|
||||
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
|
||||
!PyBool_Check(obj) &&
|
||||
#endif
|
||||
(PyInt_Check(obj) || PyLong_Check(obj)))
|
||||
|
||||
? &number_methods->nb_int : 0;
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct signed_int_rvalue_from_python : signed_int_rvalue_from_python_base
|
||||
{
|
||||
static T extract(PyObject* intermediate)
|
||||
{
|
||||
long x = PyInt_AsLong(intermediate);
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return numeric_cast<T>(x);
|
||||
}
|
||||
};
|
||||
|
||||
// A SlotPolicy for extracting unsigned integer types from Python objects
|
||||
struct unsigned_int_rvalue_from_python_base
|
||||
{
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
return (
|
||||
#if PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
|
||||
!PyBool_Check(obj) &&
|
||||
#endif
|
||||
(PyInt_Check(obj) || PyLong_Check(obj)))
|
||||
? &py_object_identity : 0;
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyInt_Type;}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct unsigned_int_rvalue_from_python : unsigned_int_rvalue_from_python_base
|
||||
{
|
||||
static T extract(PyObject* intermediate)
|
||||
{
|
||||
if (PyLong_Check(intermediate)) {
|
||||
// PyLong_AsUnsignedLong() checks for negative overflow, so no
|
||||
// need to check it here.
|
||||
unsigned long result = PyLong_AsUnsignedLong(intermediate);
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return numeric_cast<T>(result);
|
||||
} else {
|
||||
// None of PyInt_AsUnsigned*() functions check for negative
|
||||
// overflow, so use PyInt_AS_LONG instead and check if number is
|
||||
// negative, issuing the exception appropriately.
|
||||
long result = PyInt_AS_LONG(intermediate);
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
if (result < 0) {
|
||||
PyErr_SetString(PyExc_OverflowError, "can't convert negative"
|
||||
" value to unsigned");
|
||||
throw_error_already_set();
|
||||
}
|
||||
return numeric_cast<T>(result);
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // PY_VERSION_HEX >= 0x03000000
|
||||
|
||||
// Checking Python's macro instead of Boost's - we don't seem to get
|
||||
// the config right all the time. Furthermore, Python's is defined
|
||||
// when long long is absent but __int64 is present.
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
// A SlotPolicy for extracting long long types from Python objects
|
||||
|
||||
struct long_long_rvalue_from_python_base
|
||||
{
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
return PyLong_Check(obj) ? &py_object_identity : 0;
|
||||
#else
|
||||
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
// Return the identity conversion slot to avoid creating a
|
||||
// new object. We'll handle that in the extract function
|
||||
if (PyInt_Check(obj))
|
||||
return &number_methods->nb_int;
|
||||
else if (PyLong_Check(obj))
|
||||
return &number_methods->nb_long;
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyLong_Type;}
|
||||
};
|
||||
|
||||
struct long_long_rvalue_from_python : long_long_rvalue_from_python_base
|
||||
{
|
||||
static BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
|
||||
{
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
if (PyInt_Check(intermediate))
|
||||
{
|
||||
return PyInt_AS_LONG(intermediate);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
BOOST_PYTHON_LONG_LONG result = PyLong_AsLongLong(intermediate);
|
||||
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct unsigned_long_long_rvalue_from_python : long_long_rvalue_from_python_base
|
||||
{
|
||||
static unsigned BOOST_PYTHON_LONG_LONG extract(PyObject* intermediate)
|
||||
{
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
if (PyInt_Check(intermediate))
|
||||
{
|
||||
return numeric_cast<unsigned BOOST_PYTHON_LONG_LONG>(PyInt_AS_LONG(intermediate));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
unsigned BOOST_PYTHON_LONG_LONG result = PyLong_AsUnsignedLongLong(intermediate);
|
||||
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// A SlotPolicy for extracting bool from a Python object
|
||||
struct bool_rvalue_from_python
|
||||
{
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
return obj == Py_None || PyLong_Check(obj) ? &py_object_identity : 0;
|
||||
#elif PY_VERSION_HEX >= 0x02040000 && defined(BOOST_PYTHON_BOOL_INT_STRICT)
|
||||
return obj == Py_None || PyBool_Check(obj) ? &py_object_identity : 0;
|
||||
#else
|
||||
return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool extract(PyObject* intermediate)
|
||||
{
|
||||
return PyObject_IsTrue(intermediate);
|
||||
}
|
||||
|
||||
static PyTypeObject const* get_pytype()
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x02030000
|
||||
return &PyBool_Type;
|
||||
#else
|
||||
return &PyInt_Type;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
// A SlotPolicy for extracting floating types from Python objects.
|
||||
struct float_rvalue_from_python
|
||||
{
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
|
||||
if (number_methods == 0)
|
||||
return 0;
|
||||
|
||||
// For integer types, return the tp_int conversion slot to avoid
|
||||
// creating a new object. We'll handle that below
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
if (PyInt_Check(obj))
|
||||
return &number_methods->nb_int;
|
||||
#endif
|
||||
|
||||
return (PyLong_Check(obj) || PyFloat_Check(obj))
|
||||
? &number_methods->nb_float : 0;
|
||||
}
|
||||
|
||||
static double extract(PyObject* intermediate)
|
||||
{
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
if (PyInt_Check(intermediate))
|
||||
{
|
||||
return PyInt_AS_LONG(intermediate);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
return PyFloat_AS_DOUBLE(intermediate);
|
||||
}
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
|
||||
};
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
unaryfunc py_unicode_as_string_unaryfunc = PyUnicode_AsUTF8String;
|
||||
#endif
|
||||
|
||||
// A SlotPolicy for extracting C++ strings from Python objects.
|
||||
struct string_rvalue_from_python
|
||||
{
|
||||
// If the underlying object is "string-able" this will succeed
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
return (PyUnicode_Check(obj)) ? &py_unicode_as_string_unaryfunc :
|
||||
PyBytes_Check(obj) ? &py_object_identity : 0;
|
||||
#else
|
||||
return (PyString_Check(obj)) ? &obj->ob_type->tp_str : 0;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
// Remember that this will be used to construct the result object
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
static std::string extract(PyObject* intermediate)
|
||||
{
|
||||
return std::string(PyBytes_AsString(intermediate),PyBytes_Size(intermediate));
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
|
||||
#else
|
||||
static std::string extract(PyObject* intermediate)
|
||||
{
|
||||
return std::string(PyString_AsString(intermediate),PyString_Size(intermediate));
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyString_Type;}
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
|
||||
// encode_string_unaryfunc/py_encode_string -- manufacture a unaryfunc
|
||||
// "slot" which encodes a Python string using the default encoding
|
||||
extern "C" PyObject* encode_string_unaryfunc(PyObject* x)
|
||||
{
|
||||
return PyUnicode_FromEncodedObject( x, 0, 0 );
|
||||
}
|
||||
unaryfunc py_encode_string = encode_string_unaryfunc;
|
||||
|
||||
// A SlotPolicy for extracting C++ strings from Python objects.
|
||||
struct wstring_rvalue_from_python
|
||||
{
|
||||
// If the underlying object is "string-able" this will succeed
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
return PyUnicode_Check(obj)
|
||||
? &py_object_identity
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
: PyBytes_Check(obj)
|
||||
#else
|
||||
: PyString_Check(obj)
|
||||
#endif
|
||||
? &py_encode_string
|
||||
: 0;
|
||||
};
|
||||
|
||||
// Remember that this will be used to construct the result object
|
||||
static std::wstring extract(PyObject* intermediate)
|
||||
{
|
||||
// On Windows, with Python >= 3.3, PyObject_Length cannot be used to get
|
||||
// the size of the wchar_t string, because it will count the number of
|
||||
// *code points*, but some characters not on the BMP will use two UTF-16
|
||||
// *code units* (surrogate pairs).
|
||||
// This is not a problem on Unix, since wchar_t is 32-bit.
|
||||
#if defined(_WIN32) && PY_VERSION_HEX >= 0x03030000
|
||||
BOOST_STATIC_ASSERT(sizeof(wchar_t) == 2);
|
||||
|
||||
Py_ssize_t size = 0;
|
||||
wchar_t *buf = PyUnicode_AsWideCharString(intermediate, &size);
|
||||
if (buf == NULL) {
|
||||
boost::python::throw_error_already_set();
|
||||
}
|
||||
std::wstring result(buf, size);
|
||||
PyMem_Free(buf);
|
||||
#else
|
||||
std::wstring result(::PyObject_Length(intermediate), L' ');
|
||||
if (!result.empty())
|
||||
{
|
||||
int err = PyUnicode_AsWideChar(
|
||||
#if PY_VERSION_HEX < 0x03020000
|
||||
(PyUnicodeObject *)
|
||||
#endif
|
||||
intermediate
|
||||
, &result[0]
|
||||
, result.size());
|
||||
|
||||
if (err == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyUnicode_Type;}
|
||||
};
|
||||
#endif
|
||||
|
||||
struct complex_rvalue_from_python
|
||||
{
|
||||
static unaryfunc* get_slot(PyObject* obj)
|
||||
{
|
||||
if (PyComplex_Check(obj))
|
||||
return &py_object_identity;
|
||||
else
|
||||
return float_rvalue_from_python::get_slot(obj);
|
||||
}
|
||||
|
||||
static std::complex<double> extract(PyObject* intermediate)
|
||||
{
|
||||
if (PyComplex_Check(intermediate))
|
||||
{
|
||||
return std::complex<double>(
|
||||
PyComplex_RealAsDouble(intermediate)
|
||||
, PyComplex_ImagAsDouble(intermediate));
|
||||
}
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
else if (PyInt_Check(intermediate))
|
||||
{
|
||||
return PyInt_AS_LONG(intermediate);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
return PyFloat_AS_DOUBLE(intermediate);
|
||||
}
|
||||
}
|
||||
static PyTypeObject const* get_pytype() { return &PyComplex_Type;}
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* do_return_to_python(char x)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
return PyUnicode_FromStringAndSize(&x, 1);
|
||||
#else
|
||||
return PyString_FromStringAndSize(&x, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* do_return_to_python(char const* x)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
return x ? PyUnicode_FromString(x) : boost::python::detail::none();
|
||||
#else
|
||||
return x ? PyString_FromString(x) : boost::python::detail::none();
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject* x)
|
||||
{
|
||||
return x ? x : boost::python::detail::none();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject* x)
|
||||
{
|
||||
if (x == 0)
|
||||
return boost::python::detail::none();
|
||||
|
||||
Py_INCREF(x);
|
||||
return x;
|
||||
}
|
||||
|
||||
#define REGISTER_INT_CONVERTERS(signedness, U) \
|
||||
slot_rvalue_from_python< \
|
||||
signedness U \
|
||||
,signedness##_int_rvalue_from_python<signedness U> \
|
||||
>()
|
||||
|
||||
#define REGISTER_INT_CONVERTERS2(U) \
|
||||
REGISTER_INT_CONVERTERS(signed, U); \
|
||||
REGISTER_INT_CONVERTERS(unsigned, U)
|
||||
|
||||
void initialize_builtin_converters()
|
||||
{
|
||||
// booleans
|
||||
slot_rvalue_from_python<bool,bool_rvalue_from_python>();
|
||||
|
||||
// integer types
|
||||
REGISTER_INT_CONVERTERS2(char);
|
||||
REGISTER_INT_CONVERTERS2(short);
|
||||
REGISTER_INT_CONVERTERS2(int);
|
||||
REGISTER_INT_CONVERTERS2(long);
|
||||
|
||||
// using Python's macro instead of Boost's - we don't seem to get the
|
||||
// config right all the time.
|
||||
# ifdef HAVE_LONG_LONG
|
||||
slot_rvalue_from_python<signed BOOST_PYTHON_LONG_LONG,long_long_rvalue_from_python>();
|
||||
slot_rvalue_from_python<unsigned BOOST_PYTHON_LONG_LONG,unsigned_long_long_rvalue_from_python>();
|
||||
# endif
|
||||
|
||||
// floating types
|
||||
slot_rvalue_from_python<float,float_rvalue_from_python>();
|
||||
slot_rvalue_from_python<double,float_rvalue_from_python>();
|
||||
slot_rvalue_from_python<long double,float_rvalue_from_python>();
|
||||
|
||||
slot_rvalue_from_python<std::complex<float>,complex_rvalue_from_python>();
|
||||
slot_rvalue_from_python<std::complex<double>,complex_rvalue_from_python>();
|
||||
slot_rvalue_from_python<std::complex<long double>,complex_rvalue_from_python>();
|
||||
|
||||
// Add an lvalue converter for char which gets us char const*
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyString_Type>::get_pytype);
|
||||
#else
|
||||
registry::insert(convert_to_cstring,type_id<char>(),&converter::wrap_pytype<&PyUnicode_Type>::get_pytype);
|
||||
#endif
|
||||
|
||||
// Register by-value converters to std::string, std::wstring
|
||||
#if defined(Py_USING_UNICODE) && !defined(BOOST_NO_STD_WSTRING)
|
||||
slot_rvalue_from_python<std::wstring, wstring_rvalue_from_python>();
|
||||
# endif
|
||||
slot_rvalue_from_python<std::string, string_rvalue_from_python>();
|
||||
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::converter
|
@ -1,303 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/converter/from_python.hpp>
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/python/converter/rvalue_from_python_data.hpp>
|
||||
|
||||
#include <boost/python/object/find_instance.hpp>
|
||||
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <boost/python/detail/raw_pyobject.hpp>
|
||||
#include <boost/python/cast.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
|
||||
// rvalue_from_python_stage1 -- do the first stage of a conversion
|
||||
// from a Python object to a C++ rvalue.
|
||||
//
|
||||
// source - the Python object to be converted
|
||||
// converters - the registry entry for the target type T
|
||||
//
|
||||
// Postcondition: where x is the result, one of:
|
||||
//
|
||||
// 1. x.convertible == 0, indicating failure
|
||||
//
|
||||
// 2. x.construct == 0, x.convertible is the address of an object of
|
||||
// type T. Indicates a successful lvalue conversion
|
||||
//
|
||||
// 3. where y is of type rvalue_from_python_data<T>,
|
||||
// x.construct(source, y) constructs an object of type T
|
||||
// in y.storage.bytes and then sets y.convertible == y.storage.bytes,
|
||||
// or else throws an exception and has no effect.
|
||||
BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
|
||||
PyObject* source
|
||||
, registration const& converters)
|
||||
{
|
||||
rvalue_from_python_stage1_data data;
|
||||
|
||||
// First check to see if it's embedded in an extension class
|
||||
// instance, as a special case.
|
||||
data.convertible = objects::find_instance_impl(source, converters.target_type, converters.is_shared_ptr);
|
||||
data.construct = 0;
|
||||
if (!data.convertible)
|
||||
{
|
||||
for (rvalue_from_python_chain const* chain = converters.rvalue_chain;
|
||||
chain != 0;
|
||||
chain = chain->next)
|
||||
{
|
||||
void* r = chain->convertible(source);
|
||||
if (r != 0)
|
||||
{
|
||||
data.convertible = r;
|
||||
data.construct = chain->construct;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
// rvalue_result_from_python -- return the address of a C++ object which
|
||||
// can be used as the result of calling a Python function.
|
||||
//
|
||||
// src - the Python object to be converted
|
||||
//
|
||||
// data - a reference to the base part of a
|
||||
// rvalue_from_python_data<T> object, where T is the
|
||||
// target type of the conversion.
|
||||
//
|
||||
// Requires: data.convertible == ®istered<T>::converters
|
||||
//
|
||||
BOOST_PYTHON_DECL void* rvalue_result_from_python(
|
||||
PyObject* src, rvalue_from_python_stage1_data& data)
|
||||
{
|
||||
// Retrieve the registration
|
||||
// Cast in two steps for less-capable compilers
|
||||
void const* converters_ = data.convertible;
|
||||
registration const& converters = *static_cast<registration const*>(converters_);
|
||||
|
||||
// Look for an eligible converter
|
||||
data = rvalue_from_python_stage1(src, converters);
|
||||
return rvalue_from_python_stage2(src, data, converters);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* rvalue_from_python_stage2(
|
||||
PyObject* source, rvalue_from_python_stage1_data& data, registration const& converters)
|
||||
{
|
||||
if (!data.convertible)
|
||||
{
|
||||
handle<> msg(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromFormat
|
||||
#else
|
||||
::PyString_FromFormat
|
||||
#endif
|
||||
(
|
||||
"No registered converter was able to produce a C++ rvalue of type %s from this Python object of type %s"
|
||||
, converters.target_type.name()
|
||||
, source->ob_type->tp_name
|
||||
));
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, msg.get());
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
// If a construct function was registered (i.e. we found an
|
||||
// rvalue conversion), call it now.
|
||||
if (data.construct != 0)
|
||||
data.construct(source, &data);
|
||||
|
||||
// Return the address of the resulting C++ object
|
||||
return data.convertible;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* get_lvalue_from_python(
|
||||
PyObject* source
|
||||
, registration const& converters)
|
||||
{
|
||||
// Check to see if it's embedded in a class instance
|
||||
void* x = objects::find_instance_impl(source, converters.target_type);
|
||||
if (x)
|
||||
return x;
|
||||
|
||||
lvalue_from_python_chain const* chain = converters.lvalue_chain;
|
||||
for (;chain != 0; chain = chain->next)
|
||||
{
|
||||
void* r = chain->convert(source);
|
||||
if (r != 0)
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// Prevent looping in implicit conversions. This could/should be
|
||||
// much more efficient, but will work for now.
|
||||
typedef std::vector<rvalue_from_python_chain const*> visited_t;
|
||||
static visited_t visited;
|
||||
|
||||
inline bool visit(rvalue_from_python_chain const* chain)
|
||||
{
|
||||
visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain);
|
||||
if (p != visited.end() && *p == chain)
|
||||
return false;
|
||||
visited.insert(p, chain);
|
||||
return true;
|
||||
}
|
||||
|
||||
// RAII class for managing global visited marks.
|
||||
struct unvisit
|
||||
{
|
||||
unvisit(rvalue_from_python_chain const* chain)
|
||||
: chain(chain) {}
|
||||
|
||||
~unvisit()
|
||||
{
|
||||
visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain);
|
||||
assert(p != visited.end());
|
||||
visited.erase(p);
|
||||
}
|
||||
private:
|
||||
rvalue_from_python_chain const* chain;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python(
|
||||
PyObject* source
|
||||
, registration const& converters)
|
||||
{
|
||||
if (objects::find_instance_impl(source, converters.target_type))
|
||||
return true;
|
||||
|
||||
rvalue_from_python_chain const* chain = converters.rvalue_chain;
|
||||
|
||||
if (!visit(chain))
|
||||
return false;
|
||||
|
||||
unvisit protect(chain);
|
||||
|
||||
for (;chain != 0; chain = chain->next)
|
||||
{
|
||||
if (chain->convertible(source))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type)
|
||||
{
|
||||
handle<> msg(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromFormat
|
||||
#else
|
||||
::PyString_FromFormat
|
||||
#endif
|
||||
(
|
||||
"No registered converter was able to extract a C++ %s to type %s"
|
||||
" from this Python object of type %s"
|
||||
, ref_type
|
||||
, converters.target_type.name()
|
||||
, source->ob_type->tp_name
|
||||
));
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, msg.get());
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
void* lvalue_result_from_python(
|
||||
PyObject* source
|
||||
, registration const& converters
|
||||
, char const* ref_type)
|
||||
{
|
||||
handle<> holder(source);
|
||||
if (source->ob_refcnt <= 1)
|
||||
{
|
||||
handle<> msg(
|
||||
#if PY_VERSION_HEX >= 0x3000000
|
||||
::PyUnicode_FromFormat
|
||||
#else
|
||||
::PyString_FromFormat
|
||||
#endif
|
||||
(
|
||||
"Attempt to return dangling %s to object of type: %s"
|
||||
, ref_type
|
||||
, converters.target_type.name()));
|
||||
|
||||
PyErr_SetObject(PyExc_ReferenceError, msg.get());
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
void* result = get_lvalue_from_python(source, converters);
|
||||
if (!result)
|
||||
(throw_no_lvalue_from_python)(source, converters, ref_type);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject* source, registration const& converters)
|
||||
{
|
||||
(throw_no_lvalue_from_python)(source, converters, "pointer");
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject* source, registration const& converters)
|
||||
{
|
||||
(throw_no_lvalue_from_python)(source, converters, "reference");
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* reference_result_from_python(
|
||||
PyObject* source
|
||||
, registration const& converters)
|
||||
{
|
||||
return (lvalue_result_from_python)(source, converters, "reference");
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* pointer_result_from_python(
|
||||
PyObject* source
|
||||
, registration const& converters)
|
||||
{
|
||||
if (source == Py_None)
|
||||
{
|
||||
Py_DECREF(source);
|
||||
return 0;
|
||||
}
|
||||
return (lvalue_result_from_python)(source, converters, "pointer");
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void void_result_from_python(PyObject* o)
|
||||
{
|
||||
Py_DECREF(expect_non_null(o));
|
||||
}
|
||||
|
||||
} // namespace boost::python::converter
|
||||
|
||||
BOOST_PYTHON_DECL PyObject*
|
||||
pytype_check(PyTypeObject* type_, PyObject* source)
|
||||
{
|
||||
if (!PyObject_IsInstance(source, python::upcast<PyObject>(type_)))
|
||||
{
|
||||
::PyErr_Format(
|
||||
PyExc_TypeError
|
||||
, "Expecting an object of type %s; got an object of type %s instead"
|
||||
, type_->tp_name
|
||||
, source->ob_type->tp_name
|
||||
);
|
||||
throw_error_already_set();
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
@ -1,306 +0,0 @@
|
||||
// Copyright David Abrahams 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/python/converter/builtin_converters.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__) && defined(__GNUC__) \
|
||||
&& __GNUC__ == 3 && __GNUC_MINOR__ <= 4 && !defined(__APPLE_CC__)
|
||||
# define BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_PYTHON_TRACE_REGISTRY) \
|
||||
|| defined(BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND)
|
||||
# include <iostream>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace python { namespace converter {
|
||||
BOOST_PYTHON_DECL PyTypeObject const* registration::expected_from_python_type() const
|
||||
{
|
||||
if (this->m_class_object != 0)
|
||||
return this->m_class_object;
|
||||
|
||||
std::set<PyTypeObject const*> pool;
|
||||
|
||||
for(rvalue_from_python_chain* r = rvalue_chain; r ; r=r->next)
|
||||
if(r->expected_pytype)
|
||||
pool.insert(r->expected_pytype());
|
||||
|
||||
//for now I skip the search for common base
|
||||
if (pool.size()==1)
|
||||
return *pool.begin();
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyTypeObject const* registration::to_python_target_type() const
|
||||
{
|
||||
if (this->m_class_object != 0)
|
||||
return this->m_class_object;
|
||||
|
||||
if (this->m_to_python_target_type != 0)
|
||||
return this->m_to_python_target_type();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const
|
||||
{
|
||||
if (this->m_class_object == 0)
|
||||
{
|
||||
::PyErr_Format(
|
||||
PyExc_TypeError
|
||||
, const_cast<char*>("No Python class registered for C++ class %s")
|
||||
, this->target_type.name());
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
return this->m_class_object;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source) const
|
||||
{
|
||||
if (this->m_to_python == 0)
|
||||
{
|
||||
handle<> msg(
|
||||
#if PY_VERSION_HEX >= 0x3000000
|
||||
::PyUnicode_FromFormat
|
||||
#else
|
||||
::PyString_FromFormat
|
||||
#endif
|
||||
(
|
||||
"No to_python (by-value) converter found for C++ type: %s"
|
||||
, this->target_type.name()
|
||||
)
|
||||
);
|
||||
|
||||
PyErr_SetObject(PyExc_TypeError, msg.get());
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
return source == 0
|
||||
? incref(Py_None)
|
||||
: this->m_to_python(const_cast<void*>(source));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template< typename T >
|
||||
void delete_node( T* node )
|
||||
{
|
||||
if( !!node && !!node->next )
|
||||
delete_node( node->next );
|
||||
delete node;
|
||||
}
|
||||
}
|
||||
|
||||
registration::~registration()
|
||||
{
|
||||
delete_node(lvalue_chain);
|
||||
delete_node(rvalue_chain);
|
||||
}
|
||||
|
||||
|
||||
namespace // <unnamed>
|
||||
{
|
||||
typedef registration entry;
|
||||
|
||||
typedef std::set<entry> registry_t;
|
||||
|
||||
#ifndef BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND
|
||||
registry_t& entries()
|
||||
{
|
||||
static registry_t registry;
|
||||
|
||||
# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
|
||||
static bool builtin_converters_initialized = false;
|
||||
if (!builtin_converters_initialized)
|
||||
{
|
||||
// Make this true early because registering the builtin
|
||||
// converters will cause recursion.
|
||||
builtin_converters_initialized = true;
|
||||
|
||||
initialize_builtin_converters();
|
||||
}
|
||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||
std::cout << "registry: ";
|
||||
for (registry_t::iterator p = registry.begin(); p != registry.end(); ++p)
|
||||
{
|
||||
std::cout << p->target_type << "; ";
|
||||
}
|
||||
std::cout << '\n';
|
||||
# endif
|
||||
# endif
|
||||
return registry;
|
||||
}
|
||||
#else
|
||||
registry_t& static_registry()
|
||||
{
|
||||
static registry_t result;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool static_builtin_converters_initialized()
|
||||
{
|
||||
static bool result = false;
|
||||
if (result == false) {
|
||||
result = true;
|
||||
std::cout << std::flush;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
registry_t& entries()
|
||||
{
|
||||
# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
|
||||
if (!static_builtin_converters_initialized())
|
||||
{
|
||||
initialize_builtin_converters();
|
||||
}
|
||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||
std::cout << "registry: ";
|
||||
for (registry_t::iterator p = static_registry().begin(); p != static_registry().end(); ++p)
|
||||
{
|
||||
std::cout << p->target_type << "; ";
|
||||
}
|
||||
std::cout << '\n';
|
||||
# endif
|
||||
# endif
|
||||
return static_registry();
|
||||
}
|
||||
#endif // BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND
|
||||
|
||||
entry* get(type_info type, bool is_shared_ptr = false)
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||
registry_t::iterator p = entries().find(entry(type));
|
||||
|
||||
std::cout << "looking up " << type << ": "
|
||||
<< (p == entries().end() || p->target_type != type
|
||||
? "...NOT found\n" : "...found\n");
|
||||
# endif
|
||||
std::pair<registry_t::const_iterator,bool> pos_ins
|
||||
= entries().insert(entry(type,is_shared_ptr));
|
||||
|
||||
# if __MWERKS__ >= 0x3000
|
||||
// do a little invariant checking if a change was made
|
||||
if ( pos_ins.second )
|
||||
assert(entries().invariants());
|
||||
# endif
|
||||
return const_cast<entry*>(&*pos_ins.first);
|
||||
}
|
||||
} // namespace <unnamed>
|
||||
|
||||
namespace registry
|
||||
{
|
||||
void insert(to_python_function_t f, type_info source_t, PyTypeObject const* (*to_python_target_type)())
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||
std::cout << "inserting to_python " << source_t << "\n";
|
||||
# endif
|
||||
entry* slot = get(source_t);
|
||||
|
||||
assert(slot->m_to_python == 0); // we have a problem otherwise
|
||||
if (slot->m_to_python != 0)
|
||||
{
|
||||
std::string msg = (
|
||||
std::string("to-Python converter for ")
|
||||
+ source_t.name()
|
||||
+ " already registered; second conversion method ignored."
|
||||
);
|
||||
|
||||
if ( ::PyErr_Warn( NULL, const_cast<char*>(msg.c_str()) ) )
|
||||
{
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
slot->m_to_python = f;
|
||||
slot->m_to_python_target_type = to_python_target_type;
|
||||
}
|
||||
|
||||
// Insert an lvalue from_python converter
|
||||
void insert(convertible_function convert, type_info key, PyTypeObject const* (*exp_pytype)())
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||
std::cout << "inserting lvalue from_python " << key << "\n";
|
||||
# endif
|
||||
entry* found = get(key);
|
||||
lvalue_from_python_chain *registration = new lvalue_from_python_chain;
|
||||
registration->convert = convert;
|
||||
registration->next = found->lvalue_chain;
|
||||
found->lvalue_chain = registration;
|
||||
|
||||
insert(convert, 0, key,exp_pytype);
|
||||
}
|
||||
|
||||
// Insert an rvalue from_python converter
|
||||
void insert(convertible_function convertible
|
||||
, constructor_function construct
|
||||
, type_info key
|
||||
, PyTypeObject const* (*exp_pytype)())
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||
std::cout << "inserting rvalue from_python " << key << "\n";
|
||||
# endif
|
||||
entry* found = get(key);
|
||||
rvalue_from_python_chain *registration = new rvalue_from_python_chain;
|
||||
registration->convertible = convertible;
|
||||
registration->construct = construct;
|
||||
registration->expected_pytype = exp_pytype;
|
||||
registration->next = found->rvalue_chain;
|
||||
found->rvalue_chain = registration;
|
||||
}
|
||||
|
||||
// Insert an rvalue from_python converter
|
||||
void push_back(convertible_function convertible
|
||||
, constructor_function construct
|
||||
, type_info key
|
||||
, PyTypeObject const* (*exp_pytype)())
|
||||
{
|
||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||
std::cout << "push_back rvalue from_python " << key << "\n";
|
||||
# endif
|
||||
rvalue_from_python_chain** found = &get(key)->rvalue_chain;
|
||||
while (*found != 0)
|
||||
found = &(*found)->next;
|
||||
|
||||
rvalue_from_python_chain *registration = new rvalue_from_python_chain;
|
||||
registration->convertible = convertible;
|
||||
registration->construct = construct;
|
||||
registration->expected_pytype = exp_pytype;
|
||||
registration->next = 0;
|
||||
*found = registration;
|
||||
}
|
||||
|
||||
registration const& lookup(type_info key)
|
||||
{
|
||||
return *get(key);
|
||||
}
|
||||
|
||||
registration const& lookup_shared_ptr(type_info key)
|
||||
{
|
||||
return *get(key, true);
|
||||
}
|
||||
|
||||
registration const* query(type_info type)
|
||||
{
|
||||
registry_t::iterator p = entries().find(entry(type));
|
||||
# ifdef BOOST_PYTHON_TRACE_REGISTRY
|
||||
std::cout << "querying " << type
|
||||
<< (p == entries().end() || p->target_type != type
|
||||
? "...NOT found\n" : "...found\n");
|
||||
# endif
|
||||
return (p == entries().end() || p->target_type != type) ? 0 : &*p;
|
||||
}
|
||||
} // namespace registry
|
||||
|
||||
}}} // namespace boost::python::converter
|
@ -1,212 +0,0 @@
|
||||
// Copyright David Abrahams 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/type_id.hpp>
|
||||
#include <boost/python/detail/decorated_type_id.hpp>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#if defined(__QNXNTO__)
|
||||
# include <ostream>
|
||||
#else /* defined(__QNXNTO__) */
|
||||
|
||||
#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT || __EDG_VERSION__
|
||||
# include <ostream>
|
||||
#else
|
||||
# include <ostream.h>
|
||||
#endif
|
||||
|
||||
# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
|
||||
# if defined(__GNUC__) && __GNUC__ >= 3
|
||||
|
||||
// http://lists.debian.org/debian-gcc/2003/09/msg00055.html notes
|
||||
// that, in cxxabi.h of gcc-3.x for x < 4, this type is used before it
|
||||
// is declared.
|
||||
# if __GNUC__ == 3 && __GNUC_MINOR__ < 4
|
||||
class __class_type_info;
|
||||
# endif
|
||||
|
||||
# include <cxxabi.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif /* defined(__QNXNTO__) */
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
# ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
|
||||
|
||||
# if defined(__QNXNTO__)
|
||||
namespace cxxabi {
|
||||
extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
|
||||
}
|
||||
# else /* defined(__QNXNTO__) */
|
||||
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ < 3
|
||||
|
||||
namespace cxxabi = :: ;
|
||||
extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
|
||||
# else
|
||||
|
||||
namespace cxxabi = ::abi; // GCC 3.1 and later
|
||||
|
||||
# if __GNUC__ == 3 && __GNUC_MINOR__ == 0
|
||||
namespace abi
|
||||
{
|
||||
extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
|
||||
}
|
||||
# endif /* __GNUC__ == 3 && __GNUC_MINOR__ == 0 */
|
||||
# endif /* __GNUC__ < 3 */
|
||||
# endif /* __GNUC__ */
|
||||
# endif /* defined(__QNXNTO__) */
|
||||
|
||||
namespace
|
||||
{
|
||||
struct compare_first_cstring
|
||||
{
|
||||
template <class T>
|
||||
bool operator()(T const& x, T const& y)
|
||||
{
|
||||
return std::strcmp(x.first,y.first) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct free_mem
|
||||
{
|
||||
free_mem(char*p)
|
||||
: p(p) {}
|
||||
|
||||
~free_mem()
|
||||
{
|
||||
std::free(p);
|
||||
}
|
||||
char* p;
|
||||
};
|
||||
}
|
||||
|
||||
bool cxxabi_cxa_demangle_is_broken()
|
||||
{
|
||||
static bool was_tested = false;
|
||||
static bool is_broken = false;
|
||||
if (!was_tested) {
|
||||
int status;
|
||||
free_mem keeper(cxxabi::__cxa_demangle("b", 0, 0, &status));
|
||||
was_tested = true;
|
||||
if (status == -2 || strcmp(keeper.p, "bool") != 0) {
|
||||
is_broken = true;
|
||||
}
|
||||
}
|
||||
return is_broken;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
BOOST_PYTHON_DECL char const* gcc_demangle(char const* mangled)
|
||||
{
|
||||
typedef std::vector<
|
||||
std::pair<char const*, char const*>
|
||||
> mangling_map;
|
||||
|
||||
static mangling_map demangler;
|
||||
mangling_map::iterator p
|
||||
= std::lower_bound(
|
||||
demangler.begin(), demangler.end()
|
||||
, std::make_pair(mangled, (char const*)0)
|
||||
, compare_first_cstring());
|
||||
|
||||
if (p == demangler.end() || strcmp(p->first, mangled))
|
||||
{
|
||||
int status;
|
||||
free_mem keeper(
|
||||
cxxabi::__cxa_demangle(mangled, 0, 0, &status)
|
||||
);
|
||||
|
||||
assert(status != -3); // invalid argument error
|
||||
|
||||
if (status == -1)
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
else
|
||||
{
|
||||
char const* demangled
|
||||
= status == -2
|
||||
// Invalid mangled name. Best we can do is to
|
||||
// return it intact.
|
||||
? mangled
|
||||
: keeper.p;
|
||||
|
||||
// Ult Mundane, 2005 Aug 17
|
||||
// Contributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// The __cxa_demangle function is supposed to translate
|
||||
// builtin types from their one-character mangled names,
|
||||
// but it doesn't in gcc 3.3.5 and gcc 3.4.x.
|
||||
if (cxxabi_cxa_demangle_is_broken()
|
||||
&& status == -2 && strlen(mangled) == 1)
|
||||
{
|
||||
// list from
|
||||
// http://www.codesourcery.com/cxx-abi/abi.html
|
||||
switch (mangled[0])
|
||||
{
|
||||
case 'v': demangled = "void"; break;
|
||||
case 'w': demangled = "wchar_t"; break;
|
||||
case 'b': demangled = "bool"; break;
|
||||
case 'c': demangled = "char"; break;
|
||||
case 'a': demangled = "signed char"; break;
|
||||
case 'h': demangled = "unsigned char"; break;
|
||||
case 's': demangled = "short"; break;
|
||||
case 't': demangled = "unsigned short"; break;
|
||||
case 'i': demangled = "int"; break;
|
||||
case 'j': demangled = "unsigned int"; break;
|
||||
case 'l': demangled = "long"; break;
|
||||
case 'm': demangled = "unsigned long"; break;
|
||||
case 'x': demangled = "long long"; break;
|
||||
case 'y': demangled = "unsigned long long"; break;
|
||||
case 'n': demangled = "__int128"; break;
|
||||
case 'o': demangled = "unsigned __int128"; break;
|
||||
case 'f': demangled = "float"; break;
|
||||
case 'd': demangled = "double"; break;
|
||||
case 'e': demangled = "long double"; break;
|
||||
case 'g': demangled = "__float128"; break;
|
||||
case 'z': demangled = "..."; break;
|
||||
}
|
||||
}
|
||||
|
||||
p = demangler.insert(p, std::make_pair(mangled, demangled));
|
||||
keeper.p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return p->second;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_info const& x)
|
||||
{
|
||||
return os << x.name();
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, detail::decorated_type_info const& x)
|
||||
{
|
||||
os << x.m_base_type;
|
||||
if (x.m_decoration & decorated_type_info::const_)
|
||||
os << " const";
|
||||
if (x.m_decoration & decorated_type_info::volatile_)
|
||||
os << " volatile";
|
||||
if (x.m_decoration & decorated_type_info::reference)
|
||||
os << "&";
|
||||
return os;
|
||||
}
|
||||
}
|
||||
}} // namespace boost::python::converter
|
@ -1,184 +0,0 @@
|
||||
// Copyright David Abrahams 2004. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/python/dict.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
namespace
|
||||
{
|
||||
// When returning list objects from methods, it may turn out that the
|
||||
// derived class is returning something else, perhaps something not
|
||||
// even derived from list. Since it is generally harmless for a
|
||||
// Boost.Python wrapper object to hold an object of a different
|
||||
// type, and because calling list() with an object may in fact
|
||||
// perform a conversion, the least-bad alternative is to assume that
|
||||
// we have a Python list object and stuff it into the list result.
|
||||
list assume_list(object const& o)
|
||||
{
|
||||
return list(detail::borrowed_reference(o.ptr()));
|
||||
}
|
||||
|
||||
// No PyDict_CheckExact; roll our own.
|
||||
inline bool check_exact(dict_base const* p)
|
||||
{
|
||||
return p->ptr()->ob_type == &PyDict_Type;
|
||||
}
|
||||
}
|
||||
|
||||
detail::new_reference dict_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyDict_Type, const_cast<char*>("(O)"),
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
dict_base::dict_base()
|
||||
: object(detail::new_reference(PyDict_New()))
|
||||
{}
|
||||
|
||||
dict_base::dict_base(object_cref data)
|
||||
: object(call(data))
|
||||
{}
|
||||
|
||||
void dict_base::clear()
|
||||
{
|
||||
if (check_exact(this))
|
||||
PyDict_Clear(this->ptr());
|
||||
else
|
||||
this->attr("clear")();
|
||||
}
|
||||
|
||||
dict dict_base::copy()
|
||||
{
|
||||
if (check_exact(this))
|
||||
{
|
||||
return dict(detail::new_reference(
|
||||
PyDict_Copy(this->ptr())));
|
||||
}
|
||||
else
|
||||
{
|
||||
return dict(detail::borrowed_reference(
|
||||
this->attr("copy")().ptr()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
object dict_base::get(object_cref k) const
|
||||
{
|
||||
if (check_exact(this))
|
||||
{
|
||||
PyObject* result = PyDict_GetItem(this->ptr(),k.ptr());
|
||||
return object(detail::borrowed_reference(result ? result : Py_None));
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->attr("get")(k);
|
||||
}
|
||||
}
|
||||
|
||||
object dict_base::get(object_cref k, object_cref d) const
|
||||
{
|
||||
return this->attr("get")(k,d);
|
||||
}
|
||||
|
||||
bool dict_base::has_key(object_cref k) const
|
||||
{
|
||||
return extract<bool>(this->contains(k));
|
||||
}
|
||||
|
||||
list dict_base::items() const
|
||||
{
|
||||
if (check_exact(this))
|
||||
{
|
||||
return list(detail::new_reference(
|
||||
PyDict_Items(this->ptr())));
|
||||
}
|
||||
else
|
||||
{
|
||||
return assume_list(this->attr("items")());
|
||||
}
|
||||
}
|
||||
|
||||
object dict_base::iteritems() const
|
||||
{
|
||||
return this->attr("iteritems")();
|
||||
}
|
||||
|
||||
object dict_base::iterkeys() const
|
||||
{
|
||||
return this->attr("iterkeys")();
|
||||
}
|
||||
|
||||
object dict_base::itervalues() const
|
||||
{
|
||||
return this->attr("itervalues")();
|
||||
}
|
||||
|
||||
list dict_base::keys() const
|
||||
{
|
||||
if (check_exact(this))
|
||||
{
|
||||
return list(detail::new_reference(
|
||||
PyDict_Keys(this->ptr())));
|
||||
}
|
||||
else
|
||||
{
|
||||
return assume_list(this->attr("keys")());
|
||||
}
|
||||
}
|
||||
|
||||
tuple dict_base::popitem()
|
||||
{
|
||||
return tuple(detail::borrowed_reference(
|
||||
this->attr("popitem")().ptr()
|
||||
));
|
||||
}
|
||||
|
||||
object dict_base::setdefault(object_cref k)
|
||||
{
|
||||
return this->attr("setdefault")(k);
|
||||
}
|
||||
|
||||
object dict_base::setdefault(object_cref k, object_cref d)
|
||||
{
|
||||
return this->attr("setdefault")(k,d);
|
||||
}
|
||||
|
||||
void dict_base::update(object_cref other)
|
||||
{
|
||||
if (check_exact(this))
|
||||
{
|
||||
if (PyDict_Update(this->ptr(),other.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->attr("update")(other);
|
||||
}
|
||||
}
|
||||
|
||||
list dict_base::values() const
|
||||
{
|
||||
if (check_exact(this))
|
||||
{
|
||||
return list(detail::new_reference(
|
||||
PyDict_Values(this->ptr())));
|
||||
}
|
||||
else
|
||||
{
|
||||
return assume_list(this->attr("values")());
|
||||
}
|
||||
}
|
||||
|
||||
static struct register_dict_pytype_ptr
|
||||
{
|
||||
register_dict_pytype_ptr()
|
||||
{
|
||||
const_cast<converter::registration &>(
|
||||
converter::registry::lookup(boost::python::type_id<boost::python::dict>())
|
||||
).m_class_object = &PyDict_Type;
|
||||
}
|
||||
}register_dict_pytype_ptr_;
|
||||
|
||||
}}} // namespace boost::python
|
@ -1,105 +0,0 @@
|
||||
// Copyright David Abrahams 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PYTHON_SOURCE
|
||||
# define BOOST_PYTHON_SOURCE
|
||||
#endif
|
||||
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/cast.hpp>
|
||||
#include <boost/python/detail/exception_handler.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
error_already_set::~error_already_set() {}
|
||||
|
||||
// IMPORTANT: this function may only be called from within a catch block!
|
||||
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void> f)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (detail::exception_handler::chain)
|
||||
return detail::exception_handler::chain->handle(f);
|
||||
f();
|
||||
return false;
|
||||
}
|
||||
catch(const boost::python::error_already_set&)
|
||||
{
|
||||
// The python error reporting has already been handled.
|
||||
}
|
||||
catch(const std::bad_alloc&)
|
||||
{
|
||||
PyErr_NoMemory();
|
||||
}
|
||||
catch(const bad_numeric_cast& x)
|
||||
{
|
||||
PyErr_SetString(PyExc_OverflowError, x.what());
|
||||
}
|
||||
catch(const std::out_of_range& x)
|
||||
{
|
||||
PyErr_SetString(PyExc_IndexError, x.what());
|
||||
}
|
||||
catch(const std::invalid_argument& x)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, x.what());
|
||||
}
|
||||
catch(const std::exception& x)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, x.what());
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BOOST_PYTHON_DECL throw_error_already_set()
|
||||
{
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
bool exception_handler::operator()(function0<void> const& f) const
|
||||
{
|
||||
if (m_next)
|
||||
{
|
||||
return m_next->handle(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
f();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
exception_handler::exception_handler(handler_function const& impl)
|
||||
: m_impl(impl)
|
||||
, m_next(0)
|
||||
{
|
||||
if (chain != 0)
|
||||
tail->m_next = this;
|
||||
else
|
||||
chain = this;
|
||||
tail = this;
|
||||
}
|
||||
|
||||
exception_handler* exception_handler::chain;
|
||||
exception_handler* exception_handler::tail;
|
||||
|
||||
BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f)
|
||||
{
|
||||
// the constructor links the new object into a handler chain, so
|
||||
// this object isn't actaully leaked (until, of course, the
|
||||
// interpreter exits).
|
||||
new exception_handler(f);
|
||||
}
|
||||
|
||||
} // namespace boost::python::detail
|
||||
|
||||
}} // namespace boost::python
|
||||
|
||||
|
@ -1,129 +0,0 @@
|
||||
// Copyright Stefan Seefeld 2005.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/exec.hpp>
|
||||
#include <boost/python/borrowed.hpp>
|
||||
#include <boost/python/dict.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
|
||||
object BOOST_PYTHON_DECL eval(str string, object global, object local)
|
||||
{
|
||||
return eval(python::extract<char const *>(string), global, local);
|
||||
}
|
||||
|
||||
object BOOST_PYTHON_DECL eval(char const *string, object global, object local)
|
||||
{
|
||||
// Set suitable default values for global and local dicts.
|
||||
if (global.is_none())
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (local.is_none()) local = global;
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *s = const_cast<char *>(string);
|
||||
PyObject* result = PyRun_String(s, Py_eval_input, global.ptr(), local.ptr());
|
||||
if (!result) throw_error_already_set();
|
||||
return object(detail::new_reference(result));
|
||||
}
|
||||
|
||||
object BOOST_PYTHON_DECL exec(str string, object global, object local)
|
||||
{
|
||||
return exec(python::extract<char const *>(string), global, local);
|
||||
}
|
||||
|
||||
object BOOST_PYTHON_DECL exec(char const *string, object global, object local)
|
||||
{
|
||||
// Set suitable default values for global and local dicts.
|
||||
if (global.is_none())
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (local.is_none()) local = global;
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *s = const_cast<char *>(string);
|
||||
PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), local.ptr());
|
||||
if (!result) throw_error_already_set();
|
||||
return object(detail::new_reference(result));
|
||||
}
|
||||
|
||||
object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
|
||||
{
|
||||
return exec_statement(python::extract<char const *>(string), global, local);
|
||||
}
|
||||
|
||||
object BOOST_PYTHON_DECL exec_statement(char const *string, object global, object local)
|
||||
{
|
||||
// Set suitable default values for global and local dicts.
|
||||
if (global.is_none())
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (local.is_none()) local = global;
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *s = const_cast<char *>(string);
|
||||
PyObject* result = PyRun_String(s, Py_single_input, global.ptr(), local.ptr());
|
||||
if (!result) throw_error_already_set();
|
||||
return object(detail::new_reference(result));
|
||||
}
|
||||
|
||||
// Execute python source code from file filename.
|
||||
// global and local are the global and local scopes respectively,
|
||||
// used during execution.
|
||||
object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
|
||||
{
|
||||
return exec_file(python::extract<char const *>(filename), global, local);
|
||||
}
|
||||
|
||||
object BOOST_PYTHON_DECL exec_file(char const *filename, object global, object local)
|
||||
{
|
||||
// Set suitable default values for global and local dicts.
|
||||
if (global.is_none())
|
||||
{
|
||||
if (PyObject *g = PyEval_GetGlobals())
|
||||
global = object(detail::borrowed_reference(g));
|
||||
else
|
||||
global = dict();
|
||||
}
|
||||
if (local.is_none()) local = global;
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *f = const_cast<char *>(filename);
|
||||
// Let python open the file to avoid potential binary incompatibilities.
|
||||
#if PY_VERSION_HEX >= 0x03040000
|
||||
FILE *fs = _Py_fopen(f, "r");
|
||||
#elif PY_VERSION_HEX >= 0x03000000
|
||||
PyObject *fo = Py_BuildValue("s", f);
|
||||
FILE *fs = _Py_fopen(fo, "r");
|
||||
Py_DECREF(fo);
|
||||
#else
|
||||
PyObject *pyfile = PyFile_FromString(f, const_cast<char*>("r"));
|
||||
if (!pyfile) throw std::invalid_argument(std::string(f) + " : no such file");
|
||||
python::handle<> file(pyfile);
|
||||
FILE *fs = PyFile_AsFile(file.get());
|
||||
#endif
|
||||
PyObject* result = PyRun_File(fs,
|
||||
f,
|
||||
Py_file_input,
|
||||
global.ptr(), local.ptr());
|
||||
if (!result) throw_error_already_set();
|
||||
return object(detail::new_reference(result));
|
||||
}
|
||||
|
||||
} // namespace boost::python
|
||||
} // namespace boost
|
@ -1,58 +0,0 @@
|
||||
# -*- python -*-
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from faber.feature import set
|
||||
from faber.artefacts.library import library
|
||||
from faber.tools.compiler import define
|
||||
|
||||
root = module('..')
|
||||
|
||||
bpl = library('boost_python' + root.py_suffix,
|
||||
['list.cpp',
|
||||
'long.cpp',
|
||||
'dict.cpp',
|
||||
'tuple.cpp',
|
||||
'str.cpp',
|
||||
'slice.cpp',
|
||||
'converter/from_python.cpp',
|
||||
'converter/registry.cpp',
|
||||
'converter/type_id.cpp',
|
||||
'object/enum.cpp',
|
||||
'object/class.cpp',
|
||||
'object/function.cpp',
|
||||
'object/inheritance.cpp',
|
||||
'object/life_support.cpp',
|
||||
'object/pickle_support.cpp',
|
||||
'errors.cpp',
|
||||
'module.cpp',
|
||||
'converter/builtin_converters.cpp',
|
||||
'converter/arg_to_python_base.cpp',
|
||||
'object/iterator.cpp',
|
||||
'object/stl_iterator.cpp',
|
||||
'object_protocol.cpp',
|
||||
'object_operators.cpp',
|
||||
'wrapper.cpp',
|
||||
'import.cpp',
|
||||
'exec.cpp',
|
||||
'object/function_doc_signature.cpp'],
|
||||
dependencies=root.config,
|
||||
features=features + define('BOOST_PYTHON_SOURCE'))
|
||||
|
||||
bnl = library('boost_numpy' + root.py_suffix,
|
||||
['numpy/dtype.cpp',
|
||||
'numpy/matrix.cpp',
|
||||
'numpy/ndarray.cpp',
|
||||
'numpy/numpy.cpp',
|
||||
'numpy/scalars.cpp',
|
||||
'numpy/ufunc.cpp',
|
||||
bpl],
|
||||
dependencies=root.config,
|
||||
features=features + define('BOOST_NUMPY_SOURCE'),
|
||||
condition=set.define.contains('HAS_NUMPY'))
|
||||
default = [bpl, bnl]
|
@ -1,25 +0,0 @@
|
||||
// Copyright Stefan Seefeld 2005.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/import.hpp>
|
||||
#include <boost/python/borrowed.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
|
||||
object BOOST_PYTHON_DECL import(str name)
|
||||
{
|
||||
// should be 'char const *' but older python versions don't use 'const' yet.
|
||||
char *n = python::extract<char *>(name);
|
||||
python::handle<> module(PyImport_ImportModule(n));
|
||||
return python::object(module);
|
||||
}
|
||||
|
||||
} // namespace boost::python
|
||||
} // namespace boost
|
@ -1,170 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/python/list.hpp>
|
||||
#include <boost/python/ssize_t.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
|
||||
detail::new_non_null_reference list_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_non_null_reference)
|
||||
(expect_non_null)(
|
||||
PyObject_CallFunction(
|
||||
(PyObject*)&PyList_Type, const_cast<char*>("(O)"),
|
||||
arg_.ptr()));
|
||||
}
|
||||
|
||||
list_base::list_base()
|
||||
: object(detail::new_reference(PyList_New(0)))
|
||||
{}
|
||||
|
||||
list_base::list_base(object_cref sequence)
|
||||
: object(list_base::call(sequence))
|
||||
{}
|
||||
|
||||
void list_base::append(object_cref x)
|
||||
{
|
||||
if (PyList_CheckExact(this->ptr()))
|
||||
{
|
||||
if (PyList_Append(this->ptr(), x.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->attr("append")(x);
|
||||
}
|
||||
}
|
||||
|
||||
//long list_base::count(object_cref value) const;
|
||||
|
||||
void list_base::extend(object_cref sequence)
|
||||
{
|
||||
this->attr("extend")(sequence);
|
||||
}
|
||||
|
||||
long list_base::index(object_cref value) const
|
||||
{
|
||||
object result_obj(this->attr("index")(value));
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
|
||||
#else
|
||||
long result = PyInt_AsLong(result_obj.ptr());
|
||||
#endif
|
||||
if (result == -1)
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
void list_base::insert(ssize_t index, object_cref item)
|
||||
{
|
||||
if (PyList_CheckExact(this->ptr()))
|
||||
{
|
||||
if (PyList_Insert(this->ptr(), index, item.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->attr("insert")(index, item);
|
||||
}
|
||||
}
|
||||
|
||||
void list_base::insert(object const& index, object_cref x)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
ssize_t index_ = PyLong_AsSsize_t(index.ptr());
|
||||
#else
|
||||
long index_ = PyInt_AsLong(index.ptr());
|
||||
#endif
|
||||
if (index_ == -1 && PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
this->insert(index_, x);
|
||||
}
|
||||
|
||||
object list_base::pop()
|
||||
{
|
||||
return this->attr("pop")();
|
||||
}
|
||||
|
||||
object list_base::pop(ssize_t index)
|
||||
{
|
||||
return this->pop(object(index));
|
||||
}
|
||||
|
||||
object list_base::pop(object const& index)
|
||||
{
|
||||
return this->attr("pop")(index);
|
||||
}
|
||||
|
||||
void list_base::remove(object_cref value)
|
||||
{
|
||||
this->attr("remove")(value);
|
||||
}
|
||||
|
||||
void list_base::reverse()
|
||||
{
|
||||
if (PyList_CheckExact(this->ptr()))
|
||||
{
|
||||
if (PyList_Reverse(this->ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->attr("reverse")();
|
||||
}
|
||||
}
|
||||
|
||||
void list_base::sort()
|
||||
{
|
||||
if (PyList_CheckExact(this->ptr()))
|
||||
{
|
||||
if (PyList_Sort(this->ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->attr("sort")();
|
||||
}
|
||||
}
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
void list_base::sort(args_proxy const &args,
|
||||
kwds_proxy const &kwds)
|
||||
{
|
||||
this->attr("sort")(args, kwds);
|
||||
}
|
||||
#else
|
||||
void list_base::sort(object_cref cmpfunc)
|
||||
{
|
||||
this->attr("sort")(cmpfunc);
|
||||
}
|
||||
#endif
|
||||
|
||||
// For some reason, moving this to the end of the TU suppresses an ICE
|
||||
// with vc6.
|
||||
ssize_t list_base::count(object_cref value) const
|
||||
{
|
||||
object result_obj(this->attr("count")(value));
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
ssize_t result = PyLong_AsSsize_t(result_obj.ptr());
|
||||
#else
|
||||
long result = PyInt_AsLong(result_obj.ptr());
|
||||
#endif
|
||||
if (result == -1)
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct register_list_pytype_ptr
|
||||
{
|
||||
register_list_pytype_ptr()
|
||||
{
|
||||
const_cast<converter::registration &>(
|
||||
converter::registry::lookup(boost::python::type_id<boost::python::list>())
|
||||
).m_class_object = &PyList_Type;
|
||||
}
|
||||
}register_list_pytype_ptr_;
|
||||
|
||||
}}} // namespace boost::python
|
@ -1,39 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/python/long.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
new_non_null_reference long_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_non_null_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyLong_Type, const_cast<char*>("(O)"),
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
new_non_null_reference long_base::call(object const& arg_, object const& base)
|
||||
{
|
||||
return (detail::new_non_null_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyLong_Type, const_cast<char*>("(OO)"),
|
||||
arg_.ptr(), base.ptr());
|
||||
}
|
||||
|
||||
long_base::long_base()
|
||||
: object(
|
||||
detail::new_reference(
|
||||
PyObject_CallFunction((PyObject*)&PyLong_Type, const_cast<char*>("()")))
|
||||
)
|
||||
{}
|
||||
|
||||
long_base::long_base(object_cref arg)
|
||||
: object(long_base::call(arg))
|
||||
{}
|
||||
|
||||
long_base::long_base(object_cref arg, object_cref base)
|
||||
: object(long_base::call(arg, base))
|
||||
{}
|
||||
|
||||
|
||||
}}} // namespace boost::python
|
@ -1,73 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2000.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
|
||||
// producing this work.
|
||||
|
||||
#include <boost/python/scope.hpp>
|
||||
#include <boost/python/object/add_to_namespace.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
namespace
|
||||
{
|
||||
PyObject* init_module_in_scope(PyObject* m, void(*init_function)())
|
||||
{
|
||||
if (m != 0)
|
||||
{
|
||||
// Create the current module scope
|
||||
object m_obj(((borrowed_reference_t*)m));
|
||||
scope current_module(m_obj);
|
||||
|
||||
handle_exception(init_function);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void scope_setattr_doc(char const* name, object const& x, char const* doc)
|
||||
{
|
||||
// Use function::add_to_namespace to achieve overloading if
|
||||
// appropriate.
|
||||
scope current;
|
||||
objects::add_to_namespace(current, name, x, doc);
|
||||
}
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* init_module(PyModuleDef& moduledef, void(*init_function)())
|
||||
{
|
||||
return init_module_in_scope(
|
||||
PyModule_Create(&moduledef),
|
||||
init_function);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
namespace
|
||||
{
|
||||
PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } };
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*init_function)())
|
||||
{
|
||||
return init_module_in_scope(
|
||||
Py_InitModule(const_cast<char*>(name), initial_methods),
|
||||
init_function);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}}} // namespace boost::python::detail
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
BOOST_PYTHON_DECL PyObject* current_scope = 0;
|
||||
}
|
||||
|
||||
}}
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "class.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "enum.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "function.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "function_doc_signature.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "inheritance.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "iterator.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "life_support.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "pickle_support.cpp"
|
@ -1,5 +0,0 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#pragma warning(disable: 4244 4503 4752 4800 4996)
|
||||
#define BOOST_PYTHON_SOURCE
|
||||
#include "stl_iterator.cpp"
|
@ -1,764 +0,0 @@
|
||||
// Copyright David Abrahams 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/detail/prefix.hpp>
|
||||
#include <boost/mpl/lambda.hpp> // #including this first is an intel6 workaround
|
||||
|
||||
#include <boost/python/object/class.hpp>
|
||||
#include <boost/python/object/instance.hpp>
|
||||
#include <boost/python/object/class_detail.hpp>
|
||||
#include <boost/python/scope.hpp>
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
#include <boost/python/object/find_instance.hpp>
|
||||
#include <boost/python/object/pickle_support.hpp>
|
||||
#include <boost/python/detail/map_entry.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/object_protocol.hpp>
|
||||
#include <boost/detail/binary_search.hpp>
|
||||
#include <boost/python/self.hpp>
|
||||
#include <boost/python/dict.hpp>
|
||||
#include <boost/python/str.hpp>
|
||||
#include <boost/python/ssize_t.hpp>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
#include <structmember.h>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
# ifdef BOOST_PYTHON_SELF_IS_CLASS
|
||||
namespace self_ns
|
||||
{
|
||||
self_t self;
|
||||
}
|
||||
# endif
|
||||
|
||||
instance_holder::instance_holder()
|
||||
: m_next(0)
|
||||
{
|
||||
}
|
||||
|
||||
instance_holder::~instance_holder()
|
||||
{
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// This is copied from typeobject.c in the Python sources. Even though
|
||||
// class_metatype_object doesn't set Py_TPFLAGS_HAVE_GC, that bit gets
|
||||
// filled in by the base class initialization process in
|
||||
// PyType_Ready(). However, tp_is_gc is *not* copied from the base
|
||||
// type, making it assume that classes are GC-able even if (like
|
||||
// class_type_object) they're statically allocated.
|
||||
static int
|
||||
type_is_gc(PyTypeObject *python_type)
|
||||
{
|
||||
return python_type->tp_flags & Py_TPFLAGS_HEAPTYPE;
|
||||
}
|
||||
|
||||
// This is also copied from the Python sources. We can't implement
|
||||
// static_data as a subclass property effectively without it.
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *prop_get;
|
||||
PyObject *prop_set;
|
||||
PyObject *prop_del;
|
||||
PyObject *prop_doc;
|
||||
int getter_doc;
|
||||
} propertyobject;
|
||||
|
||||
// Copied from Python source and removed the part for setting docstring,
|
||||
// since we don't have a setter for __doc__ and trying to set it will
|
||||
// cause the init fail.
|
||||
static int property_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
|
||||
static const char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
|
||||
propertyobject *prop = (propertyobject *)self;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
|
||||
const_cast<char **>(kwlist), &get, &set, &del, &doc))
|
||||
return -1;
|
||||
|
||||
if (get == Py_None)
|
||||
get = NULL;
|
||||
if (set == Py_None)
|
||||
set = NULL;
|
||||
if (del == Py_None)
|
||||
del = NULL;
|
||||
|
||||
Py_XINCREF(get);
|
||||
Py_XINCREF(set);
|
||||
Py_XINCREF(del);
|
||||
Py_XINCREF(doc);
|
||||
|
||||
prop->prop_get = get;
|
||||
prop->prop_set = set;
|
||||
prop->prop_del = del;
|
||||
prop->prop_doc = doc;
|
||||
prop->getter_doc = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
static_data_descr_get(PyObject *self, PyObject * /*obj*/, PyObject * /*type*/)
|
||||
{
|
||||
propertyobject *gs = (propertyobject *)self;
|
||||
|
||||
return PyObject_CallFunction(gs->prop_get, const_cast<char*>("()"));
|
||||
}
|
||||
|
||||
static int
|
||||
static_data_descr_set(PyObject *self, PyObject * /*obj*/, PyObject *value)
|
||||
{
|
||||
propertyobject *gs = (propertyobject *)self;
|
||||
PyObject *func, *res;
|
||||
|
||||
if (value == NULL)
|
||||
func = gs->prop_del;
|
||||
else
|
||||
func = gs->prop_set;
|
||||
if (func == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError,
|
||||
value == NULL ?
|
||||
"can't delete attribute" :
|
||||
"can't set attribute");
|
||||
return -1;
|
||||
}
|
||||
if (value == NULL)
|
||||
res = PyObject_CallFunction(func, const_cast<char*>("()"));
|
||||
else
|
||||
res = PyObject_CallFunction(func, const_cast<char*>("(O)"), value);
|
||||
if (res == NULL)
|
||||
return -1;
|
||||
Py_DECREF(res);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static PyTypeObject static_data_object = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
const_cast<char*>("Boost.Python.StaticProperty"),
|
||||
sizeof(propertyobject),
|
||||
0,
|
||||
0, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC
|
||||
| Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, //&PyProperty_Type, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
static_data_descr_get, /* tp_descr_get */
|
||||
static_data_descr_set, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
property_init, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
0, // filled in with type_new /* tp_new */
|
||||
0, // filled in with __PyObject_GC_Del /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
#if PYTHON_API_VERSION >= 1012
|
||||
0 /* tp_del */
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace objects
|
||||
{
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
// XXX Not sure why this run into compiling error in Python 3
|
||||
extern "C"
|
||||
{
|
||||
// This declaration needed due to broken Python 2.2 headers
|
||||
extern DL_IMPORT(PyTypeObject) PyProperty_Type;
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOST_PYTHON_DECL PyObject* static_data()
|
||||
{
|
||||
if (static_data_object.tp_dict == 0)
|
||||
{
|
||||
Py_TYPE(&static_data_object) = &PyType_Type;
|
||||
static_data_object.tp_base = &PyProperty_Type;
|
||||
if (PyType_Ready(&static_data_object))
|
||||
return 0;
|
||||
}
|
||||
return upcast<PyObject>(&static_data_object);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// Ordinarily, descriptors have a certain assymetry: you can use
|
||||
// them to read attributes off the class object they adorn, but
|
||||
// writing the same attribute on the class object always replaces
|
||||
// the descriptor in the class __dict__. In order to properly
|
||||
// represent C++ static data members, we need to allow them to be
|
||||
// written through the class instance. This function of the
|
||||
// metaclass makes it possible.
|
||||
static int
|
||||
class_setattro(PyObject *obj, PyObject *name, PyObject* value)
|
||||
{
|
||||
// Must use "private" Python implementation detail
|
||||
// _PyType_Lookup instead of PyObject_GetAttr because the
|
||||
// latter will always end up calling the descr_get function on
|
||||
// any descriptor it finds; we need the unadulterated
|
||||
// descriptor here.
|
||||
PyObject* a = _PyType_Lookup(downcast<PyTypeObject>(obj), name);
|
||||
|
||||
// a is a borrowed reference or 0
|
||||
|
||||
// If we found a static data descriptor, call it directly to
|
||||
// force it to set the static data member
|
||||
if (a != 0 && PyObject_IsInstance(a, objects::static_data()))
|
||||
return Py_TYPE(a)->tp_descr_set(a, obj, value);
|
||||
else
|
||||
return PyType_Type.tp_setattro(obj, name, value);
|
||||
}
|
||||
}
|
||||
|
||||
static PyTypeObject class_metatype_object = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
const_cast<char*>("Boost.Python.class"),
|
||||
PyType_Type.tp_basicsize,
|
||||
0,
|
||||
0, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
class_setattro, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC
|
||||
| Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, //&PyType_Type, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
0, // filled in with type_new /* tp_new */
|
||||
0, // filled in with __PyObject_GC_Del /* tp_free */
|
||||
(inquiry)type_is_gc, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
#if PYTHON_API_VERSION >= 1012
|
||||
0 /* tp_del */
|
||||
#endif
|
||||
};
|
||||
|
||||
// Install the instance data for a C++ object into a Python instance
|
||||
// object.
|
||||
void instance_holder::install(PyObject* self) throw()
|
||||
{
|
||||
assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self)), &class_metatype_object));
|
||||
m_next = ((objects::instance<>*)self)->objects;
|
||||
((objects::instance<>*)self)->objects = this;
|
||||
}
|
||||
|
||||
|
||||
namespace objects
|
||||
{
|
||||
// Get the metatype object for all extension classes.
|
||||
BOOST_PYTHON_DECL type_handle class_metatype()
|
||||
{
|
||||
if (class_metatype_object.tp_dict == 0)
|
||||
{
|
||||
Py_TYPE(&class_metatype_object) = &PyType_Type;
|
||||
class_metatype_object.tp_base = &PyType_Type;
|
||||
if (PyType_Ready(&class_metatype_object))
|
||||
return type_handle();
|
||||
}
|
||||
return type_handle(borrowed(&class_metatype_object));
|
||||
}
|
||||
extern "C"
|
||||
{
|
||||
static void instance_dealloc(PyObject* inst)
|
||||
{
|
||||
instance<>* kill_me = (instance<>*)inst;
|
||||
|
||||
for (instance_holder* p = kill_me->objects, *next; p != 0; p = next)
|
||||
{
|
||||
next = p->next();
|
||||
p->~instance_holder();
|
||||
instance_holder::deallocate(inst, dynamic_cast<void*>(p));
|
||||
}
|
||||
|
||||
// Python 2.2.1 won't add weak references automatically when
|
||||
// tp_itemsize > 0, so we need to manage that
|
||||
// ourselves. Accordingly, we also have to clean up the
|
||||
// weakrefs ourselves.
|
||||
if (kill_me->weakrefs != NULL)
|
||||
PyObject_ClearWeakRefs(inst);
|
||||
|
||||
Py_XDECREF(kill_me->dict);
|
||||
|
||||
Py_TYPE(inst)->tp_free(inst);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
instance_new(PyTypeObject* type_, PyObject* /*args*/, PyObject* /*kw*/)
|
||||
{
|
||||
// Attempt to find the __instance_size__ attribute. If not present, no problem.
|
||||
PyObject* d = type_->tp_dict;
|
||||
PyObject* instance_size_obj = PyObject_GetAttrString(d, const_cast<char*>("__instance_size__"));
|
||||
|
||||
ssize_t instance_size = instance_size_obj ?
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
PyLong_AsSsize_t(instance_size_obj) : 0;
|
||||
#else
|
||||
PyInt_AsLong(instance_size_obj) : 0;
|
||||
#endif
|
||||
|
||||
if (instance_size < 0)
|
||||
instance_size = 0;
|
||||
|
||||
PyErr_Clear(); // Clear any errors that may have occurred.
|
||||
|
||||
instance<>* result = (instance<>*)type_->tp_alloc(type_, instance_size);
|
||||
if (result)
|
||||
{
|
||||
// Guido says we can use ob_size for any purpose we
|
||||
// like, so we'll store the total size of the object
|
||||
// there. A negative number indicates that the extra
|
||||
// instance memory is not yet allocated to any holders.
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
Py_SIZE(result) =
|
||||
#else
|
||||
result->ob_size =
|
||||
#endif
|
||||
-(static_cast<int>(offsetof(instance<>,storage) + instance_size));
|
||||
}
|
||||
return (PyObject*)result;
|
||||
}
|
||||
|
||||
static PyObject* instance_get_dict(PyObject* op, void*)
|
||||
{
|
||||
instance<>* inst = downcast<instance<> >(op);
|
||||
if (inst->dict == 0)
|
||||
inst->dict = PyDict_New();
|
||||
return python::xincref(inst->dict);
|
||||
}
|
||||
|
||||
static int instance_set_dict(PyObject* op, PyObject* dict, void*)
|
||||
{
|
||||
instance<>* inst = downcast<instance<> >(op);
|
||||
python::xdecref(inst->dict);
|
||||
inst->dict = python::incref(dict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static PyGetSetDef instance_getsets[] = {
|
||||
{const_cast<char*>("__dict__"), instance_get_dict, instance_set_dict, NULL, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
static PyMemberDef instance_members[] = {
|
||||
{const_cast<char*>("__weakref__"), T_OBJECT, offsetof(instance<>, weakrefs), 0, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static PyTypeObject class_type_object = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
const_cast<char*>("Boost.Python.instance"),
|
||||
offsetof(instance<>,storage), /* tp_basicsize */
|
||||
1, /* tp_itemsize */
|
||||
instance_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC
|
||||
| Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
offsetof(instance<>,weakrefs), /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
instance_members, /* tp_members */
|
||||
instance_getsets, /* tp_getset */
|
||||
0, //&PyBaseObject_Type, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
offsetof(instance<>,dict), /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
PyType_GenericAlloc, /* tp_alloc */
|
||||
instance_new, /* tp_new */
|
||||
0, /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
#if PYTHON_API_VERSION >= 1012
|
||||
0 /* tp_del */
|
||||
#endif
|
||||
};
|
||||
|
||||
BOOST_PYTHON_DECL type_handle class_type()
|
||||
{
|
||||
if (class_type_object.tp_dict == 0)
|
||||
{
|
||||
Py_TYPE(&class_type_object) = incref(class_metatype().get());
|
||||
class_type_object.tp_base = &PyBaseObject_Type;
|
||||
if (PyType_Ready(&class_type_object))
|
||||
return type_handle();
|
||||
// class_type_object.tp_setattro = class_setattro;
|
||||
}
|
||||
return type_handle(borrowed(&class_type_object));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void*
|
||||
find_instance_impl(PyObject* inst, type_info type, bool null_shared_ptr_only)
|
||||
{
|
||||
if (!Py_TYPE(Py_TYPE(inst)) ||
|
||||
!PyType_IsSubtype(Py_TYPE(Py_TYPE(inst)), &class_metatype_object))
|
||||
return 0;
|
||||
|
||||
instance<>* self = reinterpret_cast<instance<>*>(inst);
|
||||
|
||||
for (instance_holder* match = self->objects; match != 0; match = match->next())
|
||||
{
|
||||
void* const found = match->holds(type, null_shared_ptr_only);
|
||||
if (found)
|
||||
return found;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
object module_prefix()
|
||||
{
|
||||
return object(
|
||||
PyObject_IsInstance(scope().ptr(), upcast<PyObject>(&PyModule_Type))
|
||||
? object(scope().attr("__name__"))
|
||||
: api::getattr(scope(), "__module__", str())
|
||||
);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// Find a registered class object corresponding to id. Return a
|
||||
// null handle if no such class is registered.
|
||||
inline type_handle query_class(type_info id)
|
||||
{
|
||||
converter::registration const* p = converter::registry::query(id);
|
||||
return type_handle(
|
||||
python::borrowed(
|
||||
python::allow_null(p ? p->m_class_object : 0))
|
||||
);
|
||||
}
|
||||
|
||||
// Find a registered class corresponding to id. If not found,
|
||||
// throw an appropriate exception.
|
||||
type_handle get_class(type_info id)
|
||||
{
|
||||
type_handle result(query_class(id));
|
||||
|
||||
if (result.get() == 0)
|
||||
{
|
||||
object report("extension class wrapper for base class ");
|
||||
report = report + id.name() + " has not been created yet";
|
||||
PyErr_SetObject(PyExc_RuntimeError, report.ptr());
|
||||
throw_error_already_set();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// class_base constructor
|
||||
//
|
||||
// name - the name of the new Python class
|
||||
//
|
||||
// num_types - one more than the number of declared bases
|
||||
//
|
||||
// types - array of python::type_info, the first item
|
||||
// corresponding to the class being created, and the
|
||||
// rest corresponding to its declared bases.
|
||||
//
|
||||
inline object
|
||||
new_class(char const* name, std::size_t num_types, type_info const* const types, char const* doc)
|
||||
{
|
||||
assert(num_types >= 1);
|
||||
|
||||
// Build a tuple of the base Python type objects. If no bases
|
||||
// were declared, we'll use our class_type() as the single base
|
||||
// class.
|
||||
ssize_t const num_bases = (std::max)(num_types - 1, static_cast<std::size_t>(1));
|
||||
handle<> bases(PyTuple_New(num_bases));
|
||||
|
||||
for (ssize_t i = 1; i <= num_bases; ++i)
|
||||
{
|
||||
type_handle c = (i >= static_cast<ssize_t>(num_types)) ? class_type() : get_class(types[i]);
|
||||
// PyTuple_SET_ITEM steals this reference
|
||||
PyTuple_SET_ITEM(bases.get(), static_cast<ssize_t>(i - 1), upcast<PyObject>(c.release()));
|
||||
}
|
||||
|
||||
// Call the class metatype to create a new class
|
||||
dict d;
|
||||
|
||||
object m = module_prefix();
|
||||
if (m) d["__module__"] = m;
|
||||
|
||||
if (doc != 0)
|
||||
d["__doc__"] = doc;
|
||||
|
||||
object result = object(class_metatype())(name, bases, d);
|
||||
assert(PyType_IsSubtype(Py_TYPE(result.ptr()), &PyType_Type));
|
||||
|
||||
if (scope().ptr() != Py_None)
|
||||
scope().attr(name) = result;
|
||||
|
||||
// For pickle. Will lead to informative error messages if pickling
|
||||
// is not enabled.
|
||||
result.attr("__reduce__") = object(make_instance_reduce_function());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class_base::class_base(
|
||||
char const* name, std::size_t num_types, type_info const* const types, char const* doc)
|
||||
: object(new_class(name, num_types, types, doc))
|
||||
{
|
||||
// Insert the new class object in the registry
|
||||
converter::registration& converters = const_cast<converter::registration&>(
|
||||
converter::registry::lookup(types[0]));
|
||||
|
||||
// Class object is leaked, for now
|
||||
converters.m_class_object = (PyTypeObject*)incref(this->ptr());
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void copy_class_object(type_info const& src, type_info const& dst)
|
||||
{
|
||||
converter::registration& dst_converters
|
||||
= const_cast<converter::registration&>(converter::registry::lookup(dst));
|
||||
|
||||
converter::registration const& src_converters = converter::registry::lookup(src);
|
||||
|
||||
dst_converters.m_class_object = src_converters.m_class_object;
|
||||
}
|
||||
|
||||
void class_base::set_instance_size(std::size_t instance_size)
|
||||
{
|
||||
this->attr("__instance_size__") = instance_size;
|
||||
}
|
||||
|
||||
void class_base::add_property(
|
||||
char const* name, object const& fget, char const* docstr)
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("Osss"), fget.ptr(), 0, 0, docstr));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
|
||||
void class_base::add_property(
|
||||
char const* name, object const& fget, object const& fset, char const* docstr)
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction((PyObject*)&PyProperty_Type, const_cast<char*>("OOss"), fget.ptr(), fset.ptr(), 0, docstr));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
|
||||
void class_base::add_static_property(char const* name, object const& fget)
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction(static_data(), const_cast<char*>("O"), fget.ptr())
|
||||
);
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
|
||||
void class_base::add_static_property(char const* name, object const& fget, object const& fset)
|
||||
{
|
||||
object property(
|
||||
(python::detail::new_reference)
|
||||
PyObject_CallFunction(static_data(), const_cast<char*>("OO"), fget.ptr(), fset.ptr()));
|
||||
|
||||
this->setattr(name, property);
|
||||
}
|
||||
|
||||
void class_base::setattr(char const* name, object const& x)
|
||||
{
|
||||
if (PyObject_SetAttrString(this->ptr(), const_cast<char*>(name), x.ptr()) < 0)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
extern "C" PyObject* no_init(PyObject*, PyObject*)
|
||||
{
|
||||
::PyErr_SetString(::PyExc_RuntimeError, const_cast<char*>("This class cannot be instantiated from Python"));
|
||||
return NULL;
|
||||
}
|
||||
static ::PyMethodDef no_init_def = {
|
||||
const_cast<char*>("__init__"), no_init, METH_VARARGS,
|
||||
const_cast<char*>("Raises an exception\n"
|
||||
"This class cannot be instantiated from Python\n")
|
||||
};
|
||||
}
|
||||
|
||||
void class_base::def_no_init()
|
||||
{
|
||||
handle<> f(::PyCFunction_New(&no_init_def, 0));
|
||||
this->setattr("__init__", object(f));
|
||||
}
|
||||
|
||||
void class_base::enable_pickling_(bool getstate_manages_dict)
|
||||
{
|
||||
setattr("__safe_for_unpickling__", object(true));
|
||||
|
||||
if (getstate_manages_dict)
|
||||
{
|
||||
setattr("__getstate_manages_dict__", object(true));
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
PyObject* callable_check(PyObject* callable)
|
||||
{
|
||||
if (PyCallable_Check(expect_non_null(callable)))
|
||||
return callable;
|
||||
|
||||
::PyErr_Format(
|
||||
PyExc_TypeError
|
||||
, const_cast<char*>("staticmethod expects callable object; got an object of type %s, which is not callable")
|
||||
, Py_TYPE(callable)->tp_name
|
||||
);
|
||||
|
||||
throw_error_already_set();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void class_base::make_method_static(const char * method_name)
|
||||
{
|
||||
PyTypeObject* self = downcast<PyTypeObject>(this->ptr());
|
||||
dict d((handle<>(borrowed(self->tp_dict))));
|
||||
|
||||
object method(d[method_name]);
|
||||
|
||||
this->attr(method_name) = object(
|
||||
handle<>(
|
||||
PyStaticMethod_New((callable_check)(method.ptr()) )
|
||||
));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL type_handle registered_class_object(type_info id)
|
||||
{
|
||||
return query_class(id);
|
||||
}
|
||||
} // namespace objects
|
||||
|
||||
|
||||
void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size)
|
||||
{
|
||||
assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
|
||||
objects::instance<>* self = (objects::instance<>*)self_;
|
||||
|
||||
int total_size_needed = holder_offset + holder_size;
|
||||
|
||||
if (-Py_SIZE(self) >= total_size_needed)
|
||||
{
|
||||
// holder_offset should at least point into the variable-sized part
|
||||
assert(holder_offset >= offsetof(objects::instance<>,storage));
|
||||
|
||||
// Record the fact that the storage is occupied, noting where it starts
|
||||
Py_SIZE(self) = holder_offset;
|
||||
return (char*)self + holder_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
void* const result = PyMem_Malloc(holder_size);
|
||||
if (result == 0)
|
||||
throw std::bad_alloc();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void instance_holder::deallocate(PyObject* self_, void* storage) throw()
|
||||
{
|
||||
assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
|
||||
objects::instance<>* self = (objects::instance<>*)self_;
|
||||
if (storage != (char*)self + Py_SIZE(self))
|
||||
{
|
||||
PyMem_Free(storage);
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
@ -1,252 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/object/enum_base.hpp>
|
||||
#include <boost/python/cast.hpp>
|
||||
#include <boost/python/scope.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/dict.hpp>
|
||||
#include <boost/python/str.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/object_protocol.hpp>
|
||||
#include <structmember.h>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
struct enum_object
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
PyLongObject base_object;
|
||||
#else
|
||||
PyIntObject base_object;
|
||||
#endif
|
||||
PyObject* name;
|
||||
};
|
||||
|
||||
static PyMemberDef enum_members[] = {
|
||||
{const_cast<char*>("name"), T_OBJECT_EX, offsetof(enum_object,name),READONLY, 0},
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static void
|
||||
enum_dealloc(enum_object* self)
|
||||
{
|
||||
Py_XDECREF(self->name);
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static PyObject* enum_repr(PyObject* self_)
|
||||
{
|
||||
PyObject *mod = PyObject_GetAttrString( self_, "__module__");
|
||||
object auto_free = object(handle<>(mod));
|
||||
enum_object* self = downcast<enum_object>(self_);
|
||||
if (!self->name)
|
||||
{
|
||||
return
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
PyUnicode_FromFormat("%S.%s(%ld)", mod, self_->ob_type->tp_name, PyLong_AsLong(self_));
|
||||
#else
|
||||
PyString_FromFormat("%s.%s(%ld)", PyString_AsString(mod), self_->ob_type->tp_name, PyInt_AS_LONG(self_));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
PyObject* name = self->name;
|
||||
if (name == 0)
|
||||
return 0;
|
||||
|
||||
return
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
PyUnicode_FromFormat("%S.%s.%S", mod, self_->ob_type->tp_name, name);
|
||||
#else
|
||||
PyString_FromFormat("%s.%s.%s",
|
||||
PyString_AsString(mod), self_->ob_type->tp_name, PyString_AsString(name));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject* enum_str(PyObject* self_)
|
||||
{
|
||||
enum_object* self = downcast<enum_object>(self_);
|
||||
if (!self->name)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
return PyLong_Type.tp_str(self_);
|
||||
#else
|
||||
return PyInt_Type.tp_str(self_);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return incref(self->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PyTypeObject enum_type_object = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0) // &PyType_Type
|
||||
const_cast<char*>("Boost.Python.enum"),
|
||||
sizeof(enum_object), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
(destructor) enum_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
enum_repr, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
enum_str, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
| Py_TPFLAGS_CHECKTYPES
|
||||
#endif
|
||||
| Py_TPFLAGS_HAVE_GC
|
||||
| Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
enum_members, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, //&PyInt_Type, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
0, /* tp_new */
|
||||
0, /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
#if PYTHON_API_VERSION >= 1012
|
||||
0 /* tp_del */
|
||||
#endif
|
||||
};
|
||||
|
||||
object module_prefix();
|
||||
|
||||
namespace
|
||||
{
|
||||
object new_enum_type(char const* name, char const *doc)
|
||||
{
|
||||
if (enum_type_object.tp_dict == 0)
|
||||
{
|
||||
Py_TYPE(&enum_type_object) = incref(&PyType_Type);
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
enum_type_object.tp_base = &PyLong_Type;
|
||||
#else
|
||||
enum_type_object.tp_base = &PyInt_Type;
|
||||
#endif
|
||||
if (PyType_Ready(&enum_type_object))
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
type_handle metatype(borrowed(&PyType_Type));
|
||||
type_handle base(borrowed(&enum_type_object));
|
||||
|
||||
// suppress the instance __dict__ in these enum objects. There
|
||||
// may be a slicker way, but this'll do for now.
|
||||
dict d;
|
||||
d["__slots__"] = tuple();
|
||||
d["values"] = dict();
|
||||
d["names"] = dict();
|
||||
|
||||
object module_name = module_prefix();
|
||||
if (module_name)
|
||||
d["__module__"] = module_name;
|
||||
if (doc)
|
||||
d["__doc__"] = doc;
|
||||
|
||||
object result = (object(metatype))(name, make_tuple(base), d);
|
||||
|
||||
scope().attr(name) = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
enum_base::enum_base(
|
||||
char const* name
|
||||
, converter::to_python_function_t to_python
|
||||
, converter::convertible_function convertible
|
||||
, converter::constructor_function construct
|
||||
, type_info id
|
||||
, char const *doc
|
||||
)
|
||||
: object(new_enum_type(name, doc))
|
||||
{
|
||||
converter::registration& converters
|
||||
= const_cast<converter::registration&>(
|
||||
converter::registry::lookup(id));
|
||||
|
||||
converters.m_class_object = downcast<PyTypeObject>(this->ptr());
|
||||
converter::registry::insert(to_python, id);
|
||||
converter::registry::insert(convertible, construct, id);
|
||||
}
|
||||
|
||||
void enum_base::add_value(char const* name_, long value)
|
||||
{
|
||||
// Convert name to Python string
|
||||
object name(name_);
|
||||
|
||||
// Create a new enum instance by calling the class with a value
|
||||
object x = (*this)(value);
|
||||
|
||||
// Store the object in the enum class
|
||||
(*this).attr(name_) = x;
|
||||
|
||||
dict d = extract<dict>(this->attr("values"))();
|
||||
d[value] = x;
|
||||
|
||||
// Set the name field in the new enum instanec
|
||||
enum_object* p = downcast<enum_object>(x.ptr());
|
||||
Py_XDECREF(p->name);
|
||||
p->name = incref(name.ptr());
|
||||
|
||||
dict names_dict = extract<dict>(this->attr("names"))();
|
||||
names_dict[x.attr("name")] = x;
|
||||
}
|
||||
|
||||
void enum_base::export_values()
|
||||
{
|
||||
dict d = extract<dict>(this->attr("names"))();
|
||||
list items = d.items();
|
||||
scope current;
|
||||
|
||||
for (unsigned i = 0, max = len(items); i < max; ++i)
|
||||
api::setattr(current, items[i][0], items[i][1]);
|
||||
}
|
||||
|
||||
PyObject* enum_base::to_python(PyTypeObject* type_, long x)
|
||||
{
|
||||
object type((type_handle(borrowed(type_))));
|
||||
|
||||
dict d = extract<dict>(type.attr("values"))();
|
||||
object v = d.get(x, object());
|
||||
return incref(
|
||||
(v == object() ? type(x) : v).ptr());
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::object
|
@ -1,793 +0,0 @@
|
||||
// Copyright David Abrahams 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/docstring_options.hpp>
|
||||
#include <boost/python/object/function_object.hpp>
|
||||
#include <boost/python/object/function_handle.hpp>
|
||||
#include <boost/python/object/function_doc_signature.hpp>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/str.hpp>
|
||||
#include <boost/python/object_attributes.hpp>
|
||||
#include <boost/python/args.hpp>
|
||||
#include <boost/python/refcount.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/list.hpp>
|
||||
#include <boost/python/ssize_t.hpp>
|
||||
|
||||
#include <boost/python/detail/signature.hpp>
|
||||
#include <boost/python/detail/none.hpp>
|
||||
#include <boost/mpl/vector/vector10.hpp>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#if BOOST_PYTHON_DEBUG_ERROR_MESSAGES
|
||||
# include <cstdio>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace python {
|
||||
volatile bool docstring_options::show_user_defined_ = true;
|
||||
volatile bool docstring_options::show_cpp_signatures_ = true;
|
||||
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
|
||||
volatile bool docstring_options::show_py_signatures_ = true;
|
||||
#else
|
||||
volatile bool docstring_options::show_py_signatures_ = false;
|
||||
#endif
|
||||
}}
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
py_function_impl_base::~py_function_impl_base()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned py_function_impl_base::max_arity() const
|
||||
{
|
||||
return this->min_arity();
|
||||
}
|
||||
|
||||
extern PyTypeObject function_type;
|
||||
|
||||
function::function(
|
||||
py_function const& implementation
|
||||
#if BOOST_WORKAROUND(__EDG_VERSION__, == 245)
|
||||
, python::detail::keyword const* names_and_defaults
|
||||
#else
|
||||
, python::detail::keyword const* const names_and_defaults
|
||||
#endif
|
||||
, unsigned num_keywords
|
||||
)
|
||||
: m_fn(implementation)
|
||||
, m_nkeyword_values(0)
|
||||
{
|
||||
if (names_and_defaults != 0)
|
||||
{
|
||||
unsigned int max_arity = m_fn.max_arity();
|
||||
unsigned int keyword_offset
|
||||
= max_arity > num_keywords ? max_arity - num_keywords : 0;
|
||||
|
||||
|
||||
ssize_t tuple_size = num_keywords ? max_arity : 0;
|
||||
m_arg_names = object(handle<>(PyTuple_New(tuple_size)));
|
||||
|
||||
if (num_keywords != 0)
|
||||
{
|
||||
for (unsigned j = 0; j < keyword_offset; ++j)
|
||||
PyTuple_SET_ITEM(m_arg_names.ptr(), j, incref(Py_None));
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < num_keywords; ++i)
|
||||
{
|
||||
tuple kv;
|
||||
|
||||
python::detail::keyword const* const p = names_and_defaults + i;
|
||||
if (p->default_value)
|
||||
{
|
||||
kv = make_tuple(p->name, p->default_value);
|
||||
++m_nkeyword_values;
|
||||
}
|
||||
else
|
||||
{
|
||||
kv = make_tuple(p->name);
|
||||
}
|
||||
|
||||
PyTuple_SET_ITEM(
|
||||
m_arg_names.ptr()
|
||||
, i + keyword_offset
|
||||
, incref(kv.ptr())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* p = this;
|
||||
if (Py_TYPE(&function_type) == 0)
|
||||
{
|
||||
Py_TYPE(&function_type) = &PyType_Type;
|
||||
::PyType_Ready(&function_type);
|
||||
}
|
||||
|
||||
(void)( // warning suppression for GCC
|
||||
PyObject_INIT(p, &function_type)
|
||||
);
|
||||
}
|
||||
|
||||
function::~function()
|
||||
{
|
||||
}
|
||||
|
||||
PyObject* function::call(PyObject* args, PyObject* keywords) const
|
||||
{
|
||||
std::size_t n_unnamed_actual = PyTuple_GET_SIZE(args);
|
||||
std::size_t n_keyword_actual = keywords ? PyDict_Size(keywords) : 0;
|
||||
std::size_t n_actual = n_unnamed_actual + n_keyword_actual;
|
||||
|
||||
function const* f = this;
|
||||
|
||||
// Try overloads looking for a match
|
||||
do
|
||||
{
|
||||
// Check for a plausible number of arguments
|
||||
unsigned min_arity = f->m_fn.min_arity();
|
||||
unsigned max_arity = f->m_fn.max_arity();
|
||||
|
||||
if (n_actual + f->m_nkeyword_values >= min_arity
|
||||
&& n_actual <= max_arity)
|
||||
{
|
||||
// This will be the args that actually get passed
|
||||
handle<>inner_args(allow_null(borrowed(args)));
|
||||
|
||||
if (n_keyword_actual > 0 // Keyword arguments were supplied
|
||||
|| n_actual < min_arity) // or default keyword values are needed
|
||||
{
|
||||
if (f->m_arg_names.is_none())
|
||||
{
|
||||
// this overload doesn't accept keywords
|
||||
inner_args = handle<>();
|
||||
}
|
||||
else
|
||||
{
|
||||
// "all keywords are none" is a special case
|
||||
// indicating we will accept any number of keyword
|
||||
// arguments
|
||||
if (PyTuple_Size(f->m_arg_names.ptr()) == 0)
|
||||
{
|
||||
// no argument preprocessing
|
||||
}
|
||||
else if (n_actual > max_arity)
|
||||
{
|
||||
// too many arguments
|
||||
inner_args = handle<>();
|
||||
}
|
||||
else
|
||||
{
|
||||
// build a new arg tuple, will adjust its size later
|
||||
assert(max_arity <= static_cast<std::size_t>(ssize_t_max));
|
||||
inner_args = handle<>(
|
||||
PyTuple_New(static_cast<ssize_t>(max_arity)));
|
||||
|
||||
// Fill in the positional arguments
|
||||
for (std::size_t i = 0; i < n_unnamed_actual; ++i)
|
||||
PyTuple_SET_ITEM(inner_args.get(), i, incref(PyTuple_GET_ITEM(args, i)));
|
||||
|
||||
// Grab remaining arguments by name from the keyword dictionary
|
||||
std::size_t n_actual_processed = n_unnamed_actual;
|
||||
|
||||
for (std::size_t arg_pos = n_unnamed_actual; arg_pos < max_arity ; ++arg_pos)
|
||||
{
|
||||
// Get the keyword[, value pair] corresponding
|
||||
PyObject* kv = PyTuple_GET_ITEM(f->m_arg_names.ptr(), arg_pos);
|
||||
|
||||
// If there were any keyword arguments,
|
||||
// look up the one we need for this
|
||||
// argument position
|
||||
PyObject* value = n_keyword_actual
|
||||
? PyDict_GetItem(keywords, PyTuple_GET_ITEM(kv, 0))
|
||||
: 0;
|
||||
|
||||
if (!value)
|
||||
{
|
||||
// Not found; check if there's a default value
|
||||
if (PyTuple_GET_SIZE(kv) > 1)
|
||||
value = PyTuple_GET_ITEM(kv, 1);
|
||||
|
||||
if (!value)
|
||||
{
|
||||
// still not found; matching fails
|
||||
PyErr_Clear();
|
||||
inner_args = handle<>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++n_actual_processed;
|
||||
}
|
||||
|
||||
PyTuple_SET_ITEM(inner_args.get(), arg_pos, incref(value));
|
||||
}
|
||||
|
||||
if (inner_args.get())
|
||||
{
|
||||
//check if we proccessed all the arguments
|
||||
if(n_actual_processed < n_actual)
|
||||
inner_args = handle<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the function. Pass keywords in case it's a
|
||||
// function accepting any number of keywords
|
||||
PyObject* result = inner_args ? f->m_fn(inner_args.get(), keywords) : 0;
|
||||
|
||||
// If the result is NULL but no error was set, m_fn failed
|
||||
// the argument-matching test.
|
||||
|
||||
// This assumes that all other error-reporters are
|
||||
// well-behaved and never return NULL to python without
|
||||
// setting an error.
|
||||
if (result != 0 || PyErr_Occurred())
|
||||
return result;
|
||||
}
|
||||
f = f->m_overloads.get();
|
||||
}
|
||||
while (f);
|
||||
// None of the overloads matched; time to generate the error message
|
||||
argument_error(args, keywords);
|
||||
return 0;
|
||||
}
|
||||
|
||||
object function::signature(bool show_return_type) const
|
||||
{
|
||||
py_function const& impl = m_fn;
|
||||
|
||||
python::detail::signature_element const* return_type = impl.signature();
|
||||
python::detail::signature_element const* s = return_type + 1;
|
||||
|
||||
list formal_params;
|
||||
if (impl.max_arity() == 0)
|
||||
formal_params.append("void");
|
||||
|
||||
for (unsigned n = 0; n < impl.max_arity(); ++n)
|
||||
{
|
||||
if (s[n].basename == 0)
|
||||
{
|
||||
formal_params.append("...");
|
||||
break;
|
||||
}
|
||||
|
||||
str param(s[n].basename);
|
||||
if (s[n].lvalue)
|
||||
param += " {lvalue}";
|
||||
|
||||
if (m_arg_names) // None or empty tuple will test false
|
||||
{
|
||||
object kv(m_arg_names[n]);
|
||||
if (kv)
|
||||
{
|
||||
char const* const fmt = len(kv) > 1 ? " %s=%r" : " %s";
|
||||
param += fmt % kv;
|
||||
}
|
||||
}
|
||||
|
||||
formal_params.append(param);
|
||||
}
|
||||
|
||||
if (show_return_type)
|
||||
return "%s(%s) -> %s" % make_tuple(
|
||||
m_name, str(", ").join(formal_params), return_type->basename);
|
||||
return "%s(%s)" % make_tuple(
|
||||
m_name, str(", ").join(formal_params));
|
||||
}
|
||||
|
||||
object function::signatures(bool show_return_type) const
|
||||
{
|
||||
list result;
|
||||
for (function const* f = this; f; f = f->m_overloads.get()) {
|
||||
result.append(f->signature(show_return_type));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void function::argument_error(PyObject* args, PyObject* /*keywords*/) const
|
||||
{
|
||||
static handle<> exception(
|
||||
PyErr_NewException(const_cast<char*>("Boost.Python.ArgumentError"), PyExc_TypeError, 0));
|
||||
|
||||
object message = "Python argument types in\n %s.%s("
|
||||
% make_tuple(this->m_namespace, this->m_name);
|
||||
|
||||
list actual_args;
|
||||
for (ssize_t i = 0; i < PyTuple_Size(args); ++i)
|
||||
{
|
||||
char const* name = PyTuple_GetItem(args, i)->ob_type->tp_name;
|
||||
actual_args.append(str(name));
|
||||
}
|
||||
message += str(", ").join(actual_args);
|
||||
message += ")\ndid not match C++ signature:\n ";
|
||||
message += str("\n ").join(signatures());
|
||||
|
||||
#if BOOST_PYTHON_DEBUG_ERROR_MESSAGES
|
||||
std::printf("\n--------\n%s\n--------\n", extract<const char*>(message)());
|
||||
#endif
|
||||
PyErr_SetObject(exception.get(), message.ptr());
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
void function::add_overload(handle<function> const& overload_)
|
||||
{
|
||||
function* parent = this;
|
||||
|
||||
while (parent->m_overloads)
|
||||
parent = parent->m_overloads.get();
|
||||
|
||||
parent->m_overloads = overload_;
|
||||
|
||||
// If we have no documentation, get the docs from the overload
|
||||
if (!m_doc)
|
||||
m_doc = overload_->m_doc;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
char const* const binary_operator_names[] =
|
||||
{
|
||||
"add__",
|
||||
"and__",
|
||||
"div__",
|
||||
"divmod__",
|
||||
"eq__",
|
||||
"floordiv__",
|
||||
"ge__",
|
||||
"gt__",
|
||||
"le__",
|
||||
"lshift__",
|
||||
"lt__",
|
||||
"mod__",
|
||||
"mul__",
|
||||
"ne__",
|
||||
"or__",
|
||||
"pow__",
|
||||
"radd__",
|
||||
"rand__",
|
||||
"rdiv__",
|
||||
"rdivmod__",
|
||||
"rfloordiv__",
|
||||
"rlshift__",
|
||||
"rmod__",
|
||||
"rmul__",
|
||||
"ror__",
|
||||
"rpow__",
|
||||
"rrshift__",
|
||||
"rshift__",
|
||||
"rsub__",
|
||||
"rtruediv__",
|
||||
"rxor__",
|
||||
"sub__",
|
||||
"truediv__",
|
||||
"xor__"
|
||||
};
|
||||
|
||||
struct less_cstring
|
||||
{
|
||||
bool operator()(char const* x, char const* y) const
|
||||
{
|
||||
return BOOST_CSTD_::strcmp(x,y) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool is_binary_operator(char const* name)
|
||||
{
|
||||
return name[0] == '_'
|
||||
&& name[1] == '_'
|
||||
&& std::binary_search(
|
||||
&binary_operator_names[0]
|
||||
, binary_operator_names + sizeof(binary_operator_names)/sizeof(*binary_operator_names)
|
||||
, name + 2
|
||||
, less_cstring()
|
||||
);
|
||||
}
|
||||
|
||||
// Something for the end of the chain of binary operators
|
||||
PyObject* not_implemented(PyObject*, PyObject*)
|
||||
{
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
|
||||
handle<function> not_implemented_function()
|
||||
{
|
||||
|
||||
static object keeper(
|
||||
function_object(
|
||||
py_function(¬_implemented, mpl::vector1<void>(), 2)
|
||||
, python::detail::keyword_range())
|
||||
);
|
||||
return handle<function>(borrowed(downcast<function>(keeper.ptr())));
|
||||
}
|
||||
}
|
||||
|
||||
void function::add_to_namespace(
|
||||
object const& name_space, char const* name_, object const& attribute)
|
||||
{
|
||||
add_to_namespace(name_space, name_, attribute, 0);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
extern char py_signature_tag[];
|
||||
extern char cpp_signature_tag[];
|
||||
}
|
||||
|
||||
void function::add_to_namespace(
|
||||
object const& name_space, char const* name_, object const& attribute, char const* doc)
|
||||
{
|
||||
str const name(name_);
|
||||
PyObject* const ns = name_space.ptr();
|
||||
|
||||
if (attribute.ptr()->ob_type == &function_type)
|
||||
{
|
||||
function* new_func = downcast<function>(attribute.ptr());
|
||||
handle<> dict;
|
||||
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
// Old-style class gone in Python 3
|
||||
if (PyClass_Check(ns))
|
||||
dict = handle<>(borrowed(((PyClassObject*)ns)->cl_dict));
|
||||
else
|
||||
#endif
|
||||
if (PyType_Check(ns))
|
||||
dict = handle<>(borrowed(((PyTypeObject*)ns)->tp_dict));
|
||||
else
|
||||
dict = handle<>(PyObject_GetAttrString(ns, const_cast<char*>("__dict__")));
|
||||
|
||||
if (dict == 0)
|
||||
throw_error_already_set();
|
||||
|
||||
handle<> existing(allow_null(::PyObject_GetItem(dict.get(), name.ptr())));
|
||||
|
||||
if (existing)
|
||||
{
|
||||
if (existing->ob_type == &function_type)
|
||||
{
|
||||
new_func->add_overload(
|
||||
handle<function>(
|
||||
borrowed(
|
||||
downcast<function>(existing.get())
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
else if (existing->ob_type == &PyStaticMethod_Type)
|
||||
{
|
||||
char const* name_space_name = extract<char const*>(name_space.attr("__name__"));
|
||||
|
||||
::PyErr_Format(
|
||||
PyExc_RuntimeError
|
||||
, "Boost.Python - All overloads must be exported "
|
||||
"before calling \'class_<...>(\"%s\").staticmethod(\"%s\")\'"
|
||||
, name_space_name
|
||||
, name_
|
||||
);
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
else if (is_binary_operator(name_))
|
||||
{
|
||||
// Binary operators need an additional overload which
|
||||
// returns NotImplemented, so that Python will try the
|
||||
// __rxxx__ functions on the other operand. We add this
|
||||
// when no overloads for the operator already exist.
|
||||
new_func->add_overload(not_implemented_function());
|
||||
}
|
||||
|
||||
// A function is named the first time it is added to a namespace.
|
||||
if (new_func->name().is_none())
|
||||
new_func->m_name = name;
|
||||
|
||||
handle<> name_space_name(
|
||||
allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast<char*>("__name__"))));
|
||||
|
||||
if (name_space_name)
|
||||
new_func->m_namespace = object(name_space_name);
|
||||
}
|
||||
|
||||
// The PyObject_GetAttrString() or PyObject_GetItem calls above may
|
||||
// have left an active error
|
||||
PyErr_Clear();
|
||||
if (PyObject_SetAttr(ns, name.ptr(), attribute.ptr()) < 0)
|
||||
throw_error_already_set();
|
||||
|
||||
object mutable_attribute(attribute);
|
||||
/*
|
||||
if (doc != 0 && docstring_options::show_user_defined_)
|
||||
{
|
||||
// Accumulate documentation
|
||||
|
||||
if (
|
||||
PyObject_HasAttrString(mutable_attribute.ptr(), "__doc__")
|
||||
&& mutable_attribute.attr("__doc__"))
|
||||
{
|
||||
mutable_attribute.attr("__doc__") += "\n\n";
|
||||
mutable_attribute.attr("__doc__") += doc;
|
||||
}
|
||||
else {
|
||||
mutable_attribute.attr("__doc__") = doc;
|
||||
}
|
||||
}
|
||||
|
||||
if (docstring_options::show_signatures_)
|
||||
{
|
||||
if ( PyObject_HasAttrString(mutable_attribute.ptr(), "__doc__")
|
||||
&& mutable_attribute.attr("__doc__")) {
|
||||
mutable_attribute.attr("__doc__") += (
|
||||
mutable_attribute.attr("__doc__")[-1] != "\n" ? "\n\n" : "\n");
|
||||
}
|
||||
else {
|
||||
mutable_attribute.attr("__doc__") = "";
|
||||
}
|
||||
function* f = downcast<function>(attribute.ptr());
|
||||
mutable_attribute.attr("__doc__") += str("\n ").join(make_tuple(
|
||||
"C++ signature:", f->signature(true)));
|
||||
}
|
||||
*/
|
||||
str _doc;
|
||||
|
||||
if (docstring_options::show_py_signatures_)
|
||||
{
|
||||
_doc += str(const_cast<const char*>(detail::py_signature_tag));
|
||||
}
|
||||
if (doc != 0 && docstring_options::show_user_defined_)
|
||||
_doc += doc;
|
||||
|
||||
if (docstring_options::show_cpp_signatures_)
|
||||
{
|
||||
_doc += str(const_cast<const char*>(detail::cpp_signature_tag));
|
||||
}
|
||||
if(_doc)
|
||||
{
|
||||
object mutable_attribute(attribute);
|
||||
mutable_attribute.attr("__doc__")= _doc;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void add_to_namespace(
|
||||
object const& name_space, char const* name, object const& attribute)
|
||||
{
|
||||
function::add_to_namespace(name_space, name, attribute, 0);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void add_to_namespace(
|
||||
object const& name_space, char const* name, object const& attribute, char const* doc)
|
||||
{
|
||||
function::add_to_namespace(name_space, name, attribute, doc);
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
struct bind_return
|
||||
{
|
||||
bind_return(PyObject*& result, function const* f, PyObject* args, PyObject* keywords)
|
||||
: m_result(result)
|
||||
, m_f(f)
|
||||
, m_args(args)
|
||||
, m_keywords(keywords)
|
||||
{}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
m_result = m_f->call(m_args, m_keywords);
|
||||
}
|
||||
|
||||
private:
|
||||
PyObject*& m_result;
|
||||
function const* m_f;
|
||||
PyObject* m_args;
|
||||
PyObject* m_keywords;
|
||||
};
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// Stolen from Python's funcobject.c
|
||||
static PyObject *
|
||||
function_descr_get(PyObject *func, PyObject *obj, PyObject *type_)
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
// The implement is different in Python 3 because of the removal of unbound method
|
||||
if (obj == Py_None || obj == NULL) {
|
||||
Py_INCREF(func);
|
||||
return func;
|
||||
}
|
||||
return PyMethod_New(func, obj);
|
||||
#else
|
||||
if (obj == Py_None)
|
||||
obj = NULL;
|
||||
return PyMethod_New(func, obj, type_);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
function_dealloc(PyObject* p)
|
||||
{
|
||||
delete static_cast<function*>(p);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
function_call(PyObject *func, PyObject *args, PyObject *kw)
|
||||
{
|
||||
PyObject* result = 0;
|
||||
handle_exception(bind_return(result, static_cast<function*>(func), args, kw));
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Here we're using the function's tp_getset rather than its
|
||||
// tp_members to set up __doc__ and __name__, because tp_members
|
||||
// really depends on having a POD object type (it relies on
|
||||
// offsets). It might make sense to reformulate function as a POD
|
||||
// at some point, but this is much more expedient.
|
||||
//
|
||||
static PyObject* function_get_doc(PyObject* op, void*)
|
||||
{
|
||||
function* f = downcast<function>(op);
|
||||
list signatures = function_doc_signature_generator::function_doc_signatures(f);
|
||||
if(!signatures) return python::detail::none();
|
||||
signatures.reverse();
|
||||
return python::incref( str("\n").join(signatures).ptr());
|
||||
}
|
||||
|
||||
static int function_set_doc(PyObject* op, PyObject* doc, void*)
|
||||
{
|
||||
function* f = downcast<function>(op);
|
||||
f->doc(doc ? object(python::detail::borrowed_reference(doc)) : object());
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject* function_get_name(PyObject* op, void*)
|
||||
{
|
||||
function* f = downcast<function>(op);
|
||||
if (f->name().is_none())
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
return PyUnicode_InternFromString("<unnamed Boost.Python function>");
|
||||
#else
|
||||
return PyString_InternFromString("<unnamed Boost.Python function>");
|
||||
#endif
|
||||
else
|
||||
return python::incref(f->name().ptr());
|
||||
}
|
||||
|
||||
// We add a dummy __class__ attribute in order to fool PyDoc into
|
||||
// treating these as built-in functions and scanning their
|
||||
// documentation
|
||||
static PyObject* function_get_class(PyObject* /*op*/, void*)
|
||||
{
|
||||
return python::incref(upcast<PyObject>(&PyCFunction_Type));
|
||||
}
|
||||
|
||||
static PyObject* function_get_module(PyObject* op, void*)
|
||||
{
|
||||
function* f = downcast<function>(op);
|
||||
object const& ns = f->get_namespace();
|
||||
if (!ns.is_none()) {
|
||||
return python::incref(ns.ptr());
|
||||
}
|
||||
PyErr_SetString(
|
||||
PyExc_AttributeError, const_cast<char*>(
|
||||
"Boost.Python function __module__ unknown."));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static PyGetSetDef function_getsetlist[] = {
|
||||
{const_cast<char*>("__name__"), (getter)function_get_name, 0, 0, 0 },
|
||||
{const_cast<char*>("func_name"), (getter)function_get_name, 0, 0, 0 },
|
||||
{const_cast<char*>("__module__"), (getter)function_get_module, 0, 0, 0 },
|
||||
{const_cast<char*>("func_module"), (getter)function_get_module, 0, 0, 0 },
|
||||
{const_cast<char*>("__class__"), (getter)function_get_class, 0, 0, 0 }, // see note above
|
||||
{const_cast<char*>("__doc__"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{const_cast<char*>("func_doc"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
|
||||
{NULL, 0, 0, 0, 0} /* Sentinel */
|
||||
};
|
||||
|
||||
PyTypeObject function_type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
const_cast<char*>("Boost.Python.function"),
|
||||
sizeof(function),
|
||||
0,
|
||||
(destructor)function_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
0, //(reprfunc)func_repr, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
function_call, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, // PyObject_GenericGetAttr, /* tp_getattro */
|
||||
0, // PyObject_GenericSetAttr, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT /* | Py_TPFLAGS_HAVE_GC */,/* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, // (traverseproc)func_traverse, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, //offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, // func_memberlist, /* tp_members */
|
||||
function_getsetlist, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
function_descr_get, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, //offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
0, /* tp_new */
|
||||
0, /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
#if PYTHON_API_VERSION >= 1012
|
||||
0 /* tp_del */
|
||||
#endif
|
||||
};
|
||||
|
||||
object function_object(
|
||||
py_function const& f
|
||||
, python::detail::keyword_range const& keywords)
|
||||
{
|
||||
return python::object(
|
||||
python::detail::new_non_null_reference(
|
||||
new function(
|
||||
f, keywords.first, keywords.second - keywords.first)));
|
||||
}
|
||||
|
||||
object function_object(py_function const& f)
|
||||
{
|
||||
return function_object(f, python::detail::keyword_range());
|
||||
}
|
||||
|
||||
|
||||
handle<> function_handle_impl(py_function const& f)
|
||||
{
|
||||
return python::handle<>(
|
||||
allow_null(
|
||||
new function(f, 0, 0)));
|
||||
}
|
||||
|
||||
} // namespace objects
|
||||
|
||||
namespace detail
|
||||
{
|
||||
object BOOST_PYTHON_DECL make_raw_function(objects::py_function f)
|
||||
{
|
||||
static keyword k;
|
||||
|
||||
return objects::function_object(
|
||||
f
|
||||
, keyword_range(&k,&k));
|
||||
}
|
||||
void BOOST_PYTHON_DECL pure_virtual_called()
|
||||
{
|
||||
PyErr_SetString(
|
||||
PyExc_RuntimeError, const_cast<char*>("Pure virtual function called"));
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
@ -1,344 +0,0 @@
|
||||
// Copyright Nikolay Mladenov 2007.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// boost::python::make_tuple below are for gcc 4.4 -std=c++0x compatibility
|
||||
// (Intel C++ 10 and 11 with -std=c++0x don't need the full qualification).
|
||||
|
||||
#include <boost/python/converter/registrations.hpp>
|
||||
#include <boost/python/object/function_doc_signature.hpp>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/str.hpp>
|
||||
#include <boost/python/args.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
|
||||
#include <boost/python/detail/signature.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
bool function_doc_signature_generator::arity_cmp( function const *f1, function const *f2 )
|
||||
{
|
||||
return f1->m_fn.max_arity() < f2->m_fn.max_arity();
|
||||
}
|
||||
|
||||
bool function_doc_signature_generator::are_seq_overloads( function const *f1, function const *f2 , bool check_docs)
|
||||
{
|
||||
py_function const & impl1 = f1->m_fn;
|
||||
py_function const & impl2 = f2->m_fn;
|
||||
|
||||
//the number of parameters differs by 1
|
||||
if (impl2.max_arity()-impl1.max_arity() != 1)
|
||||
return false;
|
||||
|
||||
// if check docs then f1 shold not have docstring or have the same docstring as f2
|
||||
if (check_docs && f2->doc() != f1->doc() && f1->doc())
|
||||
return false;
|
||||
|
||||
python::detail::signature_element const* s1 = impl1.signature();
|
||||
python::detail::signature_element const* s2 = impl2.signature();
|
||||
|
||||
unsigned size = impl1.max_arity()+1;
|
||||
|
||||
for (unsigned i = 0; i != size; ++i)
|
||||
{
|
||||
//check if the argument types are the same
|
||||
if (s1[i].basename != s2[i].basename)
|
||||
return false;
|
||||
|
||||
//return type
|
||||
if (!i) continue;
|
||||
|
||||
//check if the argument default values are the same
|
||||
bool f1_has_names = bool(f1->m_arg_names);
|
||||
bool f2_has_names = bool(f2->m_arg_names);
|
||||
if ( (f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=f1->m_arg_names[i-1])
|
||||
|| (f1_has_names && !f2_has_names)
|
||||
|| (!f1_has_names && f2_has_names && f2->m_arg_names[i-1]!=python::object())
|
||||
)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<function const*> function_doc_signature_generator::flatten(function const *f)
|
||||
{
|
||||
object name = f->name();
|
||||
|
||||
std::vector<function const*> res;
|
||||
|
||||
while (f) {
|
||||
|
||||
//this if takes out the not_implemented_function
|
||||
if (f->name() == name)
|
||||
res.push_back(f);
|
||||
|
||||
f=f->m_overloads.get();
|
||||
}
|
||||
|
||||
//std::sort(res.begin(),res.end(), &arity_cmp);
|
||||
|
||||
return res;
|
||||
}
|
||||
std::vector<function const*> function_doc_signature_generator::split_seq_overloads( const std::vector<function const *> &funcs, bool split_on_doc_change)
|
||||
{
|
||||
std::vector<function const*> res;
|
||||
|
||||
std::vector<function const*>::const_iterator fi = funcs.begin();
|
||||
|
||||
function const * last = *fi;
|
||||
|
||||
while (++fi != funcs.end()){
|
||||
|
||||
//check if fi starts a new chain of overloads
|
||||
if (!are_seq_overloads( last, *fi, split_on_doc_change ))
|
||||
res.push_back(last);
|
||||
|
||||
last = *fi;
|
||||
}
|
||||
|
||||
if (last)
|
||||
res.push_back(last);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
str function_doc_signature_generator::raw_function_pretty_signature(function const *f, size_t n_overloads, bool cpp_types )
|
||||
{
|
||||
str res("object");
|
||||
|
||||
res = str("%s %s(%s)" % make_tuple( res, f->m_name, str("tuple args, dict kwds")) );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const char * function_doc_signature_generator::py_type_str(const python::detail::signature_element &s)
|
||||
{
|
||||
if (s.basename==std::string("void")){
|
||||
static const char * none = "None";
|
||||
return none;
|
||||
}
|
||||
|
||||
PyTypeObject const * py_type = s.pytype_f?s.pytype_f():0;
|
||||
if ( py_type )
|
||||
return py_type->tp_name;
|
||||
else{
|
||||
static const char * object = "object";
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
str function_doc_signature_generator::parameter_string(py_function const &f, size_t n, object arg_names, bool cpp_types)
|
||||
{
|
||||
str param;
|
||||
|
||||
python::detail::signature_element const * s = f.signature();
|
||||
if (cpp_types)
|
||||
{
|
||||
if(!n)
|
||||
s = &f.get_return_type();
|
||||
if (s[n].basename == 0)
|
||||
{
|
||||
return str("...");
|
||||
}
|
||||
|
||||
param = str(s[n].basename);
|
||||
|
||||
if (s[n].lvalue)
|
||||
param += " {lvalue}";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (n) //we are processing an argument and trying to come up with a name for it
|
||||
{
|
||||
object kv;
|
||||
if ( arg_names && (kv = arg_names[n-1]) )
|
||||
param = str( " (%s)%s" % make_tuple(py_type_str(s[n]),kv[0]) );
|
||||
else
|
||||
param = str(" (%s)%s%d" % make_tuple(py_type_str(s[n]),"arg", n) );
|
||||
}
|
||||
else //we are processing the return type
|
||||
param = py_type_str(f.get_return_type());
|
||||
}
|
||||
|
||||
//an argument - check for default value and append it
|
||||
if(n && arg_names)
|
||||
{
|
||||
object kv(arg_names[n-1]);
|
||||
if (kv && len(kv) == 2)
|
||||
{
|
||||
param = str("%s=%r" % make_tuple(param, kv[1]));
|
||||
}
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
||||
str function_doc_signature_generator::pretty_signature(function const *f, size_t n_overloads, bool cpp_types )
|
||||
{
|
||||
py_function
|
||||
const& impl = f->m_fn;
|
||||
;
|
||||
|
||||
|
||||
unsigned arity = impl.max_arity();
|
||||
|
||||
if(arity == unsigned(-1))// is this the proper raw function test?
|
||||
{
|
||||
return raw_function_pretty_signature(f,n_overloads,cpp_types);
|
||||
}
|
||||
|
||||
list formal_params;
|
||||
|
||||
size_t n_extra_default_args=0;
|
||||
|
||||
for (unsigned n = 0; n <= arity; ++n)
|
||||
{
|
||||
str param;
|
||||
|
||||
formal_params.append(
|
||||
parameter_string(impl, n, f->m_arg_names, cpp_types)
|
||||
);
|
||||
|
||||
// find all the arguments with default values preceeding the arity-n_overloads
|
||||
if (n && f->m_arg_names)
|
||||
{
|
||||
object kv(f->m_arg_names[n-1]);
|
||||
|
||||
if (kv && len(kv) == 2)
|
||||
{
|
||||
//default argument preceeding the arity-n_overloads
|
||||
if( n <= arity-n_overloads)
|
||||
++n_extra_default_args;
|
||||
}
|
||||
else
|
||||
//argument without default, preceeding the arity-n_overloads
|
||||
if( n <= arity-n_overloads)
|
||||
n_extra_default_args = 0;
|
||||
}
|
||||
}
|
||||
|
||||
n_overloads+=n_extra_default_args;
|
||||
|
||||
if (!arity && cpp_types)
|
||||
formal_params.append("void");
|
||||
|
||||
str ret_type (formal_params.pop(0));
|
||||
if (cpp_types )
|
||||
{
|
||||
return str(
|
||||
"%s %s(%s%s%s%s)"
|
||||
% boost::python::make_tuple // workaround, see top
|
||||
( ret_type
|
||||
, f->m_name
|
||||
, str(",").join(formal_params.slice(0,arity-n_overloads))
|
||||
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
|
||||
, str(" [,").join(formal_params.slice(arity-n_overloads,arity))
|
||||
, std::string(n_overloads,']')
|
||||
));
|
||||
}else{
|
||||
return str(
|
||||
"%s(%s%s%s%s) -> %s"
|
||||
% boost::python::make_tuple // workaround, see top
|
||||
( f->m_name
|
||||
, str(",").join(formal_params.slice(0,arity-n_overloads))
|
||||
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
|
||||
, str(" [,").join(formal_params.slice(arity-n_overloads,arity))
|
||||
, std::string(n_overloads,']')
|
||||
, ret_type
|
||||
));
|
||||
}
|
||||
|
||||
return str(
|
||||
"%s %s(%s%s%s%s) %s"
|
||||
% boost::python::make_tuple // workaround, see top
|
||||
( cpp_types?ret_type:str("")
|
||||
, f->m_name
|
||||
, str(",").join(formal_params.slice(0,arity-n_overloads))
|
||||
, n_overloads ? (n_overloads!=arity?str(" [,"):str("[ ")) : str()
|
||||
, str(" [,").join(formal_params.slice(arity-n_overloads,arity))
|
||||
, std::string(n_overloads,']')
|
||||
, cpp_types?str(""):ret_type
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
char py_signature_tag[] = "PY signature :";
|
||||
char cpp_signature_tag[] = "C++ signature :";
|
||||
}
|
||||
|
||||
list function_doc_signature_generator::function_doc_signatures( function const * f)
|
||||
{
|
||||
list signatures;
|
||||
std::vector<function const*> funcs = flatten( f);
|
||||
std::vector<function const*> split_funcs = split_seq_overloads( funcs, true);
|
||||
std::vector<function const*>::const_iterator sfi=split_funcs.begin(), fi;
|
||||
size_t n_overloads=0;
|
||||
for (fi=funcs.begin(); fi!=funcs.end(); ++fi)
|
||||
{
|
||||
if(*sfi == *fi){
|
||||
if((*fi)->doc())
|
||||
{
|
||||
str func_doc = str((*fi)->doc());
|
||||
|
||||
int doc_len = len(func_doc);
|
||||
|
||||
bool show_py_signature = doc_len >= int(sizeof(detail::py_signature_tag)/sizeof(char)-1)
|
||||
&& str(detail::py_signature_tag) == func_doc.slice(0, int(sizeof(detail::py_signature_tag)/sizeof(char))-1);
|
||||
if(show_py_signature)
|
||||
{
|
||||
func_doc = str(func_doc.slice(int(sizeof(detail::py_signature_tag)/sizeof(char))-1, _));
|
||||
doc_len = len(func_doc);
|
||||
}
|
||||
|
||||
bool show_cpp_signature = doc_len >= int(sizeof(detail::cpp_signature_tag)/sizeof(char)-1)
|
||||
&& str(detail::cpp_signature_tag) == func_doc.slice( 1-int(sizeof(detail::cpp_signature_tag)/sizeof(char)), _);
|
||||
|
||||
if(show_cpp_signature)
|
||||
{
|
||||
func_doc = str(func_doc.slice(_, 1-int(sizeof(detail::cpp_signature_tag)/sizeof(char))));
|
||||
doc_len = len(func_doc);
|
||||
}
|
||||
|
||||
str res="\n";
|
||||
str pad = "\n";
|
||||
|
||||
if(show_py_signature)
|
||||
{
|
||||
str sig = pretty_signature(*fi, n_overloads,false);
|
||||
res+=sig;
|
||||
if(doc_len || show_cpp_signature )res+=" :";
|
||||
pad+= str(" ");
|
||||
}
|
||||
|
||||
if(doc_len)
|
||||
{
|
||||
if(show_py_signature)
|
||||
res+=pad;
|
||||
res+= pad.join(func_doc.split("\n"));
|
||||
}
|
||||
|
||||
if( show_cpp_signature)
|
||||
{
|
||||
if(len(res)>1)
|
||||
res+="\n"+pad;
|
||||
res+=detail::cpp_signature_tag+pad+" "+pretty_signature(*fi, n_overloads,true);
|
||||
}
|
||||
|
||||
signatures.append(res);
|
||||
}
|
||||
++sfi;
|
||||
n_overloads = 0;
|
||||
}else
|
||||
++n_overloads ;
|
||||
}
|
||||
|
||||
return signatures;
|
||||
}
|
||||
|
||||
|
||||
}}}
|
||||
|
@ -1,495 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/python/object/inheritance.hpp>
|
||||
#include <boost/python/type_id.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#if _MSC_FULL_VER >= 13102171 && _MSC_FULL_VER <= 13102179
|
||||
# include <boost/graph/reverse_graph.hpp>
|
||||
#endif
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/reverse_graph.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/integer_traits.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/tuple/tuple_comparison.hpp>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
//
|
||||
// Procedure:
|
||||
//
|
||||
// The search is a BFS over the space of (type,address) pairs
|
||||
// guided by the edges of the casting graph whose nodes
|
||||
// correspond to classes, and whose edges are traversed by
|
||||
// applying associated cast functions to an address. We use
|
||||
// vertex distance to the goal node in the cast_graph to rate the
|
||||
// paths. The vertex distance to any goal node is calculated on
|
||||
// demand and outdated by the addition of edges to the graph.
|
||||
|
||||
namespace boost {
|
||||
namespace
|
||||
{
|
||||
enum edge_cast_t { edge_cast = 8010 };
|
||||
template <class T> inline void unused_variable(const T&) { }
|
||||
}
|
||||
|
||||
// Install properties
|
||||
BOOST_INSTALL_PROPERTY(edge, cast);
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef void*(*cast_function)(void*);
|
||||
|
||||
//
|
||||
// Here we put together the low-level data structures of the
|
||||
// casting graph representation.
|
||||
//
|
||||
typedef python::type_info class_id;
|
||||
|
||||
// represents a graph of available casts
|
||||
|
||||
#if 0
|
||||
struct cast_graph
|
||||
:
|
||||
#else
|
||||
typedef
|
||||
#endif
|
||||
adjacency_list<vecS,vecS, bidirectionalS, no_property
|
||||
|
||||
// edge index property allows us to look up edges in the connectivity matrix
|
||||
, property<edge_index_t,std::size_t
|
||||
|
||||
// The function which casts a void* from the edge's source type
|
||||
// to its destination type.
|
||||
, property<edge_cast_t,cast_function> > >
|
||||
#if 0
|
||||
{};
|
||||
#else
|
||||
cast_graph;
|
||||
#endif
|
||||
|
||||
typedef cast_graph::vertex_descriptor vertex_t;
|
||||
typedef cast_graph::edge_descriptor edge_t;
|
||||
|
||||
struct smart_graph
|
||||
{
|
||||
typedef std::vector<std::size_t>::const_iterator node_distance_map;
|
||||
|
||||
typedef std::pair<cast_graph::out_edge_iterator
|
||||
, cast_graph::out_edge_iterator> out_edges_t;
|
||||
|
||||
// Return a map of the distances from any node to the given
|
||||
// target node
|
||||
node_distance_map distances_to(vertex_t target) const
|
||||
{
|
||||
std::size_t n = num_vertices(m_topology);
|
||||
if (m_distances.size() != n * n)
|
||||
{
|
||||
m_distances.clear();
|
||||
m_distances.resize(n * n, (std::numeric_limits<std::size_t>::max)());
|
||||
m_known_vertices = n;
|
||||
}
|
||||
|
||||
std::vector<std::size_t>::iterator to_target = m_distances.begin() + n * target;
|
||||
|
||||
// this node hasn't been used as a target yet
|
||||
if (to_target[target] != 0)
|
||||
{
|
||||
typedef reverse_graph<cast_graph> reverse_cast_graph;
|
||||
reverse_cast_graph reverse_topology(m_topology);
|
||||
|
||||
to_target[target] = 0;
|
||||
|
||||
breadth_first_search(
|
||||
reverse_topology, target
|
||||
, visitor(
|
||||
make_bfs_visitor(
|
||||
record_distances(
|
||||
make_iterator_property_map(
|
||||
to_target
|
||||
, get(vertex_index, reverse_topology)
|
||||
# ifdef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
, *to_target
|
||||
# endif
|
||||
)
|
||||
, on_tree_edge()
|
||||
))));
|
||||
}
|
||||
|
||||
return to_target;
|
||||
}
|
||||
|
||||
cast_graph& topology() { return m_topology; }
|
||||
cast_graph const& topology() const { return m_topology; }
|
||||
|
||||
smart_graph()
|
||||
: m_known_vertices(0)
|
||||
{}
|
||||
|
||||
private:
|
||||
cast_graph m_topology;
|
||||
mutable std::vector<std::size_t> m_distances;
|
||||
mutable std::size_t m_known_vertices;
|
||||
};
|
||||
|
||||
smart_graph& full_graph()
|
||||
{
|
||||
static smart_graph x;
|
||||
return x;
|
||||
}
|
||||
|
||||
smart_graph& up_graph()
|
||||
{
|
||||
static smart_graph x;
|
||||
return x;
|
||||
}
|
||||
|
||||
//
|
||||
// Our index of class types
|
||||
//
|
||||
using boost::python::objects::dynamic_id_function;
|
||||
typedef tuples::tuple<
|
||||
class_id // static type
|
||||
, vertex_t // corresponding vertex
|
||||
, dynamic_id_function // dynamic_id if polymorphic, or 0
|
||||
>
|
||||
index_entry_interface;
|
||||
typedef index_entry_interface::inherited index_entry;
|
||||
enum { ksrc_static_t, kvertex, kdynamic_id };
|
||||
|
||||
typedef std::vector<index_entry> type_index_t;
|
||||
|
||||
|
||||
type_index_t& type_index()
|
||||
{
|
||||
static type_index_t x;
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class Tuple>
|
||||
struct select1st
|
||||
{
|
||||
typedef typename tuples::element<0, Tuple>::type result_type;
|
||||
|
||||
result_type const& operator()(Tuple const& x) const
|
||||
{
|
||||
return tuples::get<0>(x);
|
||||
}
|
||||
};
|
||||
|
||||
// map a type to a position in the index
|
||||
inline type_index_t::iterator type_position(class_id type)
|
||||
{
|
||||
typedef index_entry entry;
|
||||
|
||||
return std::lower_bound(
|
||||
type_index().begin(), type_index().end()
|
||||
, boost::make_tuple(type, vertex_t(), dynamic_id_function(0))
|
||||
, boost::bind<bool>(std::less<class_id>()
|
||||
, boost::bind<class_id>(select1st<entry>(), _1)
|
||||
, boost::bind<class_id>(select1st<entry>(), _2)));
|
||||
}
|
||||
|
||||
inline index_entry* seek_type(class_id type)
|
||||
{
|
||||
type_index_t::iterator p = type_position(type);
|
||||
if (p == type_index().end() || tuples::get<ksrc_static_t>(*p) != type)
|
||||
return 0;
|
||||
else
|
||||
return &*p;
|
||||
}
|
||||
|
||||
// Get the entry for a type, inserting if necessary
|
||||
inline type_index_t::iterator demand_type(class_id type)
|
||||
{
|
||||
type_index_t::iterator p = type_position(type);
|
||||
|
||||
if (p != type_index().end() && tuples::get<ksrc_static_t>(*p) == type)
|
||||
return p;
|
||||
|
||||
vertex_t v = add_vertex(full_graph().topology());
|
||||
vertex_t v2 = add_vertex(up_graph().topology());
|
||||
unused_variable(v2);
|
||||
assert(v == v2);
|
||||
return type_index().insert(p, boost::make_tuple(type, v, dynamic_id_function(0)));
|
||||
}
|
||||
|
||||
// Map a two types to a vertex in the graph, inserting if necessary
|
||||
typedef std::pair<type_index_t::iterator, type_index_t::iterator>
|
||||
type_index_iterator_pair;
|
||||
|
||||
inline type_index_iterator_pair
|
||||
demand_types(class_id t1, class_id t2)
|
||||
{
|
||||
// be sure there will be no reallocation
|
||||
type_index().reserve(type_index().size() + 2);
|
||||
type_index_t::iterator first = demand_type(t1);
|
||||
type_index_t::iterator second = demand_type(t2);
|
||||
if (first == second)
|
||||
++first;
|
||||
return std::make_pair(first, second);
|
||||
}
|
||||
|
||||
struct q_elt
|
||||
{
|
||||
q_elt(std::size_t distance
|
||||
, void* src_address
|
||||
, vertex_t target
|
||||
, cast_function cast
|
||||
)
|
||||
: distance(distance)
|
||||
, src_address(src_address)
|
||||
, target(target)
|
||||
, cast(cast)
|
||||
{}
|
||||
|
||||
std::size_t distance;
|
||||
void* src_address;
|
||||
vertex_t target;
|
||||
cast_function cast;
|
||||
|
||||
bool operator<(q_elt const& rhs) const
|
||||
{
|
||||
return distance < rhs.distance;
|
||||
}
|
||||
};
|
||||
|
||||
// Optimization:
|
||||
//
|
||||
// Given p, src_t, dst_t
|
||||
//
|
||||
// Get a pointer pd to the most-derived object
|
||||
// if it's polymorphic, dynamic_cast to void*
|
||||
// otherwise pd = p
|
||||
//
|
||||
// Get the most-derived typeid src_td
|
||||
//
|
||||
// ptrdiff_t offset = p - pd
|
||||
//
|
||||
// Now we can keep a cache, for [src_t, offset, src_td, dst_t] of
|
||||
// the cast transformation function to use on p and the next src_t
|
||||
// in the chain. src_td, dst_t don't change throughout this
|
||||
// process. In order to represent unreachability, when a pair is
|
||||
// found to be unreachable, we stick a 0-returning "dead-cast"
|
||||
// function in the cache.
|
||||
|
||||
// This is needed in a few places below
|
||||
inline void* identity_cast(void* p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
void* search(smart_graph const& g, void* p, vertex_t src, vertex_t dst)
|
||||
{
|
||||
// I think this test was thoroughly bogus -- dwa
|
||||
// If we know there's no path; bail now.
|
||||
// if (src > g.known_vertices() || dst > g.known_vertices())
|
||||
// return 0;
|
||||
|
||||
smart_graph::node_distance_map d(g.distances_to(dst));
|
||||
|
||||
if (d[src] == (std::numeric_limits<std::size_t>::max)())
|
||||
return 0;
|
||||
|
||||
typedef property_map<cast_graph,edge_cast_t>::const_type cast_map;
|
||||
cast_map casts = get(edge_cast, g.topology());
|
||||
|
||||
typedef std::pair<vertex_t,void*> search_state;
|
||||
typedef std::vector<search_state> visited_t;
|
||||
visited_t visited;
|
||||
std::priority_queue<q_elt> q;
|
||||
|
||||
q.push(q_elt(d[src], p, src, identity_cast));
|
||||
while (!q.empty())
|
||||
{
|
||||
q_elt top = q.top();
|
||||
q.pop();
|
||||
|
||||
// Check to see if we have a real state
|
||||
void* dst_address = top.cast(top.src_address);
|
||||
if (dst_address == 0)
|
||||
continue;
|
||||
|
||||
if (top.target == dst)
|
||||
return dst_address;
|
||||
|
||||
search_state s(top.target,dst_address);
|
||||
|
||||
visited_t::iterator pos = std::lower_bound(
|
||||
visited.begin(), visited.end(), s);
|
||||
|
||||
// If already visited, continue
|
||||
if (pos != visited.end() && *pos == s)
|
||||
continue;
|
||||
|
||||
visited.insert(pos, s); // mark it
|
||||
|
||||
// expand it:
|
||||
smart_graph::out_edges_t edges = out_edges(s.first, g.topology());
|
||||
for (cast_graph::out_edge_iterator p = edges.first
|
||||
, finish = edges.second
|
||||
; p != finish
|
||||
; ++p
|
||||
)
|
||||
{
|
||||
edge_t e = *p;
|
||||
q.push(q_elt(
|
||||
d[target(e, g.topology())]
|
||||
, dst_address
|
||||
, target(e, g.topology())
|
||||
, boost::get(casts, e)));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct cache_element
|
||||
{
|
||||
typedef tuples::tuple<
|
||||
class_id // source static type
|
||||
, class_id // target type
|
||||
, std::ptrdiff_t // offset within source object
|
||||
, class_id // source dynamic type
|
||||
>::inherited key_type;
|
||||
|
||||
cache_element(key_type const& k)
|
||||
: key(k)
|
||||
, offset(0)
|
||||
{}
|
||||
|
||||
key_type key;
|
||||
std::ptrdiff_t offset;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
std::ptrdiff_t, not_found = integer_traits<std::ptrdiff_t>::const_min);
|
||||
|
||||
bool operator<(cache_element const& rhs) const
|
||||
{
|
||||
return this->key < rhs.key;
|
||||
}
|
||||
|
||||
bool unreachable() const
|
||||
{
|
||||
return offset == not_found;
|
||||
}
|
||||
};
|
||||
|
||||
enum { kdst_t = ksrc_static_t + 1, koffset, ksrc_dynamic_t };
|
||||
typedef std::vector<cache_element> cache_t;
|
||||
|
||||
cache_t& cache()
|
||||
{
|
||||
static cache_t x;
|
||||
return x;
|
||||
}
|
||||
|
||||
inline void* convert_type(void* const p, class_id src_t, class_id dst_t, bool polymorphic)
|
||||
{
|
||||
// Quickly rule out unregistered types
|
||||
index_entry* src_p = seek_type(src_t);
|
||||
if (src_p == 0)
|
||||
return 0;
|
||||
|
||||
index_entry* dst_p = seek_type(dst_t);
|
||||
if (dst_p == 0)
|
||||
return 0;
|
||||
|
||||
// Look up the dynamic_id function and call it to get the dynamic
|
||||
// info
|
||||
boost::python::objects::dynamic_id_t dynamic_id = polymorphic
|
||||
? tuples::get<kdynamic_id>(*src_p)(p)
|
||||
: std::make_pair(p, src_t);
|
||||
|
||||
// Look in the cache first for a quickie address translation
|
||||
std::ptrdiff_t offset = (char*)p - (char*)dynamic_id.first;
|
||||
|
||||
cache_element seek(boost::make_tuple(src_t, dst_t, offset, dynamic_id.second));
|
||||
cache_t& c = cache();
|
||||
cache_t::iterator const cache_pos
|
||||
= std::lower_bound(c.begin(), c.end(), seek);
|
||||
|
||||
|
||||
// if found in the cache, we're done
|
||||
if (cache_pos != c.end() && cache_pos->key == seek.key)
|
||||
{
|
||||
return cache_pos->offset == cache_element::not_found
|
||||
? 0 : (char*)p + cache_pos->offset;
|
||||
}
|
||||
|
||||
// If we are starting at the most-derived type, only look in the up graph
|
||||
smart_graph const& g = polymorphic && dynamic_id.second != src_t
|
||||
? full_graph() : up_graph();
|
||||
|
||||
void* result = search(
|
||||
g, p, tuples::get<kvertex>(*src_p)
|
||||
, tuples::get<kvertex>(*dst_p));
|
||||
|
||||
// update the cache
|
||||
c.insert(cache_pos, seek)->offset
|
||||
= (result == 0) ? cache_element::not_found : (char*)result - (char*)p;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace python { namespace objects {
|
||||
|
||||
BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src_t, class_id dst_t)
|
||||
{
|
||||
return convert_type(p, src_t, dst_t, true);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src_t, class_id dst_t)
|
||||
{
|
||||
return convert_type(p, src_t, dst_t, false);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void add_cast(
|
||||
class_id src_t, class_id dst_t, cast_function cast, bool is_downcast)
|
||||
{
|
||||
// adding an edge will invalidate any record of unreachability in
|
||||
// the cache.
|
||||
static std::size_t expected_cache_len = 0;
|
||||
cache_t& c = cache();
|
||||
if (c.size() > expected_cache_len)
|
||||
{
|
||||
c.erase(std::remove_if(
|
||||
c.begin(), c.end(),
|
||||
mem_fn(&cache_element::unreachable))
|
||||
, c.end());
|
||||
|
||||
// If any new cache entries get added, we'll have to do this
|
||||
// again when the next edge is added
|
||||
expected_cache_len = c.size();
|
||||
}
|
||||
|
||||
type_index_iterator_pair types = demand_types(src_t, dst_t);
|
||||
vertex_t src = tuples::get<kvertex>(*types.first);
|
||||
vertex_t dst = tuples::get<kvertex>(*types.second);
|
||||
|
||||
cast_graph* const g[2] = { &up_graph().topology(), &full_graph().topology() };
|
||||
|
||||
for (cast_graph*const* p = g + (is_downcast ? 1 : 0); p < g + 2; ++p)
|
||||
{
|
||||
edge_t e;
|
||||
bool added;
|
||||
|
||||
tie(e, added) = add_edge(src, dst, **p);
|
||||
assert(added);
|
||||
|
||||
put(get(edge_cast, **p), e, cast);
|
||||
put(get(edge_index, **p), e, num_edges(full_graph().topology()) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void register_dynamic_id_aux(
|
||||
class_id static_id, dynamic_id_function get_dynamic_id)
|
||||
{
|
||||
tuples::get<kdynamic_id>(*demand_type(static_id)) = get_dynamic_id;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
@ -1,39 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/object/iterator_core.hpp>
|
||||
#include <boost/python/object/function_object.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/mpl/vector/vector10.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
namespace
|
||||
{
|
||||
PyObject* identity(PyObject* args_, PyObject*)
|
||||
{
|
||||
PyObject* x = PyTuple_GET_ITEM(args_,0);
|
||||
Py_INCREF(x);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object const& identity_function()
|
||||
{
|
||||
static object result(
|
||||
function_object(
|
||||
py_function(&identity, mpl::vector2<PyObject*,PyObject*>())
|
||||
)
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
void stop_iteration_error()
|
||||
{
|
||||
PyErr_SetObject(PyExc_StopIteration, Py_None);
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
@ -1,121 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/python/object/life_support.hpp>
|
||||
#include <boost/python/detail/none.hpp>
|
||||
#include <boost/python/refcount.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
struct life_support
|
||||
{
|
||||
PyObject_HEAD
|
||||
PyObject* patient;
|
||||
};
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static void
|
||||
life_support_dealloc(PyObject* self)
|
||||
{
|
||||
Py_XDECREF(((life_support*)self)->patient);
|
||||
self->ob_type->tp_free(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
life_support_call(PyObject *self, PyObject *arg, PyObject * /*kw*/)
|
||||
{
|
||||
// Let the patient die now
|
||||
Py_XDECREF(((life_support*)self)->patient);
|
||||
((life_support*)self)->patient = 0;
|
||||
// Let the weak reference die. This probably kills us.
|
||||
Py_XDECREF(PyTuple_GET_ITEM(arg, 0));
|
||||
return ::boost::python::detail::none();
|
||||
}
|
||||
}
|
||||
|
||||
PyTypeObject life_support_type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)//(&PyType_Type)
|
||||
const_cast<char*>("Boost.Python.life_support"),
|
||||
sizeof(life_support),
|
||||
0,
|
||||
life_support_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
0, //(reprfunc)func_repr, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
life_support_call, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, // PyObject_GenericGetAttr, /* tp_getattro */
|
||||
0, // PyObject_GenericSetAttr, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT /* | Py_TPFLAGS_HAVE_GC */,/* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, // (traverseproc)func_traverse, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, //offsetof(PyLife_SupportObject, func_weakreflist), /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, // func_memberlist, /* tp_members */
|
||||
0, //func_getsetlist, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, //offsetof(PyLife_SupportObject, func_dict), /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
0, /* tp_new */
|
||||
0, /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
#if PYTHON_API_VERSION >= 1012
|
||||
0 /* tp_del */
|
||||
#endif
|
||||
};
|
||||
|
||||
PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient)
|
||||
{
|
||||
if (nurse == Py_None || nurse == patient)
|
||||
return nurse;
|
||||
|
||||
if (Py_TYPE(&life_support_type) == 0)
|
||||
{
|
||||
Py_TYPE(&life_support_type) = &PyType_Type;
|
||||
PyType_Ready(&life_support_type);
|
||||
}
|
||||
|
||||
life_support* system = PyObject_New(life_support, &life_support_type);
|
||||
if (!system)
|
||||
return 0;
|
||||
|
||||
system->patient = 0;
|
||||
|
||||
// We're going to leak this reference, but don't worry; the
|
||||
// life_support system decrements it when the nurse dies.
|
||||
PyObject* weakref = PyWeakref_NewRef(nurse, (PyObject*)system);
|
||||
|
||||
// weakref has either taken ownership, or we have to release it
|
||||
// anyway
|
||||
Py_DECREF(system);
|
||||
if (!weakref)
|
||||
return 0;
|
||||
|
||||
system->patient = patient;
|
||||
Py_XINCREF(patient); // hang on to the patient until death
|
||||
return weakref;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
@ -1,78 +0,0 @@
|
||||
// (C) Copyright R.W. Grosse-Kunstleve 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/make_function.hpp>
|
||||
#include <boost/python/object/class.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/list.hpp>
|
||||
#include <boost/python/dict.hpp>
|
||||
#include <boost/python/str.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace {
|
||||
|
||||
tuple instance_reduce(object instance_obj)
|
||||
{
|
||||
list result;
|
||||
object instance_class(instance_obj.attr("__class__"));
|
||||
result.append(instance_class);
|
||||
object none;
|
||||
if (!getattr(instance_obj, "__safe_for_unpickling__", none))
|
||||
{
|
||||
str type_name(getattr(instance_class, "__name__"));
|
||||
str module_name(getattr(instance_class, "__module__", object("")));
|
||||
if (module_name)
|
||||
module_name += ".";
|
||||
|
||||
PyErr_SetObject(
|
||||
PyExc_RuntimeError,
|
||||
( "Pickling of \"%s\" instances is not enabled"
|
||||
" (http://www.boost.org/libs/python/doc/v2/pickle.html)"
|
||||
% (module_name+type_name)).ptr()
|
||||
);
|
||||
|
||||
throw_error_already_set();
|
||||
}
|
||||
object getinitargs = getattr(instance_obj, "__getinitargs__", none);
|
||||
tuple initargs;
|
||||
if (!getinitargs.is_none()) {
|
||||
initargs = tuple(getinitargs());
|
||||
}
|
||||
result.append(initargs);
|
||||
object getstate = getattr(instance_obj, "__getstate__", none);
|
||||
object instance_dict = getattr(instance_obj, "__dict__", none);
|
||||
long len_instance_dict = 0;
|
||||
if (!instance_dict.is_none()) {
|
||||
len_instance_dict = len(instance_dict);
|
||||
}
|
||||
if (!getstate.is_none()) {
|
||||
if (len_instance_dict > 0) {
|
||||
object getstate_manages_dict = getattr(
|
||||
instance_obj, "__getstate_manages_dict__", none);
|
||||
if (getstate_manages_dict.is_none()) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Incomplete pickle support"
|
||||
" (__getstate_manages_dict__ not set)");
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
result.append(getstate());
|
||||
}
|
||||
else if (len_instance_dict > 0) {
|
||||
result.append(instance_dict);
|
||||
}
|
||||
return tuple(result);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
object const& make_instance_reduce_function()
|
||||
{
|
||||
static object result(&instance_reduce);
|
||||
return result;
|
||||
}
|
||||
|
||||
}} // namespace boost::python
|
@ -1,48 +0,0 @@
|
||||
// Copyright Eric Niebler 2005.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Credits:
|
||||
// Andreas Kl\:ockner for fixing increment() to handle
|
||||
// error conditions.
|
||||
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/handle.hpp>
|
||||
#include <boost/python/object/stl_iterator_core.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace objects
|
||||
{
|
||||
|
||||
stl_input_iterator_impl::stl_input_iterator_impl()
|
||||
: it_()
|
||||
, ob_()
|
||||
{
|
||||
}
|
||||
|
||||
stl_input_iterator_impl::stl_input_iterator_impl(boost::python::object const &ob)
|
||||
: it_(ob.attr("__iter__")())
|
||||
, ob_()
|
||||
{
|
||||
this->increment();
|
||||
}
|
||||
|
||||
void stl_input_iterator_impl::increment()
|
||||
{
|
||||
this->ob_ = boost::python::handle<>(
|
||||
boost::python::allow_null(PyIter_Next(this->it_.ptr())));
|
||||
if (PyErr_Occurred())
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
|
||||
bool stl_input_iterator_impl::equal(stl_input_iterator_impl const &that) const
|
||||
{
|
||||
return !this->ob_ == !that.ob_;
|
||||
}
|
||||
|
||||
boost::python::handle<> const &stl_input_iterator_impl::current() const
|
||||
{
|
||||
return this->ob_;
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::objects
|
@ -1,85 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/object_operators.hpp>
|
||||
#include <boost/python/detail/raw_pyobject.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace api {
|
||||
|
||||
# define BOOST_PYTHON_COMPARE_OP(op, opid) \
|
||||
BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \
|
||||
{ \
|
||||
return object( \
|
||||
detail::new_reference( \
|
||||
PyObject_RichCompare( \
|
||||
l.ptr(), r.ptr(), opid)) \
|
||||
); \
|
||||
}
|
||||
BOOST_PYTHON_COMPARE_OP(>, Py_GT)
|
||||
BOOST_PYTHON_COMPARE_OP(>=, Py_GE)
|
||||
BOOST_PYTHON_COMPARE_OP(<, Py_LT)
|
||||
BOOST_PYTHON_COMPARE_OP(<=, Py_LE)
|
||||
BOOST_PYTHON_COMPARE_OP(==, Py_EQ)
|
||||
BOOST_PYTHON_COMPARE_OP(!=, Py_NE)
|
||||
# undef BOOST_PYTHON_COMPARE_OP
|
||||
|
||||
|
||||
#define BOOST_PYTHON_BINARY_OPERATOR(op, name) \
|
||||
BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \
|
||||
{ \
|
||||
return object( \
|
||||
detail::new_reference( \
|
||||
PyNumber_##name(l.ptr(), r.ptr())) \
|
||||
); \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_BINARY_OPERATOR(+, Add)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(-, Subtract)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(*, Multiply)
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
// We choose FloorDivide instead of TrueDivide to keep the semantic
|
||||
// conform with C/C++'s '/' operator
|
||||
BOOST_PYTHON_BINARY_OPERATOR(/, FloorDivide)
|
||||
#else
|
||||
BOOST_PYTHON_BINARY_OPERATOR(/, Divide)
|
||||
#endif
|
||||
BOOST_PYTHON_BINARY_OPERATOR(%, Remainder)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(<<, Lshift)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(>>, Rshift)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(&, And)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(^, Xor)
|
||||
BOOST_PYTHON_BINARY_OPERATOR(|, Or)
|
||||
#undef BOOST_PYTHON_BINARY_OPERATOR
|
||||
|
||||
#define BOOST_PYTHON_INPLACE_OPERATOR(op, name) \
|
||||
BOOST_PYTHON_DECL object& operator op##=(object& l, object const& r) \
|
||||
{ \
|
||||
return l = object( \
|
||||
(detail::new_reference) \
|
||||
PyNumber_InPlace##name(l.ptr(), r.ptr())); \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(+, Add)
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(-, Subtract)
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(*, Multiply)
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
// Same reason as above for choosing FloorDivide instead of TrueDivide
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(/, FloorDivide)
|
||||
#else
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(/, Divide)
|
||||
#endif
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(%, Remainder)
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(<<, Lshift)
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(>>, Rshift)
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(&, And)
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(^, Xor)
|
||||
BOOST_PYTHON_INPLACE_OPERATOR(|, Or)
|
||||
#undef BOOST_PYTHON_INPLACE_OPERATOR
|
||||
|
||||
object::object(handle<> const& x)
|
||||
: object_base(python::incref(python::expect_non_null(x.get())))
|
||||
{}
|
||||
|
||||
}}} // namespace boost::python
|
@ -1,197 +0,0 @@
|
||||
// Copyright David Abrahams 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/object_protocol.hpp>
|
||||
#include <boost/python/errors.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/ssize_t.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace api {
|
||||
|
||||
BOOST_PYTHON_DECL object getattr(object const& target, object const& key)
|
||||
{
|
||||
return object(detail::new_reference(PyObject_GetAttr(target.ptr(), key.ptr())));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object getattr(object const& target, object const& key, object const& default_)
|
||||
{
|
||||
PyObject* result = PyObject_GetAttr(target.ptr(), key.ptr());
|
||||
if (result == NULL && PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
{
|
||||
PyErr_Clear();
|
||||
return default_;
|
||||
}
|
||||
return object(detail::new_reference(result));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value)
|
||||
{
|
||||
if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void delattr(object const& target, object const& key)
|
||||
{
|
||||
if (PyObject_DelAttr(target.ptr(), key.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object getattr(object const& target, char const* key)
|
||||
{
|
||||
return object(
|
||||
detail::new_reference(
|
||||
PyObject_GetAttrString(target.ptr(), const_cast<char*>(key))
|
||||
));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object getattr(object const& target, char const* key, object const& default_)
|
||||
{
|
||||
PyObject* result = PyObject_GetAttrString(target.ptr(), const_cast<char*>(key));
|
||||
if (result == NULL && PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
{
|
||||
PyErr_Clear();
|
||||
return default_;
|
||||
}
|
||||
return object(detail::new_reference(result));
|
||||
|
||||
}
|
||||
BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value)
|
||||
{
|
||||
if (PyObject_SetAttrString(
|
||||
target.ptr(), const_cast<char*>(key), value.ptr()) == -1
|
||||
)
|
||||
{
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void delattr(object const& target, char const* key)
|
||||
{
|
||||
if (PyObject_DelAttrString(
|
||||
target.ptr(), const_cast<char*>(key)) == -1
|
||||
)
|
||||
{
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object getitem(object const& target, object const& key)
|
||||
{
|
||||
return object(detail::new_reference(
|
||||
PyObject_GetItem(target.ptr(), key.ptr())));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value)
|
||||
{
|
||||
if (PyObject_SetItem(target.ptr(), key.ptr(), value.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void delitem(object const& target, object const& key)
|
||||
{
|
||||
if (PyObject_DelItem(target.ptr(), key.ptr()) == -1)
|
||||
throw_error_already_set();
|
||||
}
|
||||
|
||||
namespace // slicing code copied directly out of the Python implementation
|
||||
{
|
||||
#undef ISINT
|
||||
#define ISINT(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x))
|
||||
|
||||
static PyObject *
|
||||
apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
|
||||
{
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
PyTypeObject *tp = u->ob_type;
|
||||
PySequenceMethods *sq = tp->tp_as_sequence;
|
||||
|
||||
if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
|
||||
ssize_t ilow = 0, ihigh = ssize_t_max;
|
||||
if (!_PyEval_SliceIndex(v, &ilow))
|
||||
return NULL;
|
||||
if (!_PyEval_SliceIndex(w, &ihigh))
|
||||
return NULL;
|
||||
return PySequence_GetSlice(u, ilow, ihigh);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
PyObject *slice = PySlice_New(v, w, NULL);
|
||||
if (slice != NULL) {
|
||||
PyObject *res = PyObject_GetItem(u, slice);
|
||||
Py_DECREF(slice);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
|
||||
/* u[v:w] = x */
|
||||
{
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
PyTypeObject *tp = u->ob_type;
|
||||
PySequenceMethods *sq = tp->tp_as_sequence;
|
||||
|
||||
if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
|
||||
ssize_t ilow = 0, ihigh = ssize_t_max;
|
||||
if (!_PyEval_SliceIndex(v, &ilow))
|
||||
return -1;
|
||||
if (!_PyEval_SliceIndex(w, &ihigh))
|
||||
return -1;
|
||||
if (x == NULL)
|
||||
return PySequence_DelSlice(u, ilow, ihigh);
|
||||
else
|
||||
return PySequence_SetSlice(u, ilow, ihigh, x);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
PyObject *slice = PySlice_New(v, w, NULL);
|
||||
if (slice != NULL) {
|
||||
int res;
|
||||
if (x != NULL)
|
||||
res = PyObject_SetItem(u, slice, x);
|
||||
else
|
||||
res = PyObject_DelItem(u, slice);
|
||||
Py_DECREF(slice);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end)
|
||||
{
|
||||
return object(
|
||||
detail::new_reference(
|
||||
apply_slice(target.ptr(), begin.get(), end.get())));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value)
|
||||
{
|
||||
if (assign_slice(
|
||||
target.ptr(), begin.get(), end.get(), value.ptr()) == -1
|
||||
)
|
||||
{
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end)
|
||||
{
|
||||
if (assign_slice(
|
||||
target.ptr(), begin.get(), end.get(), 0) == -1
|
||||
)
|
||||
{
|
||||
throw_error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::python::api
|
@ -1,37 +0,0 @@
|
||||
#include "boost/python/slice.hpp"
|
||||
|
||||
// Copyright (c) 2004 Jonathan Brandmeyer
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
slice_base::slice_base(PyObject* start, PyObject* stop, PyObject* step)
|
||||
: object(detail::new_reference( PySlice_New(start, stop, step)))
|
||||
{
|
||||
}
|
||||
|
||||
object
|
||||
slice_base::start() const
|
||||
{
|
||||
return object( detail::borrowed_reference(
|
||||
((PySliceObject*)this->ptr())->start));
|
||||
}
|
||||
|
||||
object
|
||||
slice_base::stop() const
|
||||
{
|
||||
return object( detail::borrowed_reference(
|
||||
((PySliceObject*)this->ptr())->stop));
|
||||
}
|
||||
|
||||
object
|
||||
slice_base::step() const
|
||||
{
|
||||
return object( detail::borrowed_reference(
|
||||
((PySliceObject*)this->ptr())->step));
|
||||
}
|
||||
|
||||
} } } // !namespace boost::python::detail
|
@ -1,419 +0,0 @@
|
||||
// Copyright David Abrahams 2004. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/python/str.hpp>
|
||||
#include <boost/python/extract.hpp>
|
||||
#include <boost/python/ssize_t.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
detail::new_reference str_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
(PyObject*)&PyUnicode_Type,
|
||||
#else
|
||||
(PyObject*)&PyString_Type,
|
||||
#endif
|
||||
const_cast<char*>("(O)"),
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
str_base::str_base()
|
||||
: object(detail::new_reference(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromString("")
|
||||
#else
|
||||
::PyString_FromString("")
|
||||
#endif
|
||||
))
|
||||
{}
|
||||
|
||||
str_base::str_base(const char* s)
|
||||
: object(detail::new_reference(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromString(s)
|
||||
#else
|
||||
::PyString_FromString(s)
|
||||
#endif
|
||||
))
|
||||
{}
|
||||
|
||||
namespace {
|
||||
|
||||
ssize_t str_size_as_py_ssize_t(std::size_t n)
|
||||
{
|
||||
if (n > static_cast<std::size_t>(ssize_t_max))
|
||||
{
|
||||
throw std::range_error("str size > ssize_t_max");
|
||||
}
|
||||
return static_cast<ssize_t>(n);
|
||||
}
|
||||
|
||||
} // namespace <anonymous>
|
||||
|
||||
str_base::str_base(char const* start, char const* finish)
|
||||
: object(
|
||||
detail::new_reference(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromStringAndSize
|
||||
#else
|
||||
::PyString_FromStringAndSize
|
||||
#endif
|
||||
(start, str_size_as_py_ssize_t(finish - start))
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
str_base::str_base(char const* start, std::size_t length) // new str
|
||||
: object(
|
||||
detail::new_reference(
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyUnicode_FromStringAndSize
|
||||
#else
|
||||
::PyString_FromStringAndSize
|
||||
#endif
|
||||
( start, str_size_as_py_ssize_t(length) )
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
str_base::str_base(object_cref other)
|
||||
: object(str_base::call(other))
|
||||
{}
|
||||
|
||||
#define BOOST_PYTHON_FORMAT_OBJECT(z, n, data) "O"
|
||||
#define BOOST_PYTHON_OBJECT_PTR(z, n, data) , x##n .ptr()
|
||||
|
||||
#define BOOST_PYTHON_DEFINE_STR_METHOD(name, arity) \
|
||||
str str_base:: name ( BOOST_PP_ENUM_PARAMS(arity, object_cref x) ) const \
|
||||
{ \
|
||||
return str(new_reference( \
|
||||
expect_non_null( \
|
||||
PyObject_CallMethod( \
|
||||
this->ptr(), const_cast<char*>( #name ), \
|
||||
const_cast<char*>( \
|
||||
"(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")") \
|
||||
BOOST_PP_REPEAT_1(arity, BOOST_PYTHON_OBJECT_PTR, _))))); \
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(capitalize, 0)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(center, 1)
|
||||
|
||||
long str_base::count(object_cref sub) const
|
||||
{
|
||||
return extract<long>(this->attr("count")(sub));
|
||||
}
|
||||
|
||||
long str_base::count(object_cref sub, object_cref start) const
|
||||
{
|
||||
return extract<long>(this->attr("count")(sub,start));
|
||||
}
|
||||
|
||||
long str_base::count(object_cref sub, object_cref start, object_cref end) const
|
||||
{
|
||||
return extract<long>(this->attr("count")(sub,start,end));
|
||||
}
|
||||
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
object str_base::decode() const
|
||||
{
|
||||
return this->attr("decode")();
|
||||
}
|
||||
|
||||
object str_base::decode(object_cref encoding) const
|
||||
{
|
||||
return this->attr("decode")(encoding);
|
||||
}
|
||||
|
||||
object str_base::decode(object_cref encoding, object_cref errors) const
|
||||
{
|
||||
return this->attr("decode")(encoding,errors);
|
||||
}
|
||||
#endif
|
||||
|
||||
object str_base::encode() const
|
||||
{
|
||||
return this->attr("encode")();
|
||||
}
|
||||
|
||||
object str_base::encode(object_cref encoding) const
|
||||
{
|
||||
return this->attr("encode")(encoding);
|
||||
}
|
||||
|
||||
object str_base::encode(object_cref encoding, object_cref errors) const
|
||||
{
|
||||
return this->attr("encode")(encoding,errors);
|
||||
}
|
||||
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
#define _BOOST_PYTHON_ASLONG PyLong_AsLong
|
||||
#else
|
||||
#define _BOOST_PYTHON_ASLONG PyInt_AsLong
|
||||
#endif
|
||||
|
||||
bool str_base::endswith(object_cref suffix) const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("endswith")(suffix).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::endswith(object_cref suffix, object_cref start) const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("endswith")(suffix,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::endswith(object_cref suffix, object_cref start, object_cref end) const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("endswith")(suffix,start,end).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 0)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 1)
|
||||
|
||||
long str_base::find(object_cref sub) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
long str_base::find(object_cref sub, object_cref start) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
long str_base::find(object_cref sub, object_cref start, object_cref end) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("find")(sub,start,end).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
long str_base::index(object_cref sub) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
long str_base::index(object_cref sub, object_cref start) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
long str_base::index(object_cref sub, object_cref start, object_cref end) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("index")(sub,start,end).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::isalnum() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("isalnum")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::isalpha() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("isalpha")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::isdigit() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("isdigit")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::islower() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("islower")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::isspace() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("isspace")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::istitle() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("istitle")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::isupper() const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("isupper")().ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(join, 1)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(ljust, 1)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(lower, 0)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(lstrip, 0)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(replace, 2)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(replace, 3)
|
||||
|
||||
long str_base::rfind(object_cref sub) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
long str_base::rfind(object_cref sub, object_cref start) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
long str_base::rfind(object_cref sub, object_cref start, object_cref end) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("rfind")(sub,start,end).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
long str_base::rindex(object_cref sub) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
long str_base::rindex(object_cref sub, object_cref start) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
long str_base::rindex(object_cref sub, object_cref start, object_cref end) const
|
||||
{
|
||||
long result = _BOOST_PYTHON_ASLONG(this->attr("rindex")(sub,start,end).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(rjust, 1)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(rstrip, 0)
|
||||
|
||||
list str_base::split() const
|
||||
{
|
||||
return list(this->attr("split")());
|
||||
}
|
||||
|
||||
list str_base::split(object_cref sep) const
|
||||
{
|
||||
return list(this->attr("split")(sep));
|
||||
}
|
||||
|
||||
list str_base::split(object_cref sep, object_cref maxsplit) const
|
||||
{
|
||||
return list(this->attr("split")(sep,maxsplit));
|
||||
}
|
||||
|
||||
list str_base::splitlines() const
|
||||
{
|
||||
return list(this->attr("splitlines")());
|
||||
}
|
||||
|
||||
list str_base::splitlines(object_cref keepends) const
|
||||
{
|
||||
return list(this->attr("splitlines")(keepends));
|
||||
}
|
||||
|
||||
bool str_base::startswith(object_cref prefix) const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::startswith(object_cref prefix, object_cref start) const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool str_base::startswith(object_cref prefix, object_cref start, object_cref end) const
|
||||
{
|
||||
bool result = _BOOST_PYTHON_ASLONG(this->attr("startswith")(prefix,start,end).ptr());
|
||||
if (PyErr_Occurred())
|
||||
throw_error_already_set();
|
||||
return result;
|
||||
}
|
||||
|
||||
#undef _BOOST_PYTHON_ASLONG
|
||||
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(strip, 0)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(swapcase, 0)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(title, 0)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(translate, 1)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(translate, 2)
|
||||
BOOST_PYTHON_DEFINE_STR_METHOD(upper, 0)
|
||||
|
||||
static struct register_str_pytype_ptr
|
||||
{
|
||||
register_str_pytype_ptr()
|
||||
{
|
||||
const_cast<converter::registration &>(
|
||||
converter::registry::lookup(boost::python::type_id<boost::python::str>())
|
||||
)
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
.m_class_object = &PyUnicode_Type;
|
||||
#else
|
||||
.m_class_object = &PyString_Type;
|
||||
#endif
|
||||
}
|
||||
}register_str_pytype_ptr_;
|
||||
|
||||
}}} // namespace boost::python
|
@ -1,35 +0,0 @@
|
||||
// Copyright David Abrahams 2004.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/python/tuple.hpp>
|
||||
|
||||
namespace boost { namespace python { namespace detail {
|
||||
|
||||
detail::new_reference tuple_base::call(object const& arg_)
|
||||
{
|
||||
return (detail::new_reference)PyObject_CallFunction(
|
||||
(PyObject*)&PyTuple_Type, const_cast<char*>("(O)"),
|
||||
arg_.ptr());
|
||||
}
|
||||
|
||||
tuple_base::tuple_base()
|
||||
: object(detail::new_reference(PyTuple_New(0)))
|
||||
{}
|
||||
|
||||
tuple_base::tuple_base(object_cref sequence)
|
||||
: object(call(sequence))
|
||||
{}
|
||||
|
||||
static struct register_tuple_pytype_ptr
|
||||
{
|
||||
register_tuple_pytype_ptr()
|
||||
{
|
||||
const_cast<converter::registration &>(
|
||||
converter::registry::lookup(boost::python::type_id<boost::python::tuple>())
|
||||
).m_class_object = &PyTuple_Type;
|
||||
}
|
||||
}register_tuple_pytype_ptr_;
|
||||
|
||||
|
||||
}}} // namespace boost::python
|
@ -1,66 +0,0 @@
|
||||
// Copyright David Abrahams 2004. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/wrapper.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
override wrapper_base::get_override(
|
||||
char const* name
|
||||
, PyTypeObject* class_object
|
||||
) const
|
||||
{
|
||||
if (this->m_self)
|
||||
{
|
||||
if (handle<> m = handle<>(
|
||||
python::allow_null(
|
||||
::PyObject_GetAttrString(
|
||||
this->m_self, const_cast<char*>(name))))
|
||||
)
|
||||
{
|
||||
PyObject* borrowed_f = 0;
|
||||
|
||||
if (
|
||||
PyMethod_Check(m.get())
|
||||
&& ((PyMethodObject*)m.get())->im_self == this->m_self
|
||||
&& class_object->tp_dict != 0
|
||||
)
|
||||
{
|
||||
borrowed_f = ::PyDict_GetItemString(
|
||||
class_object->tp_dict, const_cast<char*>(name));
|
||||
|
||||
|
||||
}
|
||||
if (borrowed_f != ((PyMethodObject*)m.get())->im_func)
|
||||
return override(m);
|
||||
}
|
||||
}
|
||||
return override(handle<>(detail::none()));
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
namespace converter
|
||||
{
|
||||
PyObject* BOOST_PYTHON_DECL do_polymorphic_ref_to_python(
|
||||
python::detail::wrapper_base const volatile* x, type_info src
|
||||
)
|
||||
{
|
||||
if (x == 0)
|
||||
{
|
||||
::PyErr_Format(
|
||||
PyExc_TypeError
|
||||
, "Attempting to returning pointer or reference to instance of %s\n"
|
||||
"for which no corresponding Python object exists. Wrap this function"
|
||||
"with a return return value policy"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}} // namespace boost::python::detail
|
@ -1,18 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="boost" version="1.67.0.0" targetFramework="native" />
|
||||
<package id="boost_atomic-src" version="1.67.0.0" targetFramework="native" />
|
||||
<package id="boost_chrono-src" version="1.67.0.0" targetFramework="native" />
|
||||
<package id="boost_date_time-src" version="1.67.0.0" targetFramework="native" />
|
||||
<package id="boost_regex-src" version="1.67.0.0" targetFramework="native" />
|
||||
<package id="boost_system-src" version="1.67.0.0" targetFramework="native" />
|
||||
<package id="boost_thread-src" version="1.67.0.0" targetFramework="native" />
|
||||
<package id="Python27" version="2.7.6" targetFramework="Native" />
|
||||
<package id="Python35" version="3.5.1.1" targetFramework="Native" />
|
||||
<package id="Python36" version="3.6.0" targetFramework="Native" />
|
||||
<package id="Python37" version="1.0.0.1" targetFramework="Native" />
|
||||
<package id="Python38" version="3.8.0" targetFramework="Native" />
|
||||
<package id="Python39" version="3.9.0" targetFramework="Native" />
|
||||
<package id="clang-cmake" version="6.0.0.1" targetFramework="Native" />
|
||||
<package id="llvm-cmake" version="6.0.0.1" targetFramework="Native" />
|
||||
<package id="python2" version="2.7.18" allowedVersions="[2.7.12,2.8.0)" targetFramework="native" />
|
||||
<package id="python2x86" version="2.7.18" allowedVersions="[2.7.12,2.8.0)" targetFramework="native" />
|
||||
<package id="python" version="3.13.1" allowedVersions="[3.5.2,3.14.0)" targetFramework="native" />
|
||||
<package id="pythonx86" version="3.13.1" allowedVersions="[3.5.2,3.14.0)" targetFramework="native" />
|
||||
</packages>
|
||||
|
2033
pykd/pykd.vcxproj
2033
pykd/pykd.vcxproj
File diff suppressed because it is too large
Load Diff
@ -131,186 +131,6 @@
|
||||
<ClCompile Include="pytagged.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_atomic-src.lockpool.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_chrono-src.chrono.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_chrono-src.process_cpu_clocks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_chrono-src.thread_clock.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\gregorian\boost_date_time-src.gregorian.date_generators.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\gregorian\boost_date_time-src.gregorian.gregorian_types.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\gregorian\boost_date_time-src.gregorian.greg_month.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\gregorian\boost_date_time-src.gregorian.greg_weekday.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\posix_time\boost_date_time-src.posix_time.posix_time_types.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.cpp_regex_traits.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.cregex.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.c_regex_traits.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.fileiter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.icu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.instances.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.posix_api.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.regex.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.regex_debug.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.regex_raw_buffer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.regex_traits_defaults.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.static_mutex.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.w32_regex_traits.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.wc_regex_traits.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.wide_posix_api.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.winstances.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_system-src.error_code.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\win32\boost_thread-src.win32.thread.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\win32\boost_thread-src.win32.thread_primitives.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\win32\boost_thread-src.win32.tss_dll.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\win32\boost_thread-src.win32.tss_pe.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_thread-src.future.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_thread-src.tss_null.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.dict.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.errors.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.exec.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.import.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.list.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.long.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.module.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.object_operators.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.object_protocol.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.slice.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.str.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.tuple.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\boost_python-src.wrapper.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\converter\boost_python-src.converter.arg_to_python_base.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\converter\boost_python-src.converter.builtin_converters.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\converter\boost_python-src.converter.from_python.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\converter\boost_python-src.converter.registry.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\converter\boost_python-src.converter.type_id.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\object\boost_python-src.object.class.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\object\boost_python-src.object.enum.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\object\boost_python-src.object.function.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\object\boost_python-src.object.function_doc_signature.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\object\boost_python-src.object.inheritance.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\object\boost_python-src.object.iterator.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\object\boost_python-src.object.life_support.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\object\boost_python-src.object.pickle_support.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="boost.python\object\boost_python-src.object.stl_iterator.cpp">
|
||||
<Filter>boost.python</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\lib\native\src\boost_regex-src.usinstances.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="pykd.def">
|
||||
|
1
pykd_ext
Submodule
1
pykd_ext
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit e78e6c8f691be922ea1ac9e98998ebcc4488c93d
|
1
setup/VERSION.template
Normal file
1
setup/VERSION.template
Normal file
@ -0,0 +1 @@
|
||||
0.3.4.15
|
@ -1,31 +1,19 @@
|
||||
py -2.7 setup.py bdist_zip --plat-name=win32
|
||||
py -2.7 setup.py bdist_zip --plat-name=win-amd64
|
||||
py -2.7 setup.py bdist_wheel --plat-name=win32 --python-tag=cp27
|
||||
py -2.7 setup.py bdist_wheel --plat-name=win-amd64 --python-tag=cp27
|
||||
@ECHO OFF
|
||||
SETLOCAL EnableDelayedExpansion
|
||||
|
||||
py -3.5 setup.py bdist_zip --plat-name=win32
|
||||
py -3.5 setup.py bdist_zip --plat-name=win-amd64
|
||||
py -3.5 setup.py bdist_wheel --plat-name=win32 --python-tag=cp35
|
||||
py -3.5 setup.py bdist_wheel --plat-name=win-amd64 --python-tag=cp35
|
||||
set py_list=2.7 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13
|
||||
set plat_list=win32 x64
|
||||
|
||||
py -3.6 setup.py bdist_zip --plat-name=win32
|
||||
py -3.6 setup.py bdist_zip --plat-name=win-amd64
|
||||
py -3.6 setup.py bdist_wheel --plat-name=win32 --python-tag=cp36
|
||||
py -3.6 setup.py bdist_wheel --plat-name=win-amd64 --python-tag=cp36
|
||||
REM Build wheel and zip
|
||||
REM py -<py version> setup.py bdist_wheel --plat-name=<plat-name> [bdist_zip]
|
||||
REM py -<py version> setup.py bdist_wheel --plat-name=<plat-name> [--build-base=build_dir] [--dist-dir=bdist_dir] [--egg-base=egg_dir] [bdist_zip]
|
||||
|
||||
py -3.7 setup.py bdist_zip --plat-name=win32
|
||||
py -3.7 setup.py bdist_zip --plat-name=win-amd64
|
||||
py -3.7 setup.py bdist_wheel --plat-name=win32 --python-tag=cp37
|
||||
py -3.7 setup.py bdist_wheel --plat-name=win-amd64 --python-tag=cp37
|
||||
|
||||
py -3.8 setup.py bdist_zip --plat-name=win32
|
||||
py -3.8 setup.py bdist_zip --plat-name=win-amd64
|
||||
py -3.8 setup.py bdist_wheel --plat-name=win32 --python-tag=cp38
|
||||
py -3.8 setup.py bdist_wheel --plat-name=win-amd64 --python-tag=cp38
|
||||
|
||||
py -3.9 setup.py bdist_zip --plat-name=win32
|
||||
py -3.9 setup.py bdist_zip --plat-name=win-amd64
|
||||
py -3.9 setup.py bdist_wheel --plat-name=win32 --python-tag=cp39
|
||||
py -3.9 setup.py bdist_wheel --plat-name=win-amd64 --python-tag=cp39
|
||||
|
||||
py setup.py bdist_pdb
|
||||
for %%a in (%py_list%) do (
|
||||
for %%b in (%plat_list%) do (
|
||||
set py_ver=%%a
|
||||
set plat=%%b
|
||||
py -!py_ver! -m pip install --user gitpython setuptools wheel
|
||||
py -!py_ver! setup.py bdist_wheel --plat-name=!plat! bdist_zip
|
||||
)
|
||||
)
|
||||
exit
|
||||
|
270
setup/setup.py
270
setup/setup.py
@ -1,131 +1,177 @@
|
||||
from setuptools import setup
|
||||
from wheel.bdist_wheel import bdist_wheel
|
||||
|
||||
import os
|
||||
import os
|
||||
import shutil
|
||||
import zipfile
|
||||
import sys
|
||||
import itertools
|
||||
import argparse
|
||||
import re
|
||||
import setuptools
|
||||
import git
|
||||
|
||||
if sys.version_info.major == 2:
|
||||
import pathlib2
|
||||
|
||||
_name = "pykd"
|
||||
_desc = "python windbg extension"
|
||||
_version = '0.3.4.15'
|
||||
|
||||
def getReleaseSrc():
|
||||
return 'Release_%d.%d' % sys.version_info[0:2]
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--plat-name', choices = ['win32', 'win-amd64', 'x86', 'x64'], required = True, type = str.lower)
|
||||
parser.add_argument('--build-base', type = str, required = False)
|
||||
parser.add_argument('--dist-dir', type = str, required = False)
|
||||
parser.add_argument('--egg-base', type = str, required = False)
|
||||
args, unkonwn_args = parser.parse_known_args()
|
||||
|
||||
if "bdist_wheel" in sys.argv:
|
||||
|
||||
# remove build catalog
|
||||
build_dir = os.path.join(os.path.curdir, 'build' )
|
||||
if os.path.exists(build_dir):
|
||||
shutil.rmtree(build_dir)
|
||||
|
||||
# make package catalog
|
||||
package_dir = os.path.join(os.path.curdir, _name )
|
||||
if os.path.exists(package_dir):
|
||||
shutil.rmtree(package_dir)
|
||||
os.mkdir(package_dir)
|
||||
|
||||
shutil.copy("__init__.py", package_dir)
|
||||
|
||||
bin_dir = os.path.join( os.path.curdir, '..', 'kdlibcpp/bin')
|
||||
pykd_dir = os.path.join( os.path.curdir, '..', 'out')
|
||||
if "--plat-name=win32" in sys.argv:
|
||||
bin_dir = os.path.join( bin_dir, 'x86')
|
||||
pykd_dir = os.path.join(pykd_dir, 'Win32', getReleaseSrc())
|
||||
elif "--plat-name=win-amd64" in sys.argv:
|
||||
bin_dir = os.path.join( bin_dir, 'x64')
|
||||
pykd_dir = os.path.join(pykd_dir, 'X64', getReleaseSrc())
|
||||
platform = ''
|
||||
platform_alt = ''
|
||||
configuration = 'Release'
|
||||
if (args.plat_name == 'win32') or (args.plat_name == 'x86'):
|
||||
args.plat_name = 'win32'
|
||||
platform = 'win32'
|
||||
platform_alt = 'x86'
|
||||
elif (args.plat_name == 'win-amd64') or (args.plat_name == 'x64'):
|
||||
args.plat_name = 'win-amd64'
|
||||
platform = 'x64'
|
||||
platform_alt = 'x64'
|
||||
else:
|
||||
assert(0)
|
||||
print("Unsupported platform %s" %(args.plat_name))
|
||||
exit
|
||||
|
||||
assert(os.path.isdir(bin_dir))
|
||||
python_tag = "cp%d%d" %(sys.version_info.major, sys.version_info.minor)
|
||||
|
||||
for binFile in [ f for f in os.listdir(bin_dir) if not os.path.isdir(f) ]:
|
||||
shutil.copy( os.path.join(bin_dir, binFile), os.path.join(package_dir, binFile) )
|
||||
dir_solution = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
shutil.copy( os.path.join(pykd_dir, 'pykd.pyd'), os.path.join(package_dir, 'pykd.pyd') )
|
||||
_version = ''
|
||||
|
||||
setup(
|
||||
name = _name,
|
||||
version = _version,
|
||||
description = _desc,
|
||||
# cmdclass = { 'bdist_wheel' : bdist_wheel },
|
||||
packages = ['pykd'],
|
||||
package_dir = {'pykd': package_dir},
|
||||
package_data = { 'pykd' :["*.pyd", "*.dll"]},
|
||||
include_package_data=True,
|
||||
zip_safe = False
|
||||
# Using VERSION file on releaase branch
|
||||
if os.path.isfile(os.path.join(os.path.dirname(__file__), 'VERSION')):
|
||||
with open(os.path.join(os.path.dirname(__file__), 'VERSION'), 'r') as verf:
|
||||
_version = verf.readline()
|
||||
|
||||
# Using versions from pykdver.h and branch HEAD
|
||||
if _version == '':
|
||||
versions = ['', '', '', '']
|
||||
if os.path.isfile(os.path.join(dir_solution, 'pykd', 'pykdver.h')):
|
||||
with open(os.path.join(os.path.join(dir_solution, 'pykd', 'pykdver.h')), 'r') as verf:
|
||||
lines = verf.readlines()
|
||||
for line in lines:
|
||||
ver_raw_match = re.findall(r"^#define\s*PYKD_VERSION_MAJOR\s*(.*)$", line)
|
||||
if (len(ver_raw_match)):
|
||||
versions[0] = ver_raw_match[0]
|
||||
continue
|
||||
ver_raw_match = re.findall(r"^#define\s*PYKD_VERSION_MINOR\s*(.*)$", line)
|
||||
if (len(ver_raw_match)):
|
||||
versions[1] = ver_raw_match[0]
|
||||
continue
|
||||
ver_raw_match = re.findall(r"^#define\s*PYKD_VERSION_SUBVERSION\s*(.*)$", line)
|
||||
if (len(ver_raw_match)):
|
||||
versions[2] = ver_raw_match[0]
|
||||
continue
|
||||
ver_raw_match = re.findall(r"^#define\s*PYKD_VERSION_BUILDNO\s*(.*)$", line)
|
||||
if (len(ver_raw_match)):
|
||||
versions[3] = ver_raw_match[0]
|
||||
continue
|
||||
|
||||
_version = "%s.%s.%s.%s+g" % (versions[0], versions[1], versions[2], versions[3])
|
||||
|
||||
try:
|
||||
repo = git.Repo(dir_solution)
|
||||
_version = "%s%s" % (_version, repo.git.rev_parse(repo.head, short = True))
|
||||
except:
|
||||
print("Skip using HEAD SHA as non git repo")
|
||||
|
||||
dir_dbgsdk_bin = os.path.join(dir_solution, 'kdlibcpp', 'WinDbgExt', 'bin', platform_alt)
|
||||
if not os.path.exists(dir_dbgsdk_bin):
|
||||
print("DbgSDK bin path %s doesn't exist" %(dir_dbgsdk_bin))
|
||||
sys.exit()
|
||||
|
||||
dir_pykd_bin = os.path.join(dir_solution, 'Out', platform, "%s_%d.%d" %(configuration, sys.version_info.major, sys.version_info.minor))
|
||||
if not os.path.exists(os.path.join(dir_pykd_bin, 'pykd.pyd')):
|
||||
print("pykd.pyd doesn't exist in %s" %(dir_pykd_bin))
|
||||
sys.exit()
|
||||
|
||||
if args.build_base is not None:
|
||||
dir_build_base = args.build_base
|
||||
else:
|
||||
dir_build_base = os.path.join(dir_solution, 'Obj', 'Wheel', platform, "%s_%d.%d" %(configuration, sys.version_info.major, sys.version_info.minor), 'setuptools')
|
||||
|
||||
if args.dist_dir is not None:
|
||||
dir_dist_wheel = args.dist_dir
|
||||
else:
|
||||
dir_dist_wheel = dir_pykd_bin
|
||||
|
||||
if args.egg_base is not None:
|
||||
dir_egg_base = args.egg_base
|
||||
else:
|
||||
dir_egg_base = dir_build_base
|
||||
|
||||
dir_wheel_package = os.path.join(dir_build_base, _name)
|
||||
|
||||
if os.path.exists(dir_build_base):
|
||||
shutil.rmtree(dir_build_base)
|
||||
if sys.version_info.major == 2:
|
||||
pathlib2.Path(dir_build_base).mkdir(exist_ok = True, parents = True)
|
||||
else:
|
||||
os.makedirs(dir_build_base, exist_ok = True)
|
||||
|
||||
if os.path.exists(dir_wheel_package):
|
||||
shutil.rmtree(dir_wheel_package)
|
||||
if sys.version_info.major == 2:
|
||||
pathlib2.Path(dir_wheel_package).mkdir(exist_ok = True, parents = True)
|
||||
else:
|
||||
os.makedirs(dir_wheel_package, exist_ok = True)
|
||||
|
||||
print("Using DbgSDK from %s" %(dir_dbgsdk_bin))
|
||||
print("Using pykd binary from %s" %(dir_pykd_bin))
|
||||
print("Using build directory as %s" %(dir_build_base))
|
||||
print("Using egg info directory as %s" %(dir_egg_base))
|
||||
print("Using Wheel output directory as %s" %(dir_dist_wheel))
|
||||
|
||||
shutil.copy2(os.path.join(dir_solution, 'setup', '__init__.py'), dir_wheel_package)
|
||||
shutil.copy2(os.path.join(dir_pykd_bin, 'pykd.pyd'), dir_wheel_package)
|
||||
shutil.copy2(os.path.join(dir_solution, 'Obj', 'pykd', platform, "%s_%d.%d" %(configuration, sys.version_info.major, sys.version_info.minor), 'msdia140.dll'), dir_wheel_package)
|
||||
for dbgSdkBin in [ f for f in os.listdir(dir_dbgsdk_bin) if not os.path.isdir(f) ]:
|
||||
shutil.copy2(os.path.join(dir_dbgsdk_bin, dbgSdkBin), dir_wheel_package)
|
||||
|
||||
if 'bdist_wheel' in unkonwn_args:
|
||||
print("Building bdist_wheel ...")
|
||||
sys.argv = ['setup.py']
|
||||
sys.argv.append("build")
|
||||
sys.argv.append("--build-base=%s" %(dir_build_base))
|
||||
sys.argv.append("--plat-name=%s" %(args.plat_name))
|
||||
sys.argv.append("bdist_wheel")
|
||||
sys.argv.append("--dist-dir=%s" %(dir_dist_wheel))
|
||||
sys.argv.append("--plat-name=%s" %(args.plat_name))
|
||||
sys.argv.append("--python-tag=%s" %(python_tag))
|
||||
sys.argv.append("egg_info")
|
||||
sys.argv.append("--egg-base=%s" %(dir_egg_base))
|
||||
|
||||
setuptools.setup(
|
||||
name = _name,
|
||||
version = _version,
|
||||
description = _desc,
|
||||
packages = ['pykd'],
|
||||
package_dir = {'pykd': os.path.relpath(dir_wheel_package)},
|
||||
package_data = { 'pykd' :["*.pyd", "*.dll"]},
|
||||
include_package_data=True,
|
||||
zip_safe = False
|
||||
)
|
||||
|
||||
elif "bdist_zip" in sys.argv:
|
||||
if 'bdist_zip' in unkonwn_args:
|
||||
zip_name = "pykd-%s-%s-%s.zip" %(_version, python_tag, args.plat_name)
|
||||
print("Building bdist_zip %s ..." %(zip_name))
|
||||
with zipfile.ZipFile(os.path.join(dir_dist_wheel, zip_name), mode='w') as archive:
|
||||
print("zipped msdia140.dll")
|
||||
archive.write(os.path.join(dir_solution, 'Obj', 'pykd', platform, "%s_%d.%d" %(configuration, sys.version_info.major, sys.version_info.minor), 'msdia140.dll'), arcname = 'msdia140.dll', compress_type = zipfile.ZIP_DEFLATED)
|
||||
for dbgSdkBin in [ f for f in os.listdir(dir_dbgsdk_bin) if not os.path.isdir(f) ]:
|
||||
print("zipped %s" %(dbgSdkBin))
|
||||
archive.write(os.path.join(dir_dbgsdk_bin, dbgSdkBin), arcname = dbgSdkBin, compress_type = zipfile.ZIP_DEFLATED)
|
||||
print("zipped pykd.pyd")
|
||||
archive.write(os.path.join(dir_pykd_bin, 'pykd.pyd'), arcname = 'pykd.pyd', compress_type = zipfile.ZIP_DEFLATED)
|
||||
print("zipped pykd.pdb")
|
||||
archive.write(os.path.join(dir_pykd_bin, 'pykd.pdb'), arcname = 'pykd.pdb', compress_type = zipfile.ZIP_DEFLATED)
|
||||
|
||||
#make package catalog
|
||||
|
||||
if "--plat-name=win32" in sys.argv:
|
||||
plat_name="win32"
|
||||
elif "--plat-name=win-amd64" in sys.argv:
|
||||
plat_name="win-amd64"
|
||||
|
||||
package_dir = os.path.join(os.path.curdir, _name )
|
||||
if os.path.exists(package_dir):
|
||||
shutil.rmtree(package_dir)
|
||||
os.mkdir(package_dir)
|
||||
|
||||
bin_dir = os.path.join( os.path.curdir, '..', 'kdlibcpp/bin')
|
||||
pykd_dir = os.path.join( os.path.curdir, '..', 'out')
|
||||
if plat_name=="win32":
|
||||
bin_dir = os.path.join( bin_dir, 'x86')
|
||||
pykd_dir = os.path.join(pykd_dir, 'Win32', getReleaseSrc())
|
||||
elif plat_name=="win-amd64":
|
||||
bin_dir = os.path.join( bin_dir, 'x64')
|
||||
pykd_dir = os.path.join(pykd_dir, 'X64', getReleaseSrc())
|
||||
else:
|
||||
assert(0)
|
||||
|
||||
pyver="%d%d" % sys.version_info[0:2]
|
||||
|
||||
zip_str = "pykd-%s-cp%s-%s" % ( _version, pyver, plat_name )
|
||||
zip_name = zip_str + ".zip"
|
||||
|
||||
assert(os.path.isdir(bin_dir))
|
||||
|
||||
for binFile in [ f for f in os.listdir(bin_dir) if not os.path.isdir(f) ]:
|
||||
shutil.copy( os.path.join(bin_dir, binFile), os.path.join(package_dir, binFile) )
|
||||
|
||||
shutil.copy( os.path.join(pykd_dir, 'pykd.pyd'), os.path.join(package_dir, 'pykd.pyd') )
|
||||
|
||||
dist_dir = os.path.join(os.path.curdir, 'dist')
|
||||
if not os.path.exists(dist_dir):
|
||||
os.mkdir(dist_dir)
|
||||
|
||||
with zipfile.ZipFile(os.path.join(os.path.curdir, 'dist', zip_name), mode='w' ) as archive:
|
||||
for srcFile in os.listdir(package_dir):
|
||||
print( "zipped %s" % (srcFile) )
|
||||
archive.write( os.path.join(package_dir, srcFile), compress_type = zipfile.ZIP_DEFLATED)
|
||||
|
||||
print("OK")
|
||||
|
||||
elif "bdist_pdb" in sys.argv:
|
||||
|
||||
#make pdb archive
|
||||
pyVersion = ('2.7', '3.5', '3.6', '3.7', '3.8', '3.9')
|
||||
platform = ('Win32', 'x64')
|
||||
|
||||
pdbFiles = [ os.path.join( platform, 'Release_' + version, 'pykd.pdb') for version, platform in itertools.product( pyVersion, platform ) ]
|
||||
|
||||
zip_name = "pykd-%s-symbols.zip" % _version
|
||||
|
||||
with zipfile.ZipFile(os.path.join(os.path.curdir, 'dist', zip_name), mode='w' ) as archive:
|
||||
for pdbFile in pdbFiles:
|
||||
print( "zipped %s" % (pdbFile) )
|
||||
archive.write( os.path.join(os.path.curdir, '..', 'out', pdbFile), pdbFile, compress_type = zipfile.ZIP_DEFLATED)
|
||||
|
||||
#pdbFileList = [ os.path.join( os.path.curdir, '..', 'out', fileName) for fileName in (
|
||||
|
||||
|
||||
pass
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user