Commit b0725081 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Merge remote-tracking branch 'origin/feature_buster' into feature_simulation

parents 2acab86c 9dac7def
Pipeline #2452 failed with stage
in 60 minutes and 30 seconds
......@@ -49,7 +49,6 @@ from ..commonPy.recursiveMapper import RecursiveMapper
from .synchronousTool import SynchronousToolGlueGenerator
isAsynchronous = False
scadeBackend = None
# noinspection PyListCreation
......@@ -484,6 +483,9 @@ class ScadeGlueGenerator(SynchronousToolGlueGenerator):
self.C_SourceFile.write(" %s();\n" % (self.CleanNameAsToolWants(sp._id)))
scadeBackend: ScadeGlueGenerator
def OnStartup(modelingLanguage: str, asnFile: str, subProgram: ApLevelContainer, subProgramImplementation: str, outputDir: str, maybeFVname: str, useOSS: bool) -> None:
global scadeBackend
scadeBackend = ScadeGlueGenerator()
......
......@@ -101,7 +101,6 @@ from ..commonPy.recursiveMapper import RecursiveMapper
from .asynchronousTool import ASynchronousToolGlueGenerator
isAsynchronous = True
ogBackend = None
# noinspection PyListCreation
......@@ -801,6 +800,9 @@ class OG_GlueGenerator(ASynchronousToolGlueGenerator):
# (self.CleanNameAsToolWants(nodeTypename), self.CleanNameAsToolWants(nodeTypename)))
ogBackend: OG_GlueGenerator
def OnStartup(modelingLanguage: str, asnFile: str, outputDir: str, maybeFVname: str, useOSS: bool) -> None:
global ogBackend
ogBackend = OG_GlueGenerator()
......
......@@ -48,7 +48,6 @@ from ..commonPy.recursiveMapper import RecursiveMapper
from .synchronousTool import SynchronousToolGlueGenerator
isAsynchronous = False
simulinkBackend = None
def IsElementMappedToPrimitive(node: AsnSequenceOrSetOf, names: AST_Lookup) -> bool:
......@@ -465,6 +464,9 @@ class SimulinkGlueGenerator(SynchronousToolGlueGenerator):
self.C_SourceFile.write("#endif\n")
simulinkBackend: SimulinkGlueGenerator
def OnStartup(modelingLanguage: str, asnFile: str, subProgram: ApLevelContainer, subProgramImplementation: str, outputDir: str, maybeFVname: str, useOSS: bool) -> None:
global simulinkBackend
simulinkBackend = SimulinkGlueGenerator()
......
......@@ -88,14 +88,14 @@ class SynchronousToolGlueGeneratorGeneric(Generic[TSource, TDestin]):
def __init__(self) -> None:
# The files written to
self.C_HeaderFile = None # type: IO[Any]
self.C_SourceFile = None # type: IO[Any]
self.ADA_HeaderFile = None # type: IO[Any]
self.ADA_SourceFile = None # type: IO[Any]
self.C_HeaderFile: IO[Any]
self.C_SourceFile: IO[Any]
self.ADA_HeaderFile: IO[Any]
self.ADA_SourceFile: IO[Any]
self.asn_name = ""
self.supportedEncodings = ['native', 'uper', 'acn']
self.dir = None # type: str
self.useOSS = None # type: bool
self.dir: str
self.useOSS: bool
def OnStartup(self,
modelingLanguage: str,
......
......@@ -60,7 +60,6 @@ from ..commonPy.recursiveMapper import RecursiveMapperGeneric
from .synchronousTool import SynchronousToolGlueGeneratorGeneric
isAsynchronous = False
vhdlBackend = None
# List of octet string sizes (used in VHDL type declarations)
g_octStr = [] # type: List[int]
......@@ -77,7 +76,6 @@ def RegistersAllocated(node_or_str: Union[str, AsnNode]) -> int:
node = names[node_or_str] # type: AsnNode
else:
node = node_or_str
retValue = None
if isinstance(node, AsnBasicNode):
retValue = 0
realLeafType = asnParser.g_leafTypeDict[node._leafType]
......@@ -970,6 +968,9 @@ def Common(nodeTypename: str, node: AsnNode, subProgram: ApLevelContainer, unuse
VHDL_Circuit.currentCircuit.AddParam(nodeTypename, node, param, leafTypeDict, names)
vhdlBackend: VHDLGlueGenerator
def OnStartup(modelingLanguage: str, asnFile: str, subProgram: ApLevelContainer, subProgramImplementation: str, outputDir: str, maybeFVname: str, useOSS: bool) -> None:
global vhdlBackend
vhdlBackend = VHDLGlueGenerator()
......@@ -1016,6 +1017,7 @@ def OnShutdown(modelingLanguage: str, asnFile: str, sp: ApLevelContainer, subPro
def OnFinal() -> None:
assert vhdlBackend.dir
circuitMapper = MapASN1ToVHDLCircuit()
ioRegisterMapper = MapASN1ToVHDLregisters()
readinputdataMapper = MapASN1ToVHDLreadinputdata()
......
......@@ -59,7 +59,6 @@ from .synchronousTool import SynchronousToolGlueGeneratorGeneric
isAsynchronous = False
vhdlBackend = None
def Version() -> None:
......@@ -76,7 +75,6 @@ def RegistersAllocated(node_or_str: Union[str, AsnNode]) -> int:
node = names[node_or_str] # type: AsnNode
else:
node = node_or_str
retValue = None
if isinstance(node, AsnBasicNode):
retValue = 0
realLeafType = asnParser.g_leafTypeDict[node._leafType]
......@@ -976,6 +974,9 @@ def Common(nodeTypename: str, node: AsnNode, subProgram: ApLevelContainer, unuse
VHDL_Circuit.currentCircuit.AddParam(nodeTypename, node, param, leafTypeDict, names)
vhdlBackend: VHDLGlueGenerator
def OnStartup(modelingLanguage: str, asnFile: str, subProgram: ApLevelContainer, subProgramImplementation: str, outputDir: str, maybeFVname: str, useOSS: bool) -> None:
global vhdlBackend
vhdlBackend = VHDLGlueGenerator()
......@@ -1026,6 +1027,7 @@ def AddToStr(s: str, d: str) -> None:
def OnFinal() -> None:
assert vhdlBackend.dir
circuitMapper = MapASN1ToVHDLCircuit()
ioRegisterMapper = MapASN1ToVHDLregisters()
readinputdataMapper = MapASN1ToVHDLreadinputdata()
......
......@@ -81,6 +81,8 @@ but with an extra call to OnFinal at the end.
import os
import sys
import hashlib
import pickle
import tempfile
from distutils import spawn
from typing import cast, Optional, Dict, List, Tuple, Set, Any # NOQA pylint: disable=unused-import
......@@ -154,8 +156,8 @@ of each SUBPROGRAM param.'''
except:
panic("The configured cache folder:\n\n\t" + projectCache +
"\n\n...is not there!\n")
cachedModelExists = False
aadlASTcache = None
astInfo = None
if projectCache is not None:
filehash = hashlib.md5()
for each in sorted(sys.argv[1:]):
......@@ -167,15 +169,10 @@ of each SUBPROGRAM param.'''
print("[DMT] No cached AADL model found for",
",".join(sys.argv[1:]))
else:
cachedModelExists = True
print("[DMT] Reusing cached AADL model for",
",".join(sys.argv[1:]))
import pickle
if cachedModelExists:
astInfo = pickle.load(open(aadlASTcache, 'rb'), fix_imports=False)
else:
import tempfile
astInfo = pickle.load(open(aadlASTcache, 'rb'), fix_imports=False)
if astInfo is None:
f = tempfile.NamedTemporaryFile(delete=False)
astFile = f.name
f.close()
......@@ -231,7 +228,7 @@ of each SUBPROGRAM param.'''
panic(str(e))
def SpecialCodes(asnFile: str) -> None:
def SpecialCodes(asnFile: Optional[str]) -> None:
'''This function handles the code generations needs that reside outside
the scope of individual parameters (e.g. it needs access to all ASN.1
types). This used to cover Dumpable C/Ada Types and OG headers.'''
......@@ -396,7 +393,7 @@ def ProcessAsync( # pylint: disable=dangerous-default-value
def ProcessCustomBackends(
# Taking list of tuples made of (spName, sp_impl, language, maybeFVname)
asnFile: str,
asnFile: Optional[str],
useOSS: bool,
SystemsAndImplementations: List[Tuple[str, str, str, str]]) -> None:
......@@ -433,6 +430,10 @@ def ProcessCustomBackends(
if lang.lower() == "vhdl":
workedOnVHDL = True # pragma: no cover
inform("Creating %s for %s.%s", lang.upper(), sp._id, sp_impl)
# Necessary for mypy, but guaranteed by the check above for empty sp._params.
assert asnFile is not None
for backend in getCustomBackends(lang):
backend.OnStartup(lang, asnFile, sp, sp_impl, commonPy.configMT.outputDir, maybeFVname, useOSS)
for param in sp._params:
......@@ -546,16 +547,16 @@ def main() -> None:
uniqueDataFiles[param._signal._asnFilename].setdefault(sp._language, [])
uniqueDataFiles[param._signal._asnFilename][sp._language].append(sp)
asn1files = list(uniqueDataFiles.keys())
asnFile = None # type: Optional[str]
asn1files = list(uniqueDataFiles.keys())
if len(asn1files) == 1:
asnFile = asn1files[0]
inform("Checking that all base nodes have mandatory ranges set in %s..." % asnFile)
commonPy.asnParser.ParseAsnFileList(asn1files)
elif asn1files:
panic("There appear to be more than one ASN.1 files referenced (%s)..." % str(asn1files))
if asnFile is not None:
inform("Checking that all base nodes have mandatory ranges set in %s..." % asnFile)
names = commonPy.asnParser.g_names
for node in names.values():
verify.VerifyRanges(node, names)
......@@ -610,6 +611,9 @@ def main() -> None:
if modelingLanguage.lower() in ["gui_ri", "gui_pi", "vhdl", "rhapsody"]:
modelingLanguage = "C"
# Necessary for mypy, but guaranteed by the check above for empty sp._params.
assert asnFile is not None
if modelingLanguage in async_languages:
m = ProcessAsync(modelingLanguage, asnFile, sp, maybeFVname, useOSS, badTypes)
asynchronousBackends.add(m)
......@@ -618,7 +622,9 @@ def main() -> None:
# SystemsAndImplementation loop completed - time to call OnShutdown ONCE for each async backend that we loaded
for asyncBackend in asynchronousBackends:
asyncBackend.OnShutdown(modelingLanguage, asnFile, maybeFVname)
# Appeasing mypy: asnFile can be None here, so I checked all
# B mappers - no-one depends on a None value for the asnFile.
asyncBackend.OnShutdown(modelingLanguage, '' if not asnFile else asnFile, maybeFVname)
ProcessCustomBackends(asnFile, useOSS, SystemsAndImplementations)
......
......@@ -198,7 +198,7 @@ class ApLevelContainer:
self._id = iid
self._params = [] # type: List[Param]
self._connections = [] # type: List[Connection]
self._language = None # type: str
self._language: str
def AddConnection(self, srcUniquePortId: UniquePortIdentifier, destUniquePortId: UniquePortIdentifier) -> None:
if srcUniquePortId._componentId is None:
......
......@@ -542,11 +542,18 @@ def GetAttr(node: Element, attrName: str) -> Optional[Any]:
return node._attrs[attrName]
def GetChild(node: Element, childName: str) -> Optional[Element]:
def GetAttrCertainly(node: Element, attrName: str) -> Any:
if attrName not in list(node._attrs.keys()):
assert False
return node._attrs[attrName]
def GetChild(node: Element, childName: str) -> Element:
for x in node._children:
if x._name == childName:
return x
return None # pragma: no cover
utility.panic(
"GetChild: No child with name %s" % childName) # pragma: no cover
class Pretty:
......@@ -584,12 +591,12 @@ U = TypeVar('U', int, float)
def GetRange(newModule: Module, lineNo: int, nodeWithMinAndMax: Element, valueType: Type[U]) -> Tuple[U, U]:
try:
mmin = GetAttr(nodeWithMinAndMax, "Min")
mmin = GetAttrCertainly(nodeWithMinAndMax, "Min")
# rangel = ( mmin == "MIN" ) and -2147483648L or valueType(mmin)
if mmin == "MIN":
utility.panic("You missed a range specification, or used MIN/MAX (line %s)" % lineNo) # pragma: no cover
rangel = valueType(mmin)
mmax = GetAttr(nodeWithMinAndMax, "Max")
mmax = GetAttrCertainly(nodeWithMinAndMax, "Max")
# rangeh = ( mmax == "MAX" ) and 2147483647L or valueType(mmax)
if mmax == "MAX":
utility.panic("You missed a range specification, or used MIN/MAX (line %s)" % lineNo) # pragma: no cover
......@@ -657,24 +664,27 @@ def CreateNumericString(newModule: Module, lineNo: int, xmlNumericStringNode: El
return CreateOctetString(newModule, lineNo, xmlNumericStringNode) # pragma: no cover
def getIntOrFloatOrNone(d: str) -> Union[int, float, None]:
def getIntOrFloatOrNone(d: Optional[str]) -> Union[int, float, None]:
i = f = None
try:
i = int(d)
return i
if d is not None:
i = int(d)
return i
except:
try:
f = float(d)
return f
if d is not None:
f = float(d)
return f
except:
return None
return None
def CreateReference(newModule: Module, lineNo: int, xmlReferenceNode: Element) -> AsnMetaType:
return AsnMetaType(
asnFilename=newModule._asnFilename,
lineno=lineNo,
containedType=GetAttr(xmlReferenceNode, "ReferencedTypeName"),
containedType=GetAttrCertainly(xmlReferenceNode, "ReferencedTypeName"),
Min=getIntOrFloatOrNone(GetAttr(xmlReferenceNode, "Min")),
Max=getIntOrFloatOrNone(GetAttr(xmlReferenceNode, "Max")))
......@@ -787,7 +797,7 @@ def GenericFactory(newModule: Module, xmlType: Element) -> AsnNode:
"SetType": CreateSet,
"ChoiceType": CreateChoice
} # type: Dict[str, Callable[[Module, int, Element], AsnNode]]
lineNo = GetAttr(xmlType, "Line")
lineNo = GetAttrCertainly(xmlType, "Line")
global g_lineno
g_lineno = lineNo
if len(xmlType._children) == 0: # pylint: disable=len-as-condition
......@@ -810,7 +820,7 @@ def VisitTypeAssignment(newModule: Module, xmlTypeAssignment: Element) -> Tuple[
if isArtificial is None:
utility.panic("You are using an older version of ASN1SCC - please upgrade.")
newNode._isArtificial = isArtificial == "True"
name = GetAttr(xmlTypeAssignment, "Name")
name = GetAttrCertainly(xmlTypeAssignment, "Name")
g_adaUses.setdefault(newModule._id, set()).add(name)
hasAcnEncDec = GetAttr(xmlType, "HasAcnEncDecFunction") or "False"
newNode.hasAcnEncDec = hasAcnEncDec != "False"
......@@ -819,8 +829,8 @@ def VisitTypeAssignment(newModule: Module, xmlTypeAssignment: Element) -> Tuple[
def VisitAsn1Module(xmlAsn1File: Element, xmlModule: Element, modules: List[Module]) -> None: # pylint: disable=invalid-sequence-index
newModule = Module()
newModule._id = GetAttr(xmlModule, "ID")
newModule._asnFilename = GetAttr(xmlAsn1File, "FileName")
newModule._id = GetAttrCertainly(xmlModule, "ID")
newModule._asnFilename = GetAttrCertainly(xmlAsn1File, "FileName")
newModule._exportedTypes = VisitAll(
GetChild(xmlModule, "ExportedTypes"), "ExportedType",
lambda x: GetAttr(x, "Name"))
......@@ -905,8 +915,8 @@ def PrintType(f: IO[Any], xmlType: Element, indent: str, nameCleaner: Callable[[
f.write('BOOLEAN')
elif realType._name == "IntegerType":
f.write('INTEGER')
mmin = GetAttr(realType, "Min")
mmax = GetAttr(realType, "Max")
mmin = GetAttrCertainly(realType, "Min")
mmax = GetAttrCertainly(realType, "Max")
f.write(' (%s .. %s)' % (mmin, mmax))
elif realType._name == "RealType":
f.write('REAL')
......@@ -917,11 +927,11 @@ def PrintType(f: IO[Any], xmlType: Element, indent: str, nameCleaner: Callable[[
utility.panic("BIT STRINGs are not supported, use SEQUENCE OF BOOLEAN") # pragma: no cover
elif realType._name == "OctetStringType" or realType._name == "IA5StringType" or realType._name == "NumericStringType":
f.write('OCTET STRING')
mmin = GetAttr(realType, "Min")
mmax = GetAttr(realType, "Max")
mmin = GetAttrCertainly(realType, "Min")
mmax = GetAttrCertainly(realType, "Max")
f.write(' (SIZE (%s .. %s))' % (mmin, mmax))
elif realType._name == "ReferenceType":
f.write(nameCleaner(GetAttr(realType, "ReferencedTypeName")))
f.write(nameCleaner(GetAttrCertainly(realType, "ReferencedTypeName")))
elif realType._name == "EnumeratedType":
f.write('ENUMERATED {\n')
options = []
......@@ -930,9 +940,9 @@ def PrintType(f: IO[Any], xmlType: Element, indent: str, nameCleaner: Callable[[
options.append(x)
VisitAll(realType, "EnumValue", addNewOption)
if options:
f.write(indent + ' ' + nameCleaner(GetAttr(options[0], "StringValue")) + "(" + GetAttr(options[0], "IntValue") + ")")
f.write(indent + ' ' + nameCleaner(GetAttrCertainly(options[0], "StringValue")) + "(" + GetAttrCertainly(options[0], "IntValue") + ")")
for otherOptions in options[1:]:
f.write(',\n' + indent + ' ' + nameCleaner(GetAttr(otherOptions, "StringValue")) + "(" + GetAttr(otherOptions, "IntValue") + ")")
f.write(',\n' + indent + ' ' + nameCleaner(GetAttrCertainly(otherOptions, "StringValue")) + "(" + GetAttrCertainly(otherOptions, "IntValue") + ")")
f.write('\n' + indent + '}')
elif realType._name == "SequenceType" or realType._name == "SetType":
if realType._name == "SequenceType":
......@@ -940,7 +950,7 @@ def PrintType(f: IO[Any], xmlType: Element, indent: str, nameCleaner: Callable[[
else:
f.write('SET {\n')
if len(realType._children) > 0: # pylint: disable=len-as-condition
f.write(indent + ' ' + nameCleaner(GetAttr(realType._children[0], "VarName")) + "\t")
f.write(indent + ' ' + nameCleaner(GetAttrCertainly(realType._children[0], "VarName")) + "\t")
firstChildOptional = GetAttr(realType._children[0], "Optional") == "True"
if len(realType._children[0]._children) == 0: # pylint: disable=len-as-condition
utility.panic("AST inconsistency: len(realType._children[0]._children) = 0\nContact ESA") # pragma: no cover
......@@ -948,7 +958,7 @@ def PrintType(f: IO[Any], xmlType: Element, indent: str, nameCleaner: Callable[[
if firstChildOptional:
f.write(' OPTIONAL')
for sequenceOrSetChild in realType._children[1:]:
f.write(",\n" + indent + ' ' + nameCleaner(GetAttr(sequenceOrSetChild, "VarName")) + "\t")
f.write(",\n" + indent + ' ' + nameCleaner(GetAttrCertainly(sequenceOrSetChild, "VarName")) + "\t")
childOptional = GetAttr(sequenceOrSetChild, "Optional") == "True"
if len(sequenceOrSetChild._children) == 0: # pylint: disable=len-as-condition
utility.panic("AST inconsistency: len(sequenceOrSetChild._children) = 0\nContact ESA") # pragma: no cover
......@@ -961,12 +971,12 @@ def PrintType(f: IO[Any], xmlType: Element, indent: str, nameCleaner: Callable[[
elif realType._name == "ChoiceType":
f.write('CHOICE {\n')
if len(realType._children) > 0: # pylint: disable=len-as-condition
f.write(indent + ' ' + nameCleaner(GetAttr(realType._children[0], "VarName")) + "\t")
f.write(indent + ' ' + nameCleaner(GetAttrCertainly(realType._children[0], "VarName")) + "\t")
if len(realType._children[0]._children) == 0: # pylint: disable=len-as-condition
utility.panic("AST inconsistency: len(realType._children[0]._children) = 0\nContact ESA") # pragma: no cover
PrintType(f, realType._children[0]._children[0], indent + " ", nameCleaner) # the contained type of the first child
for choiceChild in realType._children[1:]:
f.write(",\n" + indent + ' ' + nameCleaner(GetAttr(choiceChild, "VarName")) + "\t")
f.write(",\n" + indent + ' ' + nameCleaner(GetAttrCertainly(choiceChild, "VarName")) + "\t")
if len(choiceChild._children) == 0: # pylint: disable=len-as-condition
utility.panic("AST inconsistency: len(choiceChild._children) = 0\nContact ESA") # pragma: no cover
PrintType(f, choiceChild._children[0], indent + " ", nameCleaner) # the contained type
......@@ -996,6 +1006,8 @@ def PrintType(f: IO[Any], xmlType: Element, indent: str, nameCleaner: Callable[[
def PrintGrammarFromAST(f: IO[Any], nameCleaner: Callable[[str], str] = SimpleCleaner) -> None:
if g_xmlASTrootNode is None:
return
ourtypeAssignments = []
VisitAll(
g_xmlASTrootNode._children[0], "Asn1File",
......@@ -1003,7 +1015,7 @@ def PrintGrammarFromAST(f: IO[Any], nameCleaner: Callable[[str], str] = SimpleCl
lambda y: ourtypeAssignments.append((x, y))))
for a, t in ourtypeAssignments:
f.write("-- " + GetAttr(a, "FileName") + "\n%s ::= " % nameCleaner(GetAttr(t, "Name")))
f.write("-- " + GetAttrCertainly(a, "FileName") + "\n%s ::= " % nameCleaner(GetAttrCertainly(t, "Name")))
typeChild = GetChild(t, "Type")
if typeChild:
PrintType(f, typeChild, '', nameCleaner)
......
......@@ -109,42 +109,6 @@ def readContexts(tapNumbers: str) -> Dict[str, str]:
return data
class Matcher:
def __init__(self, pattern: str, flags: Any = 0) -> None:
self._pattern = re.compile(pattern, flags)
self._lastOne = None # type: Union[str, None]
self._match = None # type: Union[Match, None]
self._search = None # type: Union[Match, None]
def match(self, line: str) -> Match:
self._match = re.match(self._pattern, line)
self._lastOne = 'Match'
return self._match
def search(self, line: str) -> Match:
self._search = re.search(self._pattern, line)
self._lastOne = 'Search'
return self._search
def group(self, idx: int) -> str: # pylint: disable=inconsistent-return-statements
if self._lastOne == 'Match':
return self._match.group(idx)
elif self._lastOne == 'Search':
return self._search.group(idx)
else:
panic(
"Matcher group called with index "
"%d before match/search!\n" % idx)
def groups(self) -> Any: # pylint: disable=inconsistent-return-statements
if self._lastOne == 'Match':
return self._match.groups()
elif self._lastOne == 'Search':
return self._search.groups()
else:
panic("Matcher groups called with match/search!\n")
def mysystem(cmd: str) -> int:
p = platform.system()
if p == "Windows" or p.startswith("CYGWIN"):
......
......@@ -4,7 +4,7 @@ cleanDB:
# PostgreSQL
/etc/init.d/postgresql restart
# Since postgres takes a while to start, do this until it succeeds
bash -c "while true ; do echo 'drop database if exists circle_test; create database circle_test;' | psql -h 127.0.0.1 -U ubuntu postgres && break ; done"
bash -c "while true ; do echo 'drop database if exists circle_test; create database circle_test;' | psql -U ubuntu postgres && break ; done"
rm -f sql.log
#
# MySQL (is a toy - disabled related tests)
......@@ -33,7 +33,7 @@ print:
echo "========" ; \
echo PostgreSQL Content of $$i ; \
echo "========" ; \
echo "select * from \"$$i\" " | psql -h 127.0.0.1 -U ubuntu circle_test ; \
echo "select * from \"$$i\" " | psql -U ubuntu circle_test ; \
done
# @for i in MyInt My2ndInt MySeq MyChoice TypeEnumerated MySuperSeq T_ARR T_ARR_indexes T_ARR_elm ; do \
# echo "========" ; \
......
2004-04-28 21:50 carrer
* pydot.py: Some of the changes already made should allow pydot to
run on OSX. Bumped version to 0.9.2
2004-04-24 17:52 carrer
* setup.py: Added more metainformation to the distribution.
2004-04-24 17:51 carrer
* pydot.py: Added support for circo and fdp. Fixed piping mechanism
to not to capture stderr.
2004-04-24 13:26 carrer
* ChangeLog, LICENSE, MANIFEST, README, setup.py: Adding
suplementary files to the distribution to the CVS.
2004-04-24 12:57 carrer
* pydot.py: Bumped version to 0.9.1
2004-04-24 01:36 carrer
* pydot.py: Implemented tweaks suggested by John B. Cole to handle
non-str nodes, converting them to strings.
2004-04-24 01:10 carrer
* pydot.py: Applied patch for Windows support by Kent Johnson.
2004-04-24 01:05 carrer
* pydot.py: Fixed to properly handle unicode strings in attributes.
2004-04-20 00:06 carrer
* pydot.py:
Fixed silly error in graph_from_edges. When pasting the function
into the code, the references to the pydot module were not
removed, which are no longer needed since we now are _in_ the
module.
2004-04-19 23:33 carrer
* pydot.py:
Added support to write files with the desired output format with
write_[format]
2004-04-19 22:53 carrer
* pydot.py:
Done some clean up, no major changes.
2004-04-08 00:22 carrer
* pydot.py:
Initial revision.
2004-04-08 00:22 carrer
* pydot.py: Initial revision
Copyright (c) 2004 Ero Carrera
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
pydot - Python interface to Graphviz's Dot language
Ero Carrera (c) 2004-2007
ero@dkbza.org
This code is distributed under the MIT license.
Requirements:
-------------
pyparsing: pydot requires the pyparsing module in order to be
able to load DOT files.
GraphViz: is needed in order to render the graphs into any of
the plethora of output formats supported.
Installation:
-------------
Should suffice with doing:
python setup.py install