#include "stdafx.h" #include "Match.h" #include "GroupNotFoundException.h" namespace NppPythonScript { boost::python::str Match::py_group_number(int groupNumber) { GroupDetail *groupDetail = group(groupNumber); if (NULL == groupDetail) { throw GroupNotFoundException("no such group"); } return boost::python::str(getTextForGroup(group(groupNumber))); } boost::python::str Match::py_group_name(boost::python::str pyGroupName) { std::string stringGroupName(boost::python::extract(pyGroupName.attr("__str__")())); GroupDetail *groupDetail = groupName(stringGroupName.c_str()); if (NULL == groupDetail) { throw GroupNotFoundException("no such group"); } return boost::python::str(getTextForGroup(groupDetail)); } boost::python::str Match::getGroup(boost::python::object groupIdentifier) { if (PyInt_Check(groupIdentifier.ptr())) { return py_group_number(boost::python::extract(groupIdentifier)); } else if (PyString_Check(groupIdentifier.ptr())) { return py_group_name(boost::python::extract(groupIdentifier)); } else { return py_group_name(boost::python::extract(groupIdentifier.attr("__str__"))); } } boost::python::str Match::py_expand(boost::python::object replaceFormat) { char *result; size_t resultLength; expand(boost::python::extract(replaceFormat.attr("__str__")()), &result, &resultLength); boost::python::str pyResult(const_cast(result)); delete [] result; return pyResult; } int Match::py_start(int groupIndex) { GroupDetail *groupDetail = group(groupIndex); int result = -1; if (groupDetail && groupDetail->matched()) { result = groupDetail->start(); } return result; } int Match::py_start_name(boost::python::str groupName) { GroupDetail *groupDetail = this->groupName(boost::python::extract(groupName)); int result = -1; if (groupDetail && groupDetail->matched()) { result = groupDetail->start(); } return result; } int Match::py_end(int groupIndex) { GroupDetail *groupDetail = group(groupIndex); int result = -1; if (groupDetail && groupDetail->matched()) { result = groupDetail->end(); } return result; } int Match::py_end_name(boost::python::str groupName) { GroupDetail *groupDetail = this->groupName(boost::python::extract(groupName)); int result = -1; if (groupDetail && groupDetail->matched()) { result = groupDetail->end(); } return result; } boost::python::tuple Match::py_span(int groupIndex) { return boost::python::make_tuple(py_start(groupIndex), py_end(groupIndex)); } boost::python::tuple Match::py_span_name(boost::python::str groupName) { return boost::python::make_tuple(py_start_name(groupName), py_end_name(groupName)); } int Match::py_lastindex() { int lastGroup = groupCount() - 1; while(lastGroup > 0 && !group(lastGroup)->matched()) --lastGroup; return lastGroup; } boost::python::tuple Match::py_groups() { size_t size = groupCount(); PyObject* groupsTuple = PyTuple_New(size - 1); for(int index = 1; index != size; ++index) { boost::python::str groupContent = py_group_number(index); // PyTuple_SetItem steals a reference, but because it's a boost::python::object, it'll be Py_DECREF'd by the next iteration Py_INCREF(groupContent.ptr()); PyTuple_SetItem(groupsTuple, index - 1, groupContent.ptr()); } return boost::python::tuple(boost::python::handle(groupsTuple)); } boost::python::object py_group_variable(boost::python::tuple args, boost::python::dict kwargs) { Match *match = boost::python::extract(args[0]); return match->py_group_variable(boost::python::tuple(args.slice(1, boost::python::len(args))), kwargs); } boost::python::object Match::py_group_variable(boost::python::tuple args, boost::python::dict kwargs) { size_t size = boost::python::len(args); // For the default case, no arguments, return the whole match if (size == 0) { return py_group_number(0); } // If only one argument is specified, then we return the content of that group if (size == 1) { if (PyNumber_Check(boost::python::object(args[0]).ptr())) { return py_group_number(boost::python::extract(args[0])); } else { return py_group_name(boost::python::str(args[0])); } } // If more than one argument is specified, then we return a tuple with group contents in order of the arguments specified PyObject* groupsTuple = PyTuple_New(size); for(int index = 0; index != size; ++index) { boost::python::str groupContent; if (PyNumber_Check(boost::python::object(args[index]).ptr())) { groupContent = py_group_number(boost::python::extract(args[index])); } else { groupContent = py_group_name(boost::python::str(args[index])); } // PyTuple_SetItem steals a reference, but because it's a boost::python::object, it'll be Py_DECREF'd by the next iteration Py_INCREF(groupContent.ptr()); PyTuple_SetItem(groupsTuple, index, groupContent.ptr()); } return boost::python::tuple(boost::python::handle(groupsTuple)); } }