From 02777e127eb917081189fd7113fc6bda82b8405a Mon Sep 17 00:00:00 2001
From: Jean-Paul Chaput
Date: Sun, 19 Sep 2021 19:41:24 +0200
Subject: [PATCH] Migration towards Python3, first stage: still based on
C-Macros.
* New: Python/C++ API level:
* Write a new C++/template wrapper to get rid of boost::python
* The int & long Python type are now merged. So a C/C++ level,
it became "PyLong_X" (remove "PyInt_X") and at Python code
level, it became "int" (remove "long").
* Change: VLSISAPD finally defunct.
* Configuration is now integrated as a Hurricane component,
makes use of the new C++/template wrapper.
* vlsisapd is now defunct. Keep it in the source for now as
some remaining non essential code may have to be ported in
the future.
* Note: Python code (copy of the migration howto):
* New print function syntax print().
* Changed "dict.has_key(k)" for "k" in dict.
* Changed "except Exception, e" for "except Exception as e".
* The division "/" is now the floating point division, even if
both operand are integers. So 3/2 now gives 1.5 and no longer 1.
The integer division is now "//" : 1 = 3//2. So have to carefully
review the code to update. Most of the time we want to use "//".
We must never change to float for long that, in fact, represents
DbU (exposed as Python int type).
* execfile() must be replaced by exec(open("file").read()).
* iter().__next__() becomes iter(x).__next__().
* __getslice__() has been removed, integrated to __getitem__().
* The formating used for str(type(o)) has changed, so In Stratus,
have to update them ("" instead of "MyClass").
* the "types" module no longer supply values for default types
like str (types.StringType) or list (types.StringType).
Must use "isinstance()" where they were occuring.
* Remove the 'L' to indicate "long integer" (like "12L"), now
all Python integer are long.
* Change in bootstrap:
* Ported Coriolis builder (ccb) to Python3.
* Ported Coriolis socInstaller.py to Python3.
* Note: In PyQt4+Python3, QVariant no longer exists. Use None or
directly convert using the python syntax: bool(x), int(x), ...
By default, it is a string (str).
* Note: PyQt4 bindings & Python3 under SL7.
* In order to compile user's must upgrade to my own rebuild of
PyQt 4 & 5 bindings 4.19.21-1.el7.soc.
* Bug: In cumulus/plugins.block.htree.HTree.splitNet(), set the root
buffer of the H-Tree to the original signal (mainly: top clock).
Strangely, it was only done when working in full chip mode.
---
anabatic/CMakeLists.txt | 3 +-
anabatic/src/CMakeLists.txt | 4 +-
anabatic/src/Configuration.cpp | 2 +-
anabatic/src/PyAnabatic.cpp | 25 +-
bootstrap/CMakeLists.txt | 7 +-
bootstrap/build.conf | 1 -
bootstrap/builder/AboutWidget.py | 142 +-
bootstrap/builder/Builder.py | 166 +-
bootstrap/builder/BuilderGui.py | 113 +-
bootstrap/builder/CompileWidget.py | 351 ++-
bootstrap/builder/Configuration.py | 141 +-
bootstrap/builder/ConfigureWidget.py | 187 +-
bootstrap/builder/Highlighter.py | 119 +-
bootstrap/builder/OptionsWidget.py | 331 ++-
bootstrap/builder/Project.py | 6 +-
bootstrap/builder/ProjectWidgets.py | 142 +-
bootstrap/builder/__init__.py | 17 +-
bootstrap/ccb.py | 356 ++-
bootstrap/cmake_modules/FindBootstrap.cmake | 32 +-
.../FindPythonSitePackages.cmake | 32 +-
bootstrap/coriolisEnv.py | 341 ++-
bootstrap/socInstaller.py | 362 ++-
bora/CMakeLists.txt | 5 +-
bora/python/CMakeLists.txt | 2 +-
bora/python/boraInit.py | 38 +-
bora/src/CMakeLists.txt | 4 +-
bora/src/PyBora.cpp | 26 +-
bora/src/PyDSlicingNode.cpp | 4 +-
crlcore/CMakeLists.txt | 5 +-
crlcore/etc/common/__init__.py | 2 +-
crlcore/etc/common/colors.py | 2 +-
crlcore/etc/common/devices.py | 38 +-
crlcore/etc/common/kite.py | 10 +-
crlcore/etc/common/misc.py | 4 +-
crlcore/etc/common/patterns.py | 18 +-
crlcore/etc/node180/scn6m_deep_09/__init__.py | 2 +-
crlcore/etc/node180/scn6m_deep_09/alliance.py | 19 +-
crlcore/etc/node180/scn6m_deep_09/analog.py | 4 +-
crlcore/etc/node180/scn6m_deep_09/devices.py | 6 +-
crlcore/etc/node180/scn6m_deep_09/display.py | 5 +-
.../scn6m_deep_09/dtr_scn6m_deep_09.py | 2 +-
crlcore/etc/node180/scn6m_deep_09/etesian.py | 4 +-
crlcore/etc/node180/scn6m_deep_09/kite.py | 16 +-
crlcore/etc/node180/scn6m_deep_09/misc.py | 4 +-
crlcore/etc/node180/scn6m_deep_09/patterns.py | 4 +-
crlcore/etc/node180/scn6m_deep_09/plugins.py | 2 +-
crlcore/etc/node180/scn6m_deep_09/stratus1.py | 5 +-
.../etc/node180/scn6m_deep_09/technology.py | 19 +-
crlcore/etc/node45/freepdk45/alliance.py | 2 +-
crlcore/etc/node45/freepdk45/technology.py | 6 +-
crlcore/etc/node600/phenitec/alliance.py | 24 +-
crlcore/etc/node600/phenitec/technology.py | 16 +-
crlcore/etc/symbolic/cmos/alliance.py | 18 +-
crlcore/etc/symbolic/cmos/technology.py | 8 +-
crlcore/etc/symbolic/cmos45/alliance.py | 23 +-
crlcore/etc/symbolic/cmos45/technology.py | 8 +-
crlcore/python/CMakeLists.txt | 12 +-
crlcore/python/helpers/__init__.py | 147 +-
crlcore/python/helpers/analogtechno.py | 6 +-
crlcore/python/helpers/io.py | 16 +-
crlcore/python/helpers/overlay.py | 13 +-
crlcore/python/helpers/technology.py | 3 +-
crlcore/python/helpers/utils.py | 9 +-
crlcore/src/LibraryManager/CellsModel.cpp | 16 +-
.../src/LibraryManager/crlcore/CellDatas.h | 10 +-
crlcore/src/ccore/AllianceFramework.cpp | 2 +-
crlcore/src/ccore/CMakeLists.txt | 25 +-
crlcore/src/ccore/Histogram.cpp | 4 +-
crlcore/src/ccore/Utilities.cpp | 8 +-
crlcore/src/ccore/alliance/vst/VhdlEntity.cpp | 28 +-
crlcore/src/ccore/blif/BlifParser.cpp | 2 +-
crlcore/src/ccore/crlcore/Utilities.h | 13 +-
crlcore/src/ccore/gds/GdsDriver.cpp | 4 +-
crlcore/src/ccore/gds/GdsParser.cpp | 6 +-
crlcore/src/ccore/lefdef/LefImport.cpp | 4 +-
crlcore/src/ccore/spice/SpiceDriver.cpp | 2 +-
crlcore/src/ccore/spice/SpiceParser.cpp | 2 +-
crlcore/src/cyclop/CMakeLists.txt | 7 +-
crlcore/src/cyclop/CyclopMain.cpp | 2 +-
crlcore/src/pyCRL/CMakeLists.txt | 6 +-
crlcore/src/pyCRL/PyAllianceFramework.cpp | 4 +-
crlcore/src/pyCRL/PyCRL.cpp | 36 +-
crlcore/src/pyCRL/PyCatalogState.cpp | 12 +-
crlcore/src/pyCRL/PyConstant.cpp | 24 +-
crlcore/src/pyCRL/PyRoutingGauge.cpp | 2 +
crlcore/src/x2y/CMakeLists.txt | 1 +
cumulus/CMakeLists.txt | 3 +-
cumulus/src/Alliance.py | 2 +-
cumulus/src/CMakeLists.txt | 20 +-
cumulus/src/placeandroute.py | 14 +-
cumulus/src/plugins/__init__.py | 74 +-
cumulus/src/plugins/aboutwindow.py | 18 +-
cumulus/src/plugins/alpha/block/bigvia.py | 15 +-
cumulus/src/plugins/alpha/block/block.py | 17 +-
.../src/plugins/alpha/block/configuration.py | 27 +-
cumulus/src/plugins/alpha/block/hfns1.py | 13 +-
cumulus/src/plugins/alpha/block/hfns2.py | 5 +-
cumulus/src/plugins/alpha/block/hfns3.py | 13 +-
cumulus/src/plugins/alpha/block/hfns4.py | 5 +-
cumulus/src/plugins/alpha/block/htree.py | 21 +-
cumulus/src/plugins/alpha/block/iospecs.py | 9 +-
cumulus/src/plugins/alpha/block/matrix.py | 4 +-
cumulus/src/plugins/alpha/block/rsmt.py | 6 +-
cumulus/src/plugins/alpha/block/spares.py | 32 +-
cumulus/src/plugins/alpha/block/timing.py | 16 +-
cumulus/src/plugins/alpha/chip/__init__.py | 7 +-
cumulus/src/plugins/alpha/chip/chip.py | 7 +-
.../src/plugins/alpha/chip/configuration.py | 41 +-
cumulus/src/plugins/alpha/chip/corona.py | 41 +-
cumulus/src/plugins/alpha/chip/pads.py | 65 +-
cumulus/src/plugins/alpha/chip/power.py | 22 +-
cumulus/src/plugins/alpha/chip/powerplane.py | 39 +-
cumulus/src/plugins/alpha/core2chip/cmos.py | 4 +-
.../src/plugins/alpha/core2chip/core2chip.py | 12 +-
.../src/plugins/alpha/core2chip/libresocio.py | 4 +-
cumulus/src/plugins/alpha/core2chip/niolib.py | 4 +-
cumulus/src/plugins/alpha/core2chip/phlib.py | 4 +-
.../src/plugins/alpha/core2chip/phlib80.py | 4 +-
cumulus/src/plugins/alpha/macro/macro.py | 45 +-
cumulus/src/plugins/alpha/utils.py | 5 +-
cumulus/src/plugins/block.py | 11 +-
cumulus/src/plugins/block/vchannels.py | 18 +-
cumulus/src/plugins/checks.py | 10 +-
cumulus/src/plugins/chip/__init__.py | 11 +-
cumulus/src/plugins/chip/blockcorona.py | 110 +-
cumulus/src/plugins/chip/blockpower.py | 21 +-
cumulus/src/plugins/chip/chip.py | 15 +-
cumulus/src/plugins/chip/configuration.py | 97 +-
cumulus/src/plugins/chip/padscorona.py | 74 +-
cumulus/src/plugins/chipplace.py | 12 +-
cumulus/src/plugins/chiproute.py | 15 +-
cumulus/src/plugins/clocktree.py | 27 +-
cumulus/src/plugins/conductor.py | 14 +-
cumulus/src/plugins/core2chip/cmos.py | 4 +-
cumulus/src/plugins/core2chip/core2chip.py | 14 +-
cumulus/src/plugins/core2chip/phlib.py | 4 +-
cumulus/src/plugins/core2chip/phlib80.py | 4 +-
cumulus/src/plugins/core2chip_cmos.py | 41 +-
cumulus/src/plugins/core2chip_phlib80.py | 41 +-
cumulus/src/plugins/cts/clocktree.py | 35 +-
cumulus/src/plugins/cts/rsmt.py | 5 +-
cumulus/src/plugins/matrixplacer.py | 30 +-
cumulus/src/plugins/rsave.py | 18 +-
cumulus/src/plugins/rsaveall.py | 69 +-
cumulus/src/plugins/s2r.py | 63 +-
cumulus/src/plugins/stats.py | 11 +-
cumulus/src/plugins/vchannels.py | 104 +-
cumulus/src/tools/blif2vst.py | 3 +-
cumulus/src/tools/px2mpx.py | 539 +++--
cumulus/src/tools/yosys.py | 2 +-
documentation/content/pages/documentation.rst | 5 +-
.../pages/python-cpp-new/Implementation.rst | 507 +++++
.../pages/python-cpp-new/Introduction.rst | 76 +
.../python-cpp-new/PythonCppNew_HTML.rst | 29 +
.../examples/code/engine/smurf/CMakeLists.txt | 2 +-
documentation/output/pages/documentation.html | 4 +-
.../output/pages/python-cpp-new.html | 691 ++++++
documentation/output/pdfs/CheckToolkit.pdf | Bin 241116 -> 241137 bytes
documentation/output/pdfs/PythonCpp.pdf | Bin 174240 -> 174275 bytes
documentation/output/pdfs/PythonTutorial.pdf | Bin 298204 -> 298243 bytes
documentation/output/pdfs/RDS.pdf | Bin 117025 -> 117041 bytes
documentation/output/pdfs/Stratus.pdf | Bin 537693 -> 537948 bytes
documentation/output/pdfs/UsersGuide.pdf | Bin 673150 -> 673192 bytes
documentation/output/theme/css/coriolis.css | 7 +-
documentation/output/theme/css/nest.css | 4 +-
documentation/pelicanconf.py | 4 +-
.../nest-coriolis/static/css/coriolis.css | 4 +
equinox/CMakeLists.txt | 3 +-
etesian/CMakeLists.txt | 5 +-
etesian/src/CMakeLists.txt | 4 +-
etesian/src/Configuration.cpp | 2 +-
etesian/src/EtesianEngine.cpp | 12 +-
etesian/src/FeedCells.cpp | 2 +-
etesian/src/FlattenPower.cpp | 2 +-
etesian/src/PyEtesian.cpp | 22 +-
flute/CMakeLists.txt | 3 +-
flute/src/3.1/CMakeLists.txt | 4 +-
flute/src/3.1/PyFlute.cpp | 25 +-
hurricane/CMakeLists.txt | 7 +-
hurricane/cmake_modules/FindHURRICANE.cmake | 68 +-
hurricane/src/CMakeLists.txt | 3 +-
hurricane/src/analog/CMakeLists.txt | 10 +-
hurricane/src/analog/LayoutGenerator.cpp | 2 +-
hurricane/src/analog/MultiCapacitor.cpp | 6 +-
hurricane/src/analog/PyAnalog.cpp | 23 +-
hurricane/src/analog/PyMatrix.cpp | 2 +-
hurricane/src/configuration/CMakeLists.txt | 135 +-
.../src/configuration/ConfEditorWidget.cpp | 2 +-
hurricane/src/configuration/ConfTabWidget.cpp | 2 +-
hurricane/src/configuration/Configuration.cpp | 27 +-
.../src/configuration/ConfigurationDialog.cpp | 2 +-
.../src/configuration/ConfigurationWidget.cpp | 6 +-
.../src/configuration/LayoutDescription.cpp | 22 +-
hurricane/src/configuration/LogWidget.cpp | 2 +-
hurricane/src/configuration/Parameter.cpp | 24 +-
.../src/configuration/ParameterWidget.cpp | 2 +-
hurricane/src/configuration/ProxyProperty.cpp | 135 ++
hurricane/src/configuration/PyBasicLayer.cpp | 117 +
hurricane/src/configuration/PyBox.cpp | 221 ++
hurricane/src/configuration/PyCfg.cpp | 173 +-
.../src/configuration/PyConfiguration.cpp | 152 +-
hurricane/src/configuration/PyDataBase.cpp | 90 +
hurricane/src/configuration/PyDbU.cpp | 290 +++
hurricane/src/configuration/PyHurricane2.cpp | 70 -
hurricane/src/configuration/PyHurricane3.cpp | 132 ++
hurricane/src/configuration/PyLayer.cpp | 266 +++
hurricane/src/configuration/PyLayerMask.cpp | 202 ++
.../src/configuration/PyLayoutDescription.cpp | 131 ++
hurricane/src/configuration/PyParameter.cpp | 296 ++-
hurricane/src/configuration/PyPoint.cpp | 98 +
hurricane/src/configuration/PyTechnology.cpp | 254 +++
hurricane/src/configuration/PyTypeManager.cpp | 314 +++
.../configuration/ConfEditorWidget.h | 2 +-
.../hurricane/configuration/ConfTabWidget.h | 2 +-
.../hurricane/configuration/Configuration.h | 58 +-
.../configuration/ConfigurationDialog.h | 2 +-
.../configuration/ConfigurationWidget.h | 2 +-
.../hurricane/configuration/FilePathEdit.h | 2 +-
.../configuration/LayoutDescription.h | 82 +-
.../hurricane/configuration/LogWidget.h | 2 +-
.../hurricane/configuration/Parameter.h | 73 +-
.../hurricane/configuration/ParameterWidget.h | 4 +-
.../hurricane/configuration/ProxyProperty.h | 67 +
.../hurricane/configuration/PyBasicLayer.h | 33 +
.../hurricane/configuration/PyBox.h | 35 +
.../hurricane/configuration/PyCollection.h | 229 ++
.../hurricane/configuration/PyConfiguration.h | 19 +-
.../hurricane/configuration/PyDataBase.h | 66 +
.../hurricane/configuration/PyDbU.h | 78 +
.../hurricane/configuration/PyHurricane2.h | 479 ----
.../hurricane/configuration/PyHurricane3.h | 1655 ++++++++++++++
.../hurricane/configuration/PyLayer.h | 33 +
.../hurricane/configuration/PyLayerMask.h | 37 +
.../configuration/PyLayoutDescription.h | 33 +
.../hurricane/configuration/PyMap.h | 304 +++
.../hurricane/configuration/PyName.h | 36 +
.../hurricane/configuration/PyParameter.h | 166 +-
.../hurricane/configuration/PyPoint.h | 35 +
.../hurricane/configuration/PyTechnology.h | 33 +
.../hurricane/configuration/PyTypeManager.h | 2023 +++++++++++++++++
.../hurricane/configuration/PyVector.h | 266 +++
hurricane/src/hurricane/Backtrace.cpp | 30 +-
hurricane/src/hurricane/CMakeLists.txt | 6 +-
hurricane/src/hurricane/DbU.cpp | 8 +-
hurricane/src/hurricane/Error.cpp | 1 -
hurricane/src/hurricane/hurricane/Mask.h | 6 +-
hurricane/src/hurricane/hurricane/Point.h | 4 +-
hurricane/src/isobar/CMakeLists.txt | 4 +-
hurricane/src/isobar/PyDbU.cpp | 5 +-
hurricane/src/isobar/PyHurricane.cpp | 34 +-
hurricane/src/isobar/PyInstance.cpp | 5 -
hurricane/src/isobar/PyInterval.cpp | 4 +-
hurricane/src/isobar/PyLayerMask.cpp | 46 +-
hurricane/src/isobar/PyMaterial.cpp | 28 +-
hurricane/src/isobar/PyNet.cpp | 5 -
hurricane/src/isobar/PyNetDirection.cpp | 12 +-
hurricane/src/isobar/PyNetType.cpp | 12 +-
hurricane/src/isobar/PyOccurrence.cpp | 16 +-
hurricane/src/isobar/PyOrientation.cpp | 12 +-
hurricane/src/isobar/PyPinDirection.cpp | 12 +-
hurricane/src/isobar/PyPinPlacementStatus.cpp | 12 +-
hurricane/src/isobar/PyPlacementStatus.cpp | 12 +-
hurricane/src/isobar/PyQuery.cpp | 5 +-
hurricane/src/isobar/PyQueryMask.cpp | 32 +-
.../src/isobar/hurricane/isobar/PyDataBase.h | 2 +-
.../src/isobar/hurricane/isobar/PyHurricane.h | 196 +-
hurricane/src/utilities/CMakeLists.txt | 19 +
hurricane/src/utilities/Dots.cpp | 54 +
hurricane/src/utilities/Path.cpp | 318 +++
.../src/utilities/hurricane/utilities/Dots.h | 89 +
.../src/utilities/hurricane/utilities/Path.h | 204 ++
hurricane/src/viewer/CMakeLists.txt | 12 +-
hurricane/src/viewer/CellImage.cpp | 6 +-
hurricane/src/viewer/CellPrinter.cpp | 4 +-
hurricane/src/viewer/CellViewer.cpp | 6 +-
hurricane/src/viewer/CellWidget.cpp | 8 +-
hurricane/src/viewer/ControllerWidget.cpp | 6 +-
hurricane/src/viewer/JsonConfiguration.cpp | 4 +-
hurricane/src/viewer/PyDrawingStyle.cpp | 2 +-
hurricane/src/viewer/PyHApplication.cpp | 9 +-
hurricane/src/viewer/PyHSVr.cpp | 4 +-
hurricane/src/viewer/PyViewer.cpp | 23 +-
hurricane/src/viewer/Script.cpp | 4 +-
hurricane/src/viewer/SelectCommand.cpp | 9 -
hurricane/src/viewer/StratusScript.cpp | 15 +-
hurricane/src/viewer/StratusWidget.cpp | 4 +-
.../hurricane/viewer/JsonConfiguration.h | 12 +-
.../viewer/hurricane/viewer/JsonParameter.h | 12 +-
ispd/CMakeLists.txt | 5 +-
karakaze/CMakeLists.txt | 2 +-
karakaze/python/CMakeLists.txt | 6 +-
karakaze/python/analogdesign.py | 594 +++--
karakaze/python/oceane.py | 44 +-
katabatic/CMakeLists.txt | 5 +-
katabatic/src/CMakeLists.txt | 4 +-
katabatic/src/Configuration.cpp | 2 +-
katabatic/src/PyKatabatic.cpp | 22 +-
katana/CMakeLists.txt | 5 +-
katana/python/CMakeLists.txt | 2 +-
katana/python/katanaInit.py | 37 +-
katana/src/CMakeLists.txt | 4 +-
katana/src/Configuration.cpp | 2 +-
katana/src/GlobalRoute.cpp | 2 +-
katana/src/KatanaEngine.cpp | 2 +-
katana/src/PowerRails.cpp | 3 +-
katana/src/PyKatana.cpp | 25 +-
katana/src/PyKatanaFlags.cpp | 12 +-
katana/src/RoutingEvent.cpp | 2 +-
katana/src/SegmentFsm.cpp | 3 +-
kite/CMakeLists.txt | 5 +-
kite/python/CMakeLists.txt | 2 +-
kite/python/kiteInit.py | 52 +-
kite/src/CMakeLists.txt | 4 +-
kite/src/Configuration.cpp | 2 +-
kite/src/KiteEngine.cpp | 2 +-
kite/src/PyKite.cpp | 25 +-
kite/src/RoutingEvent.cpp | 2 +-
knik/CMakeLists.txt | 3 +-
knik/src/MatrixVertex.cpp | 2 +-
mauka/CMakeLists.txt | 5 +-
metis/CMakeLists.txt | 3 +-
nimbus/CMakeLists.txt | 5 +-
oroshi/CMakeLists.txt | 5 +-
oroshi/python/CMakeLists.txt | 2 +-
oroshi/python/__init__.py | 4 +-
oroshi/python/dtr.py | 5 +-
oroshi/python/paramsmatrix.py | 16 +-
oroshi/python/stack.py | 146 +-
oroshi/python/wip_csp.py | 6 +-
oroshi/python/wip_dp.py | 6 +-
oroshi/python/wip_transistor.py | 8 +-
solstice/CMakeLists.txt | 3 +-
stratus1/CMakeLists.txt | 3 +-
stratus1/src/dpgen/CMakeLists.txt | 2 +-
stratus1/src/dpgen/ROM_encours.py | 33 +-
stratus1/src/dpgen/dpgen_ADSB2F.py | 1 -
stratus1/src/dpgen/dpgen_Nul.py | 5 +-
stratus1/src/dpgen/dpgen_RAM.py | 9 +-
stratus1/src/dpgen/dpgen_RF1.py | 9 +-
stratus1/src/dpgen/dpgen_RF2.py | 9 +-
stratus1/src/dpgen/dpgen_ROM.py | 7 +-
stratus1/src/dpgen/dpgen_ROM2.py | 1 -
stratus1/src/dpgen/dpgen_ROM4.py | 1 -
stratus1/src/dpgen/dpgen_Regular.py | 3 +-
stratus1/src/dpgen/dpgen_Shifter.py | 3 +-
stratus1/src/dpgen/dpgen_Shrot.py | 3 +-
stratus1/src/modules/patterns/CMakeLists.txt | 2 +-
stratus1/src/modules/patterns/patread.py | 3 +-
stratus1/src/modules/patterns/patterns.py | 1 -
stratus1/src/modules/patterns/patwrite.py | 1 -
stratus1/src/modules/patterns/synopsys.py | 11 +-
stratus1/src/modules/patterns/utils.py | 5 +-
stratus1/src/stratus/CMakeLists.txt | 2 +-
stratus1/src/stratus/st_bool.py | 7 +-
stratus1/src/stratus/st_cat.py | 5 +-
stratus1/src/stratus/st_comp.py | 3 +-
stratus1/src/stratus/st_const.py | 5 +-
stratus1/src/stratus/st_export.py | 3 +-
stratus1/src/stratus/st_extend.py | 1 -
stratus1/src/stratus/st_func_gen_wallace.py | 5 +-
stratus1/src/stratus/st_generate.py | 7 +-
stratus1/src/stratus/st_getrealmodel.py | 3 +-
stratus1/src/stratus/st_instance.py | 62 +-
stratus1/src/stratus/st_model.py | 169 +-
stratus1/src/stratus/st_mult.py | 7 +-
stratus1/src/stratus/st_mult_blocs.py | 1 -
stratus1/src/stratus/st_mult_matrix.py | 1 -
stratus1/src/stratus/st_mux.py | 1 -
stratus1/src/stratus/st_net.py | 26 +-
stratus1/src/stratus/st_param.py | 1 -
stratus1/src/stratus/st_parser.py | 19 +-
stratus1/src/stratus/st_placeAndRoute.py | 17 +-
stratus1/src/stratus/st_placement.py | 24 +-
stratus1/src/stratus/st_ref.py | 26 +-
stratus1/src/stratus/st_shifter.py | 1 -
stratus1/src/stratus/st_slansky.py | 1 -
stratus1/src/stratus/stratus.py | 182 +-
stratus1/src/stratus/util.py | 1 -
stratus1/src/stratus/util_Const.py | 21 +-
stratus1/src/stratus/util_Defs.py | 3 +-
stratus1/src/stratus/util_Gen.py | 1 -
stratus1/src/stratus/util_Misc.py | 3 +-
stratus1/src/stratus/util_Place.py | 1 -
stratus1/src/stratus/util_Route.py | 1 -
stratus1/src/stratus/util_Shift.py | 1 -
stratus1/src/stratus/util_uRom.py | 1 -
tutorial/CMakeLists.txt | 5 +-
tutorial/python/CMakeLists.txt | 2 +-
tutorial/python/runDemo.py | 127 +-
tutorial/src/CMakeLists.txt | 4 +-
tutorial/src/PyTutorial.cpp | 24 +-
tutorial/src/TutorialEngine.cpp | 2 +-
tutorial/src/tutorial.py | 181 +-
unicorn/CMakeLists.txt | 5 +-
unicorn/python/CMakeLists.txt | 2 +-
unicorn/python/unicornInit.py | 116 +-
unicorn/src/CMakeLists.txt | 4 +-
unicorn/src/CgtMain.cpp | 22 +-
unicorn/src/PyUnicorn.cpp | 24 +-
unicorn/src/UnicornGui.cpp | 10 +-
unicorn/src/cgt.py | 85 +-
unicorn/src/coriolis.py | 132 +-
unittests/CMakeLists.txt | 5 +-
unittests/src/CMakeLists.txt | 2 +-
vlsisapd/CMakeLists.txt | 4 +-
vlsisapd/src/CMakeLists.txt | 2 +-
406 files changed, 14564 insertions(+), 5607 deletions(-)
create mode 100644 documentation/content/pages/python-cpp-new/Implementation.rst
create mode 100644 documentation/content/pages/python-cpp-new/Introduction.rst
create mode 100644 documentation/content/pages/python-cpp-new/PythonCppNew_HTML.rst
create mode 100644 documentation/output/pages/python-cpp-new.html
create mode 100644 hurricane/src/configuration/ProxyProperty.cpp
create mode 100644 hurricane/src/configuration/PyBasicLayer.cpp
create mode 100644 hurricane/src/configuration/PyBox.cpp
create mode 100644 hurricane/src/configuration/PyDataBase.cpp
create mode 100644 hurricane/src/configuration/PyDbU.cpp
delete mode 100644 hurricane/src/configuration/PyHurricane2.cpp
create mode 100644 hurricane/src/configuration/PyHurricane3.cpp
create mode 100644 hurricane/src/configuration/PyLayer.cpp
create mode 100644 hurricane/src/configuration/PyLayerMask.cpp
create mode 100644 hurricane/src/configuration/PyLayoutDescription.cpp
create mode 100644 hurricane/src/configuration/PyPoint.cpp
create mode 100644 hurricane/src/configuration/PyTechnology.cpp
create mode 100644 hurricane/src/configuration/PyTypeManager.cpp
create mode 100644 hurricane/src/configuration/hurricane/configuration/ProxyProperty.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyBasicLayer.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyBox.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyCollection.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyDataBase.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyDbU.h
delete mode 100644 hurricane/src/configuration/hurricane/configuration/PyHurricane2.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyHurricane3.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyLayer.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyLayerMask.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyLayoutDescription.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyMap.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyName.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyPoint.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyTechnology.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyTypeManager.h
create mode 100644 hurricane/src/configuration/hurricane/configuration/PyVector.h
create mode 100644 hurricane/src/utilities/CMakeLists.txt
create mode 100644 hurricane/src/utilities/Dots.cpp
create mode 100644 hurricane/src/utilities/Path.cpp
create mode 100644 hurricane/src/utilities/hurricane/utilities/Dots.h
create mode 100644 hurricane/src/utilities/hurricane/utilities/Path.h
diff --git a/anabatic/CMakeLists.txt b/anabatic/CMakeLists.txt
index 9786c67f..58333ae1 100644
--- a/anabatic/CMakeLists.txt
+++ b/anabatic/CMakeLists.txt
@@ -18,10 +18,9 @@
setup_boost()
setup_qt()
- find_package(PythonLibs 2 REQUIRED)
+ find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(FLUTE REQUIRED)
- find_package(VLSISAPD REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)
find_package(ETESIAN REQUIRED)
diff --git a/anabatic/src/CMakeLists.txt b/anabatic/src/CMakeLists.txt
index 7597035f..948f8977 100644
--- a/anabatic/src/CMakeLists.txt
+++ b/anabatic/src/CMakeLists.txt
@@ -11,7 +11,7 @@ endif ( CHECK_DETERMINISM )
${FLUTE_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${QtX_INCLUDE_DIR}
- ${PYTHON_INCLUDE_PATH}
+ ${Python_INCLUDE_DIRS}
)
set( includes anabatic/Constants.h
anabatic/Configuration.h
@@ -85,7 +85,7 @@ endif ( CHECK_DETERMINISM )
${QtX_LIBRARIES}
${Boost_LIBRARIES}
${LIBXML2_LIBRARIES}
- ${PYTHON_LIBRARIES} -lutil
+ ${Python_LIBRARIES} -lutil
)
add_library( anabatic ${cpps} )
diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp
index 3585a962..5e8a7085 100644
--- a/anabatic/src/Configuration.cpp
+++ b/anabatic/src/Configuration.cpp
@@ -17,7 +17,7 @@
#include
#include
#include
-#include "vlsisapd/configuration/Configuration.h"
+#include "hurricane/configuration/Configuration.h"
#include "hurricane/Warning.h"
#include "hurricane/Error.h"
#include "hurricane/Technology.h"
diff --git a/anabatic/src/PyAnabatic.cpp b/anabatic/src/PyAnabatic.cpp
index 57614ac0..8813a67f 100644
--- a/anabatic/src/PyAnabatic.cpp
+++ b/anabatic/src/PyAnabatic.cpp
@@ -55,17 +55,32 @@ extern "C" {
};
+ static PyModuleDef PyAnabatic_ModuleDef =
+ { PyModuleDef_HEAD_INIT
+ , "Anabatic" /* m_name */
+ , "Low level database for global & detailed routing."
+ /* m_doc */
+ , -1 /* m_size */
+ , PyAnabatic_Methods /* m_methods */
+ , NULL /* m_reload */
+ , NULL /* m_traverse */
+ , NULL /* m_clear */
+ , NULL /* m_free */
+ };
+
+
// ---------------------------------------------------------------
// Module Initialization : "initAnabatic ()"
- DL_EXPORT(void) initAnabatic () {
- cdebug_log(32,0) << "initAnabatic()" << endl;
+ PyMODINIT_FUNC PyInit_Anabatic ( void )
+ {
+ cdebug_log(32,0) << "PyInit_Anabatic()" << endl;
- PyObject* module = Py_InitModule( "Anabatic", PyAnabatic_Methods );
+ PyObject* module = PyModule_Create( &PyAnabatic_ModuleDef );
if (module == NULL) {
cerr << "[ERROR]\n"
<< " Failed to initialize Anabatic module." << endl;
- return;
+ return NULL;
}
PyObject* dictionnary = PyModule_GetDict(module);
@@ -77,6 +92,8 @@ extern "C" {
LoadObjectConstant( dictionnary,EngineLayerAssignByTrunk ,"EngineLayerAssignByTrunk" );
LoadObjectConstant( dictionnary,EngineLayerAssignNoGlobalM2V,"EngineLayerAssignNoGlobalM2V" );
LoadObjectConstant( dictionnary,EngineNoNetLayerAssign ,"EngineNoNetLayerAssign" );
+
+ return module;
}
diff --git a/bootstrap/CMakeLists.txt b/bootstrap/CMakeLists.txt
index 4f32de56..f3f78d75 100644
--- a/bootstrap/CMakeLists.txt
+++ b/bootstrap/CMakeLists.txt
@@ -5,12 +5,13 @@
cmake_minimum_required(VERSION 2.4.0)
- set(ignoreVariables "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
+ set(ignoreVariables USE_LIBBFD "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
add_subdirectory(cmake_modules)
list(INSERT CMAKE_MODULE_PATH 0 "${Bootstrap_SOURCE_DIR}/cmake_modules/")
- find_package(Bootstrap REQUIRED)
+ find_package(Bootstrap REQUIRED)
+ find_package(Python 3 REQUIRED COMPONENTS Interpreter Development )
find_package(PythonSitePackages REQUIRED)
print_cmake_module_path()
@@ -23,7 +24,7 @@
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
install(DIRECTORY builder
- DESTINATION ${PYTHON_SITE_PACKAGES} )
+ DESTINATION ${Python_CORIOLISLIB} )
install(FILES ccb.py
DESTINATION bin
diff --git a/bootstrap/build.conf b/bootstrap/build.conf
index ebfc43e2..86143759 100644
--- a/bootstrap/build.conf
+++ b/bootstrap/build.conf
@@ -15,7 +15,6 @@ projects = [
, 'tools' : [ "bootstrap"
, "lefdef"
, "coloquinte"
- , "vlsisapd"
, "hurricane"
, "crlcore"
, "flute"
diff --git a/bootstrap/builder/AboutWidget.py b/bootstrap/builder/AboutWidget.py
index e9f95fab..c58d3257 100644
--- a/bootstrap/builder/AboutWidget.py
+++ b/bootstrap/builder/AboutWidget.py
@@ -2,98 +2,88 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./builder/AboutWidget.py" |
# +-----------------------------------------------------------------+
-from PyQt4.QtCore import Qt
-from PyQt4.QtGui import QPalette
-from PyQt4.QtGui import QColor
-from PyQt4.QtGui import QFont
-from PyQt4.QtGui import QWidget
-from PyQt4.QtGui import QFrame
-from PyQt4.QtGui import QLabel
-from PyQt4.QtGui import QVBoxLayout
-from PyQt4.QtGui import QAction
-from PyQt4.QtGui import QKeySequence
-from PyQt4.QtGui import QApplication
+from PyQt4.QtCore import Qt
+from PyQt4.QtGui import QPalette, QColor, QFont, QWidget, \
+ QFrame, QLabel, QVBoxLayout, QAction, \
+ QKeySequence, QApplication
class AboutWidget ( QWidget ):
- def __init__ ( self, parent=None ):
- QWidget.__init__ ( self, parent )
- self.setFixedSize( 500, 400 )
- self.setStyleSheet( 'background-color: #ffffdd;' )
+ def __init__ ( self, parent=None ):
+ QWidget.__init__ ( self, parent )
+ self.setFixedSize( 500, 400 )
+ self.setStyleSheet( 'background-color: #ffffdd;' )
- topLine = QFrame()
- topLine.setFrameShape( QFrame.HLine )
- topLine.setLineWidth ( 2 )
- botLine = QFrame()
- botLine.setFrameShape( QFrame.HLine )
- botLine.setLineWidth ( 2 )
+ topLine = QFrame()
+ topLine.setFrameShape( QFrame.HLine )
+ topLine.setLineWidth ( 2 )
+ botLine = QFrame()
+ botLine.setFrameShape( QFrame.HLine )
+ botLine.setLineWidth ( 2 )
- title = QLabel( 'CCB' )
- title.setAlignment( Qt.AlignCenter )
- font = title.font()
- font.setPointSize( 72 )
- font.setWeight ( QFont.Bold )
- title.setFont( font )
+ title = QLabel( 'CCB' )
+ title.setAlignment( Qt.AlignCenter )
+ font = title.font()
+ font.setPointSize( 72 )
+ font.setWeight ( QFont.Bold )
+ title.setFont( font )
- subTitle = QLabel( 'Coriolis & Chams Builder for the Dummies' )
- subTitle.setAlignment( Qt.AlignCenter )
- subTitle.setFont( QFont('Courier',10,QFont.Bold) )
-
- authors = QLabel( 'Coriolis CAD System 1.0 . . . . . . . . ccb 1.0\n'
- 'Copyright (c) 2008-2016 . . . . . . . . . . UPMC\n'
- 'Authors . . . . . . . . . . . . . Damien Dupuis\n'
- ' . . . . . . . . . . . . Jean-Paul Chaput\n'
- 'E-Mail . . . . . . . . Jean-Paul.Chaput@lip6.fr'
- )
- authors.setAlignment( Qt.AlignCenter )
- authors.setFont( QFont('Courier',10,QFont.Bold) )
-
- vLayout = QVBoxLayout()
- vLayout.addStretch(10)
- vLayout.addWidget( topLine )
- vLayout.addWidget( title )
- vLayout.addStretch(1)
- vLayout.addWidget( subTitle )
- vLayout.addWidget( authors )
- vLayout.addStretch(1)
- vLayout.addWidget( botLine )
- vLayout.addStretch(10)
-
- frame = QFrame()
- frame.setFrameShape ( QFrame.Box )
- frame.setFrameShadow( QFrame.Sunken )
- frame.setLayout ( vLayout )
- frame.setLineWidth ( 1 )
-
- vLayout = QVBoxLayout()
- vLayout.addWidget( frame )
+ subTitle = QLabel( 'Coriolis Toolchain Builder for the Dummies' )
+ subTitle.setAlignment( Qt.AlignCenter )
+ subTitle.setFont( QFont('Courier',10,QFont.Bold) )
+ authors = QLabel( 'Coriolis CAD System 3.0 . . . . . . . . ccb 1.0\n'
+ 'Copyright (c) 2008-2021 . . Sorbonne Universite\n'
+ 'Authors . . . . . . . . . . . . . Damien Dupuis\n'
+ ' . . . . . . . . . . . . Jean-Paul Chaput\n'
+ 'E-Mail . . . . . . . . Jean-Paul.Chaput@lip6.fr'
+ )
+ authors.setAlignment( Qt.AlignCenter )
+ authors.setFont( QFont('Courier',10,QFont.Bold) )
- self.setLayout( vLayout )
-
- self._exitAction = QAction( '&Exit', self )
- self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
- self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
- self._exitAction.triggered.connect( QApplication.closeAllWindows )
- self.addAction( self._exitAction )
-
- self._closeAction = QAction( '&Close', self )
- self._closeAction.setStatusTip( 'Close the About Window' )
- self._closeAction.setShortcut ( QKeySequence('CTRL+A') )
- self._closeAction.triggered.connect( self.close )
- self.addAction( self._closeAction )
+ vLayout = QVBoxLayout()
+ vLayout.addStretch(10)
+ vLayout.addWidget( topLine )
+ vLayout.addWidget( title )
+ vLayout.addStretch(1)
+ vLayout.addWidget( subTitle )
+ vLayout.addWidget( authors )
+ vLayout.addStretch(1)
+ vLayout.addWidget( botLine )
+ vLayout.addStretch(10)
- return
+ frame = QFrame()
+ frame.setFrameShape ( QFrame.Box )
+ frame.setFrameShadow( QFrame.Sunken )
+ frame.setLayout ( vLayout )
+ frame.setLineWidth ( 1 )
+
+ vLayout = QVBoxLayout()
+ vLayout.addWidget( frame )
+ self.setLayout( vLayout )
+
+ self._exitAction = QAction( '&Exit', self )
+ self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
+ self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
+ self._exitAction.triggered.connect( QApplication.closeAllWindows )
+ self.addAction( self._exitAction )
+
+ self._closeAction = QAction( '&Close', self )
+ self._closeAction.setStatusTip( 'Close the About Window' )
+ self._closeAction.setShortcut ( QKeySequence('CTRL+A') )
+ self._closeAction.triggered.connect( self.close )
+ self.addAction( self._closeAction )
+ return
diff --git a/bootstrap/builder/Builder.py b/bootstrap/builder/Builder.py
index d5323f9f..7cabbadb 100644
--- a/bootstrap/builder/Builder.py
+++ b/bootstrap/builder/Builder.py
@@ -1,14 +1,14 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC/LIP6 2008-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2008-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./builder/Builder.py" |
# +-----------------------------------------------------------------+
@@ -20,9 +20,9 @@ import os
import os.path
import datetime
import subprocess
-from . import ErrorMessage
-from Project import Project
-from Configuration import Configuration
+from . import ErrorMessage
+from .Project import Project
+from .Configuration import Configuration
class Builder:
@@ -51,14 +51,11 @@ class Builder:
self._environment = os.environ
return
-
def __setattr__ ( self, attribute, value ):
if attribute[0] == "_":
self.__dict__[attribute] = value
return
-
if attribute in self._conf.getAllIds(): setattr( self._conf, attribute, value )
-
if attribute == "quiet": self._quiet = value
elif attribute == "rmBuild": self._rmBuild = value
elif attribute == "doBuild": self._doBuild = value
@@ -84,18 +81,15 @@ class Builder:
elif attribute == "makeArguments": self._makeArguments = value.split ()
return
-
def __getattr__ ( self, attribute ):
if attribute[0] != "_":
if attribute == 'conf': return self._conf
if attribute in self._conf.getAllIds():
return getattr( self._conf, attribute )
-
- if not self.__dict__.has_key(attribute):
+ if not attribute in self.__dict__:
raise ErrorMessage( 1, 'Builder has no attribute <%s>.'%attribute )
return self.__dict__[attribute]
-
def _guessGitHash ( self, project ):
self.gitHash = 'x'
os.chdir ( self.sourceDir+'/'+project.getName() )
@@ -103,58 +97,48 @@ class Builder:
self.gitHash = subprocess.Popen ( command, stdout=subprocess.PIPE ).stdout.readlines()[0]
return
-
def _configure ( self, fileIn, fileOut ):
fdFileIn = open ( fileIn , "r" )
fdFileOut = open ( fileOut, "w" )
-
for line in fdFileIn.readlines():
stable = False
substituted0 = line
-
while not stable:
substituted1 = re.sub ( r"@revdate@" , self.revDate, substituted0 )
substituted1 = re.sub ( r"@githash@" , self.gitHash, substituted1 )
substituted1 = re.sub ( r"@coriolisTop@", "/usr" , substituted1 )
if substituted0 == substituted1: stable = True
else: substituted0 = substituted1
-
fdFileOut.write ( substituted0 )
-
fdFileIn.close ()
fdFileOut.close ()
return
-
def _doSpec ( self ):
self._configure ( self.specFileIn, self.specFile )
return
-
def _doDebChangelog ( self ):
self._configure ( self.debChangelogIn, self.debChangelog )
return
-
def _execute ( self, command, error ):
collections = []
if self._devtoolset:
- collections.append( 'devtoolset-%d' % self._devtoolset )
- print 'Using devtoolset-%(v)d (scl enable devtoolset-%(v)d ...)' % {'v':self._devtoolset}
+ collections.append( 'devtoolset-{}'.format(self._devtoolset) )
+ print( 'Using devtoolset-{0} (scl enable devtoolset-{0} ...)'.format(self._devtoolset) )
if self._llvmtoolset:
- collections.append( 'llvm-toolset-%d' % self._llvmtoolset )
- print 'Using llvm-toolset-%(v)d (scl enable llvm-toolset-%(v)d ...)' % {'v':self._llvmtoolset}
-
+ collections.append( 'llvm-toolset-{}'.format(self._llvmtoolset) )
+ print( 'Using llvm-toolset-{0} (scl enable llvm-toolset-{v} ...)'.format(self._llvmtoolset) )
if collections:
- commandAsString = ''
- for i in range(len(command)):
- if i: commandAsString += ' '
- if ' ' in command[i]: commandAsString += '"'+command[i]+'"'
- else: commandAsString += command[i]
- command = [ 'scl', 'enable' ]
- command += collections
- command.append( commandAsString )
-
+ commandAsString = ''
+ for i in range(len(command)):
+ if i: commandAsString += ' '
+ if ' ' in command[i]: commandAsString += '"'+command[i]+'"'
+ else: commandAsString += command[i]
+ command = [ 'scl', 'enable' ]
+ command += collections
+ command.append( commandAsString )
sys.stdout.flush ()
sys.stderr.flush ()
child = subprocess.Popen ( command, env=self._environment, stdout=None )
@@ -164,28 +148,26 @@ class Builder:
ErrorMessage( status, "%s (status:%d)."%(error,status) ).terminate()
return
-
def _enableTool ( self, tool ):
return
-
def _build ( self, tool ):
toolSourceDir = os.path.join ( self.sourceDir, tool.getToolDir() )
toolBuildDir = os.path.join ( self.buildDir , tool.name )
cmakeInstallDir = os.path.join ( self.installDir, "share", "cmake", "Modules" )
# Supplied directly in the CMakeLists.txt.
#cmakeModules = os.path.join ( self.installDir, "share", "cmake", "Modules" )
-
if not os.path.isdir(toolSourceDir):
- print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
+ print( ErrorMessage( 0, 'Missing tool source directory: "{}" (skipped).' \
+ .format(toolSourceDir) ))
return
-
if self._rmBuild:
- print "Removing tool build directory: \"%s\"." % toolBuildDir
+ print( 'Removing tool build directory: "{}".'.format(toolBuildDir) )
command = [ "/bin/rm", "-rf", toolBuildDir ]
self._execute ( command, "Removing tool build directory" )
command = [ 'cmake' ]
+ if self.libSuffix: command += [ "-D", "LIB_SUFFIX:STRING=%s" % self.libSuffix ]
if self._ninja: command += [ "-G", "Ninja" ]
if self._macports: command += [ "-D", "WITH_MACPORTS:STRING=TRUE" ]
if self._noSystemBoost: command += [ "-D", "Boost_NO_SYSTEM_PATHS:STRING=TRUE"
@@ -195,7 +177,6 @@ class Builder:
if self._bfd: command += [ "-D", "USE_LIBBFD:STRING=%s" % self._bfd ]
if self._qt5: command += [ "-D", "WITH_QT5:STRING=TRUE" ]
if self._openmp: command += [ "-D", "WITH_OPENMP:STRING=TRUE" ]
-
command += [ "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self.buildMode
#, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir
@@ -203,13 +184,12 @@ class Builder:
#, "-D", "CMAKE_MODULE_PATH:STRING=%s" % cmakeModules
#, "-D", "Boost_DEBUG:STRING=TRUE"
, toolSourceDir ]
-
+
if not os.path.isdir(toolBuildDir):
- print "Creating tool build directory: \"%s\"." % toolBuildDir
+ print( 'Creating tool build directory: "{}".'.format(toolBuildDir) )
os.makedirs ( toolBuildDir )
os.chdir ( toolBuildDir )
self._execute ( command, "First CMake failed" )
-
os.chdir ( toolBuildDir )
if self._noCache:
cmakeCache = os.path.join(toolBuildDir,"CMakeCache.txt")
@@ -226,22 +206,19 @@ class Builder:
command += [ toolSourceDir ]
self._execute ( command, "Second CMake failed" )
-
if self._doBuild:
command = [ "make" ]
if self._ninja:
command = [ "ninja-build" ]
#command += [ "DESTDIR=%s" % self.installDir ]
command += self._makeArguments
- print "Make/Ninja command:", command
+ print( "Make/Ninja command:", command )
sys.stdout.flush ()
self._execute ( command, "Build failed" )
return
-
def gitArchive ( self, projectName ):
rawArchive = self.tarballDir+'/'+projectName+'.tar'
-
os.chdir ( self.sourceDir+'/'+projectName )
command = [ 'git'
, 'archive'
@@ -250,11 +227,10 @@ class Builder:
, 'devel'
]
self._execute ( command, "git archive of project %s" % projectName )
-
if not os.path.isdir ( self.archiveDir ):
os.mkdir ( self.archiveDir )
-
os.chdir ( self.archiveDir )
+
command = [ 'tar', 'xf', rawArchive ]
self._execute ( command, "unpacking raw archive %s" % rawArchive )
@@ -265,7 +241,7 @@ class Builder:
command = [ "/bin/ln", "-s", "./coriolis/bootstrap/Makefile.package"
, self.archiveDir+"/Makefile" ]
self._execute ( command, "link of %s failed" % "coriolis/boostrap/Makefile.package")
-
+
command = [ "/bin/ln", "-s", "./coriolis/bootstrap/debian", self.archiveDir ]
self._execute ( command, "Copying Debian/Ubuntu package control files" )
@@ -284,32 +260,27 @@ class Builder:
# , "--no-backup-if-mismatch"
# , "-p0", "-i", self.distribPatch ]
# self._execute ( command, "patch for distribution command failed" )
-
absSourceTarBz2 = '%s/%s' % (self.tarballDir,self.sourceTarBz2)
os.chdir ( self.tarballDir )
command = [ 'tar', 'jcf', absSourceTarBz2, os.path.basename(self.archiveDir) ]
self._execute ( command, "Creating composite archive %s" % absSourceTarBz2 )
-
return
-
def _setEnvironment ( self, systemVariable, userVariable ):
- if not self._environment.has_key(systemVariable) or self._environment[systemVariable] == "":
- if not self._environment.has_key(userVariable) or self._environment[userVariable] == "" :
+ if not systemVariable in self._environment or self._environment[systemVariable] == "":
+ if not userVariable in self._environment or self._environment[userVariable] == "" :
self._environment[ systemVariable ] = self.installDir
- print "[WARNING] Neither <%s> nor <%s> environment variables are sets." \
- % (systemVariable,userVariable)
- print " Setting <%s> to <%s>." % (systemVariable,self.installDir)
+ print( '[WARNING] Neither "{0}" nor "{1}" environment variables are sets.' \
+ .format(systemVariable,userVariable) )
+ print( ' Setting "{0}" to "{1}".'.format(systemVariable,self.installDir) )
else:
self._environment[ systemVariable ] = self._environment[ userVariable ]
-
if not self._quiet:
- print "Setting <%s> to <%s>." % (systemVariable,self._environment[systemVariable])
- if self._environment.has_key(userVariable):
- print "Transmitting <%s> as <%s>." % (userVariable,self._environment[userVariable])
+ print( 'Setting "{0}" to "{1}".'.format(systemVariable,self._environment[systemVariable]) )
+ if userVariable in self._environment:
+ print( 'Transmitting "{0}" as "{1}".'.format(userVariable,self._environment[userVariable]) )
return
-
def _commandTemplate ( self, tools, projects, command ):
if self._clang:
self._environment[ 'CC' ] = 'clang'
@@ -320,87 +291,70 @@ class Builder:
if self._macports:
self._environment[ 'BOOST_INCLUDEDIR' ] = '/opt/local/include'
self._environment[ 'BOOST_LIBRARYDIR' ] = '/opt/local/lib'
-
# Set or guess the various projects TOP environment variables.
for project in self.projects:
topVariable = "%s_TOP" % project.getName().upper()
topUserVariable = "%s_USER_TOP" % project.getName().upper()
self._setEnvironment ( topVariable, topUserVariable )
-
if tools:
# Checks if the requested tools are in the various projects.
self.standalones = tools
for project in self.projects:
self.standalones = project.activate ( self.standalones )
for tool in self.standalones:
- print "[WARNING] Tool \"%s\" is not part of any project." % tool
-
+ print( '[WARNING] Tool "{}" is not part of any project.'.format(tool) )
if projects:
for projectName in projects:
project = self.getProject ( projectName )
if not project:
ErrorMessage( 1, "No project of name \"%s\"."%projectName ).terminate()
project.activateAll()
-
if not tools and not projects:
for project in self.projects:
project.activateAll ()
-
for project in self.projects:
for tool in project.getActives():
- print "\nProcessing tool: \"%s\"." % tool.name
+ print( '\nProcessing tool: "{}".'.format(tool.name) )
getattr(self,command) ( tool )
return
-
def enable ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_enableTool" )
return
-
def enabledTools ( self ):
tools = []
for project in self.projects:
tools += project.getActives()
return tools
-
def build ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_build" )
return
-
def gitTarball ( self, tools, projects ):
if self.gitHash == "x":
self._guessGitHash ( self.getProject(projects[0]) )
-
self._doSpec ()
# self._doDebChangelog ()
-
if os.path.isdir(self.tarballDir):
- print "Removing previous tarball directory: \"%s\"." % self.tarballDir
+ print( 'Removing previous tarball directory: "{}".'.format(self.tarballDir) )
command = [ "/bin/rm", "-rf", self.tarballDir ]
self._execute ( command, "Removing top export (tarball) directory" )
-
- print "Creating tarball directory: \"%s\"." % self.tarballDir
+ print( 'Creating tarball directory: "{}".'.format(self.tarballDir) )
os.makedirs ( self.tarballDir )
self.gitArchive ( projects[0] )
-
return
-
def userTarball ( self, tools, projects ):
self.enable( tools, projects )
-
userSourceTarBz2 = os.path.join ( self.tarballDir
, datetime.date.today().strftime('%s-%s-%%Y%%m%%d.tar.bz2'%
(self.packageName
,self.packageVersion)) )
-
excludes = []
for exclude in self.packageExcludes:
excludes += [ '--exclude='+exclude ]
-
os.chdir ( self.sourceDir )
command = [ "/bin/tar"
, "--exclude-backups"
@@ -410,40 +364,34 @@ class Builder:
+ [ "-jcvf", userSourceTarBz2 ] \
+ self.enabledTools()
self._execute ( command, "tar command failed" )
-
return
-
def doRpm ( self ):
self.gitTarball ( [], self.packageProjects )
-
for rpmDir in [ "SOURCES", "SPECS", "BUILD", "tmp"
, "SRPMS", "RPMS/i386", "RPMS/i686", "RPMS/x86_64" ]:
- rpmFullDir = os.path.join ( self.rpmbuildDir, rpmDir )
- if not os.path.isdir(rpmFullDir):
- os.makedirs ( rpmFullDir )
- else:
- for entry in os.listdir(rpmFullDir):
- path = os.path.join( rpmFullDir, entry )
- if os.path.islink(path):
- realpath = os.path.realpath( os.readlink(path) )
- if not os.path.isfile(realpath):
- print 'Remove obsolete link: <%s>.' % path
- os.unlink( path )
-
+ rpmFullDir = os.path.join ( self.rpmbuildDir, rpmDir )
+ if not os.path.isdir(rpmFullDir):
+ os.makedirs ( rpmFullDir )
+ else:
+ for entry in os.listdir(rpmFullDir):
+ path = os.path.join( rpmFullDir, entry )
+ if os.path.islink(path):
+ realpath = os.path.realpath( os.readlink(path) )
+ if not os.path.isfile(realpath):
+ print( 'Remove obsolete link: "{}".'.format(path) )
+ os.unlink( path )
rpmSpecFile = os.path.join ( self.rpmbuildDir, "SPECS" , "coriolis2.spec" )
rpmSourceFile = os.path.join ( self.rpmbuildDir, "SOURCES", self.sourceTarBz2 )
sourceFile = os.path.join ( self.tarballDir , self.sourceTarBz2 )
-
+
if os.path.isfile ( rpmSpecFile ):
os.unlink ( rpmSpecFile )
os.symlink ( self.specFile, rpmSpecFile )
-
if not os.path.islink ( rpmSourceFile ):
os.symlink ( sourceFile, rpmSourceFile )
os.chdir ( self.rpmbuildDir )
-
command = [ "/usr/bin/rpmbuild"
, "--define", "_topdir %s" % self.rpmbuildDir
, "--define", "_tmppath %s" % self.tmppathDir
@@ -452,18 +400,13 @@ class Builder:
if self._devtoolset:
command += [ "--define", "scl devtoolset-%d"%self._devtoolset ]
command += [ "-ba", "--clean", rpmSpecFile ]
-
self._execute ( command, "Rebuild rpm packages" )
-
return
-
def doDeb ( self ):
self.svnTarball ( [], self.packageProjects )
-
if not os.path.isdir(self.debbuildDir):
os.makedirs ( self.debbuildDir )
-
os.chdir ( self.debbuildDir )
sourceFile = os.path.join ( self.tarballDir , self.sourceTarBz2 )
debOrigFile = os.path.join ( self.debbuildDir, "coriolis2_1.0.%s.orig.tar.bz2" % self.gitHash )
@@ -478,17 +421,12 @@ class Builder:
packageDir = os.path.join ( self.debbuildDir, "coriolis2-1.0.%s" % self.gitHash )
os.chdir ( packageDir )
-
self._environment["CFLAGS" ] = "-O2"
self._environment["CXXFLAGS"] = "-O2"
command = [ "/usr/bin/debuild", "-us", "-uc" ]
self._execute ( command, "Rebuild Debian packages" )
-
return
-
def getProject ( self, name ): return self._conf.getProject(name)
def loadConfiguration ( self, confFile ): self._conf.load( confFile )
def showConfiguration ( self ): self._conf.show()
-
-
diff --git a/bootstrap/builder/BuilderGui.py b/bootstrap/builder/BuilderGui.py
index aff453ab..82233dbf 100644
--- a/bootstrap/builder/BuilderGui.py
+++ b/bootstrap/builder/BuilderGui.py
@@ -2,75 +2,72 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Damien Dupuis |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./builder/BuilderGui.py" |
# +-----------------------------------------------------------------+
-from PyQt4.QtGui import QTabWidget
-from PyQt4.QtGui import QApplication
-from PyQt4.QtGui import QMainWindow
-from PyQt4.QtGui import QAction
-from PyQt4.QtGui import QKeySequence
-from OptionsWidget import OptionsWidget
-from CompileWidget import CompileWidget
-from ConfigureWidget import ConfigureWidget
-from AboutWidget import AboutWidget
+from PyQt4.QtGui import QTabWidget, QApplication, QMainWindow, \
+ QAction , QKeySequence
+from .OptionsWidget import OptionsWidget
+from .CompileWidget import CompileWidget
+from .ConfigureWidget import ConfigureWidget
+from .AboutWidget import AboutWidget
class BuilderGui ( QMainWindow ):
- def __init__ ( self, confFile, parent=None ):
- QMainWindow.__init__( self, parent )
- self.setWindowTitle( 'Coriolis/Chams Builder' )
- self._tabWidget = QTabWidget()
- self._configureWidget = ConfigureWidget(confFile)
- self._optionsWidget = OptionsWidget(self._configureWidget.conf)
- self._compileWidget = CompileWidget()
- self._aboutWidget = AboutWidget()
-
- self._tabWidget.addTab( self._optionsWidget , 'Options' )
- self._tabWidget.addTab( self._compileWidget , 'Compile' )
- self._tabWidget.addTab( self._configureWidget, 'Configure' )
- self.setCentralWidget( self._tabWidget )
-
- self._compileWidget.conf = self._configureWidget
- self._compileWidget.options = self._optionsWidget
-
- self._exitAction = QAction( '&Exit', self )
- self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
- self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
- self._exitAction.triggered.connect( QApplication.closeAllWindows )
-
- self._saveAction = QAction( '&Save Settings', self )
- self._saveAction.setStatusTip( 'Save Settings' )
- self._saveAction.setShortcut ( QKeySequence('CTRL+S') )
- self._saveAction.triggered.connect( self._configureWidget.saveSettings )
- self._saveAction.triggered.connect( self._optionsWidget.saveSettings )
- self._saveAction.triggered.connect( self._compileWidget.saveSettings )
-
- self._aboutAction = QAction( '&About', self )
- self._aboutAction.setStatusTip( 'A Word About Who\'s Responsible for This Thing' )
- self._aboutAction.setShortcut ( QKeySequence('CTRL+A') )
- self._aboutAction.triggered.connect( self._aboutWidget.show )
-
- fileMenu = self.menuBar().addMenu( 'File' )
- fileMenu.addAction( self._exitAction )
- fileMenu.addAction( self._saveAction )
- fileMenu.addAction( self._aboutAction )
- return
-
- def closeEvent ( self, event ):
- self._configureWidget.saveSettings()
- self._optionsWidget .saveSettings()
- self._compileWidget .saveSettings()
- event.accept()
- return
+ def __init__ ( self, confFile, parent=None ):
+ QMainWindow.__init__( self, parent )
+ self.setWindowTitle( 'Coriolis Toolchain Builder' )
+ self._tabWidget = QTabWidget()
+ self._configureWidget = ConfigureWidget(confFile)
+ self._optionsWidget = OptionsWidget(self._configureWidget.conf)
+ self._compileWidget = CompileWidget()
+ self._aboutWidget = AboutWidget()
+
+ self._tabWidget.addTab( self._optionsWidget , 'Options' )
+ self._tabWidget.addTab( self._compileWidget , 'Compile' )
+ self._tabWidget.addTab( self._configureWidget, 'Configure' )
+ self.setCentralWidget( self._tabWidget )
+
+ self._compileWidget.conf = self._configureWidget
+ self._compileWidget.options = self._optionsWidget
+
+ self._exitAction = QAction( '&Exit', self )
+ self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
+ self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
+ self._exitAction.triggered.connect( QApplication.closeAllWindows )
+
+ self._saveAction = QAction( '&Save Settings', self )
+ self._saveAction.setStatusTip( 'Save Settings' )
+ self._saveAction.setShortcut ( QKeySequence('CTRL+S') )
+ self._saveAction.triggered.connect( self._configureWidget.saveSettings )
+ self._saveAction.triggered.connect( self._optionsWidget.saveSettings )
+ self._saveAction.triggered.connect( self._compileWidget.saveSettings )
+
+ self._aboutAction = QAction( '&About', self )
+ self._aboutAction.setStatusTip( 'A Word About Who\'s Responsible for This Thing' )
+ self._aboutAction.setShortcut ( QKeySequence('CTRL+A') )
+ self._aboutAction.triggered.connect( self._aboutWidget.show )
+
+ fileMenu = self.menuBar().addMenu( 'File' )
+ fileMenu.addAction( self._exitAction )
+ fileMenu.addAction( self._saveAction )
+ fileMenu.addAction( self._aboutAction )
+ return
+
+ def closeEvent ( self, event ):
+ self._configureWidget.saveSettings()
+ self._optionsWidget .saveSettings()
+ self._compileWidget .saveSettings()
+ event.accept()
+ return
diff --git a/bootstrap/builder/CompileWidget.py b/bootstrap/builder/CompileWidget.py
index a589e3de..e442bc7d 100644
--- a/bootstrap/builder/CompileWidget.py
+++ b/bootstrap/builder/CompileWidget.py
@@ -2,11 +2,11 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
@@ -17,195 +17,166 @@
import re
import subprocess
-from PyQt4.QtCore import Qt
-from PyQt4.QtCore import pyqtSignal
-from PyQt4.QtCore import QSettings
-from PyQt4.QtGui import QFont
-from PyQt4.QtGui import QColor
-from PyQt4.QtGui import QPalette
-from PyQt4.QtGui import QTextCharFormat
-from PyQt4.QtGui import QWidget
-from PyQt4.QtGui import QLabel
-from PyQt4.QtGui import QPushButton
-from PyQt4.QtGui import QCheckBox
-from PyQt4.QtGui import QGroupBox
-from PyQt4.QtGui import QButtonGroup
-from PyQt4.QtGui import QVBoxLayout
-from PyQt4.QtGui import QHBoxLayout
-from PyQt4.QtGui import QGridLayout
-from PyQt4.QtGui import QScrollArea
-from PyQt4.QtGui import QComboBox
-from PyQt4.QtGui import QLineEdit
-from PyQt4.QtGui import QTextEdit
-from PyQt4.QtGui import QFileDialog
-from PyQt4.QtGui import QProgressBar
-from PyQt4.QtGui import QApplication
-from builder.Highlighter import Highlighter
+from PyQt4.QtCore import Qt, pyqtSignal, QSettings
+from PyQt4.QtGui import QFont, QColor, QPalette, QTextCharFormat, \
+ QWidget, QLabel, QPushButton, QCheckBox, \
+ QGroupBox, QButtonGroup, QVBoxLayout, \
+ QHBoxLayout, QGridLayout, QScrollArea, \
+ QComboBox, QLineEdit, QTextEdit, \
+ QFileDialog, QProgressBar, QApplication
+from .Highlighter import Highlighter
class CompileWidget ( QWidget ):
-
- progress = pyqtSignal(int)
-
- def __init__ ( self, parent=None ):
- QWidget.__init__ ( self, parent )
- self._options = None
- self._conf = None
-
- self._go = QPushButton( 'Go' )
- self._go.setMaximumWidth( 100 )
- font = self._go.font()
- font.setPointSizeF( font.pointSizeF()*2.0 )
- font.setWeight ( QFont.Bold )
- self._go.setFont( font )
- self._go.clicked.connect( self.go )
-
- self._saveLog = QPushButton( 'Save' )
- saveLogLabel = QLabel( 'Log File:' )
- saveLogBrowse = QPushButton( '&Browse' )
- saveLogBrowse.clicked.connect( self.browseSaveLog )
- self._saveLogEdit = QLineEdit( '' )
-
- gLayout = QGridLayout()
- gLayout.addWidget( saveLogLabel , 0, 0, 1, 1, Qt.AlignRight )
- gLayout.addWidget( self._saveLogEdit, 0, 1, 1, 6 )
- gLayout.addWidget( saveLogBrowse , 0, 7, 1, 1 )
-
- self._console = QTextEdit()
- self._console.setLineWrapMode( QTextEdit.NoWrap )
- self._console.setMinimumSize ( 800, 400 )
- palette = self._console.palette()
- palette.setColor( QPalette.Base, QColor.fromRgb(255,255,221) ) # ffffdd.
- self._console.setPalette( palette )
- font = QFont( 'Bitstream Vera Sans Mono', self._console.font().pointSize() )
- self._console.setFont( font )
- self._highlighter = Highlighter( self._console.document() )
-
- self._progressBar = QProgressBar()
- self._progressBar.setRange ( 0, 100 )
- self._progressBar.setTextVisible( True )
-
- hLayout = QHBoxLayout()
- hLayout.addStretch()
- hLayout.addWidget( self._go )
- hLayout.addStretch()
- hLayout.addWidget( self._saveLog )
- hLayout.addStretch()
-
- vLayout = QVBoxLayout()
- vLayout.addLayout( hLayout )
- vLayout.addLayout( gLayout )
- vLayout.addWidget( self._progressBar )
- vLayout.addWidget( self._console )
- self.setLayout( vLayout )
-
- self.progress.connect( self._progressBar.setValue )
- self._saveLog.clicked.connect( self.saveLog )
-
- self.readSettings()
- return
-
-
- def _setOptions ( self, options ): self._options = options
- def _setConf ( self, conf ): self._conf = conf
- def _getOptions ( self ): return self._options
- def _getConf ( self ): return self._conf
-
- options = property( _getOptions, _setOptions )
- conf = property( _getConf , _setConf )
-
-
- def browseSaveLog ( self ):
- self._saveLogEdit.setText( QFileDialog.getSaveFileName(self
- ,'Select Log File Report'
- ,self._saveLogEdit.text()
- ,'Report Files (*.log *.txt)') )
- return
-
- def saveLog ( self ):
- if self._saveLogEdit.text():
- fd = open( self._saveLogEdit.text(), 'w+' )
- fd.write( self._console.toPlainText() )
- fd.close()
- return
-
-
- def shellCommand ( self ):
- command = [ self.conf.bootstrapDir+'/ccb.py' ]
- for project in self.options.projects:
- for tool in project.actives:
- command += [ '--tool='+tool ]
- toolsCount = len(command) - 1
-
- if self.conf.rootDir: command += [ '--root=%s'%self.conf.rootDir ]
-
- #if self.options.svnUpdate: command += [ '--svn-update' ]
- #if self.options.svnStatus: command += [ '--svn-update' ]
- if self.options.enableDoc: command += [ '--doc' ]
- if self.options.devtoolset: command += [ '--devtoolset-8' ]
- if self.options.qt5: command += [ '--qt5' ]
- if self.options.noCache: command += [ '--no-cache' ]
- if self.options.rmBuild: command += [ '--rm-build' ]
- if self.options.verbose: command += [ '--verbose' ]
- if self.options.make:
- makeArguments='install '+self.options.threads
- command += [ '--make=%s'%makeArguments ]
+
+ progress = pyqtSignal(int)
+
+ def __init__ ( self, parent=None ):
+ QWidget.__init__ ( self, parent )
+ self._options = None
+ self._conf = None
- if self.options.buildMode == 'Debug':
- command += [ '--debug' ]
- return toolsCount, command
-
-
- def go ( self ):
- rePercentage = re.compile(r'^\[\s*(?P\d+)%\].*')
- reProcessTool = re.compile(r'^Processing tool:\s*"(?P.+)"')
-
- if not self.options or not self.conf: return
-
- toolsCount, command = self.shellCommand()
- if not toolsCount: return
-
- self._progressBar.reset()
- self._progressBar.setRange( 0, toolsCount*100 )
-
- strCommand = command[0]
- for arg in command[1:]:
- strCommand += ' ' + arg
- strCommand += '\n\n'
- self._console.setFontItalic( True )
- self._console.insertPlainText( strCommand )
- self._console.setFontItalic( False )
-
- toolsDone = -1
- builderProcess = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
- while True:
- line = builderProcess.stdout.readline()
- if line == '': break
-
- m = rePercentage.match( line )
- if m:
- self.progress.emit( toolsDone*100+int(m.group('percent')) )
- else:
- m = reProcessTool.match( line )
- if m:
- toolsDone += 1
-
- self._console.insertPlainText( line )
-
- scrollBar = self._console.verticalScrollBar()
- scrollBar.setValue( scrollBar.maximum() )
- QApplication.processEvents()
- builderProcess.wait()
- if builderProcess.returncode == None:
- pass
- return
-
- def readSettings ( self ):
- settings = QSettings()
- self._saveLogEdit.setText( settings.value('compile/saveLog').toString() )
- return
-
- def saveSettings ( self ):
- settings = QSettings()
- settings.setValue( 'compile/saveLog', self._saveLogEdit.text() )
- return
+ self._go = QPushButton( 'Go' )
+ self._go.setMaximumWidth( 100 )
+ font = self._go.font()
+ font.setPointSizeF( font.pointSizeF()*2.0 )
+ font.setWeight ( QFont.Bold )
+ self._go.setFont( font )
+ self._go.clicked.connect( self.go )
+
+ self._saveLog = QPushButton( 'Save' )
+ saveLogLabel = QLabel( 'Log File:' )
+ saveLogBrowse = QPushButton( '&Browse' )
+ saveLogBrowse.clicked.connect( self.browseSaveLog )
+ self._saveLogEdit = QLineEdit( '' )
+
+ gLayout = QGridLayout()
+ gLayout.addWidget( saveLogLabel , 0, 0, 1, 1, Qt.AlignRight )
+ gLayout.addWidget( self._saveLogEdit, 0, 1, 1, 6 )
+ gLayout.addWidget( saveLogBrowse , 0, 7, 1, 1 )
+
+ self._console = QTextEdit()
+ self._console.setLineWrapMode( QTextEdit.NoWrap )
+ self._console.setMinimumSize ( 800, 400 )
+ palette = self._console.palette()
+ palette.setColor( QPalette.Base, QColor.fromRgb(255,255,221) ) # ffffdd.
+ self._console.setPalette( palette )
+ font = QFont( 'Bitstream Vera Sans Mono', self._console.font().pointSize() )
+ self._console.setFont( font )
+ self._highlighter = Highlighter( self._console.document() )
+
+ self._progressBar = QProgressBar()
+ self._progressBar.setRange ( 0, 100 )
+ self._progressBar.setTextVisible( True )
+
+ hLayout = QHBoxLayout()
+ hLayout.addStretch()
+ hLayout.addWidget( self._go )
+ hLayout.addStretch()
+ hLayout.addWidget( self._saveLog )
+ hLayout.addStretch()
+
+ vLayout = QVBoxLayout()
+ vLayout.addLayout( hLayout )
+ vLayout.addLayout( gLayout )
+ vLayout.addWidget( self._progressBar )
+ vLayout.addWidget( self._console )
+ self.setLayout( vLayout )
+
+ self.progress.connect( self._progressBar.setValue )
+ self._saveLog.clicked.connect( self.saveLog )
+
+ self.readSettings()
+ return
+
+ def _setOptions ( self, options ): self._options = options
+ def _setConf ( self, conf ): self._conf = conf
+ def _getOptions ( self ): return self._options
+ def _getConf ( self ): return self._conf
+
+ options = property( _getOptions, _setOptions )
+ conf = property( _getConf , _setConf )
+
+ def browseSaveLog ( self ):
+ self._saveLogEdit.setText( QFileDialog.getSaveFileName( self
+ , 'Select Log File Report'
+ , self._saveLogEdit.text()
+ , 'Report Files (*.log *.txt)' ) )
+ return
+
+ def saveLog ( self ):
+ if self._saveLogEdit.text():
+ fd = open( self._saveLogEdit.text(), 'w+' )
+ fd.write( self._console.toPlainText() )
+ fd.close()
+ return
+
+ def shellCommand ( self ):
+ command = [ self.conf.bootstrapDir+'/ccb.py' ]
+ for project in self.options.projects:
+ for tool in project.actives:
+ command += [ '--tool='+tool ]
+ toolsCount = len(command) - 1
+ if self.conf.rootDir: command += [ '--root=%s'%self.conf.rootDir ]
+ #if self.options.svnUpdate: command += [ '--svn-update' ]
+ #if self.options.svnStatus: command += [ '--svn-update' ]
+ if self.options.enableDoc: command += [ '--doc' ]
+ if self.options.devtoolset: command += [ '--devtoolset-8' ]
+ if self.options.qt5: command += [ '--qt5' ]
+ if self.options.noCache: command += [ '--no-cache' ]
+ if self.options.rmBuild: command += [ '--rm-build' ]
+ if self.options.verbose: command += [ '--verbose' ]
+ if self.options.make:
+ makeArguments='install '+self.options.threads
+ command += [ '--make=%s'%makeArguments ]
+ if self.options.buildMode == 'Debug':
+ command += [ '--debug' ]
+ return toolsCount, command
+
+ def go ( self ):
+ rePercentage = re.compile(r'^\[\s*(?P\d+)%\].*')
+ reProcessTool = re.compile(r'^Processing tool:\s*"(?P.+)"')
+ if not self.options or not self.conf: return
+ toolsCount, command = self.shellCommand()
+ if not toolsCount: return
+ self._progressBar.reset()
+ self._progressBar.setRange( 0, toolsCount*100 )
+
+ strCommand = command[0]
+ for arg in command[1:]:
+ strCommand += ' ' + arg
+ strCommand += '\n\n'
+ self._console.setFontItalic( True )
+ self._console.insertPlainText( strCommand )
+ self._console.setFontItalic( False )
+
+ toolsDone = -1
+ builderProcess = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
+ while True:
+ line = builderProcess.stdout.readline()
+ if line == '': break
+ m = rePercentage.match( line )
+ if m:
+ self.progress.emit( toolsDone*100+int(m.group('percent')) )
+ else:
+ m = reProcessTool.match( line )
+ if m:
+ toolsDone += 1
+ self._console.insertPlainText( line )
+ scrollBar = self._console.verticalScrollBar()
+ scrollBar.setValue( scrollBar.maximum() )
+ QApplication.processEvents()
+ builderProcess.wait()
+ if builderProcess.returncode == None:
+ pass
+ return
+
+ def readSettings ( self ):
+ settings = QSettings()
+ self._saveLogEdit.setText( settings.value('compile/saveLog') )
+ return
+
+ def saveSettings ( self ):
+ settings = QSettings()
+ settings.setValue( 'compile/saveLog', self._saveLogEdit.text() )
+ return
diff --git a/bootstrap/builder/Configuration.py b/bootstrap/builder/Configuration.py
index 3f2ec6fe..98565f28 100644
--- a/bootstrap/builder/Configuration.py
+++ b/bootstrap/builder/Configuration.py
@@ -2,14 +2,14 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2008-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2008-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./builder/Configuration.py" |
# +-----------------------------------------------------------------+
@@ -21,8 +21,8 @@ import os
import os.path
import datetime
import subprocess
-from . import ErrorMessage
-from Project import Project
+from . import ErrorMessage
+from .Project import Project
class Configuration ( object ):
@@ -64,31 +64,26 @@ class Configuration ( object ):
self._updateSecondary()
return
-
def __setattr__ ( self, attribute, value ):
if attribute in Configuration.SecondaryNames:
- print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
+ print( ErrorMessage( 1, 'Attempt to write in read-only attribute "{}" in Configuration.' \
+ .format(attribute) ))
return
-
if attribute[0] == '_':
self.__dict__[attribute] = value
return
-
if attribute == 'rootDir': value = os.path.expanduser(value)
elif attribute == 'enableShared' and value != 'ON': value = 'OFF'
-
self.__dict__['_'+attribute] = value
self._updateSecondary()
return
-
def __getattr__ ( self, attribute ):
if attribute[0] != '_': attribute = '_'+attribute
- if not self.__dict__.has_key(attribute):
+ if not attribute in self.__dict__:
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
return self.__dict__[attribute]
-
def _updateSecondary ( self ):
if self._enableShared == "ON": self._libMode = "Shared"
else: self._libMode = "Static"
@@ -109,7 +104,6 @@ class Configuration ( object ):
, "%s.%s" % (self._buildMode,self._libMode) )
self._buildDir = os.path.join ( self._osDir, "build" )
self._installDir = os.path.join ( self._osDir, "install" )
-
self._specFileIn = os.path.join ( self._bootstrapDir, "%s.spec.in"%self._packageName )
self._specFile = os.path.join ( self._bootstrapDir, "%s.spec" %self._packageName )
self._debianDir = os.path.join ( self._bootstrapDir, "debian" )
@@ -126,7 +120,6 @@ class Configuration ( object ):
self._distribPatch = os.path.join ( self._sourceDir, "bootstrap", "%s-for-distribution.patch"%self._packageName )
return
-
def _guessOs ( self ):
self._libSuffix = None
self._osSlsoc7x_64 = re.compile (".*Linux.*(el7|slsoc7).*x86_64.*")
@@ -149,95 +142,89 @@ class Configuration ( object ):
self._osCygwinW10_64 = re.compile (".*CYGWIN_NT-10\.[0-3].*x86_64.*")
self._osCygwinW10 = re.compile (".*CYGWIN_NT-10\.[0-3].*i686.*")
- uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
- lines = uname.stdout.readlines()
-
- if self._osSlsoc7x_64.match(lines[0]):
+ uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
+ lines = uname.stdout.readlines()
+ osLine = lines[0].decode( 'ascii' )
+ if self._osSlsoc7x_64.match(osLine):
self._osType = "Linux.el7_64"
self._libSuffix = "64"
- elif self._osSlsoc6x_64.match(lines[0]):
+ elif self._osSlsoc6x_64.match(osLine):
self._osType = "Linux.slsoc6x_64"
self._libSuffix = "64"
- elif self._osSlsoc6x .match(lines[0]): self._osType = "Linux.slsoc6x"
- elif self._osSLSoC5x_64.match(lines[0]):
+ elif self._osSlsoc6x .match(osLine): self._osType = "Linux.slsoc6x"
+ elif self._osSLSoC5x_64.match(osLine):
self._osType = "Linux.SLSoC5x_64"
self._libSuffix = "64"
- elif self._osSLSoC5x .match(lines[0]): self._osType = "Linux.SLSoC5x"
- elif self._osFedora_64 .match(lines[0]):
+ elif self._osSLSoC5x .match(osLine): self._osType = "Linux.SLSoC5x"
+ elif self._osFedora_64 .match(osLine):
self._osType = "Linux.fc_64"
self._libSuffix = "64"
- elif self._osFedora .match(lines[0]): self._osType = "Linux.fc"
- elif self._osLinux_64 .match(lines[0]):
+ elif self._osFedora .match(osLine): self._osType = "Linux.fc"
+ elif self._osLinux_64 .match(osLine):
self._osType = "Linux.x86_64"
if os.path.exists("/usr/lib64/"):
self._libSuffix = "64"
- elif self._osLinux .match(lines[0]): self._osType = "Linux.i386"
- elif self._osDarwin .match(lines[0]): self._osType = "Darwin"
- elif self._osFreeBSD8x_amd64.match(lines[0]):
+ elif self._osLinux .match(osLine): self._osType = "Linux.i386"
+ elif self._osDarwin .match(osLine): self._osType = "Darwin"
+ elif self._osFreeBSD8x_amd64.match(osLine):
self._osType = "FreeBSD.8x.amd64"
self._libSuffix = "64"
- elif self._osFreeBSD8x_64.match(lines[0]):
+ elif self._osFreeBSD8x_64.match(osLine):
self._osType = "FreeBSD.8x.x86_64"
self._libSuffix = "64"
- elif self._osFreeBSD8x .match(lines[0]): self._osType = "FreeBSD.8x.i386"
- elif self._osCygwinW7_64.match(lines[0]):
+ elif self._osFreeBSD8x .match(osLine): self._osType = "FreeBSD.8x.i386"
+ elif self._osCygwinW7_64.match(osLine):
self._osType = "Cygwin.W7_64"
self._libSuffix = "64"
- elif self._osCygwinW7.match(lines[0]): self._osType = "Cygwin.W7"
- elif self._osCygwinW8_64.match(lines[0]):
+ elif self._osCygwinW7.match(osLine): self._osType = "Cygwin.W7"
+ elif self._osCygwinW8_64.match(osLine):
self._osType = "Cygwin.W8_64"
self._libSuffix = "64"
- elif self._osCygwinW8.match(lines[0]): self._osType = "Cygwin.W8"
- elif self._osCygwinW10_64.match(lines[0]):
+ elif self._osCygwinW8.match(osLine): self._osType = "Cygwin.W8"
+ elif self._osCygwinW10_64.match(osLine):
self._osType = "Cygwin.W10_64"
self._libSuffix = "64"
- elif self._osCygwinW10.match(lines[0]): self._osType = "Cygwin.W10"
+ elif self._osCygwinW10.match(osLine): self._osType = "Cygwin.W10"
else:
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
self._osType = uname.stdout.readlines()[0][:-1]
- print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
- print " (using: \"%s\")" % self._osType
+ print( '[WARNING] Unrecognized OS: "{}."'.format(osLine[:-1]) )
+ print( ' (using: "{}")'.format(self._osType) )
if self._libSuffix == '64' and not os.path.exists('/usr/lib64'):
self._libSuffix = None
-
return
-
def getPrimaryIds ( self ): return Configuration.PrimaryNames
def getSecondaryIds ( self ): return Configuration.SecondaryNames
def getAllIds ( self ): return Configuration.PrimaryNames + Configuration.SecondaryNames
-
def register ( self, project ):
for registered in self._projects:
if registered.getName() == project.getName():
- print ErrorMessage( 0, "Project \"%s\" is already registered (ignored)." )
+ print( ErrorMessage( 0, 'Project "{}" is already registered (ignored).'.format(project.getName()) ))
return
self._projects += [ project ]
return
-
def getProject ( self, name ):
for project in self._projects:
if project.getName() == name:
return project
return None
-
def getToolProject ( self, name ):
for project in self._projects:
if project.hasTool(name):
return project
return None
-
def load ( self, confFile ):
moduleGlobals = globals()
if not confFile:
- print 'Making an educated guess to locate the configuration file:'
+ print( 'Making an educated guess to locate the configuration file:' )
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
, os.environ['HOME']+'/coriolis-2.x/src/coriolis/bootstrap'
, os.environ['HOME']+'/coriolis/src/coriolis/bootstrap'
@@ -247,86 +234,82 @@ class Configuration ( object ):
for location in locations:
self._confFile = location + '/build.conf'
- print ' <%s>' % self._confFile
+ print( ' "{}"'.format(self._confFile) )
if os.path.isfile(self._confFile): break
if not self._confFile:
ErrorMessage( 1, 'Cannot locate any configuration file.' ).terminate()
else:
- print 'Using user-supplied configuration file:'
- print ' <%s>' % confFile
+ print( 'Using user-supplied configuration file:' )
+ print( ' "{}"'.format(confFile) )
self._confFile = confFile
if not os.path.isfile(self._confFile):
ErrorMessage( 1, 'Missing configuration file:', '<%s>'%self._confFile ).terminate()
- print 'Reading configuration from:'
- print ' <%s>' % self._confFile
-
+ print( 'Reading configuration from:' )
+ print( ' "{}"'.format(self._confFile) )
try:
- execfile( self._confFile, moduleGlobals )
- except Exception, e:
+ exec( open(self._confFile).read(), globals() )
+ except Exception as e:
ErrorMessage( 1, 'An exception occured while loading the configuration file:'
, '<%s>\n' % (self._confFile)
, 'You should check for simple python errors in this file.'
, 'Error was:'
, '%s\n' % e ).terminate()
-
- if moduleGlobals.has_key('projects'):
+
+ if 'projects' in moduleGlobals:
entryNb = 0
for entry in moduleGlobals['projects']:
entryNb += 1
- if not entry.has_key('name'):
+ if not 'name' in entry:
raise ErrorMessage( 1, 'Missing project name in project entry #%d.' % entryNb )
- if not entry.has_key('tools'):
+ if not 'tools' in entry:
raise ErrorMessage( 1, 'Missing tools list in project entry #%d (<%s>).' \
% (entryNb,entry['name']) )
if not isinstance(entry['tools'],list):
raise ErrorMessage( 1, 'Tools item of project entry #%d (<%s>) is not a list.' \
% (entryNb,entry['name']) )
- if not entry.has_key('repository'):
+ if not 'repository' in entry:
raise ErrorMessage( 1, 'Missing project repository in project entry #%d.' \
% entryNb )
self.register( Project(entry['name'],entry['tools'],entry['repository']) )
else:
- ErrorMessage( 1, 'Configuration file is missing the \'project\' symbol.'
- , '<%s>'%self._confFile ).terminate()
+ ErrorMessage( 1, 'Configuration file is missing the "project" symbol.'
+ , '"{}"'.format(self._confFile) ).terminate()
- if moduleGlobals.has_key('projectdir'):
+ if 'projectdir' in moduleGlobals:
self.projectDir = moduleGlobals['projectdir']
-
- if moduleGlobals.has_key('svnconfig'):
+ if 'svnconfig' in moduleGlobals:
svnconfig = moduleGlobals['svnconfig']
- if svnconfig.has_key('method'): self._svnMethod = svnconfig['method']
-
- if moduleGlobals.has_key('package'):
+ if 'method' in svnconfig: self._svnMethod = svnconfig['method']
+ if 'package' in moduleGlobals:
package = moduleGlobals['package']
- if package.has_key('name' ): self.packageName = package['name']
- if package.has_key('version' ): self.packageVersion = package['version']
- if package.has_key('excludes'):
+ if 'name' in package: self.packageName = package['name']
+ if 'version' in package: self.packageVersion = package['version']
+ if 'excludes' in package:
if not isinstance(package['excludes'],list):
raise ErrorMessage( 1, 'Excludes of package configuration is not a list.')
self._packageExcludes = package['excludes']
- if package.has_key('projects'):
+ if 'projects' in package:
if not isinstance(package['projects'],list):
raise ErrorMessage( 1, 'Projects to package is not a list.')
self._packageProjects = package['projects']
return
-
def show ( self ):
- print 'CCB Configuration:'
+ print( 'CCB Configuration:' )
if self._gitMethod:
- print ' Git Method: <%s>' % self._gitMethod
+ print( ' Git Method: "{}"'.format(self._gitMethod) )
else:
- print ' Git Method not defined, will not be able to push/pull.'
-
+ print( ' Git Method not defined, will not be able to push/pull.' )
for project in self._projects:
- print ' project:%-15s repository:<%s>' % ( ('<%s>'%project.getName()), project.getRepository() )
+ print( ' project:{0:>15} repository:"{1}"' \
+ .format( '"{}"'.format(project.getName()), project.getRepository() ))
toolOrder = 1
for tool in project.getTools():
- print '%s%02d:<%s>' % (' '*26,toolOrder,tool)
+ print( '{0}{1:02}:"{2}"'.format( ' '*26, toolOrder, tool ))
toolOrder += 1
print
return
diff --git a/bootstrap/builder/ConfigureWidget.py b/bootstrap/builder/ConfigureWidget.py
index 8094e1bc..be3600a0 100644
--- a/bootstrap/builder/ConfigureWidget.py
+++ b/bootstrap/builder/ConfigureWidget.py
@@ -2,45 +2,32 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Damien Dupuis |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./builder/ConfigureWidget.py" |
# +-----------------------------------------------------------------+
-from PyQt4.QtCore import Qt
-from PyQt4.QtCore import QVariant
-from PyQt4.QtCore import pyqtSignal
-from PyQt4.QtCore import QSettings
-from PyQt4.QtGui import QFont
-from PyQt4.QtGui import QWidget
-from PyQt4.QtGui import QGridLayout
-from PyQt4.QtGui import QHBoxLayout
-from PyQt4.QtGui import QVBoxLayout
-from PyQt4.QtGui import QLabel
-from PyQt4.QtGui import QPushButton
-from PyQt4.QtGui import QLineEdit
-from PyQt4.QtCore import QModelIndex
-from PyQt4.QtCore import QAbstractTableModel
-from PyQt4.QtGui import QAbstractItemView
-from PyQt4.QtGui import QHeaderView
-from PyQt4.QtGui import QTableView
-from PyQt4.QtGui import QGroupBox
-from PyQt4.QtGui import QFileDialog
-from PyQt4.QtGui import QApplication
-from Configuration import Configuration
+from PyQt4.QtCore import Qt, QVariant, pyqtSignal, QSettings, \
+ QModelIndex, QAbstractTableModel
+from PyQt4.QtGui import QFont, QWidget, QGridLayout, QHBoxLayout, \
+ QVBoxLayout, QLabel, QPushButton, \
+ QLineEdit, QAbstractItemView, QHeaderView, \
+ QTableView, QGroupBox, QFileDialog, \
+ QApplication
+from .Configuration import Configuration
class ConfSettingsModel ( QAbstractTableModel ):
- HeaderFont = QApplication.font()
+ HeaderFont = QApplication.font()
PrimaryFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Normal)
SecondaryFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Normal)
ValueFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Bold)
@@ -48,7 +35,6 @@ class ConfSettingsModel ( QAbstractTableModel ):
def __init__ ( self, conf, parent=None ):
ConfSettingsModel.HeaderFont.setBold( True )
ConfSettingsModel.SecondaryFont.setItalic( True )
-
QAbstractTableModel.__init__( self, parent )
self._conf = conf
self._ids = self._conf.getAllIds()
@@ -70,20 +56,15 @@ class ConfSettingsModel ( QAbstractTableModel ):
if row < self.rowCount():
if index.column() == 0: return self._ids[row]
elif index.column() == 1: return getattr( self._conf, self._ids[row] )
-
- return QVariant()
-
+ return None
def headerData ( self, section, orientation, role ):
- if orientation == Qt.Vertical: return QVariant()
+ if orientation == Qt.Vertical: return None
if role == Qt.FontRole: return ConfSettingsModel.HeaderFont
- if role != Qt.DisplayRole: return QVariant()
-
+ if role != Qt.DisplayRole: return None
if section == 0: return 'Setting'
elif section == 1: return 'Value'
-
- return QVariant('?')
-
+ return '?'
def rowCount ( self, index=QModelIndex() ): return len(self._ids)
def columnCount ( self, index=QModelIndex() ): return 2
@@ -119,79 +100,73 @@ class ConfSettingsWidget ( QWidget ):
peanoDataLayout = QGridLayout();
peanoDataLayout.addWidget( self._view, 0, 0, 1, 1 );
-
self.setLayout ( peanoDataLayout );
return
class ConfigureWidget ( QWidget ):
-
- def __init__ ( self, confFile, parent=None ):
- QWidget.__init__ ( self, parent )
- self._confFile = confFile
- self._conf = Configuration()
- self._rootDir = ''
-
- rootDirLabel = QLabel( 'Root Directory' )
- rootDirBrowse = QPushButton( '&Browse' )
- rootDirBrowse.clicked.connect( self.browseRootDir )
- self._rootDirEdit = QLineEdit( '' )
- #self._rootDirEdit.setFixedWidth( 600 )
-
- gLayout = QGridLayout()
- gLayout.addWidget( rootDirLabel , 0, 0, 1, 1 )
- gLayout.addWidget( self._rootDirEdit, 0, 1, 1, 6 )
- gLayout.addWidget( rootDirBrowse , 0, 7, 1, 1 )
- groupDirs = QGroupBox( 'Directories' )
- groupDirs.setLayout( gLayout )
-
- gLayout = QGridLayout()
- groupConf = QGroupBox( 'Configuration' )
- groupConf.setLayout( gLayout )
-
- vLayout = QVBoxLayout()
- vLayout.addWidget ( groupDirs )
- vLayout.addWidget ( groupConf )
- #vLayout.addStretch()
-
- self.setLayout( vLayout )
-
- self._rootDirEdit.textChanged.connect( self.rootDirChanged )
-
- self.readSettings()
-
- noteLabel = QLabel( 'Those settings can be changed only by editing build.conf' )
- gLayout.addWidget( noteLabel , 0, 0, 1, 1 )
- gLayout.addWidget( ConfSettingsWidget(self._conf), 1, 0, 1, 1 )
-
-
- def _getConf ( self ): return self._conf
- def _getRootDir ( self ): return self._rootDir
- def _getBootstrapDir ( self ): return self._getConf().bootstrapDir
-
- conf = property( _getConf )
- rootDir = property( _getRootDir )
- bootstrapDir = property( _getBootstrapDir )
-
-
- def rootDirChanged ( self, rootDir ):
- self._rootDir = rootDir
- return
-
- def browseRootDir ( self ):
- self._rootDirEdit.setText( QFileDialog.getExistingDirectory(self,'Select the Building Root Directory') )
- return
-
- def readSettings ( self ):
- settings = QSettings()
- self._rootDirEdit.setText( settings.value('conf/rootDir').toString() )
- if not self._confFile and settings.value('conf/confFile'):
- self._confFile = str( settings.value('conf/confFile').toString() )
- self._conf.load( self._confFile )
- return
-
- def saveSettings ( self ):
- settings = QSettings()
- settings.setValue( 'conf/rootDir' , self._rootDirEdit.text() )
- settings.setValue( 'conf/confFile', self._confFile )
- return
+
+ def __init__ ( self, confFile, parent=None ):
+ QWidget.__init__ ( self, parent )
+ self._confFile = confFile
+ self._conf = Configuration()
+ self._rootDir = ''
+
+ rootDirLabel = QLabel( 'Root Directory' )
+ rootDirBrowse = QPushButton( '&Browse' )
+ rootDirBrowse.clicked.connect( self.browseRootDir )
+ self._rootDirEdit = QLineEdit( '' )
+ #self._rootDirEdit.setFixedWidth( 600 )
+
+ gLayout = QGridLayout()
+ gLayout.addWidget( rootDirLabel , 0, 0, 1, 1 )
+ gLayout.addWidget( self._rootDirEdit, 0, 1, 1, 6 )
+ gLayout.addWidget( rootDirBrowse , 0, 7, 1, 1 )
+ groupDirs = QGroupBox( 'Directories' )
+ groupDirs.setLayout( gLayout )
+ gLayout = QGridLayout()
+ groupConf = QGroupBox( 'Configuration' )
+ groupConf.setLayout( gLayout )
+
+ vLayout = QVBoxLayout()
+ vLayout.addWidget ( groupDirs )
+ vLayout.addWidget ( groupConf )
+ #vLayout.addStretch()
+
+ self.setLayout( vLayout )
+ self._rootDirEdit.textChanged.connect( self.rootDirChanged )
+ self.readSettings()
+
+ noteLabel = QLabel( 'Those settings can be changed only by editing build.conf' )
+ gLayout.addWidget( noteLabel , 0, 0, 1, 1 )
+ gLayout.addWidget( ConfSettingsWidget(self._conf), 1, 0, 1, 1 )
+
+ def _getConf ( self ): return self._conf
+ def _getRootDir ( self ): return self._rootDir
+ def _getBootstrapDir ( self ): return self._getConf().bootstrapDir
+
+ conf = property( _getConf )
+ rootDir = property( _getRootDir )
+ bootstrapDir = property( _getBootstrapDir )
+
+ def rootDirChanged ( self, rootDir ):
+ self._rootDir = rootDir
+ return
+
+ def browseRootDir ( self ):
+ self._rootDirEdit.setText( QFileDialog.getExistingDirectory(self,'Select the Building Root Directory') )
+ return
+
+ def readSettings ( self ):
+ settings = QSettings()
+ self._rootDirEdit.setText( settings.value('conf/rootDir') )
+ if not self._confFile and settings.value('conf/confFile'):
+ self._confFile = str( settings.value('conf/confFile') )
+ self._conf.load( self._confFile )
+ return
+
+ def saveSettings ( self ):
+ settings = QSettings()
+ settings.setValue( 'conf/rootDir' , self._rootDirEdit.text() )
+ settings.setValue( 'conf/confFile', self._confFile )
+ return
diff --git a/bootstrap/builder/Highlighter.py b/bootstrap/builder/Highlighter.py
index cfe45bfe..95f64705 100644
--- a/bootstrap/builder/Highlighter.py
+++ b/bootstrap/builder/Highlighter.py
@@ -2,14 +2,14 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Damien Dupuis |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./builder/Highlighter.py" |
# +-----------------------------------------------------------------+
@@ -17,64 +17,61 @@
import re
from PyQt4.QtCore import Qt
-from PyQt4.QtGui import QFont
-from PyQt4.QtGui import QColor
-from PyQt4.QtGui import QTextCharFormat
-from PyQt4.QtGui import QSyntaxHighlighter
+from PyQt4.QtGui import QFont, QColor, QTextCharFormat, QSyntaxHighlighter
class Highlighter ( QSyntaxHighlighter ):
-
- Normal = 0x0001
- Bold = 0x0002
- Italic = 0x0004
-
- ttyBackground = QColor.fromRgb( 255, 255, 221 ) # #ffffdd
- ttyBlack = QColor.fromRgb( 46, 52, 54 ) # #2e3436
- ttyRed = QColor.fromRgb( 204, 0, 0 ) # #cc0000
- ttyGreen = QColor.fromRgb( 78, 154, 6 ) # #4e9a06
- ttyYellow = QColor.fromRgb( 196, 160, 0 ) # #c4a000
- ttyBlue = QColor.fromRgb( 52, 101, 164 ) # #3465a4
- ttyViolet = QColor.fromRgb( 117, 80, 123 ) # #75507b
- ttyCyan = QColor.fromRgb( 6, 152, 154 ) # #06989a
- ttyGrey = QColor.fromRgb( 211, 215, 207 ) # #d3d7cf
- ttyLightBlack = QColor.fromRgb( 85, 87, 83 ) # #555753
- ttyLightRed = QColor.fromRgb( 239, 41, 41 ) # #ef2929
- ttyLightGreen = QColor.fromRgb( 138, 226, 52 ) # #8ae234
- ttyLightYellow = QColor.fromRgb( 252, 233, 79 ) # #fce94f
- ttyLightBlue = QColor.fromRgb( 114, 159, 207 ) # #729fcf
- ttyLightViolet = QColor.fromRgb( 173, 127, 168 ) # #ad7fa8
- ttyLightCyan = QColor.fromRgb( 52, 226, 226 ) # #34e2e2
- ttyLightGrey = QColor.fromRgb( 238, 238, 236 ) # #eeeeec
-
- Rules = [ [ttyLightViolet, Bold , re.compile(r'^Scanning.*'), None]
- , [ttyLightRed , Bold , re.compile(r'^Linking.*'), None]
- , [ttyLightGreen , Normal , re.compile(r'^\[(?P\s*\d+)%\]\s*(?PBuilding.*)'), None]
- , [ttyLightGreen , Bold , re.compile(r'^\[(?P\s*\d+)%\]\s*(?PBuilt target.*)'), None]
- , [ttyLightBlue , Normal , re.compile(r'^\[(?P\s*\d+)%\]\s*(?PGenerating.*moc_.*)'), None]
- , [ttyLightBlue , Bold , re.compile(r'^Generating.*'), None]
- , [ttyLightCyan , Normal , re.compile(r'^Install the project.*'), None]
- , [ttyCyan , Bold , re.compile(r'^-- Install.*'), None]
- , [ttyCyan , Bold|Italic, re.compile(r'^-- Up-to-date.*'), None]
- ]
-
- def __init__ ( self, parent=None ):
- QSyntaxHighlighter.__init__ ( self, parent )
- for rule in Highlighter.Rules:
- if not rule[3]:
- rule[3] = QTextCharFormat()
- rule[3].setForeground( rule[0] )
- if rule[1] & Highlighter.Normal: rule[3].setFontWeight( QFont.Normal )
- if rule[1] & Highlighter.Bold: rule[3].setFontWeight( QFont.Bold )
- if rule[1] & Highlighter.Italic: rule[3].setFontItalic( True )
- return
-
- def highlightBlock ( self, line ):
- for rule in Highlighter.Rules:
- m = rule[2].match(line)
- if m:
- if m.groupdict().has_key('percent'):
- self.setFormat( 7, len(line), rule[3] )
- else:
- self.setFormat( 0, len(line), rule[3] )
- return
+
+ Normal = 0x0001
+ Bold = 0x0002
+ Italic = 0x0004
+
+ ttyBackground = QColor.fromRgb( 255, 255, 221 ) # #ffffdd
+ ttyBlack = QColor.fromRgb( 46, 52, 54 ) # #2e3436
+ ttyRed = QColor.fromRgb( 204, 0, 0 ) # #cc0000
+ ttyGreen = QColor.fromRgb( 78, 154, 6 ) # #4e9a06
+ ttyYellow = QColor.fromRgb( 196, 160, 0 ) # #c4a000
+ ttyBlue = QColor.fromRgb( 52, 101, 164 ) # #3465a4
+ ttyViolet = QColor.fromRgb( 117, 80, 123 ) # #75507b
+ ttyCyan = QColor.fromRgb( 6, 152, 154 ) # #06989a
+ ttyGrey = QColor.fromRgb( 211, 215, 207 ) # #d3d7cf
+ ttyLightBlack = QColor.fromRgb( 85, 87, 83 ) # #555753
+ ttyLightRed = QColor.fromRgb( 239, 41, 41 ) # #ef2929
+ ttyLightGreen = QColor.fromRgb( 138, 226, 52 ) # #8ae234
+ ttyLightYellow = QColor.fromRgb( 252, 233, 79 ) # #fce94f
+ ttyLightBlue = QColor.fromRgb( 114, 159, 207 ) # #729fcf
+ ttyLightViolet = QColor.fromRgb( 173, 127, 168 ) # #ad7fa8
+ ttyLightCyan = QColor.fromRgb( 52, 226, 226 ) # #34e2e2
+ ttyLightGrey = QColor.fromRgb( 238, 238, 236 ) # #eeeeec
+
+ Rules = [ [ttyLightViolet, Bold , re.compile(r'^Scanning.*'), None]
+ , [ttyLightRed , Bold , re.compile(r'^Linking.*'), None]
+ , [ttyLightGreen , Normal , re.compile(r'^\[(?P\s*\d+)%\]\s*(?PBuilding.*)'), None]
+ , [ttyLightGreen , Bold , re.compile(r'^\[(?P\s*\d+)%\]\s*(?PBuilt target.*)'), None]
+ , [ttyLightBlue , Normal , re.compile(r'^\[(?P\s*\d+)%\]\s*(?PGenerating.*moc_.*)'), None]
+ , [ttyLightBlue , Bold , re.compile(r'^Generating.*'), None]
+ , [ttyLightCyan , Normal , re.compile(r'^Install the project.*'), None]
+ , [ttyCyan , Bold , re.compile(r'^-- Install.*'), None]
+ , [ttyCyan , Bold|Italic, re.compile(r'^-- Up-to-date.*'), None]
+ ]
+
+ def __init__ ( self, parent=None ):
+ QSyntaxHighlighter.__init__ ( self, parent )
+ for rule in Highlighter.Rules:
+ if not rule[3]:
+ rule[3] = QTextCharFormat()
+ rule[3].setForeground( rule[0] )
+ if rule[1] & Highlighter.Normal: rule[3].setFontWeight( QFont.Normal )
+ if rule[1] & Highlighter.Bold: rule[3].setFontWeight( QFont.Bold )
+ if rule[1] & Highlighter.Italic: rule[3].setFontItalic( True )
+ return
+
+ def highlightBlock ( self, line ):
+ for rule in Highlighter.Rules:
+ m = rule[2].match(line)
+ if m:
+ if 'percent' in m.groupdict():
+ self.setFormat( 7, len(line), rule[3] )
+ else:
+ self.setFormat( 0, len(line), rule[3] )
+ return
diff --git a/bootstrap/builder/OptionsWidget.py b/bootstrap/builder/OptionsWidget.py
index 7ce71d83..6f91e28c 100644
--- a/bootstrap/builder/OptionsWidget.py
+++ b/bootstrap/builder/OptionsWidget.py
@@ -2,14 +2,14 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Damien Dupuis |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./builder/OptionsWidget.py" |
# +-----------------------------------------------------------------+
@@ -17,176 +17,163 @@
import re
import subprocess
-from PyQt4.QtCore import Qt
-from PyQt4.QtCore import pyqtSignal
-from PyQt4.QtCore import QSettings
-from PyQt4.QtGui import QColor
-from PyQt4.QtGui import QWidget
-from PyQt4.QtGui import QPushButton
-from PyQt4.QtGui import QCheckBox
-from PyQt4.QtGui import QGroupBox
-from PyQt4.QtGui import QButtonGroup
-from PyQt4.QtGui import QVBoxLayout
-from PyQt4.QtGui import QHBoxLayout
-from PyQt4.QtGui import QGridLayout
-from PyQt4.QtGui import QScrollArea
-from PyQt4.QtGui import QComboBox
-from builder.Project import Project
-from builder.ConfigureWidget import ConfigureWidget
-from builder.ProjectWidgets import ProjectWidgets
+from PyQt4.QtCore import Qt, pyqtSignal, QSettings
+from PyQt4.QtGui import QColor, QWidget, QPushButton, \
+ QCheckBox, QGroupBox, QButtonGroup, \
+ QVBoxLayout, QHBoxLayout, QGridLayout, \
+ QScrollArea, QComboBox
+from .Project import Project
+from .ConfigureWidget import ConfigureWidget
+from .ProjectWidgets import ProjectWidgets
class OptionsWidget ( QWidget ):
-
- progress = pyqtSignal(int)
-
- def __init__ ( self, conf, parent=None ):
- QWidget.__init__ ( self, parent )
- self._conf = conf
- self._projects = []
- for project in self._conf.projects:
- self._projects += [ ProjectWidgets(project) ]
+
+ progress = pyqtSignal(int)
+
+ def __init__ ( self, conf, parent=None ):
+ QWidget.__init__ ( self, parent )
+ self._conf = conf
+ self._projects = []
+ for project in self._conf.projects:
+ self._projects += [ ProjectWidgets(project) ]
+
+ gLayout = QGridLayout()
+ column = 0
+ for iproject in range(len(self._projects)):
+ column += self._projects[iproject].addToLayout( column, gLayout )
+ toolsGroup = QGroupBox( 'Projects && Tools' )
+ toolsGroup.setLayout( gLayout )
- gLayout = QGridLayout()
- column = 0
- for iproject in range(len(self._projects)):
- column += self._projects[iproject].addToLayout( column, gLayout )
- toolsGroup = QGroupBox( 'Projects && Tools' )
- toolsGroup.setLayout( gLayout )
-
- scrollToolsGroup = QScrollArea()
- scrollToolsGroup.setMinimumHeight( 350 )
- #scrollToolsGroup.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOn )
- scrollToolsGroup.setWidget( toolsGroup )
-
- self._buildMode = QComboBox()
- self._buildMode.addItems( ('Release', 'Debug') )
- #self._svnUpdate = QCheckBox( 'SVN Update' )
- #self._svnStatus = QCheckBox( 'SVN Status' )
- self._make = QCheckBox( 'Build' )
- self._enableDoc = QCheckBox( 'Build Documentation' )
- self._devtoolset = QCheckBox( 'Build with devtoolset 8' )
- self._qt5 = QCheckBox( 'Build with Qt 5 (Qt 4 default)' )
- self._noCache = QCheckBox( 'Remove previous CMake cache' )
- self._rmBuild = QCheckBox( 'Cleanup Build Directory' )
- self._verbose = QCheckBox( 'Display Compiler Commands' )
- self._threads = QComboBox()
- for j in range(16):
- self._threads.addItem( '-j%d'%(j+1), j+1 )
-
- self._commandGroup = QButtonGroup()
- self._commandGroup.setExclusive( True )
- #self._commandGroup.addButton( self._svnUpdate )
- #self._commandGroup.addButton( self._svnStatus )
- self._commandGroup.addButton( self._make )
-
- vLayout = QVBoxLayout()
- #vLayout.addWidget( self._svnUpdate )
- #vLayout.addWidget( self._svnStatus )
- vLayout.addWidget( self._make )
- vLayout.addStretch()
- commandGroup = QGroupBox( 'Command' )
- commandGroup.setLayout( vLayout )
-
- vLayout = QVBoxLayout()
- vLayout.addWidget( self._buildMode )
- vLayout.addWidget( self._enableDoc )
- vLayout.addWidget( self._devtoolset )
- vLayout.addWidget( self._qt5 )
- vLayout.addWidget( self._noCache )
- vLayout.addWidget( self._rmBuild )
- vLayout.addStretch()
- optionsGroup = QGroupBox( 'Command Options' )
- optionsGroup.setLayout( vLayout )
-
- vLayout = QVBoxLayout()
- vLayout.addWidget( self._threads )
- vLayout.addWidget( self._verbose )
- vLayout.addStretch()
- miscGroup = QGroupBox( 'Misc. Options' )
- miscGroup.setLayout( vLayout )
-
- hLayout = QHBoxLayout()
- hLayout.addWidget( commandGroup )
- hLayout.addWidget( optionsGroup )
- hLayout.addWidget( miscGroup )
- commands = QWidget()
- commands.setLayout( hLayout )
-
- vLayout = QVBoxLayout()
- vLayout.addWidget( commands )
- vLayout.addWidget( scrollToolsGroup )
- vLayout.addStretch()
- self.setLayout( vLayout )
-
- self.readSettings()
- return
-
-
- def _getProjects ( self ): return self._projects
- def _getBuildMode ( self ): return self._buildMode.currentText()
- def _getThreads ( self ): return self._threads.currentText()
- #def _getSvnUpdate ( self ): return self._svnUpdate.isChecked()
- #def _getSvnStatus ( self ): return self._svnStatus.isChecked()
- def _getMake ( self ): return self._make.isChecked()
- def _getEnableDoc ( self ): return self._enableDoc.isChecked()
- def _getDevtoolset ( self ): return self._devtoolset.isChecked()
- def _getQt5 ( self ): return self._qt5.isChecked()
- def _getNoCache ( self ): return self._noCache.isChecked()
- def _getRmBuild ( self ): return self._rmBuild.isChecked()
- def _getVerbose ( self ): return self._verbose.isChecked()
-
- projects = property( _getProjects )
- buildMode = property( _getBuildMode )
- threads = property( _getThreads )
- #svnUpdate = property( _getSvnUpdate )
- #svnStatus = property( _getSvnStatus )
- make = property( _getMake )
- enableDoc = property( _getEnableDoc )
- devtoolset = property( _getDevtoolset )
- qt5 = property( _getQt5 )
- noCache = property( _getNoCache )
- rmBuild = property( _getRmBuild )
- verbose = property( _getVerbose )
-
-
- def readSettings ( self ):
- settings = QSettings()
- #self._svnUpdate .setChecked( settings.value('builder/svnUpdate').toBool() )
- #self._svnStatus .setChecked( settings.value('builder/svnStatus').toBool() )
- self._make .setChecked( settings.value('builder/make' ).toBool() )
- self._enableDoc .setChecked( settings.value('builder/enableDoc').toBool() )
- self._devtoolset .setChecked( settings.value('builder/devtoolset').toBool() )
- self._qt5 .setChecked( settings.value('builder/qt5').toBool() )
- self._noCache .setChecked( settings.value('builder/noCache' ).toBool() )
- self._rmBuild .setChecked( settings.value('builder/rmBuild' ).toBool() )
- self._verbose .setChecked( settings.value('builder/verbose' ).toBool() )
-
- buildModeName = settings.value('builder/buildMode').toString()
- index = self._buildMode.findText( buildModeName )
- if index >= 0: self._buildMode.setCurrentIndex( index )
-
- threads = settings.value('builder/threads').toString()
- index = self._threads.findText( threads )
- if index >= 0: self._threads.setCurrentIndex( index )
-
- for project in self._projects: project.readFromSettings()
- return
-
-
- def saveSettings ( self ):
- settings = QSettings()
- #settings.setValue('builder/svnUpdate' , self._svnUpdate .isChecked() )
- #settings.setValue('builder/svnStatus' , self._svnStatus .isChecked() )
- settings.setValue('builder/make' , self._make .isChecked() )
- settings.setValue('builder/enableDoc' , self._enableDoc .isChecked() )
- settings.setValue('builder/devtoolset', self._devtoolset.isChecked() )
- settings.setValue('builder/qt5' , self._qt5 .isChecked() )
- settings.setValue('builder/buildMode' , self._buildMode .currentText() )
- settings.setValue('builder/noCache' , self._noCache .isChecked() )
- settings.setValue('builder/rmBuild' , self._rmBuild .isChecked() )
- settings.setValue('builder/verbose' , self._verbose .isChecked() )
- settings.setValue('builder/threads' , self._threads .currentText() )
-
- for project in self._projects: project.saveToSettings()
- return
+ scrollToolsGroup = QScrollArea()
+ scrollToolsGroup.setMinimumHeight( 350 )
+ #scrollToolsGroup.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOn )
+ scrollToolsGroup.setWidget( toolsGroup )
+
+ self._buildMode = QComboBox()
+ self._buildMode.addItems( ('Release', 'Debug') )
+ #self._svnUpdate = QCheckBox( 'SVN Update' )
+ #self._svnStatus = QCheckBox( 'SVN Status' )
+ self._make = QCheckBox( 'Build' )
+ self._enableDoc = QCheckBox( 'Build Documentation' )
+ self._devtoolset = QCheckBox( 'Build with devtoolset 8' )
+ self._qt5 = QCheckBox( 'Build with Qt 5 (Qt 4 default)' )
+ self._noCache = QCheckBox( 'Remove previous CMake cache' )
+ self._rmBuild = QCheckBox( 'Cleanup Build Directory' )
+ self._verbose = QCheckBox( 'Display Compiler Commands' )
+ self._threads = QComboBox()
+ for j in range(16):
+ self._threads.addItem( '-j%d'%(j+1), j+1 )
+
+ self._commandGroup = QButtonGroup()
+ self._commandGroup.setExclusive( True )
+ #self._commandGroup.addButton( self._svnUpdate )
+ #self._commandGroup.addButton( self._svnStatus )
+ self._commandGroup.addButton( self._make )
+
+ vLayout = QVBoxLayout()
+ #vLayout.addWidget( self._svnUpdate )
+ #vLayout.addWidget( self._svnStatus )
+ vLayout.addWidget( self._make )
+ vLayout.addStretch()
+ commandGroup = QGroupBox( 'Command' )
+ commandGroup.setLayout( vLayout )
+
+ vLayout = QVBoxLayout()
+ vLayout.addWidget( self._buildMode )
+ vLayout.addWidget( self._enableDoc )
+ vLayout.addWidget( self._devtoolset )
+ vLayout.addWidget( self._qt5 )
+ vLayout.addWidget( self._noCache )
+ vLayout.addWidget( self._rmBuild )
+ vLayout.addStretch()
+ optionsGroup = QGroupBox( 'Command Options' )
+ optionsGroup.setLayout( vLayout )
+
+ vLayout = QVBoxLayout()
+ vLayout.addWidget( self._threads )
+ vLayout.addWidget( self._verbose )
+ vLayout.addStretch()
+ miscGroup = QGroupBox( 'Misc. Options' )
+ miscGroup.setLayout( vLayout )
+
+ hLayout = QHBoxLayout()
+ hLayout.addWidget( commandGroup )
+ hLayout.addWidget( optionsGroup )
+ hLayout.addWidget( miscGroup )
+ commands = QWidget()
+ commands.setLayout( hLayout )
+
+ vLayout = QVBoxLayout()
+ vLayout.addWidget( commands )
+ vLayout.addWidget( scrollToolsGroup )
+ vLayout.addStretch()
+ self.setLayout( vLayout )
+
+ self.readSettings()
+ return
+
+ def _getProjects ( self ): return self._projects
+ def _getBuildMode ( self ): return self._buildMode.currentText()
+ def _getThreads ( self ): return self._threads.currentText()
+ #def _getSvnUpdate ( self ): return self._svnUpdate.isChecked()
+ #def _getSvnStatus ( self ): return self._svnStatus.isChecked()
+ def _getMake ( self ): return self._make.isChecked()
+ def _getEnableDoc ( self ): return self._enableDoc.isChecked()
+ def _getDevtoolset ( self ): return self._devtoolset.isChecked()
+ def _getQt5 ( self ): return self._qt5.isChecked()
+ def _getNoCache ( self ): return self._noCache.isChecked()
+ def _getRmBuild ( self ): return self._rmBuild.isChecked()
+ def _getVerbose ( self ): return self._verbose.isChecked()
+
+ projects = property( _getProjects )
+ buildMode = property( _getBuildMode )
+ threads = property( _getThreads )
+ #svnUpdate = property( _getSvnUpdate )
+ #svnStatus = property( _getSvnStatus )
+ make = property( _getMake )
+ enableDoc = property( _getEnableDoc )
+ devtoolset = property( _getDevtoolset )
+ qt5 = property( _getQt5 )
+ noCache = property( _getNoCache )
+ rmBuild = property( _getRmBuild )
+ verbose = property( _getVerbose )
+
+ def readSettings ( self ):
+ settings = QSettings()
+ #self._svnUpdate .setChecked( bool(settings.value('builder/svnUpdate' )) )
+ #self._svnStatus .setChecked( bool(settings.value('builder/svnStatus' )) )
+ self._make .setChecked( bool(settings.value('builder/make' )) )
+ self._enableDoc .setChecked( bool(settings.value('builder/enableDoc' )) )
+ self._devtoolset .setChecked( bool(settings.value('builder/devtoolset')) )
+ self._qt5 .setChecked( bool(settings.value('builder/qt5' )) )
+ self._noCache .setChecked( bool(settings.value('builder/noCache' )) )
+ self._rmBuild .setChecked( bool(settings.value('builder/rmBuild' )) )
+ self._verbose .setChecked( bool(settings.value('builder/verbose' )) )
+
+ buildModeName = settings.value('builder/buildMode')
+ index = self._buildMode.findText( buildModeName )
+ if index >= 0: self._buildMode.setCurrentIndex( index )
+
+ threads = settings.value('builder/threads')
+ index = self._threads.findText( threads )
+ if index >= 0: self._threads.setCurrentIndex( index )
+
+ for project in self._projects: project.readFromSettings()
+ return
+
+ def saveSettings ( self ):
+ settings = QSettings()
+ #settings.setValue('builder/svnUpdate' , self._svnUpdate .isChecked() )
+ #settings.setValue('builder/svnStatus' , self._svnStatus .isChecked() )
+ settings.setValue('builder/make' , self._make .isChecked() )
+ settings.setValue('builder/enableDoc' , self._enableDoc .isChecked() )
+ settings.setValue('builder/devtoolset', self._devtoolset.isChecked() )
+ settings.setValue('builder/qt5' , self._qt5 .isChecked() )
+ settings.setValue('builder/buildMode' , self._buildMode .currentText() )
+ settings.setValue('builder/noCache' , self._noCache .isChecked() )
+ settings.setValue('builder/rmBuild' , self._rmBuild .isChecked() )
+ settings.setValue('builder/verbose' , self._verbose .isChecked() )
+ settings.setValue('builder/threads' , self._threads .currentText() )
+ for project in self._projects: project.saveToSettings()
+ return
diff --git a/bootstrap/builder/Project.py b/bootstrap/builder/Project.py
index b41c522f..f5a8e6e4 100644
--- a/bootstrap/builder/Project.py
+++ b/bootstrap/builder/Project.py
@@ -2,14 +2,14 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./builder/Project.py" |
# +-----------------------------------------------------------------+
diff --git a/bootstrap/builder/ProjectWidgets.py b/bootstrap/builder/ProjectWidgets.py
index 32b7bf6e..e0bd3d3f 100644
--- a/bootstrap/builder/ProjectWidgets.py
+++ b/bootstrap/builder/ProjectWidgets.py
@@ -2,93 +2,83 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./builder/ProjectWidget.py" |
# +-----------------------------------------------------------------+
import string
-from PyQt4.QtCore import Qt
-from PyQt4.QtCore import QObject
-from PyQt4.QtCore import QSettings
-from PyQt4.QtGui import QSizePolicy
-from PyQt4.QtGui import QFrame
-from PyQt4.QtGui import QPushButton
-from PyQt4.QtGui import QCheckBox
-from PyQt4.QtGui import QLabel
+from PyQt4.QtCore import Qt, QObject, QSettings
+from PyQt4.QtGui import QSizePolicy, QFrame, QPushButton, QCheckBox, \
+ QLabel
class ProjectWidgets ( QObject ):
-
- def __init__ ( self, project ):
- self._project = project
- self._projectButton = QLabel( string.capwords(self._project.getName()) )
- self._projectButton.setStyleSheet( 'font-weight: bold;' )
- self._projectButton.setFrameShape( QFrame.Box )
- self._projectButton.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred )
-
- self._toolsCheckBoxes = []
- for tool in self._project.getTools():
- self._toolsCheckBoxes += [ QCheckBox( tool.name ) ]
-
- #self._projectButton.clicked.connect( self.toggleToolsVisibility )
- return
-
- def _getProjectButton ( self ): return self._projectButton
- def _getToolsCheckBoxes ( self ): return self._toolsCheckBoxes
-
- def _getActives ( self ):
- actives = []
- for toolCb in self._toolsCheckBoxes:
- if toolCb.isChecked(): actives += [ str(toolCb.text()) ]
- return actives
-
- projectButton = property( _getProjectButton )
- toolsCheckBoxes = property( _getToolsCheckBoxes )
- actives = property( _getActives )
-
- def addToLayout( self, column, layout ):
- toolsNb = len(self._toolsCheckBoxes)
- if toolsNb <= 10:
- layout.addWidget( self._projectButton, 0, column, Qt.AlignLeft )
- for row in range(toolsNb):
- layout.addWidget( self._toolsCheckBoxes[row], row+1, column, Qt.AlignTop )
- return 1
-
- columnSpan = toolsNb / 10
- if toolsNb % 10: columnSpan += 1
-
- layout.addWidget( self._projectButton, 0, column, 1, columnSpan, Qt.AlignJustify )
- for row in range(toolsNb):
- if row and row % 10 == 0: column += 1
- layout.addWidget( self._toolsCheckBoxes[row], row%10+1, column, Qt.AlignTop )
-
- return columnSpan
-
- #def toggleToolsVisibility ( self ):
- # self._visibleTools = not self._visibleTools
- # for toolCb in self._toolsCheckBoxes:
- # toolCb.setVisible( self._visibleTools )
- # return
-
- def readFromSettings ( self ):
- settings = QSettings()
- for toolCb in self._toolsCheckBoxes:
- toolId = 'tools/'+self._project.getName()+'/'+toolCb.text()
- toolCb.setChecked( settings.value(toolId).toBool() )
- return
-
- def saveToSettings ( self ):
- settings = QSettings()
- for toolCb in self._toolsCheckBoxes:
- toolId = 'tools/'+self._project.getName()+'/'+toolCb.text()
- settings.setValue( toolId, toolCb.isChecked() )
- return
+
+ def __init__ ( self, project ):
+ self._project = project
+ self._projectButton = QLabel( string.capwords(self._project.getName()) )
+ self._projectButton.setStyleSheet( 'font-weight: bold;' )
+ self._projectButton.setFrameShape( QFrame.Box )
+ self._projectButton.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred )
+ self._toolsCheckBoxes = []
+ for tool in self._project.getTools():
+ self._toolsCheckBoxes += [ QCheckBox( tool.name ) ]
+ #self._projectButton.clicked.connect( self.toggleToolsVisibility )
+ return
+
+ def _getProjectButton ( self ): return self._projectButton
+ def _getToolsCheckBoxes ( self ): return self._toolsCheckBoxes
+
+ def _getActives ( self ):
+ actives = []
+ for toolCb in self._toolsCheckBoxes:
+ if toolCb.isChecked(): actives += [ str(toolCb.text()) ]
+ return actives
+
+ projectButton = property( _getProjectButton )
+ toolsCheckBoxes = property( _getToolsCheckBoxes )
+ actives = property( _getActives )
+
+ def addToLayout( self, column, layout ):
+ toolsNb = len(self._toolsCheckBoxes)
+ if toolsNb <= 10:
+ layout.addWidget( self._projectButton, 0, column, Qt.AlignLeft )
+ for row in range(toolsNb):
+ layout.addWidget( self._toolsCheckBoxes[row], row+1, column, Qt.AlignTop )
+ return 1
+ columnSpan = toolsNb / 10
+ if toolsNb % 10: columnSpan += 1
+ layout.addWidget( self._projectButton, 0, column, 1, columnSpan, Qt.AlignJustify )
+ for row in range(toolsNb):
+ if row and row % 10 == 0: column += 1
+ layout.addWidget( self._toolsCheckBoxes[row], row%10+1, column, Qt.AlignTop )
+ return columnSpan
+
+ #def toggleToolsVisibility ( self ):
+ # self._visibleTools = not self._visibleTools
+ # for toolCb in self._toolsCheckBoxes:
+ # toolCb.setVisible( self._visibleTools )
+ # return
+
+ def readFromSettings ( self ):
+ settings = QSettings()
+ for toolCb in self._toolsCheckBoxes:
+ toolId = 'tools/'+self._project.getName()+'/'+toolCb.text()
+ toolCb.setChecked( bool(settings.value(toolId)) )
+ return
+
+ def saveToSettings ( self ):
+ settings = QSettings()
+ for toolCb in self._toolsCheckBoxes:
+ toolId = 'tools/'+self._project.getName()+'/'+toolCb.text()
+ settings.setValue( toolId, toolCb.isChecked() )
+ return
diff --git a/bootstrap/builder/__init__.py b/bootstrap/builder/__init__.py
index 947787ce..0ae343f5 100644
--- a/bootstrap/builder/__init__.py
+++ b/bootstrap/builder/__init__.py
@@ -2,14 +2,14 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Author : Damien Dupuis |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./builder/__init__.py" |
# +-----------------------------------------------------------------+
@@ -21,8 +21,7 @@ class ErrorMessage ( Exception ):
def __init__ ( self, code, *arguments ):
self._code = code
- self._errors = [ 'Malformed call to ErrorMessage()'
- , '%s' % str(arguments) ]
+ self._errors = [ 'Malformed call to ErrorMessage()', '{}'.format(arguments) ]
text = None
if len(arguments) == 1:
@@ -31,7 +30,6 @@ class ErrorMessage ( Exception ):
self._errors = arguments[0]
elif len(arguments) > 1:
text = list(arguments)
-
if text:
self._errors = []
while len(text[0]) == 0: del text[0]
@@ -50,11 +48,10 @@ class ErrorMessage ( Exception ):
def __str__ ( self ):
if not isinstance(self._errors,list):
return "[ERROR] %s" % self._errors
-
formatted = "\n"
for i in range(len(self._errors)):
- if i == 0: formatted += "[ERROR] %s" % self._errors[i]
- else: formatted += " %s" % self._errors[i]
+ if i == 0: formatted += "[ERROR] {}".format(self._errors[i] )
+ else: formatted += " {}".format(self._errors[i] )
if i+1 < len(self._errors): formatted += "\n"
return formatted
@@ -69,7 +66,7 @@ class ErrorMessage ( Exception ):
return
def terminate ( self ):
- print self
+ print( self )
sys.exit(self._code)
def _getCode ( self ): return self._code
diff --git a/bootstrap/ccb.py b/bootstrap/ccb.py
index fc130c09..d70dba08 100755
--- a/bootstrap/ccb.py
+++ b/bootstrap/ccb.py
@@ -1,17 +1,17 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2008-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2008-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
-# | C o r i o l i s / C h a m s B u i l d e r |
+# | T o o l c h a i n B u i l d e r |
# | |
# | Authors : Jean-Paul Chaput |
# | Damien Dupuis |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./ccb.py" |
# +-----------------------------------------------------------------+
@@ -19,37 +19,36 @@
showTrace = True
try:
- import sys
- import os.path
- import optparse
- import traceback
- import distutils.sysconfig
- import subprocess
- import re
-except ImportError, e:
- module = str(e).split()[-1]
-
- print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module
- print ' Please check your standard Python installation, it may have problems.'
- quit()
+ import sys
+ import os.path
+ import optparse
+ import traceback
+ import distutils.sysconfig
+ import subprocess
+ import re
+except ImportError as e:
+ module = str(e).split()[-1]
+ print( '[ERROR] The "{}" python module or symbol cannot be loaded.'.format(module) )
+ print( ' Please check your standard Python installation, it may have problems.' )
+ quit()
def safeImport ( moduleName, symbol=None ):
- try:
- module = __import__( moduleName, globals(), locals(), symbol )
- except ImportError, e:
- print '[ERROR] The <%s> python module or symbol cannot be loaded.' % moduleName
- print ' Please check the integrity of the package.'
- if showTrace: traceback.print_tb(sys.exc_info()[2])
- sys.exit(1)
- except Exception, e:
- print '[ERROR] An exception occured while importing module <%s>. Is is a bug,' % moduleName
- print ' you may want to report it...'
- print ' %s' % e
- if showTrace: traceback.print_tb(sys.exc_info()[2])
- sys.exit(2)
- if symbol: return module.__dict__[symbol]
- return module
+ try:
+ module = __import__( moduleName, globals(), locals(), symbol )
+ except ImportError as e:
+ print( '[ERROR] The "{}" python module or symbol cannot be loaded.'.format(moduleName) )
+ print( ' Please check the integrity of the "coriolis/boostrap" package.' )
+ if showTrace: traceback.print_tb(sys.exc_info()[2])
+ sys.exit(1)
+ except Exception as e:
+ print( '[ERROR] An exception occured while importing module "{}". Is is a bug,'.format(moduleName) )
+ print( ' you may want to report it...' )
+ print( ' {}'.format(e) )
+ if showTrace: traceback.print_tb(sys.exc_info()[2])
+ sys.exit(2)
+ if symbol: return module.__dict__[symbol]
+ return module
def checkCMake ():
@@ -57,8 +56,8 @@ def checkCMake ():
(pid,status) = os.waitpid ( child.pid, 0 )
status >>= 8
if status != 0:
- print '[ERROR] The program has not been found, please install it.'
- sys.exit(1)
+ print( '[ERROR] The "cmake" program has not been found, please install it.' )
+ sys.exit(1)
def guessOs ():
@@ -85,62 +84,60 @@ def guessOs ():
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
lines = uname.stdout.readlines()
-
- if osSlsoc7x_64.match(lines[0]):
+ line = lines[0].decode( 'ascii' )
+ if osSlsoc7x_64.match(line):
osType = "Linux.el7_64"
libDir = "lib64"
- elif osSlsoc6x_64.match(lines[0]):
+ elif osSlsoc6x_64.match(line):
osType = "Linux.slsoc6x_64"
libDir = "lib64"
- elif osSlsoc6x.match(lines[0]):
+ elif osSlsoc6x.match(line):
osType = "Linux.slsoc6x"
- elif osSLSoC5x_64.match(lines[0]):
+ elif osSLSoC5x_64.match(line):
osType = "Linux.SLSoC5x_64"
libDir = "lib64"
- elif osSLSoC5x .match(lines[0]):
+ elif osSLSoC5x .match(line):
osType = "Linux.SLSoC5x"
- elif osFedora_64.match(lines[0]):
+ elif osFedora_64.match(line):
osType = "Linux.fc_64"
libDir = "lib64"
- elif osFedora .match(lines[0]):
+ elif osFedora .match(line):
osType = "Linux.fc"
- elif osLinux_64.match(lines[0]):
+ elif osLinux_64.match(line):
osType = "Linux.x86_64"
libDir = "lib64"
- elif osLinux .match(lines[0]):
+ elif osLinux .match(line):
osType = "Linux.i386"
- elif osDarwin.match(lines[0]):
+ elif osDarwin.match(line):
osType = "Darwin"
- elif osFreeBSD8x_amd64.match(lines[0]):
+ elif osFreeBSD8x_amd64.match(line):
osType = "FreeBSD.8x.amd64"
libDir = "lib64"
- elif osFreeBSD8x_64.match(lines[0]):
+ elif osFreeBSD8x_64.match(line):
osType = "FreeBSD.8x.x86_64"
libDir = "lib64"
- elif osFreeBSD8x.match(lines[0]):
+ elif osFreeBSD8x.match(line):
osType = "FreeBSD.8x.i386"
- elif osCygwinW7_64.match(lines[0]):
+ elif osCygwinW7_64.match(line):
osType = "Cygwin.W7_64"
libDir = "lib64"
- elif osCygwinW7.match(lines[0]):
+ elif osCygwinW7.match(line):
osType = "Cygwin.W7"
- elif osCygwinW8_64.match(lines[0]):
+ elif osCygwinW8_64.match(line):
osType = "Cygwin.W8_64"
libDir = "lib64"
- elif osCygwinW8.match(lines[0]):
+ elif osCygwinW8.match(line):
osType = "Cygwin.W8"
- elif osCygwinW10_64.match(lines[0]):
+ elif osCygwinW10_64.match(line):
osType = "Cygwin.W10_64"
libDir = "lib64"
- elif osCygwinW10.match(lines[0]):
+ elif osCygwinW10.match(line):
osType = "Cygwin.W10"
else:
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
osType = uname.stdout.readlines()[0][:-1]
-
- print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
- print " (using: \"%s\")" % osType
-
+ print( '[WARNING] Unrecognized OS: "{}".'.format(lines[0][:-1]) )
+ print( ' (using: "{}")'.format(osType) )
return osType, libDir
@@ -151,10 +148,9 @@ def guessPythonSitePackage ():
def autoLocate ():
osType, libDir = guessOs()
- print 'Building for target: <%s>' % osType
- print 'Making an educated guess to locate myself:'
- sitePackage = guessPythonSitePackage()
-
+ print( 'Building for target: "{}"'.format(osType) )
+ print( 'Making an educated guess to locate myself:' )
+ sitePackage = guessPythonSitePackage()
builderDir = None
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
, os.environ['HOME']+'/coriolis-2.x/src/coriolis/bootstrap'
@@ -163,26 +159,22 @@ def autoLocate ():
, os.environ['HOME']+'/coriolis-2.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
, '/users/outil/coriolis/coriolis-2.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
]
-
for location in locations:
- print ' <%s>' % location,
+ print( ' "{}" '.format(location), end='' )
if os.path.isfile(location + '/builder/__init__.py'):
if not builderDir:
builderDir = location
- print '(Found*)'
+ print( '(Found*)' )
else:
- print '(Found)'
+ print( '(Found)' )
else:
- print '(No)'
-
+ print( '(No)' )
if not builderDir:
- print '[ERROR] Failed to locate the builder modules in any of the normal pathes.'
- print ' Please check your Coriolis/Bootsrap installation.'
+ print( '[ERROR] Failed to locate the builder modules in any of the normal pathes.' )
+ print( ' Please check your Coriolis/Bootsrap installation.' )
if showTrace: traceback.print_tb(sys.exc_info()[2])
sys.exit(1)
-
sys.path.insert( 0, builderDir )
-
return
@@ -193,125 +185,117 @@ autoLocate()
checkCMake()
parser = optparse.OptionParser ()
-parser.add_option ( "-g", "--gui" , action="store_true" , dest="gui" , help="Lauch the graphical interface." )
-# Build relateds.
-parser.add_option ( "-c", "--conf" , type="string", dest="conf" , help="Fichier de configuration." )
-parser.add_option ( "--show-conf" , action="store_true" , dest="showConf" , help="Display the Project/Tools configuration, then exit." )
-parser.add_option ( "-q", "--quiet" , action="store_true" , dest="quiet" , help="Do not print all the informative messages." )
-parser.add_option ( "-r", "--release" , action="store_true" , dest="release" , help="Build a aka optimized version." )
-parser.add_option ( "-d", "--debug" , action="store_true" , dest="debug" , help="Build a aka (-g) version." )
-parser.add_option ( "-s", "--static" , action="store_true" , dest="static" , help="Try to link statically, as much as possible." )
-parser.add_option ( "--doc" , action="store_true" , dest="doc" , help="Enable the documentation building (uses with -j1)." )
-parser.add_option ( "-v", "--verbose" , action="store_true" , dest="verboseMakefile" , help="Tells CMake to print all compilation commands." )
-parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
-parser.add_option ( "--no-build" , action="store_true" , dest="noBuild" , help="Do *not* build anything (by default: build)." )
-parser.add_option ( "--no-cache" , action="store_true" , dest="noCache" , help="Remove previous CMake cache before building." )
-parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove previous build directoty before building." )
-parser.add_option ( "--macports" , action="store_true" , dest="macports" , help="Build against MacPorts." )
-parser.add_option ( "--devtoolset" , action="store" , type="int" , dest="devtoolset" , help="Build against TUV Dev Toolset N." )
-parser.add_option ( "--llvm-toolset" , action="store" , type="int" , dest="llvmtoolset" , help="Build against TUV Dev LLVM Toolset N." )
-parser.add_option ( "--qt5" , action="store_true" , dest="qt5" , help="Build against Qt 5 (default: Qt 4)." )
-parser.add_option ( "--bfd" , action="store_true" , dest="bfd" , help="Build against Qt 5 (default: Qt 4)." )
-parser.add_option ( "--openmp" , action="store_true" , dest="openmp" , help="Enable the use of OpenMP in Gcc." )
-parser.add_option ( "--ninja" , action="store_true" , dest="ninja" , help="Use Ninja instead of UNIX Makefile." )
-parser.add_option ( "--clang" , action="store_true" , dest="clang" , help="Force use of Clang C/C++ compiler instead of system default." )
-parser.add_option ( "--make" , action="store" , type="string", dest="makeArguments", help="Arguments to pass to make (ex: \"-j4 install\")." )
-parser.add_option ( "--project" , action="append" , type="string", dest="projects" , help="The name of a project to build (may appears any number of time)." )
-parser.add_option ( "-t", "--tool" , action="append" , type="string", dest="tools" , help="The name of a tool to build (may appears any number of time)." )
+parser.add_option ( "-g", "--gui" , action="store_true" , dest="gui" , help="Lauch the graphical interface." )
+# Build relateds.
+parser.add_option ( "-c", "--conf" , type="string", dest="conf" , help="Fichier de configuration." )
+parser.add_option ( "--show-conf" , action="store_true" , dest="showConf" , help="Display the Project/Tools configuration, then exit." )
+parser.add_option ( "-q", "--quiet" , action="store_true" , dest="quiet" , help="Do not print all the informative messages." )
+parser.add_option ( "-r", "--release" , action="store_true" , dest="release" , help="Build a aka optimized version." )
+parser.add_option ( "-d", "--debug" , action="store_true" , dest="debug" , help="Build a aka (-g) version." )
+parser.add_option ( "-s", "--static" , action="store_true" , dest="static" , help="Try to link statically, as much as possible." )
+parser.add_option ( "--doc" , action="store_true" , dest="doc" , help="Enable the documentation building (uses with -j1)." )
+parser.add_option ( "-v", "--verbose" , action="store_true" , dest="verboseMakefile", help="Tells CMake to print all compilation commands." )
+parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
+parser.add_option ( "--no-build" , action="store_true" , dest="noBuild" , help="Do *not* build anything (by default: build)." )
+parser.add_option ( "--no-cache" , action="store_true" , dest="noCache" , help="Remove previous CMake cache before building." )
+parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove previous build directoty before building." )
+parser.add_option ( "--macports" , action="store_true" , dest="macports" , help="Build against MacPorts." )
+parser.add_option ( "--devtoolset" , action="store" , type="int" , dest="devtoolset" , help="Build against TUV Dev Toolset N." )
+parser.add_option ( "--llvm-toolset" , action="store" , type="int" , dest="llvmtoolset" , help="Build against TUV Dev LLVM Toolset N." )
+parser.add_option ( "--qt5" , action="store_true" , dest="qt5" , help="Build against Qt 5 (default: Qt 4)." )
+parser.add_option ( "--bfd" , action="store_true" , dest="bfd" , help="Build against Qt 5 (default: Qt 4)." )
+parser.add_option ( "--openmp" , action="store_true" , dest="openmp" , help="Enable the use of OpenMP in Gcc." )
+parser.add_option ( "--ninja" , action="store_true" , dest="ninja" , help="Use Ninja instead of UNIX Makefile." )
+parser.add_option ( "--clang" , action="store_true" , dest="clang" , help="Force use of Clang C/C++ compiler instead of system default." )
+parser.add_option ( "--make" , action="store" , type="string", dest="makeArguments" , help="Arguments to pass to make (ex: \"-j4 install\")." )
+parser.add_option ( "--project" , action="append" , type="string", dest="projects" , help="The name of a project to build (may appears any number of time)." )
+parser.add_option ( "-t", "--tool" , action="append" , type="string", dest="tools" , help="The name of a tool to build (may appears any number of time)." )
# SVN repository relateds.
# Have to be ported to Git.
-#parser.add_option ( "--svn-tag" , action="store" , type="string", dest="svnTag" , help="Explicitly select a SVN tag (for SVN related commands)." )
-#parser.add_option ( "--svn-method" , action="store" , type="string", dest="svnMethod" , help="Allows to sets the svn checkout method (svn+ssh://coriolis.soc.lip6.fr)." )
-#parser.add_option ( "--svn-status" , action="store_true" , dest="svnStatus" , help="Check status against the SVN repository." )
-#parser.add_option ( "--svn-diff" , action="store_true" , dest="svnDiff" , help="Perform a diff against the SVN repository." )
-#parser.add_option ( "--svn-update" , action="store_true" , dest="svnUpdate" , help="Update to the latest SVN version *or* the one given by svn-tag." )
-#parser.add_option ( "--svn-checkout" , action="store_true" , dest="svnCheckout" , help="Checkout the latest SVN version *or* the one given by svn-tag." )
+#parser.add_option ( "--svn-tag" , action="store" , type="string", dest="svnTag" , help="Explicitly select a SVN tag (for SVN related commands)." )
+#parser.add_option ( "--svn-method" , action="store" , type="string", dest="svnMethod" , help="Allows to sets the svn checkout method (svn+ssh://coriolis.soc.lip6.fr)." )
+#parser.add_option ( "--svn-status" , action="store_true" , dest="svnStatus" , help="Check status against the SVN repository." )
+#parser.add_option ( "--svn-diff" , action="store_true" , dest="svnDiff" , help="Perform a diff against the SVN repository." )
+#parser.add_option ( "--svn-update" , action="store_true" , dest="svnUpdate" , help="Update to the latest SVN version *or* the one given by svn-tag." )
+#parser.add_option ( "--svn-checkout" , action="store_true" , dest="svnCheckout" , help="Checkout the latest SVN version *or* the one given by svn-tag." )
# Miscellaneous.
-parser.add_option ( "--user-tarball" , action="store_true" , dest="userTarball" , help="Regenerate a tarball from checked out sources (in /tarball/." )
-parser.add_option ( "--tarball" , action="store_true" , dest="tarball" , help="Regenerate a tarball (in /tarball/." )
-parser.add_option ( "--rpm" , action="store_true" , dest="doRpm" , help="Regenerate RPM packages." )
-parser.add_option ( "--deb" , action="store_true" , dest="doDeb" , help="Regenerate Debian/Ubuntu packages." )
-# Katabatic/Kite specific options.
-parser.add_option ( "-D", "--check-db" , action="store_true" , dest="checkDb" , help="Enable Katabatic/Kite data-base checking (*very* slow)." )
-parser.add_option ( "-u", "--check-deter" , action="store_true" , dest="checkDeterminism", help="Enable Katabatic/Kite determinism checking (*very* slow)." )
+parser.add_option ( "--user-tarball" , action="store_true" , dest="userTarball" , help="Regenerate a tarball from checked out sources (in /tarball/." )
+parser.add_option ( "--tarball" , action="store_true" , dest="tarball" , help="Regenerate a tarball (in /tarball/." )
+parser.add_option ( "--rpm" , action="store_true" , dest="doRpm" , help="Regenerate RPM packages." )
+parser.add_option ( "--deb" , action="store_true" , dest="doDeb" , help="Regenerate Debian/Ubuntu packages." )
+# Katabatic/Kite specific options.
+parser.add_option ( "-D", "--check-db" , action="store_true" , dest="checkDb" , help="Enable Katabatic/Kite data-base checking (*very* slow)." )
+parser.add_option ( "-u", "--check-deter" , action="store_true" , dest="checkDeterminism", help="Enable Katabatic/Kite determinism checking (*very* slow)." )
(options, args) = parser.parse_args ()
if options.gui:
- ErrorMessage = safeImport( 'builder' , 'ErrorMessage' )
- QApplication = safeImport( 'PyQt4.QtGui' , 'QApplication' )
- BuilderGui = safeImport( 'builder.BuilderGui', 'BuilderGui' )
-
- try:
- app = QApplication( sys.argv )
- app.setOrganizationName ( 'UPMC' )
- app.setOrganizationDomain( 'lip6.fr' )
- app.setApplicationName ( 'CoriolisBuilder' )
- gui = BuilderGui( options.conf )
- gui.show()
- rcode = app.exec_()
- sys.exit( rcode )
- except ErrorMessage, e:
- print e
- if showTrace: traceback.print_tb(sys.exc_info()[2])
- sys.exit(2)
- except Exception, e:
- print '[ERROR] An exception occured while running the Qt application.'
- print ' %s' % e
- if showTrace: traceback.print_tb(sys.exc_info()[2])
- sys.exit(2)
-
+ ErrorMessage = safeImport( 'builder' , 'ErrorMessage' )
+ QApplication = safeImport( 'PyQt4.QtGui' , 'QApplication' )
+ BuilderGui = safeImport( 'builder.BuilderGui', 'BuilderGui' )
+ try:
+ app = QApplication( sys.argv )
+ app.setOrganizationName ( 'UPMC' )
+ app.setOrganizationDomain( 'lip6.fr' )
+ app.setApplicationName ( 'CoriolisBuilder' )
+ gui = BuilderGui( options.conf )
+ gui.show()
+ rcode = app.exec_()
+ sys.exit( rcode )
+ except ErrorMessage as e:
+ print( e )
+ if showTrace: traceback.print_tb(sys.exc_info()[2])
+ sys.exit(2)
+ except Exception as e:
+ print( '[ERROR] An exception occured while running the Qt application.' )
+ print( ' {}'.format(e) )
+ if showTrace: traceback.print_tb(sys.exc_info()[2])
+ sys.exit(2)
else:
-
- ErrorMessage = safeImport( 'builder' , 'ErrorMessage' )
- Builder = safeImport( 'builder.Builder', 'Builder' )
-
- try:
- builder = Builder()
- builder.loadConfiguration( options.conf )
-
- if options.showConf:
- builder.showConfiguration ()
- sys.exit(0)
-
- if options.quiet: builder.quiet = True
- if options.release: builder.buildMode = "Release"
- if options.debug: builder.buildMode = "Debug"
- if options.static: builder.enableShared = "OFF"
- if options.doc: builder.enableDoc = "ON"
- if options.checkDb: builder.checkDatabase = "ON"
- if options.checkDeterminism: builder.checkDeterminism = "ON"
- if options.verboseMakefile: builder.verboseMakefile = "ON"
- if options.rootDir: builder.rootDir = options.rootDir
- if options.noBuild: builder.doBuild = False
- if options.noCache: builder.noCache = True
- if options.rmBuild: builder.rmBuild = True
- if options.ninja: builder.ninja = True
- if options.clang or options.llvmtoolset: builder.clang = True
- if options.macports: builder.macports = True
- if options.devtoolset: builder.devtoolset = options.devtoolset
- if options.llvmtoolset: builder.llvmtoolset = options.llvmtoolset
- if options.bfd: builder.bfd = "ON"
- if options.qt5: builder.qt5 = True
- if options.openmp: builder.openmp = True
- if options.makeArguments: builder.makeArguments = options.makeArguments
- #if options.svnMethod: builder.svnMethod = options.svnMethod
- #if options.svnTag: builder.svnTag = options.svnTag
-
- #if options.svnStatus: builder.svnStatus ( tools=options.tools, projects=options.projects )
- #elif options.svnUpdate: builder.svnUpdate ( tools=options.tools, projects=options.projects )
- #elif options.svnDiff: builder.svnDiff ( tools=options.tools, projects=options.projects )
- #elif options.svnCheckout: builder.svnCheckout ( tools=options.tools, projects=options.projects )
- if options.userTarball: builder.userTarball ( tools=options.tools, projects=options.projects )
- elif options.tarball: builder.svnTarball ( tools=options.tools, projects=options.projects )
- elif options.doRpm: builder.doRpm ()
- elif options.doDeb: builder.doDeb ()
- else: builder.build ( tools=options.tools, projects=options.projects )
- except ErrorMessage, e:
- print e
- if showTrace: traceback.print_tb(sys.exc_info()[2])
- sys.exit(e.code)
- except KeyboardInterrupt, e:
- print '\n[ERROR] Interrupted by user\'s request (CTRL+C)'
- sys.exit(1)
-
+ ErrorMessage = safeImport( 'builder' , 'ErrorMessage' )
+ Builder = safeImport( 'builder.Builder', 'Builder' )
+ try:
+ builder = Builder()
+ builder.loadConfiguration( options.conf )
+ if options.showConf:
+ builder.showConfiguration ()
+ sys.exit(0)
+ if options.quiet: builder.quiet = True
+ if options.release: builder.buildMode = "Release"
+ if options.debug: builder.buildMode = "Debug"
+ if options.static: builder.enableShared = "OFF"
+ if options.doc: builder.enableDoc = "ON"
+ if options.checkDb: builder.checkDatabase = "ON"
+ if options.checkDeterminism: builder.checkDeterminism = "ON"
+ if options.verboseMakefile: builder.verboseMakefile = "ON"
+ if options.rootDir: builder.rootDir = options.rootDir
+ if options.noBuild: builder.doBuild = False
+ if options.noCache: builder.noCache = True
+ if options.rmBuild: builder.rmBuild = True
+ if options.ninja: builder.ninja = True
+ if options.clang or options.llvmtoolset: builder.clang = True
+ if options.macports: builder.macports = True
+ if options.devtoolset: builder.devtoolset = options.devtoolset
+ if options.llvmtoolset: builder.llvmtoolset = options.llvmtoolset
+ if options.bfd: builder.bfd = "ON"
+ if options.qt5: builder.qt5 = True
+ if options.openmp: builder.openmp = True
+ if options.makeArguments: builder.makeArguments = options.makeArguments
+ #if options.svnMethod: builder.svnMethod = options.svnMethod
+ #if options.svnTag: builder.svnTag = options.svnTag
+ #if options.svnStatus: builder.svnStatus ( tools=options.tools, projects=options.projects )
+ #elif options.svnUpdate: builder.svnUpdate ( tools=options.tools, projects=options.projects )
+ #elif options.svnDiff: builder.svnDiff ( tools=options.tools, projects=options.projects )
+ #elif options.svnCheckout: builder.svnCheckout ( tools=options.tools, projects=options.projects )
+ if options.userTarball: builder.userTarball ( tools=options.tools, projects=options.projects )
+ elif options.tarball: builder.svnTarball ( tools=options.tools, projects=options.projects )
+ elif options.doRpm: builder.doRpm ()
+ elif options.doDeb: builder.doDeb ()
+ else: builder.build ( tools=options.tools, projects=options.projects )
+ except ErrorMessage as e:
+ print( e )
+ if showTrace: traceback.print_tb(sys.exc_info()[2])
+ sys.exit(e.code)
+ except KeyboardInterrupt as e:
+ print( '\n[ERROR] Interrupted by user\'s request (CTRL+C)' )
+ sys.exit(1)
sys.exit(0)
diff --git a/bootstrap/cmake_modules/FindBootstrap.cmake b/bootstrap/cmake_modules/FindBootstrap.cmake
index bc67996f..8c372efc 100644
--- a/bootstrap/cmake_modules/FindBootstrap.cmake
+++ b/bootstrap/cmake_modules/FindBootstrap.cmake
@@ -94,12 +94,12 @@
set(ADDTIONAL_FLAGS "")
set(CXX_STANDARD "c++11")
endif()
- set(CMAKE_C_FLAGS_DEBUG " -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
-#set(CMAKE_C_FLAGS_DEBUG " -Wall ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
+#set(CMAKE_C_FLAGS_DEBUG " -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
+ set(CMAKE_C_FLAGS_DEBUG " -Wall ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
set(CMAKE_C_FLAGS_RELEASE " -Wall -O2 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE)
#set(CMAKE_C_FLAGS_RELEASE " -Wall -fsanitize=address ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE)
- set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
-#set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
+#set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
+ set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -O2 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE)
#set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE)
@@ -418,8 +418,30 @@
)
target_link_libraries( ${pytarget} ${pyDeplibs} )
- install( TARGETS ${pytarget} DESTINATION ${PYTHON_SITE_PACKAGES} )
+ install( TARGETS ${pytarget} DESTINATION ${Python_CORIOLISARCH} )
if( NOT ("${pyIncludes}" STREQUAL "None") )
install( FILES ${pyIncludes} DESTINATION ${inc_install_dir} )
endif()
endmacro( add_python_module )
+
+
+#
+# Build a Python extention module (3rd version).
+# Usage:
+# * pyCpps: The list of C/C++ module files.
+# * pyIncludes: The list of C/C++ header files (will be installed in
+# "inc_install_dir").
+# * pymodule: The name of the Python module (for "import PYMODULE").
+# * deplibs: The list of dependencies.
+# * inc_install_dir: The directory into which install the includes.
+#
+ macro( add_python_module3 pyCpps pyIncludes pymodule deplibs inc_install_dir )
+ add_library( ${pymodule} MODULE ${pyCpps} )
+ set_target_properties( ${pymodule} PROPERTIES PREFIX "" )
+ target_link_libraries( ${pymodule} ${deplibs} )
+
+ install( TARGETS ${pymodule} DESTINATION ${Python_CORIOLISARCH} )
+ if( NOT ("${pyIncludes}" STREQUAL "None") )
+ install( FILES ${pyIncludes} DESTINATION ${inc_install_dir} )
+ endif()
+ endmacro( add_python_module3 )
diff --git a/bootstrap/cmake_modules/FindPythonSitePackages.cmake b/bootstrap/cmake_modules/FindPythonSitePackages.cmake
index 841d0003..f9fc16b7 100644
--- a/bootstrap/cmake_modules/FindPythonSitePackages.cmake
+++ b/bootstrap/cmake_modules/FindPythonSitePackages.cmake
@@ -1,13 +1,26 @@
if(UNIX)
+ if(NOT Python_FOUND)
+ message(FATAL_ERROR "Python has not been found, maybe forgot to call find_package(Python). ")
+ endif()
# This way avoids newline in the script string.
set(SCRIPT "import os.path,distutils.sysconfig")
- set(SCRIPT "${SCRIPT}; pathes = distutils.sysconfig.get_python_lib().split('/')")
- set(SCRIPT "${SCRIPT}; print os.path.join(pathes[-2],pathes[-1])")
+ set(SCRIPT "${SCRIPT}; pathes = distutils.sysconfig.get_python_lib('platstdlib').split('/')")
+ set(SCRIPT "${SCRIPT}; print( os.path.join(pathes[-2],pathes[-1]) )")
- execute_process(COMMAND "python" "-c" "${SCRIPT}"
+ execute_process(COMMAND "${Python_EXECUTABLE}" "-c" "${SCRIPT}"
RESULT_VARIABLE RETURN_CODE
- OUTPUT_VARIABLE PYTHON_SITE_PACKAGES
+ OUTPUT_VARIABLE Python_CORIOLISARCH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ set(SCRIPT "import os.path,distutils.sysconfig")
+ set(SCRIPT "${SCRIPT}; pathes = distutils.sysconfig.get_python_lib('stdlib').split('/')")
+ set(SCRIPT "${SCRIPT}; print( os.path.join(pathes[-2],pathes[-1]) )")
+
+ execute_process(COMMAND "${Python_EXECUTABLE}" "-c" "${SCRIPT}"
+ RESULT_VARIABLE RETURN_CODE
+ OUTPUT_VARIABLE Python_CORIOLISLIB
OUTPUT_STRIP_TRAILING_WHITESPACE
)
@@ -17,14 +30,17 @@ if(UNIX)
set(FindPythonSitePackages_FOUND FALSE)
endif(RETURN_CODE EQUAL 0)
- set(PYTHON_SITE_PACKAGES "lib${LIB_SUFFIX}/${PYTHON_SITE_PACKAGES}"
- CACHE STRING "Python site packages directory." FORCE)
- mark_as_advanced(PYTHON_SITE_PACKAGES)
+ set(Python_CORIOLISARCH "lib${LIB_SUFFIX}/${Python_CORIOLISARCH}"
+ CACHE STRING "Python platform dependent install directory." FORCE)
+ set(Python_CORIOLISLIB "lib${LIB_SUFFIX}/${Python_CORIOLISLIB}"
+ CACHE STRING "Python platform independent install directory." FORCE)
+ mark_as_advanced(Python_CORIOLISARCH)
+ mark_as_advanced(Python_CORIOLISLIB)
if(FindPythonSitePackages_FOUND)
if(NOT FindPythonSitePackages_FIND_QUIETLY)
if(FindPythonSitePackages_FOUND)
- message(STATUS "Found FindPythonSitePackages : ${PYTHON_SITE_PACKAGES}")
+ message(STATUS "Found FindPythonSitePackages : ${Python_CORIOLISARCH}")
endif(FindPythonSitePackages_FOUND)
endif(NOT FindPythonSitePackages_FIND_QUIETLY)
else(FindPythonSitePackages_FOUND)
diff --git a/bootstrap/coriolisEnv.py b/bootstrap/coriolisEnv.py
index fa8aeff4..9c5504c7 100755
--- a/bootstrap/coriolisEnv.py
+++ b/bootstrap/coriolisEnv.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import re
@@ -17,27 +17,23 @@ reDebugStaticPattern = re.compile( r".*Debug\.Static.*" )
def scrubPath ( pathName ):
- pathEnv = os.getenv( pathName )
- if not pathEnv: return ""
-
- pathList = string.split( pathEnv, ':' )
- scrubbedList = []
- for pathElement in pathList:
- if reCoriolisPattern .match(pathElement) \
- or reReleaseSharedPattern.match(pathElement) \
- or reReleaseStaticPattern.match(pathElement) \
- or reDebugSharedPattern .match(pathElement) \
- or reDebugStaticPattern .match(pathElement):
- continue
- scrubbedList += [ pathElement ]
-
- if len(scrubbedList) == 0: return ""
-
- scrubbedEnv = scrubbedList[0]
- for pathElement in scrubbedList[1:]:
- scrubbedEnv += ":" + pathElement
-
- return scrubbedEnv
+ pathEnv = os.getenv( pathName )
+ if not pathEnv: return ""
+ pathList = pathEnv.split( ':' )
+ scrubbedList = []
+ for pathElement in pathList:
+ if reCoriolisPattern .match(pathElement) \
+ or reReleaseSharedPattern.match(pathElement) \
+ or reReleaseStaticPattern.match(pathElement) \
+ or reDebugSharedPattern .match(pathElement) \
+ or reDebugStaticPattern .match(pathElement):
+ continue
+ scrubbedList += [ pathElement ]
+ if len(scrubbedList) == 0: return ""
+ scrubbedEnv = scrubbedList[0]
+ for pathElement in scrubbedList[1:]:
+ scrubbedEnv += ":" + pathElement
+ return scrubbedEnv
def guessOs ():
@@ -67,41 +63,41 @@ def guessOs ():
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
lines = uname.stdout.readlines()
- if osSlsoc7x_64.match(lines[0]): osType = "Linux.el7_64"
- elif osSlsoc6x_64.match(lines[0]):
- osType = "Linux.slsoc6x_64"
- useDevtoolset = True
- elif osSlsoc6x.match(lines[0]):
- osType = "Linux.slsoc6x"
- useDevtoolset = True
- elif osSLSoC5x_64 .match(lines[0]): osType = "Linux.SLSoC5x_64"
- elif osSLSoC5x .match(lines[0]): osType = "Linux.SLSoC5x"
- elif osFedora_64 .match(lines[0]): osType = "Linux.fc_64"
- elif osFedora .match(lines[0]): osType = "Linux.fc"
- elif osUbuntu1004 .match(lines[0]): osType = "Linux.Ubuntu1004"
- elif osUbuntu1004_64 .match(lines[0]): osType = "Linux.Ubuntu1004_64"
- elif osLinux_64 .match(lines[0]): osType = "Linux.x86_64"
- elif osLinux .match(lines[0]): osType = "Linux.i386"
- elif osFreeBSD8x_64 .match(lines[0]): osType = "FreeBSD.8x.x86_64"
- elif osFreeBSD8x_amd64.match(lines[0]): osType = "FreeBSD.8x.amd64"
- elif osFreeBSD8x .match(lines[0]): osType = "FreeBSD.8x.i386"
- elif osDarwin .match(lines[0]): osType = "Darwin"
- elif osCygwinW7_64 .match(lines[0]): osType = "Cygwin.W7_64"
- elif osCygwinW7 .match(lines[0]): osType = "Cygwin.W7"
- elif osCygwinW8_64 .match(lines[0]): osType = "Cygwin.W8_64"
- elif osCygwinW8 .match(lines[0]): osType = "Cygwin.W8"
- elif osCygwinW10_64 .match(lines[0]): osType = "Cygwin.W10_64"
- elif osCygwinW10 .match(lines[0]): osType = "Cygwin.W10"
+ line = lines[0].decode( 'ascii' )
+ if osSlsoc7x_64.match(line): osType = "Linux.el7_64"
+ elif osSlsoc6x_64.match(line):
+ osType = "Linux.slsoc6x_64"
+ useDevtoolset = True
+ elif osSlsoc6x.match(line):
+ osType = "Linux.slsoc6x"
+ useDevtoolset = True
+ elif osSLSoC5x_64 .match(line): osType = "Linux.SLSoC5x_64"
+ elif osSLSoC5x .match(line): osType = "Linux.SLSoC5x"
+ elif osFedora_64 .match(line): osType = "Linux.fc_64"
+ elif osFedora .match(line): osType = "Linux.fc"
+ elif osUbuntu1004 .match(line): osType = "Linux.Ubuntu1004"
+ elif osUbuntu1004_64 .match(line): osType = "Linux.Ubuntu1004_64"
+ elif osLinux_64 .match(line): osType = "Linux.x86_64"
+ elif osLinux .match(line): osType = "Linux.i386"
+ elif osFreeBSD8x_64 .match(line): osType = "FreeBSD.8x.x86_64"
+ elif osFreeBSD8x_amd64.match(line): osType = "FreeBSD.8x.amd64"
+ elif osFreeBSD8x .match(line): osType = "FreeBSD.8x.i386"
+ elif osDarwin .match(line): osType = "Darwin"
+ elif osCygwinW7_64 .match(line): osType = "Cygwin.W7_64"
+ elif osCygwinW7 .match(line): osType = "Cygwin.W7"
+ elif osCygwinW8_64 .match(line): osType = "Cygwin.W8_64"
+ elif osCygwinW8 .match(line): osType = "Cygwin.W8"
+ elif osCygwinW10_64 .match(line): osType = "Cygwin.W10_64"
+ elif osCygwinW10 .match(line): osType = "Cygwin.W10"
else:
- uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
- osType = uname.stdout.readlines()[0][:-1]
+ uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
+ osType = uname.stdout.readlines()[0][:-1]
- print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
- print " (using: \"%s\")" % osType
+ print( "[WARNING] Unrecognized OS: \"{}\".".format( line[:-1] ))
+ print( " (using: \"{}\")".format( osType ))
ldLibraryPath = os.getenv('LD_LIBRARY_PATH')
if ldLibraryPath and 'devtoolset' in ldLibraryPath: useDevtoolset = False
-
- return (osType,useDevtoolset)
+ return ( osType, useDevtoolset )
def guessShell ():
@@ -109,12 +105,10 @@ def guessShell ():
# the user logs in. If aftewards it changes it that variable is *not*
# affected :-(.
#if os.environ.has_key('SHELL'): return os.environ['SHELL']
-
psCommand = subprocess.Popen ( ['ps', '-p', str(os.getppid()) ], stdout=subprocess.PIPE )
- shell = psCommand.stdout.readlines()[1][:-1].split()[3].lstrip('-')
+ shell = psCommand.stdout.readlines()[1].decode('ascii')[:-1].split()[3].lstrip('-')
whichCommand = subprocess.Popen ( ['which', shell ], stdout=subprocess.PIPE )
shellPath = whichCommand.stdout.readlines()[0][:-1]
-
isBourneShell = True
cshBins = [ '/usr/bin/tcsh'
, '/bin/tcsh'
@@ -126,12 +120,10 @@ def guessShell ():
, '/usr/local/bin/csh'
]
if shellPath in cshBins: isBourneShell = False
- #print 'GUESSED SHELL: "%s"' % shellPath
-
+ #print( 'GUESSED SHELL: "{}"'.format( shellPath ))
return shellPath, isBourneShell
-
if __name__ == "__main__":
osType,useDevtoolset = guessOs()
@@ -140,7 +132,7 @@ if __name__ == "__main__":
rootDir = None
shellBin, isBourneShell = guessShell()
- parser = optparse.OptionParser ()
+ parser = optparse.OptionParser()
# Build relateds.
parser.add_option ( "--query-inst-root", action="store_true" , dest="queryInstRoot" )
parser.add_option ( "--query-isys-root", action="store_true" , dest="queryISysRoot" )
@@ -152,7 +144,7 @@ if __name__ == "__main__":
parser.add_option ( "--no-python" , action="store_true" , dest="nopython" )
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" )
parser.add_option ( "--remove" , action="store_true" , dest="remove" )
- ( options, args ) = parser.parse_args ()
+ ( options, args ) = parser.parse_args()
if options.release: buildType = "Release"
if options.debug: buildType = "Debug"
@@ -161,158 +153,143 @@ if __name__ == "__main__":
if options.shared: linkType = "Shared"
if options.rootDir: rootDir = options.rootDir
- scriptPath = os.path.abspath(os.path.dirname(sys.argv[0]))
+ scriptPath = os.path.abspath( os.path.dirname( sys.argv[0] ))
if 'Debug.' in scriptPath: buildType = 'Debug'
-
if not shellBin:
- print 'echo "[ERROR] coriolisEnv.py was not able to guess/find the current shell interpeter."'
- sys.exit( 1 )
-
+ print( 'echo "[ERROR] coriolisEnv.py was not able to guess/find the current shell interpeter."' )
+ sys.exit( 1 )
strippedPath = scrubPath( "PATH" )
strippedLibraryPath = scrubPath( "LD_LIBRARY_PATH" )
strippedPythonPath = scrubPath( "PYTHONPATH" )
-
if options.remove:
- shellScript = 'echo "Removing Coriolis environment";'
- if osType == "Darwin":
- ldVar = 'DYLD_LIBRARY_PATH'
- else:
- ldVar = 'LD_LIBRARY_PATH'
-
- if isBourneShell:
- shellScript += 'export PATH={};hash -r;'.format(strippedPath)
- shellScript += 'BOOTSTRAP_TOP="";CORIOLIS_TOP="";export -n BOOTSTRAP_TOP CORIOLIS_TOP;'
- if strippedLibraryPath:
- shellScript += 'export {}={};'.format(ldVar, strippedLibraryPath)
+ shellScript = 'echo "Removing Coriolis environment";'
+ if osType == "Darwin":
+ ldVar = 'DYLD_LIBRARY_PATH'
else:
- shellScript += '{0}=""; export -n {0};'.format(ldVar)
- else:
- shellScript += 'setenv PATH {};rehash;'.format(strippedPath)
- shellScript += 'unsetenv BOOTSTRAP_TOP CORIOLIS_TOP;'
- if strippedLibraryPath:
- shellScript += 'setenv {} {};'.format(ldVar, strippedLibraryPath)
+ ldVar = 'LD_LIBRARY_PATH'
+ if isBourneShell:
+ shellScript += 'export PATH={};hash -r;'.format(strippedPath)
+ shellScript += 'BOOTSTRAP_TOP="";CORIOLIS_TOP="";export -n BOOTSTRAP_TOP CORIOLIS_TOP;'
+ if strippedLibraryPath:
+ shellScript += 'export {}={};'.format(ldVar, strippedLibraryPath)
+ else:
+ shellScript += '{0}=""; export -n {0};'.format(ldVar)
else:
- shellScript += 'unsetenv {};'.format(ldVar)
-
- print(shellScript)
- sys.exit(0)
+ shellScript += 'setenv PATH {};rehash;'.format(strippedPath)
+ shellScript += 'unsetenv BOOTSTRAP_TOP CORIOLIS_TOP;'
+ if strippedLibraryPath:
+ shellScript += 'setenv {} {};'.format(ldVar, strippedLibraryPath)
+ else:
+ shellScript += 'unsetenv {};'.format(ldVar)
+ print( shellScript )
+ sys.exit(0)
shellScriptSh = \
- 'echo "%(MESSAGE)s";' \
- 'echo "Switching to Coriolis 2.x (%(buildDir)s)";' \
- 'PATH="%(PATH)s";' \
- 'BOOTSTRAP_TOP="%(BOOTSTRAP_TOP)s";' \
- 'CORIOLIS_TOP="%(CORIOLIS_TOP)s";' \
- 'export PATH BOOTSTRAP_TOP CORIOLIS_TOP STRATUS_MAPPING_NAME;'
+ 'echo "%(MESSAGE)s";' \
+ 'echo "Switching to Coriolis 2.x (%(buildDir)s)";' \
+ 'PATH="%(PATH)s";' \
+ 'BOOTSTRAP_TOP="%(BOOTSTRAP_TOP)s";' \
+ 'CORIOLIS_TOP="%(CORIOLIS_TOP)s";' \
+ 'export PATH BOOTSTRAP_TOP CORIOLIS_TOP STRATUS_MAPPING_NAME;'
-# 'STRATUS_MAPPING_NAME="%(SYSCONF_DIR)s/stratus2sxlib.xml";' \
+# 'STRATUS_MAPPING_NAME="%(SYSCONF_DIR)s/stratus2sxlib.xml";' \
shellScriptCsh = \
- 'echo "%(MESSAGE)s";' \
- 'echo "Switching to Coriolis 2.x (%(buildDir)s)";' \
- 'setenv PATH "%(PATH)s";' \
- 'setenv BOOTSTRAP_TOP "%(BOOTSTRAP_TOP)s";' \
- 'setenv CORIOLIS_TOP "%(CORIOLIS_TOP)s";'
+ 'echo "%(MESSAGE)s";' \
+ 'echo "Switching to Coriolis 2.x (%(buildDir)s)";' \
+ 'setenv PATH "%(PATH)s";' \
+ 'setenv BOOTSTRAP_TOP "%(BOOTSTRAP_TOP)s";' \
+ 'setenv CORIOLIS_TOP "%(CORIOLIS_TOP)s";'
-# 'setenv STRATUS_MAPPING_NAME "%(SYSCONF_DIR)s/stratus2sxlib.xml";' \
+# 'setenv STRATUS_MAPPING_NAME "%(SYSCONF_DIR)s/stratus2sxlib.xml";' \
reDevtoolset = re.compile( r'/opt/rh/devtoolset-(?P\d+)/root/etc/coriolis2.*' )
buildDir = buildType + "." + linkType
scriptDir = os.path.dirname ( os.path.abspath(__file__) )
- #print "echo \"Script Location: %s\";" % scriptDir,
+ #print( "echo \"Script Location: {}\";".format( scriptDir ))
if scriptDir.startswith("/etc/coriolis2"):
- coriolisTop = "/usr"
- sysconfDir = scriptDir
- shellMessage = "Using system-wide Coriolis 2 (/usr)"
+ coriolisTop = "/usr"
+ sysconfDir = scriptDir
+ shellMessage = "Using system-wide Coriolis 2 (/usr)"
else:
- m = reDevtoolset.match( scriptDir )
- if m:
- coriolisTop = "/opt/rh/devtoolset-%d/root/usr" % m.group('version')
- sysconfDir = scriptDir
- shellMessage = "Using system-wide devtoolset-%(v)d Coriolis 2 (/opt/rh/devtoolset-%(v)d/root/usr)" \
- % { 'v':m.group('version') }
- elif scriptDir.startswith(os.getenv("HOME")+"/nightly/coriolis-2.x/"):
- rootDir = os.getenv("HOME") + "/nightly/coriolis-2.x"
- coriolisTop = "%s/%s/%s/install" % ( rootDir, osType, buildDir )
- sysconfDir = scriptDir
- shellMessage = "Using Nightly build Coriolis 2 (%s)" % coriolisTop
- elif scriptDir.startswith("/users/outil/coriolis/coriolis-2.x/") \
- or scriptDir.startswith("/soc/coriolis2/"):
- coriolisTop = "/soc/coriolis2"
- sysconfDir = coriolisTop + "/etc/coriolis2"
- shellMessage = "Using SoC network-wide Coriolis 2 (/soc/coriolis2)"
- else:
- if not rootDir:
- rootDir = os.getenv("HOME") + "/coriolis-2.x"
- coriolisTop = "%s/%s/%s/install" % ( rootDir, osType, buildDir )
- sysconfDir = coriolisTop + "/etc/coriolis2"
- shellMessage = "Using user-selected Coriolis 2 (%s)" % rootDir
+ m = reDevtoolset.match( scriptDir )
+ if m:
+ coriolisTop = "/opt/rh/devtoolset-%d/root/usr" % m.group('version')
+ sysconfDir = scriptDir
+ shellMessage = "Using system-wide devtoolset-%(v)d Coriolis 2 (/opt/rh/devtoolset-%(v)d/root/usr)" \
+ % { 'v':m.group('version') }
+ elif scriptDir.startswith(os.getenv("HOME")+"/nightly/coriolis-2.x/"):
+ rootDir = os.getenv("HOME") + "/nightly/coriolis-2.x"
+ coriolisTop = "%s/%s/%s/install" % ( rootDir, osType, buildDir )
+ sysconfDir = scriptDir
+ shellMessage = "Using Nightly build Coriolis 2 (%s)" % coriolisTop
+ elif scriptDir.startswith("/users/outil/coriolis/coriolis-2.x/") \
+ or scriptDir.startswith("/soc/coriolis2/"):
+ coriolisTop = "/soc/coriolis2"
+ sysconfDir = coriolisTop + "/etc/coriolis2"
+ shellMessage = "Using SoC network-wide Coriolis 2 (/soc/coriolis2)"
+ else:
+ if not rootDir:
+ rootDir = os.getenv("HOME") + "/coriolis-2.x"
+ coriolisTop = "%s/%s/%s/install" % ( rootDir, osType, buildDir )
+ sysconfDir = coriolisTop + "/etc/coriolis2"
+ shellMessage = "Using user-selected Coriolis 2 (%s)" % rootDir
if osType.startswith("Cygwin"):
- strippedPath = "%s/lib:%s" % ( coriolisTop, libDir, strippedPath )
-
+ strippedPath = "%s/lib:%s" % ( coriolisTop, libDir, strippedPath )
if not os.path.exists(coriolisTop):
- print 'echo "[ERROR] coriolisEnv.py, top directory <%s> do not exists."' % coriolisTop
- sys.exit( 1 )
-
+ print( 'echo "[ERROR] coriolisEnv.py, top directory <%s> do not exists."'.format( coriolisTop ))
+ sys.exit( 1 )
for lib in [ 'lib64', 'lib' ]:
- libDir = lib
- absLibDir = '{0}/{1}'.format( coriolisTop, lib )
- if os.path.isdir(absLibDir): break
- libDir = None
-
+ libDir = lib
+ absLibDir = '{0}/{1}'.format( coriolisTop, lib )
+ if os.path.isdir(absLibDir): break
+ libDir = None
if libDir is None:
- print 'echo "[ERROR] coriolisEnv.py, library directory not found."'
- sys.exit( 1 )
+ print( 'echo "[ERROR] coriolisEnv.py, library directory not found."' )
+ sys.exit( 1 )
strippedPath = "%s/bin:%s" % ( coriolisTop, strippedPath )
strippedLibraryPath = "%s:%s" % ( absLibDir , strippedLibraryPath )
-
if not options.nopython:
- pyVersion = sys.version_info
- version = "%d.%d" % (pyVersion[0],pyVersion[1])
-
- sitePackagesDir = "sitePackageDir_has_been_not_found"
- for pyPackageDir in [ "%s/python%s/site-packages" % (absLibDir,version)
- , "%s/python%s/dist-packages" % (absLibDir,version)
- , "%s/%s/site-packages" % (absLibDir,version)
- ]:
- if os.path.isdir(pyPackageDir):
- sitePackagesDir = pyPackageDir
- break
-
- strippedPythonPath = "%s:" % (sitePackagesDir) + strippedPythonPath
- strippedPythonPath = "%s/crlcore:" % (sitePackagesDir) + strippedPythonPath
- strippedPythonPath = "%s/cumulus:" % (sitePackagesDir) + strippedPythonPath
- strippedPythonPath = "%s/cumulus/plugins:" % (sitePackagesDir) + strippedPythonPath
- strippedPythonPath = "%s/stratus:" % (sitePackagesDir) + strippedPythonPath
- strippedPythonPath = "%s:" % (sysconfDir) + strippedPythonPath
-
- shellScriptSh += 'PYTHONPATH="%(PYTHONPATH)s";' \
- 'export PYTHONPATH;'
- shellScriptCsh += 'setenv PYTHONPATH "%(PYTHONPATH)s";'
-
- if osType == "Darwin":
- shellScriptSh += 'DYLD_LIBRARY_PATH="%(LD_LIBRARY_PATH)s";' \
- 'export DYLD_LIBRARY_PATH;'
- shellScriptCsh += 'setenv DYLD_LIBRARY_PATH "%(LD_LIBRARY_PATH)s";'
- else:
- shellScriptSh += 'LD_LIBRARY_PATH="%(LD_LIBRARY_PATH)s";' \
- 'export LD_LIBRARY_PATH;'
- shellScriptCsh += 'setenv LD_LIBRARY_PATH "%(LD_LIBRARY_PATH)s";'
+ pyVersion = sys.version_info
+ version = "%d.%d" % (pyVersion[0],pyVersion[1])
+ sitePackagesDir = "sitePackageDir_has_been_not_found"
+ for pyPackageDir in [ "%s/python%s/site-packages" % (absLibDir,version)
+ , "%s/python%s/dist-packages" % (absLibDir,version)
+ , "%s/%s/site-packages" % (absLibDir,version)
+ ]:
+ if os.path.isdir(pyPackageDir):
+ sitePackagesDir = pyPackageDir
+ break
+ strippedPythonPath = "%s:" % (sitePackagesDir) + strippedPythonPath
+ strippedPythonPath = "%s/crlcore:" % (sitePackagesDir) + strippedPythonPath
+ strippedPythonPath = "%s/cumulus:" % (sitePackagesDir) + strippedPythonPath
+ strippedPythonPath = "%s/cumulus/plugins:" % (sitePackagesDir) + strippedPythonPath
+ strippedPythonPath = "%s/stratus:" % (sitePackagesDir) + strippedPythonPath
+ strippedPythonPath = "%s:" % (sysconfDir) + strippedPythonPath
+ shellScriptSh += 'PYTHONPATH="%(PYTHONPATH)s";' \
+ 'export PYTHONPATH;'
+ shellScriptCsh += 'setenv PYTHONPATH "%(PYTHONPATH)s";'
+ if osType == "Darwin":
+ shellScriptSh += 'DYLD_LIBRARY_PATH="%(LD_LIBRARY_PATH)s";' \
+ 'export DYLD_LIBRARY_PATH;'
+ shellScriptCsh += 'setenv DYLD_LIBRARY_PATH "%(LD_LIBRARY_PATH)s";'
+ else:
+ shellScriptSh += 'LD_LIBRARY_PATH="%(LD_LIBRARY_PATH)s";' \
+ 'export LD_LIBRARY_PATH;'
+ shellScriptCsh += 'setenv LD_LIBRARY_PATH "%(LD_LIBRARY_PATH)s";'
shellScriptSh += "hash -r;"
shellScriptCsh += "rehash;"
-
if isBourneShell: shellScript = shellScriptSh
else: shellScript = shellScriptCsh
-
if useDevtoolset:
- shellScript += \
- ' echo "Launching a devtoolset-8 subshell though scl (CTRL+D to exit).";' \
- ' scl enable devtoolset-8 %(SHELL)s'
+ shellScript += \
+ ' echo "Launching a devtoolset-8 subshell though scl (CTRL+D to exit).";' \
+ ' scl enable devtoolset-8 %(SHELL)s'
evalScript = shellScript % { "PATH" : strippedPath
, "LD_LIBRARY_PATH" : strippedLibraryPath
@@ -325,12 +302,10 @@ if __name__ == "__main__":
, 'SHELL' : shellBin
}
if options.queryISysRoot:
- print '%s/%s' % (rootDir,osType)
- sys.exit( 0 )
-
+ print( '{}/{}'.format( rootDir, osType ))
+ sys.exit( 0 )
if options.queryInstRoot:
- print coriolisTop
- sys.exit( 0 )
-
- print evalScript
+ print( coriolisTop )
+ sys.exit( 0 )
+ print( evalScript )
sys.exit( 0 )
diff --git a/bootstrap/socInstaller.py b/bootstrap/socInstaller.py
index e0d2d26b..86867ff0 100755
--- a/bootstrap/socInstaller.py
+++ b/bootstrap/socInstaller.py
@@ -1,9 +1,9 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2015-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2015-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -24,77 +24,73 @@
showTrace = True
try:
- import sys
- import os.path
- import shutil
- import optparse
- import time
- import traceback
- import distutils.sysconfig
- import subprocess
- import socket
- import re
- import bz2
- import smtplib
- from email.mime.text import MIMEText
- from email.mime.multipart import MIMEMultipart
- from email.mime.application import MIMEApplication
-except ImportError, e:
- module = str(e).split()[-1]
+ import sys
+ import os.path
+ import shutil
+ import optparse
+ import time
+ import traceback
+ import distutils.sysconfig
+ import subprocess
+ import socket
+ import re
+ import bz2
+ import smtplib
+ from io import IOBase
+ from email.mime.text import MIMEText
+ from email.mime.multipart import MIMEMultipart
+ from email.mime.application import MIMEApplication
+except ImportError as e:
+ module = str(e).split()[-1]
class ErrorMessage ( Exception ):
def __init__ ( self, code, *arguments ):
self._code = code
- self._errors = [ 'Malformed call to ErrorMessage()', '%s' % str(arguments) ]
-
+ self._errors = [ 'Malformed call to ErrorMessage()', '{}'.format(arguments) ]
text = None
if len(arguments) == 1:
- if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
- else:
- self._errors = arguments[0]
- elif len(arguments) > 1:
- text = list(arguments)
-
- if text:
- self._errors = []
- while len(text[0]) == 0: del text[0]
-
- lstrip = 0
- if text[0].startswith('[ERROR]'): lstrip = 8
-
- for line in text:
- if line[0:lstrip ] == ' '*lstrip or \
- line[0:lstrip-1] == '[ERROR]':
- self._errors += [ line[lstrip:] ]
+ if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
else:
- self._errors += [ line.lstrip() ]
+ self._errors = arguments[0]
+ elif len(arguments) > 1:
+ text = list(arguments)
+ if text:
+ self._errors = []
+ while len(text[0]) == 0: del text[0]
+ lstrip = 0
+ if text[0].startswith('[ERROR]'): lstrip = 8
+ for line in text:
+ if line[0:lstrip ] == ' '*lstrip or \
+ line[0:lstrip-1] == '[ERROR]':
+ self._errors += [ line[lstrip:] ]
+ else:
+ self._errors += [ line.lstrip() ]
return
def __str__ ( self ):
if not isinstance(self._errors,list):
- return "[ERROR] %s" % self._errors
-
+ return "[ERROR] {}".format(self._errors)
formatted = "\n"
for i in range(len(self._errors)):
- if i == 0: formatted += "[ERROR] %s" % self._errors[i]
- else: formatted += " %s" % self._errors[i]
- if i+1 < len(self._errors): formatted += "\n"
+ if i == 0: formatted += "[ERROR] {}".format(self._errors[i])
+ else: formatted += " {}".format(self._errors[i])
+ if i+1 < len(self._errors): formatted += "\n"
return formatted
def addMessage ( self, message ):
if not isinstance(self._errors,list):
- self._errors = [ self._errors ]
+ self._errors = [ self._errors ]
if isinstance(message,list):
- for line in message:
- self._errors += [ line ]
+ for line in message:
+ self._errors += [ line ]
else:
- self._errors += [ message ]
+ self._errors += [ message ]
return
def terminate ( self ):
- print self
+ print( self )
sys.exit(self._code)
@property
@@ -104,14 +100,14 @@ class ErrorMessage ( Exception ):
class BadBinary ( ErrorMessage ):
def __init__ ( self, binary ):
- ErrorMessage.__init__( self, 1, "Binary not found: <%s>." % binary )
+ ErrorMessage.__init__( self, 1, 'Binary not found: "{}".'.format(binary) )
return
class BadReturnCode ( ErrorMessage ):
def __init__ ( self, status ):
- ErrorMessage.__init__( self, 1, "Command returned status:%d." % status )
+ ErrorMessage.__init__( self, 1, 'Command returned status:{}.'.format(status) )
return
@@ -120,25 +116,31 @@ class Command ( object ):
def __init__ ( self, arguments, fdLog=None ):
self.arguments = arguments
self.fdLog = fdLog
-
- if self.fdLog != None and not isinstance(self.fdLog,file):
- print '[WARNING] Command.__init__(): is neither None or a file.'
+ if self.fdLog != None and not isinstance(self.fdLog,IOBase):
+ print( '[WARNING] Command.__init__(): "fdLog" is neither None or a file.' )
return
def _argumentsToStr ( self, arguments ):
s = ''
for argument in arguments:
- if argument.find(' ') >= 0: s += ' "' + argument + '"'
- else: s += ' ' + argument
+ if argument.find(' ') >= 0: s += ' "' + argument + '"'
+ else: s += ' ' + argument
return s
def log ( self, text ):
- print text[:-1]
+ if isinstance(self.fdLog,IOBase):
+ if isinstance(text,bytes):
+ print( text[:-1].decode('utf-8') )
+ self.fdLog.write( text.decode('utf-8') )
+ elif isinstance(text,str):
+ print( text[:-1] )
+ self.fdLog.write( text )
+ else:
+ print( '[ERROR] Command.log(): "text" is neither bytes or str.' )
+ print( ' {}'.format(text) )
+ self.fdLog.flush()
sys.stdout.flush()
sys.stderr.flush()
- if isinstance(self.fdLog,file):
- self.fdLog.write( text )
- self.fdLog.flush()
return
def execute ( self ):
@@ -149,29 +151,26 @@ class Command ( object ):
homeDir = os.environ['HOME']
workDir = os.getcwd()
if homeDir.startswith(homeDir):
- workDir = '~' + workDir[ len(homeDir) : ]
+ workDir = '~' + workDir[ len(homeDir) : ]
user = 'root'
- if os.environ.has_key('USER'): user = os.environ['USER']
- prompt = '%s@%s:%s$' % (user,conf.masterHost,workDir)
+ if 'USER' in os.environ: user = os.environ['USER']
+ prompt = '{}@{}:{}$'.format(user,conf.masterHost,workDir)
try:
- self.log( '%s%s\n' % (prompt,self._argumentsToStr(self.arguments)) )
- print self.arguments
- child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
-
- while True:
- line = child.stdout.readline()
- if not line: break
-
- self.log( line )
- except OSError, e:
- raise BadBinary( self.arguments[0] )
+ self.log( '{}{}\n'.format(prompt,self._argumentsToStr(self.arguments)) )
+ print( self.arguments )
+ child = subprocess.Popen( self.arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
+ while True:
+ line = child.stdout.readline()
+ if not line: break
+ self.log( line )
+ except OSError as e:
+ raise BadBinary( self.arguments[0] )
(pid,status) = os.waitpid( child.pid, 0 )
status >>= 8
if status != 0:
- raise BadReturnCode( status )
-
+ raise BadReturnCode( status )
return
@@ -186,11 +185,10 @@ class CommandArg ( object ):
def __str__ ( self ):
s = ''
- if self.wd: s = 'cd %s && ' % self.wd
-
+ if self.wd: s = 'cd {} && '.format(self.wd)
for i in range(len(self.command)):
- if i: s += ' '
- s += self.command[i]
+ if i: s += ' '
+ s += self.command[i]
return s
def getArgs ( self ):
@@ -223,7 +221,7 @@ class CoriolisCommand ( CommandArg ):
CommandArg.__init__ ( self, [ ccbBin
, '--root='+rootDir
, '--project=coriolis'
- , '--make=-j%d install' % threads
+ , '--make=-j{} install'.format(threads)
] + otherArgs
, fdLog=fdLog )
return
@@ -258,21 +256,20 @@ class GitRepository ( object ):
def removeLocalRepo ( self ):
if os.path.isdir(self.localRepoDir):
- print 'Removing Git local repository: <%s>' % self.localRepoDir
- shutil.rmtree( self.localRepoDir )
+ print( 'Removing Git local repository: "{}"'.format(self.localRepoDir) )
+ shutil.rmtree( self.localRepoDir )
return
def clone ( self ):
- print 'Clone/pull from:', self.url
+ print( 'Clone/pull from:', self.url )
if not os.path.isdir(self.cloneDir):
- os.makedirs( self.cloneDir )
-
+ os.makedirs( self.cloneDir )
if not os.path.isdir(self.localRepoDir):
- os.chdir( self.cloneDir )
- Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
+ os.chdir( self.cloneDir )
+ Command( [ 'git', 'clone', self.url ], self.fdLog ).execute()
else:
- os.chdir( self.localRepoDir )
- Command( [ 'git', 'pull' ], self.fdLog ).execute()
+ os.chdir( self.localRepoDir )
+ Command( [ 'git', 'pull' ], self.fdLog ).execute()
return
def checkout ( self, branch ):
@@ -323,28 +320,26 @@ class Configuration ( object ):
self._masterHost = self._detectMasterHost()
self._success = False
self._rcode = 0
-
self._updateSecondaries()
return
def __setattr__ ( self, attribute, value ):
if attribute in Configuration.SecondaryNames:
- print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
- return
+ print( ErrorMessage( 1, 'Attempt to write in read-only attribute "{}" in Configuration.' \
+ .format(attribute) ))
+ return
if attribute == 'masterHost' or attribute == '_masterHost':
- if value == 'lepka':
- print 'Never touch the Git tree when running on .'
- self._rmSource = False
- self._rmBuild = False
- self._doGit = False
- self._doSendReport = False
-
+ if value == 'lepka':
+ print( 'Never touch the Git tree when running on "lepka".' )
+ self._rmSource = False
+ self._rmBuild = False
+ self._doGit = False
+ self._doSendReport = False
if attribute[0] == '_':
- self.__dict__[attribute] = value
- return
-
- if attribute == 'homeDir': value = os.path.expanduser(value)
+ self.__dict__[attribute] = value
+ return
+ if attribute == 'homeDir': value = os.path.expanduser(value)
self.__dict__['_'+attribute] = value
self._updateSecondaries()
@@ -352,15 +347,15 @@ class Configuration ( object ):
def __getattr__ ( self, attribute ):
if attribute[0] != '_': attribute = '_'+attribute
- if not self.__dict__.has_key(attribute):
- raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
+ if not attribute in self.__dict__:
+ raise ErrorMessage( 1, 'Configuration has no attribute "{}".'.format(attribute) )
return self.__dict__[attribute]
def _updateSecondaries ( self ):
if self._nightlyMode:
- self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
+ self._rootDir = self._homeDir + '/nightly/coriolis-2.x'
else:
- self._rootDir = self._homeDir + '/coriolis-2.x'
+ self._rootDir = self._homeDir + '/coriolis-2.x'
self._srcDir = self._rootDir + '/src'
self._logDir = self._srcDir + '/logs'
self._yosysBin = self._srcDir + '/' + GitRepository.getLocalRepository(self._coriolisRepo) + '/bootstrap/yosysInstaller.sh'
@@ -373,27 +368,24 @@ class Configuration ( object ):
def _detectMasterHost ( self ):
if self._chrootMode is None: return 'unknown'
if self._chrootMode: return 'chrooted-host'
-
masterHost = 'unknown'
hostname = socket.gethostname()
hostAddr = socket.gethostbyname(hostname)
-
if hostname == 'lepka' and hostAddr == '127.0.0.1':
- masterHost = 'lepka'
+ masterHost = 'lepka'
else:
- masterHost = hostname.split('.')[0]
+ masterHost = hostname.split('.')[0]
return masterHost
def openLog ( self, stem ):
if not os.path.isdir(self._logDir):
- os.makedirs( self._logDir )
-
+ os.makedirs( self._logDir )
index = 0
timeTag = time.strftime( "%Y.%m.%d" )
while True:
- logFile = os.path.join(self._logDir,"%s-%s-%02d.log" % (stem,timeTag,index))
+ logFile = os.path.join(self._logDir,"{}-{}-{:02}.log".format(stem,timeTag,index))
if not os.path.isfile(logFile):
- print "Report log: <%s>" % logFile
+ print( 'Report log: "{}"'.format(logFile) )
break
index += 1
fd = open( logFile, "w" )
@@ -403,65 +395,59 @@ class Configuration ( object ):
def closeLogs ( self ):
for fd in self._fds.values():
- if fd: fd.close()
+ if fd: fd.close()
return
def compressLogs ( self ):
for log in self._logs.values():
- if not log: continue
-
- fd = open( log, 'r' )
- bzfd = bz2.BZ2File( log+'.bz2', 'w' )
-
- for line in fd.readlines(): bzfd.write( line )
-
- bzfd.close()
- fd.close()
-
- os.unlink( log )
+ if not log: continue
+ fd = open( log, 'r' )
+ bzfd = bz2.BZ2File( log+'.bz2', 'w' )
+ for line in fd.readlines():
+ if isinstance(line,str):
+ bzfd.write( line.encode('utf-8') )
+ elif isinstance(line,bytes):
+ bzfd.write( line )
+ bzfd.close()
+ fd.close()
+ os.unlink( log )
return
def getCommands ( self, target ):
- commands = []
-
+ commands = []
if self.doYosys:
- if not os.path.isfile( self.yosysBin ):
- raise ErrorMessage( 1, [ 'Cannot find , should be here:'
- , ' <%s>' % self.yosysBin
- ] )
- commands.append( YosysCommand( self.yosysBin, fdLog=self.fds['yosys'] ) )
-
+ if not os.path.isfile( self.yosysBin ):
+ raise ErrorMessage( 1, [ 'Cannot find , should be here:'
+ , ' "{}"'.format(self.yosysBin)
+ ] )
+ commands.append( YosysCommand( self.yosysBin, fdLog=self.fds['yosys'] ) )
if self.doAlliance:
- if not os.path.isfile( self.alcBin ):
- raise ErrorMessage( 1, [ 'Cannot find , should be here:'
- , ' <%s>' % self.alcBin
- ] )
- commands.append( AllianceCommand( self.alcBin, fdLog=self.fds['alliance'] ) )
-
+ if not os.path.isfile( self.alcBin ):
+ raise ErrorMessage( 1, [ 'Cannot find , should be here:'
+ , ' "{}"'.format(self.alcBin)
+ ] )
+ commands.append( AllianceCommand( self.alcBin, fdLog=self.fds['alliance'] ) )
if self.doCoriolis:
- if not os.path.isfile( self.ccbBin ):
- raise ErrorMessage( 1, [ 'Cannot find , should be here:'
- , ' <%s>' % self.ccbBin
- ] )
-
- otherArgs = []
- if self.debugArg: otherArgs.append( self.debugArg )
-
- if target == 'SL7_64':
- otherArgs.append( '--project=support' )
- commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
- commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
- elif target == 'SL6_64' or target == 'SL6':
- otherArgs.append( '--project=support' )
- otherArgs.append( '--devtoolset=8' )
- commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
- commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
- elif target == 'Ubuntu18' or target == 'Debian9' or target == 'Debian10':
- if target == 'Ubuntu18': otherArgs.append( '--qt5' )
- commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
-
+ if not os.path.isfile( self.ccbBin ):
+ raise ErrorMessage( 1, [ 'Cannot find , should be here:'
+ , ' "{}"'.format(self.ccbBin)
+ ] )
+ otherArgs = []
+ if self.debugArg: otherArgs.append( self.debugArg )
+ if target == 'SL7_64':
+ otherArgs.append( '--project=support' )
+ commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
+ commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
+ elif target == 'SL6_64' or target == 'SL6':
+ otherArgs.append( '--project=support' )
+ otherArgs.append( '--devtoolset=8' )
+ commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
+ commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
+ elif target == 'Ubuntu18' or target == 'Debian9' or target == 'Debian10':
+ if target == 'Ubuntu18': otherArgs.append( '--qt5' )
+ commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
if self.doBenchs:
- commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
+ commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
return commands
@@ -469,33 +455,30 @@ class Report ( object ):
def __init__ ( self, conf ):
self.conf = conf
-
commaspace = ', '
date = time.strftime( "%A %d %B %Y" )
stateText = 'FAILED'
modeText = 'SoC installation'
if self.conf.success: stateText = 'SUCCESS'
if self.conf.nightlyMode: modeText = 'Nightly build'
-
self.message = MIMEMultipart()
- self.message['Subject'] = '[%s] Coriolis %s %s' % (stateText,modeText,date)
+ self.message['Subject'] = '[{}] Coriolis {} {}'.format(stateText,modeText,date)
self.message['From' ] = self.conf.sender
self.message['To' ] = commaspace.join( self.conf.receivers )
self.attachements = []
-
self.mainText = '\n'
self.mainText += 'Salut le Crevard,\n'
self.mainText += '\n'
if self.conf.nightlyMode:
- self.mainText += 'This is the nightly build report of Coriolis.\n'
+ self.mainText += 'This is the nightly build report of Coriolis.\n'
else:
- self.mainText += 'SoC installer report of Coriolis.\n'
- self.mainText += '%s\n' % date
+ self.mainText += 'SoC installer report of Coriolis.\n'
+ self.mainText += '{}\n'.format(date)
self.mainText += '\n'
if self.conf.success:
- self.mainText += 'Build was SUCCESSFUL\n'
+ self.mainText += 'Build was SUCCESSFUL\n'
else:
- self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
+ self.mainText += 'Build has FAILED, please have a look to the attached log file(s).\n'
self.mainText += '\n'
self.mainText += 'Complete log file(s) can be found here:\n'
return
@@ -505,28 +488,27 @@ class Report ( object ):
fd = open( logFile, 'rb' )
try:
- fd.seek( -1024*100, os.SEEK_END )
- except IOError, e:
- pass
+ fd.seek( -1024*100, os.SEEK_END )
+ except IOError as e:
+ pass
tailLines = ''
for line in fd.readlines()[1:]:
- tailLines += line
+ tailLines += line
fd.close()
- self.mainText += ' <%s>\n' % logFile
+ self.mainText += ' "{}"\n'.format(logFile)
attachement = MIMEApplication(tailLines)
attachement.add_header( 'Content-Disposition', 'attachment', filename=os.path.basename(logFile) )
-
self.attachements.append( attachement )
return
def send ( self ):
self.message.attach( MIMEText(self.mainText) )
for attachement in self.attachements:
- self.message.attach( attachement )
+ self.message.attach( attachement )
- print "Sending mail report to:"
- for receiver in self.conf.receivers: print ' <%s>' % receiver
+ print( "Sending mail report to:" )
+ for receiver in self.conf.receivers: print( ' <{}>'.format(receiver) )
session = smtplib.SMTP( 'localhost' )
session.sendmail( self.conf.sender, self.conf.receivers, self.message.as_string() )
session.quit()
@@ -577,7 +559,6 @@ try:
if conf.doAlliance: conf.openLog( 'alliance' )
if conf.doCoriolis: conf.openLog( 'coriolis' )
if conf.doBenchs: conf.openLog( 'benchs' )
-
if conf.dockerMode: os.environ['USER'] = 'root'
gitSupports = []
@@ -613,29 +594,28 @@ try:
for entry in os.listdir(conf.rootDir):
if entry.startswith('Linux.'):
buildDir = conf.rootDir+'/'+entry
- print 'Removing OS build directory: <%s>' % buildDir
+ print( 'Removing OS build directory: "{}"'.format(buildDir) )
shutil.rmtree( buildDir )
commands = conf.getCommands( options.profile )
for command in commands:
if command.host:
- print 'Executing command on remote host <%s>:' % host
+ print( 'Executing command on remote host "{}":'.format(host) )
else:
- print 'Executing command on *local* host:'
- print ' %s' % str(command)
+ print( 'Executing command on *local* host:' )
+ print( ' {}'.format(command) )
command.execute()
conf.closeLogs()
-
conf.success = True
-except ErrorMessage, e:
- print e
+except ErrorMessage as e:
+ print( e )
conf.closeLogs()
conf.success = False
if showTrace:
- print '\nPython stack trace:'
+ print( '\nPython stack trace:' )
traceback.print_tb( sys.exc_info()[2] )
conf.rcode = e.code
diff --git a/bora/CMakeLists.txt b/bora/CMakeLists.txt
index a5964191..4c4b0148 100644
--- a/bora/CMakeLists.txt
+++ b/bora/CMakeLists.txt
@@ -14,15 +14,14 @@
setup_project_paths(CORIOLIS)
set_cmake_policies()
- setup_boost(program_options filesystem python regex)
+ setup_boost(program_options)
setup_qt()
setup_qwt()
find_package(Libexecinfo REQUIRED)
- find_package(PythonLibs 2 REQUIRED)
+ find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(LEFDEF REQUIRED)
- find_package(VLSISAPD REQUIRED)
find_package(FLUTE REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)
diff --git a/bora/python/CMakeLists.txt b/bora/python/CMakeLists.txt
index 26104e4d..a2f0ef8f 100644
--- a/bora/python/CMakeLists.txt
+++ b/bora/python/CMakeLists.txt
@@ -1,2 +1,2 @@
- install ( FILES boraInit.py DESTINATION ${PYTHON_SITE_PACKAGES}/bora )
+ install ( FILES boraInit.py DESTINATION ${Python_CORIOLISLIB}/bora )
diff --git a/bora/python/boraInit.py b/bora/python/boraInit.py
index 9ba76a52..ecbb70ed 100644
--- a/bora/python/boraInit.py
+++ b/bora/python/boraInit.py
@@ -1,29 +1,27 @@
-#!/usr/bin/env python
try:
- import sys
- import os.path
- import helpers.io
- from helpers.io import ErrorMessage
- from helpers.io import WarningMessage
- import Viewer
-except Exception, e:
- helpers.io.catch( e )
- sys.exit( 1 )
+ import sys
+ import os.path
+ import helpers.io
+ from helpers.io import ErrorMessage
+ from helpers.io import WarningMessage
+ import Viewer
+except Exception as e:
+ helpers.io.catch( e )
+ sys.exit( 1 )
def boraHook ( **kw ):
bora = None
- if kw.has_key('bora'):
- bora = kw['bora']
+ if 'bora' in kw:
+ bora = kw['bora']
else:
- print ErrorMessage( 3, 'boraHook(): Must be run from a BoraEngine.' )
- return
-
+ print( ErrorMessage( 3, 'boraHook(): Must be run from a BoraEngine.' ))
+ return
try:
- userInit = os.path.join( os.getcwd(), 'coriolis2/bora.py' )
- if (os.path.exists(userInit)):
- execfile( userInit )
- except Exception, e:
- helpers.io.catch( e )
+ userInit = os.path.join( os.getcwd(), 'coriolis2/bora.py' )
+ if (os.path.exists(userInit)):
+ exec( open(userInit).read() )
+ except Exception as e:
+ helpers.io.catch( e )
return
diff --git a/bora/src/CMakeLists.txt b/bora/src/CMakeLists.txt
index 1f7444bc..3b1f488d 100644
--- a/bora/src/CMakeLists.txt
+++ b/bora/src/CMakeLists.txt
@@ -7,7 +7,7 @@
${Boost_INCLUDE_DIRS}
${QWT_INCLUDE_DIR}
${QtX_INCLUDE_DIR}
- ${PYTHON_INCLUDE_PATH}
+ ${Python_INCLUDE_DIRS}
)
set( includes bora/Constants.h
bora/ParameterRange.h
@@ -99,7 +99,7 @@
${QWT_LIBRARY}
${QtX_LIBRARIES}
${Boost_LIBRARIES}
- ${PYTHON_LIBRARIES} -lutil
+ ${Python_LIBRARIES} -lutil
)
add_library( bora ${cpps} ${mocCpps} ${pyCpps} )
diff --git a/bora/src/PyBora.cpp b/bora/src/PyBora.cpp
index f2f40072..f6d31031 100644
--- a/bora/src/PyBora.cpp
+++ b/bora/src/PyBora.cpp
@@ -1,7 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
-// Copyright (c) UPMC 2016-2018, All Rights Reserved
+// Copyright (c) Sorbonne Université 2016-2021, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@@ -63,12 +63,21 @@ extern "C" {
};
- // ---------------------------------------------------------------
- // Module Initialization : "initBora ()"
+ static PyModuleDef PyBora_ModuleDef =
+ { PyModuleDef_HEAD_INIT
+ , .m_name = "Bora"
+ , .m_doc = "Analog Place & Global Route."
+ , .m_size = -1
+ , .m_methods = PyBora_Methods
+ };
- DL_EXPORT(void) initBora ()
+
+ // ---------------------------------------------------------------
+ // Module Initialization : "PyInit_Bora ()"
+
+ PyMODINIT_FUNC PyInit_Bora ( void )
{
- cdebug.log(61) << "initBora()" << endl;
+ cdebug.log(61) << "PyInit_Bora()" << endl;
PyParameterRange_LinkPyType();
PyStepParameterRange_LinkPyType();
@@ -95,12 +104,11 @@ extern "C" {
PYTYPE_READY_SUB( BoraEngine , ToolEngine );
PYTYPE_READY_SUB( GraphicBoraEngine , GraphicTool );
-
- PyObject* module = Py_InitModule( "Bora", PyBora_Methods );
+ PyObject* module = PyModule_Create( &PyBora_ModuleDef );
if (module == NULL) {
cerr << "[ERROR]\n"
<< " Failed to initialize Bora module." << endl;
- return;
+ return NULL;
}
Py_INCREF( &PyTypeParameterRange );
@@ -128,6 +136,8 @@ extern "C" {
PySlicingNode_postModuleInit();
PyBoraEngine_postModuleInit();
+
+ return module;
}
diff --git a/bora/src/PyDSlicingNode.cpp b/bora/src/PyDSlicingNode.cpp
index 7532fc76..0be8b518 100644
--- a/bora/src/PyDSlicingNode.cpp
+++ b/bora/src/PyDSlicingNode.cpp
@@ -62,12 +62,12 @@ extern "C" {
DSlicingNode* node = NULL;
HTRY
- if (not PyArg_ParseTuple( args,"SOO|O:DSlicingNode.create"
+ if (not PyArg_ParseTuple( args,"OOO|O:DSlicingNode.create"
, &pyInstance
, &pyCell
, &pyParameterRange
, &pyRoutingGauge ) ) {
- PyErr_SetString ( ConstructorError, "DSlicingNode.create(): Invalid/bad number of parameters ." );
+ PyErr_SetString ( ConstructorError, "DSlicingNode.create(): Invalid/bad number of parameters." );
return NULL;
}
if (not IsPyCell(pyCell)) {
diff --git a/crlcore/CMakeLists.txt b/crlcore/CMakeLists.txt
index b13f4331..58d2ccfb 100644
--- a/crlcore/CMakeLists.txt
+++ b/crlcore/CMakeLists.txt
@@ -19,20 +19,19 @@
set_cmake_policies()
check_distribution()
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
- setup_boost(program_options python regex wave)
+ setup_boost(program_options)
setup_qt()
if (USE_LIBBFD)
find_package(Libbfd)
endif()
find_package(LibXml2 REQUIRED)
- find_package(PythonLibs 2 REQUIRED)
+ find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)
find_package(LEFDEF)
find_package(OPENACCESS)
- find_package(VLSISAPD REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(Libexecinfo REQUIRED)
#include(UseLATEX)
diff --git a/crlcore/etc/common/__init__.py b/crlcore/etc/common/__init__.py
index 354e2683..dd85582b 100644
--- a/crlcore/etc/common/__init__.py
+++ b/crlcore/etc/common/__init__.py
@@ -54,6 +54,6 @@ def loadGdsLayers ( gdsLayersTable ):
basicLayer.setGds2Layer ( gdsiiLayer )
basicLayer.setGds2Datatype( gdsiiDatatype )
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
return
diff --git a/crlcore/etc/common/colors.py b/crlcore/etc/common/colors.py
index 0f82815c..bb924420 100644
--- a/crlcore/etc/common/colors.py
+++ b/crlcore/etc/common/colors.py
@@ -54,7 +54,7 @@ def toRGB ( color ):
, str(options[attribute])] )
# Try a predefined color lookup.
- if stdColors.has_key(color): return stdColors[color]
+ if color in stdColors: return stdColors[color]
# Try a RGB hexa: #RRGGBB.
if color[0] == '#':
diff --git a/crlcore/etc/common/devices.py b/crlcore/etc/common/devices.py
index c185a015..990554ed 100644
--- a/crlcore/etc/common/devices.py
+++ b/crlcore/etc/common/devices.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -26,23 +26,21 @@ def addDevice ( **kw ):
global tech
try:
- if kw.has_key('name'):
- devDesc = tech.addDeviceDescriptor( kw['name'] )
-
- if kw.has_key('spice'):
- devDesc.setSpiceFilePath( kw['spice'] )
-
- if kw.has_key('connectors'):
- for connector in kw['connectors']:
- devDesc.addConnector( connector )
- else:
- print WarningMessage( 'common.addDevice(): Missing connectors on device "%s".' % kw['name' ])
-
- if kw.has_key('layouts'):
- for layout in kw['layouts']:
- devDesc.addLayout( layout[0], layout[1] )
- else:
- print WarningMessage( 'common.addDevice(): Missing layouts on device "%s".' % kw['name' ])
- except Exception, e:
- helpers.io.catch( e )
+ if 'name' in kw:
+ devDesc = tech.addDeviceDescriptor( kw['name'] )
+ if 'spice' in kw: devDesc.setSpiceFilePath( kw['spice'] )
+ if 'connectors' in kw:
+ for connector in kw['connectors']:
+ devDesc.addConnector( connector )
+ else:
+ print( WarningMessage( 'common.addDevice(): Missing connectors on device "{}".' \
+ .format(kw['name'])))
+ if 'layouts' in kw:
+ for layout in kw['layouts']:
+ devDesc.addLayout( layout[0], layout[1] )
+ else:
+ print( WarningMessage( 'common.addDevice(): Missing layouts on device "{}".' \
+ .format( kw['name'] )))
+ except Exception as e:
+ helpers.io.catch( e )
return
diff --git a/crlcore/etc/common/kite.py b/crlcore/etc/common/kite.py
index c330b09a..bd9af3bd 100644
--- a/crlcore/etc/common/kite.py
+++ b/crlcore/etc/common/kite.py
@@ -31,10 +31,10 @@ layout.addTitle ( 'Kite', 'Kite - Detailed Router' )
layout.addParameter( 'Kite', 'kite.hTracksReservedLocal', 'Vert. Locally Reserved Tracks', 0 )
layout.addParameter( 'Kite', 'kite.vTracksReservedLocal', 'Hor. Locally Reserved Tracks' , 0 )
layout.addParameter( 'Kite', 'kite.eventsLimit' , 'Events Limit' , 0 )
-layout.addParameter( 'Kite', 'kite.ripupCost' , 'Ripup Cost' , 1, 1, Cfg.ParameterWidgetFlags.UseSpinBox )
+layout.addParameter( 'Kite', 'kite.ripupCost' , 'Ripup Cost' , 1, 1, Cfg.Parameter.Flags.UseSpinBox )
layout.addSection ( 'Kite', 'Ripup Limits', 1 )
-layout.addParameter( 'Kite', 'kite.strapRipupLimit' , 'Straps' , 1, 1, Cfg.ParameterWidgetFlags.UseSpinBox )
-layout.addParameter( 'Kite', 'kite.localRipupLimit' , 'Locals' , 1, 1, Cfg.ParameterWidgetFlags.UseSpinBox )
-layout.addParameter( 'Kite', 'kite.globalRipupLimit' , 'Globals' , 1, 1, Cfg.ParameterWidgetFlags.UseSpinBox )
-layout.addParameter( 'Kite', 'kite.longGlobalRipupLimit', 'Long Globals', 1, 1, Cfg.ParameterWidgetFlags.UseSpinBox )
+layout.addParameter( 'Kite', 'kite.strapRipupLimit' , 'Straps' , 1, 1, Cfg.Parameter.Flags.UseSpinBox )
+layout.addParameter( 'Kite', 'kite.localRipupLimit' , 'Locals' , 1, 1, Cfg.Parameter.Flags.UseSpinBox )
+layout.addParameter( 'Kite', 'kite.globalRipupLimit' , 'Globals' , 1, 1, Cfg.Parameter.Flags.UseSpinBox )
+layout.addParameter( 'Kite', 'kite.longGlobalRipupLimit', 'Long Globals', 1, 1, Cfg.Parameter.Flags.UseSpinBox )
layout.addRule ( 'Kite' )
diff --git a/crlcore/etc/common/misc.py b/crlcore/etc/common/misc.py
index 5956c137..6b1cd90f 100644
--- a/crlcore/etc/common/misc.py
+++ b/crlcore/etc/common/misc.py
@@ -1,13 +1,13 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
-# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/common/misc.py" |
# +-----------------------------------------------------------------+
diff --git a/crlcore/etc/common/patterns.py b/crlcore/etc/common/patterns.py
index a9f01cc9..64710130 100644
--- a/crlcore/etc/common/patterns.py
+++ b/crlcore/etc/common/patterns.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Universit 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -16,6 +16,7 @@
import sys
import math
import helpers
+from helpers import irange
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
@@ -67,10 +68,9 @@ class Pattern ( object ):
byte = byte << 1
if line[i] != ' ': byte += 1
hexasLSB += [ hex(byte)[2:] ]
-
# Convert in MSB mode. Invert the bytes by pairs.
self._hexa = ''
- for i in range(len(hexasLSB)/2):
+ for i in irange(len(hexasLSB)/2):
self._hexa += hexasLSB[i*2+1] + hexasLSB[i*2]
return self._hexa
@@ -79,7 +79,7 @@ class Pattern ( object ):
side = math.sqrt(4*len(self._hexa))
if pow(side,2) != 4*len(self._hexa):
- print '[ERROR] The pattern is not square (%d self._bits).' % (4*len(self._hexa))
+ print( '[ERROR] The pattern is not square ({} self._bits).'.format(4*len(self._hexa)))
return None
side /= 4
@@ -154,17 +154,17 @@ def add ( **keywords ):
global LUT
try:
- if not keywords.has_key('name'):
+ if not 'name' in keywords:
raise ErrorMessage(1,['patterns.add(): Malformed pattern, missing "name" argument.', str(keywords) ])
- if keywords.has_key('bits') and keywords.has_key('hexa'):
+ if ('bits' in keywords) and ('hexa' in keywords):
w = WarningMessage( 'patterns.add(): Pattern "%s" has both bits & hexa, ignoring hexa.' % keywords['name'] )
- print w
+ print( w )
del keywords['hexa']
LUT[ keywords['name'] ] = Pattern( **keywords )
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
return
@@ -173,7 +173,7 @@ def add ( **keywords ):
def toHexa ( key ):
global LUT
- if isinstance(key,int) or isinstance(key,long) or not LUT.has_key(key): return key
+ if isinstance(key,int) or not (key in LUT): return key
return LUT[key].hexa
diff --git a/crlcore/etc/node180/scn6m_deep_09/__init__.py b/crlcore/etc/node180/scn6m_deep_09/__init__.py
index 8f89f0ad..dc0af2cb 100644
--- a/crlcore/etc/node180/scn6m_deep_09/__init__.py
+++ b/crlcore/etc/node180/scn6m_deep_09/__init__.py
@@ -16,7 +16,7 @@
import Cfg
import helpers.io
helpers.io.vprint( 1, ' o Loading "node180.scn6m_deep_09" technology.' )
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
from Hurricane import DataBase
from CRL import System
diff --git a/crlcore/etc/node180/scn6m_deep_09/alliance.py b/crlcore/etc/node180/scn6m_deep_09/alliance.py
index aa0f81c8..b37e15f4 100644
--- a/crlcore/etc/node180/scn6m_deep_09/alliance.py
+++ b/crlcore/etc/node180/scn6m_deep_09/alliance.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,26 +14,23 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
import os
import os.path
from CRL import Environment
from CRL import AllianceFramework
-
allianceTop = None
-if os.environ.has_key('ALLIANCE_TOP'):
- allianceTop = os.environ['ALLIANCE_TOP']
- if not os.path.isdir(allianceTop):
- allianceTop = None
-
+if 'ALLIANCE_TOP' in os.environ:
+ allianceTop = os.environ['ALLIANCE_TOP']
+ if not os.path.isdir(allianceTop):
+ allianceTop = None
if not allianceTop: allianceTop = '/soc/alliance'
cellsTop = allianceTop+'/cells'
-
-af = AllianceFramework.get()
-env = af.getEnvironment()
+af = AllianceFramework.get()
+env = af.getEnvironment()
env.setSCALE_X ( 100 )
env.setCATALOG ( 'CATAL' )
diff --git a/crlcore/etc/node180/scn6m_deep_09/analog.py b/crlcore/etc/node180/scn6m_deep_09/analog.py
index eb7aca9d..22a76ef7 100644
--- a/crlcore/etc/node180/scn6m_deep_09/analog.py
+++ b/crlcore/etc/node180/scn6m_deep_09/analog.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,6 +14,6 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
#import common.analog
diff --git a/crlcore/etc/node180/scn6m_deep_09/devices.py b/crlcore/etc/node180/scn6m_deep_09/devices.py
index 03d8c2f7..3bd4e28d 100644
--- a/crlcore/etc/node180/scn6m_deep_09/devices.py
+++ b/crlcore/etc/node180/scn6m_deep_09/devices.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,16 +14,14 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
import common.devices
from common.devices import addDevice
-
chamsDir = helpers.sysConfDir + '/share/coriolis2/'
spiceDir = chamsDir + 'spice/'
-
addDevice( name = 'DifferentialPairBulkConnected'
, spice = spiceDir+'DiffPairBulkConnected.spi'
, connectors = ( 'D1', 'D2', 'G1', 'G2', 'S' )
diff --git a/crlcore/etc/node180/scn6m_deep_09/display.py b/crlcore/etc/node180/scn6m_deep_09/display.py
index 50e41566..a17e9dcb 100644
--- a/crlcore/etc/node180/scn6m_deep_09/display.py
+++ b/crlcore/etc/node180/scn6m_deep_09/display.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,9 +14,8 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
import common.display
-
common.display.createStyles( scale=0.5 )
diff --git a/crlcore/etc/node180/scn6m_deep_09/dtr_scn6m_deep_09.py b/crlcore/etc/node180/scn6m_deep_09/dtr_scn6m_deep_09.py
index 01ac943c..37c3d318 100644
--- a/crlcore/etc/node180/scn6m_deep_09/dtr_scn6m_deep_09.py
+++ b/crlcore/etc/node180/scn6m_deep_09/dtr_scn6m_deep_09.py
@@ -9,7 +9,7 @@
# Used revision 8.00 of May 11, 2009.
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
from Hurricane import DbU
from helpers.analogtechno import Length
diff --git a/crlcore/etc/node180/scn6m_deep_09/etesian.py b/crlcore/etc/node180/scn6m_deep_09/etesian.py
index e438773d..b293d47f 100644
--- a/crlcore/etc/node180/scn6m_deep_09/etesian.py
+++ b/crlcore/etc/node180/scn6m_deep_09/etesian.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,6 +14,6 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
import common.etesian
diff --git a/crlcore/etc/node180/scn6m_deep_09/kite.py b/crlcore/etc/node180/scn6m_deep_09/kite.py
index 68166f80..358f4529 100644
--- a/crlcore/etc/node180/scn6m_deep_09/kite.py
+++ b/crlcore/etc/node180/scn6m_deep_09/kite.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -15,7 +15,7 @@
import Cfg
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
from Hurricane import DataBase
from CRL import AllianceFramework
@@ -85,6 +85,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
, l(0) # track offset from AB.
, l(10) # track pitch.
, l(3) # wire width.
+ , l(3) # perpandicular wire width.
, l(2) # VIA side (that is VIA12).
, l(7) # obstacle dW.
) )
@@ -97,6 +98,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
, l(0) # track offset from AB.
, l(10) # track pitch.
, l(3) # wire width.
+ , l(3) # perpandicular wire width.
, l(2) # VIA side (that is VIA23).
, l(8) # obstacle dW.
) )
@@ -109,6 +111,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta
, l(0) # track offset from AB.
, l(10) # track pitch.
, l(3) # wire width.
+ , l(3) # perpandicular wire width.
, l(2) # VIA side (that is VIA34).
, l(8) # obstacle dW.
) )
@@ -121,6 +124,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta
, l(0) # track offset from AB.
, l(15) # track pitch.
, l(6) # wire width.
+ , l(6) # perpandicular wire width.
, l(4) # VIA side (that is VIA23).
, l(8) # obstacle dW.
) )
@@ -133,6 +137,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL5') # meta
, l(0) # track offset from AB.
, l(15) # track pitch.
, l(6) # wire width.
+ , l(6) # perpandicular wire width.
, l(4) # VIA side (that is VIA23).
, l(8) # obstacle dW.
) )
@@ -145,6 +150,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL6') # meta
, l(0) # track offset from AB.
, l(15) # track pitch.
, l(6) # wire width.
+ , l(6) # perpandicular wire width.
, l(4) # VIA side (that is VIA23).
, l(8) # obstacle dW.
) )
@@ -161,6 +167,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
, l(0) # track offset from AB.
, l(10) # track pitch.
, l(3) # wire width.
+ , l(3) # perpandicular wire width.
, l(2) # VIA side (that is VIA12).
, l(7) # obstacle dW.
) )
@@ -173,6 +180,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
, l(0) # track offset from AB.
, l(10) # track pitch.
, l(3) # wire width.
+ , l(3) # perpandicular wire width.
, l(2) # VIA side (that is VIA23).
, l(8) # obstacle dW.
) )
@@ -185,6 +193,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta
, l(0) # track offset from AB.
, l(8) # track pitch.
, l(3) # wire width.
+ , l(3) # perpandicular wire width.
, l(2) # VIA side (that is VIA12).
, l(8) # obstacle dW.
) )
@@ -197,6 +206,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta
, l(0) # track offset from AB.
, l(10) # track pitch.
, l(3) # wire width.
+ , l(3) # perpandiuclar wire width.
, l(2) # VIA side (that is VIA23).
, l(8) # obstacle dW.
) )
@@ -213,6 +223,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
, l(0) # track offset from AB.
, l(10) # track pitch.
, l(3) # wire width.
+ , l(3) # perpandicular wire width.
, l(3) # VIA side (that is VIA12).
, l(7) # obstacle dW.
) )
@@ -225,6 +236,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
, l(0) # track offset from AB.
, l(10) # track pitch.
, l(3) # wire width.
+ , l(3) # perpandicular wire width.
, l(3) # VIA side (that is VIA23).
, l(8) # obstacle dW.
) )
diff --git a/crlcore/etc/node180/scn6m_deep_09/misc.py b/crlcore/etc/node180/scn6m_deep_09/misc.py
index 64235013..e283a180 100644
--- a/crlcore/etc/node180/scn6m_deep_09/misc.py
+++ b/crlcore/etc/node180/scn6m_deep_09/misc.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,6 +14,6 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
import common.misc
diff --git a/crlcore/etc/node180/scn6m_deep_09/patterns.py b/crlcore/etc/node180/scn6m_deep_09/patterns.py
index 931bf619..55de360c 100644
--- a/crlcore/etc/node180/scn6m_deep_09/patterns.py
+++ b/crlcore/etc/node180/scn6m_deep_09/patterns.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,6 +14,6 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
import common.patterns
diff --git a/crlcore/etc/node180/scn6m_deep_09/plugins.py b/crlcore/etc/node180/scn6m_deep_09/plugins.py
index 9411a1f0..e1f04729 100644
--- a/crlcore/etc/node180/scn6m_deep_09/plugins.py
+++ b/crlcore/etc/node180/scn6m_deep_09/plugins.py
@@ -15,7 +15,7 @@
import Cfg
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
from helpers import l, u, n
diff --git a/crlcore/etc/node180/scn6m_deep_09/stratus1.py b/crlcore/etc/node180/scn6m_deep_09/stratus1.py
index b68cc742..fec2ddba 100644
--- a/crlcore/etc/node180/scn6m_deep_09/stratus1.py
+++ b/crlcore/etc/node180/scn6m_deep_09/stratus1.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Universié 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -15,10 +15,9 @@
import Cfg
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
import common.stratus1
-
Cfg.getParamString( "stratus1.format" ).setString( "vst" )
Cfg.getParamString( "stratus1.simulator" ).setString( "asimut" )
diff --git a/crlcore/etc/node180/scn6m_deep_09/technology.py b/crlcore/etc/node180/scn6m_deep_09/technology.py
index be133a4e..4bce45ef 100644
--- a/crlcore/etc/node180/scn6m_deep_09/technology.py
+++ b/crlcore/etc/node180/scn6m_deep_09/technology.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,19 +14,17 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
-
-from helpers import l, u, n
-from Hurricane import DbU
-from Hurricane import DataBase
-from Hurricane import Technology
-
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
+from helpers import l, u, n
+from Hurricane import DbU
+from Hurricane import DataBase
+from Hurricane import Technology
tech = DataBase.getDB().getTechnology()
if tech:
- print WarningMessage( 'cmos.technology: Technology already exists, "%s"' % tech.getName() )
+ print( WarningMessage( 'cmos.technology: Technology already exists, "{}"'.format(tech.getName()) ))
else:
- tech = Technology.create( DataBase.getDB(), 'scn6m_deep_09' )
+ tech = Technology.create( DataBase.getDB(), 'scn6m_deep_09' )
DbU.setPrecision ( 2 )
DbU.setPhysicalsPerGrid ( 0.005, DbU.UnitPowerMicro )
@@ -34,7 +32,6 @@ DbU.setGridsPerLambda ( 18 )
DbU.setSymbolicSnapGridStep( DbU.fromLambda( 1.0) )
DbU.setPolygonStep ( DbU.fromGrid ( 9.0) )
-
import common
from common.technology import *
diff --git a/crlcore/etc/node45/freepdk45/alliance.py b/crlcore/etc/node45/freepdk45/alliance.py
index 4f0a978a..96823b0b 100644
--- a/crlcore/etc/node45/freepdk45/alliance.py
+++ b/crlcore/etc/node45/freepdk45/alliance.py
@@ -23,7 +23,7 @@ from CRL import AllianceFramework
allianceTop = None
-if os.environ.has_key('ALLIANCE_TOP'):
+if 'ALLIANCE_TOP' in os.environ:
allianceTop = os.environ['ALLIANCE_TOP']
if not os.path.isdir(allianceTop):
allianceTop = None
diff --git a/crlcore/etc/node45/freepdk45/technology.py b/crlcore/etc/node45/freepdk45/technology.py
index 2e9bf3c0..549cd7ef 100644
--- a/crlcore/etc/node45/freepdk45/technology.py
+++ b/crlcore/etc/node45/freepdk45/technology.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,7 +14,7 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
from helpers import l, u, n
from Hurricane import DbU
@@ -36,7 +36,7 @@ def setEnclosures ( layer, subLayer, enclosures ):
tech = DataBase.getDB().getTechnology()
if tech:
- print WarningMessage( 'cmos.technology: Technology already exists, "%s"' % tech.getName() )
+ print( WarningMessage( 'cmos.technology: Technology already exists, "{}"'.format(tech.getName()) ))
else:
tech = Technology.create( DataBase.getDB(), 'freepdk45' )
diff --git a/crlcore/etc/node600/phenitec/alliance.py b/crlcore/etc/node600/phenitec/alliance.py
index 1989a623..56742d99 100644
--- a/crlcore/etc/node600/phenitec/alliance.py
+++ b/crlcore/etc/node600/phenitec/alliance.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,7 +14,7 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
import os
import os.path
@@ -23,21 +23,19 @@ from CRL import AllianceFramework
allianceTop = None
-if os.environ.has_key('ALLIANCE_TOP'):
- allianceTop = os.environ['ALLIANCE_TOP']
- if not os.path.isdir(allianceTop):
- allianceTop = None
-
+if 'ALLIANCE_TOP' in os.environ:
+ allianceTop = os.environ['ALLIANCE_TOP']
+ if not os.path.isdir(allianceTop):
+ allianceTop = None
if not allianceTop: allianceTop = '/soc/alliance'
cellsTop = None
-if os.environ.has_key('CELLS_TOP'):
- cellsTop = os.environ['CELLS_TOP']
- if not os.path.isdir(cellsTop):
- cellsTop = None
-
+if 'CELLS_TOP' in os.environ:
+ cellsTop = os.environ['CELLS_TOP']
+ if not os.path.isdir(cellsTop):
+ cellsTop = None
if not cellsTop:
- cellsTop = allianceTop+'/cells'
+ cellsTop = allianceTop+'/cells'
af = AllianceFramework.get()
env = af.getEnvironment()
diff --git a/crlcore/etc/node600/phenitec/technology.py b/crlcore/etc/node600/phenitec/technology.py
index fc40f049..8a3bbb54 100644
--- a/crlcore/etc/node600/phenitec/technology.py
+++ b/crlcore/etc/node600/phenitec/technology.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,19 +14,19 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
-from helpers import l, u, n
-from Hurricane import DbU
-from Hurricane import DataBase
-from Hurricane import Technology
+from helpers import l, u, n
+from Hurricane import DbU
+from Hurricane import DataBase
+from Hurricane import Technology
tech = DataBase.getDB().getTechnology()
if tech:
- print WarningMessage( 'cmos.technology: Technology already exists, "%s"' % tech.getName() )
+ print( WarningMessage( 'cmos.technology: Technology already exists, "{}"'format(tech.getName()) ))
else:
- tech = Technology.create( DataBase.getDB(), 'phenitec06' )
+ tech = Technology.create( DataBase.getDB(), 'phenitec06' )
DbU.setPrecision ( 2 )
DbU.setPhysicalsPerGrid ( 0.002, DbU.UnitPowerMicro )
diff --git a/crlcore/etc/symbolic/cmos/alliance.py b/crlcore/etc/symbolic/cmos/alliance.py
index 368ea61f..1024ab15 100644
--- a/crlcore/etc/symbolic/cmos/alliance.py
+++ b/crlcore/etc/symbolic/cmos/alliance.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -16,23 +16,21 @@
import os
import os.path
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
from CRL import Environment
from CRL import AllianceFramework
allianceTop = None
-if os.environ.has_key('ALLIANCE_TOP'):
- allianceTop = os.environ['ALLIANCE_TOP']
- if not os.path.isdir(allianceTop):
- allianceTop = None
-
+if 'ALLIANCE_TOP' in os.environ:
+ allianceTop = os.environ['ALLIANCE_TOP']
+ if not os.path.isdir(allianceTop):
+ allianceTop = None
if not allianceTop: allianceTop = '/soc/alliance'
cellsTop = allianceTop+'/cells'
-
-af = AllianceFramework.get()
-env = af.getEnvironment()
+af = AllianceFramework.get()
+env = af.getEnvironment()
env.setSCALE_X ( 100 )
env.setCATALOG ( 'CATAL' )
diff --git a/crlcore/etc/symbolic/cmos/technology.py b/crlcore/etc/symbolic/cmos/technology.py
index d09b4fb8..93160fde 100644
--- a/crlcore/etc/symbolic/cmos/technology.py
+++ b/crlcore/etc/symbolic/cmos/technology.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -16,7 +16,7 @@
from helpers import l, u, n
from helpers.io import WarningMessage
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
from Hurricane import DbU
from Hurricane import DataBase
@@ -25,9 +25,9 @@ from Hurricane import Technology
tech = DataBase.getDB().getTechnology()
if tech:
- print WarningMessage( 'cmos.technology: Technology already exists, "%s"' % tech.getName() )
+ print( WarningMessage( 'cmos.technology: Technology already exists, "{}"'.format(tech.getName()) ))
else:
- tech = Technology.create( DataBase.getDB(), 'cmos' )
+ tech = Technology.create( DataBase.getDB(), 'cmos' )
DbU.setPrecision ( 2 )
DbU.setPhysicalsPerGrid ( 0.5, DbU.UnitPowerMicro )
diff --git a/crlcore/etc/symbolic/cmos45/alliance.py b/crlcore/etc/symbolic/cmos45/alliance.py
index d8a1201e..5f89e95a 100644
--- a/crlcore/etc/symbolic/cmos45/alliance.py
+++ b/crlcore/etc/symbolic/cmos45/alliance.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) orbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -16,24 +16,21 @@
import os
import os.path
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
-
-from CRL import Environment
-from CRL import AllianceFramework
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
+from CRL import Environment
+from CRL import AllianceFramework
allianceTop = None
-if os.environ.has_key('ALLIANCE_TOP'):
- allianceTop = os.environ['ALLIANCE_TOP']
- if not os.path.isdir(allianceTop):
- allianceTop = None
-
+if 'ALLIANCE_TOP' in os.environ:
+ allianceTop = os.environ['ALLIANCE_TOP']
+ if not os.path.isdir(allianceTop):
+ allianceTop = None
if not allianceTop: allianceTop = '/soc/alliance'
cellsTop = allianceTop+'/cells'
-
-af = AllianceFramework.get()
-env = af.getEnvironment()
+af = AllianceFramework.get()
+env = af.getEnvironment()
env.setSCALE_X ( 100 )
env.setCATALOG ( 'CATAL' )
diff --git a/crlcore/etc/symbolic/cmos45/technology.py b/crlcore/etc/symbolic/cmos45/technology.py
index 738ee7d4..26c589e6 100644
--- a/crlcore/etc/symbolic/cmos45/technology.py
+++ b/crlcore/etc/symbolic/cmos45/technology.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,7 +14,7 @@
import helpers.io
-helpers.io.vprint( 2, ' - "%s".' % helpers.truncPath(__file__) )
+helpers.io.vprint( 2, ' - "{}".'.format(helpers.truncPath(__file__)) )
from helpers import l, u, n
from Hurricane import DbU
@@ -24,9 +24,9 @@ from Hurricane import Technology
tech = DataBase.getDB().getTechnology()
if tech:
- print WarningMessage( 'cmos.technology: Technology already exists, "%s"' % tech.getName() )
+ print( WarningMessage( 'cmos.technology: Technology already exists, "{}"'.format(tech.getName()) ))
else:
- tech = Technology.create( DataBase.getDB(), 'cmos45' )
+ tech = Technology.create( DataBase.getDB(), 'cmos45' )
DbU.setPrecision ( 2 )
DbU.setPhysicalsPerGrid ( 0.0025, DbU.UnitPowerMicro )
diff --git a/crlcore/python/CMakeLists.txt b/crlcore/python/CMakeLists.txt
index a4735263..5a4697a2 100644
--- a/crlcore/python/CMakeLists.txt
+++ b/crlcore/python/CMakeLists.txt
@@ -1,7 +1,7 @@
- install( FILES helpers/__init__.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers )
- install( FILES helpers/io.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers )
- install( FILES helpers/utils.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers )
- install( FILES helpers/overlay.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers )
- install( FILES helpers/analogtechno.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers )
- install( FILES helpers/technology.py DESTINATION ${PYTHON_SITE_PACKAGES}/crlcore/helpers )
+ install( FILES helpers/__init__.py DESTINATION ${Python_CORIOLISLIB}/crlcore/helpers )
+ install( FILES helpers/io.py DESTINATION ${Python_CORIOLISLIB}/crlcore/helpers )
+ install( FILES helpers/utils.py DESTINATION ${Python_CORIOLISLIB}/crlcore/helpers )
+ install( FILES helpers/overlay.py DESTINATION ${Python_CORIOLISLIB}/crlcore/helpers )
+ install( FILES helpers/analogtechno.py DESTINATION ${Python_CORIOLISLIB}/crlcore/helpers )
+ install( FILES helpers/technology.py DESTINATION ${Python_CORIOLISLIB}/crlcore/helpers )
diff --git a/crlcore/python/helpers/__init__.py b/crlcore/python/helpers/__init__.py
index 682e1132..f88df75b 100644
--- a/crlcore/python/helpers/__init__.py
+++ b/crlcore/python/helpers/__init__.py
@@ -1,7 +1,8 @@
+
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2012-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -17,12 +18,11 @@
# rather than an ordinary directory, thus enabling the uses of the
# 'dot' notation in import.
-#print 'helpers.__init__()'
-
import sys
import os
import os.path
import re
+import math
import traceback
quiet = False
@@ -45,13 +45,23 @@ import CRL
import helpers.io
+def irange ( value ):
+ if isinstance(value,int): return range(value)
+ if isinstance(value,float):
+ r,i = math.modf( value )
+ if r != 0.0:
+ print( '[WARNING] helpers.irange(): value={} is not an integer (truncated).'\
+ .format(value) )
+ return range(int( value ))
+
+
def stype ( o ): return str(type(o)).split("'")[1]
def isderived ( derived, base ):
btype = base.mro()[0]
for dtype in derived.mro():
- if dtype == btype: return True
+ if dtype == btype: return True
return False
@@ -60,20 +70,15 @@ def truncPath ( path, maxlength=80 ):
components = path.split(os.sep)
trunc = ''
for i in range(-1,-len(components),-1):
- if len(trunc)+len(components[i]) >= maxlength: break
- if not len(trunc): trunc = components[i]
- else: trunc = os.path.join( components[i], trunc )
-
+ if len(trunc)+len(components[i]) >= maxlength: break
+ if not len(trunc): trunc = components[i]
+ else: trunc = os.path.join( components[i], trunc )
return '...' + os.sep + trunc
def textStackTrace ( trace, showIndent=True, scriptPath=None ):
- #for entry in traceback.format_list( trace ):
- # print entry,
-
indent = ''
if showIndent: indent = ' '
-
s = ''
if scriptPath:
if len(scriptPath) > 100:
@@ -82,7 +87,7 @@ def textStackTrace ( trace, showIndent=True, scriptPath=None ):
if showIndent: s += '[ERROR] '
s += 'An exception occured while loading the Python script module:\n'
- s += indent + '\"%s\"\n' % (filename)
+ s += indent + '\"{}\"\n' % (filename)
s += indent + 'You should check for simple python errors in this module.\n\n'
s += indent + 'Python stack trace:\n'
@@ -92,13 +97,13 @@ def textStackTrace ( trace, showIndent=True, scriptPath=None ):
if len(filename) > 58:
filename = filename[-58:]
filename = '.../' + filename[ filename.find('/')+1 : ]
- #s += indent + '[%02d] %45s:%-5d in \"%s()\"' % ( maxdepth-depth-1, filename, line, function )
- s += indent + '#%d in %25s() at %s:%d\n' % ( depth, function, filename, line )
+ #s += indent + '[%02d] %45s:%-5d in \"{}()\"' % ( maxdepth-depth-1, filename, line, function )
+ s += indent + '#{} in {:>25}() at {}:{}\n'.format( depth, function, filename, line )
return s
def showStackTrace ( trace ):
- print textStackTrace( trace, True )
+ print( textStackTrace( trace, True ))
return
@@ -111,24 +116,24 @@ def textPythonTrace ( scriptPath=None, e=None, tryContinue=True ):
else:
filename = scriptPath
s += '[ERROR] An exception occured while loading the Python script module:\n'
- s += ' \"%s\"\n' % (filename)
+ s += ' \"{}\"\n'.format(filename)
s += ' You should check for simple python errors in this module.\n'
-
- if isinstance(e,helpers.io.ErrorMessage): trace = e.trace
- else: trace = traceback.extract_tb( sys.exc_info()[2] )
- s += textStackTrace( trace )
-
- if e:
- s += ' Error was:\n'
- s += ' %s\n' % e
-
+ if isinstance(e,helpers.io.ErrorMessage):
+ trace = e.trace
+ s += textStackTrace( trace )
+ if e:
+ s += ' Error was:\n'
+ s += ' {}\n'.format(e)
+ else:
+ #trace = traceback.extract_tb( sys.exc_info()[2] )
+ print( traceback.format_exc() )
if tryContinue:
s += ' Trying to continue anyway...'
return s
def showPythonTrace ( scriptPath=None, e=None, tryContinue=True ):
- print textPythonTrace( scriptPath, e, tryContinue )
+ print( textPythonTrace( scriptPath, e, tryContinue ))
return
@@ -145,7 +150,7 @@ class Dots ( object ):
sys.stdout.write(self._header)
else:
if not (self._count % self._width):
- sys.stdout.write("\n%s"%self._header)
+ sys.stdout.write("\n{}".format(self._header))
sys.stdout.write(".")
sys.stdout.flush()
@@ -216,10 +221,10 @@ class Trace ( object ):
sys.stderr.write( message[1:] )
else:
sys.stderr.write( message )
- sys.stderr.flush()
for f in sflags[1]:
if f == '+': self._tab.inc()
if f == '-': self._tab.dec()
+ sys.stderr.flush()
return
@@ -244,16 +249,13 @@ def dots ( ttyWidth, leftText, rightText ):
def overload ( defaultParameters, parameters ):
overloads = {}
overloadParameters = []
-
for parameter in parameters:
overloads[ parameter[0] ] = parameter
-
for parameter in defaultParameters:
- if overloads.has_key(parameter[0]):
+ if parameter[0] in overloads:
overloadParameters.append( overloads[parameter[0]] )
else:
overloadParameters.append( parameter )
-
return tuple(overloadParameters)
@@ -276,32 +278,28 @@ def initTechno ( argQuiet ):
global technoDir
global techno
- quiet = argQuiet
-
+ quiet = argQuiet
technoFiles = [ sysConfDir+'/techno.conf' ]
if os.getenv('HOME'):
technoFiles += [ os.getenv('HOME')+'/.coriolis2/techno.py' ]
technoFiles += [ os.getcwd()+'/.coriolis2/techno.py' ]
-
technoFiles.reverse()
for technoFile in technoFiles:
if os.path.isfile(technoFile):
- if not quiet: print ' - Loading \"%s\".' % truncPath(technoFile)
- execfile(technoFile,moduleGlobals)
+ if not quiet: print( ' - Loading "{}".'.format( truncPath(technoFile) ))
+ exec(open( technoFile ).read()) # moduleGlobals
break
- if moduleGlobals.has_key('technology'):
+ if 'technology' in moduleGlobals:
techno = technology
else:
- print '[WARNING] The technology is not set. Using <%s>.' % techno
-
- if moduleGlobals.has_key('NdaDirectory'):
+ print( '[WARNING] The technology is not set. Using "{}".'.format( techno ))
+ if 'NdaDirectory' in moduleGlobals:
ndaDir = NdaDirectory
ndaConfDir = os.path.join( NdaDirectory, 'etc/coriolis2' )
else:
ndaConfDir = sysConfDir
-
technoDir = os.path.join( ndaConfDir, techno )
- if not quiet: print ' - Technology: %s.' % techno
+ if not quiet: print( ' - Technology: {}.'.format( techno ))
unitsLambda = True
@@ -314,7 +312,7 @@ def setNdaTopDir ( ndaTopDirArg ):
global ndaTopDir
if not os.path.isdir(ndaTopDirArg):
- print helpers.io.WarningMessage( 'helpers.setNdaTopDir(): Directory "%s" does not exists.' % ndaTopDirArg )
+ print( helpers.io.WarningMessage( 'helpers.setNdaTopDir(): Directory "{}" does not exists.'.format( ndaTopDirArg )))
else:
ndaTopDir = ndaTopDirArg
sys.path.append( os.path.join(ndaTopDir,'etc/coriolis2') )
@@ -331,18 +329,14 @@ def staticInitialization ( quiet=False ):
global unitsLambda
if sysConfDir != None:
- #if not quiet: print ' o helpers.staticInitialization() Already run, exit.'
return
-
reSysConfDir = re.compile(r'.*etc\/coriolis2')
- if not quiet: print ' o Locating configuration directory:'
-
+ if not quiet: print( ' o Locating configuration directory:' )
for path in sys.path:
if reSysConfDir.match(path):
sysConfDir = path
- if not quiet: print ' - "%s"' % sysConfDir
+ if not quiet: print( ' - "{}"'.format( sysConfDir ))
break
-
if not sysConfDir:
coriolisTop = os.getenv('CORIOLIS_TOP')
if coriolisTop == '/usr':
@@ -352,8 +346,7 @@ def staticInitialization ( quiet=False ):
else:
raise ErrorMessage( 1, [ 'Cannot locate the directoty holding the configuration files.'
, 'The path is something ending by <.../etc/coriolis2>.'] )
-
- if not quiet: print ' - "%s"' % sysConfDir
+ if not quiet: print( ' - "{}"'.format( sysConfDir ))
initTechno( quiet )
return
@@ -362,18 +355,14 @@ def setSysConfDir ( quiet=False ):
global sysConfDir
if sysConfDir != None:
- #if not quiet: print ' o helpers.staticInitialization() Already run, exit.'
return
-
reSysConfDir = re.compile(r'.*etc\/coriolis2')
- if not quiet: print ' o Locating configuration directory:'
-
+ if not quiet: print( ' o Locating configuration directory:' )
for path in sys.path:
if reSysConfDir.match(path):
sysConfDir = path
- if not quiet: print ' - "%s"' % sysConfDir
+ if not quiet: print( ' - "{}"'.format( sysConfDir ))
break
-
if not sysConfDir:
coriolisTop = os.getenv('CORIOLIS_TOP')
if coriolisTop == '/usr':
@@ -383,8 +372,7 @@ def setSysConfDir ( quiet=False ):
else:
raise ErrorMessage( 1, [ 'Cannot locate the directoty holding the configuration files.'
, 'The path is something ending by <.../etc/coriolis2>.'] )
-
- if not quiet: print ' - "%s"' % sysConfDir
+ if not quiet: print( ' - "{}"'.format( sysConfDir ))
sys.path.append( sysConfDir )
return
@@ -415,40 +403,37 @@ setSysConfDir( False )
def unloadUserSettings ():
global confModules
- print ' o Unloading Python user\'s modules.'
+ print( ' o Unloading Python user\'s modules.' )
for moduleName in confModules:
- refcount = sys.getrefcount( sys.modules[moduleName] )
- warning = ''
- if refcount > 3:
- warning = '(NOTE: More than 3 refcount %d)' % refcount
- #print helpers.io.WarningMessage( [ 'Configuration module "%s" has more than 3 references (%d)".' \
- # % (moduleName,refcount)
- # , 'May be unable to unload it from the Python process.'
- # ] )
- print ' - %-34s %-35s' % ('"%s".'%moduleName, warning)
- del sys.modules[ moduleName ]
+ refcount = sys.getrefcount( sys.modules[moduleName] )
+ warning = ''
+ if refcount > 3:
+ warning = '(NOTE: More than 3 refcount %d)' % refcount
+ #print( helpers.io.WarningMessage( [ 'Configuration module "{}" has more than 3 references ({})".' \
+ # .format(moduleName,refcount)
+ # , 'May be unable to unload it from the Python process.'
+ # ] ))
+ print( ' - {:-34} {:-35}'.format( '"{}".'.format(moduleName), warning ))
+ del sys.modules[ moduleName ]
confModules = set()
return
def loadUserSettings ():
rvalue = False
-
if os.path.isfile('./coriolis2/settings.py'):
if os.path.isfile('./coriolis2/__init__.py'):
sys.path.insert( 0, os.getcwd() )
import coriolis2.settings
rvalue = True
else:
- print helpers.io.WarningMessage( [ 'User\'s settings directory "%s" exists, but do not contains "__init__.py".' % './coriolis2/'
- , '(path:"%s")' % os.path.abspath(os.getcwd())
- ] )
+ print( helpers.io.WarningMessage( [ 'User\'s settings directory "{}" exists, but do not contains "__init__.py".'.format( './coriolis2/' )
+ , '(path:"{}")'.format( os.path.abspath(os.getcwd()) )
+ ] ))
else:
import symbolic.cmos
-
tagConfModules()
-
return rvalue
@@ -461,13 +446,9 @@ def tagConfModules ():
if not (moduleName in sysModules):
confModules.add( moduleName )
- #print 'Configuration modules:'
- #for moduleName in confModules:
- # print '-', moduleName
-
def resetCoriolis ():
- print ' o Full reset of Coriolis/Hurricane databases.'
+ print( ' o Full reset of Coriolis/Hurricane databases.' )
CRL.AllianceFramework.get().destroy()
Viewer.Graphics.get().clear()
Hurricane.DataBase.getDB().destroy()
diff --git a/crlcore/python/helpers/analogtechno.py b/crlcore/python/helpers/analogtechno.py
index 0bb6b4fb..a7f0207f 100644
--- a/crlcore/python/helpers/analogtechno.py
+++ b/crlcore/python/helpers/analogtechno.py
@@ -1,7 +1,8 @@
+
# -*- Mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2015-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2015-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,7 +15,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import os
import os.path
import sys
@@ -126,7 +126,7 @@ def _loadAnalogTechno ( techno, ruleTable ):
, 0 )
else:
rule.addValue( valueToDbU(entry[3], unit, entry[4]), 0 )
- except Exception, e:
+ except Exception as e:
e = ErrorMessage( 1, e )
e.addMessage( 'In {}: at index {}.'.format(technoFile,entryNo) )
print( str(e) )
diff --git a/crlcore/python/helpers/io.py b/crlcore/python/helpers/io.py
index e08251b6..f9a7d8ef 100644
--- a/crlcore/python/helpers/io.py
+++ b/crlcore/python/helpers/io.py
@@ -1,7 +1,8 @@
+
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2012-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -13,7 +14,6 @@
# | Python : "./crlcore/helpers/io.py" |
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import os
import os.path
@@ -37,7 +37,7 @@ try:
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QKeySequence
-except Exception, e:
+except Exception as e:
try:
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QSizePolicy
@@ -56,7 +56,7 @@ except Exception, e:
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QAction
from PyQt5.QtGui import QKeySequence
- except e:
+ except Exception:
print( '[ERROR] helpers.io, neither PyQt4 nor PyQt5 is available.' )
sys.exit( 1 )
import Cfg
@@ -183,10 +183,9 @@ class ErrorMessage ( Exception ):
elif len(arguments) > 1:
sys.stdout.flush()
text = list(arguments)
-
if text:
self.errors = []
- while len(text[0]) == 0: del text[0]
+ while len(text) == 0: del text[0]
lstrip = 0
if text[0].startswith('[ERROR]'): lstrip = 8
@@ -203,7 +202,6 @@ class ErrorMessage ( Exception ):
def __str__ ( self ):
if not isinstance(self.errors,list):
return "[ERROR] %s" % self.errors
-
formatted = "\n"
for i in range(len(self.errors)):
if i == 0: formatted += "[ERROR] %s" % self.errors[i]
@@ -213,7 +211,6 @@ class ErrorMessage ( Exception ):
def getLinesAsString ( self ):
if not isinstance(self.errors,list): return self.errors
-
lines = ''
for line in self.errors: lines += line + '\n'
return lines
@@ -256,13 +253,10 @@ def catch ( errorObject ):
em = ErrorMessage( 2, errorObject )
em.trace = traceback.extract_tb( sys.exc_info()[2] )
#em.scriptPath = __file__
-
print( em )
print( helpers.textStackTrace( em.trace, True, em.scriptPath ) )
-
if Viewer.Graphics.get().isEnabled():
tryCont = ErrorWidget( em ).exec_()
-
if UpdateSession.getStackSize() > 0: UpdateSession.close()
return
diff --git a/crlcore/python/helpers/overlay.py b/crlcore/python/helpers/overlay.py
index 6428bfef..1161f14c 100644
--- a/crlcore/python/helpers/overlay.py
+++ b/crlcore/python/helpers/overlay.py
@@ -1,7 +1,7 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2012-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -25,7 +25,6 @@ Contains:
* ``overlay.CfgCache`` : A cache for Cfg parameters.
"""
-from __future__ import print_function
import Cfg
import Hurricane
@@ -80,9 +79,6 @@ class Configuration:
Cfg.getParamEnumerate(attr).setInt( val )
else:
Cfg.getParamInt(attr).setInt( val )
- elif isinstance(val, long):
- p = Cfg.getParamInt( attr ) # all params have a type
- p.setInt( val )
elif isinstance(val, float):
p = Cfg.getParamDouble( attr ).setDouble( val )
elif '%' in val:
@@ -138,7 +134,6 @@ class CachedParameter ( object ):
if len(self.vEnum): p = Cfg.getParamEnumerate( self.path )
elif isinstance(self.v,bool ): p = Cfg.getParamBool ( self.path )
elif isinstance(self.v,int ): p = Cfg.getParamInt ( self.path )
- elif isinstance(self.v,long ): p = Cfg.getParamInt ( self.path )
elif isinstance(self.v,float): p = Cfg.getParamDouble ( self.path )
else: p = Cfg.getParamString ( self.path )
if p.type == Cfg.Parameter.Type.Enumerate: p.setInt ( self.v )
@@ -281,7 +276,7 @@ class CfgCache ( object ):
vEnum = None
if isinstance(v,list ): vRange = v; v = None
if isinstance(v,tuple): vEnum = v; v = None
- if not self._rattr.has_key(attr):
+ if not attr in self._rattr:
self._rattr[ attr ] = CachedParameter( self._path+'.'+attr, v )
if vRange is not None: self._rattr[ attr ].vRange = vRange
elif vEnum is not None: self._rattr[ attr ].vEnum = vEnum
@@ -292,7 +287,7 @@ class CfgCache ( object ):
Get an attribute, if it doesn't exists, then we are in an intermediate
level like ``katana``, so create a new sub CfgCache for that attribute.
"""
- if not self._rattr.has_key(attr):
+ if not attr in self._rattr:
path = self._path+'.'+attr if len(self._path) else attr
self._rattr[attr] = CfgCache( path, self._priority )
if isinstance(self._rattr[attr],CachedParameter):
@@ -300,7 +295,7 @@ class CfgCache ( object ):
return self._rattr[attr]
def _hasCachedParam ( self, elements ):
- if not self._rattr.has_key(elements[0]):
+ if not elements[0] in self._rattr:
return False
if len(elements) == 1:
return True
diff --git a/crlcore/python/helpers/technology.py b/crlcore/python/helpers/technology.py
index ee6f1ed5..4150b643 100644
--- a/crlcore/python/helpers/technology.py
+++ b/crlcore/python/helpers/technology.py
@@ -1,7 +1,7 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -17,7 +17,6 @@
Some helpers to create or load a technology and it's libraries.
"""
-from __future__ import print_function
from Hurricane import DataBase, Library, BasicLayer, Layer, ViaLayer
diff --git a/crlcore/python/helpers/utils.py b/crlcore/python/helpers/utils.py
index ac1f48c3..19ea36e6 100644
--- a/crlcore/python/helpers/utils.py
+++ b/crlcore/python/helpers/utils.py
@@ -1,7 +1,7 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -21,7 +21,6 @@ Miscellaeous utilities. Contains:
and methods.
"""
-from __future__ import print_function
import types
import inspect
import functools
@@ -82,15 +81,15 @@ def classdecorator ( cls ):
def isprop ( attr ): return isinstance( attr, property )
def wrappedSetattr ( self, attr, v ):
- if attr != '_baseClass' and self._baseClass.__dict__.has_key(attr):
+ if attr != '_baseClass' and (attr in self._baseClass.__dict__):
self._baseClass.__setattr__( attr, v )
object.__setattr__( self, attr, v )
def wrappedGetattr ( self, attr ):
if attr == '_baseClass': return self.__dict__['_baseClass']
- if self.__dict__.has_key(attr): return self.__dict__[attr]
+ if attr in self.__dict__: return self.__dict__[attr]
selfClass = type( self )
- if selfClass.__dict__.has_key(attr):
+ if attr in selfClass.__dict__:
prop = selfClass.__dict__[attr]
if isprop(prop):
return prop.__get__(self)
diff --git a/crlcore/src/LibraryManager/CellsModel.cpp b/crlcore/src/LibraryManager/CellsModel.cpp
index 96ae2693..3113ebc0 100644
--- a/crlcore/src/LibraryManager/CellsModel.cpp
+++ b/crlcore/src/LibraryManager/CellsModel.cpp
@@ -1,7 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
-// Copyright (c) UPMC 2015-2018, All Rights Reserved
+// Copyright (c) Sorbonne Université 2015-2021, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@@ -18,7 +18,7 @@
#include
#include
#include
-#include "vlsisapd/utilities/Path.h"
+#include "hurricane/utilities/Path.h"
#include "hurricane/Error.h"
#include "hurricane/Cells.h"
#include "hurricane/Library.h"
@@ -26,7 +26,7 @@
#include "crlcore/AllianceFramework.h"
#include "crlcore/Catalog.h"
#include "crlcore/AcmSigda.h"
-#include "crlcore/Ispd05Bookshelf.h"
+//#include "crlcore/Ispd05Bookshelf.h"
#include "crlcore/Blif.h"
#include "crlcore/Iccad04Lefdef.h"
#include "crlcore/CellsModel.h"
@@ -94,11 +94,11 @@ namespace CRL {
, CellLoader::Importer
, Catalog::State::Logical
, std::bind( &AcmSigda::load, placeholders::_1 ) ) );
- loaders->addLoader( new CellLoader("aux"
- , "ISPD'05 (Bookshelf)"
- , CellLoader::Importer
- , Catalog::State::Logical|Catalog::State::Physical
- , std::bind( &Ispd05::load, placeholders::_1 ) ) );
+// loaders->addLoader( new CellLoader("aux"
+// , "ISPD'05 (Bookshelf)"
+// , CellLoader::Importer
+// , Catalog::State::Logical|Catalog::State::Physical
+// , std::bind( &Ispd05::load, placeholders::_1 ) ) );
loaders->addLoader( new CellLoader("blif"
, "BLIF (Yosys/ABC)"
, CellLoader::Importer|CellLoader::MultiCell
diff --git a/crlcore/src/LibraryManager/crlcore/CellDatas.h b/crlcore/src/LibraryManager/crlcore/CellDatas.h
index 7e1af455..1466712c 100644
--- a/crlcore/src/LibraryManager/crlcore/CellDatas.h
+++ b/crlcore/src/LibraryManager/crlcore/CellDatas.h
@@ -1,7 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
-// Copyright (c) UPMC 2015-2018, All Rights Reserved
+// Copyright (c) Sorbonne Université 2015-2021, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@@ -14,12 +14,10 @@
// +-----------------------------------------------------------------+
-#ifndef CRL_CELL_DATAS_H
-#define CRL_CELL_DATAS_H
-
+#pragma once
#include
#include
-#include "vlsisapd/utilities/Path.h"
+#include "hurricane/utilities/Path.h"
#include "crlcore/Catalog.h"
namespace Hurricane {
class Cell;
@@ -187,5 +185,3 @@ namespace CRL {
}
-
-#endif // CRL_CELL_DATAS_H
diff --git a/crlcore/src/ccore/AllianceFramework.cpp b/crlcore/src/ccore/AllianceFramework.cpp
index 6465b77a..171d496f 100644
--- a/crlcore/src/ccore/AllianceFramework.cpp
+++ b/crlcore/src/ccore/AllianceFramework.cpp
@@ -14,7 +14,7 @@
// +-----------------------------------------------------------------+
#include
-#include "vlsisapd/utilities/Path.h"
+#include "hurricane/utilities/Path.h"
#include "hurricane/Initializer.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
diff --git a/crlcore/src/ccore/CMakeLists.txt b/crlcore/src/ccore/CMakeLists.txt
index 42d6f7d6..c14d4c0e 100644
--- a/crlcore/src/ccore/CMakeLists.txt
+++ b/crlcore/src/ccore/CMakeLists.txt
@@ -29,16 +29,14 @@
${CRLCORE_SOURCE_DIR}/src/ccore/liberty
${CRLCORE_SOURCE_DIR}/src/ccore/toolbox
${HURRICANE_INCLUDE_DIR}
- ${CIF_INCLUDE_DIR}
- ${CONFIGURATION_INCLUDE_DIR}
- ${PYTHON_INCLUDE_PATH}
+ ${Python_INCLUDE_DIRS}
${Boost_INCLUDE_DIR}
${QtX_INCLUDE_DIR}
)
add_definitions ( -DCORIOLIS_TOP="${CORIOLIS_TOP}"
-DSYS_CONF_DIR="${SYS_CONF_DIR}"
- -DPYTHON_SITE_PACKAGES="${PYTHON_SITE_PACKAGES}"
+ -DPYTHON_SITE_PACKAGES="${Python_CORIOLISLIB}"
)
set ( includes crlcore/Utilities.h
@@ -49,7 +47,6 @@
crlcore/GdsDriver.h
crlcore/OAParser.h
crlcore/OADriver.h
- crlcore/CifDriver.h
crlcore/SearchPath.h
crlcore/Environment.h
crlcore/Catalog.h
@@ -64,8 +61,8 @@
crlcore/Blif.h
crlcore/AcmSigda.h
crlcore/Iccad04Lefdef.h
- crlcore/Ispd04Bookshelf.h
- crlcore/Ispd05Bookshelf.h
+# crlcore/Ispd04Bookshelf.h
+# crlcore/Ispd05Bookshelf.h
crlcore/Ioc.h
crlcore/VhdlBit.h
crlcore/VhdlSignal.h
@@ -92,7 +89,6 @@
COptions.cpp
Histogram.cpp
OAParserDriver.cpp
- CifDriver.cpp
SearchPath.cpp
Environment.cpp
Catalog.cpp
@@ -119,8 +115,6 @@
set ( gds_cpps gds/GdsDriver.cpp
gds/GdsParser.cpp
)
- set ( cif_cpps cif/CifDriver.cpp
- )
set ( toolbox_cpps toolbox/HyperNetPortOccurrences.cpp
toolbox/ToolBox.cpp
toolbox/UniqueCellOccurrences.cpp
@@ -155,8 +149,8 @@
lefdef/LefDefExtension.cpp
)
set ( iccad04_cpps iccad04/Iccad04Lefdef.cpp )
- set ( ispd04_cpps ispd04/Ispd04Bookshelf.cpp )
- set ( ispd05_cpps ispd05/Ispd05Bookshelf.cpp )
+# set ( ispd04_cpps ispd04/Ispd04Bookshelf.cpp )
+# set ( ispd05_cpps ispd05/Ispd05Bookshelf.cpp )
set ( blif_cpps blif/BlifParser.cpp )
if ( LEFDEF_FOUND )
include_directories ( ${LEFDEF_INCLUDE_DIR} )
@@ -302,14 +296,11 @@
${openaccess_cpps}
)
set_target_properties ( crlcore PROPERTIES VERSION 1.0 SOVERSION 1 )
- target_link_libraries ( crlcore ${HURRICANE_PYTHON_LIBRARIES}
+ target_link_libraries ( crlcore ${HURRICANE_PYTHON_NEW_LIBRARIES}
+ ${HURRICANE_PYTHON_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES}
${HURRICANE_LIBRARIES}
${BOOKSHELF_LIBRARY}
- ${CONFIGURATION_LIBRARY}
- ${CIF_LIBRARY}
- ${AGDS_LIBRARY}
- ${UTILITIES_LIBRARY}
${LEFDEF_LIBRARIES}
${OA_LIBRARIES}
${QtX_LIBRARIES}
diff --git a/crlcore/src/ccore/Histogram.cpp b/crlcore/src/ccore/Histogram.cpp
index f71144ce..a0f60e71 100644
--- a/crlcore/src/ccore/Histogram.cpp
+++ b/crlcore/src/ccore/Histogram.cpp
@@ -1,7 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
-// Copyright (c) Sorbonne Universite 2008-2019, All Rights Reserved
+// Copyright (c) Sorbonne Universite 2008-2021, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@@ -18,7 +18,7 @@
#include
#include
#include
-#include "vlsisapd/utilities/Path.h"
+#include "hurricane/utilities/Path.h"
#include "crlcore/Histogram.h"
diff --git a/crlcore/src/ccore/Utilities.cpp b/crlcore/src/ccore/Utilities.cpp
index 473491ea..c9c5d74c 100644
--- a/crlcore/src/ccore/Utilities.cpp
+++ b/crlcore/src/ccore/Utilities.cpp
@@ -1,14 +1,14 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
-// Copyright (c) UPMC 2008-2018, All Rights Reserved
+// Copyright (c) Sorbonne Université 2008-2021, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
-// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Utilities.cpp" |
// +-----------------------------------------------------------------+
@@ -23,8 +23,8 @@
#include
namespace boptions = boost::program_options;
-#include "vlsisapd/utilities/Path.h"
-#include "vlsisapd/configuration/Configuration.h"
+#include "hurricane/utilities/Path.h"
+#include "hurricane/configuration/Configuration.h"
#include "hurricane/Backtrace.h"
#include "hurricane/Warning.h"
#include "hurricane/viewer/Script.h"
diff --git a/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp b/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp
index c949e50e..7f202229 100644
--- a/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp
+++ b/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp
@@ -187,24 +187,28 @@ namespace Vhdl {
else if (rightpar + 1 != name.size())
error = "malformed net name, right parenthesis is *not* the last character";
else {
- size_t endindex = 0;
- int value = stoi( name.substr(leftpar+1), &endindex );
-
- if (endindex != rightpar-leftpar-1)
- error = "unable to convert index (not a number)";
- else if (value < 0)
- error = "negative index";
- else {
- stem = name.substr( 0, leftpar );
- index = (size_t)value;
- return true;
+ try {
+ size_t endindex = 0;
+ int value = stoi( name.substr(leftpar+1), &endindex );
+
+ if (endindex != rightpar-leftpar-1)
+ error = "unable to convert index (not a number)";
+ else if (value < 0)
+ error = "negative index";
+ else {
+ stem = name.substr( 0, leftpar );
+ index = (size_t)value;
+ return true;
+ }
+ } catch ( exception& e ) {
+ error = e.what();
}
}
}
if (not error.empty()) {
cerr << Warning( "Entity::parseVector() Net has not a valid VHDL name, %s.\n"
- " %s\n"
+ " \"%s\"\n"
, error.c_str()
, getString(net->getName()).c_str()
) << endl;
diff --git a/crlcore/src/ccore/blif/BlifParser.cpp b/crlcore/src/ccore/blif/BlifParser.cpp
index 441f200e..df9e5cff 100644
--- a/crlcore/src/ccore/blif/BlifParser.cpp
+++ b/crlcore/src/ccore/blif/BlifParser.cpp
@@ -24,7 +24,7 @@
#include
using namespace std;
-#include "vlsisapd/configuration/Configuration.h"
+#include "hurricane/configuration/Configuration.h"
#include "hurricane/Warning.h"
#include "hurricane/Plug.h"
#include "hurricane/Net.h"
diff --git a/crlcore/src/ccore/crlcore/Utilities.h b/crlcore/src/ccore/crlcore/Utilities.h
index bc869f98..7a15d4b5 100644
--- a/crlcore/src/ccore/crlcore/Utilities.h
+++ b/crlcore/src/ccore/crlcore/Utilities.h
@@ -1,28 +1,26 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
-// Copyright (c) UPMC 2008-2018, All Rights Reserved
+// Copyright (c) Sorbonne Université 2008-2021, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
-// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/Utilities.h" |
// +-----------------------------------------------------------------+
-#ifndef CRL_UTILITIES_H
-#define CRL_UTILITIES_H
-
+#pragma once
#include
#include
#include
#include
#include
-#include "vlsisapd/utilities/Path.h"
+#include "hurricane/utilities/Path.h"
#include "hurricane/Commons.h"
#include "hurricane/Error.h"
#include "hurricane/Slot.h"
@@ -464,6 +462,3 @@ class Dots {
const std::string _left;
const std::string _right;
};
-
-
-#endif // CRL_UTILITIES
diff --git a/crlcore/src/ccore/gds/GdsDriver.cpp b/crlcore/src/ccore/gds/GdsDriver.cpp
index 93a20bb4..cb4dbea0 100644
--- a/crlcore/src/ccore/gds/GdsDriver.cpp
+++ b/crlcore/src/ccore/gds/GdsDriver.cpp
@@ -1,7 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
-// Copyright (c) UPMC 2018-2018, All Rights Reserved
+// Copyright (c) Sorbonne Université 2018-2021, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@@ -27,7 +27,7 @@
#include
using namespace std;
-#include "vlsisapd/configuration/Configuration.h"
+#include "hurricane/configuration/Configuration.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
#include "hurricane/BasicLayer.h"
diff --git a/crlcore/src/ccore/gds/GdsParser.cpp b/crlcore/src/ccore/gds/GdsParser.cpp
index 9ea0a36f..8a7a9f3a 100644
--- a/crlcore/src/ccore/gds/GdsParser.cpp
+++ b/crlcore/src/ccore/gds/GdsParser.cpp
@@ -1,14 +1,14 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
-// Copyright (c) UPMC 2018-2018, All Rights Reserved
+// Copyright (c) Sorbonne Université 2018-2021, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | G D S I I / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
-// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
+// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./gds/GdsParser.cpp" |
// +-----------------------------------------------------------------+
@@ -26,7 +26,7 @@
#include
using namespace std;
-#include "vlsisapd/configuration/Configuration.h"
+#include "hurricane/configuration/Configuration.h"
#include "hurricane/DebugSession.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
diff --git a/crlcore/src/ccore/lefdef/LefImport.cpp b/crlcore/src/ccore/lefdef/LefImport.cpp
index 37cb35f4..74912ae8 100644
--- a/crlcore/src/ccore/lefdef/LefImport.cpp
+++ b/crlcore/src/ccore/lefdef/LefImport.cpp
@@ -22,7 +22,7 @@
#if defined(HAVE_LEFDEF)
# include "lefrReader.hpp"
#endif
-#include "vlsisapd/configuration/Configuration.h"
+#include "hurricane/configuration/Configuration.h"
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
@@ -446,7 +446,7 @@ namespace {
, parser->fromUnitsMicrons( r->yh )
);
}
- //cerr << " | " << segment << endl;
+ cdebug_log(100,0) << "| " << segment << endl;
}
}
diff --git a/crlcore/src/ccore/spice/SpiceDriver.cpp b/crlcore/src/ccore/spice/SpiceDriver.cpp
index c123a92c..ca9c27b3 100644
--- a/crlcore/src/ccore/spice/SpiceDriver.cpp
+++ b/crlcore/src/ccore/spice/SpiceDriver.cpp
@@ -28,7 +28,7 @@
#include
using namespace std;
-#include "vlsisapd/configuration/Configuration.h"
+#include "hurricane/configuration/Configuration.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
#include "hurricane/BasicLayer.h"
diff --git a/crlcore/src/ccore/spice/SpiceParser.cpp b/crlcore/src/ccore/spice/SpiceParser.cpp
index e82b8116..ccc0bd2f 100644
--- a/crlcore/src/ccore/spice/SpiceParser.cpp
+++ b/crlcore/src/ccore/spice/SpiceParser.cpp
@@ -26,7 +26,7 @@
#include
using namespace std;
-#include "vlsisapd/configuration/Configuration.h"
+#include "hurricane/configuration/Configuration.h"
#include "hurricane/DebugSession.h"
#include "hurricane/UpdateSession.h"
#include "hurricane/Warning.h"
diff --git a/crlcore/src/cyclop/CMakeLists.txt b/crlcore/src/cyclop/CMakeLists.txt
index 0b1ca214..585dab8a 100644
--- a/crlcore/src/cyclop/CMakeLists.txt
+++ b/crlcore/src/cyclop/CMakeLists.txt
@@ -22,19 +22,16 @@
add_executable ( cyclop ${cpps} ${moccpps} )
target_link_libraries ( cyclop crlcore
+ ${HURRICANE_PYTHON_NEW_LIBRARIES}
${HURRICANE_PYTHON_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES}
${HURRICANE_LIBRARIES}
${BOOKSHELF_LIBRARY}
- ${AGDS_LIBRARY}
- ${CIF_LIBRARY}
- ${CONFIGURATION_LIBRARY}
- ${UTILITIES_LIBRARY}
${LEFDEF_LIBRARIES}
${OA_LIBRARIES}
${QtX_LIBRARIES}
${Boost_LIBRARIES}
- ${PYTHON_LIBRARIES}
+ ${Python_LIBRARIES}
-lutil
${LIBXML2_LIBRARIES}
${LIBEXECINFO_LIBRARIES}
diff --git a/crlcore/src/cyclop/CyclopMain.cpp b/crlcore/src/cyclop/CyclopMain.cpp
index ec4bc657..2fa002f6 100644
--- a/crlcore/src/cyclop/CyclopMain.cpp
+++ b/crlcore/src/cyclop/CyclopMain.cpp
@@ -29,7 +29,7 @@ namespace boptions = boost::program_options;
# include
#endif
-#include "vlsisapd/utilities/Path.h"
+#include "hurricane/utilities/Path.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Layer.h"
diff --git a/crlcore/src/pyCRL/CMakeLists.txt b/crlcore/src/pyCRL/CMakeLists.txt
index a19f6adc..ca1585ee 100644
--- a/crlcore/src/pyCRL/CMakeLists.txt
+++ b/crlcore/src/pyCRL/CMakeLists.txt
@@ -17,7 +17,7 @@
${HURRICANE_INCLUDE_DIR}
${CIF_INCLUDE_DIR}
${CONFIGURATION_INCLUDE_DIR}
- ${PYTHON_INCLUDE_PATH}
+ ${Python_INCLUDE_DIRS}
${Boost_INCLUDE_DIR}
)
@@ -43,7 +43,7 @@
PyToolEngineCollection.cpp
PyGraphicToolEngine.cpp
PyAcmSigda.cpp
- PyIspd05.cpp
+ #PyIspd05.cpp
PySpice.cpp
PyBlif.cpp
PyGds.cpp
@@ -65,7 +65,7 @@
crlcore/PyToolEngineCollection.h
crlcore/PyGraphicToolEngine.h
crlcore/PyAcmSigda.h
- crlcore/PyIspd05.h
+ #crlcore/PyIspd05.h
crlcore/PySpice.h
crlcore/PyBlif.h
crlcore/PyGds.h
diff --git a/crlcore/src/pyCRL/PyAllianceFramework.cpp b/crlcore/src/pyCRL/PyAllianceFramework.cpp
index b017ecf7..f83cacee 100644
--- a/crlcore/src/pyCRL/PyAllianceFramework.cpp
+++ b/crlcore/src/pyCRL/PyAllianceFramework.cpp
@@ -77,7 +77,7 @@ extern "C" {
HTRY
PyObject* arg0;
if (ParseOneArg("AllianceFramework.create()", args, INT_ARG, &arg0)) {
- flags = PyInt_AsUnsignedLongMask(arg0);
+ flags = PyLong_AsUnsignedLongMask(arg0);
}
af = AllianceFramework::create( flags );
HCATCH
@@ -230,6 +230,8 @@ extern "C" {
if ( not ParseTwoArg ( "AllianceFramework.saveCell", args, CELL_INT_ARG, &arg0, &arg1) ) return NULL;
+ //if (PyAny_AsLong(arg1) & CRL::Catalog::State::Logical)
+ // cerr << "saveSell() " << PYCELL_O(arg0) << " Logical set" << endl;
af->saveCell ( PYCELL_O(arg0),PyAny_AsLong(arg1) );
HCATCH
diff --git a/crlcore/src/pyCRL/PyCRL.cpp b/crlcore/src/pyCRL/PyCRL.cpp
index 889ce1ac..673f7676 100644
--- a/crlcore/src/pyCRL/PyCRL.cpp
+++ b/crlcore/src/pyCRL/PyCRL.cpp
@@ -31,7 +31,7 @@
#include "crlcore/PyToolEngine.h"
#include "crlcore/PyToolEngineCollection.h"
#include "crlcore/PyAcmSigda.h"
-#include "crlcore/PyIspd05.h"
+// #include "crlcore/PyIspd05.h"
#include "crlcore/PySpice.h"
#include "crlcore/PyBlif.h"
#include "crlcore/PyGds.h"
@@ -103,13 +103,28 @@ extern "C" {
};
+ static PyModuleDef PyCRL_ModuleDef =
+ { PyModuleDef_HEAD_INIT
+ , "CRL" /* m_name */
+ , "Coriolis Core I/O framework"
+ /* m_doc */
+ , -1 /* m_size */
+ , PyCRL_Methods /* m_methods */
+ , NULL /* m_reload */
+ , NULL /* m_traverse */
+ , NULL /* m_clear */
+ , NULL /* m_free */
+ };
+
+
// ---------------------------------------------------------------
// Module Initialization : "initCRL ()"
- DL_EXPORT(void) initCRL () {
- cdebug_log(30,0) << "initCRL()" << endl;
+ PyMODINIT_FUNC PyInit_CRL ( void )
+ {
+ cdebug_log(30,0) << "PyInit_CRL()" << endl;
PySystem_LinkPyType ();
PyBanner_LinkPyType ();
@@ -125,7 +140,7 @@ extern "C" {
PyToolEngine_LinkPyType ();
PyToolEngineCollection_LinkPyType ();
PyAcmSigda_LinkPyType ();
- PyIspd05_LinkPyType ();
+ // PyIspd05_LinkPyType ();
PySpice_LinkPyType ();
PyBlif_LinkPyType ();
PyGds_LinkPyType ();
@@ -148,7 +163,7 @@ extern "C" {
PYTYPE_READY ( ToolEngineCollection );
PYTYPE_READY ( ToolEngineCollectionLocator );
PYTYPE_READY ( AcmSigda );
- PYTYPE_READY ( Ispd05 );
+ // PYTYPE_READY ( Ispd05 );
PYTYPE_READY ( Spice );
PYTYPE_READY ( Blif );
PYTYPE_READY ( Gds );
@@ -165,11 +180,11 @@ extern "C" {
__cs.addType ( "alcCatalog" , &PyTypeCatalog , "" , false );
__cs.addType ( "alcCatStat" , &PyTypeCatalogState , "" , false );
- PyObject* module = Py_InitModule ( "CRL", PyCRL_Methods );
- if ( module == NULL ) {
+ PyObject* module = PyModule_Create( &PyCRL_ModuleDef );
+ if (module == NULL) {
cerr << "[ERROR]\n"
<< " Failed to initialize CRL module." << endl;
- return;
+ return NULL;
}
Py_INCREF ( &PyTypeSystem );
@@ -202,8 +217,8 @@ extern "C" {
PyModule_AddObject ( module, "ToolEngineCollectionLocator", (PyObject*)&PyTypeToolEngineCollectionLocator );
Py_INCREF ( &PyTypeAcmSigda );
PyModule_AddObject ( module, "AcmSigda", (PyObject*)&PyTypeAcmSigda );
- Py_INCREF ( &PyTypeIspd05 );
- PyModule_AddObject ( module, "Ispd05", (PyObject*)&PyTypeIspd05 );
+ // Py_INCREF ( &PyTypeIspd05 );
+ // PyModule_AddObject ( module, "Ispd05", (PyObject*)&PyTypeIspd05 );
Py_INCREF ( &PyTypeSpice );
PyModule_AddObject ( module, "Spice", (PyObject*)&PyTypeSpice );
Py_INCREF ( &PyTypeBlif );
@@ -226,6 +241,7 @@ extern "C" {
//DbULoadConstants ( dictionnary );
cdebug_log(30,0) << "CRL.so loaded " << (void*)&typeid(string) << endl;
+ return module;
}
diff --git a/crlcore/src/pyCRL/PyCatalogState.cpp b/crlcore/src/pyCRL/PyCatalogState.cpp
index be338d55..d73b4de2 100644
--- a/crlcore/src/pyCRL/PyCatalogState.cpp
+++ b/crlcore/src/pyCRL/PyCatalogState.cpp
@@ -147,12 +147,12 @@ extern "C" {
extern void PyCatalogState_LinkPyType() {
cdebug_log(30,0) << "PyCatalogState_LinkType()" << endl;
- PyTypeCatalogState.tp_dealloc = (destructor) PyCatalogState_DeAlloc;
- PyTypeCatalogState.tp_compare = (cmpfunc) PyCatalogState_Cmp;
- PyTypeCatalogState.tp_repr = (reprfunc) PyCatalogState_Repr;
- PyTypeCatalogState.tp_str = (reprfunc) PyCatalogState_Str;
- PyTypeCatalogState.tp_hash = (hashfunc) PyCatalogState_Hash;
- PyTypeCatalogState.tp_methods = PyCatalogState_Methods;
+ PyTypeCatalogState.tp_dealloc = (destructor) PyCatalogState_DeAlloc;
+ PyTypeCatalogState.tp_richcompare = (richcmpfunc)PyCatalogState_Cmp;
+ PyTypeCatalogState.tp_repr = (reprfunc) PyCatalogState_Repr;
+ PyTypeCatalogState.tp_str = (reprfunc) PyCatalogState_Str;
+ PyTypeCatalogState.tp_hash = (hashfunc) PyCatalogState_Hash;
+ PyTypeCatalogState.tp_methods = PyCatalogState_Methods;
}
diff --git a/crlcore/src/pyCRL/PyConstant.cpp b/crlcore/src/pyCRL/PyConstant.cpp
index a6559536..100eb450 100644
--- a/crlcore/src/pyCRL/PyConstant.cpp
+++ b/crlcore/src/pyCRL/PyConstant.cpp
@@ -74,20 +74,36 @@ extern "C" {
};
- DL_EXPORT(void) initConstant () {
- cdebug_log(30,0) << "initConstant()" << endl;
+ static PyModuleDef PyConstant_ModuleDef =
+ { PyModuleDef_HEAD_INIT
+ , "Constant" /* m_name */
+ , "Constants values used througout Coriolis."
+ /* m_doc */
+ , -1 /* m_size */
+ , PyConstant_Methods /* m_methods */
+ , NULL /* m_reload */
+ , NULL /* m_traverse */
+ , NULL /* m_clear */
+ , NULL /* m_free */
+ };
- PyObject* module = Py_InitModule( "Constant", PyConstant_Methods );
+
+ PyMODINIT_FUNC PyInit_Constant ( void )
+ {
+ cdebug_log(30,0) << "PyInit_Constant()" << endl;
+
+ PyObject* module = PyModule_Create( &PyConstant_ModuleDef );
if (module == NULL) {
cerr << "[ERROR]\n"
<< " Failed to initialize Constant module." << endl;
- return;
+ return NULL;
}
PyObject* dictionnary = PyModule_GetDict( module );
LoadConstants( dictionnary );
cdebug_log(30,0) << "Constant.so loaded " << (void*)&typeid(string) << endl;
+ return module;
}
diff --git a/crlcore/src/pyCRL/PyRoutingGauge.cpp b/crlcore/src/pyCRL/PyRoutingGauge.cpp
index b31b5d8f..5ccd1ad9 100644
--- a/crlcore/src/pyCRL/PyRoutingGauge.cpp
+++ b/crlcore/src/pyCRL/PyRoutingGauge.cpp
@@ -544,6 +544,8 @@ extern "C" {
, "Return the default wire width of the given layer." }
, { "getViaWidth" , (PyCFunction)PyRoutingGauge_getViaWidth , METH_VARARGS
, "Return the default via width of the given layer." }
+ , { "getPWireWidth" , (PyCFunction)PyRoutingGauge_getPWireWidth , METH_VARARGS
+ , "Return the default perpandicular wire width of the given layer." }
, { "getPowerSupplyGauge" , (PyCFunction)PyRoutingGauge_getPowerSupplyGauge, METH_NOARGS
, "Return the power supply gauge (None if there isn't)." }
, { "getLayerGauge" , (PyCFunction)PyRoutingGauge_getLayerGauge , METH_VARARGS
diff --git a/crlcore/src/x2y/CMakeLists.txt b/crlcore/src/x2y/CMakeLists.txt
index 7f48b108..dd997f0b 100644
--- a/crlcore/src/x2y/CMakeLists.txt
+++ b/crlcore/src/x2y/CMakeLists.txt
@@ -13,6 +13,7 @@
add_executable ( cx2y ${cpps} )
target_link_libraries ( cx2y crlcore
${UTILITIES_LIBRARY}
+ ${Python_LIBRARIES}
${LIBEXECINFO_LIBRARIES}
${LIBBFD_LIBRARIES}
)
diff --git a/cumulus/CMakeLists.txt b/cumulus/CMakeLists.txt
index d2e192d7..e61f68ae 100644
--- a/cumulus/CMakeLists.txt
+++ b/cumulus/CMakeLists.txt
@@ -14,9 +14,8 @@
set_cmake_policies()
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
- find_package(PythonLibs 2 REQUIRED)
+ find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
- find_package(VLSISAPD REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)
diff --git a/cumulus/src/Alliance.py b/cumulus/src/Alliance.py
index 100444c5..6b0c2b76 100644
--- a/cumulus/src/Alliance.py
+++ b/cumulus/src/Alliance.py
@@ -360,7 +360,7 @@ def staticInitialization ():
try:
print ' o Running configuration hook: Alliance.staticInitialization().'
print ' - Loading \"%s\".' % helpers.truncPath(confFile)
- execfile( confFile, moduleGlobals )
+ exec( open(confFile).read() ) #, moduleGlobals )
except Exception, e:
print '[ERROR] An exception occured while loading the configuration file:'
print ' <%s>\n' % (confFile)
diff --git a/cumulus/src/CMakeLists.txt b/cumulus/src/CMakeLists.txt
index ffef310b..8e585130 100644
--- a/cumulus/src/CMakeLists.txt
+++ b/cumulus/src/CMakeLists.txt
@@ -80,14 +80,14 @@
${CMAKE_CURRENT_SOURCE_DIR}/plugins/alpha/macro/macro.py
)
- install ( FILES ${pySources} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus )
- install ( FILES ${pyPlugins} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins )
- install ( FILES ${pyPluginCTS} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/cts )
- install ( FILES ${pyPluginC2C} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/core2chip )
- install ( FILES ${pyPluginChip} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/chip )
- install ( FILES ${pyPluginAlpha} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/alpha )
- install ( FILES ${pyPluginAlphaBlock} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/alpha/block )
- install ( FILES ${pyPluginAlphaC2C} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/alpha/core2chip )
- install ( FILES ${pyPluginAlphaChip} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/alpha/chip )
- install ( FILES ${pyPluginAlphaMacro} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins/alpha/macro )
+ install ( FILES ${pySources} DESTINATION ${Python_CORIOLISLIB}/cumulus )
+ install ( FILES ${pyPlugins} DESTINATION ${Python_CORIOLISLIB}/cumulus/plugins )
+ install ( FILES ${pyPluginCTS} DESTINATION ${Python_CORIOLISLIB}/cumulus/plugins/cts )
+ install ( FILES ${pyPluginC2C} DESTINATION ${Python_CORIOLISLIB}/cumulus/plugins/core2chip )
+ install ( FILES ${pyPluginChip} DESTINATION ${Python_CORIOLISLIB}/cumulus/plugins/chip )
+ install ( FILES ${pyPluginAlpha} DESTINATION ${Python_CORIOLISLIB}/cumulus/plugins/alpha )
+ install ( FILES ${pyPluginAlphaBlock} DESTINATION ${Python_CORIOLISLIB}/cumulus/plugins/alpha/block )
+ install ( FILES ${pyPluginAlphaC2C} DESTINATION ${Python_CORIOLISLIB}/cumulus/plugins/alpha/core2chip )
+ install ( FILES ${pyPluginAlphaChip} DESTINATION ${Python_CORIOLISLIB}/cumulus/plugins/alpha/chip )
+ install ( FILES ${pyPluginAlphaMacro} DESTINATION ${Python_CORIOLISLIB}/cumulus/plugins/alpha/macro )
install ( PROGRAMS ${pyTools} DESTINATION bin )
diff --git a/cumulus/src/placeandroute.py b/cumulus/src/placeandroute.py
index 0a6c0beb..94b0cf58 100644
--- a/cumulus/src/placeandroute.py
+++ b/cumulus/src/placeandroute.py
@@ -186,7 +186,7 @@ def pyAlimVerticalRail ( cell, xcoord ) :
# Check the value of x
nb_col = cell.getAbutmentBox().getWidth() / DbU_lambda(PITCH)
if ( xcoord >= nb_col ) or ( xcoord < 0 ) :
- print 'This is it'
+ print( 'This is it' )
message = "AlimVerticalRail : Illegal argument x , x must be between %d and %d\n" % ( 0, nb_col )
raise ErrorMessage(2,message)
@@ -926,7 +926,7 @@ def pyPowerRing ( cell, core, n ) :
topRoutingLayer = db.getTechnology().getLayer( topRoutingLayerName )
allowedDepth = CRL.AllianceFramework.get().getRoutingGauge().getLayerDepth( topRoutingLayer )
- print 'topRoutingLayer: <%s> depth:%d' % (topRoutingLayer.getName(), allowedDepth)
+ print( 'topRoutingLayer: <%s> depth:%d' % (topRoutingLayer.getName(), allowedDepth) )
UpdateSession.open()
@@ -1576,7 +1576,7 @@ def pyPowerRing ( cell, core, n ) :
# end of while
# end of while
- #print "\n\n\n\npoints_0 : ", points_0 , "\n\npoints_1 : " ,points_1 , "\n\npoints_2 : " ,points_2 , "\n\npoints_3 : " , points_3 , "\n\n\n\n"
+ #print( "\n\n\n\npoints_0 : ", points_0 , "\n\npoints_1 : " ,points_1 , "\n\npoints_2 : " ,points_2 , "\n\npoints_3 : " , points_3 , "\n\n\n\n" )
# Placer au cote du nord
for ins_pad in pad_north :
@@ -1976,16 +1976,16 @@ def isExternalClockPad ( ins ) :
def affichePad ( cell ) :
global pad_north, pad_south, pad_east, pad_west
- print "Pads in the north are :"
+ print( "Pads in the north are :" )
for pad in pad_north : print cell.getInstance ( pad.getName() ).getMasterCell().getName()
- print "Pads in the south are :"
+ print( "Pads in the south are :" )
for pad in pad_south : print cell.getInstance ( pad.getName() ).getMasterCell().getName()
- print "Pads in the east are :"
+ print( "Pads in the east are :" )
for pad in pad_east : print cell.getInstance ( pad.getName() ).getMasterCell().getName()
- print "Pads in the west are :"
+ print( "Pads in the west are :" )
for pad in pad_west : print cell.getInstance ( pad.getName() ).getMasterCell().getName()
############
diff --git a/cumulus/src/plugins/__init__.py b/cumulus/src/plugins/__init__.py
index 082fd1a5..42bd0d8d 100644
--- a/cumulus/src/plugins/__init__.py
+++ b/cumulus/src/plugins/__init__.py
@@ -1,7 +1,6 @@
-# -*- explicit-buffer-name: "__init__.py" -*-
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -16,6 +15,7 @@
import os
import sys
+import traceback
import Cfg
import helpers
from helpers.io import vprint
@@ -30,26 +30,22 @@ import CRL
from CRL import RoutingLayerGauge
-NoFlags = 0000
-ShowWarnings = 0001
-WarningsAreErrors = 0002
+NoFlags = 0
+ShowWarnings = 1
+WarningsAreErrors = 2
loaded = False
-
-def kwParseMain ( **kw ):
+def kwParseMain ( **kw ):
cell = None
- if kw.has_key('cell') and kw['cell']:
+ if ('cell' in kw) and kw['cell']:
cell = kw['cell']
-
editor = None
- if kw.has_key('editor') and kw['editor']:
+ if ('editor' in kw) and kw['editor']:
editor = kw['editor']
if cell == None: cell = editor.getCell()
-
#if cell == None:
# raise ErrorMessage( 3, 'Chip: No cell loaded yet.' )
-
return cell, editor
@@ -66,8 +62,7 @@ def kwUnicornHook ( menuPath, menuName, menuTip, moduleFile, **kw ):
editor = kw['editor']
if moduleFile.endswith('.pyc') or moduleFile.endswith('.pyo'):
moduleFile = moduleFile[:-1]
-
- if kw.has_key('beforeAction'):
+ if 'beforeAction' in kw:
editor.addToMenu( menuPath, menuName, menuTip, moduleFile, kw['beforeAction'] )
else:
editor.addToMenu( menuPath, menuName, menuTip, moduleFile )
@@ -110,7 +105,7 @@ class CheckUnplaced ( object ):
error = ErrorMessage( 3, message )
if self.flags & WarningsAreErrors: raise error
- else: print error
+ else: print( error )
return self.unplaceds
@@ -137,7 +132,7 @@ class StackedVia ( object ):
def mergeDepth ( self, depth ):
if self._hasLayout:
- print WarningMessage( 'StackedVia.mergeDepth(): Cannot be called *after* StackVia.doLayout()' )
+ print( WarningMessage( 'StackedVia.mergeDepth(): Cannot be called *after* StackVia.doLayout()' ))
return
if depth < self._bottomDepth: self._bottomDepth = depth
if depth > self._topDepth: self._topDepth = depth
@@ -187,17 +182,32 @@ class StackedVia ( object ):
, 0 , 0
, self._width, self._height
) )
- #print ' Sub-via: ', self._vias[-1]
+ #print( ' Sub-via: ', self._vias[-1] )
return
def loadPlugins ( pluginsDir ):
+ """
+ Forced import of all the modules that resides in the directory ``pluginsDir``.
+ Works in three stages:
+
+ 1. Build a list of all the ``.py`` files in the ``pluginsDir``, in case of
+ directories, import the whole package (it is assumed it *is* a Python
+ package directory).
+
+ 2. Sort the list of modules to be loaded (alphabetical order).
+ This is an attempt to get the initialization done in deterministic order.
+
+ 3. Import each module in order.
+
+ .. note:: Those modules will be searched later (in ``unicornInit.py``) for any
+ potential ``unicornHook()`` function.
+ """
sys.path.append( pluginsDir )
sys.modules['plugins'].__path__.append( pluginsDir )
-
if not os.path.isdir(pluginsDir):
- print ErrorMessage( 3, 'cumulus.__init__.py: Cannot find directory:' \
- , '<%s>' % pluginsDir )
+ print( ErrorMessage( 3, 'cumulus.__init__.py: Cannot find directory:' \
+ , '"{}"'.format(pluginsDir) ))
return
moduleNames = []
@@ -207,26 +217,24 @@ def loadPlugins ( pluginsDir ):
path = os.path.join(pluginsDir,entry)
if os.path.isdir(path):
packageName = "plugins." + entry
- if not sys.modules.has_key(packageName):
+ if not packageName in sys.modules:
module = __import__( packageName, globals(), locals() )
else:
module = sys.modules[packageName]
-
module.__path__.append( path )
continue
moduleNames.append( entry[:-3] )
moduleNames.sort()
-
for moduleName in moduleNames:
try:
- vprint( 2, ' - "%s"' % moduleName )
+ vprint( 2, ' - "{}"'.format(moduleName) )
module = __import__( moduleName, globals(), locals() )
- except ErrorMessage, e:
- print e
+ except ErrorMessage as e:
+ print( e )
helpers.showStackTrace( e.trace )
- except Exception, e:
- print e
+ except Exception as e:
+ print( e )
helpers.showPythonTrace( __file__, e )
return
@@ -235,7 +243,6 @@ def loadPlugins ( pluginsDir ):
def staticInitialization ():
global loaded
if loaded: return
-
try:
vprint( 1, ' o Preload standard plugins.' )
pluginsDir = os.path.dirname(__file__)
@@ -243,13 +250,14 @@ def staticInitialization ():
if helpers.ndaTopDir:
vprint( 1, ' o Preload NDA protected plugins.' )
- pluginsDir = os.path.join( helpers.ndaTopDir, 'python2.7/site-packages/cumulus/plugins' )
+ pluginsDir = os.path.join( helpers.ndaTopDir, 'python{}.{}/site-packages/cumulus/plugins' \
+ .format( sys.version_info.major
+ , sys.version_info.minor ))
loadPlugins( pluginsDir )
else:
vprint( 1, ' o No NDA protected plugins.' )
- except Exception, e:
+ except Exception as e:
helpers.showPythonTrace( __file__, e )
-
loaded = True
return
diff --git a/cumulus/src/plugins/aboutwindow.py b/cumulus/src/plugins/aboutwindow.py
index b64e3670..cf44f450 100644
--- a/cumulus/src/plugins/aboutwindow.py
+++ b/cumulus/src/plugins/aboutwindow.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,7 +13,6 @@
# +-----------------------------------------------------------------+
-
try:
import sys
import traceback
@@ -48,14 +46,14 @@ try:
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QApplication
except:
- print '[ERROR] AboutWindow: Neither PyQt4 nor PyQt5 is available.'
+ print( '[ERROR] AboutWindow: Neither PyQt4 nor PyQt5 is available.' )
sys.exit( 1 )
import Viewer
import helpers
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
import plugins
-except Exception, e:
+except Exception as e:
helpers.io.catch( e )
sys.exit(2)
@@ -154,16 +152,12 @@ def scriptMain ( **kw ):
rvalue = True
try:
#helpers.setTraceLevel( 550 )
-
aboutWidget = AboutWidget()
answer = aboutWidget.exec_()
- print 'answer:', answer
+ print( 'answer:', answer )
if not answer: return True
-
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
-
sys.stdout.flush()
sys.stderr.flush()
-
return rvalue
diff --git a/cumulus/src/plugins/alpha/block/bigvia.py b/cumulus/src/plugins/alpha/block/bigvia.py
index 6a47b8b9..da479f71 100644
--- a/cumulus/src/plugins/alpha/block/bigvia.py
+++ b/cumulus/src/plugins/alpha/block/bigvia.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -13,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import os.path
import Cfg
@@ -182,11 +181,11 @@ class BigVia ( object ):
trace( 550, '\t| botEnclosure[{}]: {}\n'.format(depth,DbU.getValueString(botEnclosure)) )
trace( 550, '\t| enclosure [{}]: {}\n'.format(depth,DbU.getValueString(enclosure)) )
cutArea = self.plates[ depth ].getBoundingBox()
- hEnclosure = enclosure + cutSide/2
+ hEnclosure = enclosure + cutSide//2
vEnclosure = hEnclosure
if hEnclosure*2 > cutArea.getWidth():
if self.flags & BigVia.AllowHorizontalExpand:
- hEnclosure = cutArea.getWidth()/2
+ hEnclosure = cutArea.getWidth()//2
else:
raise ErrorMessage( 1, [ 'BigVia._doCutMatrix(): Cannot create cut of {} in {}.' \
.format( cutLayer.getName(), self )
@@ -194,15 +193,15 @@ class BigVia ( object ):
] )
if vEnclosure*2 > cutArea.getHeight():
if self.flags & BigVia.AllowVerticalExpand:
- vEnclosure = cutArea.getHeight()/2
+ vEnclosure = cutArea.getHeight()//2
else:
raise ErrorMessage( 1, [ 'BigVia._doCutMatrix(): Cannot create cut of {} in {}.' \
.format( cutLayer.getName(), self )
, 'Height is too small to fit a single VIA cut.'
] )
cutArea.inflate( -hEnclosure, -vEnclosure )
- xoffset = (cutArea.getWidth () % (cutSide+cutSpacing)) / 2
- yoffset = (cutArea.getHeight() % (cutSide+cutSpacing)) / 2
+ xoffset = (cutArea.getWidth () % (cutSide+cutSpacing)) // 2
+ yoffset = (cutArea.getHeight() % (cutSide+cutSpacing)) // 2
cutArea.translate( xoffset, yoffset )
self.vias[ depth ] = []
y = cutArea.getYMin()
diff --git a/cumulus/src/plugins/alpha/block/block.py b/cumulus/src/plugins/alpha/block/block.py
index e7c13cb6..50b088f7 100644
--- a/cumulus/src/plugins/alpha/block/block.py
+++ b/cumulus/src/plugins/alpha/block/block.py
@@ -1,6 +1,6 @@
#
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -13,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import os.path
from copy import deepcopy
@@ -122,12 +121,12 @@ class Side ( object ):
if flags & IoPin.A_BEGIN:
self.ubegin += ustep
pinOffset = self.ubegin
- if not self.pins.has_key(self.ubegin):
+ if not self.ubegin in self.pins:
break
else:
self.uend -= ustep
pinOffset = self.uend
- if not self.pins.has_key(self.uend):
+ if not self.uend in self.pins:
break
else:
pinOffset = upos
@@ -148,7 +147,7 @@ class Side ( object ):
upos = pin.getY()
else:
upos = pin.getX()
- if not self.pins.has_key(upos):
+ if not upos in self.pins:
self.pins[upos] = [ pin ]
else:
self.pins[upos].append( pin )
@@ -194,7 +193,7 @@ class Side ( object ):
, pinPos.getX()
, pinPos.getY()
, gauge.getWireWidth()
- , gauge.getWireWidth() / 2
+ , gauge.getWireWidth() // 2
)
NetExternalComponents.setExternal( pin )
self.append( pin )
@@ -227,7 +226,7 @@ class Side ( object ):
, gauge.getLayer()
, pinPos.getX()
, pinPos.getY()
- , gauge.getWireWidth() / 2
+ , gauge.getWireWidth() // 2
, gauge.getWireWidth()
)
NetExternalComponents.setExternal( pin )
@@ -291,7 +290,7 @@ class Block ( object ):
@staticmethod
def lookup ( cell ):
- if Block.LUT.has_key(cell): return Block.LUT[cell]
+ if cell in Block.LUT: return Block.LUT[cell]
return None
def __init__ ( self, conf ):
@@ -834,6 +833,8 @@ class Block ( object ):
#if self.conf.useHFNS: self.findHfnTrees4()
self.initEtesian()
self.addHTrees()
+ sys.stdout.flush()
+ sys.stderr.flush()
#if self.conf.useHFNS: self.addHfnBuffers()
#if editor: editor.fit()
#Breakpoint.stop( 0, 'Clock tree(s) done.' )
diff --git a/cumulus/src/plugins/alpha/block/configuration.py b/cumulus/src/plugins/alpha/block/configuration.py
index 27bb23f2..3dd4fbf0 100644
--- a/cumulus/src/plugins/alpha/block/configuration.py
+++ b/cumulus/src/plugins/alpha/block/configuration.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -12,7 +12,6 @@
# | Python : "./plugins/block/configuration.py" |
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import re
import os.path
@@ -288,7 +287,7 @@ class GaugeConf ( object ):
trace( 550, ',+', '\tGaugeConf.rpAccess() {}\n'.format(rp) )
startDepth = self.routingGauge.getLayerDepth( rp.getOccurrence().getEntity().getLayer() )
trace( 550, '\tlayer:{} startDepth:{}\n'.format(rp.getOccurrence().getEntity().getLayer(),startDepth) )
- if self._rpToAccess.has_key(rp):
+ if rp in self._rpToAccess:
trace( 550, '-' )
return self._rpToAccess[rp]
if flags & GaugeConf.DeepDepth:
@@ -302,7 +301,7 @@ class GaugeConf ( object ):
#hoffset = self._routingGauge.getLayerGauge(hdepth).getOffset()
#contact1 = Contact.create( rp, self._routingGauge.getContactLayer(0), 0, 0 )
#midSliceY = contact1.getY() - (contact1.getY() % self._cellGauge.getSliceHeight()) \
- # + self._cellGauge.getSliceHeight() / 2
+ # + self._cellGauge.getSliceHeight() // 2
#midTrackY = midSliceY - ((midSliceY - hoffset) % hpitch)
#dy = midSliceY - contact1.getY()
#
@@ -377,7 +376,7 @@ class GaugeConf ( object ):
def rpByOccurrence ( self, occurrence, net ):
plug = occurrence.getEntity()
- if self._plugToRp.has_key(plug):
+ if plug in self._plugToRp:
rp = self._plugToRp[plug]
else:
rp = RoutingPad.create( net, occurrence, RoutingPad.BiggestArea )
@@ -386,7 +385,7 @@ class GaugeConf ( object ):
def rpAccessByOccurrence ( self, occurrence, net, flags ):
plug = occurrence.getEntity()
- if self._plugToRp.has_key(plug):
+ if plug in self._plugToRp:
rp = self._plugToRp[plug]
else:
rp = RoutingPad.create( net, occurrence, RoutingPad.BiggestArea )
@@ -394,7 +393,7 @@ class GaugeConf ( object ):
return self.rpAccess( self.rpByOccurrence(occurrence,net), flags )
def rpByPlug ( self, plug, net ):
- if self._plugToRp.has_key(plug):
+ if plug in self._plugToRp:
rp = self._plugToRp[plug]
else:
occurrence = Occurrence( plug, Path(net.getCell(),'') )
@@ -473,7 +472,7 @@ class GaugeConf ( object ):
minArea = self._routingGauge.getRoutingLayer( depth ).getMinimalArea()
extension = 0
if minArea:
- minLength = DbU.fromPhysical( minArea / DbU.toPhysical( wireWidth, DbU.UnitPowerMicro )
+ minLength = DbU.fromPhysical( minArea // DbU.toPhysical( wireWidth, DbU.UnitPowerMicro )
, DbU.UnitPowerMicro )
minLength = toFoundryGrid( minLength, DbU.SnapModeSuperior );
if isinstance(segment,Horizontal):
@@ -481,7 +480,7 @@ class GaugeConf ( object ):
uMax = segment.getTarget().getX()
segLength = abs( uMax - uMin )
if segLength < minLength:
- extension = toFoundryGrid( (minLength - segLength)/2, DbU.SnapModeSuperior )
+ extension = toFoundryGrid( (minLength - segLength)//2, DbU.SnapModeSuperior )
if uMin > uMax:
extension = - extension
segment.setDxSource( -extension )
@@ -491,7 +490,7 @@ class GaugeConf ( object ):
uMax = segment.getTarget().getY()
segLength = abs( uMax - uMin )
if segLength < minLength:
- extension = toFoundryGrid( (minLength - segLength)/2, DbU.SnapModeSuperior )
+ extension = toFoundryGrid( (minLength - segLength)//2, DbU.SnapModeSuperior )
if uMin > uMax:
extension = - extension
segment.setDySource( -extension )
@@ -1033,7 +1032,7 @@ class IoPin ( object ):
# , pinPos.getX()
# , pinPos.getY()
# , gauge.getWireWidth()
-# , gauge.getWireWidth() / 2
+# , gauge.getWireWidth() // 2
# )
# NetExternalComponents.setExternal( pin )
# side.append( self.flags, pin )
@@ -1061,7 +1060,7 @@ class IoPin ( object ):
# , gauge.getLayer()
# , pinPos.getX()
# , pinPos.getY()
-# , gauge.getWireWidth() / 2
+# , gauge.getWireWidth() // 2
# , gauge.getWireWidth()
# )
# NetExternalComponents.setExternal( pin )
@@ -1200,12 +1199,12 @@ class BlockConf ( GaugeConf ):
self.deltaAb = [ dx1, dy1, dx2, dy2 ]
def incIoPinsCounts ( self, net ):
- if not self.ioPinsCounts.has_key(net):
+ if not net in self.ioPinsCounts:
self.ioPinsCounts[net] = 0
self.ioPinsCounts[net] += 1
def getIoPinsCounts ( self, net ):
- if not self.ioPinsCounts.has_key(net): return 0
+ if not net in self.ioPinsCounts: return 0
return self.ioPinsCounts[net]
def resetBufferCount ( self ):
diff --git a/cumulus/src/plugins/alpha/block/hfns1.py b/cumulus/src/plugins/alpha/block/hfns1.py
index b0618ad0..c60ebf8e 100644
--- a/cumulus/src/plugins/alpha/block/hfns1.py
+++ b/cumulus/src/plugins/alpha/block/hfns1.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -16,7 +16,6 @@
Manage High Fanout Net Synthesis (HFNS).
"""
-from __future__ import print_function
import sys
import os.path
import re
@@ -121,11 +120,11 @@ class SlicedArea ( object ):
transf = instance.getTransformation()
occurrence.getPath().getTransformation().applyOn( transf )
transf.applyOn( ab )
- y = (ab.getYMin() - cellAb.getYMin()) / sliceHeight
+ y = (ab.getYMin() - cellAb.getYMin()) // sliceHeight
if (ab.getYMin() - cellAb.getYMin()) % sliceHeight:
print( ErrorMessage( 1, 'SlicedArea.__init__(): Misaligned {}.'.format(occurrence) ))
continue
- if not self.rows.has_key(y):
+ if not y in self.rows:
self.rows[y] = []
row = self.rows[ y ]
row.append( (occurrence,ab) )
@@ -584,7 +583,7 @@ class BufferTree ( object ):
maxWL = timing.tech.getWlEstimate( self.bufName, clusterA.size+clusterB.size )
area = Box( clusterA.area )
area.merge( clusterB.area )
- hpWL = (area.getWidth() + area.getHeight()) / 2
+ hpWL = (area.getWidth() + area.getHeight()) // 2
if hpWL >= maxWL:
return True
trace( 550, '\t> Reject merge: hpWL >= maxWL ({} >= {}).\n' \
@@ -596,7 +595,7 @@ class BufferTree ( object ):
return False
area = Box( clusterA.area )
area.merge( clusterB.area )
- hpwl = (area.getWidth() + area.getHeight()) / 2
+ hpwl = (area.getWidth() + area.getHeight()) // 2
if hpwl > 2*self.edgeLimit:
trace( 550, '\t> Reject merge, over HPWL threshold of 2*{}.\n' \
.format(DbU.getValueString(self.edgeLimit)))
diff --git a/cumulus/src/plugins/alpha/block/hfns2.py b/cumulus/src/plugins/alpha/block/hfns2.py
index 97db35d3..c369aecb 100644
--- a/cumulus/src/plugins/alpha/block/hfns2.py
+++ b/cumulus/src/plugins/alpha/block/hfns2.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -16,7 +16,6 @@
Manage High Fanout Net Synthesis (HFNS).
"""
-from __future__ import print_function
import sys
import os.path
import re
diff --git a/cumulus/src/plugins/alpha/block/hfns3.py b/cumulus/src/plugins/alpha/block/hfns3.py
index 10ba4a06..28c7d5bc 100644
--- a/cumulus/src/plugins/alpha/block/hfns3.py
+++ b/cumulus/src/plugins/alpha/block/hfns3.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -16,7 +16,6 @@
Manage High Fanout Net Synthesis (HFNS).
"""
-from __future__ import print_function
import sys
import os.path
import re
@@ -328,14 +327,14 @@ class Cluster ( object ):
graph.addNode( self
, driverCenter.getX()
, self.bufferTree.spares.toYGCellGrid(driverCenter.getY())
- + self.bufferTree.spares.conf.sliceHeight / 2
+ + self.bufferTree.spares.conf.sliceHeight // 2
, rsmt.Node.Driver )
for anchor in self.mergedAnchors:
sinkCenter = anchor.bInputRp.getPosition()
graph.addNode( anchor
, sinkCenter.getX()
, self.bufferTree.spares.toYGCellGrid(sinkCenter.getY())
- + self.bufferTree.spares.conf.sliceHeight / 2 )
+ + self.bufferTree.spares.conf.sliceHeight // 2 )
#graph.doIteratedOneSteiner()
graph.doFlute()
graph.createGRSegments()
@@ -479,7 +478,7 @@ class BufferTree ( object ):
maxWL = timing.tech.getWlEstimate( self.bufName, clusterA.size+clusterB.size )
area = Box( clusterA.area )
area.merge( clusterB.area )
- hpWL = (area.getWidth() + area.getHeight()) / 2
+ hpWL = (area.getWidth() + area.getHeight()) // 2
trace( 550, '\t> BufferTree.canMerge(): estimatedWL >= maxWL ({} >= {}).\n' \
.format(DbU.getValueString(estimatedWL),DbU.getValueString(maxWL)) )
if estimatedWL >= maxWL:
@@ -493,7 +492,7 @@ class BufferTree ( object ):
return False
area = Box( clusterA.area )
area.merge( clusterB.area )
- hpwl = (area.getWidth() + area.getHeight()) / 2
+ hpwl = (area.getWidth() + area.getHeight()) // 2
if hpwl > 2*self.edgeLimit:
trace( 550, '\t> Reject merge, over HPWL threshold of 2*{}.\n' \
.format(DbU.getValueString(self.edgeLimit)))
diff --git a/cumulus/src/plugins/alpha/block/hfns4.py b/cumulus/src/plugins/alpha/block/hfns4.py
index fbffc5b8..3aed3ed0 100644
--- a/cumulus/src/plugins/alpha/block/hfns4.py
+++ b/cumulus/src/plugins/alpha/block/hfns4.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -20,7 +20,6 @@ so each of them is under the fanout threshold. Basic method, do not
take into account the placement or the global wirelength.
"""
-from __future__ import print_function
import sys
import os.path
import re
diff --git a/cumulus/src/plugins/alpha/block/htree.py b/cumulus/src/plugins/alpha/block/htree.py
index 4f2063cf..0ed4422a 100644
--- a/cumulus/src/plugins/alpha/block/htree.py
+++ b/cumulus/src/plugins/alpha/block/htree.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -13,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import os.path
import Cfg
@@ -248,11 +247,11 @@ class HTree ( object ):
else:
driverPlugs.append( plugOcc )
quadTree.rsplitNetlist()
- if self.spares.conf.isCoreBlock:
- plug = utils.getPlugByName( quadTree.buffers[0], bufferConf.input )
- plug.setNet( self.treeNet )
- trace( 550, '\tCore mode, setting only root plug "{}"\n'.format(self.treeNet.getName()) )
- trace( 550, '\tPlug of "{}" (Cell:{})\n'.format(self.treeNet.getName()
- ,self.treeNet.getCell()) )
- for plug in self.treeNet.getPlugs():
- trace( 550, '\t| {}\n'.format(plug) )
+ #if self.spares.conf.isCoreBlock:
+ plug = utils.getPlugByName( quadTree.buffers[0], bufferConf.input )
+ plug.setNet( self.treeNet )
+ trace( 550, '\tCore mode, setting only root plug "{}"\n'.format(self.treeNet.getName()) )
+ trace( 550, '\tPlug of "{}" (Cell:{})\n'.format(self.treeNet.getName()
+ ,self.treeNet.getCell()) )
+ for plug in self.treeNet.getPlugs():
+ trace( 550, '\t| {}\n'.format(plug) )
diff --git a/cumulus/src/plugins/alpha/block/iospecs.py b/cumulus/src/plugins/alpha/block/iospecs.py
index c0043cc5..8db5218e 100644
--- a/cumulus/src/plugins/alpha/block/iospecs.py
+++ b/cumulus/src/plugins/alpha/block/iospecs.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne University 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -12,7 +12,6 @@
# | Python : "./plugins/block/iospecs.py" |
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import re
import os.path
@@ -99,7 +98,7 @@ class IoSpecs ( object ):
self._ioPadsSpec = []
def addIoPadSpec ( self, instance, side ):
- if self._ioPadsLUT.has_key(instance):
+ if instance in self._ioPadsLUT:
print( ErrorMessage( 2, 'IoSpecs.addIoPadSpec(): Duplicate pad specification for "{}" (ignored).' \
.format(instance) ) )
return self._ioPadsLUT[ instance ]
@@ -140,7 +139,7 @@ class IoSpecs ( object ):
for padDatas in datas['pads.instances']:
padName = padDatas[0]
- if not self._ioPadsLUT.has_key(padName):
+ if not padName in self._ioPadsLUT:
print( WarningMessage('IoSpecs.loadFromPinmux(): ' \
'Pad "{}" is not on any side, ignored.' \
.format(padName) ))
diff --git a/cumulus/src/plugins/alpha/block/matrix.py b/cumulus/src/plugins/alpha/block/matrix.py
index 1eb537ca..82a36e8d 100644
--- a/cumulus/src/plugins/alpha/block/matrix.py
+++ b/cumulus/src/plugins/alpha/block/matrix.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2021-2021, All Rights Reserved
+# Copyright (c) Sorbonne Université 2021-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -127,7 +127,7 @@ class RegisterMatrix ( object ):
sliceHeight = self.conf.sliceHeight
x = self.toXPitch( originX )
y = self.toYSlice( originY )
- slice = (y - yoffset) / sliceHeight
+ slice = (y - yoffset) // sliceHeight
orientation = Transformation.Orientation.ID
y = slice * sliceHeight + yoffset
if slice % 2:
diff --git a/cumulus/src/plugins/alpha/block/rsmt.py b/cumulus/src/plugins/alpha/block/rsmt.py
index 370a4cac..e623bdb6 100644
--- a/cumulus/src/plugins/alpha/block/rsmt.py
+++ b/cumulus/src/plugins/alpha/block/rsmt.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2014-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -292,7 +292,7 @@ class Graph ( object ):
def lookupNode ( self, x, y ):
geoKey = GeoKey( x, y )
- if self.nodesLUT.has_key(geoKey):
+ if geoKey in self.nodesLUT:
return self.nodesLUT[geoKey]
return None
diff --git a/cumulus/src/plugins/alpha/block/spares.py b/cumulus/src/plugins/alpha/block/spares.py
index 6fe69135..d510159f 100644
--- a/cumulus/src/plugins/alpha/block/spares.py
+++ b/cumulus/src/plugins/alpha/block/spares.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -70,7 +70,7 @@ class BufferPool ( object ):
def toIndex ( self, column, row ): return column + row*self.columns
- def fromIndex ( self, index ): return (index%self.columns, index/self.columns)
+ def fromIndex ( self, index ): return (index%self.columns, index//self.columns)
def unselect ( self ): self.selectedIndexes = []
@@ -145,11 +145,11 @@ class BufferPool ( object ):
yoffset = self.quadTree.spares.conf.icore.getTransformation().getTy()
conf = self.quadTree.spares.conf
sliceHeight = conf.sliceHeight
- poolHalfWidth = (conf.bufferConf.width * self.columns)/2 + conf.feedsConf.tieWidth()
- poolHalfHeight = (conf.bufferConf.height * self.rows)/2
+ poolHalfWidth = (conf.bufferConf.width * self.columns)//2 + conf.feedsConf.tieWidth()
+ poolHalfHeight = (conf.bufferConf.height * self.rows)//2
x = self.quadTree.spares.toXPitch( self.quadTree.area.getXCenter() - poolHalfWidth )
y = self.quadTree.spares.toYSlice( self.quadTree.area.getYCenter() - poolHalfHeight )
- slice = (y - yoffset) / sliceHeight
+ slice = (y - yoffset) // sliceHeight
trace( 540, '\tSlice height: {}\n'.format(DbU.getValueString(sliceHeight)) )
trace( 540, '\tSlice #{} (y:{})\n'.format(slice,DbU.getValueString(y)) )
for row in range(self.rows):
@@ -181,9 +181,9 @@ class BufferPool ( object ):
trace( 540, ',+', '\tQuadTree._createTies()\n' )
conf = self.quadTree.spares.conf
sliceHeight = conf.sliceHeight
- columns = self.quadTree.area.getWidth() / u(60.0)
+ columns = self.quadTree.area.getWidth() // u(60.0)
if columns % 2: columns += 1
- stepX = self.quadTree.area.getWidth() / columns
+ stepX = self.quadTree.area.getWidth() // columns
trace( 540, '\tcolumns:{}, stepX:{}\n' \
.format( columns, DbU.getValueString(stepX) ))
y = self.quadTree.area.getYMin()
@@ -191,7 +191,7 @@ class BufferPool ( object ):
for column in range(columns):
feed = conf.feedsConf.createFeed( conf.corona )
transf = self._getTransformation \
- ( self.quadTree.area.getXMin() + stepX/2 + column*stepX, y )
+ ( self.quadTree.area.getXMin() + stepX//2 + column*stepX, y )
feed.setTransformation( transf )
feed.setPlacementStatus( Instance.PlacementStatus.FIXED )
trace( 540, '\tBulk tie: {}\n'.format(feed) )
@@ -548,7 +548,7 @@ class QuadTree ( object ):
return False
if aspectRatio < 0.5:
- self.ycut = self.spares.toYSlice( self.area.getYMin() + self.area.getHeight()/2 )
+ self.ycut = self.spares.toYSlice( self.area.getYMin() + self.area.getHeight()//2 )
self.bl = QuadTree._create( self.spares
, self
, Box( self.area.getXMin()
@@ -567,7 +567,7 @@ class QuadTree ( object ):
trace( 540, '-' )
return True
elif aspectRatio > 2.0:
- self.xcut = self.spares.toXPitch( self.area.getXMin() + self.area.getWidth()/2 )
+ self.xcut = self.spares.toXPitch( self.area.getXMin() + self.area.getWidth()//2 )
self.bl = QuadTree._create( self.spares
, self
, Box( self.area.getXMin()
@@ -586,8 +586,8 @@ class QuadTree ( object ):
trace( 540, '-' )
return True
- self.ycut = self.spares.toYSlice( self.area.getYMin() + self.area.getHeight()/2 )
- self.xcut = self.spares.toXPitch( self.area.getXMin() + self.area.getWidth ()/2 )
+ self.ycut = self.spares.toYSlice( self.area.getYMin() + self.area.getHeight()//2 )
+ self.xcut = self.spares.toXPitch( self.area.getXMin() + self.area.getWidth ()//2 )
self.bl = QuadTree._create( self.spares
, self
, Box( self.area.getXMin()
@@ -829,7 +829,7 @@ class QuadTree ( object ):
plugOccsByAngle.sort( key=itemgetter(0) )
splitIndexes = []
if (len(plugOccsByAngle) > maxSinks) and (len(self.buffers) > 1):
- partSize = len(plugOccsByAngle) / len(self.buffers)
+ partSize = len(plugOccsByAngle) // len(self.buffers)
trace( 540, '\tpartSize: {}\n'.format(partSize) )
for isplit in range(1,len(self.buffers)):
maxdAngle = 0
@@ -931,7 +931,7 @@ class Spares ( object ):
if not spareSide:
raise ErrorMessage( 3, 'Spares.getSpareSpaceMargin(): "block.spareSide" parameter is zero ({}).' \
.format(spareSide) )
- areaLength = spareSide * spareSide / self.conf.sliceHeight
+ areaLength = spareSide * spareSide // self.conf.sliceHeight
bufferLength = self.conf.bufferConf.width * self.conf.bColumns * self.conf.bRows
if not areaLength:
raise ErrorMessage( 3, 'Spares.getSpareSpaceMargin(): Spare leaf area is zero.' )
@@ -972,7 +972,7 @@ class Spares ( object ):
sliceHeight = self.conf.sliceHeight
x = self.toXPitch( spareX )
y = self.toYSlice( spareY )
- slice = (y - yoffset) / sliceHeight
+ slice = (y - yoffset) // sliceHeight
orientation = Transformation.Orientation.ID
y = slice * sliceHeight + yoffset
if slice % 2:
@@ -1032,7 +1032,7 @@ class Spares ( object ):
sliceHeight = self.conf.sliceHeight
x = self.quadTree.toXPitch( position.getX() )
y = self.quadTree.toYSlice( position.getY() )
- slice = y / sliceHeight
+ slice = y // sliceHeight
orientation = Transformation.Orientation.ID
y = slice * sliceHeight
if slice % 2:
diff --git a/cumulus/src/plugins/alpha/block/timing.py b/cumulus/src/plugins/alpha/block/timing.py
index 2fe35933..4a30039a 100644
--- a/cumulus/src/plugins/alpha/block/timing.py
+++ b/cumulus/src/plugins/alpha/block/timing.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -81,7 +81,7 @@ class TechTimings ( object ):
self.capaPerLambda = 0.0
def addCell ( self, cellTiming ):
- if self.cells.has_key(cellTiming.name):
+ if cellTiming.name in self.cells:
print( ErrorMessage( 1, 'TechTimings.addCell(): Redefinition of timings for "{}"' \
.format(cellTiming.name) ))
self.cells[ cellTiming.name ] = cellTiming
@@ -92,12 +92,12 @@ class TechTimings ( object ):
def getWlEstimate ( self, cellName, sinks ):
drivingCapa = self.getDrivingCapa( cellName )
#print( 'sinks:{}, dC:{}, avgFanin:{}, CpL:{}'.format(sinks,drivingCapa,self.capaAvgFanin,self.capaPerLambda) )
- #print( '{}'.format((drivingCapa - self.capaAvgFanin*sinks) / self.capaPerLambda) )
- return DbU.fromLambda( (drivingCapa - self.capaAvgFanin*sinks) / self.capaPerLambda )
+ #print( '{}'.format((drivingCapa - self.capaAvgFanin*sinks) // self.capaPerLambda) )
+ return DbU.fromLambda( (drivingCapa - self.capaAvgFanin*sinks) // self.capaPerLambda )
def getOneSinkEqWL ( self ):
"""Return the equivalent wirelength of the sink average capacity."""
- return DbU.fromLambda(self.capaAvgFanin / self.capaPerLambda)
+ return DbU.fromLambda(self.capaAvgFanin // self.capaPerLambda)
def getSinksEstimate ( self, cellName ):
"""
@@ -105,10 +105,10 @@ class TechTimings ( object ):
wire to connect to each sink.
"""
drivingCapa = self.getDrivingCapa( cellName )
- return drivingCapa / (self.capaAvgFanin + 100.0*self.capaPerLambda)
+ return int(drivingCapa / (self.capaAvgFanin + 100.0*self.capaPerLambda))
def getDrivingCapa ( self, name ):
- if not self.cells.has_key(name):
+ if not name in self.cells:
print( ErrorMessage( 1, 'TechTimings.getDrivingCapa(): No timings for "{}"' \
.format(name) ))
return 0.0
diff --git a/cumulus/src/plugins/alpha/chip/__init__.py b/cumulus/src/plugins/alpha/chip/__init__.py
index 81d5cdf1..863a11fb 100644
--- a/cumulus/src/plugins/alpha/chip/__init__.py
+++ b/cumulus/src/plugins/alpha/chip/__init__.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -23,7 +23,6 @@ dictionnary of other modules.
OnHorizontalPitch & OnVerticalPitch.
"""
-from __future__ import print_function
from helpers.io import WarningMessage
North = 0x0001
@@ -53,6 +52,6 @@ def importConstants ( symbols ):
print( WarningMessage( 'plugins.chip.__init__.importConstants(), argument is not a symbol table.' ))
return
for symbol in globals().items():
- if isinstance(symbol[1],int) or isinstance(symbol[1],long):
- if not symbols.has_key(symbol[0]):
+ if isinstance(symbol[1],int):
+ if not symbol[0] in symbols:
symbols[ symbol[0] ] = symbol[1]
diff --git a/cumulus/src/plugins/alpha/chip/chip.py b/cumulus/src/plugins/alpha/chip/chip.py
index 6217296b..1724e9c9 100644
--- a/cumulus/src/plugins/alpha/chip/chip.py
+++ b/cumulus/src/plugins/alpha/chip/chip.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2014-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -13,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function, absolute_import
import sys
import traceback
import os.path
@@ -103,8 +102,8 @@ class Chip ( Block ):
, DbU.getValueString(coronaAb.getHeight()) ) )
with UpdateSession():
self.conf.core.setAbutmentBox( self.conf.coreAb )
- x = (coronaAb.getWidth () - self.conf.coreAb.getWidth ()) / 2
- y = (coronaAb.getHeight() - self.conf.coreAb.getHeight()) / 2
+ x = (coronaAb.getWidth () - self.conf.coreAb.getWidth ()) // 2
+ y = (coronaAb.getHeight() - self.conf.coreAb.getHeight()) // 2
trace( 550, '\tCore X, {} '.format(DbU.getValueString(x)) )
x = x - (x % self.conf.sliceHeight)
trace( 550, ' adjusted on {}, {}\n'.format( DbU.getValueString(self.conf.sliceHeight)
diff --git a/cumulus/src/plugins/alpha/chip/configuration.py b/cumulus/src/plugins/alpha/chip/configuration.py
index 3bc00c96..fcb1f0f6 100644
--- a/cumulus/src/plugins/alpha/chip/configuration.py
+++ b/cumulus/src/plugins/alpha/chip/configuration.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2014-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -12,7 +12,6 @@
# | Python : "./plugins/chip/configuration.py" |
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import os.path
import Cfg
@@ -69,7 +68,7 @@ class ChipConf ( BlockConf ):
* Outwards: the pitched box will fully enclose the original
box.
"""
- if isinstance(v,long): return ChipConf._toSymbolic( v, rounding )
+ if isinstance(v,int): return ChipConf._toSymbolic( v, rounding )
if isinstance(v,Box):
if rounding & Inwards:
roundings = [ Superior
@@ -206,12 +205,12 @@ class ChipConf ( BlockConf ):
, self.coreSize[1] - self.coreSize[1] % self.sliceHeight )
self.core.setAbutmentBox( Box( 0, 0, self.coreAb.getWidth(), self.coreAb.getHeight() ) )
trace( 550, '\tCORE ab:{}\n'.format(self.coreAb) )
- coreX = (self.coronaAb.getWidth () - self.coreAb.getWidth ()) / 2
+ coreX = (self.coronaAb.getWidth () - self.coreAb.getWidth ()) // 2
trace( 550, '\tCore X, {} '.format(DbU.getValueString(coreX)) )
coreX = coreX - (coreX % self.sliceHeight)
trace( 550, ' adjusted on {}, {}\n'.format( DbU.getValueString(self.sliceHeight)
, DbU.getValueString(coreX)) )
- coreY = (self.coronaAb.getHeight() - self.coreAb.getHeight()) / 2
+ coreY = (self.coronaAb.getHeight() - self.coreAb.getHeight()) // 2
coreY = coreY - (coreY % self.sliceHeight)
self.icore.setTransformation( Transformation( coreX, coreY, Transformation.Orientation.ID ) )
self.icore.setPlacementStatus( Instance.PlacementStatus.FIXED )
@@ -255,13 +254,13 @@ class ChipConf ( BlockConf ):
if iTrackMax < iTrackMin: iTrackMax = iTrackMin
uTrackMin = lg.getTrackPosition( abMin, iTrackMin )
uTrackMax = lg.getTrackPosition( abMin, iTrackMax )
- axis = (uTrackMax + uTrackMin) / 2
+ axis = (uTrackMax + uTrackMin) // 2
width = (iTrackMax - iTrackMin) * lg.getPitch() + lg.getWireWidth()
if self.routingGauge.isSymbolic():
trace( 550, '\tRoutingGauge is symbolic, adjust on lambda.\n' )
oneLambda = DbU.fromLambda( 1.0 )
if axis % oneLambda:
- axis -= oneLambda / 2
+ axis -= oneLambda // 2
width -= oneLambda
trace( 550, '\t[{} {}] -> [{} {}]\n'.format( iTrackMin
, iTrackMax
@@ -270,7 +269,7 @@ class ChipConf ( BlockConf ):
trace( 550, '\taxis: {:.1f}L {}\n'.format(DbU.toLambda(axis ), DbU.getValueString(axis )) )
trace( 550, '\twidth: {:.1f}L {}\n'.format(DbU.toLambda(width), DbU.getValueString(width)) )
else:
- axis = (uMax + uMin) / 2
+ axis = (uMax + uMin) // 2
width = (uMax - uMin)
trace( 550, '-' )
return axis, width
@@ -323,7 +322,7 @@ class ChipConf ( BlockConf ):
.format( DbU.getValueString(chipXMin - coronaAb.getXMin())
, DbU.toLambda(chipXMin - coronaAb.getXMin()) ) )
trace( 550, '\t| dxMax:{}\n'.format(DbU.getValueString(chipXMax - coronaAb.getXMin())) )
- coronaY, width = self.toRoutingGauge( coronaY - width/2, coronaY + width/2, layer )
+ coronaY, width = self.toRoutingGauge( coronaY - width//2, coronaY + width//2, layer )
trace( 550, '\t| On Grid\n' )
trace( 550, '\t| axis: {:.1f}L or {}\n'.format(DbU.toLambda(coronaY), DbU.getValueString(coronaY)) )
trace( 550, '\t| width:{:.1f}L or {}\n'.format(DbU.toLambda(width) , DbU.getValueString(width)) )
@@ -346,7 +345,7 @@ class ChipConf ( BlockConf ):
trace( 550, '\t| Real\n' )
trace( 550, '\t| axis: {}\n'.format(DbU.getValueString(coronaX)) )
trace( 550, '\t| width:{}\n'.format(DbU.getValueString(width)) )
- coronaX, width = self.toRoutingGauge( coronaX - width/2, coronaX + width/2, layer )
+ coronaX, width = self.toRoutingGauge( coronaX - width//2, coronaX + width//2, layer )
trace( 550, '\t| On Grid\n' )
trace( 550, '\t| axis: {:.1f}L or {}\n'.format(DbU.toLambda(coronaX), DbU.getValueString(coronaX)) )
trace( 550, '\t| width:{:.1f}L or {}\n'.format(DbU.toLambda(width) , DbU.getValueString(width)) )
@@ -369,11 +368,11 @@ class ChipConf ( BlockConf ):
topLayer = layer.getTop()
botLayer = layer.getBottom()
if self.isHorizontal(topLayer):
- coronaX, width = self.toRoutingGauge( coronaX - width /2, coronaX + width /2, botLayer )
- coronaY, height = self.toRoutingGauge( coronaY - height/2, coronaY + height/2, topLayer )
+ coronaX, width = self.toRoutingGauge( coronaX - width //2, coronaX + width //2, botLayer )
+ coronaY, height = self.toRoutingGauge( coronaY - height//2, coronaY + height//2, topLayer )
else:
- coronaX, width = self.toRoutingGauge( coronaX - width /2, coronaX + width /2, topLayer )
- coronaY, height = self.toRoutingGauge( coronaY - height/2, coronaY + height/2, botLayer )
+ coronaX, width = self.toRoutingGauge( coronaX - width //2, coronaX + width //2, topLayer )
+ coronaY, height = self.toRoutingGauge( coronaY - height//2, coronaY + height//2, botLayer )
if not (flags & OnHorizontalPitch):
trace( 550, '\tNot on horizontal routing pitch, Y on lambda only.\n' )
coronaY = self.toSymbolic( chipY - coronaAb.getYMin(), Superior )
@@ -437,8 +436,8 @@ class ChipConf ( BlockConf ):
trace( 550, '\tNot on vertical routing pitch, X on lambda only.\n' )
coronaX = self.toSymbolic( chipX - coronaAb.getXMin(), Superior )
contacts = []
- xContact = coronaX - viaPitch * (array[0]-1)/2
- yContact = coronaY - viaPitch * (array[1]-1)/2
+ xContact = coronaX - viaPitch * (array[0]-1)//2
+ yContact = coronaY - viaPitch * (array[1]-1)//2
contactSize = layer.getMinimalSize()
trace( 550, '\txContact:{} yContact:{}\n'.format(DbU.getValueString(xContact),DbU.getValueString(yContact)) )
for i in range(array[0]):
@@ -468,11 +467,11 @@ class ChipConf ( BlockConf ):
trace( 550, '\t| WxH: {} {}\n'.format(DbU.getValueString(width ), DbU.getValueString(height )) )
topLayer = layer.getTop()
if self.isHorizontal(topLayer):
- coronaX, width = self.toRoutingGauge( coronaX - width /2, coronaX + width /2, layer.getBottom() )
- coronaY, height = self.toRoutingGauge( coronaY - height/2, coronaY + height/2, topLayer )
+ coronaX, width = self.toRoutingGauge( coronaX - width //2, coronaX + width //2, layer.getBottom() )
+ coronaY, height = self.toRoutingGauge( coronaY - height//2, coronaY + height//2, topLayer )
else:
- coronaX, width = self.toRoutingGauge( coronaX - width /2, coronaX + width /2, topLayer )
- coronaY, height = self.toRoutingGauge( coronaY - height/2, coronaY + height/2, layer.getBottom() )
+ coronaX, width = self.toRoutingGauge( coronaX - width //2, coronaX + width //2, topLayer )
+ coronaY, height = self.toRoutingGauge( coronaY - height//2, coronaY + height//2, layer.getBottom() )
if direction == Pin.Direction.NORTH or direction == Pin.Direction.SOUTH:
trace( 550, '\tEast/West not on horizontal routing pitch, Y on lambda only.\n' )
coronaY = self.toSymbolic( chipY - coronaAb.getYMin(), Superior )
@@ -648,7 +647,7 @@ class ChipConf ( BlockConf ):
if not padNet and coronaNet.isGlobal():
padNet = self.chip.getNet( coronaNet.getName() )
if padNet:
- if not netPads.has_key(padNet):
+ if not padNet in netPads:
trace( 550, '\t{:>20} <-> {:<20}\n'.format(padNet.getName(),coronaNet.getName()) )
netPads[ padNet ] = coronaNet
else:
diff --git a/cumulus/src/plugins/alpha/chip/corona.py b/cumulus/src/plugins/alpha/chip/corona.py
index 081780dc..1ca8cb0d 100644
--- a/cumulus/src/plugins/alpha/chip/corona.py
+++ b/cumulus/src/plugins/alpha/chip/corona.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2014-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -13,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import bisect
from operator import methodcaller
import Cfg
@@ -114,9 +113,9 @@ class HorizontalRail ( Rail ):
print (ErrorMessage( 1, [ '{} is outside rail/corona X range,'.format(contact)
, 'power pad is likely to be to far off west or east.'
, '(core:{})'.format(self.side.innerBb) ] ) )
- if self.vias.has_key(contact.getX()): return False
+ if contact.getX() in self.vias: return False
trace( 550, '\tvias:{}\n'.format(self.vias) )
- keys = self.vias.keys()
+ keys = list( self.vias.keys() )
keys.sort()
insertIndex = bisect.bisect_left( keys, contact.getX() )
if len(keys) > 0:
@@ -228,10 +227,10 @@ class VerticalRail ( Rail ):
print (ErrorMessage( 1, [ '{} is outside rail/corona Y range'.format(contact)
, 'power pad is likely to be to far off north or south.'
, '(core:{})'.format(self.side.innerBb) ] ) )
- if self.vias.has_key(contact.getY()): return False
+ if contact.getY() in self.vias: return False
trace( 550, ',+', '\tVerticalRail.connect() [{}] @{}\n'.format(self.order,DbU.getValueString(self.axis)) )
trace( 550, '\t{}\n'.format(contact) )
- keys = self.vias.keys()
+ keys = list( self.vias.keys() )
keys.sort()
insertIndex = bisect.bisect_left( keys, contact.getY() )
trace( 550, ',+', '\tkeys:' )
@@ -362,7 +361,7 @@ class Side ( object ):
if self.horizontalDepth > self.verticalDepth:
return range( len(self.coronaCks), len(self.rails) )
trace( 550, '\tUsing half rails only.\n' )
- return range( len(self.coronaCks) + len(self.rails)/2 - 2, len(self.rails) )
+ return range( len(self.coronaCks) + len(self.rails)//2 - 2, len(self.rails) )
def connectPads ( self, padSide ):
#for contact in padSide.pins:
@@ -412,8 +411,8 @@ class SouthSide ( HorizontalSide ):
def side ( self ): return South
def getRailAxis ( self, i ):
- return self.innerBb.getYMin() - self.hRailWidth/2 - self.hRailSpace \
- - i*(self.hRailWidth + self.hRailSpace)
+ return self.innerBb.getYMin() - self.hRailWidth//2 - self.hRailSpace \
+ - i*(self.hRailWidth + self.hRailSpace)
def corner0 ( self, i ): return self.corners[SouthWest][i]
def corner1 ( self, i ): return self.corners[SouthEast][i]
@@ -432,8 +431,8 @@ class NorthSide ( HorizontalSide ):
def side ( self ): return North
def getRailAxis ( self, i ):
- return self.innerBb.getYMax() + self.hRailWidth/2 + self.hRailSpace \
- + i*(self.hRailWidth + self.hRailSpace)
+ return self.innerBb.getYMax() + self.hRailWidth//2 + self.hRailSpace \
+ + i*(self.hRailWidth + self.hRailSpace)
def corner0 ( self, i ): return self.corners[NorthWest][i]
def corner1 ( self, i ): return self.corners[NorthEast][i]
@@ -457,16 +456,16 @@ class VerticalSide ( Side ):
for rail in self.rails:
for via in rail.vias.values():
if via[1].getNet() != via[2].getNet(): continue
- spans.merge( via[1].y - via[1].height/2, via[1].y + via[1].height/2 )
+ spans.merge( via[1].y - via[1].height//2, via[1].y + via[1].height//2 )
routingGauge = self.corona.routingGauge
- for depth in range(self.getOuterRail(0).vias.values()[0][1].bottomDepth
- ,self.getOuterRail(0).vias.values()[0][1].topDepth ):
+ for depth in range(next(iter(self.getOuterRail(0).vias.values()))[1].bottomDepth
+ ,next(iter(self.getOuterRail(0).vias.values()))[1].topDepth ):
blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
pitch = routingGauge.getLayerPitch(depth)
for chunk in spans.chunks:
Horizontal.create( self.blockageNet
, blockageLayer
- , (chunk.getVMax() + chunk.getVMin())/2
+ , (chunk.getVMax() + chunk.getVMin())//2
, chunk.getVMax() - chunk.getVMin() + pitch*2
, sideXMin
, sideXMax
@@ -478,7 +477,7 @@ class VerticalSide ( Side ):
for chunk in spans.chunks:
Horizontal.create( self.blockageNet
, blockageLayer
- , (chunk.getVMax() + chunk.getVMin())/2
+ , (chunk.getVMax() + chunk.getVMin())//2
, chunk.getVMax() - chunk.getVMin() + pitch*2
, sideXMin
, sideXMax
@@ -497,8 +496,8 @@ class WestSide ( VerticalSide ):
def side ( self ): return West
def getRailAxis ( self, i ):
- return self.innerBb.getXMin() - self.vRailWidth/2 - self.vRailSpace \
- - i*(self.vRailWidth + self.vRailSpace)
+ return self.innerBb.getXMin() - self.vRailWidth//2 - self.vRailSpace \
+ - i*(self.vRailWidth + self.vRailSpace)
def corner0 ( self, i ): return self.corners[SouthWest][i]
def corner1 ( self, i ): return self.corners[NorthWest][i]
@@ -521,8 +520,8 @@ class EastSide ( VerticalSide ):
def side ( self ): return East
def getRailAxis ( self, i ):
- return self.innerBb.getXMax() + self.vRailWidth/2 + self.vRailSpace \
- + i*(self.vRailWidth + self.vRailSpace)
+ return self.innerBb.getXMax() + self.vRailWidth//2 + self.vRailSpace \
+ + i*(self.vRailWidth + self.vRailSpace)
def corner0 ( self, i ): return self.corners[SouthEast][i]
def corner1 ( self, i ): return self.corners[NorthEast][i]
@@ -542,7 +541,7 @@ class Builder ( object ):
self.block = block
self.innerBb = self.block.icoreAb
self.block.path.getTransformation().applyOn( self.innerBb )
- self.innerBb.inflate( self.hRailSpace/2, self.vRailSpace/2 )
+ self.innerBb.inflate( self.hRailSpace//2, self.vRailSpace//2 )
self.southSide = SouthSide( self )
self.northSide = NorthSide( self )
self.westSide = WestSide ( self )
diff --git a/cumulus/src/plugins/alpha/chip/pads.py b/cumulus/src/plugins/alpha/chip/pads.py
index f2640d52..f4851394 100644
--- a/cumulus/src/plugins/alpha/chip/pads.py
+++ b/cumulus/src/plugins/alpha/chip/pads.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2014-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -13,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import re
import copy
@@ -65,28 +64,28 @@ class Corner ( object ):
yCorner = self.conf.chipAb.getYMin() + axis
xBb = self.conf.chipAb.getXMin() + self.conf.ioPadHeight
yBb = self.conf.chipAb.getYMin() + self.conf.ioPadHeight
- xExtend = - onFGrid( long( 0.5 * float(self.conf.ioPadHeight - axis) ) )
+ xExtend = - onFGrid( int( 0.5 * float(self.conf.ioPadHeight - axis) ) )
yExtend = xExtend
elif self.type == SouthEast:
xCorner = self.conf.chipAb.getXMax() - axis
yCorner = self.conf.chipAb.getYMin() + axis
xBb = self.conf.chipAb.getXMax() - self.conf.ioPadHeight
yBb = self.conf.chipAb.getYMin() + self.conf.ioPadHeight
- xExtend = onFGrid( long( 0.5 * float(self.conf.ioPadHeight - axis) ) )
+ xExtend = onFGrid( int( 0.5 * float(self.conf.ioPadHeight - axis) ) )
yExtend = - xExtend
elif self.type == NorthEast:
xCorner = self.conf.chipAb.getXMax() - axis
yCorner = self.conf.chipAb.getYMax() - axis
xBb = self.conf.chipAb.getXMax() - self.conf.ioPadHeight
yBb = self.conf.chipAb.getYMax() - self.conf.ioPadHeight
- xExtend = onFGrid( long( 0.5 * float(self.conf.ioPadHeight - axis) ) )
+ xExtend = onFGrid( int( 0.5 * float(self.conf.ioPadHeight - axis) ) )
yExtend = xExtend
elif self.type == NorthWest:
xCorner = self.conf.chipAb.getXMin() + axis
yCorner = self.conf.chipAb.getYMax() - axis
xBb = self.conf.chipAb.getXMin() + self.conf.ioPadHeight
yBb = self.conf.chipAb.getYMax() - self.conf.ioPadHeight
- xExtend = - onFGrid( long( 0.5 * float(self.conf.ioPadHeight - axis) ) )
+ xExtend = - onFGrid( int( 0.5 * float(self.conf.ioPadHeight - axis) ) )
yExtend = - xExtend
return xCorner, yCorner, xBb, yBb, xExtend, yExtend
@@ -370,7 +369,7 @@ class Side ( object ):
def _placePads ( self ):
padLength = 0
for pad in self.pads: padLength += pad[1].getMasterCell().getAbutmentBox().getWidth()
- padSpacing = (self.sideLength - 2*self.conf.ioPadHeight - padLength) / (len(self.pads) + 1)
+ padSpacing = (self.sideLength - 2*self.conf.ioPadHeight - padLength) // (len(self.pads) + 1)
if self.conf.padsHavePosition:
position = self.u
for pad in self.pads:
@@ -414,8 +413,8 @@ class Side ( object ):
uMin -= DbU.fromLambda(5.0)
uMax += DbU.fromLambda(5.0)
else:
- uMin -= width/2
- uMax += width/2
+ uMin -= width//2
+ uMax += width//2
if self.type == North or self.type == South:
if self.type == North:
axis = self.conf.chipAb.getYMax() - axis
@@ -583,7 +582,7 @@ class CoreWire ( object ):
, Layer.EnclosureH|Layer.EnclosureV ) \
+ self.symContactLayer.getMinimalSize()
arrayWidth = self.symContactSize[0]
- arrayCount = (arrayWidth - contactMinSize) / self.viaPitch
+ arrayCount = (arrayWidth - contactMinSize) // self.viaPitch
trace( 550, '\tcontactMinSize: {}, arrayWidth: {}, arrayCount: {}\n' \
.format(DbU.getValueString(contactMinSize),DbU.getValueString(arrayWidth),arrayCount) )
if arrayCount < 0: arrayCount = 0
@@ -624,7 +623,7 @@ class CoreWire ( object ):
xPadMax = xContact
xCore = coronaAb.getXMin()
if not self.preferredDir:
- #xPadMax += self.bbSegment.getHeight()/2
+ #xPadMax += self.bbSegment.getHeight()//2
xPadMin += 3*vPitch
else:
accessDirection = Pin.Direction.EAST
@@ -633,7 +632,7 @@ class CoreWire ( object ):
xPadMin = xContact
xCore = coronaAb.getXMax()
if not self.preferredDir:
- #xPadMin -= self.bbSegment.getHeight()/2
+ #xPadMin -= self.bbSegment.getHeight()//2
xPadMin -= 3*vPitch
if self.addJumper:
rg = self.conf.routingGauge
@@ -644,8 +643,8 @@ class CoreWire ( object ):
gapCenter = xPadMin + 5*gaugeM5.getPitch()
else:
gapCenter = xPadMax - 5*gaugeM5.getPitch()
- xJumpMin = gapCenter - jumperGap/2
- xJumpMax = gapCenter + jumperGap/2
+ xJumpMin = gapCenter - jumperGap//2
+ xJumpMax = gapCenter + jumperGap//2
hReal1 = Horizontal.create( self.chipNet
, self.padSegment.getLayer()
, self.bbSegment.getCenter().getY()
@@ -771,7 +770,7 @@ class CoreWire ( object ):
yContact = yPadMax
yCore = coronaAb.getYMin()
#if not self.preferredDir:
- # yPadMax += self.bbSegment.getWidth()/2
+ # yPadMax += self.bbSegment.getWidth()//2
# yPadMin += 3*hPitch
else:
accessDirection = Pin.Direction.NORTH
@@ -780,7 +779,7 @@ class CoreWire ( object ):
yContact = yPadMin
yCore = coronaAb.getYMax()
#if not self.preferredDir:
- # yPadMin -= self.bbSegment.getWidth()/2
+ # yPadMin -= self.bbSegment.getWidth()//2
# yPadMin -= 3*hPitch
vReal = Vertical.create( self.chipNet
, self.padSegment.getLayer()
@@ -987,7 +986,7 @@ class Corona ( object ):
if plug.getMasterNet().isClock():
hspan.inflate( DbU.fromLambda(5.0) )
else:
- hspan.inflate( component.getWidth() / 2 )
+ hspan.inflate( component.getWidth() // 2 )
if hspan.contains( ab.getXMin() ) or hspan.contains( ab.getXMax() ):
duplicate = False
if self.padOrient == Transformation.Orientation.ID:
@@ -1056,21 +1055,21 @@ class Corona ( object ):
if side.type == North or side.type == South:
#bb.inflate( -u(0.6), 0 )
if bb.getWidth() > u(35.0):
- bb.inflate( (u(34.0) - bb.getWidth()) / 2, 0 )
+ bb.inflate( (u(34.0) - bb.getWidth()) // 2, 0 )
else:
#bb.inflate( 0, -u(0.6) )
if bb.getHeight() > u(35.0):
- bb.inflate( 0, (u(34.0) - bb.getHeight()) / 2 )
+ bb.inflate( 0, (u(34.0) - bb.getHeight()) // 2 )
if bb.intersect(innerBb):
trace( 550, '\t| Accepted.\n' )
lg = rg.getLayerGauge( component.getLayer() )
depth = lg.getDepth()
if depth > self.conf.topLayerDepth: continue
if lg.getDirection() == RoutingLayerGauge.Vertical:
- if not vsegments.has_key(depth): vsegments[ depth ] = []
+ if not depth in vsegments: vsegments[ depth ] = []
vsegments[ depth ].append( (component,bb) )
else:
- if not hsegments.has_key(depth): hsegments[ depth ] = []
+ if not depth in hsegments: hsegments[ depth ] = []
hsegments[ depth ].append( (component,bb) )
gapWidth = 0
segments = None
@@ -1152,10 +1151,10 @@ class Corona ( object ):
.format(chipIntNet.getName()) )
self.conf.setupCorona( self.westSide.gap, self.southSide.gap, self.eastSide.gap, self.northSide.gap )
self.coreSymBb = self.conf.getInstanceAb( self.conf.icorona )
- self.coreSymBb.inflate( self.conf.toSymbolic( self.westSide.gap /2, Superior )
- , self.conf.toSymbolic( self.southSide.gap/2, Superior )
- , self.conf.toSymbolic( self.eastSide.gap /2, Inferior )
- , self.conf.toSymbolic( self.northSide.gap/2, Inferior ) )
+ self.coreSymBb.inflate( self.conf.toSymbolic( self.westSide.gap //2, Superior )
+ , self.conf.toSymbolic( self.southSide.gap//2, Superior )
+ , self.conf.toSymbolic( self.eastSide.gap //2, Inferior )
+ , self.conf.toSymbolic( self.northSide.gap//2, Inferior ) )
self.southSide.drawCoreWires()
self.northSide.drawCoreWires()
self.eastSide .drawCoreWires()
@@ -1349,13 +1348,13 @@ class Corona ( object ):
xcore = icore.getTransformation().getTx()
stripeSpecs = []
stripesNb = int( (coreAb.getWidth() - 8*capViaWidth + self.supplyRailWidth) \
- / self.supplyRailPitch - 1 )
- offset = (coreAb.getWidth() - self.supplyRailPitch*(stripesNb-1)) / 2
- stripeSpecs.append( [ xcore + capViaWidth/2 , capViaWidth ] )
- stripeSpecs.append( [ xcore + 2*capViaWidth + capViaWidth/2 , capViaWidth ] )
+ // self.supplyRailPitch - 1 )
+ offset = (coreAb.getWidth() - self.supplyRailPitch*(stripesNb-1)) // 2
+ stripeSpecs.append( [ xcore + capViaWidth//2 , capViaWidth ] )
+ stripeSpecs.append( [ xcore + 2*capViaWidth + capViaWidth//2 , capViaWidth ] )
if self.chip.spares and len(self.chip.spares.rleafX) > 1:
rleafX = self.chip.spares.rleafX
- spacing = (rleafX[1] - rleafX[0]) / 2
+ spacing = (rleafX[1] - rleafX[0]) // 2
stepOffset = 0
step = 1
trace( 550, '\trleafX\n' )
@@ -1364,7 +1363,7 @@ class Corona ( object ):
if spacing < self.supplyRailPitch:
stepOffset = 1
step = 2
- spacing = (rleafX[2] - rleafX[0]) / 2
+ spacing = (rleafX[2] - rleafX[0]) // 2
if step == 1:
stripeSpecs.append( [ rleafX[0] - spacing, self.supplyRailWidth ] )
trace( 550, '\tstripe[N/A] @{}\n'.format(DbU.getValueString(stripeSpecs[-1][0])))
@@ -1382,8 +1381,8 @@ class Corona ( object ):
stripeSpecs.append( [ xcore + offset + i*self.supplyRailPitch
, self.supplyRailWidth
] )
- stripeSpecs.append( [ xcore + coreAb.getWidth() - 2*capViaWidth - capViaWidth/2 , capViaWidth ] )
- stripeSpecs.append( [ xcore + coreAb.getWidth() - capViaWidth/2 , capViaWidth ] )
+ stripeSpecs.append( [ xcore + coreAb.getWidth() - 2*capViaWidth - capViaWidth//2 , capViaWidth ] )
+ stripeSpecs.append( [ xcore + coreAb.getWidth() - capViaWidth//2 , capViaWidth ] )
trace( 550, '\ticoreAb={}\n'.format(icore.getAbutmentBox()) )
trace( 550, '\tcapViaWidth={}\n'.format(DbU.getValueString(capViaWidth)))
diff --git a/cumulus/src/plugins/alpha/chip/power.py b/cumulus/src/plugins/alpha/chip/power.py
index ca66dd41..e32a8563 100644
--- a/cumulus/src/plugins/alpha/chip/power.py
+++ b/cumulus/src/plugins/alpha/chip/power.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -45,7 +44,7 @@ class Side ( object ):
self.terminals = []
def addTerminal ( self, position, width ):
- toMerge = Interval( position-width/2, position+width/2 )
+ toMerge = Interval( position-width//2, position+width//2 )
length = len(self.terminals)
imerge = length
ichunk = 0
@@ -104,8 +103,8 @@ class Side ( object ):
class Plane ( object ):
- Horizontal = 0001
- Vertical = 0002
+ Horizontal = 1
+ Vertical = 2
def __init__ ( self, builder, metal ):
self.builder = builder
@@ -113,7 +112,7 @@ class Plane ( object ):
self.sides = {}
def addTerminal ( self, net, direction, bb ):
- if not self.sides.has_key(net):
+ if not net in self.sides:
self.sides[ net ] = { North : Side(self.builder,North,net,self.metal)
, South : Side(self.builder,South,net,self.metal)
, East : Side(self.builder,East ,net,self.metal)
@@ -135,6 +134,7 @@ class Plane ( object ):
sides[South].addTerminal( bb.getCenter().getX(), bb.getWidth() )
if bb.getYMax() >= self.builder.icoreAb.getYMax():
sides[North].addTerminal( bb.getCenter().getX(), bb.getWidth() )
+ trace( 550, '\tTerminal added\n' )
def doLayout ( self ):
for sidesOfNet in self.sides.values():
@@ -157,8 +157,8 @@ class GoCb ( object ):
if not direction: return
trace( 550, '\t| go={}\n'.format( go ))
rootNet = None
- if go.getNet().getType() == long(Net.Type.POWER): rootNet = self.builder.conf.coronaVdd
- if go.getNet().getType() == long(Net.Type.GROUND): rootNet = self.builder.conf.coronaVss
+ if go.getNet().getType() == int(Net.Type.POWER): rootNet = self.builder.conf.coronaVdd
+ if go.getNet().getType() == int(Net.Type.GROUND): rootNet = self.builder.conf.coronaVss
if not rootNet: return
if self.builder.activePlane:
layer = self.builder.activePlane.metal
@@ -170,7 +170,7 @@ class GoCb ( object ):
query.getPath().getTransformation().applyOn( bb )
self.builder.activePlane.addTerminal( rootNet, direction, bb )
else:
- print WarningMessage( 'BlockPower.GoCb() callback called without an active plane.' )
+ print( WarningMessage( 'BlockPower.GoCb() callback called without an active plane.' ))
return
@@ -254,7 +254,7 @@ class Builder ( object ):
def connectClocks ( self ):
if not self.conf.useClockTree:
- print WarningMessage( "Clock tree generation has been disabled ('chip.clockTree':False)." )
+ print( WarningMessage( "Clock tree generation has been disabled ('chip.clockTree':False)." ))
return
if len(self.conf.coronaCks) == 0:
raise ErrorMessage( 1, 'Cannot build clock terminal as no clock is not known.' )
diff --git a/cumulus/src/plugins/alpha/chip/powerplane.py b/cumulus/src/plugins/alpha/chip/powerplane.py
index b85feff7..19bcf5d0 100644
--- a/cumulus/src/plugins/alpha/chip/powerplane.py
+++ b/cumulus/src/plugins/alpha/chip/powerplane.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2021-2021, All Rights Reserved
+# Copyright (c) Sorbonne Université 2021-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -13,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
from Hurricane import DbU, Point, Transformation, Box, Interval, \
Path, Occurrence, UpdateSession, Net, \
@@ -136,16 +135,16 @@ class HorizontalRail ( Rail ):
trace( 550, '\t| Chunk=[{} {}]\n'.format( DbU.getValueString(chunk.getVMin())
, DbU.getValueString(chunk.getVMax()) ))
chunkBb = Box( chunk.getVMin()
- , self.axis - self.width/2
+ , self.axis - self.width//2
, chunk.getVMax()
- , self.axis + self.width/2 )
+ , self.axis + self.width//2 )
overlap = stripeBb.getIntersection( chunkBb )
if overlap.isEmpty(): continue
if overlap.getWidth() > 5*viaWidth:
trace( 550, '\t| Large overlap={}\n'.format(overlap) )
via = BigVia( stripe.getNet()
, plane.getLayerDepth(stripe.getLayer())
- , overlap.getXMin() + viaWidth/2
+ , overlap.getXMin() + viaWidth//2
, overlap.getYCenter()
, viaWidth
, overlap.getHeight()
@@ -155,7 +154,7 @@ class HorizontalRail ( Rail ):
via.doLayout()
via = BigVia( stripe.getNet()
, plane.getLayerDepth(stripe.getLayer())
- , overlap.getXMax() - viaWidth/2
+ , overlap.getXMax() - viaWidth//2
, overlap.getYCenter()
, viaWidth
, overlap.getHeight()
@@ -217,9 +216,9 @@ class Rails ( object ):
else:
axis = bb.getXCenter()
width = bb.getWidth()
- if not self.axisLut.has_key(axis):
+ if not axis in self.axisLut:
self.axisLut[ axis ] = {}
- if not self.axisLut[axis].has_key(width):
+ if not width in self.axisLut[axis]:
if self.isHorizontal:
self.axisLut[ axis ][ width ] = HorizontalRail( bb )
else:
@@ -259,8 +258,8 @@ class VerticalRails ( Rails ):
class Plane ( object ):
- Horizontal = 0001
- Vertical = 0002
+ Horizontal = 1
+ Vertical = 2
def __init__ ( self, builder, metal ):
self.builder = builder
@@ -358,20 +357,20 @@ class Stripes ( object ):
if pin.getLayer() != self.supplyLayer: continue
key = pin.getX()
if pin.getAccessDirection() == Pin.Direction.SOUTH:
- if not self.powers.has_key(key): self.powers[ key ] = Stripe( self, pin, None )
- else: self.powers[ key ].southPin = pin
+ if not key in self.powers: self.powers[ key ] = Stripe( self, pin, None )
+ else: self.powers[ key ].southPin = pin
elif pin.getAccessDirection() == Pin.Direction.NORTH:
- if not self.powers.has_key(key): self.powers[ key ] = Stripe( self, None, pin )
- else: self.powers[ key ].northPin = pin
+ if not key in self.powers: self.powers[ key ] = Stripe( self, None, pin )
+ else: self.powers[ key ].northPin = pin
for pin in self.conf.coronaVss.getPins():
if pin.getLayer() != self.supplyLayer: continue
key = pin.getX()
if pin.getAccessDirection() == Pin.Direction.SOUTH:
- if not self.grounds.has_key(key): self.grounds[ key ] = Stripe( self, pin, None )
- else: self.grounds[ key ].southPin = pin
+ if not key in self.grounds: self.grounds[ key ] = Stripe( self, pin, None )
+ else: self.grounds[ key ].southPin = pin
elif pin.getAccessDirection() == Pin.Direction.NORTH:
- if not self.grounds.has_key(key): self.grounds[ key ] = Stripe( self, None, pin )
- else: self.grounds[ key ].northPin = pin
+ if not key in self.grounds: self.grounds[ key ] = Stripe( self, None, pin )
+ else: self.grounds[ key ].northPin = pin
@property
def conf ( self ): return self.builder.conf
@@ -401,8 +400,8 @@ class GoCb ( object ):
elif isinstance(go,Vertical): managed = True
if not managed: return
rootNet = None
- if go.getNet().getType() == long(Net.Type.POWER): rootNet = self.builder.conf.coronaVdd
- if go.getNet().getType() == long(Net.Type.GROUND): rootNet = self.builder.conf.coronaVss
+ if go.getNet().getType() == int(Net.Type.POWER): rootNet = self.builder.conf.coronaVdd
+ if go.getNet().getType() == int(Net.Type.GROUND): rootNet = self.builder.conf.coronaVss
if not rootNet: return
if not NetExternalComponents.isExternal(go): return
if self.builder.activePlane:
diff --git a/cumulus/src/plugins/alpha/core2chip/cmos.py b/cumulus/src/plugins/alpha/core2chip/cmos.py
index 85276401..576183f6 100644
--- a/cumulus/src/plugins/alpha/core2chip/cmos.py
+++ b/cumulus/src/plugins/alpha/core2chip/cmos.py
@@ -1,7 +1,8 @@
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2019-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -18,7 +19,6 @@ Core2Chip configuration for the SxLib/PxLib Alliance historical
standard cell library.
"""
-from __future__ import print_function
import sys
import re
from Hurricane import DbU
diff --git a/cumulus/src/plugins/alpha/core2chip/core2chip.py b/cumulus/src/plugins/alpha/core2chip/core2chip.py
index 5c1e8ee8..12008cc4 100644
--- a/cumulus/src/plugins/alpha/core2chip/core2chip.py
+++ b/cumulus/src/plugins/alpha/core2chip/core2chip.py
@@ -1,7 +1,8 @@
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -43,8 +44,7 @@ The double level chip+corona serves two purpose:
small dogleg instead of a straight wire.
"""
-from __future__ import print_function
-from exceptions import NotImplementedError
+#from exceptions import NotImplementedError
import re
from Hurricane import UpdateSession, Net, Instance
from CRL import Catalog, AllianceFramework, Spice
@@ -523,7 +523,7 @@ class CoreToChip ( object ):
"""
Look for an IoNet associated to *core* net ``netName``.
"""
- if self._ioNets.has_key(netName): return True
+ if netName in self._ioNets: return True
return False
def newDummyNet ( self ):
@@ -560,9 +560,9 @@ class CoreToChip ( object ):
or the net object itself.
"""
if isinstance(coreNet,str):
- if self._ioNets.has_key(coreNet): return self._ioNet[ coreNet ]
+ if coreNet in self._ioNets: return self._ioNet[ coreNet ]
raise ErrorMessage( 1, 'CoreToChip.getIoNet(): Cannot lookup net "%s" by name.' % coreNet )
- if not self._ioNets.has_key(coreNet.getName()):
+ if not coreNet.getName() in self._ioNets:
self._ioNets[ coreNet.getName() ] = IoNet( self, coreNet )
return self._ioNets[ coreNet.getName() ]
diff --git a/cumulus/src/plugins/alpha/core2chip/libresocio.py b/cumulus/src/plugins/alpha/core2chip/libresocio.py
index 97e92443..ae9bfc1a 100644
--- a/cumulus/src/plugins/alpha/core2chip/libresocio.py
+++ b/cumulus/src/plugins/alpha/core2chip/libresocio.py
@@ -1,7 +1,8 @@
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -23,7 +24,6 @@ in upppercase. We can use them because, in real mode, we are less
dependent from the Alliance design flow.
"""
-from __future__ import print_function
import sys
import re
from Hurricane import DbU, DataBase, UpdateSession, Breakpoint, \
diff --git a/cumulus/src/plugins/alpha/core2chip/niolib.py b/cumulus/src/plugins/alpha/core2chip/niolib.py
index 11b445c6..3694b11c 100644
--- a/cumulus/src/plugins/alpha/core2chip/niolib.py
+++ b/cumulus/src/plugins/alpha/core2chip/niolib.py
@@ -1,7 +1,8 @@
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2019-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -17,7 +18,6 @@
Core2Chip configuration for the FlexLib I/O pad library ("niolib").
"""
-from __future__ import print_function
import sys
import re
from Hurricane import DbU, DataBase, UpdateSession, Breakpoint, \
diff --git a/cumulus/src/plugins/alpha/core2chip/phlib.py b/cumulus/src/plugins/alpha/core2chip/phlib.py
index 18ae614c..62cb8a6b 100644
--- a/cumulus/src/plugins/alpha/core2chip/phlib.py
+++ b/cumulus/src/plugins/alpha/core2chip/phlib.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2018-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
diff --git a/cumulus/src/plugins/alpha/core2chip/phlib80.py b/cumulus/src/plugins/alpha/core2chip/phlib80.py
index bbb37190..2372a9d1 100644
--- a/cumulus/src/plugins/alpha/core2chip/phlib80.py
+++ b/cumulus/src/plugins/alpha/core2chip/phlib80.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2018-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
diff --git a/cumulus/src/plugins/alpha/macro/macro.py b/cumulus/src/plugins/alpha/macro/macro.py
index 09f96286..7b79d46a 100644
--- a/cumulus/src/plugins/alpha/macro/macro.py
+++ b/cumulus/src/plugins/alpha/macro/macro.py
@@ -1,6 +1,6 @@
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2021-2021, All Rights Reserved
+# Copyright (c) Sorbonne Université 2021-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -13,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import os.path
from operator import itemgetter, attrgetter, methodcaller
@@ -47,7 +46,7 @@ class Macro ( object ):
@staticmethod
def lookup ( macroCell ):
trace( 550, '\tMacro.lookup() on {}\n'.format(macroCell) )
- if Macro.LUT.has_key(macroCell): return Macro.LUT[ macroCell ]
+ if macroCell in Macro.LUT: return Macro.LUT[ macroCell ]
return None
@staticmethod
@@ -179,9 +178,9 @@ class Macro ( object ):
, bb.getXMax() )
elif isinstance(component,Rectilinear) and component.getLayer() == blockageMetal3:
bb = Box( component.getBoundingBox() )
- deltaAbXMin = bb.getXMin() + minSpacingMetal3/2 - ab.getXMin()
+ deltaAbXMin = bb.getXMin() + minSpacingMetal3//2 - ab.getXMin()
bb.inflate( pitchMetal3 + deltaAbXMin
- , minSpacingMetal3/2
+ , minSpacingMetal3//2
, pitchMetal3
, pitchMetal3
)
@@ -238,11 +237,11 @@ class Macro ( object ):
ppYOngrid = yOngrid
if not self.rg.isSymbolic():
if ppYAxis < ppYOngrid:
- ppYAxis -= width/2
- ppYOngrid += wwidth/2
+ ppYAxis -= width//2
+ ppYOngrid += wwidth//2
else:
- ppYAxis += width/2
- ppYOngrid -= wwidth/2
+ ppYAxis += width//2
+ ppYOngrid -= wwidth//2
if useJumper:
jpitch = self.rg.getPitch ( gaugeMetal5.getLayer() )
jwwidth = self.rg.getWireWidth( gaugeMetal5.getLayer() )
@@ -283,7 +282,7 @@ class Macro ( object ):
, yOngrid
, wwidth
, xMin
- , xMin + ppitch + ppitch/2
+ , xMin + ppitch + ppitch//2
)
blockageNet = self.cell.getNet( '*' )
for gauge in [ gaugeMetal3, gaugeMetal3, gaugeMetal4, gaugeMetal5 ]:
@@ -313,7 +312,7 @@ class Macro ( object ):
, yOngrid
, wwidth
, xMin
- , xMin + ppitch + ppitch/2
+ , xMin + ppitch + ppitch//2
)
NetExternalComponents.setExternal( horizontal )
for component in eastPins:
@@ -335,11 +334,11 @@ class Macro ( object ):
ppYOngrid = yOngrid
if not self.rg.isSymbolic():
if ppYAxis < ppYOngrid:
- ppYAxis -= width/2
- ppYOngrid += wwidth/2
+ ppYAxis -= width//2
+ ppYOngrid += wwidth//2
else:
- ppYAxis += width/2
- ppYOngrid -= wwidth/2
+ ppYAxis += width//2
+ ppYOngrid -= wwidth//2
vertical = Vertical.create( component.getNet()
, component.getLayer()
, bb.getXMax()
@@ -377,11 +376,11 @@ class Macro ( object ):
ppXOngrid = xOngrid
if not self.rg.isSymbolic():
if ppXAxis < ppXOngrid:
- ppXAxis -= width/2
- ppXOngrid += wwidth/2
+ ppXAxis -= width//2
+ ppXOngrid += wwidth//2
else:
- ppXAxis += width/2
- ppXOngrid -= wwidth/2
+ ppXAxis += width//2
+ ppXOngrid -= wwidth//2
horizontal = Horizontal.create( component.getNet()
, component.getLayer()
, bb.getYMin()
@@ -423,11 +422,11 @@ class Macro ( object ):
ppXOngrid = xOngrid
if not self.rg.isSymbolic():
if ppXAxis < ppXOngrid:
- ppXAxis -= width/2
- ppXOngrid += wwidth/2
+ ppXAxis -= width//2
+ ppXOngrid += wwidth//2
else:
- ppXAxis += width/2
- ppXOngrid -= wwidth/2
+ ppXAxis += width//2
+ ppXOngrid -= wwidth//2
if useBigVia:
bvia = BigVia( component.getNet()
, self.getLayerDepth(component.getLayer())
diff --git a/cumulus/src/plugins/alpha/utils.py b/cumulus/src/plugins/alpha/utils.py
index 79ab4fda..f58bdbc8 100644
--- a/cumulus/src/plugins/alpha/utils.py
+++ b/cumulus/src/plugins/alpha/utils.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -13,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
from Hurricane import Breakpoint
from Hurricane import Box
from Hurricane import Vertical
diff --git a/cumulus/src/plugins/block.py b/cumulus/src/plugins/block.py
index 72934e30..8e04ba1a 100644
--- a/cumulus/src/plugins/block.py
+++ b/cumulus/src/plugins/block.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -16,7 +16,6 @@
This script hook the Block plugin inside GCT/Unicorn.
"""
-from __future__ import print_function
import sys
import traceback
import helpers
@@ -40,7 +39,6 @@ from plugins.alpha.block.block import Block
def unicornHook ( **kw ):
kw['beforeAction'] = 'misc.alpha'
-
plugins.kwUnicornHook( 'misc.alpha.block'
, 'Block P&&R'
, 'Perform block-level placement'
@@ -56,15 +54,12 @@ def scriptMain ( **kw ):
try:
helpers.setTraceLevel( 550 )
cell, editor = plugins.kwParseMain( **kw )
-
block = Block.create( cell )
if editor: block.setEditor( editor )
rvalue = block.build()
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
rvalue = False
-
sys.stdout.flush()
sys.stderr.flush()
-
return rvalue
diff --git a/cumulus/src/plugins/block/vchannels.py b/cumulus/src/plugins/block/vchannels.py
index f9ee9d4b..5ebc3394 100644
--- a/cumulus/src/plugins/block/vchannels.py
+++ b/cumulus/src/plugins/block/vchannels.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -66,15 +65,16 @@ class VChannels ( object ):
xMin = self.cell.getAbutmentBox().getXMin()
xMax = self.cell.getAbutmentBox().getXMax()
if x < xMin or x >= xMax:
- print ErrorMessage( 1, [ 'VChannels.addChannelAt(): Attempt to add a channel outside abutment box, ignored.'
- , '(%s must be included in [%s..%s]' % ( DbU.getValueString(x)
- , DbU.getValueString(xMin)
- , DbU.getValueString(xMax) ) ] ),
+ print( ErrorMessage( 1, [ 'VChannels.addChannelAt(): Attempt to add a channel outside abutment box, ignored.'
+ , '({} must be included in [{}..{}]'.format( DbU.getValueString(x)
+ , DbU.getValueString(xMin)
+ , DbU.getValueString(xMax) ) ] ))
return False
for i in range(len(self.vchannels)):
if self.vchannels[i][0] == x:
- print ErrorMessage( 1, 'VChannels.addChannelAt(): Attempt to add a channel twice at position %s, ignored.' % DbU.getValueString(x) ),
+ print( ErrorMessage( 1, 'VChannels.addChannelAt(): Attempt to add a channel twice at position {}, ignored.' \
+ .format(DbU.getValueString(x)) ))
return False
if self.vchannels[i][0] > x:
self.vchannels.insert( i, (x,width) )
@@ -126,5 +126,5 @@ class VChannels ( object ):
UpdateSession.close()
spaceMargin = (float(dw) * 100.0) / float(ab.getWidth())
- vprint( 1, ' - V-Channels space margin: %d%%.' % spaceMargin )
+ vprint( 1, ' - V-Channels space margin: {}%%.'.format(spaceMargin) )
return
diff --git a/cumulus/src/plugins/checks.py b/cumulus/src/plugins/checks.py
index 8bc6ab16..9f53d26b 100644
--- a/cumulus/src/plugins/checks.py
+++ b/cumulus/src/plugins/checks.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2021-2021, All Rights Reserved
+# Copyright (c) Sorbonne Université 2021-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import traceback
import os.path
@@ -27,7 +25,7 @@ try:
from helpers.io import WarningMessage
import plugins
from Hurricane import Net, Plug
-except Exception, e:
+except Exception as e:
helpers.io.catch( e )
sys.exit(2)
@@ -92,7 +90,7 @@ def scriptMain ( **kw ):
print( WarningMessage( 'No Cell loaded in the editor (yet), nothing done.' ) )
return 0
oneDriver( cell )
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
sys.stdout.flush()
sys.stderr.flush()
diff --git a/cumulus/src/plugins/chip/__init__.py b/cumulus/src/plugins/chip/__init__.py
index 5b897ab8..f94ebb8b 100644
--- a/cumulus/src/plugins/chip/__init__.py
+++ b/cumulus/src/plugins/chip/__init__.py
@@ -1,7 +1,6 @@
-# -*- explicit-buffer-name: "__init__.py" -*-
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -41,12 +40,12 @@ OnVerticalPitch = 0x0100
def importConstants ( symbols ):
if not isinstance(symbols,dict):
- print WarningMessage( 'plugins.chip.__init__.importConstants(), argument is not a symbol table.' )
+ print( WarningMessage( 'plugins.chip.__init__.importConstants(), argument is not a symbol table.' ))
return
for symbol in globals().items():
- if isinstance(symbol[1],int) or isinstance(symbol[1],long):
- if not symbols.has_key(symbol[0]):
+ if isinstance(symbol[1],int):
+ if not symbol[0] in symbols:
symbols[ symbol[0] ] = symbol[1]
return
diff --git a/cumulus/src/plugins/chip/blockcorona.py b/cumulus/src/plugins/chip/blockcorona.py
index f0b52813..535b9b89 100644
--- a/cumulus/src/plugins/chip/blockcorona.py
+++ b/cumulus/src/plugins/chip/blockcorona.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -107,11 +106,11 @@ class HorizontalRail ( Rail ):
, 'power pad is likely to be to far off west or east.'
, '(core:%s)' % str(self.side.innerBb) ] )
- #print ' HorizontalRail.connect() net:%s contact:%s' % (self.net.getName(),str(contact))
+ #print( ' HorizontalRail.connect() net:{} contact:{}'.format(self.net.getName(),contact) )
#if self.net != contact.getNet(): return False
- if self.vias.has_key(contact.getX()): return False
+ if contact.getX() in self.vias: return False
- keys = self.vias.keys()
+ keys = list( self.vias.keys() )
keys.sort()
insertIndex = bisect.bisect_left( keys, contact.getX() )
@@ -119,11 +118,11 @@ class HorizontalRail ( Rail ):
if insertIndex < len(keys):
insertPosition = keys[ insertIndex ]
if contactBb.getXMax() >= self.vias[insertPosition][2].getBoundingBox().getXMin():
- #print 'Reject contact %s intersect NEXT' % str(contact)
+ #print( 'Reject contact {} intersect NEXT'.format(contact) )
return False
if insertIndex > 0:
if self.vias[keys[insertIndex-1]][2].getBoundingBox().getXMax() >= contactBb.getXMin():
- #print 'Reject contact %s intersect PREVIOUS' % str(contact)
+ #print( 'Reject contact {} intersect PREVIOUS'.format(contact) )
return False
self.vias[ contact.getX() ] = [ contact.getX()
@@ -144,7 +143,7 @@ class HorizontalRail ( Rail ):
return True
def doLayout ( self ):
- #print 'HorizontalRail[%s] @%d' % (self.order,DbU.toLambda(self.axis))
+ #print( 'HorizontalRail[{}] @{}'.format(self.order,DbU.toLambda(self.axis)) )
railVias = [ self.side.corner0(self.order)
, self.side.corner1(self.order) ]
@@ -154,15 +153,15 @@ class HorizontalRail ( Rail ):
via[1].mergeDepth( self.side.getLayerDepth(self.side.getVLayer()) )
via[1].doLayout()
- #print ' Connect:', via[2], via[1].getVia( via[2].getLayer() )
+ #print( ' Connect:', via[2], via[1].getVia( via[2].getLayer() ))
Vertical.create( via[1].getVia( via[2].getLayer() )
, via[2]
, via[2].getLayer()
, via[2].getX()
, via[2].getWidth()
)
- #print via[1]._vias, '[%d %d]' % (via[1]._bottomDepth,via[1]._topDepth)
- #print via[1], self.side.getVLayer(), via[1].getVia( self.side.getVLayer() )
+ #print( via[1]._vias, '[{} {}]' % ( via[1]._bottomDepth, via[1]._topDepth ))
+ #print( via[1], self.side.getVLayer(), via[1].getVia( self.side.getVLayer() ))
railVias.append( via[1].getVia( self.side.getVLayer()) )
for i in range(1,len(railVias)):
@@ -182,7 +181,7 @@ class VerticalRail ( Rail ):
return
def doLayout ( self ):
- #print 'VerticalRail[%s] @%d' % (self.order,DbU.toLambda(self.axis))
+ #print( 'VerticalRail[{}] @{}'.format(self.order,DbU.toLambda(self.axis)))
railVias = [ self.side.corner0(self.order)
, self.side.corner1(self.order) ]
@@ -234,12 +233,12 @@ class VerticalRail ( Rail ):
, '(core:%s)' % str(self.side.innerBb) ] )
#if self.net != contact.getNet(): return False
- if self.vias.has_key(contact.getY()): return False
+ if contact.getY() in self.vias: return False
trace( 550, ',+', '\tVerticalRail.connect() [%s] @%d\n' % (self.order,DbU.toLambda(self.axis)) )
trace( 550, contact )
- keys = self.vias.keys()
+ keys = list( self.vias.keys() )
keys.sort()
insertIndex = bisect.bisect_left( keys, contact.getY() )
trace( 550, ',+', '\tkeys:' )
@@ -334,10 +333,10 @@ class Side ( object ):
def connectPads ( self, padSide ):
for contact in padSide.pins:
if not contact.getNet().isSupply() and not contact.getNet().isClock(): continue
- #print ' Connect to [-%i] @%d' % (0, DbU.toLambda(self.getOuterRail(0).axis))
+ #print( ' Connect to [-{}] @{}'.format(0, DbU.toLambda(self.getOuterRail(0).axis)))
self.getOuterRail( 0 ).connect( contact )
- halfRails = (len(self.rails)-1)/2
+ halfRails = (len(self.rails)-1)//2
trace( 550, 'halfRails:%i' % halfRails )
for contact in padSide.pins:
if not contact.getNet().isSupply() and not contact.getNet().isClock(): continue
@@ -361,7 +360,7 @@ class HorizontalSide ( Side ):
self.rails = []
for i in range(self.railsNb):
self.rails.append( HorizontalRail(self,i,self.getRailAxis(i)) )
- #print ' Rail [%i] @%d' % (i,DbU.toLambda(self._rails[-1].axis))
+ #print( ' Rail [{}] @{}'.format(i,DbU.toLambda(self._rails[-1].axis)))
return
@@ -372,8 +371,8 @@ class SouthSide ( HorizontalSide ):
return
def getRailAxis ( self, i ):
- return self.innerBb.getYMin() - self.hRailWidth/2 - self.hRailSpace \
- - i*(self.hRailWidth + self.hRailSpace)
+ return self.innerBb.getYMin() - self.hRailWidth//2 - self.hRailSpace \
+ - i*(self.hRailWidth + self.hRailSpace)
def corner0 ( self, i ): return self.corners[SouthWest][i]
def corner1 ( self, i ): return self.corners[SouthEast][i]
@@ -386,8 +385,8 @@ class NorthSide ( HorizontalSide ):
return
def getRailAxis ( self, i ):
- return self.innerBb.getYMax() + self.hRailWidth/2 + self.hRailSpace \
- + i*(self.hRailWidth + self.hRailSpace)
+ return self.innerBb.getYMax() + self.hRailWidth//2 + self.hRailSpace \
+ + i*(self.hRailWidth + self.hRailSpace)
def corner0 ( self, i ): return self.corners[NorthWest][i]
def corner1 ( self, i ): return self.corners[NorthEast][i]
@@ -409,36 +408,37 @@ class VerticalSide ( Side ):
for via in rail.vias.values():
if via[1].getNet() != via[2].getNet(): continue
- spans.merge( via[1]._y - via[1]._height/2, via[1]._y + via[1]._height/2 )
+ spans.merge( via[1]._y - via[1]._height//2, via[1]._y + via[1]._height//2 )
routingGauge = self.corona.routingGauge
- for depth in range(self.getInnerRail(0).vias.values()[0][1].bottomDepth
- ,self.getInnerRail(0).vias.values()[0][1].topDepth ):
- blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
- pitch = routingGauge.getLayerPitch(depth)
-
- for chunk in spans.chunks:
- Horizontal.create( self.blockageNet
- , blockageLayer
- , (chunk.getVMax() + chunk.getVMin())/2
- , chunk.getVMax() - chunk.getVMin() + pitch*2
- , sideXMin
- , sideXMax
- )
-
- depth -= 2
- if depth > 0:
- blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
- pitch = routingGauge.getLayerPitch(depth)
-
- for chunk in spans.chunks:
- Horizontal.create( self.blockageNet
- , blockageLayer
- , (chunk.getVMax() + chunk.getVMin())/2
- , chunk.getVMax() - chunk.getVMin() + pitch*2
- , sideXMin
- , sideXMax
- )
+ if len(self.getInnerRail(0).vias):
+ for depth in range(next(iter(self.getInnerRail(0).vias.values()))[1].bottomDepth
+ ,next(iter(self.getInnerRail(0).vias.values()))[1].topDepth ):
+ blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
+ pitch = routingGauge.getLayerPitch(depth)
+
+ for chunk in spans.chunks:
+ Horizontal.create( self.blockageNet
+ , blockageLayer
+ , (chunk.getVMax() + chunk.getVMin())//2
+ , chunk.getVMax() - chunk.getVMin() + pitch*2
+ , sideXMin
+ , sideXMax
+ )
+
+ depth -= 2
+ if depth > 0:
+ blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
+ pitch = routingGauge.getLayerPitch(depth)
+
+ for chunk in spans.chunks:
+ Horizontal.create( self.blockageNet
+ , blockageLayer
+ , (chunk.getVMax() + chunk.getVMin())//2
+ , chunk.getVMax() - chunk.getVMin() + pitch*2
+ , sideXMin
+ , sideXMax
+ )
return
@@ -449,8 +449,8 @@ class WestSide ( VerticalSide ):
return
def getRailAxis ( self, i ):
- return self.innerBb.getXMin() - self.vRailWidth/2 - self.vRailSpace \
- - i*(self.vRailWidth + self.vRailSpace)
+ return self.innerBb.getXMin() - self.vRailWidth//2 - self.vRailSpace \
+ - i*(self.vRailWidth + self.vRailSpace)
def corner0 ( self, i ): return self.corners[SouthWest][i]
def corner1 ( self, i ): return self.corners[NorthWest ][i]
@@ -469,8 +469,8 @@ class EastSide ( VerticalSide ):
return
def getRailAxis ( self, i ):
- return self.innerBb.getXMax() + self.vRailWidth/2 + self.vRailSpace \
- + i*(self.vRailWidth + self.vRailSpace)
+ return self.innerBb.getXMax() + self.vRailWidth//2 + self.vRailSpace \
+ + i*(self.vRailWidth + self.vRailSpace)
def corner0 ( self, i ): return self.corners[SouthEast][i]
def corner1 ( self, i ): return self.corners[NorthEast ][i]
@@ -494,7 +494,7 @@ class Corona ( object ):
self.innerBb = self.block.bb
self.block.path.getTransformation().applyOn( self.innerBb )
- self.innerBb.inflate( self.hRailSpace/2, self.vRailSpace/2 )
+ self.innerBb.inflate( self.hRailSpace//2, self.vRailSpace//2 )
if not self.conf.useClockTree: self.railsNb -= 1
diff --git a/cumulus/src/plugins/chip/blockpower.py b/cumulus/src/plugins/chip/blockpower.py
index 76135ebe..3b82e327 100644
--- a/cumulus/src/plugins/chip/blockpower.py
+++ b/cumulus/src/plugins/chip/blockpower.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -40,7 +39,7 @@ class Side ( object ):
return
def addTerminal ( self, position, width ):
- toMerge = Interval( position-width/2, position+width/2 )
+ toMerge = Interval( position-width//2, position+width//2 )
length = len(self.terminals)
imerge = length
@@ -106,8 +105,8 @@ class Side ( object ):
class Plane ( object ):
- Horizontal = 0001
- Vertical = 0002
+ Horizontal = 1
+ Vertical = 2
def __init__ ( self, block, metal ):
self.block = block
@@ -116,7 +115,7 @@ class Plane ( object ):
return
def addTerminal ( self, net, direction, bb ):
- if not self.sides.has_key(net):
+ if not net in self.sides:
self.sides[ net ] = { North : Side(self.block,North,net,self.metal)
, South : Side(self.block,South,net,self.metal)
, East : Side(self.block,East ,net,self.metal)
@@ -160,8 +159,8 @@ class GoCb ( object ):
if not direction: return
rootNet = None
- if go.getNet().getType() == long(Net.Type.POWER): rootNet = self.block.conf.coronaVdd
- if go.getNet().getType() == long(Net.Type.GROUND): rootNet = self.block.conf.coronaVss
+ if go.getNet().getType() == int(Net.Type.POWER): rootNet = self.block.conf.coronaVdd
+ if go.getNet().getType() == int(Net.Type.GROUND): rootNet = self.block.conf.coronaVss
if not rootNet: return
if self.block.activePlane:
@@ -169,7 +168,7 @@ class GoCb ( object ):
query.getPath().getTransformation().applyOn( bb )
self.block.activePlane.addTerminal( rootNet, direction, bb )
else:
- print WarningMessage( 'BlockPower.GoCb() callback called without an active plane.' )
+ print( WarningMessage( 'BlockPower.GoCb() callback called without an active plane.' ))
return
@@ -211,7 +210,7 @@ class Block ( object ):
def connectClock ( self ):
if not self.conf.useClockTree:
- print WarningMessage( "Clock tree generation has been disabled ('chip.clockTree':False)." )
+ print( WarningMessage( "Clock tree generation has been disabled ('chip.clockTree':False)." ))
return
if not self.conf.coronaCk:
diff --git a/cumulus/src/plugins/chip/chip.py b/cumulus/src/plugins/chip/chip.py
index 6815767f..c1f68bfb 100644
--- a/cumulus/src/plugins/chip/chip.py
+++ b/cumulus/src/plugins/chip/chip.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -124,8 +123,8 @@ class PlaceRoute ( object ):
UpdateSession.open()
self.conf.core.setAbutmentBox( self.conf.coreSize )
- x = (coronaAb.getWidth () - self.conf.coreSize.getWidth ()) / 2
- y = (coronaAb.getHeight() - self.conf.coreSize.getHeight()) / 2
+ x = (coronaAb.getWidth () - self.conf.coreSize.getWidth ()) // 2
+ y = (coronaAb.getHeight() - self.conf.coreSize.getHeight()) // 2
x = x - (x % self.conf.getSliceHeight())
y = y - (y % self.conf.getSliceHeight())
self.conf.icore.setTransformation ( Transformation(x,y,Transformation.Orientation.ID) )
@@ -150,7 +149,7 @@ class PlaceRoute ( object ):
if plug.getInstance() == self.conf.icore:
coreCk = plug.getMasterNet()
if not coreCk:
- print WarningMessage( 'Core <%s> is not connected to chip clock.' % self.conf.icore.getName() )
+ print( WarningMessage( 'Core "{}" is not connected to chip clock.'.format(self.conf.icore.getName()) ))
if self.conf.useClockTree and coreCk:
ht = plugins.cts.clocktree.HTree.create( self.conf, coreCell, coreCk, coreCell.getAbutmentBox() )
@@ -160,6 +159,8 @@ class PlaceRoute ( object ):
etesian.setBlock( self.conf.icore )
etesian.setViewer( self.conf.viewer )
etesian.place()
+ etesian.toHurricane()
+ etesian.flattenPower()
etesian.destroy()
ht.connectLeaf()
@@ -169,6 +170,8 @@ class PlaceRoute ( object ):
etesian = Etesian.EtesianEngine.create( self.conf.corona )
etesian.setBlock( self.conf.icore )
etesian.place()
+ etesian.toHurricane()
+ etesian.flattenPower()
etesian.destroy()
return
diff --git a/cumulus/src/plugins/chip/configuration.py b/cumulus/src/plugins/chip/configuration.py
index 10f3ece1..851f12a0 100644
--- a/cumulus/src/plugins/chip/configuration.py
+++ b/cumulus/src/plugins/chip/configuration.py
@@ -1,7 +1,6 @@
-# -*- explicit-buffer-name: "configuration.py" -*-
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -83,12 +82,12 @@ def getRpBb ( instance, netName ):
def showNet ( cell, netName ):
net = cell.getNet(netName)
if not net:
- print ErrorMessage( 3, 'Cell %s doesn\'t have net %s' % (cell.getName(),netName) )
+ print( ErrorMessage( 3, 'Cell {} doesn\'t have net {}'.format(cell.getName(),netName) ))
return
- print 'Components of', netName
+ print( 'Components of', netName )
for component in net.getComponents():
- print '| ', component, component.getBoundingBox()
+ print( '| ', component, component.getBoundingBox() )
return
@@ -240,8 +239,8 @@ class GaugeConf ( object ):
self.topLayerDepth = layerGauge.getDepth()
break
if not self.topLayerDepth:
- print WarningMessage( 'Gauge top layer not defined, using top of gauge (%d).' \
- % self.routingGauge.getDepth() )
+ print( WarningMessage( 'Gauge top layer not defined, using top of gauge ({}).' \
+ .format(self.routingGauge.getDepth()) ))
self.topLayerDepth = self.routingGauge.getDepth() - 1
self.horizontalDepth = -1
@@ -271,7 +270,7 @@ class GaugeConf ( object ):
def _loadIoPadGauge ( self, ioPadGaugeName ):
self.ioPadGauge = CRL.AllianceFramework.get().getCellGauge( ioPadGaugeName )
if not self.ioPadGauge:
- print WarningMessage( 'IO pad gauge "%s" not found.' % ioPadGaugeName )
+ print( WarningMessage( 'IO pad gauge "{}" not found.'.format(ioPadGaugeName) ))
return
def isHorizontal ( self, layer ):
@@ -281,8 +280,8 @@ class GaugeConf ( object ):
if lg.getDirection() == RoutingLayerGauge.Horizontal: return True
return False
- print ErrorMessage( 1, 'GaugeConf.isHorizontal(): Layer "%s" is not part of gauge "%s", cannot know preferred direction.' \
- % (layer.getName(), self.routingGauge.getName()) )
+ print( ErrorMessage( 1, 'GaugeConf.isHorizontal(): Layer "{}" is not part of gauge "{}", cannot know preferred direction.' \
+ .format(layer.getName(), self.routingGauge.getName()) ))
return False
def isVertical ( self, layer ): return not self.isHorizontal( layer )
@@ -347,7 +346,7 @@ class GaugeConf ( object ):
def _rpAccess ( self, rp, flags ):
trace( 550, ',+', '\t_rpAccess() %s\n' % str(rp) )
- if self._rpToAccess.has_key(rp):
+ if rp in self._rpToAccess:
trace( 550, '-' )
return self._rpToAccess[rp]
@@ -362,7 +361,7 @@ class GaugeConf ( object ):
hoffset = self.routingGauge.getLayerGauge(hdepth).getOffset()
contact1 = Contact.create( rp, self.routingGauge.getContactLayer(0), 0, 0 )
midSliceY = contact1.getY() - (contact1.getY() % self.cellGauge.getSliceHeight()) \
- + self.cellGauge.getSliceHeight() / 2
+ + self.cellGauge.getSliceHeight() // 2
midTrackY = midSliceY - ((midSliceY - hoffset) % hpitch)
dy = midSliceY - contact1.getY()
@@ -413,7 +412,7 @@ class GaugeConf ( object ):
def _rpByOccurrence ( self, occurrence, net ):
plug = occurrence.getEntity()
- if self._plugToRp.has_key(plug):
+ if plug in self._plugToRp:
rp = self._plugToRp[plug]
else:
rp = RoutingPad.create( net, occurrence, RoutingPad.BiggestArea )
@@ -423,7 +422,7 @@ class GaugeConf ( object ):
def _rpAccessByOccurrence ( self, occurrence, net, flags ):
plug = occurrence.getEntity()
- if self._plugToRp.has_key(plug):
+ if plug in self._plugToRp:
rp = self._plugToRp[plug]
else:
rp = RoutingPad.create( net, occurrence, RoutingPad.BiggestArea )
@@ -432,7 +431,7 @@ class GaugeConf ( object ):
return self._rpAccess( self._rpByOccurrence(occurrence,net), flags )
def _rpByPlug ( self, plug, net ):
- if self._plugToRp.has_key(plug):
+ if plug in self._plugToRp:
rp = self._plugToRp[plug]
else:
occurrence = Occurrence( plug, Path(net.getCell(),'') )
@@ -488,7 +487,7 @@ class ChipConf ( object ):
@staticmethod
def toSymbolic ( v, rounding ):
- if isinstance(v,long): return ChipConf._toSymbolic( v, rounding )
+ if isinstance(v,int): return ChipConf._toSymbolic( v, rounding )
if isinstance(v,Box):
if rounding & Inwards:
roundings = [ Superior
@@ -510,28 +509,28 @@ class ChipConf ( object ):
@staticmethod
def _readChipSize( chipConfigDict ):
- if not chipConfigDict.has_key('chip.size'): return Box()
+ if not 'chip.size' in chipConfigDict: return Box()
chipSize = chipConfigDict['chip.size']
if not isinstance(chipSize,tuple):
- print ErrorMessage( 1, 'The Chip size parameter is *not* a tuple.' )
+ print( ErrorMessage( 1, 'The Chip size parameter is *not* a tuple.' ))
return Box()
if len(chipSize) != 2:
- print ErrorMessage( 1, 'The Chip size parameter is *not* a tuple of exactly two items.' )
+ print( ErrorMessage( 1, 'The Chip size parameter is *not* a tuple of exactly two items.' ))
return Box()
return Box( 0, 0, chipSize[0], chipSize[1] )
@staticmethod
def _readCoreSize( chipConfigDict ):
- if not chipConfigDict.has_key('core.size'):
- print ErrorMessage( 1, 'The Core size parameter is missing.' )
+ if not 'core.size' in chipConfigDict:
+ print( ErrorMessage( 1, 'The Core size parameter is missing.' ))
return Box()
coreSize = chipConfigDict['core.size']
if not isinstance(coreSize,tuple):
- print ErrorMessage( 1, 'The Core size parameter is *not* a tuple.' )
+ print( ErrorMessage( 1, 'The Core size parameter is *not* a tuple.' ))
return Box()
if len(coreSize) != 2:
- print ErrorMessage( 1, 'The Core size parameter is *not* a tuple of exactly two items.' )
+ print( ErrorMessage( 1, 'The Core size parameter is *not* a tuple of exactly two items.' ))
return Box()
return Box( 0, 0, coreSize[0], coreSize[1] )
@@ -539,7 +538,7 @@ class ChipConf ( object ):
@staticmethod
def _readClockTree( chipConfigDict ):
useClockTree = False
- if chipConfigDict.has_key('chip.clockTree'):
+ if 'chip.clockTree' in chipConfigDict:
if chipConfigDict['chip.clockTree']:
useClockTree = True
return useClockTree
@@ -547,12 +546,12 @@ class ChipConf ( object ):
@staticmethod
def _readChipName( chipConfigDict ):
- if chipConfigDict.has_key('chip.name'): return chipConfigDict['chip.name']
+ if 'chip.name' in chipConfigDict: return chipConfigDict['chip.name']
return 'chip'
def _loadIoPadGauge ( self, chipConfigDict ):
- if not chipConfigDict.has_key('pads.ioPadGauge'):
+ if not 'pads.ioPadGauge' in chipConfigDict:
#raise ErrorMessage( 1, 'The IO pad gauge configuration parameter "pads.ioPadGauge" is missing.' )
return
self.gaugeConf._loadIoPadGauge( chipConfigDict['pads.ioPadGauge'] )
@@ -560,7 +559,7 @@ class ChipConf ( object ):
def _readPads ( self, chipConfigDict, keyword ):
- if not chipConfigDict.has_key(keyword): return []
+ if not keyword in chipConfigDict: return []
padConfList = chipConfigDict[keyword]
if not isinstance(padConfList,list):
raise ErrorMessage( 1, 'The "%s" entry is not a list.' )
@@ -575,7 +574,7 @@ class ChipConf ( object ):
instanceName = padConfList[i]
elif isinstance(padConfList[i],list):
self.padsHavePosition = True
- if isinstance(padConfList[i][0],long) and isinstance(padConfList[i][1],str):
+ if isinstance(padConfList[i][0],int) and isinstance(padConfList[i][1],str):
position = padConfList[i][0]
instanceName = padConfList[i][1]
@@ -590,7 +589,7 @@ class ChipConf ( object ):
def _readPadInstances ( self, chipConfigDict ):
- if not chipConfigDict.has_key('pads.instances'): return [ ]
+ if not 'pads.instances' in chipConfigDict: return [ ]
padInstancesConf = chipConfigDict['pads.instances']
if not isinstance(padInstancesConf,list):
@@ -734,20 +733,20 @@ class ChipConf ( object ):
uTrackMin = lg.getTrackPosition( abMin, iTrackMin )
uTrackMax = lg.getTrackPosition( abMin, iTrackMax )
- axis = (uTrackMax + uTrackMin) / 2
+ axis = (uTrackMax + uTrackMin) // 2
width = (iTrackMax - iTrackMin) * lg.getPitch() + lg.getWireWidth()
if self.gaugeConf.routingGauge.isSymbolic():
oneLambda = DbU.fromLambda( 1.0 )
if axis % oneLambda:
- axis -= oneLambda / 2
+ axis -= oneLambda // 2
width -= oneLambda
trace( 550, '\t[%i %i]\n' % (iTrackMin, iTrackMax) )
trace( 550, '\taxis: %sl %s\n' % (DbU.toLambda(axis ), DbU.getValueString(axis )) )
trace( 550, '\twidth: %sl %s\n' % (DbU.toLambda(width), DbU.getValueString(width)) )
else:
- axis = (uMax + uMin) / 2
+ axis = (uMax + uMin) // 2
width = (uMax - uMin)
trace( 550, '-' )
@@ -812,7 +811,7 @@ class ChipConf ( object ):
% (DbU.getValueString(chipXMin - coronaAb.getXMin()), DbU.toLambda(chipXMin - coronaAb.getXMin()) ) )
trace( 550, '\t| dxMax:%10s\n' % DbU.getValueString(chipXMax - coronaAb.getXMin()) )
- coronaY, width = self.toRoutingGauge( coronaY - width/2, coronaY + width/2, layer )
+ coronaY, width = self.toRoutingGauge( coronaY - width//2, coronaY + width//2, layer )
trace( 550, '\t| On Grid\n' )
trace( 550, '\t| axis: %10sl or %10s\n' % (DbU.toLambda(coronaY), DbU.getValueString(coronaY)) )
@@ -843,7 +842,7 @@ class ChipConf ( object ):
trace( 550, '\t| axis: %s\n' % DbU.getValueString(coronaX) )
trace( 550, '\t| width:%s\n' % DbU.getValueString(width) )
- coronaX, width = self.toRoutingGauge( coronaX - width/2, coronaX + width/2, layer )
+ coronaX, width = self.toRoutingGauge( coronaX - width//2, coronaX + width//2, layer )
trace( 550, '\t| On Grid\n' )
trace( 550, '\t| axis: %s or %s\n' % (DbU.toLambda(coronaX), DbU.getValueString(coronaX)) )
@@ -873,11 +872,11 @@ class ChipConf ( object ):
topLayer = layer.getTop()
if self.gaugeConf.isHorizontal(topLayer):
- coronaX, width = self.toRoutingGauge( coronaX - width /2, coronaX + width /2, layer.getBottom() )
- coronaY, height = self.toRoutingGauge( coronaY - height/2, coronaY + height/2, topLayer )
+ coronaX, width = self.toRoutingGauge( coronaX - width //2, coronaX + width //2, layer.getBottom() )
+ coronaY, height = self.toRoutingGauge( coronaY - height//2, coronaY + height//2, topLayer )
else:
- coronaX, width = self.toRoutingGauge( coronaX - width /2, coronaX + width /2, topLayer )
- coronaY, height = self.toRoutingGauge( coronaY - height/2, coronaY + height/2, layer.getBottom() )
+ coronaX, width = self.toRoutingGauge( coronaX - width //2, coronaX + width //2, topLayer )
+ coronaY, height = self.toRoutingGauge( coronaY - height//2, coronaY + height//2, layer.getBottom() )
if not (flags & OnHorizontalPitch):
trace( 550, '\tNot on horizontal routing pitch, Y on lambda only.\n' )
@@ -934,8 +933,8 @@ class ChipConf ( object ):
coronaX = self.toSymbolic( chipX - coronaAb.getXMin(), Superior )
contacts = []
- xContact = coronaX - viaPitch * (array[0]-1)/2
- yContact = coronaY - viaPitch * (array[1]-1)/2
+ xContact = coronaX - viaPitch * (array[0]-1)//2
+ yContact = coronaY - viaPitch * (array[1]-1)//2
contactSize = layer.getMinimalSize()
trace( 550, '\txContact:%sl yContact:%sl\n' % (DbU.toLambda(xContact),DbU.toLambda(yContact)) )
@@ -973,11 +972,11 @@ class ChipConf ( object ):
topLayer = layer.getTop()
if self.gaugeConf.isHorizontal(topLayer):
- coronaX, width = self.toRoutingGauge( coronaX - width /2, coronaX + width /2, layer.getBottom() )
- coronaY, height = self.toRoutingGauge( coronaY - height/2, coronaY + height/2, topLayer )
+ coronaX, width = self.toRoutingGauge( coronaX - width //2, coronaX + width //2, layer.getBottom() )
+ coronaY, height = self.toRoutingGauge( coronaY - height//2, coronaY + height//2, topLayer )
else:
- coronaX, width = self.toRoutingGauge( coronaX - width /2, coronaX + width /2, topLayer )
- coronaY, height = self.toRoutingGauge( coronaY - height/2, coronaY + height/2, layer.getBottom() )
+ coronaX, width = self.toRoutingGauge( coronaX - width //2, coronaX + width //2, topLayer )
+ coronaY, height = self.toRoutingGauge( coronaY - height//2, coronaY + height//2, layer.getBottom() )
if direction == Pin.Direction.NORTH or direction == Pin.Direction.SOUTH:
trace( 550, '\tEast/West not on horizontal routing pitch, Y on lambda only.\n' )
@@ -1023,8 +1022,8 @@ class ChipConf ( object ):
def checkNotFounds ( padList, side ):
for i in range(len(padList)):
if not isinstance(padList[i][1],Instance):
- print ErrorMessage( 1, 'The pad [%d] (%s) of list %s do not exists in netlist (skipped).'
- % (i,padList[i][1],side) )
+ print( ErrorMessage( 1, 'The pad [{}] ({}) of list %s do not exists in netlist (skipped).' \
+ .format(i,padList[i][1],side) ))
return
@@ -1158,7 +1157,7 @@ class ChipConf ( object ):
padNet = self.cell.getNet( coronaNet.getName() )
if padNet:
- if not netPads.has_key(padNet):
+ if not padNet in netPads:
trace( 550, '\t%20s <-> %-20s\n' % (padNet.getName(),coronaNet.getName()) )
netPads[ padNet ] = coronaNet
else:
@@ -1298,7 +1297,7 @@ def loadConfiguration ( cell, viewer=None ):
raise ErrorMessage( 1, 'ChipPlugin, configuration directory "./coriolis2/" is missing "__init__.py".' )
from coriolis2.ioring import chip
- except Exception, e:
+ except Exception as e:
catch( e )
return ChipConf( chip, cell, viewer )
diff --git a/cumulus/src/plugins/chip/padscorona.py b/cumulus/src/plugins/chip/padscorona.py
index 0d861172..e98318c0 100644
--- a/cumulus/src/plugins/chip/padscorona.py
+++ b/cumulus/src/plugins/chip/padscorona.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -454,7 +453,7 @@ class Side ( object ):
if m: padName = m.group( 'power' )
padNet = padInstance.getMasterCell().getNet( padName )
- #print 'padName:', padName, 'padNet:', padNet
+ #print( 'padName:', padName, 'padNet:', padNet )
if padNet:
plug = padInstance.getPlug( padNet )
chipNet = plug.getNet()
@@ -470,7 +469,7 @@ class Side ( object ):
def _placePads ( self ):
padLength = 0
for pad in self.pads: padLength += pad[1].getMasterCell().getAbutmentBox().getWidth()
- padSpacing = (self.sideLength - 2*self.conf.getIoPadHeight() - padLength) / (len(self.pads) + 1)
+ padSpacing = (self.sideLength - 2*self.conf.getIoPadHeight() - padLength) // (len(self.pads) + 1)
if self.conf.padsHavePosition:
for i in range(len(self.pads)):
@@ -510,8 +509,8 @@ class Side ( object ):
uMin -= DbU.fromLambda(5.0)
uMax += DbU.fromLambda(5.0)
else:
- uMin -= width/2
- uMax += width/2
+ uMin -= width//2
+ uMax += width//2
if self.type == North or self.type == South:
if self.type == North:
@@ -706,7 +705,7 @@ class CoreWire ( object ):
+ self.symContactLayer.getMinimalSize()
arrayWidth = self.symContactSize[0]
- arrayCount = (arrayWidth - contactMinSize) / CoreWire.viaPitch
+ arrayCount = (arrayWidth - contactMinSize) // CoreWire.viaPitch
trace( 550, '\tCoreWire.viaPitch: %sl\n' % (DbU.toLambda(CoreWire.viaPitch)) )
trace( 550, '\tcontactMinSize: %sl, arrayWidth: %sl, arrayCount: %d\n'
% (DbU.toLambda(contactMinSize),DbU.toLambda(arrayWidth),arrayCount) )
@@ -758,7 +757,7 @@ class CoreWire ( object ):
xPadMax = xContact
xCore = coronaAb.getXMin()
if not self.preferredDir:
- xPadMax += self.bbSegment.getHeight()/2
+ xPadMax += self.bbSegment.getHeight()//2
else:
accessDirection = Pin.Direction.EAST
xPadMax = self.bbSegment.getXMax()
@@ -766,7 +765,7 @@ class CoreWire ( object ):
xPadMin = xContact
xCore = coronaAb.getXMax()
if not self.preferredDir:
- xPadMin -= self.bbSegment.getHeight()/2
+ xPadMin -= self.bbSegment.getHeight()//2
hReal = Horizontal.create( self.chipNet
, self.padSegment.getLayer()
@@ -856,7 +855,7 @@ class CoreWire ( object ):
yContact = yPadMax
yCore = coronaAb.getYMin()
if not self.preferredDir:
- yPadMax += self.bbSegment.getWidth()/2
+ yPadMax += self.bbSegment.getWidth()//2
else:
accessDirection = Pin.Direction.NORTH
yPadMax = self.bbSegment.getYMax()
@@ -864,7 +863,7 @@ class CoreWire ( object ):
yContact = yPadMin
yCore = coronaAb.getYMax()
if not self.preferredDir:
- yPadMin -= self.bbSegment.getWidth()/2
+ yPadMin -= self.bbSegment.getWidth()//2
vReal = Vertical.create( self.chipNet
, self.padSegment.getLayer()
@@ -1054,7 +1053,7 @@ class Corona ( object ):
if plug.getMasterNet().isClock():
hspan.inflate( DbU.fromLambda(5.0) )
else:
- hspan.inflate( component.getWidth() / 2 )
+ hspan.inflate( component.getWidth() // 2 )
if hspan.contains( ab.getXMin() ) or hspan.contains( ab.getXMax() ):
duplicate = False
@@ -1116,10 +1115,10 @@ class Corona ( object ):
if depth > self.conf.gaugeConf.topLayerDepth: continue
if lg.getDirection() == RoutingLayerGauge.Vertical:
- if not vsegments.has_key(depth): vsegments[ depth ] = []
+ if not depth in vsegments: vsegments[ depth ] = []
vsegments[ depth ].append( (component,bb) )
else:
- if not hsegments.has_key(depth): hsegments[ depth ] = []
+ if not depth in hsegments: hsegments[ depth ] = []
hsegments[ depth ].append( (component,bb) )
#if len(vsegments) + len(hsegments) == 0:
@@ -1215,10 +1214,10 @@ class Corona ( object ):
self.conf.setupCorona( self.westSide.gap, self.southSide.gap, self.eastSide.gap, self.northSide.gap )
self.coreSymBb = self.conf.getInstanceAb( self.conf.icorona )
- self.coreSymBb.inflate( self.conf.toSymbolic( self.westSide.gap /2, Superior )
- , self.conf.toSymbolic( self.southSide.gap/2, Superior )
- , self.conf.toSymbolic( self.eastSide.gap /2, Inferior )
- , self.conf.toSymbolic( self.northSide.gap/2, Inferior ) )
+ self.coreSymBb.inflate( self.conf.toSymbolic( self.westSide.gap //2, Superior )
+ , self.conf.toSymbolic( self.southSide.gap//2, Superior )
+ , self.conf.toSymbolic( self.eastSide.gap //2, Inferior )
+ , self.conf.toSymbolic( self.northSide.gap//2, Inferior ) )
self.southSide.drawCoreWires()
self.northSide.drawCoreWires()
@@ -1229,45 +1228,44 @@ class Corona ( object ):
and len(self.westSide .coreWires) \
and not self.southSide.coreWires[0].inCoronaRange \
and not self.westSide .coreWires[0].inCoronaRange:
- print ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on south-east corner are outside corona range.'
- , 'This will generate a short-circuit between S:"%s" and W:"%s".' % \
- ( self.southSide.coreWires[0].chipNet.getName()
- , self.westSide .coreWires[0].chipNet.getName()) ] )
+ print( ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on south-east corner are outside corona range.'
+ , 'This will generate a short-circuit between S:"{}" and W:"{}".' \
+ .format( self.southSide.coreWires[0].chipNet.getName()
+ , self.westSide .coreWires[0].chipNet.getName()) ] ))
if len(self.southSide.coreWires) \
and len(self.eastSide .coreWires) \
and not self.southSide.coreWires[-1].inCoronaRange \
and not self.eastSide .coreWires[ 0].inCoronaRange:
- print ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on south-west corner are outside corona range.'
- , 'This will generate a short-circuit between S:"%s" and E:"%s.' % \
- ( self.southSide.coreWires[-1].chipNet.getName()
- , self.eastSide .coreWires[ 0].chipNet.getName()) ] )
+ print( ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on south-west corner are outside corona range.'
+ , 'This will generate a short-circuit between S:"{}" and E:"{}".' \
+ .format( self.southSide.coreWires[-1].chipNet.getName()
+ , self.eastSide .coreWires[ 0].chipNet.getName()) ] ))
if len(self.northSide.coreWires) \
and len(self.westSide .coreWires) \
and not self.northSide.coreWires[ 0].inCoronaRange \
and not self.westSide .coreWires[-1].inCoronaRange:
- print ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on north-east corner are outside corona range.'
- , 'This will generate a short-circuit between N:"%s" and W:"%s".' % \
- ( self.northSide.coreWires[ 0].chipNet.getName()
- , self.westSide .coreWires[-1].chipNet.getName()) ] )
+ print( ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on north-east corner are outside corona range.'
+ , 'This will generate a short-circuit between N:"{}" and W:"{}".' \
+ .format( self.northSide.coreWires[ 0].chipNet.getName()
+ , self.westSide .coreWires[-1].chipNet.getName()) ] ))
if len(self.northSide.coreWires) \
and len(self.eastSide .coreWires) \
and not self.northSide.coreWires[-1].inCoronaRange \
and not self.eastSide .coreWires[-1].inCoronaRange:
- print ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on north-west corner are outside corona range.'
- , 'This will generate a short-circuit between N:"%s" and E:"%s.' % \
- ( self.northSide.coreWires[-1].chipNet.getName()
- , self.eastSide .coreWires[-1].chipNet.getName()) ] )
-
+ print( ErrorMessage( 1, [ 'Corona._placeInnerCorona(): Both pads on north-west corner are outside corona range.'
+ , 'This will generate a short-circuit between N:"{}" and E:"{}".' \
+ .format( self.northSide.coreWires[-1].chipNet.getName()
+ , self.eastSide .coreWires[-1].chipNet.getName()) ] ))
return
# def _locatePadRails ( self ):
# if not self.clockPad:
-# print ErrorMessage( 1, 'There must be at least one pad of model "%s" to guess the pad rails.' \
-# % self.pckName )
+# print( ErrorMessage( 1, 'There must be at least one pad of model "%s" to guess the pad rails.' \
+# .format(self.pckName) ))
# return False
#
# for plug in self.clockPad.getPlugs():
diff --git a/cumulus/src/plugins/chipplace.py b/cumulus/src/plugins/chipplace.py
index 5d28edc8..68153d2b 100644
--- a/cumulus/src/plugins/chipplace.py
+++ b/cumulus/src/plugins/chipplace.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -29,7 +28,6 @@ import plugins.chip.chip
def unicornHook ( **kw ):
kw['beforeAction'] = 'placeAndRoute.stepByStep'
#kw['beforeAction'] = 'placeAndRoute.clockTree'
-
plugins.kwAddMenu ( 'placeAndRoute', 'P&&R', **kw )
plugins.kwUnicornHook( 'placeAndRoute.placeChip'
, 'PLace Chip'
@@ -45,19 +43,15 @@ def scriptMain ( **kw ):
try:
#helpers.setTraceLevel( 550 )
cell, editor = plugins.kwParseMain( **kw )
-
conf = plugins.chip.configuration.loadConfiguration( cell, editor )
conf.chipValidate()
if not conf.validated: return False
-
placeChip = plugins.chip.chip.PlaceRoute( conf )
placeChip.doChipPlacement()
return placeChip.validated
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
rvalue = False
-
sys.stdout.flush()
sys.stderr.flush()
-
return rvalue
diff --git a/cumulus/src/plugins/chiproute.py b/cumulus/src/plugins/chiproute.py
index 0ce911d0..603c11ef 100644
--- a/cumulus/src/plugins/chiproute.py
+++ b/cumulus/src/plugins/chiproute.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -22,6 +21,7 @@ from helpers.io import ErrorMessage
from helpers.io import WarningMessage
import plugins
import plugins.chip.chip
+from Hurricane import Breakpoint
# --------------------------------------------------------------------
@@ -44,24 +44,21 @@ def unicornHook ( **kw ):
def scriptMain ( **kw ):
rvalue = True
try:
- #helpers.setTraceLevel( 550 )
-
+ Breakpoint.setStopLevel( 99 )
+ helpers.setTraceLevel( 550 )
cell, editor = plugins.kwParseMain( **kw )
conf = plugins.chip.configuration.loadConfiguration( cell, editor )
conf.chipValidate()
if not conf.validated: return False
-
prChip = plugins.chip.chip.PlaceRoute( conf )
prChip.validate()
prChip.doChipPlacement()
prChip.doChipRouting()
prChip.save()
return prChip.validated
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
rvalue = False
-
sys.stdout.flush()
sys.stderr.flush()
-
return rvalue
diff --git a/cumulus/src/plugins/clocktree.py b/cumulus/src/plugins/clocktree.py
index 3e575509..cee90872 100644
--- a/cumulus/src/plugins/clocktree.py
+++ b/cumulus/src/plugins/clocktree.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -40,7 +39,6 @@ from plugins.chip.configuration import ChipConf
def unicornHook ( **kw ):
kw['beforeAction'] = 'placeAndRoute.placeChip'
-
plugins.kwAddMenu ( 'placeAndRoute', 'P&&R', **kw )
plugins.kwUnicornHook( 'placeAndRoute.clockTree'
, 'Place Block && Clock Tree'
@@ -55,34 +53,27 @@ def scriptMain ( **kw ):
try:
#helpers.setTraceLevel( 550 )
errorCode = 0
-
- print ' o Cleaning up any previous run.'
+ print( ' o Cleaning up any previous run.' )
for fileName in os.listdir('.'):
if fileName.endswith('.ap'):
- print ' - <%s>' % fileName
+ print( ' - "{}"'.format(fileName) )
os.unlink(fileName)
-
cell = None
- if kw.has_key('cell') and kw['cell']:
+ if ('cell' in kw) and kw['cell']:
cell = kw['cell']
-
editor = None
- if kw.has_key('editor') and kw['editor']:
+ if ('editor' in kw) and kw['editor']:
editor = kw['editor']
- print ' o Editor detected, running in graphic mode.'
+ print( ' o Editor detected, running in graphic mode.' )
if cell == None: cell = editor.getCell()
-
if cell == None:
raise ErrorMessage( 3, 'ClockTree: No cell loaded yet.' )
-
conf = ChipConf( {}, cell, editor )
-
if cell.getAbutmentBox().isEmpty():
spaceMargin = Cfg.getParamPercentage('etesian.spaceMargin').asPercentage() / 100.0 + 0.01
aspectRatio = Cfg.getParamPercentage('etesian.aspectRatio').asPercentage() / 100.0
computeAbutmentBox( cell, spaceMargin, aspectRatio, conf.cellGauge )
if editor: editor.fit()
-
ht = HTree.create( conf, cell, None, cell.getAbutmentBox() )
if editor: editor.refresh()
etesian = Etesian.EtesianEngine.create( cell )
@@ -91,9 +82,9 @@ def scriptMain ( **kw ):
#ht.prune()
ht.route()
etesian.toHurricane()
+ etesian.flattenPower()
etesian.destroy()
ht.save( cell )
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
-
return 0
diff --git a/cumulus/src/plugins/conductor.py b/cumulus/src/plugins/conductor.py
index c95a4c79..7350a751 100644
--- a/cumulus/src/plugins/conductor.py
+++ b/cumulus/src/plugins/conductor.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import traceback
import os.path
@@ -37,7 +35,7 @@ try:
import Katana
import Unicorn
import plugins
-except Exception, e:
+except Exception as e:
catch( e )
sys.exit(2)
@@ -88,11 +86,11 @@ def scriptMain ( **kw ):
useFixedAbHeight = Cfg.getParamBool('conductor.useFixedAbHeight').asBool()
cell = None
- if kw.has_key('cell') and kw['cell']:
+ if ('cell' in kw) and kw['cell']:
cell = kw['cell']
editor = None
- if kw.has_key('editor') and kw['editor']:
+ if ('editor' in kw) and kw['editor']:
editor = kw['editor']
print( ' o Editor found, running in graphic mode.' )
editor.setLayerVisible( 'rubber', False )
@@ -168,7 +166,7 @@ def scriptMain ( **kw ):
Cfg.Configuration.popDefaultPriority()
- except Exception, e:
+ except Exception as e:
catch( e )
return 0
diff --git a/cumulus/src/plugins/core2chip/cmos.py b/cumulus/src/plugins/core2chip/cmos.py
index cb8b7b8c..847dc379 100644
--- a/cumulus/src/plugins/core2chip/cmos.py
+++ b/cumulus/src/plugins/core2chip/cmos.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
diff --git a/cumulus/src/plugins/core2chip/core2chip.py b/cumulus/src/plugins/core2chip/core2chip.py
index f076b885..267a2abc 100644
--- a/cumulus/src/plugins/core2chip/core2chip.py
+++ b/cumulus/src/plugins/core2chip/core2chip.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -238,7 +238,7 @@ class IoPad ( object ):
ioNet.buildNets( context )
- if not self.coreToChip.ioPadInfos.has_key(self.direction):
+ if not self.direction in self.coreToChip.ioPadInfos:
raise ErrorMessage( 1, 'IoPad.createPad(): Unsupported direction %d (%s) for pad "%s".' \
% (self.direction
,IoPad.directionToStr(self.direction)
@@ -315,16 +315,16 @@ class CoreToChip ( object ):
def hasIoNet ( self, netName ):
- if self._ioNets.has_key(netName): return True
+ if netName in self._ioNets: return True
return False
def getIoNet ( self, coreNet ):
if isinstance(coreNet,str):
- if self._ioNets.has_key(coreNet): return self._ioNet[ coreNet ]
+ if coreNet in self._ioNets: return self._ioNet[ coreNet ]
raise ErrorMessage( 1, 'CoreToChip.getIoNet(): Cannot lookup net "%s" by name.' % coreNet )
- if not self._ioNets.has_key(coreNet.getName()):
+ if not coreNet.getName() in self._ioNets:
self._ioNets[ coreNet.getName() ] = IoNet( self, coreNet )
return self._ioNets[ coreNet.getName() ]
@@ -350,7 +350,7 @@ class CoreToChip ( object ):
return
def _buildStandardPad ( self, ioNet ):
- if not self.ioPadInfos.has_key(ioNet.coreNet.getDirection()):
+ if not ioNet.coreNet.getDirection() in self.ioPadInfos:
raise ErrorMessage( 1, 'CoreToChip._buildStandardPad(): Unsupported direction %d (%s) for core net "%s".' \
% (ioNet.coreNet.getDirection()
,netDirectionToStr(ioNet.coreNet.getDirection())
diff --git a/cumulus/src/plugins/core2chip/phlib.py b/cumulus/src/plugins/core2chip/phlib.py
index 18ae614c..64d6498a 100644
--- a/cumulus/src/plugins/core2chip/phlib.py
+++ b/cumulus/src/plugins/core2chip/phlib.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
diff --git a/cumulus/src/plugins/core2chip/phlib80.py b/cumulus/src/plugins/core2chip/phlib80.py
index bbb37190..dec539b1 100644
--- a/cumulus/src/plugins/core2chip/phlib80.py
+++ b/cumulus/src/plugins/core2chip/phlib80.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
diff --git a/cumulus/src/plugins/core2chip_cmos.py b/cumulus/src/plugins/core2chip_cmos.py
index e4f73d87..963c7734 100644
--- a/cumulus/src/plugins/core2chip_cmos.py
+++ b/cumulus/src/plugins/core2chip_cmos.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -28,7 +28,6 @@ import plugins.core2chip.cmos
def unicornHook ( **kw ):
kw['beforeAction'] = 'placeAndRoute.stepByStep'
#kw['beforeAction'] = 'placeAndRoute.clockTree'
-
plugins.kwAddMenu ( 'placeAndRoute' , 'P&&R', **kw )
plugins.kwAddMenu ( 'placeAndRoute.core2chip', 'Core To Chip', **kw )
plugins.kwUnicornHook( 'placeAndRoute.core2chip.cmos'
@@ -41,24 +40,18 @@ def unicornHook ( **kw ):
def scriptMain ( **kw ):
- rvalue = True
- try:
- #helpers.setTraceLevel( 550 )
-
- cell, editor = plugins.kwParseMain( **kw )
- if not cell:
- raise ErrorMessage( 1, 'CoreToChip_cmos.scriptMain(): No cell (core) loaded in the editor yet.' )
-
- chip_cmos = plugins.core2chip.cmos.cmos( cell )
- chip_cmos.buildChip()
-
- if editor: editor.setCell( chip_cmos.chip )
-
- except Exception, e:
- helpers.io.catch( e )
- rvalue = False
-
- sys.stdout.flush()
- sys.stderr.flush()
-
- return rvalue
+ rvalue = True
+ try:
+ #helpers.setTraceLevel( 550 )
+ cell, editor = plugins.kwParseMain( **kw )
+ if not cell:
+ raise ErrorMessage( 1, 'CoreToChip_cmos.scriptMain(): No cell (core) loaded in the editor yet.' )
+ chip_cmos = plugins.core2chip.cmos.cmos( cell )
+ chip_cmos.buildChip()
+ if editor: editor.setCell( chip_cmos.chip )
+ except Exception as e:
+ helpers.io.catch( e )
+ rvalue = False
+ sys.stdout.flush()
+ sys.stderr.flush()
+ return rvalue
diff --git a/cumulus/src/plugins/core2chip_phlib80.py b/cumulus/src/plugins/core2chip_phlib80.py
index defd17fa..da7459d8 100644
--- a/cumulus/src/plugins/core2chip_phlib80.py
+++ b/cumulus/src/plugins/core2chip_phlib80.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python
+
# -*- coding: utf-8 -*-
#
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -28,7 +28,6 @@ import core2chip.phlib80
def unicornHook ( **kw ):
kw['beforeAction'] = 'placeAndRoute.stepByStep'
#kw['beforeAction'] = 'placeAndRoute.clockTree'
-
plugins.kwAddMenu ( 'placeAndRoute' , 'P&&R', **kw )
plugins.kwAddMenu ( 'placeAndRoute.core2chip', 'Core To Chip', **kw )
plugins.kwUnicornHook( 'placeAndRoute.core2chip.phlib80'
@@ -41,24 +40,18 @@ def unicornHook ( **kw ):
def scriptMain ( **kw ):
- rvalue = True
- try:
- #helpers.setTraceLevel( 550 )
-
- cell, editor = plugins.kwParseMain( **kw )
- if not cell:
- raise ErrorMessage( 1, 'CoreToChip_phlib80.scriptMain(): No cell (core) loaded in the editor yet.' )
-
- chip_phlib80 = core2chip.phlib80.phlib80( cell )
- chip_phlib80.buildChip()
-
- if editor: editor.setCell( chip_phlib80.chip )
-
- except Exception, e:
- helpers.io.catch( e )
- rvalue = False
-
- sys.stdout.flush()
- sys.stderr.flush()
-
- return rvalue
+ rvalue = True
+ try:
+ #helpers.setTraceLevel( 550 )
+ cell, editor = plugins.kwParseMain( **kw )
+ if not cell:
+ raise ErrorMessage( 1, 'CoreToChip_phlib80.scriptMain(): No cell (core) loaded in the editor yet.' )
+ chip_phlib80 = core2chip.phlib80.phlib80( cell )
+ chip_phlib80.buildChip()
+ if editor: editor.setCell( chip_phlib80.chip )
+ except Exception as e:
+ helpers.io.catch( e )
+ rvalue = False
+ sys.stdout.flush()
+ sys.stderr.flush()
+ return rvalue
diff --git a/cumulus/src/plugins/cts/clocktree.py b/cumulus/src/plugins/cts/clocktree.py
index 1d576fdc..fc74f03b 100755
--- a/cumulus/src/plugins/cts/clocktree.py
+++ b/cumulus/src/plugins/cts/clocktree.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -64,14 +63,14 @@ class HTree ( object ):
% aspectRatio )
ht = HTree( conf, cell, clockNet, clockBox )
- print ' o Creating clock H-Tree for "%s".' % cell.getName()
- print ' - Clock is "%s"' % ht.masterClock.getName()
+ print( ' o Creating clock H-Tree for "{}".'.format(cell.getName()) )
+ print( ' - Clock is "{}"'.format(ht.masterClock.getName()) )
ht.build()
trace( 550, '\tht.build() OK\n' )
ht.place()
trace( 550, '\tht.place() OK\n' )
#ht.route()
- print ' - H-Tree depth: %d' % ht.getTreeDepth()
+ print( ' - H-Tree depth: {}'.format(ht.getTreeDepth()) )
trace( 550, '\tusedVTracks: %s\n' % str(ht.usedVTracks) )
return ht
@@ -82,7 +81,7 @@ class HTree ( object ):
if self.minSide < DbU.fromLambda(100.0):
raise ErrorMessage( 3, 'ClockTree: clockTree.minimumSide (%g) is less than 100 lambda.' \
% DbU.toLambda(self.minSide) )
- print ' - Minimum side for clock area: %sl' % DbU.toLambda(self.minSide)
+ print( ' - Minimum side for clock area: {}'.format(DbU.toLambda(self.minSide)) )
UpdateSession.open()
self.framework = CRL.AllianceFramework.get()
@@ -150,7 +149,7 @@ class HTree ( object ):
yslice = self.toYCellGrid(y)
transformation = Transformation.Orientation.ID
- if ((yslice-self.area.getYMin()) / self.conf.cellGauge.getSliceHeight()) % 2 != 0:
+ if ((yslice-self.area.getYMin()) // self.conf.cellGauge.getSliceHeight()) % 2 != 0:
transformation = Transformation.Orientation.MY
yslice += self.conf.cellGauge.getSliceHeight()
@@ -165,7 +164,7 @@ class HTree ( object ):
instance.destroy()
x = transformation.getTx()
- for i in range(instanceWidth/tieWidth):
+ for i in range(instanceWidth//tieWidth):
feed = Instance.create( self.cell
, 'htree_feed_%i' % self.feedCounter()
, self.tieCell
@@ -248,7 +247,7 @@ class HTree ( object ):
# This is a Steiner point.
node.component = self.conf.createContact( net
, x
- , node.y + self.conf.cellGauge.getSliceHeight()/2 - self.conf.routingGauge.getLayerGauge(self.horizontalDeepDepth).getPitch()
+ , node.y + self.conf.cellGauge.getSliceHeight()//2 - self.conf.routingGauge.getLayerGauge(self.horizontalDeepDepth).getPitch()
, GaugeConf.DeepDepth )
trace( 550, '\tCreate (Steiner) node.component: @Y%d (y:%d - %d) %s\n' \
% (DbU.toLambda(node.realY)
@@ -478,8 +477,8 @@ class HTreeNode ( object ):
def place ( self ):
trace( 550, '\rplace HTreeNode %s\n' % self.ckNet.getName() )
- x = self.area.getXMin() + self.area.getWidth ()/4
- y = self.area.getYMin() + self.area.getHeight()/4
+ x = self.area.getXMin() + self.area.getWidth ()//4
+ y = self.area.getYMin() + self.area.getHeight()//4
halfWidth = self.area.getHalfWidth ()
halfHeight = self.area.getHalfHeight()
@@ -578,18 +577,18 @@ def computeAbutmentBox ( cell, spaceMargin, aspectRatio, cellGauge ):
# instancesNb += 1
# cellLength += int( DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()) )
#
- # # ar = x/y S = x*y = spaceMargin*SH x=S/y ar = S/y^2
- # # y = sqrt(S/AR)
- # gcellLength = float(cellLength)*(1+spaceMargin) / sliceHeight
- # rows = math.sqrt( gcellLength/aspectRatio )
+ # # ar = x//y S = x*y = spaceMargin*SH x=S//y ar = S//y^2
+ # # y = sqrt(S//AR)
+ # gcellLength = float(cellLength)*(1+spaceMargin) // sliceHeight
+ # rows = math.sqrt( gcellLength//aspectRatio )
# if math.trunc(rows) != rows: rows = math.trunc(rows) + 1
# else: rows = math.trunc(rows)
- # columns = gcellLength / rows
+ # columns = gcellLength // rows
# if math.trunc(columns) != columns: columns = math.trunc(columns) + 1
# else: columns = math.trunc(columns)
#
# print ' o Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \
- # % (spaceMargin*100.0,aspectRatio*100.0,(cellLength/sliceHeight))
+ # % (spaceMargin*100.0,aspectRatio*100.0,(cellLength//sliceHeight))
# print ' - GCell grid: [%dx%d]' % (columns,rows)
UpdateSession.open()
diff --git a/cumulus/src/plugins/cts/rsmt.py b/cumulus/src/plugins/cts/rsmt.py
index 8851871b..d33a66ec 100644
--- a/cumulus/src/plugins/cts/rsmt.py
+++ b/cumulus/src/plugins/cts/rsmt.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
diff --git a/cumulus/src/plugins/matrixplacer.py b/cumulus/src/plugins/matrixplacer.py
index f628b4f9..a0fdd6c6 100644
--- a/cumulus/src/plugins/matrixplacer.py
+++ b/cumulus/src/plugins/matrixplacer.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import traceback
import helpers
@@ -162,8 +160,8 @@ class NetDatas ( object ):
tags[tag] = 1
else:
tags = self._dtags if direction & DIRECT else self._rtags
- if tags.has_key(tag): tags[tag] += 1
- else: tags[tag] = 1
+ if tag in tags: tags[tag] += 1
+ else: tags[tag] = 1
return
def mergeTags ( self, tags, direction ):
@@ -277,8 +275,8 @@ class InstanceDatas ( object ):
tags[tag] = 1
else:
tags = self._dtags if direction & DIRECT else self._rtags
- if tags.has_key(tag): tags[tag] += 1
- else: tags[tag] = 1
+ if tag in tags: tags[tag] += 1
+ else: tags[tag] = 1
return
def mergeTags ( self, tags, direction ):
@@ -321,8 +319,8 @@ class MatchSet ( object ):
for instanceDatas in cellDag.directOrdereds:
matched = True
for tag in self.tags:
- if not instanceDatas.dtags.has_key(tag) \
- and not instanceDatas.rtags.has_key(tag):
+ if not tag in instanceDatas.dtags \
+ and not tag in instanceDatas.rtags:
matched = False
break
if matched:
@@ -469,11 +467,11 @@ class CellDag ( object ):
def lookup ( self, element ):
if isinstance(element,Net):
- if self.netsDatas.has_key(element.getId()):
+ if element.getId() in self.netsDatas:
return self.netsDatas[element.getId()]
raise ErrorMessage( 1, 'CellDag.lookup(): Missing NetDatas for {}.'.format(element) )
if isinstance(element,Instance):
- if self.instancesDatas.has_key(element.getId()):
+ if element.getId() in self.instancesDatas:
return self.instancesDatas[element.getId()]
raise ErrorMessage( 1, 'CellDag.lookup(): Missing InstanceDatas for {}.'.format(element) )
raise ErrorMessage( 1, 'CellDag.lookup(): {} has not Datas support.'.format(element) )
@@ -644,7 +642,7 @@ class CellDag ( object ):
histogram = {}
for netDatas in self.netsDatas.values():
print( 'netDatas:{}'.format(netDatas) )
- if histogram.has_key(netDatas.plugCount):
+ if netDatas.plugCount in histogram:
histogram[netDatas.plugCount] += 1
else:
histogram[netDatas.plugCount] = 1
@@ -1034,14 +1032,14 @@ class MatrixPlacer ( object ):
self.finalizeBottom()
def tagRow ( self, row, nets ):
- if not self.tagRows.has_key(row):
+ if not row in self.tagRows:
self.tagRows[row] = []
self.tagRows[row] += nets
for net in nets:
self.dag.addNetTag( net, 'h{}'.format(row) )
def tagColumn ( self, column, nets ):
- if not self.tagColumns.has_key(column):
+ if not column in self.tagColumns:
self.tagColumns[column] = []
self.tagColumns[column] += nets
for net in nets:
@@ -1151,7 +1149,7 @@ def scriptMain ( **kw ):
matrix.dag.showReverseCone( 'subckt_5_dm13_subckt_332_src3_c_63_subckt_112_sff1_x4', 10 )
return True
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
rvalue = False
diff --git a/cumulus/src/plugins/rsave.py b/cumulus/src/plugins/rsave.py
index d0295aa5..a4c1b5a2 100644
--- a/cumulus/src/plugins/rsave.py
+++ b/cumulus/src/plugins/rsave.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,7 +13,6 @@
# +-----------------------------------------------------------------+
-from __future__ import print_function
import sys
import traceback
import os.path
@@ -26,7 +24,7 @@ try:
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
import plugins
-except Exception, e:
+except Exception as e:
helpers.io.catch( e )
sys.exit(2)
@@ -43,6 +41,9 @@ def rsave ( cell, views=CRL.Catalog.State.Physical, depth=0, enableSpice=False )
"""
framework = CRL.AllianceFramework.get()
if depth == 0: print( ' o Recursive Save-Cell.' )
+ if cell.isUniquified(): views |= CRL.Catalog.State.Logical
+ if cell.getName().endswith('_cts'): views |= CRL.Catalog.State.Logical
+ if cell.getName().endswith('_r' ): views |= CRL.Catalog.State.Logical
sviews = ''
if views & CRL.Catalog.State.Logical:
sviews += 'netlist'
@@ -65,9 +66,6 @@ def rsave ( cell, views=CRL.Catalog.State.Physical, depth=0, enableSpice=False )
if sviews: sviews += ','
sviews += 'layout'
print( ' {}+ {} ({}).'.format(' '*(depth*2), cell.getName(), sviews) )
- if cell.isUniquified(): views |= CRL.Catalog.State.Logical
- if cell.getName().endswith('_cts'): views |= CRL.Catalog.State.Logical
- if cell.getName().endswith('_r' ): views |= CRL.Catalog.State.Logical
framework.saveCell( cell, views )
spiceFlags = CRL.Spice.TopCell if depth == 0 else 0
CRL.Spice.save( cell, spiceFlags )
@@ -101,13 +99,13 @@ def scriptMain ( **kw ):
#helpers.setTraceLevel( 550 )
cell, editor = plugins.kwParseMain( **kw )
views = CRL.Catalog.State.Physical
- if kw.has_key('views'): views = kw['views']
+ if 'views' in kw: views = kw['views']
if not cell:
print( WarningMessage( 'No Cell loaded in the editor (yet), nothing done.' ) )
return 0
rsave( cell, views )
CRL.destroyAllVHDL()
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
sys.stdout.flush()
sys.stderr.flush()
diff --git a/cumulus/src/plugins/rsaveall.py b/cumulus/src/plugins/rsaveall.py
index 3febf9e3..7a5a6f67 100644
--- a/cumulus/src/plugins/rsaveall.py
+++ b/cumulus/src/plugins/rsaveall.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2015-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2015-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -24,7 +23,7 @@ try:
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
import plugins
-except Exception, e:
+except Exception as e:
helpers.io.catch( e )
sys.exit(2)
@@ -36,23 +35,19 @@ except Exception, e:
# standard cell (mainly the feed-through).
def rsave ( cell, depth=0 ):
- if cell.isTerminal(): return
-
- framework = CRL.AllianceFramework.get()
- if depth == 0: print ' o Recursive Save-Cell.'
-
- print ' %s+ %s (netlist+layout).' % ( ' '*(depth*2), cell.getName() )
- flags = CRL.Catalog.State.Logical
- if not cell.getAbutmentBox().isEmpty():
- flags |= CRL.Catalog.State.Physical
-
- framework.saveCell( cell, flags )
-
- for instance in cell.getInstances():
- masterCell = instance.getMasterCell()
- if not masterCell.isTerminal():
- rsave( masterCell, depth+1 )
- return
+ if cell.isTerminal(): return
+ framework = CRL.AllianceFramework.get()
+ if depth == 0: print( ' o Recursive Save-Cell.' )
+ print( ' {}+ {} (netlist+layout).'.format( ' '*(depth*2), cell.getName() ))
+ flags = CRL.Catalog.State.Logical
+ if not cell.getAbutmentBox().isEmpty():
+ flags |= CRL.Catalog.State.Physical
+ framework.saveCell( cell, flags )
+ for instance in cell.getInstances():
+ masterCell = instance.getMasterCell()
+ if not masterCell.isTerminal():
+ rsave( masterCell, depth+1 )
+ return
# --------------------------------------------------------------------
@@ -69,22 +64,16 @@ def unicornHook ( **kw ):
def scriptMain ( **kw ):
- try:
- #helpers.setTraceLevel( 550 )
-
- cell, editor = plugins.kwParseMain( **kw )
-
- if not cell:
- print WarningMessage( 'No Cell loaded in the editor (yet), nothing done.' )
- return 0
-
- rsave( cell )
- CRL.destroyAllVHDL()
-
- except Exception, e:
- helpers.io.catch( e )
-
- sys.stdout.flush()
- sys.stderr.flush()
-
- return 0
+ try:
+ #helpers.setTraceLevel( 550 )
+ cell, editor = plugins.kwParseMain( **kw )
+ if not cell:
+ print( WarningMessage( 'No Cell loaded in the editor (yet), nothing done.' ))
+ return 0
+ rsave( cell )
+ CRL.destroyAllVHDL()
+ except Exception as e:
+ helpers.io.catch( e )
+ sys.stdout.flush()
+ sys.stderr.flush()
+ return 0
diff --git a/cumulus/src/plugins/s2r.py b/cumulus/src/plugins/s2r.py
index 65ef5d19..b3289356 100644
--- a/cumulus/src/plugins/s2r.py
+++ b/cumulus/src/plugins/s2r.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2014-2018, All Rights Reserved
+# Copyright (c) Sorbonne Université 2014-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -27,7 +26,7 @@ try:
from Hurricane import Library
from CRL import Gds
import plugins
-except Exception, e:
+except Exception as e:
helpers.io.catch( e )
sys.exit(2)
@@ -39,21 +38,18 @@ class S2R ( object ):
def __init__ ( self ):
self.s2r = None
-
pathes = os.environ[ "PATH" ]
for path in pathes.split(':'):
- binary = os.path.join( path, 's2r' )
- if os.path.exists(binary):
- self.s2r = binary
- break
+ binary = os.path.join( path, 's2r' )
+ if os.path.exists(binary):
+ self.s2r = binary
+ break
if not self.s2r:
- print ErrorMessage( 1, 'S2R.__init__(): No s2r binary found in PATH, please setup Alliance environement.' )
+ print( ErrorMessage( 1, 'S2R.__init__(): No s2r binary found in PATH, please setup Alliance environement.' ))
return
-
def convert ( self, cell ):
if not self.s2r: return
-
os.environ[ 'RDS_IN' ] = 'gds'
os.environ[ 'RDS_OUT' ] = 'gds'
process = subprocess.Popen( [ self.s2r, cell.getName() ]
@@ -62,14 +58,12 @@ class S2R ( object ):
, shell =False
)
for line in process.stdout.readlines():
- print 's2r | %s' % line[:-1]
-
+ print( 's2r | {}'.format(line[:-1] ))
gdsFile = os.path.join( os.environ['MBK_WORK_LIB'], cell.getName()+'.gds' )
-
rootLibrary = DataBase.getDB().getRootLibrary()
gdsLibrary = rootLibrary.getLibrary( 'gds' )
if not gdsLibrary:
- gdsLibrary = Library.create( rootLibrary, 'GDS' )
+ gdsLibrary = Library.create( rootLibrary, 'GDS' )
Gds.load( gdsLibrary, gdsFile )
return gdsLibrary.getCell( cell.getName() )
@@ -88,23 +82,20 @@ def unicornHook ( **kw ):
def scriptMain ( **kw ):
- rvalue = True
- try:
- #helpers.setTraceLevel( 550 )
-
- cell, editor = plugins.kwParseMain( **kw )
- s2r = S2R()
- gdsCell = s2r.convert( cell )
- print gdsCell
- if editor: editor.setCell( gdsCell )
-
- except Exception, e:
- helpers.io.catch( e )
- if locals().has_key('editor') and editor \
- and locals().has_key('cell' ) and cell: editor.fit()
- rvalue = False
-
- sys.stdout.flush()
- sys.stderr.flush()
-
- return rvalue
+ rvalue = True
+ try:
+ #helpers.setTraceLevel( 550 )
+ cell, editor = plugins.kwParseMain( **kw )
+ s2r = S2R()
+ gdsCell = s2r.convert( cell )
+ print( gdsCell )
+ if editor: editor.setCell( gdsCell )
+ except Exception as e:
+ helpers.io.catch( e )
+ if 'editor' in locals() and editor \
+ and 'cell' in locals() and cell:
+ editor.fit()
+ rvalue = False
+ sys.stdout.flush()
+ sys.stderr.flush()
+ return rvalue
diff --git a/cumulus/src/plugins/stats.py b/cumulus/src/plugins/stats.py
index 4aac5023..7726530a 100644
--- a/cumulus/src/plugins/stats.py
+++ b/cumulus/src/plugins/stats.py
@@ -1,6 +1,6 @@
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) SU 2020-2020, All Rights Reserved
+# Copyright (c) Sorbonne Université 2020-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -18,7 +18,6 @@ This script hook the Stats plugin inside GCT/Unicorn.
Compute some statistics on a hierarchical block.
"""
-from __future__ import print_function
import sys
import traceback
import helpers
@@ -44,7 +43,7 @@ class Stats ( object ):
def lookup ( p ):
if isinstance(p,Cell): cell = p
else: cell = p.getMasterCell()
- if Stats.LUT.has_key(cell): return Stats.LUT[ cell ]
+ if cell in Stats.LUT: return Stats.LUT[ cell ]
return None
@staticmethod
@@ -59,7 +58,7 @@ class Stats ( object ):
def consolidate ():
ordereds = {}
for item in Stats.LUT.values():
- if not ordereds.has_key(item.depth):
+ if not item.depth in ordereds:
ordereds[item.depth] = []
ordereds[item.depth].append( item )
rkeys = ordereds.keys()
@@ -150,7 +149,7 @@ def scriptMain ( **kw ):
stats = Stats( cell, 0 )
stats.display()
- except Exception, e:
+ except Exception as e:
helpers.io.catch( e )
rvalue = False
diff --git a/cumulus/src/plugins/vchannels.py b/cumulus/src/plugins/vchannels.py
index b11e8bb3..b23dd8a5 100644
--- a/cumulus/src/plugins/vchannels.py
+++ b/cumulus/src/plugins/vchannels.py
@@ -1,7 +1,6 @@
-#!/usr/bin/env python
-#
+
# This file is part of the Coriolis Software.
-# Copyright (c) UPMC 2019-2019, All Rights Reserved
+# Copyright (c) Sorbonne Université 2019-2021, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
@@ -14,28 +13,28 @@
# +-----------------------------------------------------------------+
try:
- import sys
- import traceback
- import os.path
- import math
- import Cfg
- import Hurricane
- from Hurricane import Breakpoint
- from Hurricane import UpdateSession
- import Viewer
- import CRL
- from CRL import RoutingLayerGauge
- import helpers
- from helpers import trace
- from helpers.io import ErrorMessage, catch
- from helpers import l, u, n
- import Etesian
- import Unicorn
- import plugins
- import block.vchannels
-except Exception, e:
- catch( e )
- sys.exit(2)
+ import sys
+ import traceback
+ import os.path
+ import math
+ import Cfg
+ import Hurricane
+ from Hurricane import Breakpoint
+ from Hurricane import UpdateSession
+ import Viewer
+ import CRL
+ from CRL import RoutingLayerGauge
+ import helpers
+ from helpers import trace
+ from helpers.io import ErrorMessage, catch
+ from helpers import l, u, n
+ import Etesian
+ import Unicorn
+ import plugins
+ import block.vchannels
+except Exception as e:
+ catch( e )
+ sys.exit(2)
# --------------------------------------------------------------------
@@ -43,7 +42,6 @@ except Exception, e:
def unicornHook ( **kw ):
kw['beforeAction'] = 'placeAndRoute.placeChip'
-
plugins.kwAddMenu ( 'placeAndRoute', 'P&&R', **kw )
plugins.kwUnicornHook( 'placeAndRoute.vchannels'
, 'Add vertical routing channels'
@@ -55,34 +53,26 @@ def unicornHook ( **kw ):
def scriptMain ( **kw ):
- try:
- #helpers.setTraceLevel( 550 )
-
- errorCode = 0
-
- cell = None
- if kw.has_key('cell') and kw['cell']:
- cell = kw['cell']
-
- editor = None
- if kw.has_key('editor') and kw['editor']:
- editor = kw['editor']
- print ' o Editor found, running in graphic mode.'
- if cell == None: cell = editor.getCell()
-
- if cell == None:
- raise ErrorMessage( 3, 'VChannels: No cell loaded yet.' )
-
- if cell.getAbutmentBox().isEmpty():
- raise ErrorMessage( 3, 'VChannels: cell "%s" is not placed yet.' % cell.getName() )
-
- vchannels = block.VChannels.VChannels( cell )
- for i in range(48):
- vchannels.addChannelAt( l(250.0*(i+1)), l(190.0) )
- vchannels.expandChannels()
- if editor: editor.refresh()
-
- except Exception, e:
- catch( e )
-
- return 0
+ try:
+ #helpers.setTraceLevel( 550 )
+ errorCode = 0
+ cell = None
+ if 'cell' in kw and kw['cell']:
+ cell = kw['cell']
+ editor = None
+ if 'editor' in kw and kw['editor']:
+ editor = kw['editor']
+ print( ' o Editor found, running in graphic mode.' )
+ if cell == None: cell = editor.getCell()
+ if cell == None:
+ raise ErrorMessage( 3, 'VChannels: No cell loaded yet.' )
+ if cell.getAbutmentBox().isEmpty():
+ raise ErrorMessage( 3, 'VChannels: cell "%s" is not placed yet.' % cell.getName() )
+ vchannels = block.VChannels.VChannels( cell )
+ for i in range(48):
+ vchannels.addChannelAt( l(250.0*(i+1)), l(190.0) )
+ vchannels.expandChannels()
+ if editor: editor.refresh()
+ except Exception as e:
+ catch( e )
+ return 0
diff --git a/cumulus/src/tools/blif2vst.py b/cumulus/src/tools/blif2vst.py
index 41dd9c69..29ee9434 100755
--- a/cumulus/src/tools/blif2vst.py
+++ b/cumulus/src/tools/blif2vst.py
@@ -1,6 +1,5 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
-from __future__ import print_function
import sys
import traceback
import os.path
diff --git a/cumulus/src/tools/px2mpx.py b/cumulus/src/tools/px2mpx.py
index b5825273..29bfd9a6 100755
--- a/cumulus/src/tools/px2mpx.py
+++ b/cumulus/src/tools/px2mpx.py
@@ -1,291 +1,286 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
try:
- import sys
- import traceback
- import os.path
- import optparse
- import math
- import Cfg
- import Hurricane
- from Hurricane import DataBase
- from Hurricane import DbU
- from Hurricane import Transformation
- from Hurricane import Box
- from Hurricane import UpdateSession
- from Hurricane import Breakpoint
- from Hurricane import Net
- from Hurricane import NetExternalComponents
- from Hurricane import BasicLayer
- from Hurricane import ContactLayer
- from Hurricane import ViaLayer
- from Hurricane import RegularLayer
- from Hurricane import TransistorLayer
- from Hurricane import DiffusionLayer
- from Hurricane import Cell
- from Hurricane import Instance
- from Hurricane import Net
- from Hurricane import Contact
- from Hurricane import Horizontal
- from Hurricane import Vertical
- import Viewer
- import CRL
- from CRL import RoutingLayerGauge
- import helpers
- from helpers import trace
- from helpers.io import ErrorMessage
+ import sys
+ import traceback
+ import os.path
+ import optparse
+ import math
+ import Cfg
+ import Hurricane
+ from Hurricane import DataBase
+ from Hurricane import DbU
+ from Hurricane import Transformation
+ from Hurricane import Box
+ from Hurricane import UpdateSession
+ from Hurricane import Breakpoint
+ from Hurricane import Net
+ from Hurricane import NetExternalComponents
+ from Hurricane import BasicLayer
+ from Hurricane import ContactLayer
+ from Hurricane import ViaLayer
+ from Hurricane import RegularLayer
+ from Hurricane import TransistorLayer
+ from Hurricane import DiffusionLayer
+ from Hurricane import Cell
+ from Hurricane import Instance
+ from Hurricane import Net
+ from Hurricane import Contact
+ from Hurricane import Horizontal
+ from Hurricane import Vertical
+ import Viewer
+ import CRL
+ from CRL import RoutingLayerGauge
+ import helpers
+ from helpers import trace
+ from helpers.io import ErrorMessage
except ImportError, e:
- serror = str(e)
- if serror.startswith('No module named'):
- module = serror.split()[-1]
- print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module
- print ' Please check the integrity of the package.'
- if str(e).find('cannot open shared object file'):
- library = serror.split(':')[0]
- print '[ERROR] The <%s> shared library cannot be loaded.' % library
- print ' Under RHEL 6, you must be under devtoolset-2.'
- print ' (scl enable devtoolset-2 bash)'
- sys.exit(1)
+ serror = str(e)
+ if serror.startswith('No module named'):
+ module = serror.split()[-1]
+ print( '[ERROR] The "{}" python module or symbol cannot be loaded.'.format(module) )
+ print( ' Please check the integrity of the "coriolis" package.' )
+ if str(e).find('cannot open shared object file'):
+ library = serror.split(':')[0]
+ print( '[ERROR] The "{}" shared library cannot be loaded.'.format(library) )
+ print( ' Under RHEL 6, you must be under devtoolset-2.' )
+ print( ' (scl enable devtoolset-2 bash)' )
+ sys.exit(1)
except Exception, e:
- print '[ERROR] A strange exception occurred while loading the basic Coriolis/Python'
- print ' modules. Something may be wrong at Python/C API level.\n'
- print ' %s' % e
- sys.exit(2)
+ print( '[ERROR] A strange exception occurred while loading the basic Coriolis/Python' )
+ print( ' modules. Something may be wrong at Python/C API level.\n' )
+ print( ' {}'.format(e) )
+ sys.exit(2)
-framework = CRL.AllianceFramework.get()
+framework = CRL.AllianceFramework.get()
def getDeltas ( layer ):
- #deltas = { 'L_METAL1' : DbU.fromLambda( -1.0 )
- # , 'L_METAL2' : DbU.fromLambda( 3.0 )
- # , 'L_blockage2': DbU.fromLambda( -1.0 )
- # , 'L_blockage4': DbU.fromLambda( -1.0 )
- # , 'L_xWell' : DbU.fromLambda( 6.0 )
- # , 'L_Trans' : DbU.fromLambda( -3.0 )
- # , 'L_Diff' : DbU.fromLambda( -1.0 )
- # , 'L_Tie' : DbU.fromLambda( 1.2 )
- # , 'W_Diff' : DbU.fromLambda( 0.2 )
- # , 'W_xWell' : DbU.fromLambda( 12.0 )
- # , 'mW_METAL1' : DbU.fromLambda( 4.0 )
- # , 'mW_METAL2' : DbU.fromLambda( 4.0 )
- # }
- deltas = { 'L_METAL1' : DbU.fromLambda( -1.0 )
- , 'L_METAL2' : DbU.fromLambda( 1.5 )
- , 'L_blockage2': DbU.fromLambda( -0.5 )
- , 'L_blockage4': DbU.fromLambda( -0.5 )
- , 'L_xWell' : DbU.fromLambda( 6.0 )
- , 'L_Trans' : DbU.fromLambda( -3.0 )
- , 'L_Diff' : DbU.fromLambda( -1.0 )
- , 'L_Tie' : DbU.fromLambda( 1.2 )
- , 'W_Diff' : DbU.fromLambda( 0.2 )
- , 'W_xWell' : DbU.fromLambda( 12.0 )
- , 'W_blockage2': DbU.fromLambda( -1.0 )
- , 'mW_METAL1' : DbU.fromLambda( 4.0 )
- , 'mW_METAL2' : DbU.fromLambda( 6.0 )
- }
-
- dL = 0
- dW = 0
- mW = 0
-
- if isinstance(layer,TransistorLayer):
- dL = deltas[ 'L_Trans' ]
- elif isinstance(layer,RegularLayer):
- if layer.getName() == 'METAL1':
- dL = deltas[ 'L_METAL1' ]
- mW = deltas[ 'mW_METAL1' ]
- elif layer.getName() == 'METAL2' or layer.getName() == 'METAL3':
- dL = deltas[ 'L_METAL2' ]
- mW = deltas[ 'mW_METAL2' ]
- elif layer.getName() == 'BLOCKAGE2':
- dL = deltas[ 'L_blockage2' ]
- elif layer.getName() == 'BLOCKAGE4':
- dL = deltas[ 'L_blockage4' ]
- elif layer.getName().endswith('WELL'):
- dL = deltas[ 'L_xWell' ]
- dW = deltas[ 'W_xWell' ]
- elif isinstance(layer,DiffusionLayer):
- if layer.getName().endswith('DIF'):
- dL = deltas[ 'L_Diff' ]
- dW = deltas[ 'W_Diff' ]
- elif layer.getName().endswith('TIE'):
- dL = deltas[ 'L_Tie' ]
- return dL, dW, mW
+ #deltas = { 'L_METAL1' : DbU.fromLambda( -1.0 )
+ # , 'L_METAL2' : DbU.fromLambda( 3.0 )
+ # , 'L_blockage2': DbU.fromLambda( -1.0 )
+ # , 'L_blockage4': DbU.fromLambda( -1.0 )
+ # , 'L_xWell' : DbU.fromLambda( 6.0 )
+ # , 'L_Trans' : DbU.fromLambda( -3.0 )
+ # , 'L_Diff' : DbU.fromLambda( -1.0 )
+ # , 'L_Tie' : DbU.fromLambda( 1.2 )
+ # , 'W_Diff' : DbU.fromLambda( 0.2 )
+ # , 'W_xWell' : DbU.fromLambda( 12.0 )
+ # , 'mW_METAL1' : DbU.fromLambda( 4.0 )
+ # , 'mW_METAL2' : DbU.fromLambda( 4.0 )
+ # }
+ deltas = { 'L_METAL1' : DbU.fromLambda( -1.0 )
+ , 'L_METAL2' : DbU.fromLambda( 1.5 )
+ , 'L_blockage2': DbU.fromLambda( -0.5 )
+ , 'L_blockage4': DbU.fromLambda( -0.5 )
+ , 'L_xWell' : DbU.fromLambda( 6.0 )
+ , 'L_Trans' : DbU.fromLambda( -3.0 )
+ , 'L_Diff' : DbU.fromLambda( -1.0 )
+ , 'L_Tie' : DbU.fromLambda( 1.2 )
+ , 'W_Diff' : DbU.fromLambda( 0.2 )
+ , 'W_xWell' : DbU.fromLambda( 12.0 )
+ , 'W_blockage2': DbU.fromLambda( -1.0 )
+ , 'mW_METAL1' : DbU.fromLambda( 4.0 )
+ , 'mW_METAL2' : DbU.fromLambda( 6.0 )
+ }
+
+ dL = 0
+ dW = 0
+ mW = 0
+
+ if isinstance(layer,TransistorLayer):
+ dL = deltas[ 'L_Trans' ]
+ elif isinstance(layer,RegularLayer):
+ if layer.getName() == 'METAL1':
+ dL = deltas[ 'L_METAL1' ]
+ mW = deltas[ 'mW_METAL1' ]
+ elif layer.getName() == 'METAL2' or layer.getName() == 'METAL3':
+ dL = deltas[ 'L_METAL2' ]
+ mW = deltas[ 'mW_METAL2' ]
+ elif layer.getName() == 'BLOCKAGE2':
+ dL = deltas[ 'L_blockage2' ]
+ elif layer.getName() == 'BLOCKAGE4':
+ dL = deltas[ 'L_blockage4' ]
+ elif layer.getName().endswith('WELL'):
+ dL = deltas[ 'L_xWell' ]
+ dW = deltas[ 'W_xWell' ]
+ elif isinstance(layer,DiffusionLayer):
+ if layer.getName().endswith('DIF'):
+ dL = deltas[ 'L_Diff' ]
+ dW = deltas[ 'W_Diff' ]
+ elif layer.getName().endswith('TIE'):
+ dL = deltas[ 'L_Tie' ]
+ return dL, dW, mW
def px2mpx ( editor, pxCell ):
- global framework
-
- if pxCell == None:
- raise ErrorMessage( 3, 'px2mpx.px2mpx(): Mandatory pxCell argument is None.' )
- mpxCell = None
-
- print '\nProcessing', pxCell
-
- UpdateSession.open()
- try:
- if pxCell.getName() != 'padreal':
- mpxCellName = pxCell.getName()[:-2]+'mpx'
- else:
- mpxCellName = pxCell.getName()+'_mpx'
- mpxCell = framework.createCell( mpxCellName )
-
- if editor:
- editor.setCell( mpxCell )
-
- Left = 0x0001
- Right = 0x0002
- Middle = 0x0000
- AllSpan = Left|Right
-
- ab = pxCell.getAbutmentBox()
- mpxCell.setAbutmentBox( Box( ab.getXMin()*2, ab.getYMin()*2, ab.getXMax()*2, ab.getYMax()*2 ) )
-
- for instance in pxCell.getInstances():
- masterCell = instance.getMasterCell()
- if masterCell.getName() == 'padreal':
- masterCell = framework.getCell( 'padreal_mpx', CRL.Catalog.State.Physical )
-
- originTransf = instance.getTransformation()
- mpxInstance = Instance.create( mpxCell
- , instance.getName()
- , masterCell
- , Transformation( originTransf.getTx()*2
- , originTransf.getTy()*2
- , originTransf.getOrientation() )
- )
- mpxInstance.setPlacementStatus( Instance.PlacementStatus.PLACED )
-
- for net in pxCell.getNets():
- mpxNet = Net.create( mpxCell, net.getName() )
- if net.isExternal(): mpxNet.setExternal( True )
- if net.isGlobal (): mpxNet.setGlobal( True )
- mpxNet.setType ( net.getType () )
- mpxNet.setDirection( net.getDirection() )
-
- for component in net.getComponents():
- layer = component.getLayer()
- dupComponent = None
-
- print ' Processing', component
-
- if isinstance(component,Contact):
- dupComponent = Contact.create( mpxNet
- , layer
- , component.getX ()*2
- , component.getY ()*2
- , component.getWidth ()*2
- , component.getHeight()*2
- )
- elif isinstance(component,Horizontal):
- dL, dW, mW = getDeltas( layer )
- dLLeft = dL
- dLRight = dL
- skipComponent = False
-
- bb = component.getBoundingBox()
- if component.getSourceX() > component.getTargetX(): component.invert()
- if isinstance(layer,RegularLayer):
- if layer.getBasicLayer().getMaterial().getCode() == BasicLayer.Material.blockage:
- print ' Blockage BB:%s vs. AB:%s' % (bb, ab)
- if layer.getName()[-1] == '2' or layer.getName()[-1] == '4':
- state = 0
- if bb.getXMin() <= ab.getXMin(): state |= Left
- if bb.getXMax() >= ab.getXMax(): state |= Right
-
- if not (state&Left):
- print ' Shrink left.'
- dLLeft = dL - DbU.fromLambda( 1.5 )
- if not(state&Right):
- print ' Shrink right.'
- dLRight = dL - DbU.fromLambda( 1.5 )
-
- if layer.getName()[-1] == '4' and state == AllSpan:
- print ' Skipping component.'
- skipComponent = True
-
- width = mW
- if component.getWidth() > mW:
- width = component.getWidth()*2 + dW
-
- #print DbU.toLambda(bb.getWidth()), DbU.toLambda( dLLeft-dLRight)
- if bb.getWidth()*2 > abs(dLLeft+dLRight) and not skipComponent:
- dupComponent = Horizontal.create( mpxNet
- , layer
- , component.getY ()*2
- , width
- , component.getDxSource()*2 - dLLeft
- , component.getDxTarget()*2 + dLRight
- )
- print ' Copy:', dupComponent
- else:
- print ' Horizontal component too small *or* skipped, not converted'
-
- elif isinstance(component,Vertical):
- dL, dW, mW = getDeltas( component.getLayer() )
- dLTop = dL
- dLBottom = dL
- dX = 0
- skipComponent = False
-
- if component.getSourceY() > component.getTargetY(): component.invert()
- if isinstance(layer,RegularLayer):
- if layer.getBasicLayer().getMaterial().getCode() == BasicLayer.Material.blockage:
- if layer.getName()[-1] == '3' or layer.getName()[-1] == '5':
- state = 0
- bb = component.getBoundingBox()
- if bb.getXMin() <= ab.getXMin(): state |= Left
- if bb.getXMax() >= ab.getXMax(): state |= Right
-
- if state == Left:
- dX = DbU.fromLambda( -2.0 )
- dW += DbU.fromLambda( -2.0 )
- elif state == Right:
- dX = DbU.fromLambda( 2.0 )
- dW += DbU.fromLambda( -2.0 )
- elif state == 0:
- dX = 0
- dW += DbU.fromLambda( -4.0 )
-
- if layer.getName()[-1] == '5':
- if state == AllSpan:
- print ' Skipping component.'
- skipComponent = True
- else:
- dLTop = DbU.fromLambda(120.0) - component.getDyTarget()*2
-
- if dW < component.getWidth() and not skipComponent:
- width = mW
- if component.getWidth() > mW:
- width = component.getWidth()*2 + dW
+ global framework
- dupComponent = Vertical.create( mpxNet
- , layer
- , component.getX ()*2 + dX
- , width
- , component.getDySource()*2 - dLBottom
- , component.getDyTarget()*2 + dLTop
- )
- else:
- print ' Vertical component too small *or* skipped, not converted'
-
+ if pxCell == None:
+ raise ErrorMessage( 3, 'px2mpx.px2mpx(): Mandatory pxCell argument is None.' )
+ mpxCell = None
+ print '\nProcessing', pxCell
+
+ UpdateSession.open()
+ try:
+ if pxCell.getName() != 'padreal':
+ mpxCellName = pxCell.getName()[:-2]+'mpx'
else:
- print '[WARNING] Unchanged component:', component
+ mpxCellName = pxCell.getName()+'_mpx'
+ mpxCell = framework.createCell( mpxCellName )
+ if editor:
+ editor.setCell( mpxCell )
+ Left = 0x0001
+ Right = 0x0002
+ Middle = 0x0000
+ AllSpan = Left|Right
+ ab = pxCell.getAbutmentBox()
+ mpxCell.setAbutmentBox( Box( ab.getXMin()*2, ab.getYMin()*2, ab.getXMax()*2, ab.getYMax()*2 ) )
- if dupComponent and NetExternalComponents.isExternal( component ):
- NetExternalComponents.setExternal( dupComponent )
+ for instance in pxCell.getInstances():
+ masterCell = instance.getMasterCell()
+ if masterCell.getName() == 'padreal':
+ masterCell = framework.getCell( 'padreal_mpx', CRL.Catalog.State.Physical )
+ originTransf = instance.getTransformation()
+ mpxInstance = Instance.create( mpxCell
+ , instance.getName()
+ , masterCell
+ , Transformation( originTransf.getTx()*2
+ , originTransf.getTy()*2
+ , originTransf.getOrientation() )
+ )
+ mpxInstance.setPlacementStatus( Instance.PlacementStatus.PLACED )
+
+ for net in pxCell.getNets():
+ mpxNet = Net.create( mpxCell, net.getName() )
+ if net.isExternal(): mpxNet.setExternal( True )
+ if net.isGlobal (): mpxNet.setGlobal( True )
+ mpxNet.setType ( net.getType () )
+ mpxNet.setDirection( net.getDirection() )
+
+ for component in net.getComponents():
+ layer = component.getLayer()
+ dupComponent = None
+
+ print ' Processing', component
+
+ if isinstance(component,Contact):
+ dupComponent = Contact.create( mpxNet
+ , layer
+ , component.getX ()*2
+ , component.getY ()*2
+ , component.getWidth ()*2
+ , component.getHeight()*2
+ )
+ elif isinstance(component,Horizontal):
+ dL, dW, mW = getDeltas( layer )
+ dLLeft = dL
+ dLRight = dL
+ skipComponent = False
+
+ bb = component.getBoundingBox()
+ if component.getSourceX() > component.getTargetX(): component.invert()
+ if isinstance(layer,RegularLayer):
+ if layer.getBasicLayer().getMaterial().getCode() == BasicLayer.Material.blockage:
+ print ' Blockage BB:%s vs. AB:%s' % (bb, ab)
+ if layer.getName()[-1] == '2' or layer.getName()[-1] == '4':
+ state = 0
+ if bb.getXMin() <= ab.getXMin(): state |= Left
+ if bb.getXMax() >= ab.getXMax(): state |= Right
+
+ if not (state&Left):
+ print ' Shrink left.'
+ dLLeft = dL - DbU.fromLambda( 1.5 )
+ if not(state&Right):
+ print ' Shrink right.'
+ dLRight = dL - DbU.fromLambda( 1.5 )
+
+ if layer.getName()[-1] == '4' and state == AllSpan:
+ print ' Skipping component.'
+ skipComponent = True
+
+ width = mW
+ if component.getWidth() > mW:
+ width = component.getWidth()*2 + dW
+
+ #print DbU.toLambda(bb.getWidth()), DbU.toLambda( dLLeft-dLRight)
+ if bb.getWidth()*2 > abs(dLLeft+dLRight) and not skipComponent:
+ dupComponent = Horizontal.create( mpxNet
+ , layer
+ , component.getY ()*2
+ , width
+ , component.getDxSource()*2 - dLLeft
+ , component.getDxTarget()*2 + dLRight
+ )
+ print ' Copy:', dupComponent
+ else:
+ print ' Horizontal component too small *or* skipped, not converted'
+
+ elif isinstance(component,Vertical):
+ dL, dW, mW = getDeltas( component.getLayer() )
+ dLTop = dL
+ dLBottom = dL
+ dX = 0
+ skipComponent = False
+
+ if component.getSourceY() > component.getTargetY(): component.invert()
+ if isinstance(layer,RegularLayer):
+ if layer.getBasicLayer().getMaterial().getCode() == BasicLayer.Material.blockage:
+ if layer.getName()[-1] == '3' or layer.getName()[-1] == '5':
+ state = 0
+ bb = component.getBoundingBox()
+ if bb.getXMin() <= ab.getXMin(): state |= Left
+ if bb.getXMax() >= ab.getXMax(): state |= Right
+
+ if state == Left:
+ dX = DbU.fromLambda( -2.0 )
+ dW += DbU.fromLambda( -2.0 )
+ elif state == Right:
+ dX = DbU.fromLambda( 2.0 )
+ dW += DbU.fromLambda( -2.0 )
+ elif state == 0:
+ dX = 0
+ dW += DbU.fromLambda( -4.0 )
+
+ if layer.getName()[-1] == '5':
+ if state == AllSpan:
+ print ' Skipping component.'
+ skipComponent = True
+ else:
+ dLTop = DbU.fromLambda(120.0) - component.getDyTarget()*2
+
+ if dW < component.getWidth() and not skipComponent:
+ width = mW
+ if component.getWidth() > mW:
+ width = component.getWidth()*2 + dW
- if editor: editor.fit()
-
- except ErrorMessage, e:
- print e; errorCode = e.code
- except Exception, e:
- print '\n\n', e; errorCode = 1
- traceback.print_tb(sys.exc_info()[2])
-
- UpdateSession.close()
- return mpxCell
+ dupComponent = Vertical.create( mpxNet
+ , layer
+ , component.getX ()*2 + dX
+ , width
+ , component.getDySource()*2 - dLBottom
+ , component.getDyTarget()*2 + dLTop
+ )
+ else:
+ print ' Vertical component too small *or* skipped, not converted'
+
+ else:
+ print '[WARNING] Unchanged component:', component
+
+ if dupComponent and NetExternalComponents.isExternal( component ):
+ NetExternalComponents.setExternal( dupComponent )
+
+ if editor: editor.fit()
+
+ except ErrorMessage, e:
+ print e; errorCode = e.code
+ except Exception, e:
+ print '\n\n', e; errorCode = 1
+ traceback.print_tb(sys.exc_info()[2])
+
+ UpdateSession.close()
+ return mpxCell
def scriptMain ( **kw ):
diff --git a/cumulus/src/tools/yosys.py b/cumulus/src/tools/yosys.py
index 3c7c00ff..74ecb90b 100755
--- a/cumulus/src/tools/yosys.py
+++ b/cumulus/src/tools/yosys.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import sys
import os
diff --git a/documentation/content/pages/documentation.rst b/documentation/content/pages/documentation.rst
index 7c6d80a8..16fb4563 100644
--- a/documentation/content/pages/documentation.rst
+++ b/documentation/content/pages/documentation.rst
@@ -55,7 +55,10 @@ Coriolis Documentation
A Tutorial to use Coriolis through Python
`Python/C++ Tutorial <{filename}/pages/python-cpp/PythonCpp_HTML.rst>`_ |br|
- A Tutorial to the Python/C++ interface |API|
+ A Tutorial to the Python/C++ interface |API| (C-macros version)
+
+ `Python/C++ Tutorial (template) <{filename}/pages/python-cpp-new/PythonCppNew_HTML.rst>`_ |br|
+ A Tutorial to the Python/C++ interface |API| (C++ template version)
`Stratus Language <{filename}/pages/stratus/Stratus_HTML.rst>`_ |br|
A Netlist Capture Language (on top of Python)
diff --git a/documentation/content/pages/python-cpp-new/Implementation.rst b/documentation/content/pages/python-cpp-new/Implementation.rst
new file mode 100644
index 00000000..67fabb7e
--- /dev/null
+++ b/documentation/content/pages/python-cpp-new/Implementation.rst
@@ -0,0 +1,507 @@
+.. -*- Mode: rst -*-
+
+
+2. Implementation
+=================
+
+We do not try to provides an iterface as sleek as ``pybind11`` that completely
+hides the Python/C API. Instead we keep mostly visible the classic structure of
+the Python/C API but we provides templates to automate as much as possible the
+boring tasks (and code duplication). This way, if we need a very specific
+feature at some point, we can still revert back to the pure Python/C API.
+
+The key features of our wrapper are:
+
+* The ``PyTypeManager`` and it's derived classes to store and share informations
+ about all our newly defined ``PyTypeObjects``.
+
+* The ``callMethod<>()`` and ``callFunction<>()`` function templates to
+ automatically generate a wrapper around C++ object methods or functions.
+
+* The ``PyBoject* objectLink( CppT* )`` functions templates that provides C++ to Python
+ object translation.
+
+* The ``bool pyAs( PyObject*, CppT*& )`` functions templates that provides Python to C++
+ object translation.
+
+We creates only two kind of ``PyObject`` (but many ``PyTypeObject``):
+
+* ``PyVoidpointer`` which encapsulate one void pointer to the C++ associated
+ object.
+
+ .. code-block:: Python
+
+ extern "C" {
+ typedef struct PyVoidPointer {
+ PyObject_HEAD
+ void* _object;
+ };
+ }
+
+* ``PyIteratorPointer`` which encapsulate one void pointer to the C++ associated
+ iterator and one another to the ``PyObject`` of the container.
+
+ .. code-block:: Python
+
+ extern "C" {
+ typedef struct PyVoidPointer {
+ PyObject_HEAD
+ void* _object; // C++ iterator.
+ PyVoidPointer* _container; // Python wrapped container.
+ };
+ }
+
+
+2.1 PyTypeManager
+~~~~~~~~~~~~~~~~~
+
+``PyTypeManager`` has two usage:
+
+* Act as a registry of all the created ``PyTypeObject``, and serve as a
+ dispatcher for the ``PyTypeObject`` *tp* like methods.
+
+* Provide a non-template abstract base class for all the derived ``PyTypeObject``.
+ As said, it is not a template class but it supplies function member
+ template. Derived classes are provides for different kind of C++
+ class.
+
+ * :cb:`PyTypeManagerVTrunk`
+
+ Is an intermediate between the non-template base class and all the
+ templatized others.
+
+ * :cb:`PyTypeManagerNonDBo`
+
+ Template for standalone C++ classes that are not derived from ``DBo``.
+ For example ``Box`` or ``Parameter``.
+
+ * :cb:`PyTypeManagerDBo`
+
+ Template for C++ classes that *are* not derived from ``DBo``.
+ For example ``Cell`` or ``Instance``.
+
+ * :cb:`PyTypeManagerVector`, template for C++ ``std::vector``.
+
+ * :cb:`PyTypeManagerVectorIterator`
+
+ Template for C++ ``std::vector::iterator``, automatically created
+ from the vector registration.
+
+ * :cb:`PyTypeManagerMap`, template for C++ ``std::map``.
+
+ * :cb:`PyTypeManagerMapIterator`
+
+ Template for C++ ``std::vector::iterator``, automatically created
+ from the map registration.
+
+ * :cb:`PyTypeManagerCollection<,CppT>`, template for C++ ``Hurricane::Collection``.
+
+ * :cb:`PyTypeManagerCollectionIterator<,CppT>`
+
+ Template for C++ ``Hurricane::Locator``, automatically created from
+ the collection registration.
+
+
+2.2 Highjacking the *tp* methods
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions of a ``PyTypeObject`` like the *tp* methods (``tp_alloc``, ``tp_print``,
+``tp_hash``, ...) must have a C-linkage. So we create *one* function per slot that
+we want to use, set that *same* function for all the created ``PyTypeObject``, and
+perform a dispact in it. The drawback is that for each access we have to perform
+a map lookup. Hope it is fast.
+
+Excerpt from the code:
+
+.. code-block:: C++
+
+ namespace Isobar3 {
+
+ extern "C" {
+
+ // Here we have C-linkage.
+ extern long _tpHash ( PyObject* self )
+ {
+ // Dispatch towards the relevant class, based on ob_type pointer.
+ return PyTypeManager::get( self->ob_type )->_getTpHash( asVPtr(self) );
+ }
+
+ }
+
+ class PyTypeManager {
+ public:
+ void PyTypeManager::_setupPyType ()
+ // Derived classes must implement it as they see fit.
+ virtual long _getTpHash ( PyVoidPointer* ) = 0;
+ template
+ static PyTypeManager* _get();
+ private:
+ PyTypeObject _typeObject;
+ };
+
+ void PyTypeManager::_setupPyType ()
+ {
+ PyTypeObject* ob_type = _getTypeObject();
+ ob_type->tp_name = _getPyTypeName().c_str();
+ ob_type->tp_dealloc = (destructor)&::Isobar3::_tpDeAlloc;
+ ob_type->tp_str = (reprfunc) &::Isobar3::_tpStr;
+ // All Python Type will call the same _tpHash().
+ ob_type->tp_hash = (hashfunc) &::Isobar3::_tpHash;
+ ob_type->tp_compare = (cmpfunc) &::Isobar3::_getTpCompare;
+ ob_type->tp_methods = _getMethods();
+ ob_type->tp_getset = _getGetsets();
+ }
+
+ } // Isobar3 namespace.
+
+
+2.3 Going From Python to C++
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To convert a C++ object (pointer) into a Python object, a set of
+:cb:`pyAs<>` templates functions are supplieds.
+
+Specialization for all POD type that can be directly translated into
+Python types must be provideds (``bool``, ``int``, ``long``, ``double``,
+``std::string``, ...).
+
+Partial specialization for type availables through the ``PyTypeManager``
+is supplied. It checks the manager for the type's existence.
+
+.. code-block:: C++
+
+ // Most generic template, should *not* be used.
+ // So issue an error message and report a failed conversion.
+ template
+ inline bool pyAs ( PyObject* pyArg, T& arg )
+ {
+ std::cerr << "Isobar3.pyAs(): Unsupported type \""
+ << demangle(typeid(T).name()) << "\"" << endl;
+ return false;
+ }
+
+ // Template specialization for POD type "int".
+ template<>
+ inline bool pyAs ( PyObject* pyArg, int& arg )
+ {
+ if (PyInt_Check (pyArg)) { arg = PyInt_AsLong ( pyArg ); }
+ else if (PyLong_Check(pyArg)) { arg = PyLong_AsLong( pyArg ); }
+ else return false;
+ return true;
+ }
+
+ // Template partial specialization for any type registered in
+ // the PyTypeManager.
+ template
+ inline bool pyAs ( PyObject* pyArg, T*& arg )
+ {
+ PyTypeManager* manager = PyTypeManager::_get();
+ if (not manager) {
+ std::cerr << "Isobar3.pyAs(): Unsupported type \""
+ << typeid(T).name() << "\"" << endl;
+ return false;
+ }
+ arg = (T*)( asVPtr( pyArg )->_object );
+ return true;
+ }
+
+ template
+ inline bool pyAs ( PyVoidPointer* pyArg, T*& arg )
+ { return pyAs( (PyObject*)pyArg, arg ); }
+
+
+2.4 Going From C++ to Python
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To convert a Python object into a C++ object, a set of
+:cb:`objectLink<>` templates functions are supplieds.
+
+We completely disable the partially specialized templates for
+objects that are non-POD as the compiler seems to be unable to
+choose the fully specialized template in this case (or I still
+misunderstood the template resolution mechanism).
+
+In the case of object registered in ``PyTypeManager``, we delegate
+the ``PyObject`` creation to the ``PyTypeManager::link()`` template
+function, which in turn, can call the right ``PyTypeManagerVTrunk::_link()``
+method.
+
+.. note:: The ``PyTypeManagerVTrunk::_link()`` method is the reason
+ **why** we need the intermediate ``PyTypeManagerVTrunk``
+ template class.
+
+
+.. code-block:: C++
+
+ // The most generic template, should *not* be used. So raise a Python exception.
+ template< typename CppT >
+ inline PyObject* objectLink ( CppT object )
+ {
+ std::string message = "Overload for Isobar3::objectLink< "
+ + demangle(typeid(CppT).name()) + " >() is missing.";
+ PyErr_SetString( HurricaneError, message.c_str() );
+ return NULL;
+ }
+
+ // Disable this template if "CppT" is an already supported type.
+ template< typename CppT
+ , typename std::enable_if< !std::is_same::value
+ && !std::is_same::value
+ && !std::is_same::value
+ && !std::is_same::value
+ ,bool>::type = true >
+ inline PyObject* objectLink ( CppT* object )
+ { return PyTypeManager::link( object ); }
+
+ // Disable this template if "CppT" is an already supported type.
+ template< typename CppT
+ , typename std::enable_if< !std::is_same::value
+ && !std::is_same::value
+ && !std::is_same::value
+ && !std::is_same::value
+ ,bool>::type = true >
+ inline PyObject* objectLink ( const CppT* object )
+ { return PyTypeManager::link( const_cast( object )); }
+
+ // Specializations for POD type "int" .
+ template<> inline PyObject* objectLink ( int i )
+ { return PyInt_FromLong( i ); }
+
+ template<> inline PyObject* objectLink ( const int i )
+ { return PyInt_FromLong( i ); }
+
+ template<> inline PyObject* objectLink ( const int* i )
+ { return PyInt_FromLong( *i ); }
+
+
+2.5 Object Methods Wrappers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One of the more tedious task in exporting a C++ interface towards Python is
+to have wrap the C++ functions/methods into C-linkage functions that can be
+put into the ``PyMethodDef`` table.
+
+Basically, we want to fit:
+
+* A C++ function or method with a variable number of arguments, each argument
+ having it's own type.
+
+ .. code-block:: C++
+
+ class Parameter {
+ // ...
+ public:
+ void addValue ( std::string s, int v );
+ // ...
+ };
+
+* Into a ``PyCFunction`` prototype.
+
+ .. code-block:: C++
+
+ extern "C" {
+ typedef PyObject* ( *PyCFunction )( PyObject* self, PyObject* args );
+ }
+
+ Here, the C++ object is provided through the first argument and the
+ functions arguments through a *tuple* in second argument. In Python
+ wrappers, the tuple doesn't have any complex structure, it boils down
+ to a sequence of ``PyObject*`` (that must match the number of arguments
+ of it's C++ function conterpart).
+
+So, the problem is to change a tuple which size is only kown at *runtime*
+into a list of C/C++ parameters known at *compile time*.
+
+I am not such an expert in template programming so I can find a *generic*
+solution able to handle any number of parameters. Instead I did write
+a set of templates managing the translation from zero to ten parameters.
+I did delay that translation as much as possible so it happens very close
+to the C++ function call and the duplicated code needed for each template
+is kept to a minimum.
+
+To translate the Python tuple into an ordered list (vector like) of C++
+object *of different types*, the obvious choice is C++ ``std::tuple<>``.
+
+Another challenge is the return type. I distinguish three flavor of
+return type:
+
+* Function returning nothing (``void``).
+* Function returning a value.
+* Function returning a reference to a value.
+* Function returning a pointer.
+
+To uniformize the return type we create four templates ``_callMethodReturn<>()``
+that takes whatever the C++ return type is, and turn it into a ``PyObject*``.
+Except for the functions returning ``void``, we call ``objectLink<>()`` to
+wrap the value.
+
+Here is an excerpt of the code:
+
+.. code-block:: C++
+
+ // Flavor for "return by pointer".
+ template< typename TC, typename TR, typename... TArgs
+ , typename std::enable_if::value,bool>::type = true >
+ inline PyObject* _callMethodReturn ( TR(TC::* method)(TArgs...), TC* cppObject, TArgs... args )
+ {
+ TR pvalue = (cppObject->*method)( args... );
+ return objectLink( pvalue );
+ }
+
+ // Flavor for "return void".
+ template< typename TC, typename TR, typename... TArgs
+ , typename std::enable_if::value,bool>::type = true >
+ inline PyObject* _callMethodReturn ( TR(TC::* method)(TArgs...), TC* cppObject, TArgs... args )
+ {
+ (cppObject->*method)( args... );
+ Py_RETURN_NONE;
+ }
+
+ // Function without argument.
+ template< typename TC, typename TR >
+ inline PyObject* _callMethod ( TR(TC::* method)(), TC* cppObject, std::tuple<> )
+ { return _callMethodReturn( method, cppObject ); }
+
+ // Function with one argument.
+ template< typename TC, typename TR, typename TA0 >
+ inline PyObject* _callMethod ( TR(TC::* method)(TA0), TC* cppObject, std::tuple args )
+ { return _callMethodReturn( method, cppObject, std::get<0>(args) ); }
+
+ // Function with two arguments.
+ template< typename TC, typename TR, typename TA0, typename TA1 >
+ PyObject* _callMethod ( TR(TC::* method)(TA0,TA1), TC* cppObject, std::tuple args )
+ { return _callMethodReturn( method, cppObject, std::get<0>(args), std::get<1>(args) ); }
+
+
+The complete work of translating the Python tuple into a ``std::tuple<>`` and error
+handling is done with a dedicated template class ``PyMethodWrapper`` and it's ``call()``
+method.
+
+As a class template cannot guess the template parameters, we wrap them into a
+function template which can perform the guess. The ``callMethod<>`` template function.
+
+In the end, what the user can write is simply:
+
+.. code-block:: C++
+
+ static PyObject* PyParameter_addValue ( PyVoidPointer* self, PyObject* args )
+ { return callMethod("Parameter.addValue",&Parameter::addValue,self,args); }
+
+ PyMethodDef PyParameter_Methods[] =
+ { { "isFile" , (PyCFunction)PyParameter_isFile , METH_NOARGS
+ , "Tells if this parameter (string) holds a file name." }
+ , { "addValue", (PyCFunction)PyParameter_addValue, METH_VARARGS
+ , "Add a new value to parameter of enumerated type." }
+ // ...
+ , {NULL, NULL, 0, NULL} /* sentinel */
+ };
+
+
+2.6 Case of C++ overloaded functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This apply to both overloaded functions and functions with arguments values.
+
+In that case, the only solution is to create a set of different functions
+with differents arguments to expose all the various signature of the function.
+We then create a function wrapper that calls them in decreasing number of
+parameters order.
+
+.. note::
+
+ If something goes wrong in a ``callMethod()``, it returns ``NULL`` and
+ sets an error exception. If, say, the ``setString3()`` variant fails,
+ but ``setString2()`` succeed, it will clear the error and sets ``rvalue``
+ to something non-``NULL``.
+
+You may also notice that the signature of an un-overloaded function is that
+of a normal function, not a class method, with the object (aka C++ ``this``
+passed as the first argument). So ``callMethod()`` and ``PyMethodWrapper``
+support both case (through different constructors).
+
+.. code-block:: C++
+
+ static bool setString1 ( Parameter* self, std::string value )
+ { return self->setString(value); }
+
+ static bool setString2 ( Parameter* self, std::string value, unsigned int flags )
+ { return self->setString(value,Configuration::getDefaultPriority(),flags); }
+
+ static bool setString3 ( Parameter* self
+ , std::string value
+ , unsigned int flags
+ , Parameter::Priority pri )
+ { return self->setString(value,pri,flags); }
+
+ static PyObject* PyParameter_setString ( PyVoidPointer* self, PyObject* args )
+ {
+ PyObject* rvalue = callMethod("Parameter.setString",&setString3,self,args);
+ if (not rvalue) rvalue = callMethod("Parameter.setString",&setString2,self,args);
+ if (not rvalue) rvalue = callMethod("Parameter.setString",&setString1,self,args);
+ return rvalue;
+ }
+
+ PyMethodDef PyParameter_Methods[] =
+ { { "isFile" , (PyCFunction)PyParameter_isFile , METH_NOARGS
+ , "Tells if this parameter (string) holds a file name." }
+ , { "setString", (PyCFunction)PyParameter_setString, METH_VARARGS
+ , "Set the parameter value as a string." }
+ // ...
+ , {NULL, NULL, 0, NULL} /* sentinel */
+ };
+
+
+2.7 Wrapper for ordinary functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The same mechanic as for the object methods has been built for ordinary
+functions. The top level wrapper beeing ``callFunction<>()`` ...
+
+.. code-block:: C++
+
+ static PyObject* PyCfg_hasParameter ( PyObject* module, PyObject* args )
+ { return callFunction("hasParameter",&hasParameter,args); }
+
+ static PyMethodDef PyCfg_Methods[] =
+ { { "hasParameter", (PyCFunction)PyCfg_hasParameter, METH_VARARGS
+ , "Tells if a parameter exists already in the DB." }
+ // ...
+ , {NULL, NULL, 0, NULL} /* sentinel */
+ };
+
+
+2.8 Object post-create hook
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By defining specialization of the ``pyTypePostModuleinit<>()`` function template,
+you can add any post-treatment to a Python type object. Like adding sub-classes
+or constants values.
+
+In the following code, we add ``Priority`` as a sub-object of ``Parameter`` then
+set some constant values in ``Priority``. This was we emulate the behavior of
+the ``Priority`` ``enum``.
+
+.. code-block:: C++
+
+ template<>
+ inline void pyTypePostModuleInit ( PyTypeObject* typeObject )
+ {
+ PyTypeManagerNonDBo::create( (PyObject*)typeObject
+ , Cfg::PyParameterPriority_Methods
+ , NULL
+ , PyTypeManager::NoCppDelete );
+ }
+
+ template<>
+ inline void pyTypePostModuleInit ( PyTypeObject* typeObject )
+ {
+ // Parameter::Priority enum.
+ addConstant( typeObject, "UseDefault" , Cfg::Parameter::UseDefault );
+ addConstant( typeObject, "ApplicationBuiltin", Cfg::Parameter::ApplicationBuiltin );
+ addConstant( typeObject, "ConfigurationFile" , Cfg::Parameter::ConfigurationFile );
+ addConstant( typeObject, "UserFile" , Cfg::Parameter::UserFile );
+ addConstant( typeObject, "CommandLine" , Cfg::Parameter::CommandLine );
+ addConstant( typeObject, "Interactive" , Cfg::Parameter::Interactive );
+ }
+
+
diff --git a/documentation/content/pages/python-cpp-new/Introduction.rst b/documentation/content/pages/python-cpp-new/Introduction.rst
new file mode 100644
index 00000000..e0221a5a
--- /dev/null
+++ b/documentation/content/pages/python-cpp-new/Introduction.rst
@@ -0,0 +1,76 @@
+.. -*- Mode: rst -*-
+
+
+1. Introduction
+===============
+
+* This document is written for people already familiar with the
+ `Python/C API Reference Manual`_.
+
+* The macros provided by the Hurricane Python/C API are written using
+ the standard Python C/API. That is, you may not use them and write
+ directly your functions with the original API or any mix between.
+ You only have to respect some naming convention.
+
+* Coriolis is build against Python 2.7.
+
+
+1.1 About Technical Choices
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some would say, why not use *off the shelf* wrappers like ``swig``,
+``boost::python`` or ``pybind11``, here are some clues.
+
+#. **Partial exposure of the C++ class tree.** We expose at Python level
+ C++ base classes, only if they provides common methods that we want
+ to see. Otherwise, we just show them as base classes under Python.
+ For instance ``Library`` is derived from ``DBo``, but we won't see
+ it under Python.
+
+#. **Bi-directional communication.** When a Python object is deleted, the
+ wrapper obviously has a pointer toward the underlying C++ object and
+ is able to delete it. But, the reverse case can occurs, meaning that
+ you have a C++ object wrapped in Python and the database delete the
+ underlying object. The wrapped Python object *must* be informed that
+ it no longer refer a valid C++ one. Moreover, as we do not control
+ when Python objects gets deleteds (that is, when their reference count
+ reaches zero), we can have valid Python object with a dangling
+ C++ pointer. So our Python objects can be warned by the C++ objects
+ that they are no longer valid and any other operation than the
+ deletion should result in a severe non-blocking error.
+
+ To be precise, this apply to persistent object in the C++ database,
+ like ``Cell``, ``Net``, ``Instance`` or ``Component``. Short lived
+ objects like ``Box`` or ``Point`` retains the classic Python behavior.
+
+ Another aspect is that, for all derived ``DBo`` objects, one and only
+ one Python object is associated. For one given ``Instance`` object we
+ will always return the *same* ``PyInstance`` object, thanks to the
+ bi-directional link. Obviously, the *reference count* of the
+ ``PyInstance`` is managed accordingly. This mechanism is implemented
+ by the ``PyTypeManager::_link()`` method.
+
+#. **Linking accross modules.** As far as I understand, the wrappers
+ are for monolithic libraries. That is, you wrap the entire library
+ in one go. But Hurricane has a modular design, the core database
+ then various tools. We do not, and cannot, have one gigantic wrapper
+ that would encompass all the libraries in one go. We do one Python
+ module for one C++ library.
+
+ This brings another issue, at Python level this time. The Python
+ modules for the libraries have to share some functions. Python
+ provides a mechanism to pass C function pointers accross modules,
+ (``Capsule``) but I did not fully understand it.
+
+ Instead, we register all the newly defined Python type object
+ in the ``PyTypeManager`` and we link the associated C++ library
+ into all Python modules. So all types and ancillary functions can
+ easily be seen accross modules.
+
+ This way, we do not rely upon a pointer transmission through Python
+ modules, but directly uses linker capabilities.
+
+ **The PyTypeManager** approach also suppress the need to *split* into
+ two libraries the Python modules like in the C-Macros implementation,
+ and the double compilation pass.
+
diff --git a/documentation/content/pages/python-cpp-new/PythonCppNew_HTML.rst b/documentation/content/pages/python-cpp-new/PythonCppNew_HTML.rst
new file mode 100644
index 00000000..dab81f06
--- /dev/null
+++ b/documentation/content/pages/python-cpp-new/PythonCppNew_HTML.rst
@@ -0,0 +1,29 @@
+.. -*- mode: rst; explicit-buffer-name: "PythonCppNew_HTML.rst" -*-
+
+
+============================================
+Hurricane Python/C++ API Tutorial (template)
+============================================
+
+
+:slug: python-cpp-new
+:date: 2020-01-02 16:00
+:Authors: Jean-Paul Chaput
+:Contact:
+:Version: June 4, 2019 (jpc)
+:status: hidden
+
+
+.. include:: ../../../etc/definitions.rst
+
+
+Printable version of this Document
+==================================
+
+
+.. contents::
+ :depth: 2
+
+.. include:: Introduction.rst
+.. include:: Implementation.rst
+
diff --git a/documentation/examples/code/engine/smurf/CMakeLists.txt b/documentation/examples/code/engine/smurf/CMakeLists.txt
index ed1548ec..295f9bea 100644
--- a/documentation/examples/code/engine/smurf/CMakeLists.txt
+++ b/documentation/examples/code/engine/smurf/CMakeLists.txt
@@ -11,7 +11,7 @@
setup_project_paths(CORIOLIS)
set_cmake_policies()
- setup_boost(program_options python regex)
+ setup_boost(program_options python)
setup_qt()
find_package(LibXml2 REQUIRED)
diff --git a/documentation/output/pages/documentation.html b/documentation/output/pages/documentation.html
index 0b4b8f2a..ad8c67b0 100644
--- a/documentation/output/pages/documentation.html
+++ b/documentation/output/pages/documentation.html
@@ -141,7 +141,9 @@ Using the software
Python Tutorial
A Tutorial to use Coriolis through Python
Python/C++ Tutorial
-A Tutorial to the Python/C++ interface api
+A Tutorial to the Python/C++ interface api (C-macros version)
+Python/C++ Tutorial (template)
+A Tutorial to the Python/C++ interface api (C++ template version)
Stratus Language
A Netlist Capture Language (on top of Python)
DpGen Extension (Stratus)
diff --git a/documentation/output/pages/python-cpp-new.html b/documentation/output/pages/python-cpp-new.html
new file mode 100644
index 00000000..4fe139b7
--- /dev/null
+++ b/documentation/output/pages/python-cpp-new.html
@@ -0,0 +1,691 @@
+
+
+
+
+
+
+
+
+
+
+ Hurricane Python/C++ API Tutorial (template) - Coriolis VLSI CAD Tools [offline]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+This document is written for people already familiar with the
+Python/C API Reference Manual .
+The macros provided by the Hurricane Python/C API are written using
+the standard Python C/API. That is, you may not use them and write
+directly your functions with the original API or any mix between.
+You only have to respect some naming convention.
+Coriolis is build against Python 2.7.
+
+
+
+
Some would say, why not use off the shelf wrappers like swig ,
+boost::python or pybind11 , here are some clues.
+
+Partial exposure of the C++ class tree. We expose at Python level
+C++ base classes, only if they provides common methods that we want
+to see. Otherwise, we just show them as base classes under Python.
+For instance Library is derived from DBo , but we won't see
+it under Python.
+
+Bi-directional communication. When a Python object is deleted, the
+wrapper obviously has a pointer toward the underlying C++ object and
+is able to delete it. But, the reverse case can occurs, meaning that
+you have a C++ object wrapped in Python and the database delete the
+underlying object. The wrapped Python object must be informed that
+it no longer refer a valid C++ one. Moreover, as we do not control
+when Python objects gets deleteds (that is, when their reference count
+reaches zero), we can have valid Python object with a dangling
+C++ pointer. So our Python objects can be warned by the C++ objects
+that they are no longer valid and any other operation than the
+deletion should result in a severe non-blocking error.
+To be precise, this apply to persistent object in the C++ database,
+like Cell , Net , Instance or Component . Short lived
+objects like Box or Point retains the classic Python behavior.
+Another aspect is that, for all derived DBo objects, one and only
+one Python object is associated. For one given Instance object we
+will always return the same PyInstance object, thanks to the
+bi-directional link. Obviously, the reference count of the
+PyInstance is managed accordingly. This mechanism is implemented
+by the PyTypeManager::_link() method.
+
+Linking accross modules. As far as I understand, the wrappers
+are for monolithic libraries. That is, you wrap the entire library
+in one go. But Hurricane has a modular design, the core database
+then various tools. We do not, and cannot, have one gigantic wrapper
+that would encompass all the libraries in one go. We do one Python
+module for one C++ library.
+This brings another issue, at Python level this time. The Python
+modules for the libraries have to share some functions. Python
+provides a mechanism to pass C function pointers accross modules,
+(Capsule ) but I did not fully understand it.
+Instead, we register all the newly defined Python type object
+in the PyTypeManager and we link the associated C++ library
+into all Python modules. So all types and ancillary functions can
+easily be seen accross modules.
+This way, we do not rely upon a pointer transmission through Python
+modules, but directly uses linker capabilities.
+The PyTypeManager approach also suppress the need to split into
+two libraries the Python modules like in the C-Macros implementation,
+and the double compilation pass.
+
+
+
+
+
+
+
+
We do not try to provides an iterface as sleek as pybind11 that completely
+hides the Python/C API. Instead we keep mostly visible the classic structure of
+the Python/C API but we provides templates to automate as much as possible the
+boring tasks (and code duplication). This way, if we need a very specific
+feature at some point, we can still revert back to the pure Python/C API.
+
The key features of our wrapper are:
+
+The PyTypeManager and it's derived classes to store and share informations
+about all our newly defined PyTypeObjects .
+The callMethod<>() and callFunction<>() function templates to
+automatically generate a wrapper around C++ object methods or functions.
+The PyBoject* objectLink<CppT>( CppT* ) functions templates that provides C++ to Python
+object translation.
+The bool pyAs<CppT>( PyObject*, CppT*& ) functions templates that provides Python to C++
+object translation.
+
+
We creates only two kind of PyObject (but many PyTypeObject ):
+
+PyVoidpointer which encapsulate one void pointer to the C++ associated
+object.
+extern "C" {
+ typedef struct PyVoidPointer {
+ PyObject_HEAD
+ void * _object ;
+ };
+}
+
+
+PyIteratorPointer which encapsulate one void pointer to the C++ associated
+iterator and one another to the PyObject of the container.
+extern "C" {
+ typedef struct PyVoidPointer {
+ PyObject_HEAD
+ void * _object ; // C ++ iterator .
+ PyVoidPointer * _container ; // Python wrapped container .
+ };
+}
+
+
+
+
+
+
PyTypeManager has two usage:
+
+Act as a registry of all the created PyTypeObject , and serve as a
+dispatcher for the PyTypeObject tp like methods.
+
+Provide a non-template abstract base class for all the derived PyTypeObject .
+As said, it is not a template class but it supplies function member
+template. Derived classes are provides for different kind of C++
+class.
+
+PyTypeManagerVTrunk<CppT>
+Is an intermediate between the non-template base class and all the
+templatized others.
+
+PyTypeManagerNonDBo<CppT>
+Template for standalone C++ classes that are not derived from DBo .
+For example Box or Parameter .
+
+PyTypeManagerDBo<CppT>
+Template for C++ classes that are not derived from DBo .
+For example Cell or Instance .
+
+PyTypeManagerVector<CppT> , template for C++ std::vector<CppT*> .
+
+PyTypeManagerVectorIterator<CppT>
+Template for C++ std::vector<CppT*>::iterator , automatically created
+from the vector registration.
+
+PyTypeManagerMap<CppK,CppT> , template for C++ std::map<CppK*,CppT*> .
+
+PyTypeManagerMapIterator<CppK,CppT>
+Template for C++ std::vector<CppK*,CppT*>::iterator , automatically created
+from the map registration.
+
+PyTypeManagerCollection<,CppT> , template for C++ Hurricane::Collection<CppT*> .
+
+PyTypeManagerCollectionIterator<,CppT>
+Template for C++ Hurricane::Locator<CppT*> , automatically created from
+the collection registration.
+
+
+
+
+
+
+
+
Functions of a PyTypeObject like the tp methods (tp_alloc , tp_print ,
+tp_hash , ...) must have a C-linkage. So we create one function per slot that
+we want to use, set that same function for all the created PyTypeObject , and
+perform a dispact in it. The drawback is that for each access we have to perform
+a map lookup. Hope it is fast.
+
Excerpt from the code:
+
namespace Isobar3 {
+
+ extern "C" {
+
+ // Here we have C-linkage.
+ extern long _tpHash ( PyObject * self )
+ {
+ // Dispatch towards the relevant class, based on ob_type pointer.
+ return PyTypeManager :: get ( self -> ob_type ) -> _getTpHash ( asVPtr ( self ) );
+ }
+
+ }
+
+ class PyTypeManager {
+ public :
+ void PyTypeManager :: _setupPyType ()
+ // Derived classes must implement it as they see fit.
+ virtual long _getTpHash ( PyVoidPointer * ) = 0 ;
+ template < typename CppT >
+ static PyTypeManager * _get ();
+ private :
+ PyTypeObject _typeObject ;
+ };
+
+ void PyTypeManager :: _setupPyType ()
+ {
+ PyTypeObject * ob_type = _getTypeObject ();
+ ob_type -> tp_name = _getPyTypeName (). c_str ();
+ ob_type -> tp_dealloc = ( destructor ) &:: Isobar3 :: _tpDeAlloc ;
+ ob_type -> tp_str = ( reprfunc ) &:: Isobar3 :: _tpStr ;
+ // All Python Type will call the same _tpHash().
+ ob_type -> tp_hash = ( hashfunc ) &:: Isobar3 :: _tpHash ;
+ ob_type -> tp_compare = ( cmpfunc ) &:: Isobar3 :: _getTpCompare ;
+ ob_type -> tp_methods = _getMethods ();
+ ob_type -> tp_getset = _getGetsets ();
+ }
+
+} // Isobar3 namespace.
+
+
+
+
+
To convert a C++ object (pointer) into a Python object, a set of
+pyAs<> templates functions are supplieds.
+
Specialization for all POD type that can be directly translated into
+Python types must be provideds (bool , int , long , double ,
+std::string , ...).
+
Partial specialization for type availables through the PyTypeManager
+is supplied. It checks the manager for the type's existence.
+
// Most generic template, should *not* be used.
+// So issue an error message and report a failed conversion.
+template < typename T >
+inline bool pyAs ( PyObject * pyArg , T & arg )
+{
+ std :: cerr << "Isobar3.pyAs<T>(): Unsupported type \" "
+ << demangle ( typeid ( T ). name ()) << " \" " << endl ;
+ return false ;
+}
+
+// Template specialization for POD type "int".
+template <>
+inline bool pyAs ( PyObject * pyArg , int & arg )
+{
+ if ( PyInt_Check ( pyArg )) { arg = PyInt_AsLong ( pyArg ); }
+ else if ( PyLong_Check ( pyArg )) { arg = PyLong_AsLong ( pyArg ); }
+ else return false ;
+ return true ;
+}
+
+// Template partial specialization for any type registered in
+// the PyTypeManager.
+template < typename T >
+inline bool pyAs ( PyObject * pyArg , T *& arg )
+{
+ PyTypeManager * manager = PyTypeManager :: _get < T > ();
+ if ( not manager ) {
+ std :: cerr << "Isobar3.pyAs<T>(): Unsupported type \" "
+ << typeid ( T ). name () << " \" " << endl ;
+ return false ;
+ }
+ arg = ( T * )( asVPtr ( pyArg ) -> _object );
+ return true ;
+}
+
+template < typename T >
+inline bool pyAs ( PyVoidPointer * pyArg , T *& arg )
+{ return pyAs ( ( PyObject * ) pyArg , arg ); }
+
+
+
+
+
To convert a Python object into a C++ object, a set of
+objectLink<> templates functions are supplieds.
+
We completely disable the partially specialized templates for
+objects that are non-POD as the compiler seems to be unable to
+choose the fully specialized template in this case (or I still
+misunderstood the template resolution mechanism).
+
In the case of object registered in PyTypeManager , we delegate
+the PyObject creation to the PyTypeManager::link() template
+function, which in turn, can call the right PyTypeManagerVTrunk<CppT>::_link()
+method.
+
+
Note
+
The PyTypeManagerVTrunk<CppT>::_link() method is the reason
+why we need the intermediate PyTypeManagerVTrunk<CppT>
+template class.
+
+
// The most generic template, should *not* be used. So raise a Python exception.
+template < typename CppT >
+inline PyObject * objectLink ( CppT object )
+{
+ std :: string message = "Overload for Isobar3::objectLink< "
+ + demangle ( typeid ( CppT ). name ()) + " >() is missing." ;
+ PyErr_SetString ( HurricaneError , message . c_str () );
+ return NULL ;
+}
+
+// Disable this template if "CppT" is an already supported type.
+template < typename CppT
+ , typename std :: enable_if < ! std :: is_same < CppT , bool >:: value
+ && ! std :: is_same < CppT , int >:: value
+ && ! std :: is_same < CppT , std :: string >:: value
+ && ! std :: is_same < CppT , const std :: string >:: value
+ , bool >:: type = true >
+inline PyObject * objectLink ( CppT * object )
+{ return PyTypeManager :: link < CppT > ( object ); }
+
+// Disable this template if "CppT" is an already supported type.
+template < typename CppT
+ , typename std :: enable_if < ! std :: is_same < CppT , bool >:: value
+ && ! std :: is_same < CppT , int >:: value
+ && ! std :: is_same < CppT , std :: string >:: value
+ && ! std :: is_same < CppT , const std :: string >:: value
+ , bool >:: type = true >
+inline PyObject * objectLink ( const CppT * object )
+{ return PyTypeManager :: link < CppT > ( const_cast < CppT *> ( object )); }
+
+// Specializations for POD type "int" .
+template <> inline PyObject * objectLink < int > ( int i )
+{ return PyInt_FromLong ( i ); }
+
+template <> inline PyObject * objectLink < const int > ( const int i )
+{ return PyInt_FromLong ( i ); }
+
+template <> inline PyObject * objectLink < const int *> ( const int * i )
+{ return PyInt_FromLong ( * i ); }
+
+
+
+
+
One of the more tedious task in exporting a C++ interface towards Python is
+to have wrap the C++ functions/methods into C-linkage functions that can be
+put into the PyMethodDef table.
+
Basically, we want to fit:
+
+A C++ function or method with a variable number of arguments, each argument
+having it's own type.
+class Parameter {
+ // ...
+ public :
+ void addValue ( std :: string s , int v );
+ // ...
+};
+
+
+Into a PyCFunction prototype.
+extern "C" {
+ typedef PyObject * ( * PyCFunction )( PyObject * self , PyObject * args );
+}
+
+Here, the C++ object is provided through the first argument and the
+functions arguments through a tuple in second argument. In Python
+wrappers, the tuple doesn't have any complex structure, it boils down
+to a sequence of PyObject* (that must match the number of arguments
+of it's C++ function conterpart).
+
+
+
So, the problem is to change a tuple which size is only kown at runtime
+into a list of C/C++ parameters known at compile time .
+
I am not such an expert in template programming so I can find a generic
+solution able to handle any number of parameters. Instead I did write
+a set of templates managing the translation from zero to ten parameters.
+I did delay that translation as much as possible so it happens very close
+to the C++ function call and the duplicated code needed for each template
+is kept to a minimum.
+
To translate the Python tuple into an ordered list (vector like) of C++
+object of different types , the obvious choice is C++ std::tuple<> .
+
Another challenge is the return type. I distinguish three flavor of
+return type:
+
+Function returning nothing (void ).
+Function returning a value.
+Function returning a reference to a value.
+Function returning a pointer.
+
+
To uniformize the return type we create four templates _callMethodReturn<>()
+that takes whatever the C++ return type is, and turn it into a PyObject* .
+Except for the functions returning void , we call objectLink<>() to
+wrap the value.
+
Here is an excerpt of the code:
+
// Flavor for "return by pointer".
+template < typename TC , typename TR , typename ... TArgs
+ , typename std :: enable_if < std :: is_pointer < TR >:: value , bool >:: type = true >
+inline PyObject * _callMethodReturn ( TR ( TC ::* method )( TArgs ...), TC * cppObject , TArgs ... args )
+{
+ TR pvalue = ( cppObject ->* method )( args ... );
+ return objectLink ( pvalue );
+}
+
+// Flavor for "return void".
+template < typename TC , typename TR , typename ... TArgs
+ , typename std :: enable_if < std :: is_void < TR >:: value , bool >:: type = true >
+inline PyObject * _callMethodReturn ( TR ( TC ::* method )( TArgs ...), TC * cppObject , TArgs ... args )
+{
+ ( cppObject ->* method )( args ... );
+ Py_RETURN_NONE ;
+}
+
+// Function without argument.
+template < typename TC , typename TR >
+inline PyObject * _callMethod ( TR ( TC ::* method )(), TC * cppObject , std :: tuple <> )
+{ return _callMethodReturn < TC , TR > ( method , cppObject ); }
+
+// Function with one argument.
+template < typename TC , typename TR , typename TA0 >
+inline PyObject * _callMethod ( TR ( TC ::* method )( TA0 ), TC * cppObject , std :: tuple < TA0 > args )
+{ return _callMethodReturn ( method , cppObject , std :: get < 0 > ( args ) ); }
+
+// Function with two arguments.
+template < typename TC , typename TR , typename TA0 , typename TA1 >
+PyObject * _callMethod ( TR ( TC ::* method )( TA0 , TA1 ), TC * cppObject , std :: tuple < TA0 , TA1 > args )
+{ return _callMethodReturn ( method , cppObject , std :: get < 0 > ( args ), std :: get < 1 > ( args ) ); }
+
+
The complete work of translating the Python tuple into a std::tuple<> and error
+handling is done with a dedicated template class PyMethodWrapper and it's call()
+method.
+
As a class template cannot guess the template parameters, we wrap them into a
+function template which can perform the guess. The callMethod<> template function.
+
In the end, what the user can write is simply:
+
static PyObject * PyParameter_addValue ( PyVoidPointer * self , PyObject * args )
+{ return callMethod ( "Parameter.addValue" , & Parameter :: addValue , self , args ); }
+
+PyMethodDef PyParameter_Methods [] =
+ { { "isFile" , ( PyCFunction ) PyParameter_isFile , METH_NOARGS
+ , "Tells if this parameter (string) holds a file name." }
+ , { "addValue" , ( PyCFunction ) PyParameter_addValue , METH_VARARGS
+ , "Add a new value to parameter of enumerated type." }
+ // ...
+ , { NULL , NULL , 0 , NULL } /* sentinel */
+ };
+
+
+
+
+
This apply to both overloaded functions and functions with arguments values.
+
In that case, the only solution is to create a set of different functions
+with differents arguments to expose all the various signature of the function.
+We then create a function wrapper that calls them in decreasing number of
+parameters order.
+
+
Note
+
If something goes wrong in a callMethod() , it returns NULL and
+sets an error exception. If, say, the setString3() variant fails,
+but setString2() succeed, it will clear the error and sets rvalue
+to something non-NULL .
+
+
You may also notice that the signature of an un-overloaded function is that
+of a normal function, not a class method, with the object (aka C++ this
+passed as the first argument). So callMethod() and PyMethodWrapper
+support both case (through different constructors).
+
static bool setString1 ( Parameter * self , std :: string value )
+{ return self -> setString ( value ); }
+
+static bool setString2 ( Parameter * self , std :: string value , unsigned int flags )
+{ return self -> setString ( value , Configuration :: getDefaultPriority (), flags ); }
+
+static bool setString3 ( Parameter * self
+ , std :: string value
+ , unsigned int flags
+ , Parameter :: Priority pri )
+{ return self -> setString ( value , pri , flags ); }
+
+static PyObject * PyParameter_setString ( PyVoidPointer * self , PyObject * args )
+{
+ PyObject * rvalue = callMethod ( "Parameter.setString" , & setString3 , self , args );
+ if ( not rvalue ) rvalue = callMethod ( "Parameter.setString" , & setString2 , self , args );
+ if ( not rvalue ) rvalue = callMethod ( "Parameter.setString" , & setString1 , self , args );
+ return rvalue ;
+}
+
+PyMethodDef PyParameter_Methods [] =
+ { { "isFile" , ( PyCFunction ) PyParameter_isFile , METH_NOARGS
+ , "Tells if this parameter (string) holds a file name." }
+ , { "setString" , ( PyCFunction ) PyParameter_setString , METH_VARARGS
+ , "Set the parameter value as a string." }
+ // ...
+ , { NULL , NULL , 0 , NULL } /* sentinel */
+ };
+
+
+
+
+
The same mechanic as for the object methods has been built for ordinary
+functions. The top level wrapper beeing callFunction<>() ...
+
static PyObject * PyCfg_hasParameter ( PyObject * module , PyObject * args )
+{ return callFunction ( "hasParameter" , & hasParameter , args ); }
+
+static PyMethodDef PyCfg_Methods [] =
+ { { "hasParameter" , ( PyCFunction ) PyCfg_hasParameter , METH_VARARGS
+ , "Tells if a parameter exists already in the DB." }
+ // ...
+ , { NULL , NULL , 0 , NULL } /* sentinel */
+ };
+
+
+
+
+
By defining specialization of the pyTypePostModuleinit<>() function template,
+you can add any post-treatment to a Python type object. Like adding sub-classes
+or constants values.
+
In the following code, we add Priority as a sub-object of Parameter then
+set some constant values in Priority . This was we emulate the behavior of
+the Priority enum .
+
template <>
+inline void pyTypePostModuleInit < Cfg :: Parameter > ( PyTypeObject * typeObject )
+{
+ PyTypeManagerNonDBo < Cfg :: Parameter :: Priority >:: create ( ( PyObject * ) typeObject
+ , Cfg :: PyParameterPriority_Methods
+ , NULL
+ , PyTypeManager :: NoCppDelete );
+}
+
+template <>
+inline void pyTypePostModuleInit < Cfg :: Parameter :: Priority > ( PyTypeObject * typeObject )
+{
+// Parameter::Priority enum.
+ addConstant ( typeObject , "UseDefault" , Cfg :: Parameter :: UseDefault );
+ addConstant ( typeObject , "ApplicationBuiltin" , Cfg :: Parameter :: ApplicationBuiltin );
+ addConstant ( typeObject , "ConfigurationFile" , Cfg :: Parameter :: ConfigurationFile );
+ addConstant ( typeObject , "UserFile" , Cfg :: Parameter :: UserFile );
+ addConstant ( typeObject , "CommandLine" , Cfg :: Parameter :: CommandLine );
+ addConstant ( typeObject , "Interactive" , Cfg :: Parameter :: Interactive );
+}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/documentation/output/pdfs/CheckToolkit.pdf b/documentation/output/pdfs/CheckToolkit.pdf
index c7add24c6205351732d5b2333c02ead9c169dff6..46216962f5045c726c76807ebd9f5e5a5a99a344 100644
GIT binary patch
delta 39256
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
D{I#HF
delta 39070
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