boost::python::object NotepadPlusWrapper::prompt(boost::python::object promptObj, boost::python::object title, boost::python::object initial) { PromptDialog promptDlg(m_hInst, m_nppHandle); const char *cPrompt = NULL; const char *cTitle = NULL; const char *cInitial = NULL; if (!promptObj | !promptObj.is_none()) cPrompt = (const char *)boost::python::extract<const char *>(promptObj.attr("__str__")()); if (!title | !title.is_none()) cTitle= (const char *)boost::python::extract<const char *>(title.attr("__str__")()); if (!initial | !initial.is_none()) cInitial = (const char *)boost::python::extract<const char *>(initial.attr("__str__")()); PromptDialog::PROMPT_RESULT result; GILRelease release; result = promptDlg.showPrompt(cPrompt, cTitle, cInitial); release.reacquire(); if (PromptDialog::RESULT_OK == result) { return boost::python::str(promptDlg.getText()); } else { return boost::python::object(); } }
boost::python::str ScintillaWrapper::getWord(boost::python::object position, boost::python::object useOnlyWordChars /* = true */) { int pos; if (position.is_none()) { pos = callScintilla(SCI_GETCURRENTPOS); } else { pos = boost::python::extract<int>(position); } bool wordChars; if (useOnlyWordChars.is_none()) { wordChars = true; } else { wordChars = boost::python::extract<bool>(useOnlyWordChars); } int startPos = callScintilla(SCI_WORDSTARTPOSITION, pos, wordChars); int endPos = callScintilla(SCI_WORDENDPOSITION, pos, wordChars); Sci_TextRange tr; tr.chrg.cpMin = startPos; tr.chrg.cpMax = endPos; tr.lpstrText = new char[size_t((endPos - startPos) + 1)]; callScintilla(SCI_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&tr)); boost::python::str retVal(const_cast<const char *>(tr.lpstrText)); delete[] tr.lpstrText; return retVal; }
void ScintillaWrapper::replace(boost::python::object searchStr, boost::python::object replaceStr, boost::python::object flags) { int start = 0; int end = GetLength(); int iFlags = 0; if (!flags.is_none()) { iFlags |= boost::python::extract<int>(flags); } const char *replaceChars = boost::python::extract<const char*>(replaceStr.attr("__str__")()); size_t replaceLength = strlen(replaceChars); Sci_TextToFind src; src.lpstrText = const_cast<char*>((const char *)boost::python::extract<const char *>(searchStr.attr("__str__")())); BeginUndoAction(); int result = 0; while(result != -1) { src.chrg.cpMin = start; src.chrg.cpMax = end; result = callScintilla(SCI_FINDTEXT, iFlags, reinterpret_cast<LPARAM>(&src)); // If nothing found, then just finish if (-1 == result) { return; } else { // Replace the location found with the replacement text SetTargetStart(src.chrgText.cpMin); SetTargetEnd(src.chrgText.cpMax); callScintilla(SCI_REPLACETARGET, replaceLength, reinterpret_cast<LPARAM>(replaceChars)); start = src.chrgText.cpMin + (int)replaceLength; end = end + ((int)replaceLength - (src.chrgText.cpMax - src.chrgText.cpMin)); } } EndUndoAction(); }
h::Stage func_setitem_operator1(h::Func &that, p::object arg_passed, T right_hand) { p::tuple args_passed; p::extract<p::tuple> tuple_extract(arg_passed); if(tuple_extract.check()) { args_passed = tuple_extract(); } else if(arg_passed.is_none()) { // args_passed tuple is left empty } else { args_passed = p::make_tuple(arg_passed); } return func_setitem_operator0(that, args_passed, right_hand); }
void ScintillaWrapper::pymlsearch(boost::python::object searchExp, boost::python::object callback, boost::python::object flags, boost::python::object startPosition, boost::python::object endPosition) { boost::python::object re_module( (boost::python::handle<>(PyImport_ImportModule("re"))) ); if (!re_module.is_none()) { boost::python::str contents; contents = GetText(); int iFlags = 0; if (!flags.is_none()) { iFlags = boost::python::extract<int>(flags); } iFlags |= boost::python::extract<int>(re_module.attr("MULTILINE")); boost::python::object re = re_module.attr("compile")(searchExp, iFlags); boost::python::object match; int pos = 0; if (!startPosition.is_none()) { pos = boost::python::extract<int>(startPosition); } int endPos = 0; if (!endPosition.is_none()) { endPos = boost::python::extract<int>(endPosition); } bool endPosFixed = true; if (endPos == 0) { endPos = GetLength(); endPosFixed = false; } int line; do { match = re.attr("search")(contents, pos, endPos); // If nothing found, then skip if (!match.is_none()) { pos = boost::python::extract<int>(match.attr("start")()); line = LineFromPosition(pos); boost::python::object result = callback(line, match); // If return value was false, then stop the search if (!result.is_none() && !boost::python::extract<bool>(result)) { return; } if (!endPosFixed) { endPos = GetLength(); } pos = boost::python::extract<int>(match.attr("end")()); } } while (!match.is_none()); } // end re_module check }
void ScintillaWrapper::pysearch(boost::python::object searchExp, boost::python::object callback, boost::python::object flags, boost::python::object startLine, boost::python::object endLine) { boost::python::object re_module( (boost::python::handle<>(PyImport_ImportModule("re"))) ); if (!re_module.is_none()) { int start = 0; if (!startLine.is_none()) { start = boost::python::extract<int>(startLine); } int end; int lineCount = GetLineCount(); bool endFixed = false; if (!endLine.is_none()) { endFixed = true; end = boost::python::extract<int>(endLine); } else { end = lineCount - 1; } boost::python::object re = re_module.attr("compile")(searchExp, flags); bool called; boost::python::object match; for(int line = start; line <= end && line < lineCount; ++line) { int pos = 0; called = false; do { match = re.attr("search")(GetLine(line), pos); // If nothing found, then continue to next line if (!match.is_none()) { boost::python::object result = callback(line, match); // If return value was false, then stop the search if (!result.is_none() && !boost::python::extract<bool>(result)) { return; } pos = boost::python::extract<int>(match.attr("end")()); called = true; } } while (!match.is_none()); // If we called the user function, update the lineCount // (...Who knows what they've done!) :) if (called) { lineCount = GetLineCount(); if (!endFixed) end = lineCount - 1; } } // end line loop } // end re_module check }
void ScintillaWrapper::pyreplace(boost::python::object searchExp, boost::python::object replaceStr, boost::python::object count, boost::python::object flags, boost::python::object startLine, boost::python::object endLine) { boost::python::object re_module( (boost::python::handle<>(PyImport_ImportModule("re"))) ); if (!re_module.is_none()) { BeginUndoAction(); const char *strCount = boost::python::extract<const char *>(count.attr("__str__")()); int iCount; int iFlags = 0; if (!flags.is_none()) { iFlags = boost::python::extract<int>(flags); } int start = 0; if (!startLine.is_none()) { start = boost::python::extract<int>(startLine); } int end = -1; if (!startLine.is_none()) { end = boost::python::extract<int>(endLine); } iCount = atoi(strCount); bool ignoreCount = (iCount == 0); bool includeLineEndings = (iFlags & RE_INCLUDELINEENDINGS) == RE_INCLUDELINEENDINGS; long lineCount = GetLineCount(); boost::python::object re = re_module.attr("compile")(searchExp, flags); size_t bufferLength = 0; Sci_TextRange range; range.chrg.cpMin = 0; range.lpstrText = NULL; boost::python::tuple result; idx_t currentStartPosition; int infiniteLoopCheck = 0; int previousLine = -1; for(int line = start; line < lineCount && (ignoreCount || iCount > 0) && (-1 == end || line <= end); ++line) { if (line == previousLine) { if (++infiniteLoopCheck >= 1000) { EndUndoAction(); PyErr_SetString(PyExc_SystemError, "Infinite loop detected in pyreplace"); if (range.lpstrText) { delete[] range.lpstrText; } throw boost::python::error_already_set(); } } previousLine = line; if (includeLineEndings) { result = boost::python::extract<boost::python::tuple>(re.attr("subn")(replaceStr, GetLine(line), ignoreCount ? 0 : iCount)); } else { range.chrg.cpMin = PositionFromLine(line); range.chrg.cpMax = GetLineEndPosition(line); if (bufferLength < (size_t)((range.chrg.cpMax - range.chrg.cpMin) + 1)) { if (range.lpstrText) delete [] range.lpstrText; bufferLength = (size_t)((range.chrg.cpMax - range.chrg.cpMin) + 1); range.lpstrText = new char[bufferLength + 1]; } callScintilla(SCI_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&range)); result = boost::python::extract<boost::python::tuple>(re.attr("subn")(replaceStr, const_cast<const char *>(range.lpstrText), ignoreCount ? 0 : iCount)); } int numSubs = boost::python::extract<int>(result[1]); if (numSubs != 0) { size_t resultLength = _len(result[0]); if (includeLineEndings) { currentStartPosition = (idx_t)PositionFromLine(line); replaceWholeLine(line, result[0]); } else { currentStartPosition = (idx_t)range.chrg.cpMin; replaceLine(line, result[0]); } int newLine = LineFromPosition((int)(currentStartPosition + resultLength)); // If the line number has moved on more than one // there must have been one or more new lines in the // replacement, or no newline, hence the lines have become less if ((newLine - line) != (includeLineEndings ? 1 : 0)) { line = newLine - (includeLineEndings ? 1 : 0); lineCount = GetLineCount(); } iCount -= numSubs; } } if (range.lpstrText) delete[] range.lpstrText; EndUndoAction(); } }
void ScintillaWrapper::pymlreplace(boost::python::object searchExp, boost::python::object replaceStr, boost::python::object count, boost::python::object flags, boost::python::object startPosition, boost::python::object endPosition) { boost::python::str contents; offset_t currentOffset = 0; if (startPosition.is_none() && endPosition.is_none()) { contents = GetCharacterPointer(); } else { Sci_TextRange range; if (!startPosition.is_none()) { range.chrg.cpMin = boost::python::extract<int>(startPosition); } else { range.chrg.cpMin = 0; } if (!endPosition.is_none()) { range.chrg.cpMax = boost::python::extract<int>(endPosition); } else { range.chrg.cpMax = GetLength(); } currentOffset = (offset_t)range.chrg.cpMin; range.lpstrText = new char[size_t((range.chrg.cpMax - range.chrg.cpMin) + 1)]; callScintilla(SCI_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&range)); contents = boost::python::str(const_cast<const char *>(range.lpstrText)); delete[] range.lpstrText; } boost::python::object re_module( (boost::python::handle<>(PyImport_ImportModule("re"))) ); int iFlags = 0; int iCount = 0; if (!flags.is_none()) { iFlags = boost::python::extract<int>(flags); } if (!count.is_none()) { iCount = boost::python::extract<int>(count); } if (0 == iCount) iCount = -1; boost::python::object re = re_module.attr("compile")(searchExp, iFlags | boost::python::extract<int>(re_module.attr("MULTILINE"))); if (!re_module.is_none()) { boost::python::object match; BeginUndoAction(); boost::python::object oreplacement; size_t replacementLength; idx_t matchStart, matchEnd; idx_t startPos = 0; do { match = re.attr("search")(contents, startPos); if (!match.is_none()) { // Get expanded replacement string oreplacement = match.attr("expand")(replaceStr); // Calculate offsets matchStart = (idx_t)boost::python::extract<int>(match.attr("start")()); matchEnd = (idx_t)boost::python::extract<int>(match.attr("end")()); // Extract text replacement const char *replacement = boost::python::extract<const char *>(oreplacement); replacementLength = _len(oreplacement); // Replace text in Scintilla callScintilla(SCI_SETTARGETSTART, static_cast<offset_t>(matchStart) + currentOffset); callScintilla(SCI_SETTARGETEND, static_cast<offset_t>(matchEnd) + currentOffset); callScintilla(SCI_REPLACETARGET, replacementLength, reinterpret_cast<LPARAM>(replacement)); // Calculate the difference between the old string, // and the new replacement, and add it to the currentOffset currentOffset += static_cast<offset_t>(replacementLength - (matchEnd - matchStart)); // Set startPos to the end of the last match - startPos is with the original document startPos = matchEnd; } } while(!match.is_none() && (iCount == -1 || --iCount > 0)); EndUndoAction(); } }
Datum convert_python_to_datum(const boost::python::object &obj) { ScopedRecursionGuard srg(" while converting Python object to MWorks datum"); if (obj.is_none()) { return Datum(); } PyObject *pObj = obj.ptr(); if (PyBool_Check(pObj)) { return Datum(bool(pObj == Py_True)); } else if (PyArray_IsScalar(pObj, Bool)) { return Datum(bool(PyObject_IsTrue(pObj))); } else if (PyInt_Check(pObj)) { // Must come *after* PyBool_Check long l_val = PyInt_AsLong(pObj); if ((l_val == -1) && PyErr_Occurred()) throw_error_already_set(); return Datum(l_val); } else if (PyArray_IsScalar(pObj, Integer)) { return convert_python_to_datum(manageNewRef(PyNumber_Int(pObj))); } else if (PyLong_Check(pObj)) { long long ll_val = PyLong_AsLongLong(pObj); if ((ll_val == -1) && PyErr_Occurred()) throw_error_already_set(); return Datum(ll_val); } else if (PyFloat_Check(pObj)) { double value = PyFloat_AsDouble(pObj); if ((value == -1.0) && PyErr_Occurred()) throw_error_already_set(); return Datum(value); } else if (PyArray_IsScalar(pObj, Floating)) { return convert_python_to_datum(manageNewRef(PyNumber_Float(pObj))); } else if (PyString_Check(pObj) || PyUnicode_Check(pObj)) { boost::python::object string; if (!PyUnicode_Check(pObj)) { string = obj; } else { string = manageNewRef( PyUnicode_AsUTF8String(pObj) ); } char *buffer; Py_ssize_t size; if (PyString_AsStringAndSize(string.ptr(), &buffer, &size)) throw_error_already_set(); return Datum(buffer, int(size)); } else if (PyMapping_Check(pObj)) { int size = int(PyMapping_Size(pObj)); if (size == -1) throw_error_already_set(); Datum dict(M_DICTIONARY, size); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wwritable-strings" boost::python::object keys = manageNewRef( PyMapping_Keys(pObj) ); boost::python::object values = manageNewRef( PyMapping_Values(pObj) ); #pragma clang diagnostic pop for (int i = 0; i < size; i++) { dict.addElement(convert_python_to_datum(manageBorrowedRef( PyList_GetItem(keys.ptr(), i) )), convert_python_to_datum(manageBorrowedRef( PyList_GetItem(values.ptr(), i) ))); } return dict; } else if (PySequence_Check(pObj)) { // Must come *after* PyString_Check, PyUnicode_Check, and PyMapping_Check int size = int(PySequence_Size(pObj)); if (size == -1) throw_error_already_set(); Datum list(M_LIST, size); for (int i = 0; i < size; i++) { list.setElement(i, convert_python_to_datum(manageNewRef(PySequence_GetItem(pObj, i)))); } return list; } PyErr_Format(PyExc_TypeError, "Cannot convert object of type %s", pObj->ob_type->tp_name); throw_error_already_set(); return Datum(); // Never reached }