mirror of https://github.com/KLayout/klayout.git
Merge branch 'master' into wip2
This commit is contained in:
commit
8da6a131e8
|
|
@ -1,39 +1,37 @@
|
|||
Relevant KLayout version: 0.28.6<br>
|
||||
Relevant KLayout version: 0.28.13<br>
|
||||
Author: Kazzz-S<br>
|
||||
Last modified: 2023-03-19<br>
|
||||
Last modified: 2023-11-11<br>
|
||||
|
||||
# 1. Introduction
|
||||
This directory **`macbuild`** contains various files required for building KLayout (http://www.klayout.de/) version 0.28.6 or later for different 64-bit macOS, including:
|
||||
* Catalina (10.15.7) : the primary development environment
|
||||
* Big Sur (11.x) : experimental; Apple (M1|M2) chip is not tested since the author does not own an (M1|M2) Mac
|
||||
* Monterey (12.x) : -- ditto --
|
||||
* Ventura (13.x) : -- ditto --
|
||||
This directory **`macbuild`** contains various files required for building KLayout (http://www.klayout.de/) version 0.28.13 or later for different 64-bit macOS, including:
|
||||
* Monterey (12.x) : the primary development environment
|
||||
* Ventura (13.x) : experimental
|
||||
* Sonoma (14.x) : -- ditto --
|
||||
|
||||
Building KLayout for the previous operating systems listed below should still be possible. <br>
|
||||
However, they are not actively supported, and DMG packages are not provided.
|
||||
Building KLayout for the previous operating systems listed below has been discontinued.<br>
|
||||
Pre-built DMG packages are also not provided.
|
||||
* Big Sur (11.7.10)
|
||||
* Catalina (10.15.7)
|
||||
* Mojave (10.14)
|
||||
* High Sierra (10.13)
|
||||
* Sierra (10.12)
|
||||
* El Capitan (10.11)
|
||||
|
||||
Throughout this document, the primary target machine is **Intel x86_64** with **macOS Catalina**.<br>
|
||||
A **((Notes))** marker indicates special notes for specific operating systems.
|
||||
Throughout this document, the primary target machine is **Intel x86_64** with **macOS Monterey**.<br>
|
||||
All Apple (M1|M2|M3) chips are still untested, as the author does not own an (M1|M2|M3) Mac.<br>
|
||||
|
||||
# 2. Qt Frameworks
|
||||
**((Notes))** For **Catalina**
|
||||
|
||||
The default Qt framework is "Qt5" from MacPorts (https://www.macports.org/), which is usually located under:
|
||||
```
|
||||
/opt/local/libexec/qt5/
|
||||
```
|
||||
|
||||
**((Notes))** For **Big Sur**, **Monterey**, and **Ventura**
|
||||
|
||||
The default Qt framework is "Qt5" from Homebrew (https://brew.sh/), which is usually located under:
|
||||
```
|
||||
/usr/local/opt/qt@5/
|
||||
```
|
||||
|
||||
If you prefer **MacPorts** (https://www.macports.org/), "Qt5" is usually located under:
|
||||
```
|
||||
/opt/local/libexec/qt5/
|
||||
```
|
||||
|
||||
You can also choose "Qt5" from Anaconda3 (https://www.anaconda.com/), which is usually located under:
|
||||
```
|
||||
$HOME/opt/anaconda3/pkgs/qt-{version}
|
||||
|
|
@ -46,91 +44,26 @@ If you have installed Anaconda3 under $HOME/opt/anaconda3/, make a symbolic link
|
|||
The migration work to "Qt6" is ongoing. You can try to use it; however, you will encounter some build and runtime errors.
|
||||
|
||||
# 3. Script language support: Ruby and Python
|
||||
Earlier, by default, supported script languages, i.e., Ruby and Python, were those standard ones bundled with the OS.<br>
|
||||
```
|
||||
$ /usr/bin/ruby -v
|
||||
ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin19]
|
||||
|
||||
$ /usr/bin/python --version
|
||||
Python 2.7.16
|
||||
```
|
||||
Note that this configuration for backward compatibility is possible only for macOS Catalina (10.15.7).<br>
|
||||
In contrast, Homebrew's Ruby 3.2 and Python 3.9 are the default environment for Big Sur, Monterey, and Ventura.<br>
|
||||
Since Python 2.7 is already deprecated, using MacPorts' or Homebrew's Ruby 3.2 and Python 3.9 are also recommended for Catalina.
|
||||
|
||||
The build script **`build4mac.py`** provides several possible combinations of Qt5, Ruy, and Python modules to accommodate such a slightly complex environment.<br>
|
||||
The build script **`build4mac.py`** provides several possible combinations of Qt5, Ruby, and Python modules to suit the user's needs and preferences.<br>
|
||||
Some typical use cases are described in Section 6.
|
||||
|
||||
# 4. Prerequisites
|
||||
You need to have the followings:
|
||||
* The latest Xcode and command-line tool kit compliant with each OS
|
||||
* Qt5 package from MacPorts, Homebrew, or Anaconda3
|
||||
* Optionally, Ruby and Python packages from MacPorts, Homebrew, or Anaconda3
|
||||
* Qt5 package from Homebrew, MacPorts, or Anaconda3
|
||||
* Optionally, Ruby and Python packages from Homebrew, MacPorts, or Anaconda3
|
||||
#### For matching versions of Ruby and Python, please also refer to `build4mac_env.py`.
|
||||
|
||||
# 5. Command-line options of **`build4mac.py`**
|
||||
**((Notes))** For **Catalina**
|
||||
|
||||
**`build4mac.py`** is the top level Python script for for building KLayout for a macOS.
|
||||
The operating system type is detected automatically.
|
||||
|
||||
```
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
<< Usage of 'build4mac.py' >>
|
||||
for building KLayout 0.28.6 or later on different Apple macOS / Mac OSX platforms.
|
||||
|
||||
$ [python] ./build4mac.py
|
||||
option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value
|
||||
--------------------------------------------------------------------------------------+---------------
|
||||
[-q|--qt <type>] : case-insensitive type=['Qt5MacPorts', 'Qt5Brew', 'Qt5Ana3', | qt5macports
|
||||
: 'Qt6MacPorts', 'Qt6Brew'] |
|
||||
: Qt5MacPorts: use Qt5 from MacPorts |
|
||||
: Qt5Brew: use Qt5 from Homebrew |
|
||||
: Qt5Ana3: use Qt5 from Anaconda3 |
|
||||
: Qt6MacPorts: use Qt6 from MacPorts (*) |
|
||||
: Qt6Brew: use Qt6 from Homebrew (*) |
|
||||
: (*) migration to Qt6 is ongoing |
|
||||
[-r|--ruby <type>] : case-insensitive type=['nil', 'Sys', 'MP31', 'HB31', 'Ana3', | sys
|
||||
: 'MP32', HB32'] |
|
||||
: nil: don't bind Ruby |
|
||||
: Sys: use OS-bundled Ruby [2.0 - 2.6] depending on OS |
|
||||
: MP31: use Ruby 3.1 from MacPorts |
|
||||
: HB31: use Ruby 3.1 from Homebrew |
|
||||
: Ana3: use Ruby 3.1 from Anaconda3 |
|
||||
: MP32: use Ruby 3.2 from MacPorts |
|
||||
: HB32: use Ruby 3.2 from Homebrew |
|
||||
[-p|--python <type>] : case-insensitive type=['nil', 'Sys', 'MP38', 'HB38', 'Ana3', | sys
|
||||
: 'MP39', HB39', 'HBAuto'] |
|
||||
: nil: don't bind Python |
|
||||
: Sys: use OS-bundled Python 2.7 up to Catalina |
|
||||
: MP38: use Python 3.8 from MacPorts |
|
||||
: HB38: use Python 3.8 from Homebrew |
|
||||
: Ana3: use Python 3.9 from Anaconda3 |
|
||||
: MP39: use Python 3.9 from MacPorts |
|
||||
: HB39: use Python 3.9 from Homebrew |
|
||||
: HBAuto: use the latest Python 3.x auto-detected from Homebrew |
|
||||
[-P|--buildPymod] : build and deploy Pymod (*.whl and *.egg) for LW-*.dmg | disabled
|
||||
[-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled
|
||||
[-u|--noqtuitools] : don't include uitools in Qt binding | disabled
|
||||
[-m|--make <option>] : option passed to 'make' | '--jobs=4'
|
||||
[-d|--debug] : enable debug mode build | disabled
|
||||
[-c|--checkcom] : check command-line and exit without building | disabled
|
||||
[-y|--deploy] : deploy executables and dylibs, including Qt's Frameworks | disabled
|
||||
[-Y|--DEPLOY] : deploy executables and dylibs for those who built KLayout | disabled
|
||||
: from the source code and use the tools in the same machine |
|
||||
: ! After confirmation of the successful build of 'klayout.app', |
|
||||
: rerun this script with BOTH: |
|
||||
: 1) the same options used for building AND |
|
||||
: 2) <-y|--deploy> OR <-Y|--DEPLOY> |
|
||||
: optionally with [-v|--verbose <0-3>] |
|
||||
[-v|--verbose <0-3>] : verbose level of `macdeployqt' (effective with -y only) | 1
|
||||
: 0 = no output, 1 = error/warning (default), |
|
||||
: 2 = normal, 3 = debug |
|
||||
[-?|--?] : print this usage and exit; in zsh, quote like '-?' or '--?' | disabled
|
||||
-----------------------------------------------------------------------------------------+---------------
|
||||
```
|
||||
|
||||
**((Notes))** For **Big Sur**, **Monterey**, and **Ventura**
|
||||
```
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
<< Usage of 'build4mac.py' >>
|
||||
for building KLayout 0.28.6 or later on different Apple macOS / Mac OSX platforms.
|
||||
for building KLayout 0.28.13 or later on different Apple macOS platforms.
|
||||
|
||||
$ [python] ./build4mac.py
|
||||
option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value
|
||||
|
|
@ -143,28 +76,26 @@ $ [python] ./build4mac.py
|
|||
: Qt6MacPorts: use Qt6 from MacPorts (*) |
|
||||
: Qt6Brew: use Qt6 from Homebrew (*) |
|
||||
: (*) migration to Qt6 is ongoing |
|
||||
[-r|--ruby <type>] : case-insensitive type=['nil', 'Sys', 'MP31', 'HB31', 'Ana3', | hb32
|
||||
: 'MP32', HB32'] |
|
||||
[-r|--ruby <type>] : case-insensitive type=['nil', 'Sys', 'MP32', 'HB32', 'Ana3'] | hb32
|
||||
: nil: don't bind Ruby |
|
||||
: Sys: use OS-bundled Ruby [2.0 - 2.6] depending on OS |
|
||||
: MP31: use Ruby 3.1 from MacPorts |
|
||||
: HB31: use Ruby 3.1 from Homebrew |
|
||||
: Ana3: use Ruby 3.1 from Anaconda3 |
|
||||
: Sys: use [Sonoma|Ventura|Monterey]-bundled Ruby 2.6 |
|
||||
: MP32: use Ruby 3.2 from MacPorts |
|
||||
: HB32: use Ruby 3.2 from Homebrew |
|
||||
[-p|--python <type>] : case-insensitive type=['nil', 'Sys', 'MP38', 'HB38', 'Ana3', | hb39
|
||||
: 'MP39', HB39', 'HBAuto'] |
|
||||
: HB32: use Ruby 3.2 from Homebrew |
|
||||
: Ana3: use Ruby 3.1 from Anaconda3 |
|
||||
[-p|--python <type>] : case-insensitive type=['nil', 'MP311', 'HB311', 'Ana3', | hb311
|
||||
: 'MP39', 'hb311', 'HBAuto'] |
|
||||
: nil: don't bind Python |
|
||||
: Sys: use OS-bundled Python 2.7 up to Catalina |
|
||||
: MP38: use Python 3.8 from MacPorts |
|
||||
: HB38: use Python 3.8 from Homebrew |
|
||||
: Ana3: use Python 3.9 from Anaconda3 |
|
||||
: MP39: use Python 3.9 from MacPorts |
|
||||
: HB39: use Python 3.9 from Homebrew |
|
||||
: MP311: use Python 3.11 from MacPorts |
|
||||
: HB311: use Python 3.11 from Homebrew |
|
||||
: Ana3: use Python 3.11 from Anaconda3 |
|
||||
: MP39: use Python 3.9 from MacPorts (+) |
|
||||
: hb311: use Python 3.9 from Homebrew (+) |
|
||||
: (+) for the backward compatibility tests |
|
||||
: HBAuto: use the latest Python 3.x auto-detected from Homebrew |
|
||||
[-P|--buildPymod] : build and deploy Pymod (*.whl and *.egg) for LW-*.dmg | disabled
|
||||
[-P|--buildPymod] : build and deploy Pymod (*.whl) for LW-*.dmg | disabled
|
||||
[-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled
|
||||
[-u|--noqtuitools] : don't include uitools in Qt binding | disabled
|
||||
[-g|--nolibgit2] : don't include libgit2 for Git package support | disabled
|
||||
[-m|--make <option>] : option passed to 'make' | '--jobs=4'
|
||||
[-d|--debug] : enable debug mode build | disabled
|
||||
[-c|--checkcom] : check command-line and exit without building | disabled
|
||||
|
|
@ -184,81 +115,27 @@ $ [python] ./build4mac.py
|
|||
```
|
||||
|
||||
# 6. Use-cases
|
||||
In this section, the actual file and directory names are those obtained on macOS Catalina.<br>
|
||||
In this section, the actual file and directory names are those obtained on macOS Monterey.<br>
|
||||
On different OS, those names differ accordingly.
|
||||
|
||||
### 6A. Standard build using the OS-bundled Ruby and Python **((Notes))** only for Catalina
|
||||
0. Install MacPorts, then install Qt5 by
|
||||
```
|
||||
$ sudo port install coreutils
|
||||
$ sudo port install findutils
|
||||
$ sudo port install qt5
|
||||
```
|
||||
1. Invoke **`build4mac.py`** with the default options: **((Notes))** only for Catalina
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ ./build4mac.py
|
||||
```
|
||||
2. Confirm successful build (it will take about one hour, depending on your machine spec).
|
||||
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-y" to deploy executables and libraries (including Qt's framework) under **`klayout.app`** bundle.<br>
|
||||
The buddy command-line tools (strm*) will also be deployed in this step.
|
||||
```
|
||||
$ ./build4mac.py -y
|
||||
```
|
||||
The application bundle **`klayout.app`** is located under:<br>
|
||||
**`ST-qt5MP.pkg.macos-Catalina-release-RsysPsys`** directory, where the three name parts below are important.
|
||||
* "ST-" means that this is a standard package (LW-, HW-, and EX- are other possibilities explained below).
|
||||
* "qt5MP" means that Qt5 from MacPorts is used.
|
||||
* "RsysPsys" means that Ruby is OS-bundled; Python is OS-bundled.
|
||||
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
|
||||
### 6A. Standard build using the OS-bundled Ruby and Python with MacPorts
|
||||
This build has been discontinued.
|
||||
|
||||
If you use the "-Y" option instead of the "-y" in Step-3, the Qt5 framework is NOT deployed in the application bundle.<br>
|
||||
Then the directory name will be **`LW-qt5MP.pkg.macos-Catalina-release-RsysPsys`**, where
|
||||
* "LW-" means that this is a lightweight package.
|
||||
|
||||
#### If you build KLayout from the source code AND run it on the same machine, the "-Y" option is highly recommended.
|
||||
|
||||
### 6B. Fully MacPorts-flavored build with MacPorts Ruby 3.2 and MacPorts Python 3.9
|
||||
0. Install MacPorts, then install Qt5, Ruby 3.2, and Python 3.9 by
|
||||
```
|
||||
$ sudo port install coreutils
|
||||
$ sudo port install findutils
|
||||
$ sudo port install qt5
|
||||
$ sudo port install ruby32
|
||||
$ sudo port install python39
|
||||
$ sudo port install py39-pip
|
||||
```
|
||||
1. Invoke **`build4mac.py`** with the following options:
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ ./build4mac.py -q qt5macports -r mp32 -p mp39
|
||||
```
|
||||
2. Confirm successful build (it will take about one hour, depending on your machine spec).
|
||||
3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
|
||||
The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.<br>
|
||||
If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
|
||||
|
||||
```
|
||||
$ ./build4mac.py -q qt5macports -r mp32 -p mp39 -Y
|
||||
```
|
||||
The application bundle **`klayout.app`** is located under:<br>
|
||||
**`LW-qt5MP.pkg.macos-Catalina-release-Rmp32Pmp39`** directory, where
|
||||
* "LW-" means this is a lightweight package.
|
||||
* "qt5MP" means that Qt5 from MacPorts is used.
|
||||
* "Rmp32Pmp39" means that Ruby is 3.2 from MacPorts; Python is 3.9 from MacPorts.
|
||||
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
|
||||
|
||||
### 6C. Fully Homebrew-flavored build with Homebrew Ruby 3.2 and Homebrew Python 3.9
|
||||
0. Install Homebrew, then install Qt5, Ruby 3.2, and Python 3.9 by
|
||||
### 6B. Fully Homebrew-flavored build with Homebrew Ruby 3.2 and Homebrew Python 3.11
|
||||
0. Install Homebrew, then install Qt5, Ruby 3.2, Python 3.11, and libgit2 by
|
||||
```
|
||||
$ brew install qt@5
|
||||
$ brew install ruby@3.2
|
||||
$ brew install python@3.9
|
||||
$ brew install python@3.11
|
||||
$ brew install libgit2
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ cd macbuild
|
||||
$ ./python3HB.py -v 3.11
|
||||
```
|
||||
1. Invoke **`build4mac.py`** with the following options: **((Notes))** These options are the default for Big Sur, Monterey, and Ventura.
|
||||
1. Invoke **`build4mac.py`** with the following options: **((Notes))** These options are the default values for Monterey, Ventura, and Sonoma.
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ ./build4mac.py -q qt5brew -r hb32 -p hb39
|
||||
$ ./build4mac.py -q qt5brew -r hb32 -p hb311
|
||||
```
|
||||
2. Confirm successful build (it will take about one hour, depending on your machine spec).
|
||||
3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
|
||||
|
|
@ -266,48 +143,85 @@ $ ./build4mac.py -q qt5brew -r hb32 -p hb39
|
|||
If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
|
||||
|
||||
```
|
||||
$ ./build4mac.py -q qt5brew -r hb32 -p hb39 -Y
|
||||
$ ./build4mac.py -q qt5brew -r hb32 -p hb311 -Y
|
||||
```
|
||||
The application bundle **`klayout.app`** is located under:<br>
|
||||
**`LW-qt5Brew.pkg.macos-Catalina-release-Rhb32Phb39`** directory, where
|
||||
**`LW-qt5Brew.pkg.macos-Monterey-release-Rhb32Phb311`** directory, where
|
||||
* "LW-" means this is a lightweight package.
|
||||
* "qt5Brew" means that Qt5 from Homebrew is used.
|
||||
* "Rhb32Phb39" means that Ruby is 3.2 from Homebrew; Python is 3.9 from Homebrew.
|
||||
* "Rhb32Phb311" means that Ruby is 3.2 from Homebrew; Python is 3.11 from Homebrew.
|
||||
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
|
||||
|
||||
### 6D. Partially Homebrew-flavored build with System Ruby and Homebrew Python 3.9
|
||||
0. Install Homebrew, then install Qt5 and Python 3.9 by
|
||||
### 6C. Partially Homebrew-flavored build with System Ruby and Homebrew Python 3.11
|
||||
0. Install Homebrew, then install Qt5, Python 3.11, and libgit2 by
|
||||
```
|
||||
$ brew install qt@5
|
||||
$ brew install python@3.9
|
||||
$ brew install python@3.11
|
||||
$ brew install libgit2
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ cd macbuild
|
||||
$ ./python3HB.py -v 3.11
|
||||
```
|
||||
1. Invoke **`build4mac.py`** with the following options:
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ ./build4mac.py -q qt5brew -r sys -p hb39
|
||||
$ ./build4mac.py -q qt5brew -r sys -p hb311
|
||||
```
|
||||
2. Confirm successful build (it will take about one hour, depending on your machine spec).
|
||||
3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-y" to deploy executables and libraries (including Qt and Python frameworks) under the **`klayout.app`** bundle.<br>
|
||||
The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.
|
||||
|
||||
```
|
||||
$ ./build4mac.py -q qt5brew -r sys -p hb39 -y
|
||||
$ ./build4mac.py -q qt5brew -r sys -p hb311 -y
|
||||
```
|
||||
The application bundle **`klayout.app`** is located under:<br>
|
||||
**`HW-qt5Brew.pkg.macos-Catalina-release-RsysPhb39`** directory, where
|
||||
**`HW-qt5Brew.pkg.macos-Monterey-release-RsysPhb311`** directory, where
|
||||
* "HW-" means this is a heavyweight package because both Qt5 and Python Frameworks are deployed.
|
||||
* "qt5Brew" means that Qt5 from Homebrew is used.
|
||||
* "RsysPhb39" means that Ruby is OS-bundled; Python is 3.9 from Homebrew.
|
||||
* "RsysPhb311" means that Ruby is OS-bundled; Python is 3.11 from Homebrew.
|
||||
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
|
||||
### Important
|
||||
So far, the deployment of Homebrew Ruby is not supported. <br>
|
||||
So far, the deployment of Homebrew Ruby is not supported.<br>
|
||||
Therefore, if you intend to use the "-y" option for deployment, you need to use the "-r sys" option for building.
|
||||
|
||||
### 6E. Fully Anaconda3-flavored build with Anaconda3 Ruby 3.1 and Anaconda3 Python 3.9
|
||||
0. Install Anaconda3, then install Ruby 3.1 by
|
||||
### 6D. Fully MacPorts-flavored build with MacPorts Ruby 3.2 and MacPorts Python 3.11
|
||||
0. Install MacPorts, then install Qt5, Ruby 3.2, Python 3.11, and libgit2 by
|
||||
```
|
||||
$ conda install ruby=3.1.2
|
||||
$ sudo port install coreutils
|
||||
$ sudo port install findutils
|
||||
$ sudo port install qt5
|
||||
$ sudo port install ruby32
|
||||
$ sudo port install python311
|
||||
$ sudo port install py311-pip
|
||||
$ sudo port install libgit2
|
||||
```
|
||||
1. Invoke **`build4mac.py`** with the following options:
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ ./build4mac.py -q qt5macports -r mp32 -p mp311
|
||||
```
|
||||
2. Confirm successful build (it will take about one hour, depending on your machine spec).
|
||||
3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
|
||||
The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.<br>
|
||||
If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
|
||||
|
||||
```
|
||||
$ ./build4mac.py -q qt5macports -r mp32 -p mp311 -Y
|
||||
```
|
||||
The application bundle **`klayout.app`** is located under:<br>
|
||||
**`LW-qt5MP.pkg.macos-Monterey-release-Rmp32Pmp311`** directory, where
|
||||
* "LW-" means this is a lightweight package.
|
||||
* "qt5MP" means that Qt5 from MacPorts is used.
|
||||
* "Rmp32Pmp311" means that Ruby is 3.2 from MacPorts; Python is 3.11 from MacPorts.
|
||||
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
|
||||
|
||||
### 6E. Fully Anaconda3-flavored build with Anaconda3 Ruby 3.1 and Anaconda3 Python 3.11
|
||||
0. Install Anaconda3 (Anaconda3-2023.09-0-MacOSX-x86_64.pkg), then install Ruby 3.1 and libgit2 by
|
||||
```
|
||||
$ conda install ruby=3.1.4
|
||||
$ conda install -c conda-forge libgit2
|
||||
```
|
||||
|
||||
1. Invoke **`build4mac.py`** with the following options:
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
|
|
@ -322,10 +236,10 @@ $ ./build4mac.py -q qt5ana3 -r ana3 -p ana3
|
|||
$ ./build4mac.py -q qt5ana3 -r ana3 -p ana3 -Y
|
||||
```
|
||||
The application bundle **`klayout.app`** is located under:<br>
|
||||
**`LW-qt5Ana3.pkg.macos-Catalina-release-Rana3Pana3`** directory, where
|
||||
**`LW-qt5Ana3.pkg.macos-Monterey-release-Rana3Pana3`** directory, where
|
||||
* "LW-" means this is a lightweight package.
|
||||
* "qt5Ana3" means that Qt5 from Anaconda3 is used.
|
||||
* "Rana3Pana3" means that Ruby (3.1) is from Anaconda3; Python (3.9) is from Anaconda3.
|
||||
* "Rana3Pana3" means that Ruby (3.1) is from Anaconda3; Python (3.11) is from Anaconda3.
|
||||
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
|
||||
5. You may have to set the `PYTHONHOME` environment variable like:
|
||||
```
|
||||
|
|
@ -333,14 +247,14 @@ export PYTHONHOME=$HOME/opt/anaconda3
|
|||
```
|
||||
|
||||
### 6F. Other combinations
|
||||
Logically, several module combinations other than 6A through 6E are possible, including `nil` choice.<br>
|
||||
Logically, several module combinations other than 6B through 6E are possible, including `nil` choice.<br>
|
||||
The resultant package directory name will begin with **`EX-`** (exceptional) if you choose such a combination.
|
||||
|
||||
----
|
||||
|
||||
# 7. Making a DMG installer
|
||||
You can make a DMG installer using another Python script **`makeDMG4mac.py`**.<br>
|
||||
This script requires a directory generated by **`build4mac.py`** with the [-y|-Y] option (refer to 6A through 6D).
|
||||
This script requires a directory generated by **`build4mac.py`** with the [-y|-Y] option (refer to 6B through 6E).
|
||||
|
||||
1. Make a symbolic link (if it does not exist) from the parent directory (where **`build.sh`** exists) to **`makeDMG4mac.py`**, that is,
|
||||
```
|
||||
|
|
@ -349,18 +263,18 @@ makeDMG4mac.py -> macbuild/makeDMG4mac.py
|
|||
2. Invoke **`makeDMG4mac.py`** with -p and -m options, for example,
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ ./makeDMG4mac.py -p LW-qt5MP.pkg.macos-Catalina-release-Rmp32Pmp39 -m
|
||||
$ ./makeDMG4mac.py -p LW-qt5MP.pkg.macos-Monterey-release-Rmp32Pmp311 -m
|
||||
```
|
||||
This command will generate the two files below:<br>
|
||||
* **`LW-klayout-0.28.6-macOS-Catalina-1-qt5MP-Rmp32Pmp39.dmg`** ---(1) the main DMG file
|
||||
* **`LW-klayout-0.28.6-macOS-Catalina-1-qt5MP-Rmp32Pmp39.dmg.md5`** ---(2) MD5-value text file
|
||||
* **`LW-klayout-0.28.13-macOS-Monterey-1-qt5MP-Rmp32Pmp311.dmg`** ---(1) the main DMG file
|
||||
* **`LW-klayout-0.28.13-macOS-Monterey-1-qt5MP-Rmp32Pmp311.dmg.md5`** ---(2) MD5-value text file
|
||||
|
||||
# Known issues
|
||||
Because we assume some specific versions of non-OS-standard Ruby and Python, updating MacPorts, Homebrew, or Anaconda3 may cause build- and link errors.<br>
|
||||
Because we assume some specific versions of non-OS-standard Ruby and Python, updating Homebrew, MacPorts, or Anaconda3 may cause build- and link errors.<br>
|
||||
In such cases, you need to update the dictionary contents of **`build4mac_env.py`**.
|
||||
|
||||
# Final comments
|
||||
No need to say KLayout is a great tool! <br>
|
||||
No need to say KLayout is a great tool!<br>
|
||||
With the object-oriented script language (both Ruby and Python) support, our error-prone layout jobs can be significantly simplified and sped up.<br>
|
||||
Building KLayout from its source code is not difficult. Try it with your favorite environment!
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 209 KiB After Width: | Height: | Size: 199 KiB |
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 198 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -6,6 +6,25 @@ import os
|
|||
pwd = os.getcwd()
|
||||
sys.path.append(pwd)
|
||||
|
||||
piphelpstr = """
|
||||
--------------------------------------------------------------------------------
|
||||
(1) Install ['pandas', 'scipy', 'matplotlib']
|
||||
>>> import pip
|
||||
>>> pip.main( ['install', 'pandas', 'scipy', 'matplotlib'] )
|
||||
|
||||
(2) List modules
|
||||
>>> import pip
|
||||
>>> pip.main( ['list'] )
|
||||
|
||||
(3) Uninstall ['scipy']
|
||||
>>> import pip
|
||||
>>> pip.main( ['uninstall', 'scipy'] )
|
||||
--------------------------------------------------------------------------------
|
||||
"""
|
||||
def howtopip():
|
||||
print(piphelpstr)
|
||||
|
||||
|
||||
variables = globals().copy()
|
||||
variables.update(locals())
|
||||
shell = code.InteractiveConsole(variables)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
#!/Applications/klayout.app/Contents/MacOS/klayout -b -r
|
||||
import readline
|
||||
import code
|
||||
import sys
|
||||
import os
|
||||
pwd = os.getcwd()
|
||||
sys.path.append(pwd)
|
||||
|
||||
rootPython = "/Applications/klayout.app/Contents/Frameworks/Python.framework/Versions"
|
||||
verPython = "${PYTHON_VER}"
|
||||
piptarget = [ "--target", "%s/%s/lib/python%s/site-packages" % (rootPython, verPython, verPython) ]
|
||||
|
||||
piphelpstr = """
|
||||
--------------------------------------------------------------------------------
|
||||
(1) Install ['pandas', 'scipy', 'matplotlib']
|
||||
>>> import pip
|
||||
>>> pip.main( ['install', 'pandas', 'scipy', 'matplotlib'] + piptarget )
|
||||
|
||||
(2) List modules
|
||||
>>> import pip
|
||||
>>> pip.main( ['list'] )
|
||||
|
||||
(3) Uninstall ['scipy']
|
||||
>>> import pip
|
||||
>>> pip.main( ['uninstall', 'scipy'] )
|
||||
--------------------------------------------------------------------------------
|
||||
"""
|
||||
def howtopip():
|
||||
print(piphelpstr)
|
||||
|
||||
|
||||
variables = globals().copy()
|
||||
variables.update(locals())
|
||||
shell = code.InteractiveConsole(variables)
|
||||
cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
|
||||
banner = "Python %s on %s\n%s\n(%s)" % (sys.version, sys.platform,
|
||||
cprt, "KLayout Python Console")
|
||||
exit_msg = 'now exiting %s...' % "KLayout Python Console"
|
||||
shell.interact(banner, exit_msg)
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -6,11 +6,12 @@
|
|||
#
|
||||
# Here are dictionaries of ...
|
||||
# different modules for building KLayout (http://www.klayout.de/index.php)
|
||||
# version 0.26.1 or later on different Apple Mac OSX platforms.
|
||||
# version 0.28.13 or later on different Apple Mac OSX platforms.
|
||||
#
|
||||
# This file is imported by 'build4mac.py' script.
|
||||
#===============================================================================
|
||||
import os
|
||||
import re
|
||||
import glob
|
||||
import platform
|
||||
|
||||
|
|
@ -30,25 +31,31 @@ if Machine == "arm64": # Apple Silicon!
|
|||
HomebrewSearchPathFilter1 = '\t+%s/opt' % DefaultHomebrewRoot
|
||||
HomebrewSearchPathFilter2 = '\t+@loader_path/../../../../../../../../../../opt'
|
||||
HomebrewSearchPathFilter3 = '@loader_path/../../../../../../../../../../opt' # no leading white space
|
||||
# 1: absolute path as in ~python@3.9.17
|
||||
# 2: relative path as in python@3.9.18~
|
||||
# 1: absolute path as seen in ~python@3.9.17
|
||||
# 2: relative path as seen in python@3.9.18
|
||||
else:
|
||||
DefaultHomebrewRoot = '/usr/local'
|
||||
HomebrewSearchPathFilter1 = '\t+%s/opt' % DefaultHomebrewRoot
|
||||
HomebrewSearchPathFilter2 = '\t+@loader_path/../../../../../../../../../../opt'
|
||||
HomebrewSearchPathFilter3 = '@loader_path/../../../../../../../../../../opt' # no leading white space
|
||||
# 1: absolute path as in ~python@3.9.17
|
||||
# 1: absolute path as seen in ~python@3.9.17
|
||||
# BigSur{kazzz-s} lib-dynload (1)% otool -L _sqlite3.cpython-39-darwin.so
|
||||
# _sqlite3.cpython-39-darwin.so:
|
||||
# ===> /usr/local/opt/sqlite/lib/libsqlite3.0.dylib (compatibility version 9.0.0, current version 9.6.0)
|
||||
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.100.5)
|
||||
#
|
||||
# 2: relative path as in python@3.9.18~
|
||||
# 2: relative path as seen in python@3.9.18
|
||||
# Monterey{kazzz-s} lib-dynload (1)% otool -L _sqlite3.cpython-39-darwin.so
|
||||
# _sqlite3.cpython-39-darwin.so:
|
||||
# ===> @loader_path/../../../../../../../../../../opt/sqlite/lib/libsqlite3.0.dylib (compatibility version 9.0.0, current version 9.6.0)
|
||||
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
|
||||
#
|
||||
# 3. absolute path again as seen in python@3.11
|
||||
# Monterey{kazzz-s} lib-dynload (1)% otool -L _sqlite3.cpython-311-darwin.so
|
||||
# _sqlite3.cpython-311-darwin.so:
|
||||
# ===> /usr/local/opt/sqlite/lib/libsqlite3.0.dylib (compatibility version 9.0.0, current version 9.6.0)
|
||||
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
|
||||
#
|
||||
# Ref. https://github.com/Homebrew/homebrew-core/issues/140930#issuecomment-1701524467
|
||||
del System, Node, Release, MacVersion, Machine, Processor
|
||||
|
||||
|
|
@ -102,91 +109,21 @@ Qt6Brew = { 'qmake' : '%s/opt/qt@6/bin/qmake' % DefaultHomebrewRoot,
|
|||
|
||||
#-----------------------------------------------------
|
||||
# [2] Ruby
|
||||
# * Dropped the followings (2023-10-24).
|
||||
# Sys: [ElCapitan - BigSur]
|
||||
# Ext: [Ruby31]
|
||||
# * See 415b5aa2efca04928f1148a69e77efd5d76f8c1d
|
||||
# for the previous states.
|
||||
#-----------------------------------------------------
|
||||
RubyNil = [ 'nil' ]
|
||||
RubySys = [ 'RubyElCapitan', 'RubySierra', 'RubyHighSierra', 'RubyMojave' ]
|
||||
RubySys += [ 'RubyCatalina', 'RubyBigSur', 'RubyMonterey', 'RubyVentura' ]
|
||||
RubyExt = [ 'Ruby31MacPorts', 'Ruby32MacPorts', 'Ruby31Brew', 'Ruby32Brew', 'RubyAnaconda3' ]
|
||||
RubySys = [ 'RubyMonterey', 'RubyVentura', 'RubySonoma' ]
|
||||
RubyExt = [ 'Ruby32MacPorts', 'Ruby32Brew', 'RubyAnaconda3' ]
|
||||
Rubies = RubyNil + RubySys + RubyExt
|
||||
|
||||
#-----------------------------------------------------
|
||||
# Whereabouts of different components of Ruby
|
||||
#-----------------------------------------------------
|
||||
# Bundled with Yosemite (10.10)
|
||||
# !!! Yosemite is no longer supported (KLayout 0.26 ~) but remains here to keep the record of
|
||||
# the directory structure of earlier generations.
|
||||
# [Key Type Name] = 'Sys'
|
||||
RubyYosemite = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby',
|
||||
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
|
||||
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.dylib'
|
||||
}
|
||||
|
||||
# Bundled with El Capitan (10.11)
|
||||
# [Key Type Name] = 'Sys'
|
||||
RubyElCapitan = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby',
|
||||
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
|
||||
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.dylib'
|
||||
}
|
||||
|
||||
# Bundled with Sierra (10.12)
|
||||
# [Key Type Name] = 'Sys'
|
||||
RubySierra = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby',
|
||||
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
|
||||
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/libruby.dylib'
|
||||
}
|
||||
|
||||
# Bundled with High Sierra (10.13)
|
||||
# [Key Type Name] = 'Sys'
|
||||
RubyHighSierra = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby',
|
||||
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
|
||||
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/libruby.dylib'
|
||||
}
|
||||
|
||||
# Bundled with Mojave (10.14)
|
||||
# The missing Ruby header files under "/System/Library/Frameworks/Ruby.framework/" were manually deployed there
|
||||
# from "Xcode-10.1-beta2" with the corresponding Ruby version.
|
||||
# [Key Type Name] = 'Sys'
|
||||
RubyMojave = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby',
|
||||
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
|
||||
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/libruby.dylib'
|
||||
}
|
||||
|
||||
# Bundled with Catalina (10.15)
|
||||
# !!! Catalina does not allow to hack the "/System" directory; it's READ ONLY even for the super user!
|
||||
# Hence, we need to refer to the Ruby header file in "Xcode.app" directly.
|
||||
#
|
||||
# With the major release of "macOS Big Sur (11.0)" in November 2020, Xcode has been updated, too.
|
||||
# (base) MacBookPro2{kazzz-s}(1)$ pwd
|
||||
# /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0
|
||||
#
|
||||
# (base) MacBookPro2{kazzz-s}(2)$ ll
|
||||
# total 4
|
||||
# drwxr-xr-x 6 root wheel 192 11 15 20:57 .
|
||||
# drwxr-xr-x 3 root wheel 96 10 20 05:33 ..
|
||||
# drwxr-xr-x 23 root wheel 736 10 24 11:57 ruby
|
||||
# -rw-r--r-- 1 root wheel 868 10 19 19:32 ruby.h
|
||||
# lrwxr-xr-x 1 root wheel 19 11 15 20:57 universal-darwin19 -> universal-darwin20/ <=== manually created this symbolic link
|
||||
# drwxr-xr-x 6 root wheel 192 10 20 05:33 universal-darwin20
|
||||
# [Key Type Name] = 'Sys'
|
||||
CatalinaSDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
|
||||
RubyCatalina = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby',
|
||||
'inc': '%s/System/Library/Frameworks/Ruby.framework/Headers' % CatalinaSDK,
|
||||
'inc2': '%s/System/Library/Frameworks/Ruby.framework/Headers/ruby' % CatalinaSDK,
|
||||
'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % CatalinaSDK
|
||||
}
|
||||
|
||||
# Bundled with Big Sur (11.x)
|
||||
# Refer to the "Catalina" section above
|
||||
# [Key Type Name] = 'Sys'
|
||||
BigSurSDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
|
||||
RubyBigSur = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby',
|
||||
'inc': '%s/System/Library/Frameworks/Ruby.framework/Headers' % BigSurSDK,
|
||||
'inc2': '%s/System/Library/Frameworks/Ruby.framework/Headers/ruby' % BigSurSDK,
|
||||
'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % BigSurSDK
|
||||
}
|
||||
|
||||
# Bundled with Monterey (12.x)
|
||||
# Refer to the "Catalina" section above
|
||||
# [Key Type Name] = 'Sys'
|
||||
MontereySDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
|
||||
RubyMonterey = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby',
|
||||
|
|
@ -195,8 +132,7 @@ RubyMonterey = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/
|
|||
'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % MontereySDK
|
||||
}
|
||||
|
||||
# Bundled with Ventura (14.x)
|
||||
# Refer to the "Catalina" section above
|
||||
# Bundled with Ventura (13.x)
|
||||
# [Key Type Name] = 'Sys'
|
||||
VenturaSDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
|
||||
RubyVentura = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby',
|
||||
|
|
@ -205,15 +141,16 @@ RubyVentura = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/
|
|||
'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % VenturaSDK
|
||||
}
|
||||
|
||||
# Ruby 3.1 from MacPorts (https://www.macports.org/) *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# install with 'sudo port install ruby31'
|
||||
# [Key Type Name] = 'MP31'
|
||||
Ruby31MacPorts = { 'exe': '/opt/local/bin/ruby3.1',
|
||||
'inc': '/opt/local/include/ruby-3.1.3',
|
||||
'lib': '/opt/local/lib/libruby.3.1.dylib'
|
||||
# Bundled with Sonoma (14.x)
|
||||
# [Key Type Name] = 'Sys'
|
||||
SonomaSDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
|
||||
RubySonoma = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby',
|
||||
'inc': '%s/System/Library/Frameworks/Ruby.framework/Headers' % SonomaSDK,
|
||||
'inc2': '%s/System/Library/Frameworks/Ruby.framework/Headers/ruby' % SonomaSDK,
|
||||
'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % SonomaSDK
|
||||
}
|
||||
|
||||
# Ruby 3.2 from MacPorts (https://www.macports.org/) *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# Ruby 3.2 from MacPorts (https://www.macports.org/)
|
||||
# install with 'sudo port install ruby32'
|
||||
# [Key Type Name] = 'MP32'
|
||||
Ruby32MacPorts = { 'exe': '/opt/local/bin/ruby3.2',
|
||||
|
|
@ -221,16 +158,7 @@ Ruby32MacPorts = { 'exe': '/opt/local/bin/ruby3.2',
|
|||
'lib': '/opt/local/lib/libruby.3.2.dylib'
|
||||
}
|
||||
|
||||
# Ruby 3.1 from Homebrew *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# install with 'brew install ruby@3.1'
|
||||
# [Key Type Name] = 'HB31'
|
||||
HBRuby31Path = '%s/opt/ruby@3.1' % DefaultHomebrewRoot
|
||||
Ruby31Brew = { 'exe': '%s/bin/ruby' % HBRuby31Path,
|
||||
'inc': '%s/include/ruby-3.1.0' % HBRuby31Path,
|
||||
'lib': '%s/lib/libruby.3.1.dylib' % HBRuby31Path
|
||||
}
|
||||
|
||||
# Ruby 3.2 from Homebrew *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# Ruby 3.2 from Homebrew
|
||||
# install with 'brew install ruby@3.2'
|
||||
# [Key Type Name] = 'HB32'
|
||||
HBRuby32Path = '%s/opt/ruby@3.2' % DefaultHomebrewRoot
|
||||
|
|
@ -239,7 +167,7 @@ Ruby32Brew = { 'exe': '%s/bin/ruby' % HBRuby32Path,
|
|||
'lib': '%s/lib/libruby.3.2.dylib' % HBRuby32Path
|
||||
}
|
||||
|
||||
# Ruby 3.1 bundled with anaconda3 installed under /Applications/anaconda3/ *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# Ruby 3.1 bundled with anaconda3 installed under /Applications/anaconda3/
|
||||
# The standard installation deploys the tool under $HOME/opt/anaconda3/.
|
||||
# If so, you need to make a symbolic link: /Applications/anaconda3 ---> $HOME/opt/anaconda3/
|
||||
# [Key Type Name] = 'Ana3'
|
||||
|
|
@ -250,157 +178,118 @@ RubyAnaconda3 = { 'exe': '/Applications/anaconda3/bin/ruby',
|
|||
|
||||
# Consolidated dictionary kit for Ruby
|
||||
RubyDictionary = { 'nil' : None,
|
||||
'RubyYosemite' : RubyYosemite,
|
||||
'RubyElCapitan' : RubyElCapitan,
|
||||
'RubySierra' : RubySierra,
|
||||
'RubyHighSierra': RubyHighSierra,
|
||||
'RubyMojave' : RubyMojave,
|
||||
'RubyCatalina' : RubyCatalina,
|
||||
'RubyBigSur' : RubyBigSur,
|
||||
'RubyMonterey' : RubyMonterey,
|
||||
'RubyVentura' : RubyVentura,
|
||||
'Ruby31MacPorts': Ruby31MacPorts,
|
||||
'RubySonoma' : RubySonoma,
|
||||
'Ruby32MacPorts': Ruby32MacPorts,
|
||||
'Ruby31Brew' : Ruby31Brew,
|
||||
'Ruby32Brew' : Ruby32Brew,
|
||||
'RubyAnaconda3' : RubyAnaconda3
|
||||
}
|
||||
|
||||
#-----------------------------------------------------
|
||||
# [3] Python
|
||||
# * Dropped the followings (2023-10-24).
|
||||
# Sys: [ElCapitan - Monterey]
|
||||
# Ext: [Python38]
|
||||
# * See 415b5aa2efca04928f1148a69e77efd5d76f8c1d
|
||||
# for the previous states.
|
||||
#-----------------------------------------------------
|
||||
PythonNil = [ 'nil' ]
|
||||
PythonSys = [ 'PythonElCapitan', 'PythonSierra', 'PythonHighSierra', 'PythonMojave' ]
|
||||
PythonSys += [ 'PythonCatalina', 'PythonBigSur', 'PythonMonterey' ]
|
||||
PythonExt = [ 'Python38MacPorts', 'Python39MacPorts', 'Python38Brew', 'Python39Brew' ]
|
||||
PythonSys = [ ]
|
||||
PythonExt = [ 'Python39MacPorts', 'Python39Brew' ]
|
||||
PythonExt += [ 'Python311MacPorts', 'Python311Brew' ]
|
||||
PythonExt += [ 'PythonAnaconda3', 'PythonAutoBrew' ]
|
||||
Pythons = PythonNil + PythonSys + PythonExt
|
||||
|
||||
#-----------------------------------------------------
|
||||
# Whereabouts of different components of Python
|
||||
#-----------------------------------------------------
|
||||
# Bundled with Yosemite (10.10)
|
||||
# !!! Yosemite is no longer supported but remains here to keep the record of the directory structure
|
||||
# of earlier generations.
|
||||
# [Key Type Name] = 'Sys'
|
||||
PythonYosemite = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
|
||||
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
|
||||
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
|
||||
}
|
||||
|
||||
# Bundled with El Capitan (10.11)
|
||||
# [Key Type Name] = 'Sys'
|
||||
PythonElCapitan = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
|
||||
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
|
||||
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
|
||||
}
|
||||
|
||||
# Bundled with Sierra (10.12)
|
||||
# [Key Type Name] = 'Sys'
|
||||
PythonSierra = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
|
||||
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
|
||||
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
|
||||
}
|
||||
|
||||
# Bundled with High Sierra (10.13)
|
||||
# [Key Type Name] = 'Sys'
|
||||
PythonHighSierra= { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
|
||||
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
|
||||
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
|
||||
}
|
||||
|
||||
# Bundled with Mojave (10.14)
|
||||
# [Key Type Name] = 'Sys'
|
||||
PythonMojave = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
|
||||
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
|
||||
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
|
||||
}
|
||||
|
||||
# Bundled with Catalina (10.15)
|
||||
# [Key Type Name] = 'Sys'
|
||||
PythonCatalina = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
|
||||
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
|
||||
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
|
||||
}
|
||||
|
||||
# Bundled with Big Sur (11.x)
|
||||
# ** IMPORTANT NOTES **
|
||||
# Xcode [13.1 .. ] does not allow to link the legacy Python 2.7 library not to produce unsupported applications.
|
||||
# This code block remains here to keep the parallelism.
|
||||
# [Key Type Name] = 'Sys'
|
||||
PythonBigSur = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
|
||||
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
|
||||
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
|
||||
}
|
||||
|
||||
# Bundled with Monterey (12.x)
|
||||
# ** IMPORTANT NOTES **
|
||||
# Xcode [13.1 .. ] does not allow to link the legacy Python 2.7 library not to produce unsupported applications.
|
||||
# This code block remains here to keep the parallelism.
|
||||
# [Key Type Name] = 'Sys'
|
||||
PythonMonterey = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
|
||||
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
|
||||
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
|
||||
}
|
||||
|
||||
# Python 3.8 from MacPorts (https://www.macports.org/) *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# install with 'sudo port install python38'
|
||||
# [Key Type Name] = 'MP38'
|
||||
Python38MacPorts= { 'exe': '/opt/local/Library/Frameworks/Python.framework/Versions/3.8/bin/python3.8',
|
||||
'inc': '/opt/local/Library/Frameworks/Python.framework/Versions/3.8/include/python3.8',
|
||||
'lib': '/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/libpython3.8.dylib'
|
||||
}
|
||||
|
||||
# Python 3.9 from MacPorts (https://www.macports.org/) *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# Python 3.9 from MacPorts (https://www.macports.org/)
|
||||
# install with 'sudo port install python39'
|
||||
# [Key Type Name] = 'MP38'
|
||||
Python39MacPorts= { 'exe': '/opt/local/Library/Frameworks/Python.framework/Versions/3.9/bin/python3.9',
|
||||
'inc': '/opt/local/Library/Frameworks/Python.framework/Versions/3.9/include/python3.9',
|
||||
'lib': '/opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/libpython3.9.dylib'
|
||||
}
|
||||
# [Key Type Name] = 'MP39'
|
||||
Python39MacPorts = { 'exe': '/opt/local/Library/Frameworks/Python.framework/Versions/3.9/bin/python3.9',
|
||||
'inc': '/opt/local/Library/Frameworks/Python.framework/Versions/3.9/include/python3.9',
|
||||
'lib': '/opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/libpython3.9.dylib'
|
||||
}
|
||||
|
||||
# Python 3.8 from Homebrew *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# install with 'brew install python@3.8'
|
||||
# [Key Type Name] = 'HB38'
|
||||
HBPython38FrameworkPath = '%s/opt/python@3.8/Frameworks/Python.framework' % DefaultHomebrewRoot
|
||||
Python38Brew = { 'exe': '%s/Versions/3.8/bin/python3.8' % HBPython38FrameworkPath,
|
||||
'inc': '%s/Versions/3.8/include/python3.8' % HBPython38FrameworkPath,
|
||||
'lib': '%s/Versions/3.8/lib/libpython3.8.dylib' % HBPython38FrameworkPath
|
||||
}
|
||||
# Python 3.11 from MacPorts (https://www.macports.org/)
|
||||
# install with 'sudo port install python311'
|
||||
# [Key Type Name] = 'MP311'
|
||||
Python311MacPorts = { 'exe': '/opt/local/Library/Frameworks/Python.framework/Versions/3.11/bin/python3.11',
|
||||
'inc': '/opt/local/Library/Frameworks/Python.framework/Versions/3.11/include/python3.11',
|
||||
'lib': '/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/libpython3.11.dylib'
|
||||
}
|
||||
|
||||
# Python 3.9 from Homebrew *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# Python 3.9 from Homebrew
|
||||
# install with 'brew install python@3.9'
|
||||
# [Key Type Name] = 'HB39'
|
||||
HBPython39FrameworkPath = '%s/opt/python@3.9/Frameworks/Python.framework' % DefaultHomebrewRoot
|
||||
Python39Brew = { 'exe': '%s/Versions/3.9/bin/python3.9' % HBPython39FrameworkPath,
|
||||
'inc': '%s/Versions/3.9/include/python3.9' % HBPython39FrameworkPath,
|
||||
'lib': '%s/Versions/3.9/lib/libpython3.9.dylib' % HBPython39FrameworkPath
|
||||
}
|
||||
Python39Brew = { 'exe': '%s/Versions/3.9/bin/python3.9' % HBPython39FrameworkPath,
|
||||
'inc': '%s/Versions/3.9/include/python3.9' % HBPython39FrameworkPath,
|
||||
'lib': '%s/Versions/3.9/lib/libpython3.9.dylib' % HBPython39FrameworkPath
|
||||
}
|
||||
|
||||
# Python 3.8 bundled with anaconda3 installed under /Applications/anaconda3/ *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# Python 3.11 from Homebrew
|
||||
# install with 'brew install python@3.11'
|
||||
# [Key Type Name] = 'HB311'
|
||||
HBPython311FrameworkPath = '%s/opt/python@3.11/Frameworks/Python.framework' % DefaultHomebrewRoot
|
||||
Python311Brew = { 'exe': '%s/Versions/3.11/bin/python3.11' % HBPython311FrameworkPath,
|
||||
'inc': '%s/Versions/3.11/include/python3.11' % HBPython311FrameworkPath,
|
||||
'lib': '%s/Versions/3.11/lib/libpython3.11.dylib' % HBPython311FrameworkPath
|
||||
}
|
||||
|
||||
# Python 3.11 bundled with anaconda3 installed under /Applications/anaconda3/
|
||||
# The standard installation deploys the tool under $HOME/opt/anaconda3/.
|
||||
# If so, you need to make a symbolic link: /Applications/anaconda3 ---> $HOME/opt/anaconda3/
|
||||
# [Key Type Name] = 'Ana3'
|
||||
PythonAnaconda3 = { 'exe': '/Applications/anaconda3/bin/python3.9',
|
||||
'inc': '/Applications/anaconda3/include/python3.9',
|
||||
'lib': '/Applications/anaconda3/lib/libpython3.9.dylib'
|
||||
PythonAnaconda3 = { 'exe': '/Applications/anaconda3/bin/python3.11',
|
||||
'inc': '/Applications/anaconda3/include/python3.11',
|
||||
'lib': '/Applications/anaconda3/lib/libpython3.11.dylib'
|
||||
}
|
||||
|
||||
# Latest Python from Homebrew *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# Latest Python from Homebrew
|
||||
# install with 'brew install python'
|
||||
# There can be multiple candidates such as: (python, python3, python@3, python@3.8, python@3.9)
|
||||
# There can be multiple candidates such as: (python, python3, python@3, python@3.8, python@3.9,
|
||||
# python@3.10, python@3.11, python@3.12, python@3.13 )
|
||||
# Hard to tell which is going to be available to the user. Picking the last one.
|
||||
# [Key Type Name] = 'HBAuto'
|
||||
HBPythonAutoFrameworkPath = ""
|
||||
HBPythonAutoVersion = ""
|
||||
try:
|
||||
HBPythonAutoFrameworkPath = glob.glob( "%s/opt/python*/Frameworks/Python.framework" % DefaultHomebrewRoot )[-1]
|
||||
# expand 3* into HBPythonAutoVersion, there should be only one, but I am taking no chances.
|
||||
patPF = r"(%s/opt/python)([@]?)(3[.]?)([0-9]*)(/Frameworks/Python[.]framework)" % DefaultHomebrewRoot
|
||||
regPF = re.compile(patPF)
|
||||
dicPy = dict()
|
||||
for item in glob.glob( "%s/opt/python*/Frameworks/Python.framework" % DefaultHomebrewRoot ):
|
||||
if regPF.match(item):
|
||||
pyver = regPF.match(item).groups()[3] # ([0-9]*)
|
||||
if pyver == "":
|
||||
pyver = "0"
|
||||
dicPy[ int(pyver) ] = ( item, "3."+pyver )
|
||||
keys = sorted( dicPy.keys(), reverse=True )
|
||||
HBPythonAutoFrameworkPath = dicPy[keys[0]][0]
|
||||
HBPythonAutoVersion = dicPy[keys[0]][1]
|
||||
|
||||
HBAutoFrameworkVersionPath, HBPythonAutoVersion = os.path.split( glob.glob( "%s/Versions/3*" % HBPythonAutoFrameworkPath )[0] )
|
||||
PythonAutoBrew = { 'exe': '%s/%s/bin/python%s' % ( HBAutoFrameworkVersionPath, HBPythonAutoVersion, HBPythonAutoVersion ),
|
||||
'inc': '%s/%s/include/python%s' % ( HBAutoFrameworkVersionPath, HBPythonAutoVersion, HBPythonAutoVersion ),
|
||||
'lib': glob.glob( "%s/%s/lib/*.dylib" % ( HBAutoFrameworkVersionPath, HBPythonAutoVersion ) )[0]
|
||||
}
|
||||
"""
|
||||
# when I have [python3, python@3, python@3.8, python@3.9, python@3.10, python@3.11]
|
||||
print(HBPythonAutoFrameworkPath)
|
||||
print(HBAutoFrameworkVersionPath)
|
||||
print(HBPythonAutoVersion)
|
||||
print(PythonAutoBrew)
|
||||
quit()
|
||||
|
||||
/usr/local/opt/python@3.11/Frameworks/Python.framework
|
||||
/usr/local/opt/python@3.11/Frameworks/Python.framework/Versions
|
||||
3.11
|
||||
{ 'exe': '/usr/local/opt/python@3.11/Frameworks/Python.framework/Versions/3.11/bin/python3.11',
|
||||
'inc': '/usr/local/opt/python@3.11/Frameworks/Python.framework/Versions/3.11/include/python3.11',
|
||||
'lib': '/usr/local/opt/python@3.11/Frameworks/Python.framework/Versions/3.11/lib/libpython3.11.dylib'
|
||||
}
|
||||
"""
|
||||
except Exception as e:
|
||||
_have_Homebrew_Python = False
|
||||
print( " WARNING!!! Since you don't have the Homebrew Python Frameworks, you cannot use the '-p HBAuto' option. " )
|
||||
|
|
@ -409,19 +298,12 @@ else:
|
|||
_have_Homebrew_Python = True
|
||||
|
||||
# Consolidated dictionary kit for Python
|
||||
PythonDictionary = { 'nil' : None,
|
||||
'PythonElCapitan' : PythonElCapitan,
|
||||
'PythonSierra' : PythonSierra,
|
||||
'PythonHighSierra': PythonHighSierra,
|
||||
'PythonMojave' : PythonMojave,
|
||||
'PythonCatalina' : PythonCatalina,
|
||||
'PythonBigSur' : PythonBigSur,
|
||||
'PythonMonterey' : PythonMonterey,
|
||||
'Python38MacPorts': Python38MacPorts,
|
||||
'Python39MacPorts': Python39MacPorts,
|
||||
'Python38Brew' : Python38Brew,
|
||||
'Python39Brew' : Python39Brew,
|
||||
'PythonAnaconda3' : PythonAnaconda3
|
||||
PythonDictionary = { 'nil' : None,
|
||||
'Python39MacPorts' : Python39MacPorts,
|
||||
'Python311MacPorts': Python311MacPorts,
|
||||
'Python39Brew' : Python39Brew,
|
||||
'Python311Brew' : Python311Brew,
|
||||
'PythonAnaconda3' : PythonAnaconda3
|
||||
}
|
||||
if _have_Homebrew_Python:
|
||||
PythonDictionary['PythonAutoBrew'] = PythonAutoBrew
|
||||
|
|
|
|||
|
|
@ -623,18 +623,24 @@ def Patch_Python_In_PythonFramework( pythonFrameworkPath,
|
|||
#----------------------------------------------------------------------------------------
|
||||
## To change the Python's relative library paths to the absolute paths
|
||||
#
|
||||
# 1: absolute path as in ~python@3.9.17
|
||||
# 1: absolute path as seen in ~python@3.9.17
|
||||
# BigSur{kazzz-s} lib-dynload (1)% otool -L _sqlite3.cpython-39-darwin.so
|
||||
# _sqlite3.cpython-39-darwin.so:
|
||||
# ===> /usr/local/opt/sqlite/lib/libsqlite3.0.dylib (compatibility version 9.0.0, current version 9.6.0)
|
||||
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.100.5)
|
||||
#
|
||||
# 2: relative path as in python@3.9.18~
|
||||
# 2: relative path as seen in python@3.9.18
|
||||
# Monterey{kazzz-s} lib-dynload (1)% otool -L _sqlite3.cpython-39-darwin.so
|
||||
# _sqlite3.cpython-39-darwin.so:
|
||||
# ===> @loader_path/../../../../../../../../../../opt/sqlite/lib/libsqlite3.0.dylib (compatibility version 9.0.0, current version 9.6.0)
|
||||
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
|
||||
#
|
||||
# 3. absolute path again as seen in python@3.11
|
||||
# Monterey{kazzz-s} lib-dynload (1)% otool -L _sqlite3.cpython-311-darwin.so
|
||||
# _sqlite3.cpython-311-darwin.so:
|
||||
# ===> /usr/local/opt/sqlite/lib/libsqlite3.0.dylib (compatibility version 9.0.0, current version 9.6.0)
|
||||
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
|
||||
#
|
||||
# @param[in] frameworkPath: Python Framework path
|
||||
# @param[in] debug_level: debug level
|
||||
#
|
||||
|
|
@ -650,10 +656,10 @@ def Change_Python_LibPath_RelativeToAbsolute( frameworkPath, debug_level=0 ):
|
|||
patRel3 = r'(%s)(.+)' % HomebrewSearchPathFilter3 # = '@loader_path/../../../../../../../../../../opt'
|
||||
regRel3 = re.compile(patRel3)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
# (A) Collect *.[so|dylib] that the Python Frameworks depends on
|
||||
#----------------------------------------------------------------------
|
||||
# Ref. https://formulae.brew.sh/formula/python@3.9#default
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
# Ref. https://formulae.brew.sh/formula/python@3.9
|
||||
# as of 2023-09-22, python@3.9 depends on:
|
||||
# gdbm 1.23 GNU database manager
|
||||
# mpdecimal 2.5.1 Library for decimal floating point arithmetic
|
||||
|
|
@ -661,6 +667,14 @@ def Change_Python_LibPath_RelativeToAbsolute( frameworkPath, debug_level=0 ):
|
|||
# readline 8.2.1 Library for command-line editing
|
||||
# sqlite 3.43.1 Command-line interface for SQLite
|
||||
# xz 5.4.4 General-purpose data compression with high compression ratio
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
# https://formulae.brew.sh/formula/python@3.11
|
||||
# as of 2023-10-24, python@3.11 depends on:
|
||||
# mpdecimal 2.5.1 Library for decimal floating point arithmetic
|
||||
# openssl@3 3.1.3 Cryptography and SSL/TLS Toolkit
|
||||
# sqlite 3.43.2 Command-line interface for SQLite
|
||||
# xz 5.4.4 General-purpose data compression with high compression ratio
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
find_grep_results = os.popen( 'find %s -type f | grep -E "%s"' % (frameworkPath, filter_regex) ).read().split('\n')
|
||||
framework_files = filter( lambda x: x != '', map(lambda x: x.strip(), find_grep_results) )
|
||||
|
||||
|
|
@ -745,6 +759,37 @@ def Change_Python_LibPath_RelativeToAbsolute( frameworkPath, debug_level=0 ):
|
|||
print( " ---> Change_Python_LibPath_RelativeToAbsolute(): Changed the library paths." )
|
||||
return 0
|
||||
|
||||
#----------------------------------------------------------------------------------------
|
||||
## To generate the 'start-console.py' file from the template file
|
||||
#
|
||||
# @param[in] template: input template file (template-start-console.py)
|
||||
# @param[in] pythonver: Python version string such as "3.11"
|
||||
# @param[in] target: output target file (start-console.py)
|
||||
#
|
||||
# @return True on success, False on failure
|
||||
#----------------------------------------------------------------------------------------
|
||||
def Generate_Start_Console_Py( template, pythonver, target ):
|
||||
try:
|
||||
fd = open( template, "r" )
|
||||
tmpl = fd.read()
|
||||
fd.close()
|
||||
except Exception as e:
|
||||
print( "! Failed to read <%s>" % template, file=sys.stderr )
|
||||
return False
|
||||
else:
|
||||
t = string.Template(tmpl)
|
||||
startpy = t.safe_substitute( PYTHON_VER=pythonver )
|
||||
|
||||
try:
|
||||
fd = open( target, "w" )
|
||||
fd.write(startpy)
|
||||
fd.close()
|
||||
except Exception as e:
|
||||
print( "! Failed to write <%s>" % target, file=sys.stderr )
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
#----------------
|
||||
# End of File
|
||||
#----------------
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ def SetGlobals():
|
|||
global WorkDir # work directory name
|
||||
global LogFile # log file name
|
||||
global Usage # string on usage
|
||||
global DryRun # dry-run mode; print the command line and exit
|
||||
# auxiliary variables on platform
|
||||
global System # 6-tuple from platform.uname()
|
||||
global Node # - do -
|
||||
|
|
@ -48,16 +49,19 @@ def SetGlobals():
|
|||
Usage += "<< Usage of 'macQAT.py' >>\n"
|
||||
Usage += " for running 'ut_runner' after building KLayout.\n"
|
||||
Usage += "\n"
|
||||
Usage += "$ [python] ./macQAT.py \n"
|
||||
Usage += "$ [python] ./macQAT.py\n"
|
||||
Usage += " option & argument : descriptions | default value\n"
|
||||
Usage += " -----------------------------------------------------------------+---------------\n"
|
||||
Usage += " [-u|--usage] : print usage of 'ut_runner'and exit | disabled \n"
|
||||
Usage += " | \n"
|
||||
Usage += " <-r|--run> : run this script | disabled \n"
|
||||
Usage += " [-s|--stop] : stop on error | disabled \n"
|
||||
Usage += " [-x|--exclude <tests>] : exclude test(s) such as 'pymod,pya' | '' \n"
|
||||
Usage += " [-a|--args <string>] : arguments other than '-x' and '-c' | '' \n"
|
||||
Usage += " [-?|--?] : print this usage and exit | disabled \n"
|
||||
Usage += " [-u|--usage] : print usage of 'ut_runner'and exit | disabled\n"
|
||||
Usage += " |\n"
|
||||
Usage += " <-r|--run> : run this script | disabled\n"
|
||||
Usage += " [-s|--stop] : stop on error | disabled\n"
|
||||
Usage += " [-x|--exclude <tests>] : exclude test(s) such as 'pymod,pya' | ''\n"
|
||||
Usage += " : you can use this option multiple times |\n"
|
||||
Usage += " [-a|--args <string>] : arguments other than '-x' and '-c' | ''\n"
|
||||
Usage += " : you can use this option multiple times |\n"
|
||||
Usage += " [--dryrun] : print the command line and exit | disabled\n"
|
||||
Usage += " [-?|--?] : print this usage and exit | disabled\n"
|
||||
Usage += "--------------------------------------------------------------------+-------------------\n"
|
||||
|
||||
ProjectDir = os.getcwd()
|
||||
|
|
@ -65,11 +69,12 @@ def SetGlobals():
|
|||
Run = False
|
||||
ContinueOnError = True
|
||||
TestsExcluded = list()
|
||||
Arguments = ""
|
||||
Arguments = list()
|
||||
GitSHA1 = GetGitShortSHA1()
|
||||
TimeStamp = GetTimeStamp()
|
||||
WorkDir = "QATest_%s_%s__%s" % (GitSHA1, TimeStamp, os.path.basename(ProjectDir) )
|
||||
LogFile = WorkDir + ".log"
|
||||
DryRun = False
|
||||
|
||||
(System, Node, Release, Version, Machine, Processor) = platform.uname()
|
||||
|
||||
|
|
@ -103,6 +108,7 @@ def ParseCommandLineArguments():
|
|||
global ContinueOnError
|
||||
global TestsExcluded
|
||||
global Arguments
|
||||
global DryRun
|
||||
|
||||
p = optparse.OptionParser( usage=Usage )
|
||||
p.add_option( '-u', '--usage',
|
||||
|
|
@ -124,13 +130,21 @@ def ParseCommandLineArguments():
|
|||
help='stop on error (false)' )
|
||||
|
||||
p.add_option( '-x', '--exclude',
|
||||
action='append',
|
||||
dest='exclude_tests',
|
||||
help="exclude test(s) such as 'pymod,pya' ('')" )
|
||||
|
||||
p.add_option( '-a', '--args',
|
||||
action='append',
|
||||
dest='arguments',
|
||||
help="arguments other than '-x' and '-c' ('')" )
|
||||
|
||||
p.add_option( '--dryrun',
|
||||
action='store_true',
|
||||
dest='dryrun',
|
||||
default=False,
|
||||
help='print the command line and exit (false)' )
|
||||
|
||||
p.add_option( '-?', '--??',
|
||||
action='store_true',
|
||||
dest='checkusage',
|
||||
|
|
@ -140,8 +154,9 @@ def ParseCommandLineArguments():
|
|||
p.set_defaults( runner_usage = False,
|
||||
runme = False,
|
||||
stop_on_error = False,
|
||||
exclude_tests = "",
|
||||
arguments = "",
|
||||
exclude_tests = list(),
|
||||
arguments = list(),
|
||||
dryrun = False,
|
||||
checkusage = False )
|
||||
|
||||
opt, args = p.parse_args()
|
||||
|
|
@ -152,11 +167,15 @@ def ParseCommandLineArguments():
|
|||
RunnerUsage = opt.runner_usage
|
||||
Run = opt.runme
|
||||
ContinueOnError = not opt.stop_on_error
|
||||
if not opt.exclude_tests == "":
|
||||
TestsExcluded = [ item.strip() for item in opt.exclude_tests.split(',') ]
|
||||
if not len(opt.exclude_tests) == 0:
|
||||
excluded_tests = list()
|
||||
for item in opt.exclude_tests:
|
||||
excluded_tests += [ subitem.strip() for subitem in item.split(',') ]
|
||||
TestsExcluded = sorted(list(set(excluded_tests)))
|
||||
else:
|
||||
TestsExcluded = []
|
||||
Arguments = opt.arguments
|
||||
DryRun = opt.dryrun
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
## Hide/Show the private directory
|
||||
|
|
@ -248,16 +267,20 @@ def Main():
|
|||
command += " -c"
|
||||
for item in TestsExcluded:
|
||||
command += ' -x %s' % item
|
||||
if not Arguments == "":
|
||||
command += " %s" % Arguments
|
||||
if not len(Arguments) == 0:
|
||||
for arg in Arguments:
|
||||
command += " %s" % arg
|
||||
|
||||
print( "" )
|
||||
print( "### Dumping the log to <%s>" % LogFile )
|
||||
print( "------------------------------------------------------------" )
|
||||
print( " Git SHA1 = %s" % GitSHA1 )
|
||||
print( " Time stamp = %s" % TimeStamp )
|
||||
print( "------------------------------------------------------------" )
|
||||
sleep( 1.0 )
|
||||
print( "------------------------------------------------------------------------" )
|
||||
print( " Git SHA1 = %s" % GitSHA1 )
|
||||
print( " Time stamp = %s" % TimeStamp )
|
||||
print( " Command line = %s" % command )
|
||||
print( "------------------------------------------------------------------------" )
|
||||
if DryRun:
|
||||
quit()
|
||||
sleep(1.0)
|
||||
HidePrivateDir()
|
||||
RunTester( command, logfile=LogFile )
|
||||
ShowPrivateDir()
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
# The top Bash script to run "ut_runner" after building KLayout
|
||||
# (http://www.klayout.de/index.php) version 0.26.1 or later on different Apple
|
||||
# ßMac OSX platforms.
|
||||
# Mac OSX platforms.
|
||||
#
|
||||
# This script must be copied to a "*.macQAT/" directory to run.
|
||||
#===============================================================================
|
||||
|
|
@ -68,8 +68,8 @@ if [ $# -eq 1 ]; then
|
|||
echo " Time stamp = ${timestamp}"
|
||||
echo " Log file = ${logfile}"
|
||||
echo " Usage:"
|
||||
echo " ./QATest.sh -h: to get the help of 'ut_runner'"
|
||||
echo " ./QATest.sh -r: to run the tests with '-c' option: continues after an error"
|
||||
echo " ./macQAT.sh -h: to get the help of 'ut_runner'"
|
||||
echo " ./macQAT.sh -r: to run the tests with '-c' option: continues after an error"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
|
@ -79,8 +79,8 @@ else
|
|||
echo " Time stamp = ${timestamp}"
|
||||
echo " Log file = ${logfile}"
|
||||
echo " Usage:"
|
||||
echo " ./QATest.sh -h: to get the help of 'ut_runner'"
|
||||
echo " ./QATest.sh -r: to run the tests with '-c' option: continues after an error"
|
||||
echo " ./macQAT.sh -h: to get the help of 'ut_runner'"
|
||||
echo " ./macQAT.sh -r: to run the tests with '-c' option: continues after an error"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
|
||||
#===============================================================================
|
||||
# File: "macbuild/macQAT2.sh"
|
||||
#
|
||||
# The top Bash script to run "ut_runner" after building KLayout
|
||||
# (http://www.klayout.de/index.php) version 0.26.1 or later on different Apple
|
||||
# Mac OSX platforms.
|
||||
#
|
||||
# This script must be copied to a directory that can be found in $PATH.
|
||||
#===============================================================================
|
||||
|
||||
prjdir=`pwd`
|
||||
|
||||
if [ $# -ge 2 ]; then
|
||||
first_arg=$1
|
||||
shift
|
||||
remaining_args=("$@")
|
||||
echo "#########################"
|
||||
echo "# Starging macQAT2.sh #"
|
||||
echo "#########################"
|
||||
echo " Current Dir: $prjdir"
|
||||
echo " First Arg: $first_arg"
|
||||
echo "Remaining Args: ${remaining_args[@]}"
|
||||
echo ""
|
||||
export TESTSRC=../
|
||||
export TESTTMP=$first_arg
|
||||
export DYLD_LIBRARY_PATH=$prjdir:$prjdir/db_plugins:$prjdir/lay_plugins
|
||||
./ut_runner ${remaining_args[@]}
|
||||
else
|
||||
echo "Usage: -------------------------------------------------"
|
||||
echo " $ macQAT2.sh <test_dir> <args to ./ut_runner>"
|
||||
echo " ex. $ change directory to a *.macQAT/"
|
||||
echo " $ macQAT2.sh __Homebrew tlGitTests"
|
||||
echo "--------------------------------------------------------"
|
||||
fi
|
||||
|
||||
#--------------
|
||||
# End of File
|
||||
#--------------
|
||||
|
|
@ -47,7 +47,7 @@ def SetGlobals():
|
|||
global DefaultBundleName # the default bundle name 'klayout.app'
|
||||
global BundleName # application bundle name in the DMG
|
||||
global DMGSerialNum # the DMG serial number
|
||||
global PackagePrefix # the package prefix: 'ST-', 'LW-', 'HW-', or 'EX-'
|
||||
global PackagePrefix # the package prefix: LW-', 'HW-', or 'EX-'
|
||||
global QtIdentification # Qt identification
|
||||
global RubyPythonID # Ruby- and Python-identification
|
||||
global KLVersion # KLayout's version
|
||||
|
|
@ -77,13 +77,13 @@ def SetGlobals():
|
|||
Usage = "\n"
|
||||
Usage += "---------------------------------------------------------------------------------------------------------\n"
|
||||
Usage += "<< Usage of 'makeDMG4mac.py' >>\n"
|
||||
Usage += " for making a DMG file of KLayout 0.28.4 or later on different Apple macOS / Mac OSX platforms.\n"
|
||||
Usage += " for making a DMG file of KLayout 0.28.13 or later on different Apple macOS platforms.\n"
|
||||
Usage += "\n"
|
||||
Usage += "$ [python] ./makeDMG4mac.py\n"
|
||||
Usage += " option & argument : descriptions | default value\n"
|
||||
Usage += " ----------------------------------------------------------------------------------+-----------------\n"
|
||||
Usage += " <-p|--pkg <dir>> : package directory created by `build4mac.py` with [-y|-Y] | ``\n"
|
||||
Usage += " : like 'LW-qt5MP.pkg.macos-Catalina-release-Rmp32Pmp39' | \n"
|
||||
Usage += " : like 'LW-qt5MP.pkg.macos-Monterey-release-Rmp32Pmp311' | \n"
|
||||
Usage += " <-c|--clean> : clean the work directory | disabled\n"
|
||||
Usage += " <-m|--make> : make a compressed DMG file | disabled\n"
|
||||
Usage += " : <-c|--clean> and <-m|--make> are mutually exclusive | \n"
|
||||
|
|
@ -103,9 +103,13 @@ def SetGlobals():
|
|||
print(Usage)
|
||||
quit()
|
||||
|
||||
release = int( Release.split(".")[0] ) # take the first of ['19', '0', '0']
|
||||
release = int( Release.split(".")[0] ) # take the first of ['21', '0', '0']
|
||||
LatestOS = ""
|
||||
if release == 22:
|
||||
if release == 23:
|
||||
GenOSName = "macOS"
|
||||
Platform = "Sonoma"
|
||||
LatestOS = Platform
|
||||
elif release == 22:
|
||||
GenOSName = "macOS"
|
||||
Platform = "Ventura"
|
||||
LatestOS = Platform
|
||||
|
|
@ -113,26 +117,6 @@ def SetGlobals():
|
|||
GenOSName = "macOS"
|
||||
Platform = "Monterey"
|
||||
LatestOS = Platform
|
||||
elif release == 20:
|
||||
GenOSName = "macOS"
|
||||
Platform = "BigSur"
|
||||
LatestOS = Platform
|
||||
elif release == 19:
|
||||
GenOSName = "macOS"
|
||||
Platform = "Catalina"
|
||||
LatestOS = Platform
|
||||
elif release == 18:
|
||||
GenOSName = "macOS"
|
||||
Platform = "Mojave"
|
||||
elif release == 17:
|
||||
GenOSName = "macOS"
|
||||
Platform = "HighSierra"
|
||||
elif release == 16:
|
||||
Platform = "Sierra"
|
||||
GenOSName = "macOS"
|
||||
elif release == 15:
|
||||
GenOSName = "MacOSX"
|
||||
Platform = "ElCapitan"
|
||||
else:
|
||||
Platform = ""
|
||||
print("")
|
||||
|
|
@ -141,7 +125,7 @@ def SetGlobals():
|
|||
sys.exit(1)
|
||||
|
||||
if not Machine == "x86_64":
|
||||
if Machine == "arm64" and Platform in ["Ventura", "Monterey", "BigSur"]: # with an Apple Silicon Chip
|
||||
if Machine == "arm64" and Platform in ["Sonoma", "Ventura", "Monterey"]: # with an Apple Silicon Chip
|
||||
print("")
|
||||
print( "### Your Mac equips an Apple Silicon Chip ###" )
|
||||
print("")
|
||||
|
|
@ -207,18 +191,18 @@ def SetGlobals():
|
|||
## To check the contents of the package directory
|
||||
#
|
||||
# The package directory name should look like:
|
||||
# * LW-qt5Ana3.pkg.macos-Catalina-release-Rana3Pana3
|
||||
# * LW-qt5Brew.pkg.macos-Catalina-release-Rhb32Phb39 --- (1)
|
||||
# * LW-qt5MP.pkg.macos-Catalina-release-Rmp32Pmp39
|
||||
# * HW-qt5Brew.pkg.macos-Catalina-release-RsysPhb39
|
||||
# * LW-qt5Ana3.pkg.macos-Monterey-release-Rana3Pana3
|
||||
# * LW-qt5Brew.pkg.macos-Monterey-release-Rhb32Phb311 --- (1)
|
||||
# * LW-qt5MP.pkg.macos-Monterey-release-Rmp32Pmp311
|
||||
# * HW-qt5Brew.pkg.macos-Monterey-release-RsysPhb311
|
||||
#
|
||||
# * LW-qt6Ana3.pkg.macos-Catalina-release-Rana3Pana3
|
||||
# * LW-qt6Brew.pkg.macos-Catalina-release-Rhb32Phb39
|
||||
# * LW-qt6MP.pkg.macos-Catalina-release-Rmp32Pmp39
|
||||
# * HW-qt6Brew.pkg.macos-Catalina-release-RsysPhb39
|
||||
# * LW-qt6Ana3.pkg.macos-Monterey-release-Rana3Pana3
|
||||
# * LW-qt6Brew.pkg.macos-Monterey-release-Rhb32Phb311
|
||||
# * LW-qt6MP.pkg.macos-Monterey-release-Rmp32Pmp311
|
||||
# * HW-qt6Brew.pkg.macos-Monterey-release-RsysPhb311
|
||||
#
|
||||
# Generated DMG will be, for example,
|
||||
# (1) ---> LW-klayout-0.28.4-macOS-Catalina-1-qt5Brew-Rhb32Phb39.dmg
|
||||
# (1) ---> LW-klayout-0.28.13-macOS-Monterey-1-qt5Brew-Rhb32Phb311.dmg
|
||||
#
|
||||
# @return on success, positive integer in [MB] that tells approx. occupied disc space;
|
||||
# on failure, -1
|
||||
|
|
@ -257,19 +241,18 @@ def CheckPkgDirectory():
|
|||
|
||||
#-----------------------------------------------------------------------------------------------
|
||||
# [2] Identify (Qt, Ruby, Python) from PkgDir
|
||||
# * ST-qt5MP.pkg.macos-Catalina-release-RsysPsys # 'ST' has been restored in 0.28.3
|
||||
# * LW-qt5Ana3.pkg.macos-Catalina-release-Rana3Pana3
|
||||
# * LW-qt5Brew.pkg.macos-Catalina-release-Rhb32Phb39
|
||||
# * LW-qt5MP.pkg.macos-Catalina-release-Rmp32Pmp39
|
||||
# * HW-qt5Brew.pkg.macos-Catalina-release-RsysPhb39
|
||||
# * EX-qt5MP.pkg.macos-Catalina-release-Rhb32Pmp39
|
||||
# * LW-qt5Ana3.pkg.macos-Monterey-release-Rana3Pana3
|
||||
# * LW-qt5Brew.pkg.macos-Monterey-release-Rhb32Phb311
|
||||
# * LW-qt5MP.pkg.macos-Monterey-release-Rmp32Pmp311
|
||||
# * HW-qt5Brew.pkg.macos-Monterey-release-RsysPhb311
|
||||
# * EX-qt5MP.pkg.macos-Monterey-release-Rhb32Pmp311
|
||||
#
|
||||
# * LW-qt6Ana3.pkg.macos-Catalina-release-Rana3Pana3
|
||||
# * LW-qt6Brew.pkg.macos-Catalina-release-Rhb32Phb39
|
||||
# * LW-qt6MP.pkg.macos-Catalina-release-Rmp32Pmp39
|
||||
# * HW-qt6Brew.pkg.macos-Catalina-release-RsysPhb39
|
||||
# * LW-qt6Ana3.pkg.macos-Monterey-release-Rana3Pana3
|
||||
# * LW-qt6Brew.pkg.macos-Monterey-release-Rhb32Phb311
|
||||
# * LW-qt6MP.pkg.macos-Monterey-release-Rmp32Pmp311
|
||||
# * HW-qt6Brew.pkg.macos-Monterey-release-RsysPhb311
|
||||
#-----------------------------------------------------------------------------------------------
|
||||
patQRP = u'(ST|LW|HW|EX)([-])([qt5|qt6][0-9A-Za-z]+)([.]pkg[.])([A-Za-z]+[-][A-Za-z]+[-]release[-])([0-9A-Za-z]+)'
|
||||
patQRP = u'(LW|HW|EX)([-])([qt5|qt6][0-9A-Za-z]+)([.]pkg[.])([A-Za-z]+[-][A-Za-z]+[-]release[-])([0-9A-Za-z]+)'
|
||||
regQRP = re.compile(patQRP)
|
||||
if not regQRP.match(PkgDir):
|
||||
print( "! Cannot identify (Qt, Ruby, Python) from the package directory name" )
|
||||
|
|
@ -297,14 +280,12 @@ def CheckPkgDirectory():
|
|||
LatestOSMacPorts = Platform == LatestOS
|
||||
LatestOSMacPorts &= PackagePrefix == "LW"
|
||||
LatestOSMacPorts &= QtIdentification in [ "qt5MP", "qt6MP" ]
|
||||
LatestOSMacPorts &= RubyPythonID in [ "Rmp31Pmp38", "Rmp31Pmp39", \
|
||||
"Rmp32Pmp38", "Rmp32Pmp39" ]
|
||||
LatestOSMacPorts &= RubyPythonID in [ "Rmp32Pmp311", "Rmp32Pmp39" ]
|
||||
|
||||
LatestOSHomebrew = Platform == LatestOS
|
||||
LatestOSHomebrew &= PackagePrefix == "LW"
|
||||
LatestOSHomebrew &= QtIdentification in [ "qt5Brew", "qt6Brew" ]
|
||||
LatestOSHomebrew &= RubyPythonID in [ "Rhb31Phb38", "Rhb31Phb39", "Rhb31Phbauto", \
|
||||
"Rhb32Phb38", "Rhb32Phb39", "Rhb32Phbauto" ]
|
||||
LatestOSHomebrew &= RubyPythonID in [ "Rhb32Phb311", "Rhb32Phb39", "Rhb32Phbauto" ]
|
||||
|
||||
LatestOSAnaconda3 = Platform == LatestOS
|
||||
LatestOSAnaconda3 &= PackagePrefix == "LW"
|
||||
|
|
@ -314,7 +295,7 @@ def CheckPkgDirectory():
|
|||
LatestOSHomebrewH = Platform == LatestOS
|
||||
LatestOSHomebrewH &= PackagePrefix == "HW"
|
||||
LatestOSHomebrewH &= QtIdentification in [ "qt5Brew", "qt6Brew" ]
|
||||
LatestOSHomebrewH &= RubyPythonID in [ "RsysPhb39", "RsysPhb39", "RsysPhbauto" ] # Sys-Homebre hybrid
|
||||
LatestOSHomebrewH &= RubyPythonID in [ "RsysPhb311", "RsysPhb39", "RsysPhbauto" ] # Sys-Homebre hybrid
|
||||
|
||||
if LatestOSMacPorts:
|
||||
mydic = DicLightHeavyW["ports"]
|
||||
|
|
|
|||
|
|
@ -16,29 +16,19 @@ import subprocess
|
|||
#
|
||||
# @return matching platform name on success; "" on failure
|
||||
#------------------------------------------------------------------------------
|
||||
def Test_My_Platform( platforms=[ 'Catalina', 'BigSur', 'Monterey', 'Ventura' ] ):
|
||||
def Test_My_Platform( platforms=[ 'Monterey', 'Ventura', 'Sonoma' ] ):
|
||||
(System, Node, Release, MacVersion, Machine, Processor) = platform.uname()
|
||||
|
||||
if not System == "Darwin":
|
||||
return ""
|
||||
|
||||
release = int( Release.split(".")[0] ) # take the first of ['19', '0', '0']
|
||||
if release == 22:
|
||||
release = int( Release.split(".")[0] ) # take the first of ['21', '0', '0']
|
||||
if release == 23:
|
||||
Platform = "Sonoma"
|
||||
elif release == 22:
|
||||
Platform = "Ventura"
|
||||
elif release == 21:
|
||||
Platform = "Monterey"
|
||||
elif release == 20:
|
||||
Platform = "BigSur"
|
||||
elif release == 19:
|
||||
Platform = "Catalina"
|
||||
elif release == 18:
|
||||
Platform = "Mojave"
|
||||
elif release == 17:
|
||||
Platform = "HighSierra"
|
||||
elif release == 16:
|
||||
Platform = "Sierra"
|
||||
elif release == 15:
|
||||
Platform = "ElCapitan"
|
||||
else:
|
||||
Platform = ""
|
||||
|
||||
|
|
@ -54,7 +44,7 @@ def Test_My_Platform( platforms=[ 'Catalina', 'BigSur', 'Monterey', 'Ventura' ]
|
|||
#------------------------------------------------------------------------------
|
||||
def Get_Build_Target_Dict():
|
||||
buildTargetDic = dict()
|
||||
buildTargetDic[0] = 'std' # has been restored in 0.28.3
|
||||
# buildTargetDic[0] = 'std'
|
||||
buildTargetDic[1] = 'ports'
|
||||
buildTargetDic[2] = 'brew'
|
||||
buildTargetDic[3] = 'brewHW'
|
||||
|
|
@ -88,14 +78,14 @@ def Get_Build_Options( targetDic, platform ):
|
|||
buildOp["std"] = [ '-q', '%sMacPorts' % qtType, '-r', 'sys', '-p', 'sys' ]
|
||||
logfile["std"] = "%sMP.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPsys")
|
||||
elif target == "ports":
|
||||
buildOp["ports"] = [ '-q', '%sMacPorts' % qtType, '-r', 'MP32', '-p', 'MP39' ]
|
||||
logfile["ports"] = "%sMP.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rmp32Pmp39")
|
||||
buildOp["ports"] = [ '-q', '%sMacPorts' % qtType, '-r', 'MP32', '-p', 'MP311' ]
|
||||
logfile["ports"] = "%sMP.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rmp32Pmp311")
|
||||
elif target == "brew":
|
||||
buildOp["brew"] = [ '-q', '%sBrew' % qtType, '-r', 'HB32', '-p', 'HB39' ]
|
||||
logfile["brew"] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rhb32Phb39")
|
||||
buildOp["brew"] = [ '-q', '%sBrew' % qtType, '-r', 'HB32', '-p', 'HB311' ]
|
||||
logfile["brew"] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rhb32Phb311")
|
||||
elif target == "brewHW":
|
||||
buildOp["brewHW"] = [ '-q', '%sBrew' % qtType, '-r', 'sys', '-p', 'HB39' ]
|
||||
logfile["brewHW"] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPhb39")
|
||||
buildOp["brewHW"] = [ '-q', '%sBrew' % qtType, '-r', 'sys', '-p', 'HB311' ]
|
||||
logfile["brewHW"] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPhb311")
|
||||
elif target == "ana3":
|
||||
buildOp["ana3"] = [ '-q', '%sAna3' % qtType, '-r', 'Ana3', '-p', 'Ana3' ]
|
||||
logfile["ana3"] = "%sAna3.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rana3Pana3")
|
||||
|
|
@ -130,14 +120,12 @@ def Get_QAT_Directory( targetDic, platform ):
|
|||
dirQAT = dict()
|
||||
for key in targetDic.keys():
|
||||
target = targetDic[key]
|
||||
if target == "std":
|
||||
dirQAT["std"] = '%sMP.build.macos-%s-release-RsysPsys.macQAT' % (qtType, platform)
|
||||
elif target == "ports":
|
||||
dirQAT["ports"] = '%sMP.build.macos-%s-release-Rmp32Pmp39.macQAT' % (qtType, platform)
|
||||
if target == "ports":
|
||||
dirQAT["ports"] = '%sMP.build.macos-%s-release-Rmp32Pmp311.macQAT' % (qtType, platform)
|
||||
elif target == "brew":
|
||||
dirQAT["brew"] = '%sBrew.build.macos-%s-release-Rhb32Phb39.macQAT' % (qtType, platform)
|
||||
dirQAT["brew"] = '%sBrew.build.macos-%s-release-Rhb32Phb311.macQAT' % (qtType, platform)
|
||||
elif target == "brewHW":
|
||||
dirQAT["brewHW"] = '%sBrew.build.macos-%s-release-RsysPhb39.macQAT' % (qtType, platform)
|
||||
dirQAT["brewHW"] = '%sBrew.build.macos-%s-release-RsysPhb311.macQAT' % (qtType, platform)
|
||||
elif target == "ana3":
|
||||
dirQAT["ana3"] = '%sAna3.build.macos-%s-release-Rana3Pana3.macQAT' % (qtType, platform)
|
||||
elif target == "brewA":
|
||||
|
|
@ -170,17 +158,14 @@ def Get_Package_Options( targetDic, platform, srlDMG, makeflag ):
|
|||
packOp = dict()
|
||||
for key in targetDic.keys():
|
||||
target = targetDic[key]
|
||||
if target == "std":
|
||||
packOp["std"] = [ '-p', 'ST-%sMP.pkg.macos-%s-release-RsysPsys' % (qtType, platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "ports":
|
||||
packOp["ports"] = [ '-p', 'LW-%sMP.pkg.macos-%s-release-Rmp32Pmp39' % (qtType, platform),
|
||||
if target == "ports":
|
||||
packOp["ports"] = [ '-p', 'LW-%sMP.pkg.macos-%s-release-Rmp32Pmp311' % (qtType, platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "brew":
|
||||
packOp["brew"] = [ '-p', 'LW-%sBrew.pkg.macos-%s-release-Rhb32Phb39' % (qtType, platform),
|
||||
packOp["brew"] = [ '-p', 'LW-%sBrew.pkg.macos-%s-release-Rhb32Phb311' % (qtType, platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "brewHW":
|
||||
packOp["brewHW"] = [ '-p', 'HW-%sBrew.pkg.macos-%s-release-RsysPhb39' % (qtType, platform),
|
||||
packOp["brewHW"] = [ '-p', 'HW-%sBrew.pkg.macos-%s-release-RsysPhb311' % (qtType, platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "ana3":
|
||||
packOp["ana3"] = [ '-p', 'LW-%sAna3.pkg.macos-%s-release-Rana3Pana3' % (qtType, platform),
|
||||
|
|
@ -212,23 +197,24 @@ def Parse_CommandLine_Arguments():
|
|||
global DryRun # True for dry-run
|
||||
|
||||
platform = Test_My_Platform()
|
||||
if platform in [ "Ventura", "Monterey", "BigSur" ]:
|
||||
if platform in [ "Sonoma", "Ventura", "Monterey" ]:
|
||||
targetopt = "1,2,3,4"
|
||||
else:
|
||||
targetopt = "0,1,2,3,4"
|
||||
targetopt = "0"
|
||||
|
||||
Usage = "\n"
|
||||
Usage += "----------------------------------------------------------------------------------------------------------\n"
|
||||
Usage += " nightlyBuild.py [EXPERIMENTAL] \n"
|
||||
Usage += " << To execute the jobs for making KLayout's DMGs for macOS Catalina, Big Sur, Monterey, or Ventura >>\n"
|
||||
Usage += " nightlyBuild.py [EXPERIMENTAL]\n"
|
||||
Usage += " << To execute the jobs for making KLayout's DMGs for\n"
|
||||
Usage += " macOS Monterey, Ventura, or Sonoma >>\n"
|
||||
Usage += "\n"
|
||||
Usage += "$ [python] nightlyBuild.py\n"
|
||||
Usage += " option & argument : comment on option if any | default value\n"
|
||||
Usage += " ------------------------------------------------------------------------+--------------\n"
|
||||
Usage += " [--qt <type>] : 5='qt5', 6='qt6' (migration to Qt6 is ongoing) | 5\n"
|
||||
Usage += " [--target <list>] : 0='std' 1='ports', 2='brew', 3='brewHW', 4='ana3', | '%s'\n" % targetopt
|
||||
Usage += " 5='brewA', 6='brewAHW' | \n"
|
||||
Usage += " * with --qt=6, use --target='2,3' (4 is ignored) | \n"
|
||||
Usage += " [--target <list>] : 1='ports', 2='brew', 3='brewHW', 4='ana3', | '%s'\n" % targetopt
|
||||
Usage += " 5='brewA', 6='brewAHW' |\n"
|
||||
Usage += " * with --qt=6, use --target='2,3' (4 is ignored) |\n"
|
||||
Usage += " [--build] : build and deploy | disabled\n"
|
||||
Usage += " [--pymod] : build and deploy Pymod, too | disabled\n"
|
||||
Usage += " [--test] : run the QA Test | disabled\n"
|
||||
|
|
@ -237,18 +223,18 @@ def Parse_CommandLine_Arguments():
|
|||
Usage += " [--upload <dropbox>] : upload DMGs to $HOME/Dropbox/klayout/<dropbox> | disabled\n"
|
||||
Usage += " [--dryrun] : dry-run for --build option | disabled\n"
|
||||
Usage += " [-?|--?] : print this usage and exit | disabled\n"
|
||||
Usage += " | \n"
|
||||
Usage += " To use this script, make a symbolic link in the project root by: | \n"
|
||||
Usage += " $ ln -s ./macbuild/nightlyBuild.py . | \n"
|
||||
Usage += " | \n"
|
||||
Usage += " Regular sequence for using this script: | \n"
|
||||
Usage += " (1) $ ./nightlyBuild.py --build --pymod | \n"
|
||||
Usage += " (2) (confirm the build results) | \n"
|
||||
Usage += " (3) $ ./nightlyBuild.py --test | \n"
|
||||
Usage += " (4) $ ./nightlyBuild.py --check (confirm the QA Test results) | \n"
|
||||
Usage += " (5) $ ./nightlyBuild.py --makedmg 1 | \n"
|
||||
Usage += " (6) $ ./nightlyBuild.py --upload '0.28.4' | \n"
|
||||
Usage += " (7) $ ./nightlyBuild.py --cleandmg 1 | \n"
|
||||
Usage += " |\n"
|
||||
Usage += " To use this script, make a symbolic link in the project root by: |\n"
|
||||
Usage += " $ ln -s ./macbuild/nightlyBuild.py . |\n"
|
||||
Usage += " |\n"
|
||||
Usage += " Regular sequence for using this script: |\n"
|
||||
Usage += " (1) $ ./nightlyBuild.py --build --pymod |\n"
|
||||
Usage += " (2) (confirm the build results) |\n"
|
||||
Usage += " (3) $ ./nightlyBuild.py --test |\n"
|
||||
Usage += " (4) $ ./nightlyBuild.py --check (confirm the QA Test results) |\n"
|
||||
Usage += " (5) $ ./nightlyBuild.py --makedmg 1 |\n"
|
||||
Usage += " (6) $ ./nightlyBuild.py --upload '0.28.12' |\n"
|
||||
Usage += " (7) $ ./nightlyBuild.py --cleandmg 1 |\n"
|
||||
Usage += "---------------------------------------------------------------------------+------------------------------\n"
|
||||
|
||||
p = optparse.OptionParser( usage=Usage )
|
||||
|
|
@ -325,9 +311,9 @@ def Parse_CommandLine_Arguments():
|
|||
print(Usage)
|
||||
quit()
|
||||
|
||||
myPlatform = Test_My_Platform( [ 'Catalina', 'BigSur', 'Monterey', 'Ventura' ] )
|
||||
myPlatform = Test_My_Platform( [ 'Monterey', 'Ventura', 'Sonoma' ] )
|
||||
if myPlatform == "":
|
||||
print( "! Current platform is not [ 'Catalina', 'BigSur', 'Monterey', 'Ventura' ]" )
|
||||
print( "! Current platform is not [ 'Monterey', 'Ventura', 'Sonoma' ]" )
|
||||
print(Usage)
|
||||
quit()
|
||||
|
||||
|
|
@ -345,7 +331,7 @@ def Parse_CommandLine_Arguments():
|
|||
targetDic = Get_Build_Target_Dict()
|
||||
Target = list()
|
||||
for idx in targetIdx:
|
||||
if idx in range(0, 7): # '0' has been restored in 0.28.3
|
||||
if idx in range(1, 7):
|
||||
Target.append( targetDic[idx] )
|
||||
|
||||
Build = opt.build
|
||||
|
|
@ -394,7 +380,7 @@ def Build_Deploy():
|
|||
|
||||
command1 = [ pyBuilder ] + buildOp[key]
|
||||
|
||||
if key in [ "std", "brewHW", "brewAHW" ] :
|
||||
if key in [ "brewHW", "brewAHW" ] :
|
||||
command2 = "time"
|
||||
command2 += " \\\n %s" % pyBuilder
|
||||
for option in buildOp[key]:
|
||||
|
|
|
|||
|
|
@ -31,12 +31,13 @@ def SetGlobals():
|
|||
Usage += "<< Usage of 'python3HB.py' >>\n"
|
||||
Usage += " to setup the standardized directory structures for Homebrew's Python 3.x on Mac\n"
|
||||
Usage += "\n"
|
||||
Usage += " option & argument : descriptions | default value\n"
|
||||
Usage += " -----------------------------------------------------------+---------------\n"
|
||||
Usage += " <-v|--version <number>>: in ['3.8', '3.9', '3.10', '3.11'] | ''\n"
|
||||
Usage += " [-u|-unlink] : unlink only | disabled\n"
|
||||
Usage += " [-?|--?] : print this usage and exit | disabled\n"
|
||||
Usage += "--------------------------------------------------------------+----------------------\n"
|
||||
Usage += " option & argument : descriptions | default value\n"
|
||||
Usage += " -------------------------------------------------------------------+----------\n"
|
||||
Usage += " <-v|--version <number>>: in ['3.8', '3.9', '3.10', '3.11', '3.12', | ''\n"
|
||||
Usage += " '3.13'] | ''\n"
|
||||
Usage += " [-u|-unlink] : unlink only | disabled\n"
|
||||
Usage += " [-?|--?] : print this usage and exit | disabled\n"
|
||||
Usage += "----------------------------------------------------------------------+--------------\n"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Parse the command line arguments
|
||||
|
|
@ -49,7 +50,7 @@ def Parse_CLI_Args():
|
|||
|
||||
p.add_option( '-v', '--version',
|
||||
dest='version',
|
||||
help="python3 version=['3.8', '3.9', '3.10', '3.11']" )
|
||||
help="python3 version=['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']" )
|
||||
|
||||
p.add_option( '-u', '--unlink',
|
||||
action='store_true',
|
||||
|
|
@ -74,7 +75,7 @@ def Parse_CLI_Args():
|
|||
|
||||
Version = opt.version
|
||||
UnlinkOnly = opt.unlink
|
||||
if not Version in [ '3.8', '3.9', '3.10', '3.11' ]:
|
||||
if not Version in [ '3.8', '3.9', '3.10', '3.11', '3.12', '3.13' ]:
|
||||
print( "! Unsupported Python 3 version <%s>" % Version )
|
||||
print(Usage)
|
||||
sys.exit(0)
|
||||
|
|
|
|||
|
|
@ -286,6 +286,25 @@ struct test_arg_func<gsi::ObjectType>
|
|||
return;
|
||||
}
|
||||
|
||||
if (arg.is_list ()) {
|
||||
|
||||
// we may implicitly convert an array into a constructor call of a target object -
|
||||
// for now we only check whether the number of arguments is compatible with the array given.
|
||||
|
||||
int n = int (arg.size ());
|
||||
|
||||
*ret = false;
|
||||
for (gsi::ClassBase::method_iterator c = atype.cls ()->begin_constructors (); c != atype.cls ()->end_constructors (); ++c) {
|
||||
if ((*c)->compatible_with_num_args (n)) {
|
||||
*ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (! arg.is_user ()) {
|
||||
*ret = false;
|
||||
return;
|
||||
|
|
@ -620,6 +639,8 @@ struct writer<gsi::VoidType>
|
|||
}
|
||||
};
|
||||
|
||||
void push_args (gsi::SerialArgs &arglist, const tl::Variant &args, const gsi::MethodBase *meth, tl::Heap *heap);
|
||||
|
||||
/**
|
||||
* @brief Specialization for void
|
||||
*/
|
||||
|
|
@ -628,29 +649,67 @@ struct writer<gsi::ObjectType>
|
|||
{
|
||||
void operator() (gsi::SerialArgs *aa, tl::Variant *arg, const gsi::ArgType &atype, tl::Heap *heap)
|
||||
{
|
||||
if (atype.is_ref () || atype.is_cref () || atype.is_ptr () || atype.is_cptr ()) {
|
||||
if (arg->is_nil ()) {
|
||||
|
||||
if (arg->is_nil ()) {
|
||||
if (atype.is_ref () || atype.is_cref ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot pass nil to reference parameters")));
|
||||
} else if (! atype.is_cptr () && ! atype.is_ptr ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot pass nil to direct parameters")));
|
||||
}
|
||||
|
||||
if (atype.is_ref () || atype.is_cref ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Cannot pass nil to reference parameters")));
|
||||
aa->write<void *> ((void *) 0);
|
||||
|
||||
} else if (arg->is_list ()) {
|
||||
|
||||
// we may implicitly convert an array into a constructor call of a target object -
|
||||
// for now we only check whether the number of arguments is compatible with the array given.
|
||||
|
||||
int n = int (arg->size ());
|
||||
const gsi::MethodBase *meth = 0;
|
||||
for (gsi::ClassBase::method_iterator c = atype.cls ()->begin_constructors (); c != atype.cls ()->end_constructors (); ++c) {
|
||||
if ((*c)->compatible_with_num_args (n)) {
|
||||
meth = *c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aa->write<void *> ((void *) 0);
|
||||
if (!meth) {
|
||||
throw tl::Exception (tl::to_string (tr ("No constructor of %s available that takes %d arguments (implicit call from tuple)")), atype.cls ()->name (), n);
|
||||
}
|
||||
|
||||
} else {
|
||||
// implicit call of constructor
|
||||
gsi::SerialArgs retlist (meth->retsize ());
|
||||
gsi::SerialArgs arglist (meth->argsize ());
|
||||
|
||||
if (! arg->is_user ()) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s)")), atype.cls ()->name ()));
|
||||
}
|
||||
push_args (arglist, *arg, meth, heap);
|
||||
|
||||
const tl::VariantUserClassBase *cls = arg->user_cls ();
|
||||
if (!cls) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s)")), atype.cls ()->name ()));
|
||||
}
|
||||
if (cls->is_const () && (atype.is_ref () || atype.is_ptr ())) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Cannot pass a const reference of class %s to a non-const reference or pointer parameter")), atype.cls ()->name ()));
|
||||
}
|
||||
meth->call (0, arglist, retlist);
|
||||
|
||||
void *new_obj = retlist.read<void *> (*heap);
|
||||
if (new_obj && (atype.is_ptr () || atype.is_cptr () || atype.is_ref () || atype.is_cref ())) {
|
||||
// For pointers or refs, ownership over these objects is not transferred.
|
||||
// Hence we have to keep them on the heap.
|
||||
// TODO: what if the called method takes ownership using keep()?
|
||||
heap->push (new gsi::ObjectHolder (atype.cls (), new_obj));
|
||||
}
|
||||
|
||||
aa->write<void *> (new_obj);
|
||||
|
||||
} else {
|
||||
|
||||
if (! arg->is_user ()) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s)")), atype.cls ()->name ()));
|
||||
}
|
||||
|
||||
const tl::VariantUserClassBase *cls = arg->user_cls ();
|
||||
if (!cls) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s)")), atype.cls ()->name ()));
|
||||
}
|
||||
if (cls->is_const () && (atype.is_ref () || atype.is_ptr ())) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Cannot pass a const reference of class %s to a non-const reference or pointer parameter")), atype.cls ()->name ()));
|
||||
}
|
||||
|
||||
if (atype.is_ref () || atype.is_cref () || atype.is_ptr () || atype.is_cptr ()) {
|
||||
|
||||
if (cls->gsi_cls ()->is_derived_from (atype.cls ())) {
|
||||
|
||||
|
|
@ -673,36 +732,24 @@ struct writer<gsi::ObjectType>
|
|||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s)")), atype.cls ()->name ()));
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
} else {
|
||||
if (cls->gsi_cls ()->is_derived_from (atype.cls ())) {
|
||||
|
||||
if (! arg->is_user ()) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s)")), atype.cls ()->name ()));
|
||||
}
|
||||
if (cls->gsi_cls ()->adapted_type_info ()) {
|
||||
aa->write<void *> (cls->gsi_cls ()->create_adapted_from_obj (get_object (*arg)));
|
||||
} else {
|
||||
aa->write<void *> ((void *) cls->gsi_cls ()->clone (get_object (*arg)));
|
||||
}
|
||||
|
||||
const tl::VariantUserClassBase *cls = arg->user_cls ();
|
||||
if (!cls) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s)")), atype.cls ()->name ()));
|
||||
}
|
||||
if (cls->is_const () && (atype.is_ref () || atype.is_ptr ())) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Cannot pass a const reference of class %s to a non-const reference or pointer parameter")), atype.cls ()->name ()));
|
||||
}
|
||||
} else if (cls->gsi_cls ()->can_convert_to (atype.cls ())) {
|
||||
|
||||
if (cls->gsi_cls ()->is_derived_from (atype.cls ())) {
|
||||
aa->write<void *> (atype.cls ()->create_obj_from (cls->gsi_cls (), get_object (*arg)));
|
||||
|
||||
if (cls->gsi_cls ()->adapted_type_info ()) {
|
||||
aa->write<void *> (cls->gsi_cls ()->create_adapted_from_obj (get_object (*arg)));
|
||||
} else {
|
||||
aa->write<void *> ((void *) cls->gsi_cls ()->clone (get_object (*arg)));
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s)")), atype.cls ()->name ()));
|
||||
}
|
||||
|
||||
} else if (cls->gsi_cls ()->can_convert_to (atype.cls ())) {
|
||||
|
||||
aa->write<void *> (atype.cls ()->create_obj_from (cls->gsi_cls (), get_object (*arg)));
|
||||
|
||||
} else {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s)")), atype.cls ()->name ()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -710,6 +757,23 @@ struct writer<gsi::ObjectType>
|
|||
}
|
||||
};
|
||||
|
||||
void push_args (gsi::SerialArgs &arglist, const tl::Variant &args, const gsi::MethodBase *meth, tl::Heap *heap)
|
||||
{
|
||||
int n = int (args.size ());
|
||||
int narg = 0;
|
||||
|
||||
for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments () && narg < n; ++a, ++narg) {
|
||||
try {
|
||||
// Note: this const_cast is ugly, but it will basically enable "out" parameters
|
||||
// TODO: clean this up.
|
||||
gsi::do_on_type<writer> () (a->type (), &arglist, const_cast<tl::Variant *> ((args.get_list ().begin () + narg).operator-> ()), *a, heap);
|
||||
} catch (tl::Exception &ex) {
|
||||
std::string msg = ex.msg () + tl::sprintf (tl::to_string (tr (" (argument '%s')")), a->spec ()->name ());
|
||||
throw tl::Exception (msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Reader function for serialization
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "gsi.h"
|
||||
#include "gsiSerialisation.h"
|
||||
#include "tlLog.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
|
@ -38,7 +39,14 @@ public:
|
|||
|
||||
~AdaptorSynchronizer ()
|
||||
{
|
||||
mp_src->copy_to (mp_target, *mp_heap);
|
||||
try {
|
||||
// NOTE: exceptions must not escape destructors as a basic C++ design requirement
|
||||
mp_src->copy_to (mp_target, *mp_heap);
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::error << ex.msg ();
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
delete mp_src;
|
||||
delete mp_target;
|
||||
mp_src = 0;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,20 @@ A::A (int nn) {
|
|||
f = false;
|
||||
}
|
||||
|
||||
A::A (int n1, int n2) {
|
||||
++a_count;
|
||||
e = Enum (0);
|
||||
n = n1 + n2;
|
||||
f = false;
|
||||
}
|
||||
|
||||
A::A (int n1, int n2, double n3) {
|
||||
++a_count;
|
||||
e = Enum (0);
|
||||
n = (n1 + n2) * n3;
|
||||
f = false;
|
||||
}
|
||||
|
||||
A::A (const A &a)
|
||||
: gsi::ObjectBase (a)
|
||||
{
|
||||
|
|
@ -339,7 +353,17 @@ static A *a_ctor (int i)
|
|||
return new A (i);
|
||||
}
|
||||
|
||||
void A::a20 (A *ptr)
|
||||
static A *a_ctor2 (int i, int j)
|
||||
{
|
||||
return new A (i, j);
|
||||
}
|
||||
|
||||
static A *a_ctor3 (int i, int j, double f)
|
||||
{
|
||||
return new A (i, j, f);
|
||||
}
|
||||
|
||||
void A::a20 (A *ptr)
|
||||
{
|
||||
if (a_inst.get () != ptr) {
|
||||
a_inst.reset (ptr);
|
||||
|
|
@ -360,26 +384,26 @@ static int b_count = 0;
|
|||
B::B ()
|
||||
{
|
||||
++b_count;
|
||||
av.push_back (A (100));
|
||||
av.push_back (A (121));
|
||||
av.push_back (A (144));
|
||||
avc_nc.push_back (new A_NC (-3100));
|
||||
avc_nc.push_back (new A_NC (-3121));
|
||||
av_nc.push_back (new A_NC (7100));
|
||||
av_nc.push_back (new A_NC (7121));
|
||||
av_nc.push_back (new A_NC (7144));
|
||||
av_nc.push_back (new A_NC (7169));
|
||||
m_av.push_back (A (100));
|
||||
m_av.push_back (A (121));
|
||||
m_av.push_back (A (144));
|
||||
m_avc_nc.push_back (new A_NC (-3100));
|
||||
m_avc_nc.push_back (new A_NC (-3121));
|
||||
m_av_nc.push_back (new A_NC (7100));
|
||||
m_av_nc.push_back (new A_NC (7121));
|
||||
m_av_nc.push_back (new A_NC (7144));
|
||||
m_av_nc.push_back (new A_NC (7169));
|
||||
}
|
||||
|
||||
B::~B ()
|
||||
{
|
||||
while (! av_nc.empty ()) {
|
||||
delete av_nc.back ();
|
||||
av_nc.pop_back ();
|
||||
while (! m_av_nc.empty ()) {
|
||||
delete m_av_nc.back ();
|
||||
m_av_nc.pop_back ();
|
||||
}
|
||||
while (! avc_nc.empty ()) {
|
||||
delete const_cast<A_NC *> (avc_nc.back ());
|
||||
avc_nc.pop_back ();
|
||||
while (! m_avc_nc.empty ()) {
|
||||
delete const_cast<A_NC *> (m_avc_nc.back ());
|
||||
m_avc_nc.pop_back ();
|
||||
}
|
||||
if (b_inst == this) {
|
||||
b_inst = 0;
|
||||
|
|
@ -405,22 +429,22 @@ B &B::operator=(const B &d)
|
|||
}
|
||||
|
||||
m = d.m;
|
||||
a = d.a;
|
||||
bv = d.bv;
|
||||
av = d.av;
|
||||
while (! av_nc.empty ()) {
|
||||
delete av_nc.back ();
|
||||
av_nc.pop_back ();
|
||||
m_a = d.m_a;
|
||||
m_bv = d.m_bv;
|
||||
m_av = d.m_av;
|
||||
while (! m_av_nc.empty ()) {
|
||||
delete m_av_nc.back ();
|
||||
m_av_nc.pop_back ();
|
||||
}
|
||||
for (std::vector <A_NC *>::const_iterator i = d.av_nc.begin (); i != d.av_nc.end (); ++i) {
|
||||
av_nc.push_back (new A_NC (**i));
|
||||
for (std::vector <A_NC *>::const_iterator i = d.m_av_nc.begin (); i != d.m_av_nc.end (); ++i) {
|
||||
m_av_nc.push_back (new A_NC (**i));
|
||||
}
|
||||
while (! avc_nc.empty ()) {
|
||||
delete const_cast<A_NC *> (avc_nc.back ());
|
||||
avc_nc.pop_back ();
|
||||
while (! m_avc_nc.empty ()) {
|
||||
delete const_cast<A_NC *> (m_avc_nc.back ());
|
||||
m_avc_nc.pop_back ();
|
||||
}
|
||||
for (std::vector <const A_NC *>::const_iterator i = d.avc_nc.begin (); i != d.avc_nc.end (); ++i) {
|
||||
avc_nc.push_back (new A_NC (**i));
|
||||
for (std::vector <const A_NC *>::const_iterator i = d.m_avc_nc.begin (); i != d.m_avc_nc.end (); ++i) {
|
||||
m_avc_nc.push_back (new A_NC (**i));
|
||||
}
|
||||
m_var = d.m_var;
|
||||
m_vars = d.m_vars;
|
||||
|
|
@ -461,7 +485,7 @@ std::string B::addr () const
|
|||
return c;
|
||||
}
|
||||
|
||||
static int b3_ext (const B *b, A *aptr)
|
||||
static int aptr_to_n_ext (const B *b, A *aptr)
|
||||
{
|
||||
return b->b3 (aptr);
|
||||
}
|
||||
|
|
@ -1030,6 +1054,8 @@ static gsi::QFlagsClass<Enum> decl_qflags_enum ("", "Enums");
|
|||
|
||||
static gsi::Class<A> decl_a ("", "A",
|
||||
gsi::constructor ("new_a|new", &a_ctor) +
|
||||
gsi::constructor ("new", &a_ctor2) +
|
||||
gsi::constructor ("new", &a_ctor3) +
|
||||
gsi::method ("instance_count", &A::instance_count) +
|
||||
gsi::method ("new_a_by_variant", &A::new_a_by_variant) +
|
||||
|
||||
|
|
@ -1146,8 +1172,8 @@ static gsi::Class<A> decl_a ("", "A",
|
|||
gsi::method ("af?|af", &A::af1) +
|
||||
gsi::method ("aa", &A::a) +
|
||||
gsi::method ("aa", &A::a_static) +
|
||||
gsi::method ("a1", &A::a1) +
|
||||
gsi::method ("a1c", &A::a1c) +
|
||||
gsi::method ("a1|get_n", &A::a1) +
|
||||
gsi::method ("a1c|get_n_const", &A::a1c) +
|
||||
gsi::method ("a2", &A::a2) +
|
||||
gsi::method ("a3", &A::a3) +
|
||||
#if defined(HAVE_QT)
|
||||
|
|
@ -1262,8 +1288,8 @@ static gsi::Class<B> decl_b ("", "B",
|
|||
gsi::method ("set_str", &B::set_str) +
|
||||
gsi::method ("str_ccptr", &B::str_ccptr) +
|
||||
gsi::method ("set_str_combine", &B::set_str_combine) +
|
||||
gsi::method_ext ("b3|aptr_to_n", &b3_ext) +
|
||||
gsi::method ("b4|aref_to_s", &B::b4) +
|
||||
gsi::method_ext ("b3|aptr_to_n", &aptr_to_n_ext) +
|
||||
gsi::method ("b4|aref_to_s", &B::aref_to_s) +
|
||||
gsi::method ("make_a", &B::make_a) +
|
||||
gsi::method ("set_an", &B::set_an) +
|
||||
gsi::method ("an", &B::an) +
|
||||
|
|
@ -1280,18 +1306,23 @@ static gsi::Class<B> decl_b ("", "B",
|
|||
gsi::method ("xxx|amember_cptr", &B::amember_cptr) +
|
||||
gsi::method ("yyy|amember_cref", &B::amember_cref) +
|
||||
gsi::method ("zzz|amember_ref", &B::amember_ref) +
|
||||
gsi::method ("b15|arg_is_not_nil", &B::b15) +
|
||||
gsi::method ("b16a|av", &B::b16a) +
|
||||
gsi::method ("b16b|av_cref", &B::b16b) +
|
||||
gsi::method ("b16c|av_ref", &B::b16c) +
|
||||
gsi::method ("b17a|av_cref=", &B::b17a) +
|
||||
gsi::method ("b17b|av_ref=", &B::b17b) +
|
||||
gsi::method ("b17c|av=", &B::b17c) +
|
||||
gsi::method ("b17d|av_cptr=", &B::b17d) +
|
||||
gsi::method ("b17e|av_ptr=", &B::b17e) +
|
||||
gsi::iterator ("b18", &B::b18) +
|
||||
gsi::iterator ("b18b", &B::b18b) +
|
||||
gsi::iterator ("b18c", &B::b18b) +
|
||||
gsi::method ("b15|arg_is_not_nil", &B::arg_is_not_nil) +
|
||||
gsi::method ("b16a|av", &B::av) +
|
||||
gsi::method ("b16b|av_cref", &B::av_cref) +
|
||||
gsi::method ("b16c|av_ref", &B::av_ref) +
|
||||
gsi::method ("push_a", &B::push_a) +
|
||||
gsi::method ("push_a_cref", &B::push_a_cref) +
|
||||
gsi::method ("push_a_cptr", &B::push_a_cptr) +
|
||||
gsi::method ("push_a_ref", &B::push_a_ref) +
|
||||
gsi::method ("push_a_ptr", &B::push_a_ptr) +
|
||||
gsi::method ("b17a|av_cref=", &B::set_av_cref) +
|
||||
gsi::method ("b17b|av_ref=", &B::set_av_ref) +
|
||||
gsi::method ("b17c|av=", &B::set_av) +
|
||||
gsi::method ("b17d|av_cptr=", &B::set_av_cptr) +
|
||||
gsi::method ("b17e|av_ptr=", &B::set_av_ptr) +
|
||||
gsi::iterator ("b18|each_a", &B::b18) +
|
||||
gsi::iterator ("b18b|each_a_ref", &B::b18b) +
|
||||
gsi::iterator ("b18c|each_a_ptr", &B::b18c) +
|
||||
gsi::method ("b20a|var_is_nil", &B::b20a) +
|
||||
gsi::method ("b20b|var_is_double", &B::b20b) +
|
||||
gsi::method ("b20c|var_is_long", &B::b20c) +
|
||||
|
|
|
|||
|
|
@ -73,7 +73,17 @@ struct A
|
|||
*/
|
||||
A (int nn);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Parametrized constructor 2
|
||||
*/
|
||||
A (int n1, int n2);
|
||||
|
||||
/**
|
||||
* @brief Parametrized constructor 3
|
||||
*/
|
||||
A (int n1, int n2, double n3);
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
A (const A &a);
|
||||
|
|
@ -640,7 +650,7 @@ struct B
|
|||
return aptr->n;
|
||||
}
|
||||
|
||||
std::string b4 (const A &aref) {
|
||||
std::string aref_to_s (const A &aref) {
|
||||
return tl::sprintf ("b4_result: %d", aref.n);
|
||||
}
|
||||
|
||||
|
|
@ -650,7 +660,7 @@ struct B
|
|||
|
||||
void set_an (int n)
|
||||
{
|
||||
a.n = n;
|
||||
m_a.n = n;
|
||||
}
|
||||
|
||||
int an (A a)
|
||||
|
|
@ -660,7 +670,7 @@ struct B
|
|||
|
||||
void set_an_cref (const int &n)
|
||||
{
|
||||
a.n = n;
|
||||
m_a.n = n;
|
||||
}
|
||||
|
||||
const int &an_cref (const A &a)
|
||||
|
|
@ -670,122 +680,155 @@ struct B
|
|||
|
||||
std::vector <A>::const_iterator b10b () const
|
||||
{
|
||||
return av.begin ();
|
||||
return m_av.begin ();
|
||||
}
|
||||
|
||||
std::vector <A>::const_iterator b10e () const
|
||||
{
|
||||
return av.end ();
|
||||
return m_av.end ();
|
||||
}
|
||||
|
||||
std::vector <A>::iterator b10b_nc ()
|
||||
{
|
||||
return av.begin ();
|
||||
return m_av.begin ();
|
||||
}
|
||||
|
||||
std::vector <A>::iterator b10e_nc ()
|
||||
{
|
||||
return av.end ();
|
||||
return m_av.end ();
|
||||
}
|
||||
|
||||
ValueIter<std::vector <A>::const_iterator> b11b () const
|
||||
{
|
||||
return ValueIter<std::vector <A>::const_iterator> (av.begin ());
|
||||
return ValueIter<std::vector <A>::const_iterator> (m_av.begin ());
|
||||
}
|
||||
|
||||
ValueIter<std::vector <A>::const_iterator> b11e () const
|
||||
{
|
||||
return ValueIter<std::vector <A>::const_iterator> (av.end ());
|
||||
return ValueIter<std::vector <A>::const_iterator> (m_av.end ());
|
||||
}
|
||||
|
||||
std::vector <A_NC *>::const_iterator b12b () const
|
||||
{
|
||||
return av_nc.begin ();
|
||||
return m_av_nc.begin ();
|
||||
}
|
||||
|
||||
std::vector <A_NC *>::const_iterator b12e () const
|
||||
{
|
||||
return av_nc.end ();
|
||||
return m_av_nc.end ();
|
||||
}
|
||||
|
||||
std::vector <const A_NC *>::const_iterator b13b () const
|
||||
{
|
||||
return avc_nc.begin ();
|
||||
return m_avc_nc.begin ();
|
||||
}
|
||||
|
||||
std::vector <const A_NC *>::const_iterator b13e () const
|
||||
{
|
||||
return avc_nc.end ();
|
||||
return m_avc_nc.end ();
|
||||
}
|
||||
|
||||
A *amember_or_nil (bool nn) { return nn ? &a : 0; }
|
||||
A *amember_ptr () { return &a; }
|
||||
A &amember_ref () { return a; }
|
||||
const A *amember_cptr () const { return &a; }
|
||||
const A &amember_cref () const { return a; }
|
||||
A *amember_or_nil (bool nn) { return nn ? &m_a : 0; }
|
||||
A *amember_ptr () { return &m_a; }
|
||||
A &amember_ref () { return m_a; }
|
||||
const A *amember_cptr () const { return &m_a; }
|
||||
const A &amember_cref () const { return m_a; }
|
||||
|
||||
bool b15 (A *a)
|
||||
bool arg_is_not_nil (A *a)
|
||||
{
|
||||
return a != 0;
|
||||
}
|
||||
|
||||
std::vector <A> b16a () const
|
||||
std::vector <A> av () const
|
||||
{
|
||||
return av;
|
||||
return m_av;
|
||||
}
|
||||
|
||||
const std::vector <A> &b16b () const
|
||||
const std::vector <A> &av_cref () const
|
||||
{
|
||||
return av;
|
||||
return m_av;
|
||||
}
|
||||
|
||||
std::vector <A> &b16c ()
|
||||
std::vector <A> &av_ref ()
|
||||
{
|
||||
return av;
|
||||
return m_av;
|
||||
}
|
||||
|
||||
void b17a (const std::vector <A> &v)
|
||||
void set_av_cref (const std::vector <A> &v)
|
||||
{
|
||||
av = v;
|
||||
m_av = v;
|
||||
}
|
||||
|
||||
void b17b (std::vector <A> &v)
|
||||
void set_av_ref (std::vector <A> &v)
|
||||
{
|
||||
av = v;
|
||||
m_av = v;
|
||||
}
|
||||
|
||||
void b17c (std::vector <A> v)
|
||||
void set_av (std::vector <A> v)
|
||||
{
|
||||
av = v;
|
||||
m_av = v;
|
||||
}
|
||||
|
||||
void b17d (const std::vector <A> *v)
|
||||
void set_av_cptr (const std::vector <A> *v)
|
||||
{
|
||||
if (v) {
|
||||
av = *v;
|
||||
m_av = *v;
|
||||
} else {
|
||||
m_av.clear ();
|
||||
}
|
||||
}
|
||||
|
||||
void b17e (std::vector <A> *v)
|
||||
void set_av_ptr (std::vector <A> *v)
|
||||
{
|
||||
if (v) {
|
||||
av = *v;
|
||||
m_av = *v;
|
||||
} else {
|
||||
m_av.clear ();
|
||||
}
|
||||
}
|
||||
|
||||
void push_a (A a)
|
||||
{
|
||||
m_av.push_back (a);
|
||||
}
|
||||
|
||||
void push_a_cref (const A &a)
|
||||
{
|
||||
m_av.push_back (a);
|
||||
}
|
||||
|
||||
void push_a_ref (A &a)
|
||||
{
|
||||
m_av.push_back (a);
|
||||
}
|
||||
|
||||
void push_a_cptr (const A *a)
|
||||
{
|
||||
if (a) {
|
||||
m_av.push_back (*a);
|
||||
}
|
||||
}
|
||||
|
||||
void push_a_ptr (A *a)
|
||||
{
|
||||
if (a) {
|
||||
m_av.push_back (*a);
|
||||
}
|
||||
}
|
||||
|
||||
FreeIter<std::vector <A>::const_iterator> b18 () const
|
||||
{
|
||||
return FreeIter<std::vector <A>::const_iterator> (av.begin (), av.end ());
|
||||
return FreeIter<std::vector <A>::const_iterator> (m_av.begin (), m_av.end ());
|
||||
}
|
||||
|
||||
FreeIterUseRef<std::vector <A>::const_iterator> b18b () const
|
||||
{
|
||||
return FreeIterUseRef<std::vector <A>::const_iterator> (av.begin (), av.end ());
|
||||
return FreeIterUseRef<std::vector <A>::const_iterator> (m_av.begin (), m_av.end ());
|
||||
}
|
||||
|
||||
FreeIterUsePtr<std::vector <A>::const_iterator> b18c () const
|
||||
{
|
||||
return FreeIterUsePtr<std::vector <A>::const_iterator> (av.begin (), av.end ());
|
||||
return FreeIterUsePtr<std::vector <A>::const_iterator> (m_av.begin (), m_av.end ());
|
||||
}
|
||||
|
||||
bool b20a (const tl::Variant &var) const { return var.is_nil (); }
|
||||
|
|
@ -862,30 +905,30 @@ struct B
|
|||
|
||||
FreeIter<std::vector <B>::const_iterator> each_b_copy () const
|
||||
{
|
||||
return FreeIter<std::vector <B>::const_iterator> (bv.begin (), bv.end ());
|
||||
return FreeIter<std::vector <B>::const_iterator> (m_bv.begin (), m_bv.end ());
|
||||
}
|
||||
|
||||
FreeIterUseRef<std::vector <B>::const_iterator> each_b_cref () const
|
||||
{
|
||||
return FreeIterUseRef<std::vector <B>::const_iterator> (bv.begin (), bv.end ());
|
||||
return FreeIterUseRef<std::vector <B>::const_iterator> (m_bv.begin (), m_bv.end ());
|
||||
}
|
||||
|
||||
FreeIterUsePtr<std::vector <B>::const_iterator> each_b_cptr () const
|
||||
{
|
||||
return FreeIterUsePtr<std::vector <B>::const_iterator> (bv.begin (), bv.end ());
|
||||
return FreeIterUsePtr<std::vector <B>::const_iterator> (m_bv.begin (), m_bv.end ());
|
||||
}
|
||||
|
||||
FreeIterUseRef<std::vector <B>::iterator> each_b_ref ()
|
||||
{
|
||||
return FreeIterUseRef<std::vector <B>::iterator> (bv.begin (), bv.end ());
|
||||
return FreeIterUseRef<std::vector <B>::iterator> (m_bv.begin (), m_bv.end ());
|
||||
}
|
||||
|
||||
FreeIterUsePtr<std::vector <B>::iterator> each_b_ptr ()
|
||||
{
|
||||
return FreeIterUsePtr<std::vector <B>::iterator> (bv.begin (), bv.end ());
|
||||
return FreeIterUsePtr<std::vector <B>::iterator> (m_bv.begin (), m_bv.end ());
|
||||
}
|
||||
|
||||
void push_b (const B &b) { bv.push_back (b); }
|
||||
void push_b (const B &b) { m_bv.push_back (b); }
|
||||
|
||||
std::map<int, A *> map_iaptr () { return m_map_iaptr; }
|
||||
const std::map<int, A *> &map_iaptr_cref () { return m_map_iaptr; }
|
||||
|
|
@ -996,11 +1039,11 @@ struct B
|
|||
#endif
|
||||
|
||||
std::string m;
|
||||
A a;
|
||||
std::vector <B> bv;
|
||||
std::vector <A> av;
|
||||
std::vector <A_NC *> av_nc;
|
||||
std::vector <const A_NC *> avc_nc;
|
||||
A m_a;
|
||||
std::vector <B> m_bv;
|
||||
std::vector <A> m_av;
|
||||
std::vector <A_NC *> m_av_nc;
|
||||
std::vector <const A_NC *> m_avc_nc;
|
||||
tl::Variant m_var;
|
||||
std::vector<tl::Variant> m_vars;
|
||||
std::map<int, std::string> m_map1;
|
||||
|
|
|
|||
|
|
@ -57,14 +57,14 @@ TEST(1)
|
|||
v = e.parse ("A.aa").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("static_a"));
|
||||
|
||||
v = e.parse ("A.new.a1").execute ();
|
||||
v = e.parse ("A.new.get_n").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("17"));
|
||||
v = e.parse ("var a=A.new").execute ();
|
||||
v = e.parse ("a.a5(-5); a.a1").execute ();
|
||||
v = e.parse ("a.a5(-5); a.get_n").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("-5"));
|
||||
|
||||
// mapping of property assignment to method
|
||||
v = e.parse ("a.n = -177; a.a1").execute ();
|
||||
v = e.parse ("a.n = -177; a.get_n").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("-177"));
|
||||
bool error = false;
|
||||
try {
|
||||
|
|
@ -104,9 +104,9 @@ TEST(1)
|
|||
v = e.parse ("A.instance_count").execute ();
|
||||
EXPECT_EQ (v.to_int (), base_insts); // remaining instances
|
||||
|
||||
v = e.parse ("var a1=A.new; a1.a5(-15); var a2=a1.dup; a2.a5(107); a1.a1").execute ();
|
||||
v = e.parse ("var a1=A.new; a1.a5(-15); var a2=a1.dup; a2.a5(107); a1.get_n").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("-15"));
|
||||
v = e.parse ("var a1=A.new; a1.a5(-15); var a2=a1.dup; a2.a5(107); a2.a1").execute ();
|
||||
v = e.parse ("var a1=A.new; a1.a5(-15); var a2=a1.dup; a2.a5(107); a2.get_n").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("107"));
|
||||
|
||||
v = e.parse ("var a=A.new; a.get_e.to_s").execute ();
|
||||
|
|
@ -218,12 +218,22 @@ TEST(2)
|
|||
EXPECT_EQ (v.to_string (), std::string ("5"));
|
||||
v = e.parse ("var b=B.new; var a1=A.new(-17); var a2=A.new(42); b.av = [ a1, a2 ]; to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: -17,A: 42"));
|
||||
v = e.parse ("var b=B.new; var a1=A.new(-17); var a2=A.new(42); b.av = []; b.push_a(a1); b.push_a(a2); to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: -17,A: 42"));
|
||||
v = e.parse ("var b=B.new; var a1=A.new(-17); var a2=A.new(42); b.av = []; b.push_a_cref(a1); b.push_a_cptr(a2); to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: -17,A: 42"));
|
||||
v = e.parse ("var b=B.new; var a1=A.new(-17); var a2=A.new(42); b.av = []; b.push_a_ref(a1); b.push_a_ptr(a2); to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: -17,A: 42"));
|
||||
v = e.parse ("var b=B.new; var a1=A.new(-17); var a2=A.new(1); b.av_cref = [ a1, a2 ]; to_s(b.av_cref)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: -17,A: 1"));
|
||||
v = e.parse ("var b=B.new; b.av = [ A.new(-13) ]; b.av_cptr = nil; to_s(b.av)").execute ();
|
||||
v = e.parse ("var b=B.new; b.av_cptr = [ A.new(-13) ]; to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: -13"));
|
||||
v = e.parse ("var b=B.new; b.av = [ A.new(13) ]; b.av_ptr = nil; to_s(b.av)").execute ();
|
||||
v = e.parse ("var b=B.new; b.av_ptr = [ A.new(13) ]; to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: 13"));
|
||||
v = e.parse ("var b=B.new; b.av = [ A.new(-13) ]; b.av_cptr = nil; to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string (""));
|
||||
v = e.parse ("var b=B.new; b.av = [ A.new(13) ]; b.av_ptr = nil; to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string (""));
|
||||
v = e.parse ("var b=B.new; var a1=A.new(17); b.av_ref = [ a1 ]; to_s(b.av_ref)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: 17"));
|
||||
v = e.parse ("var b=B.new; b.arg_is_not_nil(nil)").execute ();
|
||||
|
|
@ -234,6 +244,21 @@ TEST(2)
|
|||
EXPECT_EQ (v.to_string (), std::string ("17"));
|
||||
v = e.parse ("var b=B.new; b.bx(-1)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("xz"));
|
||||
|
||||
// List to constructor call
|
||||
v = e.parse ("var b=B.new; b.av = [ [5, 6], [4, 6, 0.5], [42] ]; to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: 11,A: 5,A: 42"));
|
||||
v = e.parse ("var b=B.new; b.av = []; b.push_a([ 1, 2 ]); b.push_a([ 17 ]); to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: 3,A: 17"));
|
||||
v = e.parse ("var b=B.new; b.av = []; b.push_a([ 1, 2 ]); b.push_a_cref([ 17 ]); to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: 3,A: 17"));
|
||||
v = e.parse ("var b=B.new; b.av = []; b.push_a([ 1, 2 ]); b.push_a_cptr([ 17 ]); to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: 3,A: 17"));
|
||||
v = e.parse ("var b=B.new; b.av = []; b.push_a([ 1, 2 ]); b.push_a_ref([ 17 ]); to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: 3,A: 17"));
|
||||
v = e.parse ("var b=B.new; b.av = []; b.push_a([ 1, 2 ]); b.push_a_ptr([ 17 ]); to_s(b.av)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("A: 3,A: 17"));
|
||||
|
||||
/*
|
||||
TODO: No detailed type analysis for ambiguity resolution so far:
|
||||
v = e.parse ("var b=B.new; b.bx('hello', 1)").execute ();
|
||||
|
|
@ -316,15 +341,15 @@ TEST(2)
|
|||
EXPECT_EQ (v.to_string (), std::string ("A: 177"));
|
||||
v = e.parse ("b.amember_or_nil(false)").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("nil"));
|
||||
v = e.parse ("b.amember_ptr.a5(177); b.amember_ref.a1").execute ();
|
||||
v = e.parse ("b.amember_ptr.a5(177); b.amember_ref.get_n").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("177"));
|
||||
v = e.parse ("b.amember_ref.a1c").execute ();
|
||||
v = e.parse ("b.amember_ref.get_n_const").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("177"));
|
||||
v = e.parse ("b.amember_cref.a1c").execute ();
|
||||
v = e.parse ("b.amember_cref.get_n_const").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("177"));
|
||||
error = false;
|
||||
try {
|
||||
v = e.parse ("b.amember_cref.a1").execute ();
|
||||
v = e.parse ("b.amember_cref.get_n").execute ();
|
||||
} catch (...) {
|
||||
// can't call non-const method on const ref
|
||||
error = true;
|
||||
|
|
@ -334,16 +359,16 @@ TEST(2)
|
|||
// references: storage in variables
|
||||
v = e.parse ("var aref = b.amember_ptr").execute ();
|
||||
v = e.parse ("aref.n = 178").execute ();
|
||||
v = e.parse ("aref.a1").execute ();
|
||||
v = e.parse ("aref.get_n").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("178"));
|
||||
v = e.parse ("aref.a1 == 178").execute ();
|
||||
v = e.parse ("aref.get_n == 178").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("true"));
|
||||
v = e.parse ("b.amember_ref.a1").execute ();
|
||||
v = e.parse ("b.amember_ref.get_n").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("178"));
|
||||
|
||||
// references: storage in variables
|
||||
v = e.parse ("var aref = b.amember_cptr").execute ();
|
||||
v = e.parse ("aref.a1c").execute ();
|
||||
v = e.parse ("aref.get_n_const").execute ();
|
||||
EXPECT_EQ (v.to_string (), std::string ("178"));
|
||||
error = false;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -104,9 +104,15 @@ equals(HAVE_PTHREADS, "1") {
|
|||
}
|
||||
|
||||
equals(HAVE_GIT2, "1") {
|
||||
!isEmpty(BITS_PATH) {
|
||||
include($$BITS_PATH/git2/git2.pri)
|
||||
!mac {
|
||||
!isEmpty(BITS_PATH) {
|
||||
include($$BITS_PATH/git2/git2.pri)
|
||||
} else {
|
||||
LIBS += -lgit2
|
||||
}
|
||||
} else {
|
||||
QMAKE_INCDIR += $$(MAC_LIBGIT2_INC)
|
||||
QMAKE_LFLAGS += -L$$(MAC_LIBGIT2_LIB)
|
||||
LIBS += -lgit2
|
||||
}
|
||||
DEFINES += HAVE_GIT2
|
||||
|
|
|
|||
|
|
@ -390,6 +390,8 @@ PythonInterpreter::~PythonInterpreter ()
|
|||
m_stdout = PythonPtr ();
|
||||
m_stderr = PythonPtr ();
|
||||
|
||||
sp_interpreter = 0;
|
||||
|
||||
if (m_embedded) {
|
||||
|
||||
Py_Finalize ();
|
||||
|
|
@ -400,8 +402,6 @@ PythonInterpreter::~PythonInterpreter ()
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
sp_interpreter = 0;
|
||||
}
|
||||
|
||||
char *
|
||||
|
|
|
|||
|
|
@ -200,7 +200,8 @@ match_method (int mid, PyObject *self, PyObject *args, bool strict)
|
|||
|
||||
tl_assert (cls_decl != 0);
|
||||
|
||||
int argc = args == NULL ? 0 : int (PyTuple_Size (args));
|
||||
bool is_tuple = PyTuple_Check (args);
|
||||
int argc = args == NULL ? 0 : (is_tuple ? int (PyTuple_Size (args)) : int (PyList_Size (args)));
|
||||
|
||||
// get number of candidates by argument count
|
||||
const gsi::MethodBase *meth = 0;
|
||||
|
|
@ -277,9 +278,10 @@ match_method (int mid, PyObject *self, PyObject *args, bool strict)
|
|||
int sc = 0;
|
||||
int i = 0;
|
||||
for (gsi::MethodBase::argument_iterator a = (*m)->begin_arguments (); is_valid && i < argc && a != (*m)->end_arguments (); ++a, ++i) {
|
||||
if (test_arg (*a, PyTuple_GetItem (args, i), false /*strict*/)) {
|
||||
PyObject *arg = is_tuple ? PyTuple_GetItem (args, i) : PyList_GetItem (args, i);
|
||||
if (test_arg (*a, arg, false /*strict*/)) {
|
||||
++sc;
|
||||
} else if (test_arg (*a, PyTuple_GetItem (args, i), true /*loose*/)) {
|
||||
} else if (test_arg (*a, arg, true /*loose*/)) {
|
||||
// non-scoring match
|
||||
} else {
|
||||
is_valid = false;
|
||||
|
|
@ -326,7 +328,8 @@ match_method (int mid, PyObject *self, PyObject *args, bool strict)
|
|||
// one candidate, but needs checking whether compatibility is given - this avoid having to route NotImplemented over TypeError exceptions later
|
||||
int i = 0;
|
||||
for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); i < argc && a != meth->end_arguments (); ++a, ++i) {
|
||||
if (! test_arg (*a, PyTuple_GetItem (args, i), true /*loose*/)) {
|
||||
PyObject *arg = is_tuple ? PyTuple_GetItem (args, i) : PyList_GetItem (args, i);
|
||||
if (! test_arg (*a, arg, true /*loose*/)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -607,16 +610,17 @@ special_method_impl (gsi::MethodBase::special_method_type smt, PyObject *self, P
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
push_args (gsi::SerialArgs &arglist, const gsi::MethodBase *meth, PyObject *args, tl::Heap &heap)
|
||||
{
|
||||
bool is_tuple = PyTuple_Check (args);
|
||||
int i = 0;
|
||||
int argc = args == NULL ? 0 : int (PyTuple_Size (args));
|
||||
int argc = args == NULL ? 0 : (is_tuple ? int (PyTuple_Size (args)) : int (PyList_Size (args)));
|
||||
|
||||
try {
|
||||
|
||||
for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); i < argc && a != meth->end_arguments (); ++a, ++i) {
|
||||
push_arg (*a, arglist, PyTuple_GetItem (args, i), heap);
|
||||
push_arg (*a, arglist, is_tuple ? PyTuple_GetItem (args, i) : PyList_GetItem (args, i), heap);
|
||||
}
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
|
|
@ -726,7 +730,7 @@ property_getter_adaptor (int mid, PyObject *self, PyObject *args)
|
|||
|
||||
PYA_TRY
|
||||
|
||||
int argc = args == NULL ? 0 : int (PyTuple_Size (args));
|
||||
int argc = args == NULL ? 0 : (PyTuple_Check (args) ? int (PyTuple_Size (args)) : int (PyList_Size (args)));
|
||||
if (argc != 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("Property getters must not have an argument")));
|
||||
}
|
||||
|
|
@ -747,12 +751,12 @@ property_setter_adaptor (int mid, PyObject *self, PyObject *args)
|
|||
|
||||
PYA_TRY
|
||||
|
||||
int argc = args == NULL ? 0 : int (PyTuple_Size (args));
|
||||
int argc = args == NULL ? 0 : (PyTuple_Check (args) ? int (PyTuple_Size (args)) : int (PyList_Size (args)));
|
||||
if (argc != 1) {
|
||||
throw tl::Exception (tl::to_string (tr ("Property setter needs exactly one argument")));
|
||||
}
|
||||
|
||||
PyObject *value = PyTuple_GetItem (args, 0);
|
||||
PyObject *value = PyTuple_Check (args) ? PyTuple_GetItem (args, 0) : PyList_GetItem (args, 0);
|
||||
if (value) {
|
||||
ret = property_setter_impl (mid, self, value);
|
||||
}
|
||||
|
|
@ -777,7 +781,8 @@ method_init_adaptor (int mid, PyObject *self, PyObject *args)
|
|||
p->destroy ();
|
||||
}
|
||||
|
||||
const gsi::MethodBase *meth = match_method (mid, self, args, PyTuple_Size (args) > 0 || ! p->cls_decl ()->can_default_create ());
|
||||
int argc = PyTuple_Check (args) ? int (PyTuple_Size (args)) : int (PyList_Size (args));
|
||||
const gsi::MethodBase *meth = match_method (mid, self, args, argc > 0 || ! p->cls_decl ()->can_default_create ());
|
||||
|
||||
if (meth && meth->smt () == gsi::MethodBase::None) {
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
namespace pya
|
||||
{
|
||||
|
||||
void push_args (gsi::SerialArgs &arglist, const gsi::MethodBase *meth, PyObject *args, tl::Heap &heap);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Serialization adaptors for strings, variants, vectors and maps
|
||||
|
||||
|
|
@ -43,9 +45,26 @@ class PythonBasedStringAdaptor
|
|||
{
|
||||
public:
|
||||
PythonBasedStringAdaptor (const PythonPtr &string)
|
||||
: m_stdstr (python2c<std::string> (string.get ())), m_string (string)
|
||||
: m_string (string)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
if (PyString_Check (string.get ())) {
|
||||
m_stdstr = python2c<std::string> (string.get ());
|
||||
} else
|
||||
#else
|
||||
if (PyBytes_Check (string.get ())) {
|
||||
m_stdstr = python2c<std::string> (string.get ());
|
||||
} else
|
||||
#endif
|
||||
if (PyUnicode_Check (string.get ()) || PyByteArray_Check (string.get ())) {
|
||||
m_stdstr = python2c<std::string> (string.get ());
|
||||
} else {
|
||||
// use object protocol to get the string through str(...)
|
||||
PythonRef as_str (PyObject_Str (string.get ()));
|
||||
if (as_str) {
|
||||
m_stdstr = python2c<std::string> (as_str.get ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char *c_str () const
|
||||
|
|
@ -454,6 +473,8 @@ struct writer<gsi::ObjectType>
|
|||
{
|
||||
void operator() (gsi::SerialArgs *aa, PyObject *arg, const gsi::ArgType &atype, tl::Heap *heap)
|
||||
{
|
||||
const gsi::ClassBase *acls = atype.cls ();
|
||||
|
||||
if (arg == Py_None || arg == NULL) {
|
||||
|
||||
if (! (atype.is_ptr () || atype.is_cptr ())) {
|
||||
|
|
@ -465,14 +486,50 @@ struct writer<gsi::ObjectType>
|
|||
|
||||
}
|
||||
|
||||
if (atype.is_ptr () || atype.is_cptr () || atype.is_ref () || atype.is_cref ()) {
|
||||
if (PyTuple_Check (arg) || PyList_Check (arg)) {
|
||||
|
||||
// we may implicitly convert a tuple into a constructor call of a target object -
|
||||
// for now we only check whether the number of arguments is compatible with the list given.
|
||||
|
||||
int n = PyTuple_Check (arg) ? int (PyTuple_Size (arg)) : int (PyList_Size (arg));
|
||||
const gsi::MethodBase *meth = 0;
|
||||
for (gsi::ClassBase::method_iterator c = acls->begin_constructors (); c != acls->end_constructors (); ++c) {
|
||||
if ((*c)->compatible_with_num_args (n)) {
|
||||
meth = *c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!meth) {
|
||||
throw tl::Exception (tl::to_string (tr ("No constructor of %s available that takes %d arguments (implicit call from tuple)")), acls->name (), n);
|
||||
}
|
||||
|
||||
// implicit call of constructor
|
||||
gsi::SerialArgs retlist (meth->retsize ());
|
||||
gsi::SerialArgs arglist (meth->argsize ());
|
||||
|
||||
push_args (arglist, meth, arg, *heap);
|
||||
|
||||
meth->call (0, arglist, retlist);
|
||||
|
||||
void *new_obj = retlist.read<void *> (*heap);
|
||||
if (new_obj && (atype.is_ptr () || atype.is_cptr () || atype.is_ref () || atype.is_cref ())) {
|
||||
// For pointers or refs, ownership over these objects is not transferred.
|
||||
// Hence we have to keep them on the heap.
|
||||
// TODO: what if the called method takes ownership using keep()?
|
||||
heap->push (new gsi::ObjectHolder (acls, new_obj));
|
||||
}
|
||||
|
||||
aa->write<void *> (new_obj);
|
||||
|
||||
} else if (atype.is_ptr () || atype.is_cptr () || atype.is_ref () || atype.is_cref ()) {
|
||||
|
||||
const gsi::ClassBase *cls_decl = PythonModule::cls_for_type (Py_TYPE (arg));
|
||||
if (! cls_decl) {
|
||||
throw tl::TypeError (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), Py_TYPE (arg)->tp_name));
|
||||
}
|
||||
|
||||
if (cls_decl->is_derived_from (atype.cls ())) {
|
||||
if (cls_decl->is_derived_from (acls)) {
|
||||
|
||||
PYAObjectBase *p = PYAObjectBase::from_pyobject (arg);
|
||||
|
||||
|
|
@ -483,14 +540,15 @@ struct writer<gsi::ObjectType>
|
|||
aa->write<void *> (p->obj ());
|
||||
}
|
||||
|
||||
} else if (cls_decl->can_convert_to (atype.cls ())) {
|
||||
} else if (cls_decl->can_convert_to (acls)) {
|
||||
|
||||
PYAObjectBase *p = PYAObjectBase::from_pyobject (arg);
|
||||
|
||||
// We can convert objects for cref and cptr, but ownership over these objects is not transferred.
|
||||
// Hence we have to keep them on the heap.
|
||||
void *new_obj = atype.cls ()->create_obj_from (p->cls_decl (), p->obj ());
|
||||
heap->push (new gsi::ObjectHolder (atype.cls (), new_obj));
|
||||
// TODO: what if the called method takes ownership using keep()?
|
||||
void *new_obj = acls->create_obj_from (p->cls_decl (), p->obj ());
|
||||
heap->push (new gsi::ObjectHolder (acls, new_obj));
|
||||
aa->write<void *> (new_obj);
|
||||
|
||||
} else {
|
||||
|
|
@ -504,7 +562,7 @@ struct writer<gsi::ObjectType>
|
|||
throw tl::TypeError (tl::sprintf (tl::to_string (tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), Py_TYPE (arg)->tp_name));
|
||||
}
|
||||
|
||||
if (cls_decl->is_derived_from (atype.cls ())) {
|
||||
if (cls_decl->is_derived_from (acls)) {
|
||||
|
||||
PYAObjectBase *p = PYAObjectBase::from_pyobject (arg);
|
||||
|
||||
|
|
@ -515,7 +573,7 @@ struct writer<gsi::ObjectType>
|
|||
aa->write<void *> (atype.cls ()->clone (p->obj ()));
|
||||
}
|
||||
|
||||
} else if (cls_decl->can_convert_to (atype.cls ())) {
|
||||
} else if (cls_decl->can_convert_to (acls)) {
|
||||
|
||||
PYAObjectBase *p = PYAObjectBase::from_pyobject (arg);
|
||||
aa->write<void *> (atype.cls ()->create_obj_from (cls_decl, p->obj ()));
|
||||
|
|
@ -887,8 +945,10 @@ void PythonBasedVectorAdaptor::push (gsi::SerialArgs &r, tl::Heap &heap)
|
|||
|
||||
void PythonBasedVectorAdaptor::clear ()
|
||||
{
|
||||
if (PySequence_Check (m_array.get ())) {
|
||||
PySequence_DelSlice (m_array.get (), 0, PySequence_Length (m_array.get ()));
|
||||
if (PyList_Check (m_array.get ())) {
|
||||
PyList_SetSlice (m_array.get (), 0, PyList_Size (m_array.get ()), NULL);
|
||||
} else if (PyTuple_Check (m_array.get ())) {
|
||||
throw tl::Exception (tl::to_string (tr ("Tuples cannot be modified and cannot be used as out parameters")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1141,19 +1201,38 @@ struct test_arg_func<gsi::ObjectType>
|
|||
{
|
||||
void operator() (bool *ret, PyObject *arg, const gsi::ArgType &atype, bool loose)
|
||||
{
|
||||
const gsi::ClassBase *acls = atype.cls ();
|
||||
|
||||
// for const X * or X *, null is an allowed value
|
||||
if ((atype.is_cptr () || atype.is_ptr ()) && arg == Py_None) {
|
||||
*ret = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (loose && (PyTuple_Check (arg) || PyList_Check (arg))) {
|
||||
|
||||
// we may implicitly convert a tuple into a constructor call of a target object -
|
||||
// for now we only check whether the number of arguments is compatible with the list given.
|
||||
|
||||
int n = PyTuple_Check (arg) ? int (PyTuple_Size (arg)) : int (PyList_Size (arg));
|
||||
*ret = false;
|
||||
for (gsi::ClassBase::method_iterator c = acls->begin_constructors (); c != acls->end_constructors (); ++c) {
|
||||
if ((*c)->compatible_with_num_args (n)) {
|
||||
*ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
const gsi::ClassBase *cls_decl = PythonModule::cls_for_type (Py_TYPE (arg));
|
||||
if (! cls_decl) {
|
||||
*ret = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (! (cls_decl == atype.cls () || (loose && (cls_decl->is_derived_from (atype.cls ()) || cls_decl->can_convert_to(atype.cls ()))))) {
|
||||
if (! (cls_decl == acls || (loose && (cls_decl->is_derived_from (atype.cls ()) || cls_decl->can_convert_to (atype.cls ()))))) {
|
||||
*ret = false;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,8 +117,9 @@ void check_error ()
|
|||
} else if (PyErr_GivenExceptionMatches (exc_type.get (), PyExc_SystemExit)) {
|
||||
|
||||
int status = 0;
|
||||
if (exc_value && test_type<int> (exc_value.get (), true)) {
|
||||
status = python2c<int> (exc_value.get ());
|
||||
if (exc_value) {
|
||||
tl::Variant st = python2c<tl::Variant> (exc_value.get ());
|
||||
status = st.to_int ();
|
||||
}
|
||||
|
||||
throw tl::ExitException (status);
|
||||
|
|
|
|||
|
|
@ -943,7 +943,7 @@ static gsi::ArgType create_void_type ()
|
|||
|
||||
static gsi::ArgType s_void_type = create_void_type ();
|
||||
|
||||
static void
|
||||
void
|
||||
push_args (gsi::SerialArgs &arglist, const gsi::MethodBase *meth, VALUE *argv, int argc, tl::Heap &heap)
|
||||
{
|
||||
int i = 0;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
namespace rba
|
||||
{
|
||||
|
||||
void push_args (gsi::SerialArgs &arglist, const gsi::MethodBase *meth, VALUE *argv, int argc, tl::Heap &heap);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Serialization adaptors for strings, variants, vectors and maps
|
||||
|
||||
|
|
@ -46,7 +48,7 @@ class RubyBasedStringAdaptor
|
|||
public:
|
||||
RubyBasedStringAdaptor (VALUE value)
|
||||
{
|
||||
m_string = rba_safe_string_value (value);
|
||||
m_string = rba_safe_obj_as_string (value);
|
||||
gc_lock_object (m_string);
|
||||
}
|
||||
|
||||
|
|
@ -497,6 +499,42 @@ struct writer <gsi::ObjectType>
|
|||
aa->write<void *> ((void *) 0);
|
||||
}
|
||||
|
||||
} else if (TYPE (arg) == T_ARRAY) {
|
||||
|
||||
// we may implicitly convert an array into a constructor call of a target object -
|
||||
// for now we only check whether the number of arguments is compatible with the array given.
|
||||
|
||||
int n = RARRAY_LEN (arg);
|
||||
const gsi::MethodBase *meth = 0;
|
||||
for (gsi::ClassBase::method_iterator c = atype.cls ()->begin_constructors (); c != atype.cls ()->end_constructors (); ++c) {
|
||||
if ((*c)->compatible_with_num_args (n)) {
|
||||
meth = *c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!meth) {
|
||||
throw tl::Exception (tl::to_string (tr ("No constructor of %s available that takes %d arguments (implicit call from tuple)")), atype.cls ()->name (), n);
|
||||
}
|
||||
|
||||
// implicit call of constructor
|
||||
gsi::SerialArgs retlist (meth->retsize ());
|
||||
gsi::SerialArgs arglist (meth->argsize ());
|
||||
|
||||
push_args (arglist, meth, RARRAY_PTR (arg), n, *heap);
|
||||
|
||||
meth->call (0, arglist, retlist);
|
||||
|
||||
void *new_obj = retlist.read<void *> (*heap);
|
||||
if (new_obj && (atype.is_ptr () || atype.is_cptr () || atype.is_ref () || atype.is_cref ())) {
|
||||
// For pointers or refs, ownership over these objects is not transferred.
|
||||
// Hence we have to keep them on the heap.
|
||||
// TODO: what if the called method takes ownership using keep()?
|
||||
heap->push (new gsi::ObjectHolder (atype.cls (), new_obj));
|
||||
}
|
||||
|
||||
aa->write<void *> (new_obj);
|
||||
|
||||
} else {
|
||||
|
||||
if (TYPE (arg) != T_DATA) {
|
||||
|
|
@ -1152,6 +1190,21 @@ struct test_arg_func<gsi::ObjectType>
|
|||
// for const X * or X *, nil is an allowed value
|
||||
*ret = true;
|
||||
|
||||
} else if (loose && TYPE (arg) == T_ARRAY) {
|
||||
|
||||
// we may implicitly convert an array into a constructor call of a target object -
|
||||
// for now we only check whether the number of arguments is compatible with the array given.
|
||||
|
||||
int n = RARRAY_LEN (arg);
|
||||
|
||||
*ret = false;
|
||||
for (gsi::ClassBase::method_iterator c = atype.cls ()->begin_constructors (); c != atype.cls ()->end_constructors (); ++c) {
|
||||
if ((*c)->compatible_with_num_args (n)) {
|
||||
*ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
*ret = (TYPE (arg) == T_DATA);
|
||||
|
|
|
|||
|
|
@ -265,7 +265,17 @@ bool TestBase::do_test (bool editable, bool slow)
|
|||
|
||||
reset_checkpoint ();
|
||||
|
||||
execute (this);
|
||||
try {
|
||||
execute (this);
|
||||
} catch (tl::CancelException &) {
|
||||
throw;
|
||||
} catch (tl::Exception &ex) {
|
||||
raise (std::string ("Exception caught: ") + ex.msg ());
|
||||
} catch (std::runtime_error &ex) {
|
||||
raise (std::string ("std::runtime_error caught: ") + ex.what ());
|
||||
} catch (...) {
|
||||
raise (std::string ("unspecific exception caught: "));
|
||||
}
|
||||
|
||||
m_testtmp.clear ();
|
||||
|
||||
|
|
|
|||
|
|
@ -191,6 +191,18 @@ class KLayoutMain_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def test_12
|
||||
|
||||
# Application.exit(0) - Python
|
||||
out = `#{self.klayout_bin} -z -r #{File.join(File.dirname(__FILE__), "test12.py")} 2>&1`
|
||||
assert_equal(out, "Before exit()\n")
|
||||
|
||||
# Application.exit(0) - Ruby
|
||||
out = `#{self.klayout_bin} -z -r #{File.join(File.dirname(__FILE__), "test12.rb")} 2>&1`
|
||||
assert_equal(out, "Before exit()\n")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
print("Before exit()")
|
||||
pya.Application.instance().exit(0)
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
$stdout.puts("Before exit()")
|
||||
$stdout.flush
|
||||
RBA::Application::instance.exit(0)
|
||||
|
||||
|
|
@ -26,6 +26,12 @@ import copy
|
|||
# Set this to True to disable some tests involving exceptions
|
||||
leak_check = "TEST_LEAK_CHECK" in os.environ
|
||||
|
||||
class ObjectWithStr:
|
||||
def __init__(self, s):
|
||||
self.s = s
|
||||
def __str__(self):
|
||||
return self.s
|
||||
|
||||
# see test_21
|
||||
class AEXT(pya.A):
|
||||
def __init__(self):
|
||||
|
|
@ -35,7 +41,7 @@ class AEXT(pya.A):
|
|||
def g(self):
|
||||
return self.offset
|
||||
def m(self):
|
||||
return self.offset+self.a1()
|
||||
return self.offset+self.get_n()
|
||||
# Note: there are no protected methods, but this emulates the respective test for RBA
|
||||
def call_a10_prot(self, f):
|
||||
a10_prot(f)
|
||||
|
|
@ -43,7 +49,7 @@ class AEXT(pya.A):
|
|||
return str(self.offset)
|
||||
|
||||
def repr_of_a(self):
|
||||
return "a1=" + str(self.a1())
|
||||
return "a1=" + str(self.get_n())
|
||||
|
||||
pya.A.__repr__ = repr_of_a
|
||||
|
||||
|
|
@ -150,9 +156,9 @@ class BasicTest(unittest.TestCase):
|
|||
self.assertEqual( pya.A.instance_count(), ic0 + 1 )
|
||||
|
||||
a = pya.A()
|
||||
self.assertEqual(a.a1(), 17)
|
||||
self.assertEqual(a.get_n(), 17)
|
||||
a.assign(pya.A(110))
|
||||
self.assertEqual(a.a1(), 110)
|
||||
self.assertEqual(a.get_n(), 110)
|
||||
|
||||
a = None
|
||||
self.assertEqual( pya.A.instance_count(), ic0 )
|
||||
|
|
@ -182,15 +188,16 @@ class BasicTest(unittest.TestCase):
|
|||
self.assertEqual( pya.A.aa(), "static_a" )
|
||||
self.assertEqual( a.aa(), "a" )
|
||||
|
||||
self.assertEqual( a.a1(), 17 )
|
||||
self.assertEqual( a.get_n(), 17 )
|
||||
a.a5(-5)
|
||||
self.assertEqual( a.a1(), -5 )
|
||||
self.assertEqual( a.get_n(), -5 )
|
||||
a.a5(0x7fffffff)
|
||||
self.assertEqual( a.a1(), 0x7fffffff )
|
||||
self.assertEqual( a.get_n(), 0x7fffffff )
|
||||
a.a5(-0x80000000)
|
||||
self.assertEqual( a.a1(), -0x80000000 )
|
||||
self.assertEqual( a.get_n(), -0x80000000 )
|
||||
|
||||
self.assertEqual( a.a3("a"), 1 )
|
||||
self.assertEqual( a.a3(ObjectWithStr("abcde")), 5 ) # implicitly using to_s for string conversion
|
||||
self.assertEqual( a.a3("ab"), 2 )
|
||||
self.assertEqual( a.a3("µ"), 2 ) # two UTF8 bytes
|
||||
if "a3_qstr" in a.__dict__:
|
||||
|
|
@ -249,7 +256,7 @@ class BasicTest(unittest.TestCase):
|
|||
self.assertEqual( pya.A.instance_count(), ic0 )
|
||||
a = pya.A.new_a( 55 )
|
||||
self.assertEqual( pya.A.instance_count(), ic0 + 1 )
|
||||
self.assertEqual( a.a1(), 55 )
|
||||
self.assertEqual( a.get_n(), 55 )
|
||||
self.assertEqual( a.a_vp1( a.a_vp2() ), "abc" )
|
||||
a.destroy()
|
||||
self.assertEqual( pya.A.instance_count(), ic0 )
|
||||
|
|
@ -403,9 +410,9 @@ class BasicTest(unittest.TestCase):
|
|||
a = pya.A.new_a_by_variant()
|
||||
self.assertEqual(pya.A.instance_count(), ic0 + 1)
|
||||
|
||||
self.assertEqual(a.a1(), 17)
|
||||
self.assertEqual(a.get_n(), 17)
|
||||
a.a5(-15)
|
||||
self.assertEqual(a.a1(), -15)
|
||||
self.assertEqual(a.get_n(), -15)
|
||||
|
||||
a = None
|
||||
self.assertEqual(pya.A.instance_count(), ic0)
|
||||
|
|
@ -422,6 +429,85 @@ class BasicTest(unittest.TestCase):
|
|||
b._destroy()
|
||||
self.assertEqual(pya.B.instance_count(), ic0)
|
||||
|
||||
def test_11(self):
|
||||
|
||||
# implicitly converting tuples/lists to objects by calling the constructor
|
||||
|
||||
b = pya.B()
|
||||
b.av_cptr = [ pya.A(17), [1,2], [4,6,0.5] ]
|
||||
|
||||
arr = []
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [17, 3, 5])
|
||||
|
||||
b = pya.B()
|
||||
# NOTE: this gives an error (printed only) that tuples can't be modified as out parameters
|
||||
b.av_ref = ( (1,2), (6,2,0.25), [42] )
|
||||
|
||||
arr = []
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [3, 2, 42])
|
||||
|
||||
b = pya.B()
|
||||
aa = [ (1,2), (6,2,0.25), [42] ]
|
||||
b.av_ptr = aa
|
||||
|
||||
arr = []
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [3, 2, 42])
|
||||
|
||||
# NOTE: as we used aa in "av_ptr", it got modified as out parameter and
|
||||
# now holds A object references
|
||||
arr = []
|
||||
for a in aa:
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [3, 2, 42])
|
||||
|
||||
b.av = ()
|
||||
|
||||
arr = []
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [])
|
||||
|
||||
b.push_a_ref( (1, 7) )
|
||||
|
||||
arr = []
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [8])
|
||||
|
||||
b.push_a_ptr( (1, 7, 0.25) )
|
||||
|
||||
arr = []
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [8, 2])
|
||||
|
||||
b.push_a_cref( [42] )
|
||||
|
||||
arr = []
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [8, 2, 42])
|
||||
|
||||
b.push_a_cptr( (1, 16) )
|
||||
|
||||
arr = []
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [8, 2, 42, 17])
|
||||
|
||||
b.push_a( (4, 6, 0.5) )
|
||||
|
||||
arr = []
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [8, 2, 42, 17, 5])
|
||||
|
||||
def test_12(self):
|
||||
|
||||
a1 = pya.A()
|
||||
|
|
@ -429,16 +515,16 @@ class BasicTest(unittest.TestCase):
|
|||
a2 = a1
|
||||
a3 = a2.dup()
|
||||
|
||||
self.assertEqual( a1.a1(), -15 )
|
||||
self.assertEqual( a2.a1(), -15 )
|
||||
self.assertEqual( a3.a1(), -15 )
|
||||
self.assertEqual( a1.get_n(), -15 )
|
||||
self.assertEqual( a2.get_n(), -15 )
|
||||
self.assertEqual( a3.get_n(), -15 )
|
||||
|
||||
a1.a5( 11 )
|
||||
a3.a5( -11 )
|
||||
|
||||
self.assertEqual( a1.a1(), 11 )
|
||||
self.assertEqual( a2.a1(), 11 )
|
||||
self.assertEqual( a3.a1(), -11 )
|
||||
self.assertEqual( a1.get_n(), 11 )
|
||||
self.assertEqual( a2.get_n(), 11 )
|
||||
self.assertEqual( a3.get_n(), -11 )
|
||||
|
||||
self.assertEqual( a1.a10_d(5.2), "5.2" )
|
||||
self.assertEqual( a1.a10_s(0x70000000), "0" )
|
||||
|
|
@ -651,7 +737,7 @@ class BasicTest(unittest.TestCase):
|
|||
|
||||
err_caught = False
|
||||
try:
|
||||
b.amember_cptr().a1() # cannot call non-const method on const reference
|
||||
b.amember_cptr().get_n() # cannot call non-const method on const reference
|
||||
except:
|
||||
err_caught = True
|
||||
self.assertEqual( err_caught, True )
|
||||
|
|
@ -675,7 +761,7 @@ class BasicTest(unittest.TestCase):
|
|||
|
||||
try:
|
||||
for a in b.b10():
|
||||
arr.append(a.a1()) # b10 is a const iterator - cannot call a1 on it
|
||||
arr.append(a.get_n()) # b10 is a const iterator - cannot call a1 on it
|
||||
except:
|
||||
err_caught = True
|
||||
self.assertEqual( err_caught, True )
|
||||
|
|
@ -687,7 +773,7 @@ class BasicTest(unittest.TestCase):
|
|||
|
||||
try:
|
||||
for a in b.b10p():
|
||||
arr.append(a.a1()) # b10p is a const iterator - cannot call a1 on it
|
||||
arr.append(a.get_n()) # b10p is a const iterator - cannot call a1 on it
|
||||
except:
|
||||
err_caught = True
|
||||
self.assertEqual( err_caught, True )
|
||||
|
|
@ -695,7 +781,7 @@ class BasicTest(unittest.TestCase):
|
|||
|
||||
arr = []
|
||||
for a in b.b10():
|
||||
arr.append(a.dup().a1())
|
||||
arr.append(a.dup().get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
|
|
@ -706,99 +792,99 @@ class BasicTest(unittest.TestCase):
|
|||
# destroyed too early.
|
||||
bdup = b.dup()
|
||||
for a in bdup.b10():
|
||||
arr.append(a.dup().a1())
|
||||
arr.append(a.dup().get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
return
|
||||
|
||||
arr = []
|
||||
for a in b.b10():
|
||||
arr.append(a.a1c())
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
for a in b.b10p():
|
||||
arr.append(a.dup().a1())
|
||||
arr.append(a.dup().get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
# Ticket #811:
|
||||
for a in b.dup().b10p():
|
||||
arr.append(a.dup().a1())
|
||||
arr.append(a.dup().get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
bdup = b.dup()
|
||||
for a in bdup.b10p():
|
||||
arr.append(a.dup().a1())
|
||||
arr.append(a.dup().get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
for a in b.b10p():
|
||||
arr.append(a.a1c())
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
for a in b.b11():
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
bdup = b.dup()
|
||||
for a in bdup.b11():
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
for a in b.b12():
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [7100, 7121, 7144, 7169])
|
||||
|
||||
arr = []
|
||||
bdup = b.dup()
|
||||
for a in bdup.b12():
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [7100, 7121, 7144, 7169])
|
||||
|
||||
aarr = b.b16a()
|
||||
arr = []
|
||||
for a in aarr:
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
aarr = b.b16b()
|
||||
arr = []
|
||||
for a in aarr:
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
aarr = b.b16c()
|
||||
arr = []
|
||||
for a in aarr:
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
b.b17a( [ pya.A.new_a( 101 ), pya.A.new_a( -122 ) ] )
|
||||
arr = []
|
||||
for a in b.b11():
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [101, -122])
|
||||
|
||||
b.b17a( [] )
|
||||
arr = []
|
||||
for a in b.b11():
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [])
|
||||
|
||||
b.b17b( [ pya.A.new_a( 102 ), pya.A.new_a( -123 ) ] )
|
||||
arr = []
|
||||
for a in b.b11():
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [102, -123])
|
||||
|
||||
b.b17c( [ pya.A.new_a( 100 ), pya.A.new_a( 121 ), pya.A.new_a( 144 ) ] )
|
||||
arr = []
|
||||
for a in b.b11():
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
if not leak_check:
|
||||
|
|
@ -806,7 +892,7 @@ class BasicTest(unittest.TestCase):
|
|||
arr = []
|
||||
try:
|
||||
for a in b.b13():
|
||||
arr.append(a.a1())
|
||||
arr.append(a.get_n())
|
||||
except:
|
||||
err_caught = True
|
||||
self.assertEqual( err_caught, True )
|
||||
|
|
@ -814,28 +900,28 @@ class BasicTest(unittest.TestCase):
|
|||
|
||||
arr = []
|
||||
for a in b.b13():
|
||||
arr.append(a.a1c())
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [-3100, -3121])
|
||||
|
||||
arr = []
|
||||
bdup = b.dup()
|
||||
for a in bdup.b13():
|
||||
arr.append(a.a1c())
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [-3100, -3121])
|
||||
|
||||
arr = []
|
||||
for a in b.b18():
|
||||
arr.append(a.a1c())
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
for a in b.b18():
|
||||
arr.append(a.a1())
|
||||
for a in b.each_a():
|
||||
arr.append(a.get_n())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
for a in b.b18b():
|
||||
arr.append(a.a1c())
|
||||
for a in b.each_a_ref():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
|
|
@ -843,8 +929,8 @@ class BasicTest(unittest.TestCase):
|
|||
# since A is a managed object and is not turned into a copy.
|
||||
err_caught = False
|
||||
try:
|
||||
for a in b.b18b():
|
||||
arr.append(a.a1())
|
||||
for a in b.each_a_ref():
|
||||
arr.append(a.get_n())
|
||||
except:
|
||||
err_caught = True
|
||||
end
|
||||
|
|
@ -852,17 +938,17 @@ class BasicTest(unittest.TestCase):
|
|||
self.assertEqual(err_caught, True)
|
||||
|
||||
arr = []
|
||||
for a in b.b18c():
|
||||
arr.append(a.a1c())
|
||||
for a in b.each_a_ptr():
|
||||
arr.append(a.get_n_const())
|
||||
self.assertEqual(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
# this does not work since b18c delivers a "const *" which cannot be used to call a non-const
|
||||
# this does not work since each_a_ptr delivers a "const *" which cannot be used to call a non-const
|
||||
# method on
|
||||
err_caught = False
|
||||
try:
|
||||
for a in b.b18c():
|
||||
arr.append(a.a1())
|
||||
for a in b.each_a_ptr():
|
||||
arr.append(a.get_n())
|
||||
except:
|
||||
err_caught = True
|
||||
end
|
||||
|
|
@ -1035,23 +1121,23 @@ class BasicTest(unittest.TestCase):
|
|||
a_count = pya.A.instance_count()
|
||||
a = b.make_a( 1971 );
|
||||
self.assertEqual( pya.A.instance_count(), a_count + 1 )
|
||||
self.assertEqual( a.a1(), 1971 );
|
||||
self.assertEqual( a.get_n(), 1971 );
|
||||
self.assertEqual( b.an( a ), 1971 );
|
||||
|
||||
aa = b.make_a( -61 );
|
||||
self.assertEqual( pya.A.instance_count(), a_count + 2 )
|
||||
self.assertEqual( b.an_cref( aa ), -61 );
|
||||
self.assertEqual( a.a1(), 1971 );
|
||||
self.assertEqual( a.get_n(), 1971 );
|
||||
self.assertEqual( b.an( a ), 1971 );
|
||||
self.assertEqual( aa.a1(), -61 );
|
||||
self.assertEqual( aa.get_n(), -61 );
|
||||
self.assertEqual( b.an( aa ), -61 );
|
||||
|
||||
aa.a5(98);
|
||||
a.a5(100);
|
||||
|
||||
self.assertEqual( a.a1(), 100 );
|
||||
self.assertEqual( a.get_n(), 100 );
|
||||
self.assertEqual( b.an( a ), 100 );
|
||||
self.assertEqual( aa.a1(), 98 );
|
||||
self.assertEqual( aa.get_n(), 98 );
|
||||
self.assertEqual( b.an( aa ), 98 );
|
||||
|
||||
a._destroy()
|
||||
|
|
@ -1064,10 +1150,10 @@ class BasicTest(unittest.TestCase):
|
|||
|
||||
b = pya.B()
|
||||
b.set_an( 77 )
|
||||
self.assertEqual( b.amember_cptr().a1c(), 77 );
|
||||
self.assertEqual( b.amember_cptr().get_n_const(), 77 );
|
||||
|
||||
b.set_an_cref( 79 )
|
||||
self.assertEqual( b.amember_cptr().a1c(), 79 );
|
||||
self.assertEqual( b.amember_cptr().get_n_const(), 79 );
|
||||
|
||||
aref = b.amember_cptr()
|
||||
err_caught = False
|
||||
|
|
@ -1075,14 +1161,14 @@ class BasicTest(unittest.TestCase):
|
|||
if not leak_check:
|
||||
|
||||
try:
|
||||
x = aref.a1() # cannot call non-const method on const reference (as delivered by amember_cptr)
|
||||
x = aref.get_n() # cannot call non-const method on const reference (as delivered by amember_cptr)
|
||||
except:
|
||||
err_caught = True
|
||||
self.assertEqual( err_caught, True )
|
||||
self.assertEqual( aref.a1c(), 79 );
|
||||
self.assertEqual( aref.get_n_const(), 79 );
|
||||
|
||||
b.set_an( -1 )
|
||||
self.assertEqual( aref.a1c(), -1 );
|
||||
self.assertEqual( aref.get_n_const(), -1 );
|
||||
|
||||
def test_19(self):
|
||||
|
||||
|
|
@ -1140,11 +1226,11 @@ class BasicTest(unittest.TestCase):
|
|||
|
||||
a1 = b.amember_or_nil_alt( True )
|
||||
a2 = b.amember_ptr_alt()
|
||||
self.assertEqual( a1.a1(), 17 )
|
||||
self.assertEqual( a2.a1(), 17 )
|
||||
self.assertEqual( a1.get_n(), 17 )
|
||||
self.assertEqual( a2.get_n(), 17 )
|
||||
a1.a5( 761 )
|
||||
self.assertEqual( a1.a1(), 761 )
|
||||
self.assertEqual( a2.a1(), 761 )
|
||||
self.assertEqual( a1.get_n(), 761 )
|
||||
self.assertEqual( a2.get_n(), 761 )
|
||||
|
||||
a1 = b.amember_or_nil( False )
|
||||
self.assertEqual( a1, None )
|
||||
|
|
@ -2279,13 +2365,8 @@ class BasicTest(unittest.TestCase):
|
|||
self.assertEqual(b.map1_cptr_null() == None, True);
|
||||
self.assertEqual(b.map1_ptr_null() == None, True);
|
||||
|
||||
try:
|
||||
# error converting 1 or True to string
|
||||
b.map1 = { 42: 1, -17: True }
|
||||
error_caught = False
|
||||
except:
|
||||
error_caught = True
|
||||
self.assertEqual(error_caught, True)
|
||||
b.map1 = { 42: 1, -17: True }
|
||||
self.assertEqual(map2str(b.map1), "{-17: True, 42: 1}")
|
||||
|
||||
b.map1 = { 42: "1", -17: "True" }
|
||||
self.assertEqual(map2str(b.map1), "{-17: True, 42: 1}")
|
||||
|
|
|
|||
|
|
@ -4,6 +4,19 @@
|
|||
# safe in multiple inclusions
|
||||
require File.expand_path('../basic_testcore_defs', __FILE__)
|
||||
|
||||
|
||||
class ObjectWithStr
|
||||
|
||||
def initialize(s)
|
||||
@s = s
|
||||
end
|
||||
|
||||
def to_s
|
||||
@s
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Basic_TestClass < TestBase
|
||||
|
||||
def test_FIRST
|
||||
|
|
@ -21,9 +34,9 @@ class Basic_TestClass < TestBase
|
|||
assert_equal( RBA::A::instance_count, ic0 + 1 )
|
||||
|
||||
a = RBA::A.new
|
||||
assert_equal(a.a1, 17)
|
||||
assert_equal(a.get_n, 17)
|
||||
a.assign(RBA::A.new(110))
|
||||
assert_equal(a.a1, 110)
|
||||
assert_equal(a.get_n, 110)
|
||||
|
||||
a = nil
|
||||
GC.start
|
||||
|
|
@ -76,15 +89,16 @@ class Basic_TestClass < TestBase
|
|||
assert_equal( RBA::A.aa, "static_a" )
|
||||
assert_equal( a.aa, "a" )
|
||||
|
||||
assert_equal( a.a1, 17 )
|
||||
assert_equal( a.get_n, 17 )
|
||||
a.a5 -5
|
||||
assert_equal( a.a1, -5 )
|
||||
assert_equal( a.get_n, -5 )
|
||||
a.a5 0x7fffffff
|
||||
assert_equal( a.a1, 0x7fffffff )
|
||||
assert_equal( a.get_n, 0x7fffffff )
|
||||
a.a5 -0x80000000
|
||||
assert_equal( a.a1, -0x80000000 )
|
||||
assert_equal( a.get_n, -0x80000000 )
|
||||
|
||||
assert_equal( a.a3("a"), 1 )
|
||||
assert_equal( a.a3(ObjectWithStr::new("abcde")), 5 ) # implicitly using to_s for string conversion
|
||||
assert_equal( a.a3("ab"), 2 )
|
||||
assert_equal( a.a3("µ"), 2 ) # two UTF8 bytes
|
||||
if a.respond_to?(:a3_qstr)
|
||||
|
|
@ -142,7 +156,7 @@ class Basic_TestClass < TestBase
|
|||
assert_equal( RBA::A::instance_count, ic0 )
|
||||
a = RBA::A::new_a( 55 )
|
||||
assert_equal( RBA::A::instance_count, ic0 + 1 )
|
||||
assert_equal( a.a1, 55 )
|
||||
assert_equal( a.get_n, 55 )
|
||||
assert_equal( a.a_vp1( a.a_vp2 ), "abc" )
|
||||
a.destroy
|
||||
assert_equal( RBA::A::instance_count, ic0 )
|
||||
|
|
@ -302,9 +316,9 @@ class Basic_TestClass < TestBase
|
|||
a = RBA::A.new_a_by_variant
|
||||
assert_equal(RBA::A::instance_count, ic0 + 1)
|
||||
|
||||
assert_equal(a.a1, 17)
|
||||
assert_equal(a.get_n, 17)
|
||||
a.a5(-15)
|
||||
assert_equal(a.a1, -15)
|
||||
assert_equal(a.get_n, -15)
|
||||
|
||||
a = nil
|
||||
GC.start
|
||||
|
|
@ -327,6 +341,67 @@ class Basic_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
def test_11
|
||||
|
||||
# implicitly converting tuples/lists to objects by calling the constructor
|
||||
|
||||
b = RBA::B::new()
|
||||
b.av_cptr = [ RBA::A::new(17), [1,2], [4,6,0.5] ]
|
||||
|
||||
arr = b.each_a.collect { |a| a.get_n_const }
|
||||
assert_equal(arr, [17, 3, 5])
|
||||
|
||||
b = RBA::B::new()
|
||||
# NOTE: this gives an error (printed only) that tuples can't be modified as out parameters
|
||||
b.av_ref = [ [1,2], [6,2,0.25], [42] ]
|
||||
|
||||
arr = b.each_a.collect { |a| a.get_n_const }
|
||||
assert_equal(arr, [3, 2, 42])
|
||||
|
||||
b = RBA::B::new()
|
||||
aa = [ [1,2], [6,2,0.25], [42] ]
|
||||
b.av_ptr = aa
|
||||
|
||||
arr = b.each_a.collect { |a| a.get_n_const }
|
||||
assert_equal(arr, [3, 2, 42])
|
||||
|
||||
# NOTE: as we used aa in "av_ptr", it got modified as out parameter and
|
||||
# now holds A object references
|
||||
arr = b.each_a.collect { |a| a.get_n_const }
|
||||
assert_equal(arr, [3, 2, 42])
|
||||
|
||||
b.av = []
|
||||
|
||||
arr = b.each_a.collect { |a| a.get_n_const }
|
||||
assert_equal(arr, [])
|
||||
|
||||
b.push_a_ref([1, 7])
|
||||
|
||||
arr = b.each_a.collect { |a| a.get_n_const }
|
||||
assert_equal(arr, [8])
|
||||
|
||||
b.push_a_ptr([1, 7, 0.25])
|
||||
|
||||
arr = b.each_a.collect { |a| a.get_n_const }
|
||||
assert_equal(arr, [8, 2])
|
||||
|
||||
b.push_a_cref([42])
|
||||
|
||||
arr = b.each_a.collect { |a| a.get_n_const }
|
||||
assert_equal(arr, [8, 2, 42])
|
||||
|
||||
b.push_a_cptr([1, 16])
|
||||
|
||||
arr = b.each_a.collect { |a| a.get_n_const }
|
||||
assert_equal(arr, [8, 2, 42, 17])
|
||||
|
||||
b.push_a([4, 6, 0.5])
|
||||
|
||||
arr = b.each_a.collect { |a| a.get_n_const }
|
||||
assert_equal(arr, [8, 2, 42, 17, 5])
|
||||
|
||||
end
|
||||
|
||||
def test_12
|
||||
|
||||
a1 = RBA::A.new
|
||||
|
|
@ -334,16 +409,16 @@ class Basic_TestClass < TestBase
|
|||
a2 = a1
|
||||
a3 = a2.dup
|
||||
|
||||
assert_equal( a1.a1, -15 )
|
||||
assert_equal( a2.a1, -15 )
|
||||
assert_equal( a3.a1, -15 )
|
||||
assert_equal( a1.get_n, -15 )
|
||||
assert_equal( a2.get_n, -15 )
|
||||
assert_equal( a3.get_n, -15 )
|
||||
|
||||
a1.a5( 11 )
|
||||
a3.a5( -11 )
|
||||
|
||||
assert_equal( a1.a1, 11 )
|
||||
assert_equal( a2.a1, 11 )
|
||||
assert_equal( a3.a1, -11 )
|
||||
assert_equal( a1.get_n, 11 )
|
||||
assert_equal( a2.get_n, 11 )
|
||||
assert_equal( a3.get_n, -11 )
|
||||
|
||||
assert_equal( a1.a10_s(0x70000000), "0" )
|
||||
assert_equal( a1.a10_s(0x7fffffff), "-1" )
|
||||
|
|
@ -564,7 +639,7 @@ class Basic_TestClass < TestBase
|
|||
|
||||
err_caught = false
|
||||
begin
|
||||
b.amember_cptr.a1 # cannot call non-const method on const reference
|
||||
b.amember_cptr.get_n # cannot call non-const method on const reference
|
||||
rescue
|
||||
err_caught = true
|
||||
end
|
||||
|
|
@ -590,7 +665,7 @@ class Basic_TestClass < TestBase
|
|||
if !$leak_check
|
||||
|
||||
begin
|
||||
b.b10 { |a| arr.push(a.a1) } # b10 is a const iterator - cannot call a1 on it
|
||||
b.b10 { |a| arr.push(a.get_n) } # b10 is a const iterator - cannot call a1 on it
|
||||
rescue
|
||||
err_caught = true
|
||||
end
|
||||
|
|
@ -604,7 +679,7 @@ class Basic_TestClass < TestBase
|
|||
if !$leak_check
|
||||
|
||||
begin
|
||||
b.b10p { |a| arr.push(a.a1) } # b10p is a const iterator - cannot call a1 on it
|
||||
b.b10p { |a| arr.push(a.get_n) } # b10p is a const iterator - cannot call a1 on it
|
||||
rescue
|
||||
err_caught = true
|
||||
end
|
||||
|
|
@ -614,85 +689,85 @@ class Basic_TestClass < TestBase
|
|||
end
|
||||
|
||||
arr = []
|
||||
b.b10 { |a| arr.push(a.dup.a1) }
|
||||
b.b10 { |a| arr.push(a.dup.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
b.dup.b10 { |a| arr.push(a.dup.a1) }
|
||||
b.dup.b10 { |a| arr.push(a.dup.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
b.b10 { |a| arr.push(a.a1c) }
|
||||
b.b10 { |a| arr.push(a.get_n_const) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
b.b10p { |a| arr.push(a.dup.a1) }
|
||||
b.b10p { |a| arr.push(a.dup.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
b.dup.b10p { |a| arr.push(a.dup.a1) }
|
||||
b.dup.b10p { |a| arr.push(a.dup.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
b.b10p { |a| arr.push(a.a1c) }
|
||||
b.b10p { |a| arr.push(a.get_n_const) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
b.b11 { |a| arr.push(a.a1) }
|
||||
b.b11 { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
b.dup.b11 { |a| arr.push(a.a1) }
|
||||
b.dup.b11 { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
b.b12 { |a| arr.push(a.a1) }
|
||||
b.b12 { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [7100, 7121, 7144, 7169])
|
||||
|
||||
arr = []
|
||||
b.dup.b12 { |a| arr.push(a.a1) }
|
||||
b.dup.b12 { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [7100, 7121, 7144, 7169])
|
||||
|
||||
aarr = b.b16a
|
||||
arr = []
|
||||
aarr.each { |a| arr.push(a.a1) }
|
||||
aarr.each { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
aarr = b.b16b
|
||||
arr = []
|
||||
aarr.each { |a| arr.push(a.a1) }
|
||||
aarr.each { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
aarr = b.b16c
|
||||
arr = []
|
||||
aarr.each { |a| arr.push(a.a1) }
|
||||
aarr.each { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
b.b17a( [ RBA::A.new_a( 101 ), RBA::A.new_a( -122 ) ] )
|
||||
arr = []
|
||||
b.b11 { |a| arr.push(a.a1) }
|
||||
b.b11 { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [101, -122])
|
||||
|
||||
b.b17a( [] )
|
||||
arr = []
|
||||
b.b11 { |a| arr.push(a.a1) }
|
||||
b.b11 { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [])
|
||||
|
||||
b.b17b( [ RBA::A.new_a( 102 ), RBA::A.new_a( -123 ) ] )
|
||||
arr = []
|
||||
b.b11 { |a| arr.push(a.a1) }
|
||||
b.b11 { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [102, -123])
|
||||
|
||||
b.b17c( [ RBA::A.new_a( 100 ), RBA::A.new_a( 121 ), RBA::A.new_a( 144 ) ] )
|
||||
arr = []
|
||||
b.b11 { |a| arr.push(a.a1) }
|
||||
b.b11 { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
if !$leak_check
|
||||
|
||||
arr = []
|
||||
begin
|
||||
b.b13 { |a| arr.push(a.a1) }
|
||||
b.b13 { |a| arr.push(a.get_n) }
|
||||
rescue
|
||||
err_caught = true
|
||||
end
|
||||
|
|
@ -702,31 +777,31 @@ class Basic_TestClass < TestBase
|
|||
end
|
||||
|
||||
arr = []
|
||||
b.b13 { |a| arr.push(a.a1c) }
|
||||
b.b13 { |a| arr.push(a.get_n_const) }
|
||||
assert_equal(arr, [-3100, -3121])
|
||||
|
||||
arr = []
|
||||
b.dup.b13 { |a| arr.push(a.a1c) }
|
||||
b.dup.b13 { |a| arr.push(a.get_n_const) }
|
||||
assert_equal(arr, [-3100, -3121])
|
||||
|
||||
arr = []
|
||||
b.b18 { |a| arr.push(a.a1c) }
|
||||
b.each_a { |a| arr.push(a.get_n_const) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
b.b18 { |a| arr.push(a.a1) }
|
||||
b.each_a { |a| arr.push(a.get_n) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
b.b18b { |a| arr.push(a.a1c) }
|
||||
b.each_a_ref { |a| arr.push(a.get_n_const) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
# even though b18b returns a "const A &", calling a non-const method does not work
|
||||
# even though each_a_ref returns a "const A &", calling a non-const method does not work
|
||||
# since A is a managed object and is not turned into a copy.
|
||||
err_caught = false
|
||||
begin
|
||||
b.b18b { |a| arr.push(a.a1) }
|
||||
b.each_a_ref { |a| arr.push(a.get_n) }
|
||||
rescue
|
||||
err_caught = true
|
||||
end
|
||||
|
|
@ -734,15 +809,15 @@ class Basic_TestClass < TestBase
|
|||
assert_equal(err_caught, true)
|
||||
|
||||
arr = []
|
||||
b.b18c { |a| arr.push(a.a1c) }
|
||||
b.each_a_ptr { |a| arr.push(a.get_n_const) }
|
||||
assert_equal(arr, [100, 121, 144])
|
||||
|
||||
arr = []
|
||||
# this does not work since b18c delivers a "const *" which cannot be used to call a non-const
|
||||
# this does not work since each_a_ptr delivers a "const *" which cannot be used to call a non-const
|
||||
# method on
|
||||
err_caught = false
|
||||
begin
|
||||
b.b18c { |a| arr.push(a.a1) }
|
||||
b.each_a_ptr { |a| arr.push(a.get_n) }
|
||||
rescue
|
||||
err_caught = true
|
||||
end
|
||||
|
|
@ -952,23 +1027,23 @@ class Basic_TestClass < TestBase
|
|||
a = b.make_a( 1971 );
|
||||
assert_equal( RBA::A.instance_count, a_count + 1 )
|
||||
|
||||
assert_equal( a.a1, 1971 );
|
||||
assert_equal( a.get_n, 1971 );
|
||||
assert_equal( b.an( a ), 1971 );
|
||||
|
||||
aa = b.make_a( -61 );
|
||||
assert_equal( RBA::A.instance_count, a_count + 2 )
|
||||
assert_equal( b.an_cref( aa ), -61 );
|
||||
assert_equal( a.a1, 1971 );
|
||||
assert_equal( a.get_n, 1971 );
|
||||
assert_equal( b.an( a ), 1971 );
|
||||
assert_equal( aa.a1, -61 );
|
||||
assert_equal( aa.get_n, -61 );
|
||||
assert_equal( b.an( aa ), -61 );
|
||||
|
||||
aa.a5 98;
|
||||
a.a5 100;
|
||||
|
||||
assert_equal( a.a1, 100 );
|
||||
assert_equal( a.get_n, 100 );
|
||||
assert_equal( b.an( a ), 100 );
|
||||
assert_equal( aa.a1, 98 );
|
||||
assert_equal( aa.get_n, 98 );
|
||||
assert_equal( b.an( aa ), 98 );
|
||||
|
||||
a._destroy
|
||||
|
|
@ -984,10 +1059,10 @@ class Basic_TestClass < TestBase
|
|||
|
||||
b = RBA::B.new
|
||||
b.set_an( 77 )
|
||||
assert_equal( b.amember_cptr.a1c, 77 );
|
||||
assert_equal( b.amember_cptr.get_n_const, 77 );
|
||||
|
||||
b.set_an_cref( 79 )
|
||||
assert_equal( b.amember_cptr.a1c, 79 );
|
||||
assert_equal( b.amember_cptr.get_n_const, 79 );
|
||||
|
||||
aref = b.amember_cptr
|
||||
err_caught = false
|
||||
|
|
@ -995,17 +1070,17 @@ class Basic_TestClass < TestBase
|
|||
if !$leak_check
|
||||
|
||||
begin
|
||||
x = aref.a1 # cannot call non-const method on const reference (as delivered by amember_cptr)
|
||||
x = aref.get_n # cannot call non-const method on const reference (as delivered by amember_cptr)
|
||||
rescue
|
||||
err_caught = true
|
||||
end
|
||||
assert_equal( err_caught, true )
|
||||
assert_equal( aref.a1c, 79 );
|
||||
assert_equal( aref.get_n_const, 79 );
|
||||
|
||||
end
|
||||
|
||||
b.set_an( -1 )
|
||||
assert_equal( aref.a1c, -1 );
|
||||
assert_equal( aref.get_n_const, -1 );
|
||||
|
||||
end
|
||||
|
||||
|
|
@ -1095,11 +1170,11 @@ class Basic_TestClass < TestBase
|
|||
|
||||
a1 = b.amember_or_nil( true )
|
||||
a2 = b.amember_ptr
|
||||
assert_equal( a1.a1, 17 )
|
||||
assert_equal( a2.a1, 17 )
|
||||
assert_equal( a1.get_n, 17 )
|
||||
assert_equal( a2.get_n, 17 )
|
||||
a1.a5( 761 )
|
||||
assert_equal( a1.a1, 761 )
|
||||
assert_equal( a2.a1, 761 )
|
||||
assert_equal( a1.get_n, 761 )
|
||||
assert_equal( a2.get_n, 761 )
|
||||
|
||||
a1 = b.amember_or_nil( false )
|
||||
assert_equal( a1, nil )
|
||||
|
|
@ -2198,19 +2273,9 @@ class Basic_TestClass < TestBase
|
|||
assert_equal(b.map1_cptr_null == nil, true);
|
||||
assert_equal(b.map1_ptr_null == nil, true);
|
||||
|
||||
begin
|
||||
b.map1 = { 42 => 1, -17 => true }
|
||||
error = nil
|
||||
rescue => ex
|
||||
error = ex.message.split("\n")[0]
|
||||
end
|
||||
if error == "can't convert Fixnum into String"
|
||||
# Ok
|
||||
elsif error == "no implicit conversion of Fixnum into String" || error == "no implicit conversion of Integer into String"
|
||||
# Ok
|
||||
else
|
||||
assert_equal(error, "")
|
||||
end
|
||||
b.map1 = { 42 => 1, -17 => true }
|
||||
assert_equal(b.map1.inspect, "{-17=>\"true\", 42=>\"1\"}")
|
||||
|
||||
b.map1 = { 42 => "1", -17 => "true" }
|
||||
assert_equal(b.map1.inspect, "{-17=>\"true\", 42=>\"1\"}")
|
||||
|
||||
|
|
@ -2985,7 +3050,7 @@ class Basic_TestClass < TestBase
|
|||
|
||||
assert_equal(RBA::B::int_to_optional(1, true), 1)
|
||||
assert_equal(RBA::B::int_to_optional(1, false), nil)
|
||||
assert_equal(RBA::B::int_to_optional_a(1, true).a1, 1)
|
||||
assert_equal(RBA::B::int_to_optional_a(1, true).get_n, 1)
|
||||
assert_equal(RBA::B::int_to_optional_a(1, false), nil)
|
||||
|
||||
assert_equal(RBA::B::optional_to_int(1, -1), 1)
|
||||
|
|
|
|||
Loading…
Reference in New Issue