From 3162c84e953fb440525b4ba2b51a2401f5ddb3b4 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Thu, 19 Sep 2019 14:33:27 -0300 Subject: [PATCH] Implementing session attribute getter. --- .gitignore | 1 + py3270.cbp | 1 + src/include/py3270.h | 4 ++++ src/module/init.c | 40 +++++++++++++++++++++------------------- src/terminal/attributes.cc | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/terminal/init.cc | 30 ++++++++++++++++++++++++++++++ src/terminal/network.cc | 2 -- src/terminal/set.cc | 1 + testprograms/sample.py | 25 +++++++++++++++---------- 9 files changed, 165 insertions(+), 31 deletions(-) create mode 100644 src/terminal/attributes.cc diff --git a/.gitignore b/.gitignore index 000775a..c9be0e8 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ rpm/SPECS rpm/SRPMS scripts *.[0-9] +*.bak diff --git a/py3270.cbp b/py3270.cbp index 9112d78..ea6f8f2 100644 --- a/py3270.cbp +++ b/py3270.cbp @@ -51,6 +51,7 @@ + diff --git a/src/include/py3270.h b/src/include/py3270.h index c86b7dc..f667c65 100644 --- a/src/include/py3270.h +++ b/src/include/py3270.h @@ -97,6 +97,8 @@ Host *host; } pySession; + DLL_PRIVATE void py3270_session_type_init(PyTypeObject *type); + DLL_PRIVATE PyObject * py3270_get_module_version(PyObject *self, PyObject *args); DLL_PRIVATE PyObject * py3270_get_module_revision(PyObject *self, PyObject *args); @@ -106,6 +108,8 @@ DLL_PRIVATE int py3270_session_init(PyObject *self, PyObject *args, PyObject *kwds); DLL_PRIVATE void py3270_session_finalize(PyObject *self); + DLL_PRIVATE PyObject * py3270_session_getter(PyObject *self, void *name); + DLL_PRIVATE int py3270_session_setter(PyObject *self, PyObject *value, void *name); // DLL_PRIVATE PyObject * py3270_session_getattr(PyObject *self, char *attr_name); diff --git a/src/module/init.c b/src/module/init.c index 348b4e7..d67e269 100644 --- a/src/module/init.c +++ b/src/module/init.c @@ -31,6 +31,8 @@ #include + static void cleanup(PyObject *module); + /*---[ Globals ]------------------------------------------------------------------------------------*/ static PyMethodDef methods[] = { @@ -64,7 +66,8 @@ static struct PyModuleDef definition = { .m_name = "tn3270", // name of module .m_doc = PACKAGE_DESCRIPTION, // module documentation, may be NUL .m_size = -1, // size of per-interpreter state of the module or -1 if the module keeps state in global variables. - .m_methods = methods // Module methods + .m_methods = methods, // Module methods + .m_free = (freefunc) cleanup }; //# Tornar essa tabela pública e testar em getattr, se for um método usar PyMethod_New para retornar um método. @@ -106,15 +109,15 @@ static PyTypeObject SessionType = { .tp_methods = py3270_session_methods, -// .tp_alloc = -// .tp_free = -// .tp_getattr = py3270_session_getattr }; /*---[ Implement ]----------------------------------------------------------------------------------*/ PyMODINIT_FUNC PyInit_tn3270(void) { + // Initialize custom attributes & methods. + py3270_session_type_init(&SessionType); + // // Initialize module. // @@ -125,24 +128,11 @@ PyMODINIT_FUNC PyInit_tn3270(void) PyObject *module = PyModule_Create(&definition); + debug("Initializing module %p", module); + if(!module) return NULL; - /* - // - // Create exception object - // - PyObject * except = PyErr_NewException("tn3270.Error", NULL, NULL); - - Py_XINCREF(except); - if (PyModule_AddObject(module, "error", except) < 0) { - Py_XDECREF(except); - Py_CLEAR(except); - Py_DECREF(module); - return NULL; - } - */ - // // Create custom type // @@ -155,3 +145,15 @@ PyMODINIT_FUNC PyInit_tn3270(void) return module; } + +static void cleanup(PyObject *module) { + + debug("Cleaning up module %p", module); + + if(SessionType.tp_getset) { + free(SessionType.tp_getset); + SessionType.tp_getset = NULL; + } + +} + diff --git a/src/terminal/attributes.cc b/src/terminal/attributes.cc new file mode 100644 index 0000000..1c36e39 --- /dev/null +++ b/src/terminal/attributes.cc @@ -0,0 +1,92 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como get.cc e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + * Referências: + * + * + * + * + */ + + #include + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + +PyObject * py3270_session_getter(PyObject *self, void *name) { + + debug("%s(%s)",__FUNCTION__,(const char *) name); + + return py3270_session_call(self, [name](TN3270::Host &host){ + + auto attribute = host[(const char *) name]; + + switch(attribute.getType()) { + case TN3270::Attribute::String: + return PyUnicode_FromString(attribute.toString().c_str()); + + case TN3270::Attribute::Boolean: + return PyBool_FromLong(attribute.getBoolean()); + + case TN3270::Attribute::Uchar: + throw std::system_error(ENOTSUP, std::system_category()); + + case TN3270::Attribute::Int16: + throw std::system_error(ENOTSUP, std::system_category()); + + case TN3270::Attribute::Uint16: + throw std::system_error(ENOTSUP, std::system_category()); + + case TN3270::Attribute::Int32: + return PyLong_FromLong(attribute.getInt32()); + + case TN3270::Attribute::Int32x: + throw std::system_error(ENOTSUP, std::system_category()); + + case TN3270::Attribute::Uint32: + return PyLong_FromLong(attribute.getUint32()); + + case TN3270::Attribute::Int64: + throw std::system_error(ENOTSUP, std::system_category()); + + case TN3270::Attribute::Uint64: + throw std::system_error(ENOTSUP, std::system_category()); + + default: + throw runtime_error("Unexpected atttribute type"); + } + + return PyLong_FromLong(0); + + }); + +} + +int py3270_session_setter(PyObject *self, PyObject *value, void *name) { + + return 0; +} + diff --git a/src/terminal/init.cc b/src/terminal/init.cc index c75ba50..bf0629d 100644 --- a/src/terminal/init.cc +++ b/src/terminal/init.cc @@ -35,6 +35,7 @@ */ #include + #include /*---[ Implement ]----------------------------------------------------------------------------------*/ @@ -47,6 +48,35 @@ static void cleanup(pySession * session) { } +void py3270_session_type_init(PyTypeObject *type) { + + // Load lib3270's attributes + { + auto attributes = TN3270::getAttributes(); + size_t szData = sizeof(struct PyGetSetDef) * (attributes.size()+1); + + type->tp_getset = (struct PyGetSetDef *) malloc(szData); + memset(type->tp_getset,0,szData); + + size_t ix = 0; + for(auto attribute : attributes) { + + debug("Creating attribute %s",attribute->name); + + type->tp_getset[ix].name = (char *) attribute->name; + type->tp_getset[ix].doc = (char *) (attribute->description ? attribute->description : attribute->summary); + type->tp_getset[ix].get = py3270_session_getter; + type->tp_getset[ix].set = py3270_session_setter; + type->tp_getset[ix].closure = (void *) attribute->name; + ix++; + } + + + } + +} + + int py3270_session_init(PyObject *self, PyObject *args, PyObject *kwds) { pySession * session = (pySession *) self; diff --git a/src/terminal/network.cc b/src/terminal/network.cc index afbce2a..45b1ba1 100644 --- a/src/terminal/network.cc +++ b/src/terminal/network.cc @@ -40,8 +40,6 @@ PyObject * py3270_session_connect(PyObject *self, PyObject *args) { - printf("\n\n*************%s\n\n",__FUNCTION__); - return py3270_session_call(self, [args](TN3270::Host &host){ const char * url = ""; diff --git a/src/terminal/set.cc b/src/terminal/set.cc index 6a6b963..86b752c 100644 --- a/src/terminal/set.cc +++ b/src/terminal/set.cc @@ -36,6 +36,7 @@ /*---[ Implement ]----------------------------------------------------------------------------------*/ + /* PyObject * terminal_set_string_at(PyObject *self, PyObject *args) { diff --git a/testprograms/sample.py b/testprograms/sample.py index d8e7f3b..b4bf282 100644 --- a/testprograms/sample.py +++ b/testprograms/sample.py @@ -1,7 +1,7 @@ #!/usr/bin/python #-*- coding: utf-8 -import weakref +import inspect import tn3270 print("Teste extensão pw3270") @@ -11,20 +11,22 @@ print(tn3270.revision()) session = tn3270.Session("") -del session +print("Using tn3270 version " + session.version + " revision " + session.revision) -input("Press enter to exit") +print(session.cstate) +print(session.width) +print(session.connected) +print(session.url) + +session.connect('') -#print("Using tn3270 version " + session.version + " revision " + session.revision) +print(session.connected) -#print(session.cstate) -#print(session.width) -#print(session.connected) -#print(session.url) +print('----------------------') +inspect.getmembers(session) +print('----------------------') -# print(session.connect) -#print(session.connected) #print term.IsConnected() #print term.IsReady() @@ -35,6 +37,9 @@ input("Press enter to exit") #print term #print "-----------------------------------------------------------------------" +del session +input("Press enter to exit") + -- libgit2 0.21.2