%module pyabc // ------------------------------------------------------------------- // SWIG typemap allowing us to grab a Python callable object // ------------------------------------------------------------------- #ifdef SWIG %typemap(in) PyObject *PyFunc { if ( !PyCallable_Check($source) ) { PyErr_SetString(PyExc_TypeError, "Need a callable object!"); return NULL; } $target = $source; } #endif /* #ifdef SWIG */ %{ #include #include #include #include #include #include #include #include #include #include #include int n_ands() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); if ( pNtk && Abc_NtkIsStrash(pNtk) ) { return Abc_NtkNodeNum(pNtk); } return -1; } int n_nodes() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); if ( pNtk ) { return Abc_NtkNodeNum(pNtk); } return -1; } int n_pis() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); if ( pNtk ) { return Abc_NtkPiNum(pNtk); } return -1; } int n_pos() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); if ( pNtk ) { return Abc_NtkPoNum(pNtk); } return -1; } int n_latches() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); if ( pNtk ) { return Abc_NtkLatchNum(pNtk); } return -1; } int n_levels() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); if ( pNtk ) { return Abc_NtkLevel(pNtk); } return -1; } double n_area() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); if ( pNtk && Abc_NtkHasMapping(pNtk) ) { return Abc_NtkGetMappedArea(pNtk); } return -1; } int has_comb_model() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); return pNtk && pNtk->pModel; } int has_seq_model() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); return pNtk && pNtk->pSeqModel; } int n_bmc_frames() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); return Abc_FrameReadBmcFrames(pAbc); } int prob_status() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); return Abc_FrameReadProbStatus(pAbc); } int is_valid_cex() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); return pNtk && Abc_FrameReadCex(pAbc) && Abc_NtkIsValidCex( pNtk, Abc_FrameReadCex(pAbc) ); } int is_true_cex() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); return pNtk && Abc_FrameReadCex(pAbc) && Abc_NtkIsTrueCex( pNtk, Abc_FrameReadCex(pAbc) ); } int n_cex_pis() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); return Abc_FrameReadCex(pAbc) ? Abc_FrameReadCexPiNum( pAbc ) : -1; } int n_cex_regs() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); return Abc_FrameReadCex(pAbc) ? Abc_FrameReadCexRegNum( pAbc ) : -1; } int cex_po() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); return Abc_FrameReadCex(pAbc) ? Abc_FrameReadCexPo( pAbc ) : -1; } int cex_frame() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); return Abc_FrameReadCex(pAbc) ? Abc_FrameReadCexFrame( pAbc ) : -1; } int n_phases() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); return pNtk ? Abc_NtkPhaseFrameNum(pNtk) : 1; } int is_const_po( int iPoNum ) { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); return Abc_FrameCheckPoConst( pAbc, iPoNum ); } Abc_Cex_t* _cex_get() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Abc_Cex_t* pCex = Abc_FrameReadCex(pAbc); if ( ! pCex ) { return NULL; } return Abc_CexDup( pCex, -1 ); } int _cex_get_vec_len() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Vec_Ptr_t* vCexVec = Abc_FrameReadCexVec(pAbc); if( ! vCexVec ) { return 0; } return Vec_PtrSize(vCexVec); } Abc_Cex_t* _cex_get_vec(int i) { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Vec_Ptr_t* vCexVec = Abc_FrameReadCexVec(pAbc); if( ! vCexVec ) { return NULL; } Abc_Cex_t* pCex = (Abc_Cex_t*)Vec_PtrEntry( vCexVec, i ); if ( ! pCex ) { return NULL; } return Abc_CexDup( pCex, -1 ); } int _status_get_vec_len() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Vec_Int_t* vStatusVec = Abc_FrameReadStatusVec(pAbc); if( ! vStatusVec ) { return 0; } return Vec_IntSize(vStatusVec); } int _status_get_vec(int i) { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Vec_Int_t* vStatusVec = Abc_FrameReadStatusVec(pAbc); if( ! vStatusVec ) { return -1; } return Vec_IntEntry( vStatusVec, i ); } void _cex_put(Abc_Cex_t* pCex) { if ( pCex ) { pCex = Abc_CexDup(pCex, -1); } Abc_FrameSetCex( pCex ); } void _cex_free(Abc_Cex_t* pCex) { Abc_CexFree(pCex); } int _cex_n_regs(Abc_Cex_t* pCex) { return pCex->nRegs; } int _cex_n_pis(Abc_Cex_t* pCex) { return pCex->nPis; } int _cex_get_po(Abc_Cex_t* pCex) { return pCex->iPo; } int _cex_get_frame(Abc_Cex_t* pCex) { return pCex->iFrame; } static PyObject* VecInt_To_PyList(Vec_Int_t* v) { PyObject* pylist = PyList_New( Vec_IntSize(v) ); int elem, i; Vec_IntForEachEntry( v, elem, i) { PyList_SetItem( pylist, i, PyInt_FromLong(elem) ); } return pylist; } PyObject* eq_classes() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Vec_Ptr_t *vPoEquivs = Abc_FrameReadPoEquivs(pAbc); PyObject* eq_classes; Vec_Int_t* pEntry; int i; if( ! vPoEquivs ) { Py_RETURN_NONE; } eq_classes = PyList_New( Vec_PtrSize(vPoEquivs) ); Vec_PtrForEachEntry( Vec_Int_t*, vPoEquivs, pEntry, i ) { PyList_SetItem( eq_classes, i, VecInt_To_PyList(pEntry) ); } return eq_classes; } void _pyabc_array_clear() { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Vec_Int_t *vObjIds = Abc_FrameReadObjIds(pAbc); Vec_IntClear( vObjIds ); } void _pyabc_array_push(int i) { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Vec_Int_t *vObjIds = Abc_FrameReadObjIds(pAbc); Vec_IntPush( vObjIds, i ); } int pyabc_array_read_entry(int i) { Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); Vec_Int_t *vObjIds = Abc_FrameReadObjIds(pAbc); if( !vObjIds ) return -1; return Vec_IntEntry( vObjIds, i ); } static PyObject* pyabc_internal_python_command_callback = 0; void pyabc_internal_set_command_callback( PyObject* callback ) { Py_XINCREF(callback); Py_XDECREF(pyabc_internal_python_command_callback); pyabc_internal_python_command_callback = callback; } static int pyabc_internal_abc_command_callback(Abc_Frame_t * pAbc, int argc, char ** argv) { int i; PyObject* args; PyObject* arglist; PyObject* res; PyGILState_STATE gstate; long lres; if ( !pyabc_internal_python_command_callback ) return 0; gstate = PyGILState_Ensure(); args = PyList_New(argc); for( i=0 ; i0: return pid, status elif pid==0: return 0,0 elif pid == -1 and e == errno.ECHILD: return 0,0 elif pid==-1 and e != errno.EINTR: raise OSError(e, 'unknown error in wait3()') def _sigint_wait_thread_func(fd): global _die_flag while True: _retry_select(fd) _retry_read(fd) with _active_lock: if _die_flag: os._exit(-1) _die_flag = True for pid in _active_pids: rc = _posix_kill(pid, signal.SIGINT) for fname in _active_temp_files: os.remove(fname) os._exit(-1) def _child_wait_thread_func(fd): while True: _retry_select(fd) rc = _retry_read(fd) with _active_lock: while True: pid, status = _retry_wait() if pid==0: break if pid in _active_pids: _active_pids.remove(pid) _terminated_pids[pid] = status os.write(_wait_fd_write, "1") _terminated_pids_cond.notifyAll() _sigint_pipe_read_fd = -1 _sigint_pipe_write_fd = -1 _sigchld_pipe_read_fd = -1 _sigchld_pipe_write_fd = -1 wait_fd = -1 _wait_fd_write = -1 def _start_threads(): global wait_fd, _wait_fd_write wait_fd, _wait_fd_write = os.pipe() global _sigint_pipe_read_fd, _sigint_pipe_write_fd _sigint_pipe_read_fd, _sigint_pipe_write_fd = os.pipe() sigint_read = os.fdopen(_sigint_pipe_read_fd, "r", 0 ) sigint_wait_thread = threading.Thread(target=_sigint_wait_thread_func, name="SIGINT wait thread", args=(sigint_read,)) sigint_wait_thread.setDaemon(True) sigint_wait_thread.start() install_sigint_handler(_sigint_pipe_write_fd) global _sigchld_pipe_read_fd, _sigchld_pipe_write_fd _sigchld_pipe_read_fd, _sigchld_pipe_write_fd = os.pipe() sigchld_read = os.fdopen(_sigchld_pipe_read_fd, "r", 0 ) child_wait_thread = threading.Thread(target=_child_wait_thread_func, name="child process wait thread", args=(sigchld_read,)) child_wait_thread.setDaemon(True) child_wait_thread.start() install_sigchld_handler(_sigchld_pipe_write_fd) _close_on_fork = [] def close_on_fork(fd): _close_on_fork.append(fd) def after_fork(): _set_death_signal() global _close_on_fork for fd in _close_on_fork: os.close(fd) _close_on_fork = [] os.close(wait_fd) os.close(_wait_fd_write) os.close(_sigint_pipe_read_fd) os.close(_sigint_pipe_write_fd) os.close(_sigchld_pipe_read_fd) os.close(_sigchld_pipe_write_fd) global _active_lock _active_lock = threading.Lock() global _terminated_pids_cond _terminated_pids_cond = threading.Condition(_active_lock) global _terminated_pids _terminated_pids = {} global _active_pids _active_pids = set() global _active_temp_files _active_temp_files = set() _start_threads() class _sigint_block_section(object): def __init__(self): self.blocked = False def __enter__(self): block_sigint() self.blocked = True def __exit__(self, type, value, traceback): self.release() def release(self): if self.blocked: self.blocked = False unblock_sigint() _old_os_fork = os.fork def _fork(): ppid = os.getpid() with _sigint_block_section() as cs: with _active_lock: if _die_flag: os._exit(-1) pid = _old_os_fork() if pid == 0: after_fork() if pid > 0: _active_pids.add(pid) return pid def _waitpid(pid, options=0): while True: with _active_lock: if pid in _terminated_pids: _retry_os_read(wait_fd) status = _terminated_pids[pid] del _terminated_pids[pid] return pid, status if options==os.WNOHANG: return 0, 0 _terminated_pids_cond.wait() def _wait(options=0): while True: with _active_lock: for pid, status in _terminated_pids.iteritems(): _retry_os_read(wait_fd) del _terminated_pids[pid] return pid, status if options==os.WNOHANG: return 0, 0 _terminated_pids_cond.wait() _old_os_kill = os.kill def _kill(pid, sig): with _active_lock: if pid in _terminated_pids: return None return _old_os_kill(pid,sig) os.kill = _kill os.fork = _fork os.wait = _wait os.waitpid = _waitpid def _split_command_line(cmd): args = [] i=0 while i= len(cmd): break arg = [] in_quotes = None while i': with open(args[-1],'w') as fout: p = subprocess.Popen(args[:-2], stdout=fout) rc = p.wait() return rc else: p = subprocess.Popen(args) return p.wait() def tmpfile(prefix, suffix): with _active_lock: with tempfile.NamedTemporaryFile(delete=False, prefix=prefix, suffix=suffix) as file: _active_temp_files.add(file.name) return file.name def tmpfile_remove(fname, leave): with _active_lock: os.remove(fname) _active_temp_files.remove(fname) pyabc_internal_set_util_callbacks( system, tmpfile,tmpfile_remove ) _start_threads() _registered_commands = {} def _cmd_callback(args): try: assert len(args) > 0 cmd = args[0] assert cmd in _registered_commands res = _registered_commands[cmd](args) assert type(res) == int, "User-defined Python command must return an integer." return res except Exception, e: import traceback traceback.print_exc() except SystemExit, se: pass return 0 pyabc_internal_set_command_callback( _cmd_callback ) def add_abc_command(fcmd, group, cmd, change): _registered_commands[ cmd ] = fcmd pyabc_internal_register_command( group, cmd, change) import optparse xxx = {} def cmd_python(cmd_args): usage = "usage: %prog [options] " parser = optparse.OptionParser(usage, prog="python") parser.add_option("-c", "--cmd", dest="cmd", help="Execute Python command directly") parser.add_option("-v", "--version", action="store_true", dest="version", help="Display Python Version") options, args = parser.parse_args(cmd_args) if options.version: print sys.version return 0 if options.cmd: exec options.cmd in xxx return 0 scripts_dir = os.getenv('ABC_PYTHON_SCRIPTS', ".") scripts_dirs = scripts_dir.split(':') for fname in args[1:]: if os.path.isabs(fname): execfile(fname, xxx) else: for d in scripts_dirs: fname = os.path.join(scripts_dir, fname) if os.path.exists(fname): execfile(fname, xxx) break return 0 add_abc_command(cmd_python, "Python", "python", 0) %}