Export Catalog::State creation support to Python.

* New: In CRL::PyCatalog, add the second parameter "add" to getState()
    so we can request the creation of the state if needed.
* New: In CRL::PyCatalogState, export setCell() and setInMemory() methods.
* Bug: In CRL::Subckt::createModel(), when a cell has a State entry in
    the catalog, also check that it really has a Cell loaded in memory.
    If not, throw an exception (and do not crash).
This commit is contained in:
Jean-Paul Chaput 2021-04-28 12:58:47 +02:00
parent 39d8aa479e
commit dcfba9ef18
4 changed files with 42 additions and 4 deletions

View File

@ -57,6 +57,7 @@ namespace CRL {
if (_cell) { if (_cell) {
if (isPad ()) _cell->setPad ( true ); if (isPad ()) _cell->setPad ( true );
if (isFeed()) _cell->setFeed( true ); if (isFeed()) _cell->setFeed( true );
_library = _cell->getLibrary();
} }
return _cell; return _cell;
} }

View File

@ -303,7 +303,11 @@ namespace {
if (af->isInCatalog(modelName)) { if (af->isInCatalog(modelName)) {
model = Model::find( modelName ); model = Model::find( modelName );
if (not model) { if (not model) {
model = new Model ( af->getCell( modelName, Catalog::State::Views, 0 ) ); cell = af->getCell( modelName, Catalog::State::Views, 0 );
if (not cell)
throw Error( "Subckt::createModel(): Cell \"%s\" has a catalog entry but is not loaded."
, modelName.c_str() );
model = new Model ( cell );
} }
} }
} else { } else {

View File

@ -69,13 +69,15 @@ extern "C" {
char* name = NULL; char* name = NULL;
Catalog::State* state = NULL; Catalog::State* state = NULL;
PyObject* pyAdd = NULL;
HTRY HTRY
METHOD_HEAD("Catalog.getState()") METHOD_HEAD("Catalog.getState()")
if ( not PyArg_ParseTuple(args,"s",&name) ) { if ( not PyArg_ParseTuple(args,"s|O:Catalog.getState",&name,&pyAdd) ) {
PyErr_SetString( ConstructorError, "Catalog.getState(): Invalid number or bad type of parameters."); PyErr_SetString( ConstructorError, "Catalog.getState(): Invalid number or bad type of parameters.");
return NULL; return NULL;
} }
state = catalog->getState( Name(name) ); bool add = (pyAdd) and PyObject_IsTrue(pyAdd);
state = catalog->getState( Name(name), add );
HCATCH HCATCH
if (not state) Py_RETURN_FALSE; if (not state) Py_RETURN_FALSE;
return PyCatalogState_Link(state); return PyCatalogState_Link(state);

View File

@ -43,12 +43,13 @@ namespace CRL {
using Isobar::PyLibrary_Link; using Isobar::PyLibrary_Link;
using Isobar::PyCell; using Isobar::PyCell;
using Isobar::PyCell_Link; using Isobar::PyCell_Link;
using Isobar::PyTypeCell;
extern "C" { extern "C" {
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(CatalogState,state,function) #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Catalog::State,state,function)
// x=================================================================x // x=================================================================x
@ -65,6 +66,7 @@ extern "C" {
DirectGetBoolAttribute(PyCatalogState_isDelete ,isDelete ,PyCatalogState,Catalog::State) DirectGetBoolAttribute(PyCatalogState_isDelete ,isDelete ,PyCatalogState,Catalog::State)
DirectGetBoolAttribute(PyCatalogState_isPhysical ,isPhysical ,PyCatalogState,Catalog::State) DirectGetBoolAttribute(PyCatalogState_isPhysical ,isPhysical ,PyCatalogState,Catalog::State)
DirectGetBoolAttribute(PyCatalogState_isLogical ,isLogical ,PyCatalogState,Catalog::State) DirectGetBoolAttribute(PyCatalogState_isLogical ,isLogical ,PyCatalogState,Catalog::State)
DirectGetBoolAttribute(PyCatalogState_isInMemory ,isInMemory ,PyCatalogState,Catalog::State)
DirectSetBoolAttribute(PyCatalogState_setTerminalNetlist,setTerminalNetlist,PyCatalogState,Catalog::State) DirectSetBoolAttribute(PyCatalogState_setTerminalNetlist,setTerminalNetlist,PyCatalogState,Catalog::State)
DirectSetBoolAttribute(PyCatalogState_setFeed ,setFeed ,PyCatalogState,Catalog::State) DirectSetBoolAttribute(PyCatalogState_setFeed ,setFeed ,PyCatalogState,Catalog::State)
@ -72,6 +74,29 @@ extern "C" {
DirectSetBoolAttribute(PyCatalogState_setDelete ,setDelete ,PyCatalogState,Catalog::State) DirectSetBoolAttribute(PyCatalogState_setDelete ,setDelete ,PyCatalogState,Catalog::State)
DirectSetBoolAttribute(PyCatalogState_setPhysical ,setPhysical ,PyCatalogState,Catalog::State) DirectSetBoolAttribute(PyCatalogState_setPhysical ,setPhysical ,PyCatalogState,Catalog::State)
DirectSetBoolAttribute(PyCatalogState_setLogical ,setLogical ,PyCatalogState,Catalog::State) DirectSetBoolAttribute(PyCatalogState_setLogical ,setLogical ,PyCatalogState,Catalog::State)
DirectSetBoolAttribute(PyCatalogState_setInMemory ,setInMemory ,PyCatalogState,Catalog::State)
static PyObject* PyCatalogState_setCell ( PyCatalogState* self, PyObject* args )
{
cdebug_log(20,0) << "PyCatalogState.setCell()" << endl;
METHOD_HEAD("PyCatalogState.setCell()")
HTRY
PyObject* pyCell = NULL;
if (PyArg_ParseTuple(args,"O:State.setCell()",&pyCell) ) {
if (not IsPyCell(pyCell)) {
PyErr_SetString ( ConstructorError, "State.setCell(): Argument is not of type Cell." );
return NULL;
}
state->setCell( PYCELL_O(pyCell) );
} else {
PyErr_SetString ( ConstructorError, "Bad parameters given to State.setCell()." );
return NULL;
}
HCATCH
Py_RETURN_NONE;
}
// Standart Destroy (Attribute). // Standart Destroy (Attribute).
@ -91,6 +116,10 @@ extern "C" {
, "Return true if the Cell possesses a physical (layout) view." } , "Return true if the Cell possesses a physical (layout) view." }
, { "isLogical" , (PyCFunction)PyCatalogState_isLogical, METH_NOARGS , { "isLogical" , (PyCFunction)PyCatalogState_isLogical, METH_NOARGS
, "Return true if the Cell possesses a logical (netlist) view." } , "Return true if the Cell possesses a logical (netlist) view." }
, { "isInMemory" , (PyCFunction)PyCatalogState_isInMemory, METH_NOARGS
, "Return true if the Cell is already loaded in memory." }
, { "setCell" , (PyCFunction)PyCatalogState_setCell, METH_VARARGS
, "Set the cell associated with this state." }
, { "setTerminalNetlist", (PyCFunction)PyCatalogState_setTerminalNetlist, METH_VARARGS , { "setTerminalNetlist", (PyCFunction)PyCatalogState_setTerminalNetlist, METH_VARARGS
, "Sets/reset the TerminalNetlist flag of a Cell." } , "Sets/reset the TerminalNetlist flag of a Cell." }
, { "setFeed" , (PyCFunction)PyCatalogState_setFeed, METH_VARARGS , { "setFeed" , (PyCFunction)PyCatalogState_setFeed, METH_VARARGS
@ -103,6 +132,8 @@ extern "C" {
, "Sets/reset the Pysical flag of a Cell." } , "Sets/reset the Pysical flag of a Cell." }
, { "setLogical" , (PyCFunction)PyCatalogState_setLogical, METH_VARARGS , { "setLogical" , (PyCFunction)PyCatalogState_setLogical, METH_VARARGS
, "Sets/reset the Logical flag of a Cell." } , "Sets/reset the Logical flag of a Cell." }
, { "setInMemory" , (PyCFunction)PyCatalogState_setInMemory, METH_VARARGS
, "Sets/reset the in memory flag of a Cell." }
, {NULL, NULL, 0, NULL} /* sentinel */ , {NULL, NULL, 0, NULL} /* sentinel */
}; };