Merge branch 'pymod' into net-extract

This commit is contained in:
Matthias Koefferlein 2018-10-09 23:43:58 +02:00
commit 3392c08d36
59 changed files with 1051 additions and 446 deletions

View File

@ -43,6 +43,16 @@ matrix:
- PIP_UPDATE="1"
- PYTHON_BUILD=true
- BREW_BUNDLE=true
- name: "klayout python3.6.5_1 osx10.13"
os: osx
osx_image: xcode9.4 # macOS 10.13
env:
- MATRIX_EVAL="brew update; brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/f2a764ef944b1080be64bd88dca9a1d80130c558/Formula/python.rb; brew switch python 3.6.5_1; shopt -s expand_aliases; alias python='python3'; alias pip='pip3';"
- ARCHFLAGS="-std=c++11"
- PIP_UPDATE="1"
- PYTHON_BUILD=true
- BREW_BUNDLE=false
- name: "klayout python3 osx10.12"
os: osx
@ -58,11 +68,11 @@ matrix:
os: osx
osx_image: xcode8 # macOS 10.11
env:
- MATRIX_EVAL="shopt -s expand_aliases; alias python='python3'; alias pip='pip3';"
- MATRIX_EVAL="brew update; brew config; brew upgrade python;"
- ARCHFLAGS="-std=c++11"
- PIP_UPDATE="1"
- PYTHON_BUILD=true
- BREW_BUNDLE=true
- BREW_BUNDLE=false
- name: "klayout python3.6 package"
os: linux

View File

@ -2,6 +2,12 @@
GITCOMMIT := $(shell git rev-parse --short HEAD)
KLAYOUT_VERSION := $(shell source version.sh && echo $$KLAYOUT_VERSION)
ifndef PYTHON_VERSION
PYTHON_VERSION := B37
endif
ifndef MACOS_VERSION
MACOS_VERSION := HighSierra
endif
.ONESHELL:
@ -31,6 +37,7 @@ test:
ln -s klayout.app/Contents/MacOS/klayout klayout; \
export TESTTMP=testtmp; \
export TESTSRC=..; \
export DYLD_LIBRARY_PATH=.:db_plugins/:lay_plugins/; \
./ut_runner -h || true; \
cd ..

View File

@ -31,7 +31,7 @@ Also by default, supported script languages, i.e, Ruby and Python, are those sta
You may want to use a non-OS-standard script language such as Python 3.6 from Anaconda2 (https://www.anaconda.com/download/#macos) in combination with KLayout.
Since Anaconda2 is a popular Python development environment, this is worth trying. Unfortunately, however, some dynamic linkage problems are observed as of today.
On the other hand, Python 3.6 provided by MacPorts or Homebrew is usable.
On the other hand, Python 3.7 provided by MacPorts or Homebrew is usable.
Please try this (refer to 3B below or Section #5) if you feel it's useful.
# 3. Use-cases
@ -90,20 +90,20 @@ $ ./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m
# 5. Alternative building options
### 5.1 Python 3.6 from Homebrew, Qt 5.10.1 from Homebrew
### 5.1 Python 3.7 from Homebrew, Qt 5.10.1 from Homebrew
Homebrew's installation of python3 (`brew install python3`) places a `Python.framework` in `/usr/local/opt/python/Frameworks/Python.framework/`, which you can use to build KLayout from. Qt can also be downloaded from brew with `brew install qt`.
```
# Build step
./build4mac.py -p B36 -q Qt5Brew
./build4mac.py -p B37 -q Qt5Brew
# build with log
./build4mac.py -p B36 -q Qt5Brew 2>&1 | tee qt5.build.macos-HighSierra-release-version.log
./build4mac.py -p B37 -q Qt5Brew 2>&1 | tee qt5.build.macos-HighSierra-release-version.log
# Deploy step
./build4mac.py -p B36 -q Qt5Brew -y # normal deploy
./build4mac.py -p B36 -q Qt5Brew -y -v 3 2>&1 | tee qt5.pkg.macos-HighSierra-release.log # deploy with debug options
./build4mac.py -p B37 -q Qt5Brew -y # normal deploy
./build4mac.py -p B37 -q Qt5Brew -y -v 3 2>&1 | tee qt5.pkg.macos-HighSierra-release.log # deploy with debug options
# Packaging step
./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m -q Qt5101

Binary file not shown.

View File

@ -67,7 +67,7 @@ def SetGlobals():
Usage += " : Refer to 'macbuild/build4mac_env.py' for details | \n"
Usage += " [-q|--qt <type>] : type=['Qt4MacPorts', 'Qt5MacPorts', 'Qt5Brew'] | qt5macports \n"
Usage += " [-r|--ruby <type>] : type=['nil', 'Sys', 'Src24', 'MP24', 'B25'] | sys \n"
Usage += " [-p|--python <type>] : type=['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B36'] | sys \n"
Usage += " [-p|--python <type>] : type=['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B37'] | sys \n"
Usage += " [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled \n"
Usage += " [-m|--make <option>] : option passed to 'make' | -j4 \n"
Usage += " [-d|--debug] : enable debug mode build | disabled \n"
@ -175,7 +175,7 @@ def ParseCommandLineArguments():
p.add_option( '-p', '--python',
dest='type_python',
help="Python type=['nil', 'Sys', 'Ana27', 'Ana36', 'MP36']" )
help="Python type=['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B37']" )
p.add_option( '-n', '--noqtbinding',
action='store_true',
@ -294,7 +294,7 @@ def ParseCommandLineArguments():
exit()
# Determine Python type
candidates = [ i.upper() for i in ['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B36'] ]
candidates = [ i.upper() for i in ['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B37'] ]
ModulePython = ""
index = 0
for item in candidates:
@ -324,7 +324,7 @@ def ParseCommandLineArguments():
ModulePython = 'Python36MacPorts'
NonOSStdLang = True
elif index == 5:
ModulePython = 'Python36Brew'
ModulePython = 'Python37Brew'
NonOSStdLang = True
else:
index += 1
@ -581,6 +581,10 @@ def DeployBinariesForBundle():
# | +-- '*.dylib'
# +-- MacOS/+
# | +-- 'klayout'
# | +-- 'db_plugins'/+
# | +-- '*.dylib'
# | +-- 'lay_plugins'/+
# | +-- '*.dylib'
# +-- Buddy/+
# +-- 'strm2cif'
# +-- 'strm2dxf'
@ -631,8 +635,9 @@ def DeployBinariesForBundle():
# :
#-------------------------------------------------------------------------------
os.chdir( targetDirF )
dynamicLinkLibs = glob.glob( AbsMacBinDir + "/*.dylib" )
dynamicLinkLibs = glob.glob( os.path.join( AbsMacBinDir, "*.dylib" ) )
depDicOrdinary = {} # inter-library dependency dictionary
pathDic = {} # paths to insert for each library
for item in dynamicLinkLibs:
if os.path.isfile(item) and not os.path.islink(item):
#-------------------------------------------------------------------
@ -646,13 +651,54 @@ def DeployBinariesForBundle():
os.chmod( nameStyle3, 0o0755 )
#-------------------------------------------------------------------
# (B) Then get inter-library dependencies
# Note that will pull all dependencies and sort them out later
# dropping those which don't have a path entry
#-------------------------------------------------------------------
otoolCm = "otool -L %s | grep libklayout" % nameStyle3
otoolCm = "otool -L %s | grep dylib" % nameStyle3
otoolOut = os.popen( otoolCm ).read()
dependDic = DecomposeLibraryDependency(otoolOut)
depDicOrdinary.update(dependDic)
#-------------------------------------------------------------------
# (C) This library goes into Frameworks, hence record it's path there
#-------------------------------------------------------------------
pathDic[nameStyle3] = "@executable_path/../Frameworks/" + nameStyle3
os.chdir(ProjectDir)
#-------------------------------------------------------------------
# copy the contents of the plugin directories to a place next to the application
# binary
#-------------------------------------------------------------------
for piDir in [ "db_plugins", "lay_plugins" ]:
os.makedirs( os.path.join( targetDirM, piDir ))
dynamicLinkLibs = glob.glob( os.path.join( MacBinDir, piDir, "*.dylib" ) )
for item in dynamicLinkLibs:
if os.path.isfile(item) and not os.path.islink(item):
#-------------------------------------------------------------------
# (A) Copy an ordinary *.dylib file here by changing the name
# to style (3) and set its mode to 0755 (sanity check).
#-------------------------------------------------------------------
fullName = os.path.basename(item).split('.')
# e.g. [ 'libklayout_lay', '0', '25', '0', 'dylib' ]
nameStyle3 = fullName[0] + "." + fullName[1] + ".dylib"
destPath = os.path.join( targetDirM, piDir, nameStyle3 )
shutil.copy2( item, destPath )
os.chmod( destPath, 0o0755 )
#-------------------------------------------------------------------
# (B) Then get inter-library dependencies
# Note that will pull all dependencies and sort them out later
# dropping those which don't have a path entry
#-------------------------------------------------------------------
otoolCm = "otool -L %s | grep 'dylib'" % destPath
otoolOut = os.popen( otoolCm ).read()
dependDic = DecomposeLibraryDependency(otoolOut)
depDicOrdinary.update(dependDic)
#-------------------------------------------------------------------
# (C) This library goes into the plugin dir
#-------------------------------------------------------------------
pathDic[nameStyle3] = "@executable_path/" + piDir + "/" + nameStyle3
'''
PrintLibraryDependencyDictionary( depDicOrdinary, "Style (3)" )
PrintLibraryDependencyDictionary( depDicOrdinary, pathDic, "Style (3)" )
exit()
'''
@ -662,7 +708,8 @@ def DeployBinariesForBundle():
# and make the library aware of the locations of libraries
# on which it depends; that is, inter-library dependency
#-------------------------------------------------------------
ret = SetChangeIdentificationNameOfDyLib( depDicOrdinary )
os.chdir( targetDirF )
ret = SetChangeIdentificationNameOfDyLib( depDicOrdinary, pathDic )
if not ret == 0:
msg = "!!! Failed to set and change to new identification names !!!"
print(msg)
@ -691,7 +738,6 @@ def DeployBinariesForBundle():
shutil.copy2( sourceDir1 + "/klayout", targetDirM )
shutil.copy2( sourceDir2 + "/klayout.icns", targetDirR )
os.chmod( targetDir0 + "/PkgInfo", 0o0644 )
os.chmod( targetDir0 + "/Info.plist", 0o0644 )
os.chmod( targetDirM + "/klayout", 0o0755 )
@ -765,12 +811,12 @@ def DeployBinariesForBundle():
deploymentPython = True
if deploymentPython and NonOSStdLang:
from build4mac_util import WalkFrameworkPaths, PerformChanges, DetectChanges
from build4mac_util import WalkFrameworkPaths, PerformChanges
bundlePath = AbsMacPkgDir + '/klayout.app'
# bundlePath = os.getcwd() + '/qt5.pkg.macos-HighSierra-release/klayout.app'
bundleExecPathAbs = '%s/Contents/MacOS/' % bundlePath
pythonOriginalFrameworkPath = '/usr/local/opt/python3/Frameworks/Python.framework'
pythonOriginalFrameworkPath = '/usr/local/opt/python/Frameworks/Python.framework'
pythonFrameworkPath = '%s/Contents/Frameworks/Python.framework' % bundlePath
print(" [8.1] Deploying Python from %s ..." % pythonOriginalFrameworkPath)
@ -1012,8 +1058,6 @@ def main():
if not ret2 == 0:
sys.exit(1)
else:
sys.exit(0)
#===================================================================================
if __name__ == "__main__":

View File

@ -126,7 +126,7 @@ RubyDictionary = { 'nil' : None,
# [3] Python
#-----------------------------------------------------
Pythons = [ 'nil', 'PythonYosemite', 'PythonElCapitan', 'PythonSierra', 'PythonHighSierra' ]
Pythons += [ 'Anaconda27', 'Anaconda36', 'Python36MacPorts', 'Python36Brew' ]
Pythons += [ 'Anaconda27', 'Anaconda36', 'Python36MacPorts', 'Python37Brew' ]
#-----------------------------------------------------
# Whereabout of different components of Python
@ -188,11 +188,11 @@ Python36MacPorts= { 'exe': '/opt/local/Library/Frameworks/Python.framework/Versi
'lib': '/opt/local/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6m.dylib'
}
# Python 3.6 from Brew *+*+*+ EXPERIMENTAL *+*+*+
# Python 3.7 from Brew *+*+*+ EXPERIMENTAL *+*+*+
# [Key Type Name] = 'pybrew'
Python36Brew= { 'exe': '/usr/local/opt/python/libexec/bin/python' ,
'inc': '/usr/local/opt/python3/Frameworks/Python.framework/Versions/3.6/Headers',
'lib': '/usr/local/opt/python3/Frameworks/Python.framework/Versions/3.6/Python'
Python37Brew= { 'exe': '/usr/local/opt/python/libexec/bin/python' ,
'inc': '/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/Headers',
'lib': '/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/Python'
}
# Consolidated dictionary kit for Python
@ -204,7 +204,7 @@ PythonDictionary= { 'nil' : None,
'Anaconda27' : Anaconda27,
'Anaconda36' : Anaconda36,
'Python36MacPorts': Python36MacPorts,
'Python36Brew' : Python36Brew,
'Python37Brew' : Python37Brew,
}
#-----------------------------------------------------

View File

@ -59,15 +59,18 @@ def DecomposeLibraryDependency( depstr ):
# @param[in] depdic dictionary
# @param[in] namedic dictionary name
#------------------------------------------------------------------------------
def PrintLibraryDependencyDictionary( depdic, namedic ):
def PrintLibraryDependencyDictionary( depdic, pathdic, namedic ):
keys = depdic.keys()
print("")
print("##### Contents of <%s> #####:" % namedic )
for key in keys:
supporters = depdic[key]
print( " %s:" % key )
keyName = os.path.basename(key)
print( " %s: (%s)" % (key, pathdic[keyName]) )
for item in supporters:
print( " %s" % item )
itemName = os.path.basename(item)
if itemName != keyName and (itemName in pathdic):
print( " %s (%s)" % (item, pathdic[itemName]) )
#------------------------------------------------------------------------------
## To set and change identification name of KLayout's dylib
@ -76,7 +79,7 @@ def PrintLibraryDependencyDictionary( depdic, namedic ):
#
# @return 0 on success; non-zero on failure
#------------------------------------------------------------------------------
def SetChangeIdentificationNameOfDyLib( libdic ):
def SetChangeIdentificationNameOfDyLib( libdic, pathDic ):
cmdNameId = XcodeToolChain['nameID']
cmdNameChg = XcodeToolChain['nameCH']
dependentLibs = libdic.keys()
@ -86,7 +89,8 @@ def SetChangeIdentificationNameOfDyLib( libdic ):
# [1] Set the identification name of each dependent library
#-----------------------------------------------------------
nameOld = "%s" % lib
nameNew = "@executable_path/../Frameworks/%s" % lib
libName = os.path.basename(lib)
nameNew = pathDic[libName]
command = "%s %s %s" % ( cmdNameId, nameNew, nameOld )
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to set the new identification name to <%s> !!!"
@ -98,13 +102,15 @@ def SetChangeIdentificationNameOfDyLib( libdic ):
#-------------------------------------------------------------------------
supporters = libdic[lib]
for sup in supporters:
nameOld = "%s" % sup
nameNew = "@executable_path/../Frameworks/%s" % sup
command = "%s %s %s %s" % ( cmdNameChg, nameOld, nameNew, lib )
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to make the library aware of the new identification name <%s> of supporter <%s> !!!"
print( msg % (nameNew, sup), file=sys.stderr )
return 1
supName = os.path.basename(sup)
if libName != supName and (supName in pathDic):
nameOld = "%s" % sup
nameNew = pathDic[supName]
command = "%s %s %s %s" % ( cmdNameChg, nameOld, nameNew, lib )
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to make the library aware of the new identification name <%s> of supporter <%s> !!!"
print( msg % (nameNew, sup), file=sys.stderr )
return 1
# for-lib
return 0

View File

@ -361,7 +361,7 @@ def MakeTargetDMGFile(msg=""):
# (4) Mount the DMG
#--------------------------------------------------------
print( ">>> (4) Mounting <%s> to <%s>" % (WorkDMG, MountDir ) )
command1 = "hdiutil attach %s -readwrite -noverify -noautoopen -quiet" % WorkDMG
command1 = "hdiutil attach %s -readwrite -noverify -quiet -noautoopen" % WorkDMG
os.system(command1)
command2 = "hdiutil info | grep %s | grep \"/dev/\" | awk '{print $1}'" % VolumeDMG

View File

@ -191,7 +191,8 @@ class Config(object):
"""
Gets the version string
"""
return "0.26"
return "0.26.0.dev1"
config = Config()
@ -345,11 +346,14 @@ rdb = Extension(config.root + '.rdb',
# Core setup function
if __name__ == '__main__':
setup(name = config.root,
version = config.version(),
description = 'KLayout standalone Python package',
author = 'Matthias Koefferlein',
author_email = 'matthias@klayout.de',
packages = [config.root],
package_dir = {config.root: 'src/pymod/distutils_src'},
ext_modules = [_tl, _gsi, _pya, _db, _rdb] + db_plugins + [tl, db, rdb])
setup(name=config.root,
version=config.version(),
license='GNU GPLv3',
description='KLayout standalone Python package',
long_description='TODO',
author='Matthias Koefferlein',
author_email='matthias@klayout.de',
url='https://github.com/klayoutmatthias/klayout',
packages=[config.root],
package_dir={config.root: 'src/pymod/distutils_src'},
ext_modules=[_tl, _gsi, _pya, _db, _rdb] + db_plugins + [tl, db, rdb])

View File

@ -35,16 +35,6 @@ INCLUDEPATH += $$TL_INC $$GSI_INC $$VERSION_INC $$DB_INC $$LIB_INC $$RDB_INC
DEPENDPATH += $$TL_INC $$GSI_INC $$VERSION_INC $$DB_INC $$LIB_INC $$RDB_INC
LIBS += -L$$DESTDIR -lklayout_tl -lklayout_db -lklayout_gsi -lklayout_lib -lklayout_rdb
PLUGINPATH += \
$$PWD/../../../plugins/common \
$$PWD/../../../plugins/streamers/gds2/db_plugin \
$$PWD/../../../plugins/streamers/cif/db_plugin \
$$PWD/../../../plugins/streamers/oasis/db_plugin \
$$PWD/../../../plugins/streamers/dxf/db_plugin \
INCLUDEPATH += $$PLUGINPATH
DEPENDPATH += $$PLUGINPATH
INCLUDEPATH += $$RBA_INC
DEPENDPATH += $$RBA_INC

View File

@ -28,7 +28,27 @@ namespace bd
{
GenericReaderOptions::GenericReaderOptions ()
: m_prefix ("i"), m_group_prefix ("Input"), m_create_other_layers (true)
: m_prefix ("i"), m_group_prefix ("Input"), m_create_other_layers (true),
m_common_enable_text_objects (true),
m_common_enable_properties (true),
m_gds2_box_mode (1),
m_gds2_allow_big_records (true),
m_gds2_allow_multi_xy_records (true),
m_oasis_read_all_properties (true),
m_oasis_expect_strict_mode (-1),
m_cif_wire_mode (0),
m_cif_dbu (0.001),
m_cif_keep_layer_names (false),
m_dxf_dbu (0.001),
m_dxf_unit (1.0),
m_dxf_text_scaling (100.0),
m_dxf_polyline_mode (0),
m_dxf_circle_points (100),
m_dxf_circle_accuracy (0.0),
m_dxf_contour_accuracy (0.0),
m_dxf_render_texts_as_polygons (false),
m_dxf_keep_layer_names (false),
m_dxf_keep_other_cells (false)
{
// .. nothing yet ..
}
@ -79,11 +99,11 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
std::string group ("[" + m_group_prefix + " options - GDS2 and OASIS specific]");
cmd << tl::arg (group +
"#!--" + m_long_prefix + "no-texts", &m_common_reader_options.enable_text_objects, "Skips text objects",
"#!--" + m_long_prefix + "no-texts", &m_common_enable_text_objects, "Skips text objects",
"With this option set, text objects won't be read."
)
<< tl::arg (group +
"#!--" + m_long_prefix + "no-properties", &m_common_reader_options.enable_properties, "Skips properties",
"#!--" + m_long_prefix + "no-properties", &m_common_enable_properties, "Skips properties",
"With this option set, properties won't be read."
)
;
@ -93,20 +113,20 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
std::string group ("[" + m_group_prefix + " options - GDS2 specific]");
cmd << tl::arg (group +
"#!--" + m_long_prefix + "no-multi-xy-records", &m_gds2_reader_options.allow_multi_xy_records, "Gives an error on multi-XY records",
"#!--" + m_long_prefix + "no-multi-xy-records", &m_gds2_allow_multi_xy_records, "Gives an error on multi-XY records",
"This option disables an advanced interpretation of GDS2 which allows unlimited polygon and path "
"complexity. For compatibility with other readers, this option restores the standard behavior and "
"disables this feature."
)
<< tl::arg (group +
"#!--" + m_long_prefix + "no-big-records", &m_gds2_reader_options.allow_big_records, "Gives an error on big (>32767 bytes) records",
"#!--" + m_long_prefix + "no-big-records", &m_gds2_allow_big_records, "Gives an error on big (>32767 bytes) records",
"The GDS2 specification claims the record length to be a signed 16 bit value. So a record "
"can be 32767 bytes max. To allow bigger records (i.e. bigger polygons), the usual approach "
"is to take the length as a unsigned 16 bit value, so the length is up to 65535 bytes. "
"This option restores the original behavior and reports big (>32767 bytes) records are errors."
)
<< tl::arg (group +
"-" + m_prefix + "b|--" + m_long_prefix + "box-mode=mode", &m_gds2_reader_options.box_mode, "Specifies how BOX records are read",
"-" + m_prefix + "b|--" + m_long_prefix + "box-mode=mode", &m_gds2_box_mode, "Specifies how BOX records are read",
"This an option provided for compatibility with other readers. The mode value specifies how "
"BOX records are read:\n"
"\n"
@ -122,7 +142,7 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
std::string group ("[" + m_group_prefix + " options - OASIS specific]");
cmd << tl::arg (group +
"#--" + m_long_prefix + "expect-strict-mode=mode", &m_oasis_reader_options.expect_strict_mode, "Makes the reader expect strict or non-strict mode",
"#--" + m_long_prefix + "expect-strict-mode=mode", &m_oasis_expect_strict_mode, "Makes the reader expect strict or non-strict mode",
"With this option, the OASIS reader will expect strict mode (mode is 1) or expect non-strict mode "
"(mode is 0). By default, both modes are allowed. This is a diagnostic feature and does not "
"have any other effect than checking the mode."
@ -150,7 +170,7 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
std::string group ("[" + m_group_prefix + " options - CIF specific]");
cmd << tl::arg (group +
"-" + m_prefix + "w|--" + m_long_prefix + "wire-mode=mode", &m_cif_reader_options.wire_mode, "Specifies how wires (W) are read",
"-" + m_prefix + "w|--" + m_long_prefix + "wire-mode=mode", &m_cif_wire_mode, "Specifies how wires (W) are read",
"This option specifies how wire objects (W) are read:\n"
"\n"
"* 0: as square ended paths (the default)\n"
@ -164,19 +184,19 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
std::string group ("[" + m_group_prefix + " options - DXF specific]");
cmd << tl::arg (group +
"-" + m_prefix + "u|--" + m_long_prefix + "dxf-unit=unit", &m_dxf_reader_options.unit, "Specifies the DXF drawing units",
"-" + m_prefix + "u|--" + m_long_prefix + "dxf-unit=unit", &m_dxf_unit, "Specifies the DXF drawing units",
"Since DXF is unitless, this value needs to be given to specify the drawing units. "
"By default, a drawing unit of micrometers is assumed."
)
<< tl::arg (group +
"#--" + m_long_prefix + "dxf-text-scaling=factor", &m_dxf_reader_options.text_scaling, "Specifies text scaling",
"#--" + m_long_prefix + "dxf-text-scaling=factor", &m_dxf_text_scaling, "Specifies text scaling",
"This value specifies text scaling in percent. A value of 100 roughly means that the letter "
"pitch of the font will be 92% of the specified text height. That value applies for ROMANS fonts. "
"When generating GDS texts, a value of 100 generates TEXT objects with "
"the specified size. Smaller values generate smaller sizes."
)
<< tl::arg (group +
"#--" + m_long_prefix + "dxf-polyline-mode=mode", &m_dxf_reader_options.polyline_mode, "Specifies how POLYLINE records are handled",
"#--" + m_long_prefix + "dxf-polyline-mode=mode", &m_dxf_polyline_mode, "Specifies how POLYLINE records are handled",
"This value specifies how POLYLINE records are handled:\n"
"\n"
"* 0: automatic mode (default)\n"
@ -186,11 +206,11 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
"* 4: as 3 and auto-close contours"
)
<< tl::arg (group +
"#--" + m_long_prefix + "dxf-circle-points=points", &m_dxf_reader_options.circle_points, "Specifies the number of points for a full circle for arc interpolation",
"#--" + m_long_prefix + "dxf-circle-points=points", &m_dxf_circle_points, "Specifies the number of points for a full circle for arc interpolation",
"See --" + m_long_prefix + "dxf-circle-accuracy for another way of specifying the number of points per circle."
)
<< tl::arg (group +
"#--" + m_long_prefix + "dxf-circle-accuracy=value", &m_dxf_reader_options.circle_accuracy, "Specifies the accuracy of circle approximation",
"#--" + m_long_prefix + "dxf-circle-accuracy=value", &m_dxf_circle_accuracy, "Specifies the accuracy of circle approximation",
"This value specifies the approximation accuracy of the circle and other\n"
"\"round\" structures. If this value is a positive number bigger than the\n"
"database unit (see dbu), it will control the number of points the\n"
@ -203,16 +223,16 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
"The value is given in the units of the DXF file."
)
<< tl::arg (group +
"#--" + m_long_prefix + "dxf-contour-accuracy=value", &m_dxf_reader_options.contour_accuracy, "Specifies the point accuracy for contour closing",
"#--" + m_long_prefix + "dxf-contour-accuracy=value", &m_dxf_contour_accuracy, "Specifies the point accuracy for contour closing",
"This value specifies the distance (in units of the DXF file) by which points can be separated and still\n"
"be considered to be connected. This value is effective in polyline mode 3 and 4.\n"
)
<< tl::arg (group +
"#--" + m_long_prefix + "dxf-render-texts-as-polygons", &m_dxf_reader_options.render_texts_as_polygons, "Renders texts as polygons",
"#--" + m_long_prefix + "dxf-render-texts-as-polygons", &m_dxf_render_texts_as_polygons, "Renders texts as polygons",
"If this option is used, texts are converted to polygons instead of being converted to labels."
)
<< tl::arg (group +
"#--" + m_long_prefix + "dxf-keep-other-cells", &m_dxf_reader_options.keep_other_cells, "Keeps cells which are not instantiated by the top cell",
"#--" + m_long_prefix + "dxf-keep-other-cells", &m_dxf_keep_other_cells, "Keeps cells which are not instantiated by the top cell",
"With this option, all cells not found to be instantiated are kept as additional top cells. "
"By default, such cells are removed."
)
@ -234,36 +254,49 @@ void GenericReaderOptions::set_layer_map (const std::string &lm)
void GenericReaderOptions::set_read_named_layers (bool f)
{
m_dxf_reader_options.keep_layer_names = f;
m_cif_reader_options.keep_layer_names = f;
m_dxf_keep_layer_names = f;
m_cif_keep_layer_names = f;
}
void GenericReaderOptions::set_dbu (double dbu)
{
m_dxf_reader_options.dbu = dbu;
m_cif_reader_options.dbu = dbu;
m_dxf_dbu = dbu;
m_cif_dbu = dbu;
}
void
GenericReaderOptions::configure (db::LoadLayoutOptions &load_options) const
{
db::CommonReaderOptions common_reader_options = m_common_reader_options;
common_reader_options.layer_map = m_layer_map;
common_reader_options.create_other_layers = m_create_other_layers;
load_options.set_option_by_name ("layer_map", tl::Variant::make_variant (m_layer_map));
load_options.set_option_by_name ("create_other_layers", m_create_other_layers);
load_options.set_option_by_name ("text_enabled", m_common_enable_text_objects);
load_options.set_option_by_name ("properties_enabled", m_common_enable_properties);
db::DXFReaderOptions dxf_reader_options = m_dxf_reader_options;
dxf_reader_options.layer_map = m_layer_map;
dxf_reader_options.create_other_layers = m_create_other_layers;
load_options.set_option_by_name ("gds2_box_mode", m_gds2_box_mode);
load_options.set_option_by_name ("gds2_allow_big_records", m_gds2_allow_big_records);
load_options.set_option_by_name ("gds2_allow_multi_xy_records", m_gds2_allow_multi_xy_records);
db::CIFReaderOptions cif_reader_options = m_cif_reader_options;
cif_reader_options.layer_map = m_layer_map;
cif_reader_options.create_other_layers = m_create_other_layers;
load_options.set_option_by_name ("oasis_read_all_properties", m_oasis_read_all_properties);
load_options.set_option_by_name ("oasis_expect_strict_mode", m_oasis_expect_strict_mode);
load_options.set_options (common_reader_options);
load_options.set_options (m_gds2_reader_options);
load_options.set_options (m_oasis_reader_options);
load_options.set_options (cif_reader_options);
load_options.set_options (dxf_reader_options);
load_options.set_option_by_name ("cif_layer_map", tl::Variant::make_variant (m_layer_map));
load_options.set_option_by_name ("cif_create_other_layers", m_create_other_layers);
load_options.set_option_by_name ("cif_dbu", m_dxf_dbu);
load_options.set_option_by_name ("cif_wire_mode", m_cif_wire_mode);
load_options.set_option_by_name ("cif_keep_layer_names", m_cif_keep_layer_names);
load_options.set_option_by_name ("dxf_layer_map", tl::Variant::make_variant (m_layer_map));
load_options.set_option_by_name ("dxf_create_other_layers", m_create_other_layers);
load_options.set_option_by_name ("dxf_dbu", m_dxf_dbu);
load_options.set_option_by_name ("dxf_unit", m_dxf_unit);
load_options.set_option_by_name ("dxf_text_scaling", m_dxf_text_scaling);
load_options.set_option_by_name ("dxf_polyline_mode", m_dxf_polyline_mode);
load_options.set_option_by_name ("dxf_circle_points", m_dxf_circle_points);
load_options.set_option_by_name ("dxf_circle_accuracy", m_dxf_circle_accuracy);
load_options.set_option_by_name ("dxf_contour_accuracy", m_dxf_contour_accuracy);
load_options.set_option_by_name ("dxf_render_texts_as_polygons", m_dxf_render_texts_as_polygons);
load_options.set_option_by_name ("dxf_keep_layer_names", m_dxf_keep_layer_names);
load_options.set_option_by_name ("dxf_keep_other_cells", m_dxf_keep_other_cells);
}
}

View File

@ -25,10 +25,6 @@
#include "bdCommon.h"
#include "dbCommonReader.h"
#include "dbGDS2Format.h"
#include "dbOASISFormat.h"
#include "dbDXFFormat.h"
#include "dbCIFFormat.h"
#include <string>
@ -99,13 +95,40 @@ public:
private:
std::string m_prefix, m_long_prefix, m_group_prefix;
// generic
db::LayerMap m_layer_map;
bool m_create_other_layers;
db::CommonReaderOptions m_common_reader_options;
db::GDS2ReaderOptions m_gds2_reader_options;
db::OASISReaderOptions m_oasis_reader_options;
db::CIFReaderOptions m_cif_reader_options;
db::DXFReaderOptions m_dxf_reader_options;
// common GDS2+OASIS
bool m_common_enable_text_objects;
bool m_common_enable_properties;
// GDS2
unsigned int m_gds2_box_mode;
bool m_gds2_allow_big_records;
bool m_gds2_allow_multi_xy_records;
// OASIS
bool m_oasis_read_all_properties;
int m_oasis_expect_strict_mode;
// CIF
unsigned int m_cif_wire_mode;
double m_cif_dbu;
bool m_cif_keep_layer_names;
// DXF
double m_dxf_dbu;
double m_dxf_unit;
double m_dxf_text_scaling;
int m_dxf_polyline_mode;
int m_dxf_circle_points;
double m_dxf_circle_accuracy;
double m_dxf_contour_accuracy;
bool m_dxf_render_texts_as_polygons;
bool m_dxf_keep_layer_names;
bool m_dxf_keep_other_cells;
void set_layer_map (const std::string &lm);
void set_dbu (double dbu);

View File

@ -30,21 +30,43 @@ namespace bd
{
GenericWriterOptions::GenericWriterOptions ()
: m_scale_factor (1.0), m_dbu (0.0),
m_dont_write_empty_cells (false), m_keep_instances (false), m_write_context_info (true)
: m_scale_factor (1.0),
m_dbu (0.0),
m_dont_write_empty_cells (false),
m_keep_instances (false),
m_write_context_info (true),
m_gds2_max_vertex_count (8000),
m_gds2_no_zero_length_paths (false),
m_gds2_multi_xy_records (false),
m_gds2_max_cellname_length (32000),
m_gds2_libname ("LIB"),
m_gds2_user_units (1.0),
m_gds2_write_timestamps (true),
m_gds2_write_cell_properties (false),
m_gds2_write_file_properties (false),
m_oasis_compression_level (2),
m_oasis_write_cblocks (false),
m_oasis_strict_mode (false),
m_oasis_recompress (false),
m_oasis_permissive (false),
m_oasis_write_std_properties (1),
m_oasis_subst_char ("*"),
m_cif_dummy_calls (false),
m_cif_blank_separator (false),
m_dxf_polygon_mode (0)
{
// .. nothing yet ..
}
const std::string GenericWriterOptions::gds2_format_name = "GDS2";
const std::string GenericWriterOptions::gds2text_format_name = "GDS2Text"; // no special options
const std::string GenericWriterOptions::oasis_format_name = "OASIS";
const std::string GenericWriterOptions::dxf_format_name = "DXF";
const std::string GenericWriterOptions::cif_format_name = "CIF";
void
GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::string &format)
{
const std::string gds2_format_name = m_gds2_writer_options.format_name ();
const std::string gds2text_format_name = gds2_format_name + "Text"; // no special options
const std::string oasis_format_name = m_oasis_writer_options.format_name ();
const std::string dxf_format_name = m_dxf_writer_options.format_name ();
const std::string cif_format_name = m_cif_writer_options.format_name ();
std::string group ("[Output options - General]");
cmd << tl::arg (group +
@ -116,47 +138,47 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
std::string group = "[Output options - GDS2 specific]";
cmd << tl::arg (group +
"-ov|--max-vertex-count=count", &m_gds2_writer_options.max_vertex_count, "Specifies the maximum number of points per polygon",
"-ov|--max-vertex-count=count", &m_gds2_max_vertex_count, "Specifies the maximum number of points per polygon",
"If this number is given, polygons are cut into smaller parts if they have more "
"than the specified number of points. If not given, the maximum number of points will be used. "
"This is 8190 unless --multi-xy-records is given."
)
<< tl::arg (group +
"#--multi-xy-records", &m_gds2_writer_options.multi_xy_records, "Allows unlimited number of points",
"#--multi-xy-records", &m_gds2_multi_xy_records, "Allows unlimited number of points",
"If this option is given, multiple XY records will be written to accomodate an unlimited number "
"of points per polygon or path. However, such files may not be compatible with some consumers."
)
<< tl::arg (group +
"#--no-zero-length-paths", &m_gds2_writer_options.no_zero_length_paths, "Converts zero-length paths to polygons",
"#--no-zero-length-paths", &m_gds2_no_zero_length_paths, "Converts zero-length paths to polygons",
"If this option is given, zero-length paths (such with one point) are not written as paths "
"but converted to polygons. This avoids compatibility issues with consumers of this layout file."
)
<< tl::arg (group +
"-on|--cellname-length=length", &m_gds2_writer_options.max_cellname_length, "Limits cell names to the given length",
"-on|--cellname-length=length", &m_gds2_max_cellname_length, "Limits cell names to the given length",
"If this option is given, long cell names will truncated if their length exceeds the given length."
)
<< tl::arg (group +
"-ol|--libname=libname", &m_gds2_writer_options.libname, "Uses the given library name",
"-ol|--libname=libname", &m_gds2_libname, "Uses the given library name",
"This option can specify the GDS2 LIBNAME for the output file. By default, the original LIBNAME is "
"written."
)
<< tl::arg (group +
"#--user-units=unit", &m_gds2_writer_options.user_units, "Specifies the user unit to use",
"#--user-units=unit", &m_gds2_user_units, "Specifies the user unit to use",
"Specifies the GDS2 user unit. By default micrometers are used for the user unit."
)
<< tl::arg (group +
"#!--no-timestamps", &m_gds2_writer_options.write_timestamps, "Don't write timestamps",
"#!--no-timestamps", &m_gds2_write_timestamps, "Don't write timestamps",
"Writes a dummy time stamp instead of the actual time. With this option, GDS2 files become "
"bytewise indentical even if written at different times. This option is useful if binary "
"identity is important (i.e. in regression scenarios)."
)
<< tl::arg (group +
"#--write-cell-properties", &m_gds2_writer_options.write_cell_properties, "Write cell properties",
"#--write-cell-properties", &m_gds2_write_cell_properties, "Write cell properties",
"This option enables a GDS2 extension that allows writing of cell properties to GDS2 files. "
"Consumers that don't support this feature, may not be able to read such a GDS2 files."
)
<< tl::arg (group +
"#--write-file-properties", &m_gds2_writer_options.write_file_properties, "Write file properties",
"#--write-file-properties", &m_gds2_write_file_properties, "Write file properties",
"This option enables a GDS2 extension that allows writing of file properties to GDS2 files. "
"Consumers that don't support this feature, may not be able to read such a GDS2 files."
)
@ -170,7 +192,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
std::string group = "[Output options - OASIS specific]";
cmd << tl::arg (group +
"-ok|--compression-level=level", &m_oasis_writer_options.compression_level, "Specifies the OASIS compression level",
"-ok|--compression-level=level", &m_oasis_compression_level, "Specifies the OASIS compression level",
"This level describes how hard the OASIS writer will try to compress the shapes "
"using shape arrays. Building shape arrays may take some time and requires some memory. "
"The default compression level is 2.\n"
@ -179,23 +201,23 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
"* 2++ - enhanced shape array search algorithm using 2nd and further neighbor distances as well\n"
)
<< tl::arg (group +
"-ob|--cblocks", &m_oasis_writer_options.write_cblocks, "Uses CBLOCK compression"
"-ob|--cblocks", &m_oasis_write_cblocks, "Uses CBLOCK compression"
)
<< tl::arg (group +
"-ot|--strict-mode", &m_oasis_writer_options.strict_mode, "Uses strict mode"
"-ot|--strict-mode", &m_oasis_strict_mode, "Uses strict mode"
)
<< tl::arg (group +
"#--recompress", &m_oasis_writer_options.recompress, "Compresses shape arrays again",
"#--recompress", &m_oasis_recompress, "Compresses shape arrays again",
"With this option, shape arrays will be expanded and recompressed. This may result in a better "
"compression ratio, but at the cost of slower execution."
)
<< tl::arg (group +
"#--permissive", &m_oasis_writer_options.permissive, "Permissive mode",
"#--permissive", &m_oasis_permissive, "Permissive mode",
"In permissive mode, certain forbidden objects are reported as warnings, not as errors: "
"paths with odd width, polygons with less than three points etc."
)
<< tl::arg (group +
"#--write-std-properties", &m_oasis_writer_options.write_std_properties, "Writes some global standard properties",
"#--write-std-properties", &m_oasis_write_std_properties, "Writes some global standard properties",
"This is an integer describing what standard properties shall be written. 0 is \"none\", "
"1 means \"global standard properties such as S_TOP_CELL\" are produced (the default). With 2 also per-cell bounding "
"boxes are produced."
@ -215,7 +237,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
std::string group = "[Output options - DXF specific]";
cmd << tl::arg (group +
"-op|--polygon-mode=mode", &m_dxf_writer_options.polygon_mode, "Specifies how to write polygons",
"-op|--polygon-mode=mode", &m_dxf_polygon_mode, "Specifies how to write polygons",
"This option specifies how to write polygons:\n"
"* 0: create POLYLINE (default)\n"
"* 1: create LWPOLYLINE\n"
@ -232,11 +254,11 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
std::string group = "[Output options - CIF specific]";
cmd << tl::arg (group +
"#--dummy-calls", &m_cif_writer_options.dummy_calls, "Produces dummy calls",
"#--dummy-calls", &m_cif_dummy_calls, "Produces dummy calls",
"If this option is given, the writer will produce dummy cell calls on global level for all top cells"
)
<< tl::arg (group +
"#--blank-separator", &m_cif_writer_options.blank_separator, "Uses blanks as x/y separators",
"#--blank-separator", &m_cif_blank_separator, "Uses blanks as x/y separators",
"If this option is given, blank characters will be used to separate x and y values. "
"Otherwise comma characters will be used.\n"
"Use this option if your CIF consumer cannot read comma characters as x/y separators."
@ -249,7 +271,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
void GenericWriterOptions::set_oasis_substitution_char (const std::string &text)
{
if (! text.empty ()) {
m_oasis_writer_options.subst_char = text[0];
m_oasis_subst_char = text[0];
}
}
@ -306,10 +328,29 @@ GenericWriterOptions::configure (db::SaveLayoutOptions &save_options, const db::
save_options.set_keep_instances (m_keep_instances);
save_options.set_write_context_info (m_write_context_info);
save_options.set_options (m_gds2_writer_options);
save_options.set_options (m_oasis_writer_options);
save_options.set_options (m_dxf_writer_options);
save_options.set_options (m_cif_writer_options);
save_options.set_option_by_name ("gds2_max_vertex_count", m_gds2_max_vertex_count);
save_options.set_option_by_name ("gds2_no_zero_length_paths", m_gds2_no_zero_length_paths);
save_options.set_option_by_name ("gds2_multi_xy_records", m_gds2_multi_xy_records);
save_options.set_option_by_name ("gds2_max_cellname_length", m_gds2_max_cellname_length);
save_options.set_option_by_name ("gds2_libname", m_gds2_libname);
save_options.set_option_by_name ("gds2_user_units", m_gds2_user_units);
save_options.set_option_by_name ("gds2_write_timestamps", m_gds2_write_timestamps);
save_options.set_option_by_name ("gds2_write_cell_properties", m_gds2_write_cell_properties);
save_options.set_option_by_name ("gds2_write_file_properties", m_gds2_write_file_properties);
save_options.set_option_by_name ("oasis_compression_level", m_oasis_compression_level);
save_options.set_option_by_name ("oasis_write_cblocks", m_oasis_write_cblocks);
save_options.set_option_by_name ("oasis_strict_mode", m_oasis_strict_mode);
save_options.set_option_by_name ("oasis_recompress", m_oasis_recompress);
save_options.set_option_by_name ("oasis_permissive", m_oasis_permissive);
// Note: "..._ext" is a version taking the real value (not just a boolean)
save_options.set_option_by_name ("oasis_write_std_properties_ext", m_oasis_write_std_properties);
save_options.set_option_by_name ("oasis_substitution_char", m_oasis_subst_char);
save_options.set_option_by_name ("cif_dummy_calls", m_cif_dummy_calls);
save_options.set_option_by_name ("cif_blank_separator", m_cif_blank_separator);
save_options.set_option_by_name ("dxf_polygon_mode", m_dxf_polygon_mode);
if (!m_cell_selection.empty ()) {

View File

@ -24,10 +24,6 @@
#define HDR_bdWriterOptions
#include "bdCommon.h"
#include "dbGDS2Format.h"
#include "dbOASISFormat.h"
#include "dbDXFFormat.h"
#include "dbCIFFormat.h"
#include <string>
@ -69,7 +65,7 @@ public:
*/
void add_options_for_gds2 (tl::CommandLineOptions &cmd)
{
add_options (cmd, m_gds2_writer_options.format_name ());
add_options (cmd, gds2_format_name);
}
/**
@ -77,7 +73,7 @@ public:
*/
void add_options_for_oasis (tl::CommandLineOptions &cmd)
{
add_options (cmd, m_oasis_writer_options.format_name ());
add_options (cmd, oasis_format_name);
}
/**
@ -85,7 +81,7 @@ public:
*/
void add_options_for_cif (tl::CommandLineOptions &cmd)
{
add_options (cmd, m_cif_writer_options.format_name ());
add_options (cmd, cif_format_name);
}
/**
@ -93,7 +89,7 @@ public:
*/
void add_options_for_dxf (tl::CommandLineOptions &cmd)
{
add_options (cmd, m_dxf_writer_options.format_name ());
add_options (cmd, dxf_format_name);
}
/**
@ -102,6 +98,12 @@ public:
*/
void configure (db::SaveLayoutOptions &save_options, const db::Layout &layout) const;
static const std::string gds2_format_name;
static const std::string gds2text_format_name;
static const std::string oasis_format_name;
static const std::string cif_format_name;
static const std::string dxf_format_name;
private:
double m_scale_factor;
double m_dbu;
@ -109,10 +111,29 @@ private:
bool m_keep_instances;
bool m_write_context_info;
std::string m_cell_selection;
db::GDS2WriterOptions m_gds2_writer_options;
db::OASISWriterOptions m_oasis_writer_options;
db::CIFWriterOptions m_cif_writer_options;
db::DXFWriterOptions m_dxf_writer_options;
unsigned int m_gds2_max_vertex_count;
bool m_gds2_no_zero_length_paths;
bool m_gds2_multi_xy_records;
unsigned int m_gds2_max_cellname_length;
std::string m_gds2_libname;
double m_gds2_user_units;
bool m_gds2_write_timestamps;
bool m_gds2_write_cell_properties;
bool m_gds2_write_file_properties;
int m_oasis_compression_level;
bool m_oasis_write_cblocks;
bool m_oasis_strict_mode;
bool m_oasis_recompress;
bool m_oasis_permissive;
int m_oasis_write_std_properties;
std::string m_oasis_subst_char;
bool m_cif_dummy_calls;
bool m_cif_blank_separator;
int m_dxf_polygon_mode;
void set_oasis_substitution_char (const std::string &text);
};

View File

@ -21,9 +21,9 @@
*/
#include "bdConverterMain.h"
#include "dbCIFFormat.h"
#include "bdWriterOptions.h"
BD_PUBLIC int strm2cif (int argc, char *argv[])
{
return bd::converter_main (argc, argv, db::CIFWriterOptions ().format_name ());
return bd::converter_main (argc, argv, bd::GenericWriterOptions::cif_format_name);
}

View File

@ -21,9 +21,9 @@
*/
#include "bdConverterMain.h"
#include "dbDXFFormat.h"
#include "bdWriterOptions.h"
BD_PUBLIC int strm2dxf (int argc, char *argv[])
{
return bd::converter_main (argc, argv, db::DXFWriterOptions ().format_name ());
return bd::converter_main (argc, argv, bd::GenericWriterOptions::dxf_format_name);
}

View File

@ -21,9 +21,9 @@
*/
#include "bdConverterMain.h"
#include "dbGDS2Format.h"
#include "bdWriterOptions.h"
BD_PUBLIC int strm2gds (int argc, char *argv[])
{
return bd::converter_main (argc, argv, db::GDS2WriterOptions ().format_name ());
return bd::converter_main (argc, argv, bd::GenericWriterOptions::gds2_format_name);
}

View File

@ -21,9 +21,9 @@
*/
#include "bdConverterMain.h"
#include "dbGDS2Format.h"
#include "bdWriterOptions.h"
BD_PUBLIC int strm2gdstxt (int argc, char *argv[])
{
return bd::converter_main (argc, argv, db::GDS2WriterOptions ().format_name () + "Text");
return bd::converter_main (argc, argv, bd::GenericWriterOptions::gds2text_format_name);
}

View File

@ -21,9 +21,9 @@
*/
#include "bdConverterMain.h"
#include "dbOASISFormat.h"
#include "bdWriterOptions.h"
BD_PUBLIC int strm2oas (int argc, char *argv[])
{
return bd::converter_main (argc, argv, db::OASISWriterOptions ().format_name ());
return bd::converter_main (argc, argv, bd::GenericWriterOptions::gds2_format_name);
}

View File

@ -24,9 +24,9 @@
#include "bdWriterOptions.h"
#include "dbClip.h"
#include "dbLayout.h"
#include "dbGDS2Writer.h"
#include "dbOASISWriter.h"
#include "dbReader.h"
#include "dbWriter.h"
#include "dbSaveLayoutOptions.h"
#include "tlLog.h"
#include "tlCommandLineParser.h"

View File

@ -24,8 +24,6 @@
#include "bdWriterOptions.h"
#include "gsiInterpreter.h"
#include "dbLayout.h"
#include "dbGDS2Writer.h"
#include "dbOASISWriter.h"
#include "dbReader.h"
#include "tlLog.h"
#include "tlCommandLineParser.h"

View File

@ -26,6 +26,7 @@
#include "tlUnitTest.h"
#include "dbLayout.h"
#include "dbCell.h"
#include "dbSaveLayoutOptions.h"
// Testing writer options
TEST(1)
@ -73,23 +74,23 @@ TEST(1)
EXPECT_EQ (stream_opt.dont_write_empty_cells (), false);
EXPECT_EQ (stream_opt.keep_instances (), false);
EXPECT_EQ (stream_opt.write_context_info (), true);
EXPECT_EQ (stream_opt.get_options<db::CIFWriterOptions> ().blank_separator, false);
EXPECT_EQ (stream_opt.get_options<db::CIFWriterOptions> ().dummy_calls, false);
EXPECT_EQ (stream_opt.get_options<db::DXFWriterOptions> ().polygon_mode, 0);
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().libname, "LIB");
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().max_vertex_count, (unsigned int) 8000);
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().multi_xy_records, false);
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().write_timestamps, true);
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().no_zero_length_paths, false);
EXPECT_EQ (tl::to_string (stream_opt.get_options<db::GDS2WriterOptions> ().user_units), "1");
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().write_cell_properties, false);
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().write_file_properties, false);
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().write_cblocks, false);
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().compression_level, 2);
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().strict_mode, false);
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().recompress, false);
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().subst_char, "*");
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().write_std_properties, 1);
EXPECT_EQ (stream_opt.get_option_by_name ("cif_blank_separator").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("cif_dummy_calls").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_polygon_mode").to_int (), 0);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_libname").to_string (), "LIB");
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_max_vertex_count").to_uint (), (unsigned int) 8000);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_multi_xy_records").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_timestamps").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_no_zero_length_paths").to_bool (), false);
EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("gds2_user_units").to_double ()), "1");
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_cell_properties").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_file_properties").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_cblocks").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_compression_level").to_int (), 2);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_strict_mode").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_recompress").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_substitution_char").to_string (), "*");
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_std_properties_ext").to_int (), 1);
opt.configure (stream_opt, layout);
@ -98,23 +99,23 @@ TEST(1)
EXPECT_EQ (stream_opt.dont_write_empty_cells (), true);
EXPECT_EQ (stream_opt.keep_instances (), true);
EXPECT_EQ (stream_opt.write_context_info (), false);
EXPECT_EQ (stream_opt.get_options<db::CIFWriterOptions> ().blank_separator, true);
EXPECT_EQ (stream_opt.get_options<db::CIFWriterOptions> ().dummy_calls, true);
EXPECT_EQ (stream_opt.get_options<db::DXFWriterOptions> ().polygon_mode, 2);
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().libname, "MYLIBNAME");
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().max_vertex_count, (unsigned int) 250);
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().multi_xy_records, true);
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().write_timestamps, false);
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().no_zero_length_paths, true);
EXPECT_EQ (tl::to_string (stream_opt.get_options<db::GDS2WriterOptions> ().user_units), "2.5");
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().write_cell_properties, true);
EXPECT_EQ (stream_opt.get_options<db::GDS2WriterOptions> ().write_file_properties, true);
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().write_cblocks, true);
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().compression_level, 9);
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().strict_mode, true);
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().recompress, true);
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().subst_char, "X");
EXPECT_EQ (stream_opt.get_options<db::OASISWriterOptions> ().write_std_properties, 2);
EXPECT_EQ (stream_opt.get_option_by_name ("cif_blank_separator").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("cif_dummy_calls").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_polygon_mode").to_int (), 2);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_libname").to_string (), "MYLIBNAME");
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_max_vertex_count").to_uint (), (unsigned int) 250);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_multi_xy_records").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_timestamps").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_no_zero_length_paths").to_bool (), true);
EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("gds2_user_units").to_double ()), "2.5");
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_cell_properties").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_write_file_properties").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_cblocks").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_compression_level").to_int (), 9);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_strict_mode").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_recompress").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_substitution_char").to_string (), "X");
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_write_std_properties_ext").to_int (), 2);
}
static std::string cells2string (const db::Layout &layout, const std::set<db::cell_index_type> &cells)
@ -241,52 +242,52 @@ TEST(10)
cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv);
db::LoadLayoutOptions stream_opt;
EXPECT_EQ (tl::to_string (stream_opt.get_options<db::CIFReaderOptions> ().dbu), "0.001");
EXPECT_EQ (stream_opt.get_options<db::CIFReaderOptions> ().wire_mode, (unsigned int) 0);
EXPECT_EQ (stream_opt.get_options<db::CIFReaderOptions> ().layer_map.to_string (), "layer_map()");
EXPECT_EQ (stream_opt.get_options<db::CIFReaderOptions> ().create_other_layers, true);
EXPECT_EQ (tl::to_string (stream_opt.get_options<db::DXFReaderOptions> ().dbu), "0.001");
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().layer_map.to_string (), "layer_map()");
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().create_other_layers, true);
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().unit, 1.0);
EXPECT_EQ (tl::to_string (stream_opt.get_options<db::DXFReaderOptions> ().circle_accuracy), "0");
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().circle_points, 100);
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().keep_other_cells, false);
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().polyline_mode, 0);
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().render_texts_as_polygons, false);
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().text_scaling, 100);
EXPECT_EQ (stream_opt.get_options<db::CommonReaderOptions> ().layer_map.to_string (), "layer_map()");
EXPECT_EQ (stream_opt.get_options<db::CommonReaderOptions> ().create_other_layers, true);
EXPECT_EQ (stream_opt.get_options<db::CommonReaderOptions> ().enable_properties, true);
EXPECT_EQ (stream_opt.get_options<db::CommonReaderOptions> ().enable_text_objects, true);
EXPECT_EQ (stream_opt.get_options<db::GDS2ReaderOptions> ().box_mode, (unsigned int) 1);
EXPECT_EQ (stream_opt.get_options<db::GDS2ReaderOptions> ().allow_big_records, true);
EXPECT_EQ (stream_opt.get_options<db::GDS2ReaderOptions> ().allow_multi_xy_records, true);
EXPECT_EQ (stream_opt.get_options<db::OASISReaderOptions> ().expect_strict_mode, -1);
EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("cif_dbu").to_double ()), "0.001");
EXPECT_EQ (stream_opt.get_option_by_name ("cif_wire_mode").to_uint (), (unsigned int) 0);
EXPECT_EQ (stream_opt.get_option_by_name ("cif_layer_map").to_user<db::LayerMap> ().to_string (), "layer_map()");
EXPECT_EQ (stream_opt.get_option_by_name ("cif_create_other_layers").to_bool (), true);
EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("dxf_dbu").to_double ()), "0.001");
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_layer_map").to_user<db::LayerMap> ().to_string (), "layer_map()");
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_create_other_layers").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_unit").to_double (), 1.0);
EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("dxf_circle_accuracy").to_double ()), "0");
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_circle_points").to_int (), 100);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_keep_other_cells").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_polyline_mode").to_int (), 0);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_render_texts_as_polygons").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_text_scaling").to_int (), 100);
EXPECT_EQ (stream_opt.get_option_by_name ("layer_map").to_user<db::LayerMap> ().to_string (), "layer_map()");
EXPECT_EQ (stream_opt.get_option_by_name ("create_other_layers").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("properties_enabled").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("text_enabled").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_box_mode").to_uint (), (unsigned int) 1);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_allow_big_records").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_allow_multi_xy_records").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_expect_strict_mode").to_int (), -1);
opt.configure (stream_opt);
EXPECT_EQ (tl::to_string (stream_opt.get_options<db::CIFReaderOptions> ().dbu), "0.125");
EXPECT_EQ (stream_opt.get_options<db::CIFReaderOptions> ().wire_mode, (unsigned int) 1);
EXPECT_EQ (stream_opt.get_options<db::CIFReaderOptions> ().layer_map.to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')");
EXPECT_EQ (stream_opt.get_options<db::CIFReaderOptions> ().create_other_layers, false);
EXPECT_EQ (tl::to_string (stream_opt.get_options<db::DXFReaderOptions> ().dbu), "0.125");
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().layer_map.to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')");
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().create_other_layers, false);
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().unit, 2.5);
EXPECT_EQ (tl::to_string (stream_opt.get_options<db::DXFReaderOptions> ().circle_accuracy), "0.5");
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().circle_points, 1000);
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().keep_other_cells, true);
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().polyline_mode, 3);
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().render_texts_as_polygons, true);
EXPECT_EQ (stream_opt.get_options<db::DXFReaderOptions> ().text_scaling, 75);
EXPECT_EQ (stream_opt.get_options<db::CommonReaderOptions> ().layer_map.to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')");
EXPECT_EQ (stream_opt.get_options<db::CommonReaderOptions> ().create_other_layers, false);
EXPECT_EQ (stream_opt.get_options<db::CommonReaderOptions> ().enable_properties, false);
EXPECT_EQ (stream_opt.get_options<db::CommonReaderOptions> ().enable_text_objects, false);
EXPECT_EQ (stream_opt.get_options<db::GDS2ReaderOptions> ().box_mode, (unsigned int) 3);
EXPECT_EQ (stream_opt.get_options<db::GDS2ReaderOptions> ().allow_big_records, false);
EXPECT_EQ (stream_opt.get_options<db::GDS2ReaderOptions> ().allow_multi_xy_records, false);
EXPECT_EQ (stream_opt.get_options<db::OASISReaderOptions> ().expect_strict_mode, 1);
EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("cif_dbu").to_double ()), "0.125");
EXPECT_EQ (stream_opt.get_option_by_name ("cif_wire_mode").to_uint (), (unsigned int) 1);
EXPECT_EQ (stream_opt.get_option_by_name ("cif_layer_map").to_user<db::LayerMap> ().to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')");
EXPECT_EQ (stream_opt.get_option_by_name ("cif_create_other_layers").to_bool (), false);
EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("dxf_dbu").to_double ()), "0.125");
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_layer_map").to_user<db::LayerMap> ().to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')");
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_create_other_layers").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_unit").to_double (), 2.5);
EXPECT_EQ (tl::to_string (stream_opt.get_option_by_name ("dxf_circle_accuracy").to_double ()), "0.5");
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_circle_points").to_int (), 1000);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_keep_other_cells").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_polyline_mode").to_int (), 3);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_render_texts_as_polygons").to_bool (), true);
EXPECT_EQ (stream_opt.get_option_by_name ("dxf_text_scaling").to_int (), 75);
EXPECT_EQ (stream_opt.get_option_by_name ("layer_map").to_user<db::LayerMap> ().to_string (), "layer_map('1/0';'3-4/0-255';'A : 17/0')");
EXPECT_EQ (stream_opt.get_option_by_name ("create_other_layers").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("properties_enabled").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("text_enabled").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_box_mode").to_uint (), (unsigned int) 3);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_allow_big_records").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("gds2_allow_multi_xy_records").to_bool (), false);
EXPECT_EQ (stream_opt.get_option_by_name ("oasis_expect_strict_mode").to_int (), 1);
}

View File

@ -21,13 +21,10 @@
*/
#include "bdConverterMain.h"
#include "bdWriterOptions.h"
#include "dbStream.h"
#include "dbCIFFormat.h"
#include "dbDXFReader.h"
#include "dbOASISReader.h"
#include "dbGDS2Reader.h"
#include "dbTestSupport.h"
#include "contrib/dbGDS2TextReader.h"
#include "dbReader.h"
#include "tlUnitTest.h"
// Testing the converter main implementation (CIF)
@ -40,14 +37,13 @@ TEST(1)
const char *argv[] = { "x", input.c_str (), output.c_str () };
EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, db::CIFReaderOptions ().format_name ()), 0);
EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::cif_format_name), 0);
db::Layout layout;
{
tl::InputStream stream (output);
db::LoadLayoutOptions options;
options.set_options (new db::CIFReaderOptions ());
db::Reader reader (stream);
reader.read (layout, options);
EXPECT_EQ (reader.format (), "CIF");
@ -66,14 +62,13 @@ TEST(2)
const char *argv[] = { "x", input.c_str (), output.c_str () };
EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, db::DXFReaderOptions ().format_name ()), 0);
EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::dxf_format_name), 0);
db::Layout layout;
{
tl::InputStream stream (output);
db::LoadLayoutOptions options;
options.set_options (new db::DXFReaderOptions ());
db::Reader reader (stream);
reader.read (layout, options);
EXPECT_EQ (reader.format (), "DXF");
@ -98,14 +93,13 @@ TEST(3)
const char *argv[] = { "x", input.c_str (), output.c_str () };
EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, db::GDS2ReaderOptions ().format_name ()), 0);
EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::gds2_format_name), 0);
db::Layout layout;
{
tl::InputStream stream (output);
db::LoadLayoutOptions options;
options.set_options (new db::GDS2ReaderOptions ());
db::Reader reader (stream);
reader.read (layout, options);
EXPECT_EQ (reader.format (), "GDS2");
@ -124,14 +118,13 @@ TEST(4)
const char *argv[] = { "x", input.c_str (), output.c_str () };
EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, db::GDS2ReaderOptions ().format_name () + "Text"), 0);
EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::gds2text_format_name), 0);
db::Layout layout;
{
tl::InputStream stream (output);
db::LoadLayoutOptions options;
options.set_options (new db::GDS2ReaderOptions ());
db::Reader reader (stream);
reader.read (layout, options);
EXPECT_EQ (reader.format (), "GDS2Text");
@ -150,14 +143,13 @@ TEST(5)
const char *argv[] = { "x", input.c_str (), output.c_str () };
EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, db::OASISReaderOptions ().format_name ()), 0);
EXPECT_EQ (bd::converter_main (sizeof (argv) / sizeof (argv[0]), (char **) argv, bd::GenericWriterOptions::oasis_format_name), 0);
db::Layout layout;
{
tl::InputStream stream (output);
db::LoadLayoutOptions options;
options.set_options (new db::OASISReaderOptions ());
db::Reader reader (stream);
reader.read (layout, options);
EXPECT_EQ (reader.format (), "OASIS");

View File

@ -30,10 +30,25 @@ TEST(1)
std::string fp (tl::testsrc ());
fp += "/testdata/bd/strmrun.py";
std::string path = tl::combine_path (tl::get_inst_path (), "strmrun ") + fp;
tl::InputPipe pipe (path);
std::string cmd;
#if defined(__APPLE__)
// NOTE: because of system integrity, MacOS does not inherit DYLD_LIBRARY_PATH to child
// processes like sh. We need to port this variable explicitly.
const char *ldpath_name = "DYLD_LIBRARY_PATH";
const char *ldpath = getenv (ldpath_name);
if (ldpath) {
cmd += std::string (ldpath_name) + "=\"" + ldpath + "\"; export " + ldpath_name + "; ";
}
#endif
cmd += tl::combine_path (tl::get_inst_path (), "strmrun ") + fp;
tl::info << cmd;
tl::InputPipe pipe (cmd);
tl::InputStream is (pipe);
std::string data = is.read_all ();
tl::info << data;
EXPECT_EQ (data, "Hello, world (0,-42;42,0)!\n");
}

View File

@ -21,13 +21,3 @@ INCLUDEPATH += $$BD_INC $$DB_INC $$TL_INC $$GSI_INC
DEPENDPATH += $$BD_INC $$DB_INC $$TL_INC $$GSI_INC
LIBS += -L$$DESTDIR_UT -lklayout_bd -lklayout_db -lklayout_tl -lklayout_gsi
PLUGINPATH += \
$$PWD/../../plugins/common \
$$PWD/../../plugins/streamers/gds2/db_plugin \
$$PWD/../../plugins/streamers/cif/db_plugin \
$$PWD/../../plugins/streamers/oasis/db_plugin \
$$PWD/../../plugins/streamers/dxf/db_plugin \
INCLUDEPATH += $$PLUGINPATH
DEPENDPATH += $$PLUGINPATH

View File

@ -129,6 +129,8 @@ void init (const std::vector<std::string> &_paths)
#if defined(_WIN32)
pattern.set_case_sensitive (false);
pattern = std::string ("*.dll");
#elif defined(__APPLE__)
pattern = std::string ("*.dylib");
#else
pattern = std::string ("*.so");
#endif

View File

@ -25,6 +25,7 @@
#include "dbStream.h"
#include "tlClassRegistry.h"
#include "tlStream.h"
#include "tlExpression.h"
namespace db
{
@ -105,5 +106,34 @@ namespace db
return 0;
}
}
void
LoadLayoutOptions::set_option_by_name (const std::string &method, const tl::Variant &value)
{
// Utilizes the GSI binding to set the values
tl::Variant options_ref = tl::Variant::make_variant_ref (this);
const tl::EvalClass *eval_cls = options_ref.user_cls ()->eval_cls ();
tl::ExpressionParserContext context;
tl::Variant out;
std::vector<tl::Variant> args;
args.push_back (value);
eval_cls->execute (context, out, options_ref, method + "=", args);
}
tl::Variant
LoadLayoutOptions::get_option_by_name (const std::string &method)
{
// Utilizes the GSI binding to set the values
tl::Variant options_ref = tl::Variant::make_variant_ref (this);
const tl::EvalClass *eval_cls = options_ref.user_cls ()->eval_cls ();
tl::ExpressionParserContext context;
tl::Variant out;
std::vector<tl::Variant> args;
eval_cls->execute (context, out, options_ref, method, args);
return out;
}
}

View File

@ -33,6 +33,8 @@
#include "dbStreamLayers.h"
#include "gsiObject.h"
#include "gsiClass.h"
#include "tlVariant.h"
namespace db
{
@ -182,6 +184,22 @@ public:
*/
FormatSpecificReaderOptions *get_options (const std::string &name);
/**
* @brief Sets a layout reader option by name
*
* The name is taken to be a GSI method which is called to set the
* option. For example, setting "gds2_unit", the method "gds2_unit=" is
* called with the given value.
*/
void set_option_by_name (const std::string &name, const tl::Variant &value);
/**
* @brief Gets a layout reader option by name
*
* See "set_option_by_name" for details.
*/
tl::Variant get_option_by_name (const std::string &name);
private:
std::map <std::string, FormatSpecificReaderOptions *> m_options;

View File

@ -25,6 +25,7 @@
#include "dbStream.h"
#include "tlClassRegistry.h"
#include "tlStream.h"
#include "tlExpression.h"
namespace db
{
@ -125,6 +126,35 @@ SaveLayoutOptions::get_options (const std::string &format)
}
}
void
SaveLayoutOptions::set_option_by_name (const std::string &method, const tl::Variant &value)
{
// Utilizes the GSI binding to set the values
tl::Variant options_ref = tl::Variant::make_variant_ref (this);
const tl::EvalClass *eval_cls = options_ref.user_cls ()->eval_cls ();
tl::ExpressionParserContext context;
tl::Variant out;
std::vector<tl::Variant> args;
args.push_back (value);
eval_cls->execute (context, out, options_ref, method + "=", args);
}
tl::Variant
SaveLayoutOptions::get_option_by_name (const std::string &method)
{
// Utilizes the GSI binding to set the values
tl::Variant options_ref = tl::Variant::make_variant_ref (this);
const tl::EvalClass *eval_cls = options_ref.user_cls ()->eval_cls ();
tl::ExpressionParserContext context;
tl::Variant out;
std::vector<tl::Variant> args;
eval_cls->execute (context, out, options_ref, method, args);
return out;
}
void
SaveLayoutOptions::set_format (const std::string &format_name)
{

View File

@ -33,6 +33,10 @@
#include "dbLayout.h"
#include "dbStreamLayers.h"
#include "gsiObject.h"
#include "gsiClass.h"
#include "tlVariant.h"
namespace db
{
@ -409,6 +413,22 @@ public:
*/
void get_cells (const db::Layout &layout, std::set <db::cell_index_type> &cells, const std::vector <std::pair <unsigned int, db::LayerProperties> > &valid_layers) const;
/**
* @brief Sets a layout reader option by name
*
* The name is taken to be a GSI method which is called to set the
* option. For example, setting "gds2_unit", the method "gds2_unit=" is
* called with the given value.
*/
void set_option_by_name (const std::string &name, const tl::Variant &value);
/**
* @brief Gets a layout reader option by name
*
* See "set_option_by_name" for details.
*/
tl::Variant get_option_by_name (const std::string &name);
private:
std::string m_format;
std::map<unsigned int, db::LayerProperties> m_layers;

View File

@ -38,6 +38,11 @@ static void set_layer_map (db::LoadLayoutOptions *options, const db::LayerMap &l
options->get_options<db::CommonReaderOptions> ().create_other_layers = f;
}
static void set_layer_map1 (db::LoadLayoutOptions *options, const db::LayerMap &lm)
{
options->get_options<db::CommonReaderOptions> ().layer_map = lm;
}
static db::LayerMap &get_layer_map (db::LoadLayoutOptions *options)
{
return options->get_options<db::CommonReaderOptions> ().layer_map;
@ -91,6 +96,12 @@ gsi::ClassExt<db::LoadLayoutOptions> common_reader_options (
"\n"
"Starting with version 0.25 this option only applies to GDS2 and OASIS format. Other formats provide their own configuration."
) +
gsi::method_ext ("layer_map=", &set_layer_map1, gsi::arg ("map"),
"@brief Sets the layer map, but does not affect the \"create_other_layers\" flag.\n"
"@param map The layer map to set."
"\n"
"This convenience method has been introduced with version 0.26."
) +
gsi::method_ext ("select_all_layers", &select_all_layers,
"@brief Selects all layers and disables the layer map\n"
"\n"
@ -104,6 +115,8 @@ gsi::ClassExt<db::LoadLayoutOptions> common_reader_options (
"@return A reference to the layer map\n"
"\n"
"Starting with version 0.25 this option only applies to GDS2 and OASIS format. Other formats provide their own configuration."
"\n"
"Python note: this method has been turned into a property in version 0.26."
) +
gsi::method_ext ("create_other_layers?", &create_other_layers,
"@brief Gets a value indicating whether other layers shall be created\n"

View File

@ -0,0 +1,104 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "tlUnitTest.h"
#include "dbLoadLayoutOptions.h"
#include "gsiDecl.h"
class MyReaderOptions
: public db::FormatSpecificReaderOptions
{
public:
MyReaderOptions ()
: db::FormatSpecificReaderOptions ()
{
}
virtual FormatSpecificReaderOptions *clone () const
{
return new MyReaderOptions (*this);
}
virtual const std::string &format_name () const
{
static std::string fmt ("myformat");
return fmt;
}
std::string value;
db::LayerMap lm;
};
static std::string get_myreader_value (const db::LoadLayoutOptions *options)
{
return options->get_options<MyReaderOptions> ().value;
}
static void set_myreader_value (db::LoadLayoutOptions *options, const std::string &v)
{
options->get_options<MyReaderOptions> ().value = v;
}
static db::LayerMap get_myreader_lm (const db::LoadLayoutOptions *options)
{
return options->get_options<MyReaderOptions> ().lm;
}
static void set_myreader_lm (db::LoadLayoutOptions *options, const db::LayerMap &lm)
{
options->get_options<MyReaderOptions> ().lm = lm;
}
static
gsi::ClassExt<db::LoadLayoutOptions> myreaderoptions_cls (
gsi::method_ext ("myreader_value", &get_myreader_value) +
gsi::method_ext ("myreader_value=", &set_myreader_value) +
gsi::method_ext ("myreader_lm", &get_myreader_lm) +
gsi::method_ext ("myreader_lm=", &set_myreader_lm),
"@hide");
TEST(1)
{
db::LoadLayoutOptions opt;
MyReaderOptions myopt;
myopt.value = "42";
opt.set_options (myopt);
EXPECT_EQ (opt.get_options<MyReaderOptions> ().value, "42");
EXPECT_EQ (opt.get_option_by_name ("myreader_value").to_string (), "42");
opt.set_option_by_name ("myreader_value", tl::Variant ("abc"));
EXPECT_EQ (opt.get_option_by_name ("myreader_value").to_string (), "abc");
db::LayerMap lm = db::LayerMap::from_string_file_format ("1/0:2\n10/0");
EXPECT_EQ (lm.to_string (), "layer_map('1/0 : 2/0';'10/0')");
opt.set_option_by_name ("myreader_lm", tl::Variant::make_variant (lm));
EXPECT_EQ (opt.get_option_by_name ("myreader_lm").to_user<db::LayerMap> ().to_string (), "layer_map('1/0 : 2/0';'10/0')");
myopt.value = "17";
opt.set_options (myopt);
EXPECT_EQ (opt.get_options<MyReaderOptions> ().value, "17");
EXPECT_EQ (opt.get_option_by_name ("myreader_value").to_string (), "17");
}

View File

@ -0,0 +1,104 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "tlUnitTest.h"
#include "dbSaveLayoutOptions.h"
#include "gsiDecl.h"
class MyWriterOptions
: public db::FormatSpecificWriterOptions
{
public:
MyWriterOptions ()
: db::FormatSpecificWriterOptions ()
{
}
virtual FormatSpecificWriterOptions *clone () const
{
return new MyWriterOptions (*this);
}
virtual const std::string &format_name () const
{
static std::string fmt ("myformat");
return fmt;
}
std::string value;
db::LayerMap lm;
};
static std::string get_mywriter_value (const db::SaveLayoutOptions *options)
{
return options->get_options<MyWriterOptions> ().value;
}
static void set_mywriter_value (db::SaveLayoutOptions *options, const std::string &v)
{
options->get_options<MyWriterOptions> ().value = v;
}
static db::LayerMap get_mywriter_lm (const db::SaveLayoutOptions *options)
{
return options->get_options<MyWriterOptions> ().lm;
}
static void set_mywriter_lm (db::SaveLayoutOptions *options, const db::LayerMap &lm)
{
options->get_options<MyWriterOptions> ().lm = lm;
}
static
gsi::ClassExt<db::SaveLayoutOptions> mywriteroptions_cls (
gsi::method_ext ("mywriter_value", &get_mywriter_value) +
gsi::method_ext ("mywriter_value=", &set_mywriter_value) +
gsi::method_ext ("mywriter_lm", &get_mywriter_lm) +
gsi::method_ext ("mywriter_lm=", &set_mywriter_lm),
"@hide");
TEST(1)
{
db::SaveLayoutOptions opt;
MyWriterOptions myopt;
myopt.value = "42";
opt.set_options (myopt);
EXPECT_EQ (opt.get_options<MyWriterOptions> ().value, "42");
EXPECT_EQ (opt.get_option_by_name ("mywriter_value").to_string (), "42");
opt.set_option_by_name ("mywriter_value", tl::Variant ("abc"));
EXPECT_EQ (opt.get_option_by_name ("mywriter_value").to_string (), "abc");
db::LayerMap lm = db::LayerMap::from_string_file_format ("1/0:2\n10/0");
EXPECT_EQ (lm.to_string (), "layer_map('1/0 : 2/0';'10/0')");
opt.set_option_by_name ("mywriter_lm", tl::Variant::make_variant (lm));
EXPECT_EQ (opt.get_option_by_name ("mywriter_lm").to_user<db::LayerMap> ().to_string (), "layer_map('1/0 : 2/0';'10/0')");
myopt.value = "17";
opt.set_options (myopt);
EXPECT_EQ (opt.get_options<MyWriterOptions> ().value, "17");
EXPECT_EQ (opt.get_option_by_name ("mywriter_value").to_string (), "17");
}

View File

@ -51,7 +51,9 @@ SOURCES = \
dbTrans.cc \
dbVector.cc \
dbWriterTools.cc \
dbVariableWidthPath.cc
dbVariableWidthPath.cc \
dbLoadLayoutOptionsTests.cc \
dbSaveLayoutOptionsTests.cc
INCLUDEPATH += $$TL_INC $$DB_INC $$GSI_INC
DEPENDPATH += $$TL_INC $$DB_INC $$GSI_INC

View File

@ -130,6 +130,8 @@ void init (const std::vector<std::string> &_paths)
#if defined(_WIN32)
pattern.set_case_sensitive (false);
pattern = std::string ("*.dll");
#elif defined(__APPLE__)
pattern = std::string ("*.dylib");
#else
pattern = std::string ("*.so");
#endif

View File

@ -25,6 +25,7 @@
#include "dbSaveLayoutOptions.h"
#include "dbLoadLayoutOptions.h"
#include "dbPluginCommon.h"
namespace db
{
@ -34,7 +35,7 @@ namespace db
* NOTE: this structure is non-public linkage by intention. This way it's instantiated
* in all compile units and the shared object does not need to be linked.
*/
class CIFReaderOptions
class DB_PLUGIN_PUBLIC CIFReaderOptions
: public FormatSpecificReaderOptions
{
public:
@ -118,7 +119,7 @@ public:
* NOTE: this structure is non-public linkage by intention. This way it's instantiated
* in all compile units and the shared object does not need to be linked.
*/
class CIFWriterOptions
class DB_PLUGIN_PUBLIC CIFWriterOptions
: public FormatSpecificWriterOptions
{
public:

View File

@ -59,6 +59,11 @@ static void set_layer_map (db::LoadLayoutOptions *options, const db::LayerMap &l
options->get_options<db::CIFReaderOptions> ().create_other_layers = f;
}
static void set_layer_map1 (db::LoadLayoutOptions *options, const db::LayerMap &lm)
{
options->get_options<db::CIFReaderOptions> ().layer_map = lm;
}
static db::LayerMap &get_layer_map (db::LoadLayoutOptions *options)
{
return options->get_options<db::CIFReaderOptions> ().layer_map;
@ -103,6 +108,13 @@ gsi::ClassExt<db::LoadLayoutOptions> cif_reader_options (
"This method has been added in version 0.25 and replaces the respective global option in \\LoadLayoutOptions "
"in a format-specific fashion."
) +
gsi::method_ext ("cif_layer_map=", &set_layer_map1, gsi::arg ("map"),
"@brief Sets the layer map\n"
"This sets a layer mapping for the reader. Unlike \\cif_set_layer_map, the 'create_other_layers' flag is not changed.\n"
"@param map The layer map to set."
"\n"
"This convenience method has been added in version 0.26."
) +
gsi::method_ext ("cif_select_all_layers", &select_all_layers,
"@brief Selects all layers and disables the layer map\n"
"\n"
@ -117,7 +129,9 @@ gsi::ClassExt<db::LoadLayoutOptions> cif_reader_options (
"@return A reference to the layer map\n"
"\n"
"This method has been added in version 0.25 and replaces the respective global option in \\LoadLayoutOptions "
"in a format-specific fashion."
"in a format-specific fashion.\n"
"\n"
"Python note: this method has been turned into a property in version 0.26."
) +
gsi::method_ext ("cif_create_other_layers?", &create_other_layers,
"@brief Gets a value indicating whether other layers shall be created\n"

View File

@ -13,7 +13,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../
LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi
# This makes the test pull the mebes library for testing (not installed)
PLUGINPATH = $$OUT_PWD/../../../../db_plugins
QMAKE_RPATHDIR += $$PLUGINPATH

View File

@ -25,6 +25,7 @@
#include "dbLoadLayoutOptions.h"
#include "dbSaveLayoutOptions.h"
#include "dbPluginCommon.h"
namespace db
{
@ -34,7 +35,7 @@ namespace db
* NOTE: this structure is non-public linkage by intention. This way it's instantiated
* in all compile units and the shared object does not need to be linked.
*/
class DXFReaderOptions
class DB_PLUGIN_PUBLIC DXFReaderOptions
: public FormatSpecificReaderOptions
{
public:
@ -192,7 +193,7 @@ public:
* NOTE: this structure is non-public linkage by intention. This way it's instantiated
* in all compile units and the shared object does not need to be linked.
*/
class DXFWriterOptions
class DB_PLUGIN_PUBLIC DXFWriterOptions
: public FormatSpecificWriterOptions
{
public:

View File

@ -133,6 +133,11 @@ static void set_layer_map (db::LoadLayoutOptions *options, const db::LayerMap &l
options->get_options<db::DXFReaderOptions> ().create_other_layers = f;
}
static void set_layer_map1 (db::LoadLayoutOptions *options, const db::LayerMap &lm)
{
options->get_options<db::DXFReaderOptions> ().layer_map = lm;
}
static db::LayerMap &get_layer_map (db::LoadLayoutOptions *options)
{
return options->get_options<db::DXFReaderOptions> ().layer_map;
@ -177,6 +182,13 @@ gsi::ClassExt<db::LoadLayoutOptions> dxf_reader_options (
"This method has been added in version 0.25 and replaces the respective global option in \\LoadLayoutOptions "
"in a format-specific fashion."
) +
gsi::method_ext ("dxf_layer_map=", &set_layer_map1, gsi::arg ("map"),
"@brief Sets the layer map\n"
"This sets a layer mapping for the reader. Unlike \\dxf_set_layer_map, the 'create_other_layers' flag is not changed.\n"
"@param map The layer map to set."
"\n"
"This convenience method has been added in version 0.26."
) +
gsi::method_ext ("dxf_select_all_layers", &select_all_layers,
"@brief Selects all layers and disables the layer map\n"
"\n"
@ -192,6 +204,8 @@ gsi::ClassExt<db::LoadLayoutOptions> dxf_reader_options (
"\n"
"This method has been added in version 0.25 and replaces the respective global option in \\LoadLayoutOptions "
"in a format-specific fashion."
"\n"
"Python note: this method has been turned into a property in version 0.26."
) +
gsi::method_ext ("dxf_create_other_layers?", &create_other_layers,
"@brief Gets a value indicating whether other layers shall be created\n"

View File

@ -13,7 +13,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../
LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi
# This makes the test pull the mebes library for testing (not installed)
PLUGINPATH = $$OUT_PWD/../../../../db_plugins
QMAKE_RPATHDIR += $$PLUGINPATH

View File

@ -25,6 +25,7 @@
#include "dbSaveLayoutOptions.h"
#include "dbLoadLayoutOptions.h"
#include "dbPluginCommon.h"
namespace db
{
@ -34,7 +35,7 @@ namespace db
* NOTE: this structure is non-public linkage by intention. This way it's instantiated
* in all compile units and the shared object does not need to be linked.
*/
class GDS2ReaderOptions
class DB_PLUGIN_PUBLIC GDS2ReaderOptions
: public FormatSpecificReaderOptions
{
public:
@ -97,7 +98,7 @@ public:
* NOTE: this structure is non-public linkage by intention. This way it's instantiated
* in all compile units and the shared object does not need to be linked.
*/
class GDS2WriterOptions
class DB_PLUGIN_PUBLIC GDS2WriterOptions
: public FormatSpecificWriterOptions
{
public:

View File

@ -14,7 +14,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../
LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi
# This makes the test pull the mebes library for testing (not installed)
PLUGINPATH = $$OUT_PWD/../../../../db_plugins
QMAKE_RPATHDIR += $$PLUGINPATH

View File

@ -13,7 +13,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../
LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi
# This makes the test pull the mebes library for testing (not installed)
PLUGINPATH = $$OUT_PWD/../../../../db_plugins
QMAKE_RPATHDIR += $$PLUGINPATH

View File

@ -25,6 +25,7 @@
#include "dbSaveLayoutOptions.h"
#include "dbLoadLayoutOptions.h"
#include "dbPluginCommon.h"
namespace db
{
@ -34,7 +35,7 @@ namespace db
* NOTE: this structure is non-public linkage by intention. This way it's instantiated
* in all compile units and the shared object does not need to be linked.
*/
class OASISReaderOptions
class DB_PLUGIN_PUBLIC OASISReaderOptions
: public FormatSpecificReaderOptions
{
public:
@ -92,7 +93,7 @@ public:
* NOTE: this structure is non-public linkage by intention. This way it's instantiated
* in all compile units and the shared object does not need to be linked.
*/
class OASISWriterOptions
class DB_PLUGIN_PUBLIC OASISWriterOptions
: public FormatSpecificWriterOptions
{
public:

View File

@ -30,6 +30,51 @@
namespace gsi
{
// ---------------------------------------------------------------
// gsi Implementation of specific methods of LoadLayoutOptions
static void set_oasis_read_all_properties (db::LoadLayoutOptions *options, bool f)
{
options->get_options<db::OASISReaderOptions> ().read_all_properties = f;
}
static int get_oasis_read_all_properties (const db::LoadLayoutOptions *options)
{
return options->get_options<db::OASISReaderOptions> ().read_all_properties;
}
static void set_oasis_expect_strict_mode (db::LoadLayoutOptions *options, int f)
{
options->get_options<db::OASISReaderOptions> ().expect_strict_mode = f;
}
static int get_oasis_expect_strict_mode (const db::LoadLayoutOptions *options)
{
return options->get_options<db::OASISReaderOptions> ().expect_strict_mode;
}
// extend lay::LoadLayoutOptions with the OASIS options
static
gsi::ClassExt<db::LoadLayoutOptions> oasis_reader_options (
gsi::method_ext ("oasis_read_all_properties=", &set_oasis_read_all_properties,
// this method is mainly provided as access point for the generic interface
"@hide"
) +
gsi::method_ext ("oasis_read_all_properties?", &get_oasis_read_all_properties,
// this method is mainly provided as access point for the generic interface
"@hide"
) +
gsi::method_ext ("oasis_expect_strict_mode=", &set_oasis_expect_strict_mode,
// this method is mainly provided as access point for the generic interface
"@hide"
) +
gsi::method_ext ("oasis_expect_strict_mode?", &get_oasis_expect_strict_mode,
// this method is mainly provided as access point for the generic interface
"@hide"
),
""
);
// ---------------------------------------------------------------
// gsi Implementation of specific methods
@ -78,6 +123,16 @@ static bool get_oasis_write_std_properties (const db::SaveLayoutOptions *options
return options->get_options<db::OASISWriterOptions> ().write_std_properties != 0;
}
static void set_oasis_write_std_properties_ext (db::SaveLayoutOptions *options, int f)
{
options->get_options<db::OASISWriterOptions> ().write_std_properties = f;
}
static int get_oasis_write_std_properties_ext (const db::SaveLayoutOptions *options)
{
return options->get_options<db::OASISWriterOptions> ().write_std_properties;
}
static void set_oasis_write_cell_bounding_boxes (db::SaveLayoutOptions *options, bool f)
{
db::OASISWriterOptions &oasis_options = options->get_options<db::OASISWriterOptions> ();
@ -222,6 +277,14 @@ gsi::ClassExt<db::SaveLayoutOptions> oasis_writer_options (
"\n"
"This method has been introduced in version 0.24."
) +
gsi::method_ext ("oasis_write_std_properties_ext=", &set_oasis_write_std_properties_ext,
// this method is mainly provided as access point for the generic interface
"@hide"
) +
gsi::method_ext ("oasis_write_std_properties_ext", &get_oasis_write_std_properties_ext,
// this method is mainly provided as access point for the generic interface
"@hide"
) +
gsi::method_ext ("oasis_compression_level=", &set_oasis_compression,
"@brief Set the OASIS compression level\n"
"@args level\n"

View File

@ -15,7 +15,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../
LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi
# This makes the test pull the mebes library for testing (not installed)
PLUGINPATH = $$OUT_PWD/../../../../db_plugins
QMAKE_RPATHDIR += $$PLUGINPATH

View File

@ -13,7 +13,6 @@ DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../
LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi
# This makes the test pull the mebes library for testing (not installed)
PLUGINPATH = $$OUT_PWD/../../../../db_plugins
QMAKE_RPATHDIR += $$PLUGINPATH

View File

@ -53,7 +53,20 @@ int run_pymodtest (tl::TestBase *_this, const std::string &fn)
std::string text;
{
std::string cmd = std::string ("\"") + STRINGIFY (PYTHON) + "\" " + fp + " 2>&1";
std::string cmd;
#if defined(__APPLE__)
// NOTE: because of system integrity, MacOS does not inherit DYLD_LIBRARY_PATH to child
// processes like sh. We need to port this variable explicitly.
const char *ldpath_name = "DYLD_LIBRARY_PATH";
const char *ldpath = getenv (ldpath_name);
if (ldpath) {
cmd += std::string (ldpath_name) + "=\"" + ldpath + "\"; export " + ldpath_name + "; ";
}
#endif
cmd += std::string ("\"") + STRINGIFY (PYTHON) + "\" " + fp + " 2>&1";
tl::info << cmd;
tl::InputPipe pipe (cmd);
tl::InputStream is (pipe);

View File

@ -966,10 +966,17 @@ InputPipe::~InputPipe ()
void
InputPipe::close ()
{
wait ();
}
int InputPipe::wait ()
{
int ret = 0;
if (m_file != NULL) {
fclose (m_file);
ret = pclose (m_file);
m_file = NULL;
}
return ret;
}
size_t

View File

@ -326,6 +326,7 @@ public:
/**
* @brief Closes the pipe
* This method will wait for the child process to terminate.
*/
virtual void close ();
@ -352,6 +353,11 @@ public:
return std::string ();
}
/**
* @brief Closes the pipe and returns the exit code of the child process
*/
int wait ();
private:
// No copying
InputPipe (const InputPipe &);

View File

@ -0,0 +1,44 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "tlStream.h"
#include "tlUnitTest.h"
TEST(InputPipe1)
{
tl::InputPipe pipe ("echo HELLOWORLD");
tl::InputStream str (pipe);
tl::TextInputStream tstr (str);
EXPECT_EQ (tstr.get_line (), "HELLOWORLD");
EXPECT_EQ (pipe.wait (), 0);
}
TEST(InputPipe2)
{
tl::InputPipe pipe ("thiscommanddoesnotexistithink 2>&1");
tl::InputStream str (pipe);
tl::TextInputStream tstr (str);
tstr.get_line ();
int ret = pipe.wait ();
tl::info << "Process exit code: " << ret;
EXPECT_NE (ret, 0);
}

View File

@ -380,48 +380,6 @@ main_cont (int &argc, char **argv)
pya::PythonInterpreter::initialize ();
gsi::initialize_external ();
#if defined(HAVE_QT)
// NOTE: we need an application object, but we don't call parse_cmd. This makes the object
// behave neutral as far as possible.
lay::GuiApplication app (argc, argv);
app.init_app ();
app.ruby_interpreter ().push_console (&console);
app.python_interpreter ().push_console (&console);
app.autorun ();
#if QT_VERSION < 0x050000
QTextCodec::setCodecForTr (QTextCodec::codecForName ("utf8"));
#endif
#else
// select the system locale
setlocale (LC_ALL, "");
// initialize the modules (load their plugins from the paths)
db::init ();
// initialize the GSI class system (Variant binding, Expression support)
// We have to do this now since plugins may register GSI classes and before the
// ruby interpreter, because it depends on a proper class system.
gsi::initialize ();
// initialize the tl::Expression subsystem with GSI-bound classes
gsi::initialize_expressions ();
// instantiate the interpreters
ruby_interpreter.reset (new rba::RubyInterpreter ());
ruby_interpreter->push_console (&console);
python_interpreter.reset (new pya::PythonInterpreter ());
python_interpreter->push_console (&console);
#endif
// Search and initialize plugin unit tests
std::string inst_dir = tl::get_inst_path ();
@ -464,6 +422,48 @@ main_cont (int &argc, char **argv)
throw tl::Exception ("No test libraries found - make sure, the *.ut files are next to the ut_runner executable.");
}
#if defined(HAVE_QT)
// NOTE: we need an application object, but we don't call parse_cmd. This makes the object
// behave neutral as far as possible.
lay::GuiApplication app (argc, argv);
app.init_app ();
app.ruby_interpreter ().push_console (&console);
app.python_interpreter ().push_console (&console);
app.autorun ();
#if QT_VERSION < 0x050000
QTextCodec::setCodecForTr (QTextCodec::codecForName ("utf8"));
#endif
#else
// select the system locale
setlocale (LC_ALL, "");
// initialize the modules (load their plugins from the paths)
db::init ();
// initialize the GSI class system (Variant binding, Expression support)
// We have to do this now since plugins may register GSI classes and before the
// ruby interpreter, because it depends on a proper class system.
gsi::initialize ();
// initialize the tl::Expression subsystem with GSI-bound classes
gsi::initialize_expressions ();
// instantiate the interpreters
ruby_interpreter.reset (new rba::RubyInterpreter ());
ruby_interpreter->push_console (&console);
python_interpreter.reset (new pya::PythonInterpreter ());
python_interpreter->push_console (&console);
#endif
bool editable = false, non_editable = false;
bool gsi_coverage = false;
std::vector<std::string> class_names;

View File

@ -1,98 +0,0 @@
import os, subprocess
import sys
from macbuild.build4mac_util import WalkFrameworkPaths, PerformChanges, DetectChanges
from pathlib import Path
# bundlePath = AbsMacPkgDir
bundlePath = os.getcwd() + '/qt5.pkg.macos-HighSierra-release/klayout.app'
bundleExecPathAbs = '%s/Contents/MacOS/' % bundlePath
pythonOriginalFrameworkPath = '/usr/local/opt/python/Frameworks/Python.framework'
pythonFrameworkPath = '%s/Contents/Frameworks/Python.framework' % bundlePath
print("[1] Copying Python Framework")
shell_commands = list()
shell_commands.append(f"rm -rf {pythonFrameworkPath}")
shell_commands.append(f"rsync -a --safe-links {pythonOriginalFrameworkPath}/ {pythonFrameworkPath}")
shell_commands.append(f"mkdir {pythonFrameworkPath}/Versions/3.6/lib/python3.6/site-packages/")
shell_commands.append(f"cp -RL {pythonOriginalFrameworkPath}/Versions/3.6/lib/python3.6/site-packages/{{pip*,pkg_resources,setuptools*,wheel*}} " +
f"{pythonFrameworkPath}/Versions/3.6/lib/python3.6/site-packages/")
shell_commands.append(f"rm -rf {pythonFrameworkPath}/Versions/3.6/lib/python3.6/test")
shell_commands.append(f"rm -rf {pythonFrameworkPath}/Versions/3.6/Resources")
shell_commands.append(f"rm -rf {pythonFrameworkPath}/Versions/3.6/bin")
for command in shell_commands:
if subprocess.call( command, shell=True ) != 0:
msg = "command failed: %s"
print( msg % command, file=sys.stderr )
exit(1)
print("[2] Relinking dylib dependencies inside Python.framework")
depdict = WalkFrameworkPaths(pythonFrameworkPath)
appPythonFrameworkPath = '@executable_path/../Frameworks/Python.framework/'
PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath)], bundleExecPathAbs)
usrLocalPath = '/usr/local/opt/'
appUsrLocalPath = '@executable_path/../Frameworks/'
depdict = WalkFrameworkPaths(pythonFrameworkPath)
PerformChanges(depdict, [(usrLocalPath, appUsrLocalPath)], bundleExecPathAbs, libdir=True)
print("[3] Relinking dylib dependencies for klayout")
klayoutPath = bundleExecPathAbs
depdict = WalkFrameworkPaths(klayoutPath, filter_regex=r'klayout$')
PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath)], bundleExecPathAbs)
libKlayoutPath = bundleExecPathAbs + '../Frameworks'
depdict = WalkFrameworkPaths(libKlayoutPath, filter_regex=r'libklayout')
PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath)], bundleExecPathAbs)
print("[4] Patching site.py, pip/, and distutils/")
site_module = f"{pythonFrameworkPath}/Versions/3.6/lib/python3.6/site.py"
with open(site_module, 'r') as site:
buf = site.readlines()
with open(site_module, 'w') as site:
import re
for line in buf:
# This will fool pip into thinking it's inside a virtual environment
# and install new packates to the correct site-packages
if re.match("^PREFIXES", line) is not None:
line = line + "sys.real_prefix = sys.prefix\n"
# do not allow installation in the user folder.
if re.match("^ENABLE_USER_SITE", line) is not None:
line = "ENABLE_USER_SITE = False\n"
site.write(line)
pip_module = f"{pythonFrameworkPath}/Versions/3.6/lib/python3.6/site-packages/pip/__init__.py"
with open(pip_module, 'r') as pip:
buf = pip.readlines()
with open(pip_module, 'w') as pip:
import re
for line in buf:
# this will reject user's configuration of pip, forcing the isolated mode
line = re.sub("return isolated$", "return isolated or True", line)
pip.write(line)
distutilsconfig = f"{pythonFrameworkPath}/Versions/3.6/lib/python3.6/distutils/distutils.cfg"
with open(distutilsconfig, 'r') as file:
buf = file.readlines()
with open(distutilsconfig, 'w') as file:
import re
for line in buf:
# This will cause all packages to be installed to sys.prefix
if re.match('prefix=', line) is not None:
continue
file.write(line)
# pythonPath = bundleExecPathAbs + '../Frameworks/Python.framework/Versions/3.6/bin/'
# # pythonOriginalPrefixPath = '/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6'
# # appPythonBinPath = '@executable_path/../'
# depdict = WalkFrameworkPaths(pythonPath, filter_regex=r'python')
# print(depdict)
# PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath),
# (Path(pythonOriginalFrameworkPath).resolve(), appPythonFrameworkPath)], bundleExecPathAbs)
# usrLocalPath = '/usr/local/lib/'
# appUsrLocalPath = '@executable_path/../Frameworks/'
# depdict = WalkFrameworkPaths(pythonFrameworkPath)
# PerformChanges(depdict, [(usrLocalPath, appUsrLocalPath)], bundleExecPathAbs)

View File

@ -1,14 +1,28 @@
import site; print(site.getsitepackages())
import pip
installed_packages = pip.get_installed_distributions()
installed_packages_list = sorted(["%s==%s" % (i.key, i.version)
for i in installed_packages])
print(installed_packages_list)
def get_pip_main():
import pip
# check if pip version is new:
if int(pip.__version__.split('.')[0]) > 9:
from pip._internal import main
else:
from pip import main
return main
import sys
print("Executing from: ", sys.executable)
print("-------------")
if pip.main(['install', '--upgrade', 'numpy']) > 0:
import os
print("Environment variables:")
for variable, value in os.environ.items():
if variable == 'DROPBOX_OAUTH_BEARER':
continue
print(variable, ":", value)
pipmain = get_pip_main()
print("-------------")
if pipmain(['install', '--upgrade', 'numpy']) > 0:
exit(1)
print("-------------")
@ -16,14 +30,3 @@ print("-------------")
print("Importing numpy")
import numpy
print("-------------")
import sys;
print("Executing from: ", sys.executable)
print("-------------")
import os
print("Environment variables:")
for variable, value in os.environ.items():
print(variable, ":", value)

View File

@ -30,8 +30,25 @@ load("test_prologue.rb")
class KLayoutMain_TestClass < TestBase
def setup
@klayout_home_name = "KLAYOUT_HOME"
@klayout_home = ENV[@klayout_home_name]
# setting "KLAYOUT_HOME" to empty means we don't search any place
# for macros
ENV[@klayout_home_name] = ""
end
def teardown
ENV[@klayout_home_name] = @klayout_home
end
def klayout_bin
File.join(RBA::Application::instance.inst_path, "klayout")
# special location for MacOS
file = File.join(RBA::Application::instance.inst_path, "klayout.app", "Contents", "MacOS", "klayout")
if !File.exists?(file)
file = File.join(RBA::Application::instance.inst_path, "klayout")
end
return file
end
def test_1

View File

@ -31,14 +31,14 @@ class DBReadersTests(unittest.TestCase):
lm.map(pya.LayerInfo(1, 0), 2, pya.LayerInfo(42, 17))
opt.set_layer_map(lm, True)
self.assertEqual(opt.layer_map().to_string(), "1/0 : 42/17\n")
self.assertEqual(opt.layer_map.to_string(), "1/0 : 42/17\n")
self.assertEqual(opt.create_other_layers, True)
opt.create_other_layers = False
self.assertEqual(opt.create_other_layers, False)
opt.select_all_layers()
self.assertEqual(opt.layer_map().to_string(), "")
self.assertEqual(opt.layer_map.to_string(), "")
self.assertEqual(opt.create_other_layers, True)
opt.text_enabled = True
@ -88,14 +88,14 @@ class DBReadersTests(unittest.TestCase):
lm.map(pya.LayerInfo(1, 0), 2, pya.LayerInfo(42, 17))
opt.dxf_set_layer_map(lm, True)
self.assertEqual(opt.dxf_layer_map().to_string(), "1/0 : 42/17\n")
self.assertEqual(opt.dxf_layer_map.to_string(), "1/0 : 42/17\n")
self.assertEqual(opt.dxf_create_other_layers, True)
opt.dxf_create_other_layers = False
self.assertEqual(opt.dxf_create_other_layers, False)
opt.dxf_select_all_layers()
self.assertEqual(opt.dxf_layer_map().to_string(), "")
self.assertEqual(opt.dxf_layer_map.to_string(), "")
self.assertEqual(opt.dxf_create_other_layers, True)
opt.dxf_dbu = 0.5
@ -144,14 +144,14 @@ class DBReadersTests(unittest.TestCase):
lm.map(pya.LayerInfo(1, 0), 2, pya.LayerInfo(42, 17))
opt.cif_set_layer_map(lm, True)
self.assertEqual(opt.cif_layer_map().to_string(), "1/0 : 42/17\n")
self.assertEqual(opt.cif_layer_map.to_string(), "1/0 : 42/17\n")
self.assertEqual(opt.cif_create_other_layers, True)
opt.cif_create_other_layers = False
self.assertEqual(opt.cif_create_other_layers, False)
opt.cif_select_all_layers()
self.assertEqual(opt.cif_layer_map().to_string(), "")
self.assertEqual(opt.cif_layer_map.to_string(), "")
self.assertEqual(opt.cif_create_other_layers, True)
opt.cif_keep_layer_names = True

24
travis-build.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
set -e
export PING_SLEEP=30s
bash -c "while true; do echo -n '.'; sleep $PING_SLEEP; done" &
PING_LOOP_PID=$!
touch build.txt
echo "build"
make build >> build.txt 2>&1 || tail -500 build.txt
echo "deploy"
make deploy >> build.txt 2>&1 || tail -500 build.txt
echo "test"
make test >> build.txt 2>&1 || tail -500 build.txt
echo "dropbox-deploy"
make dropbox-deploy
echo "build finished"
kill $PING_LOOP_PID
exit 0