diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp
index 6f94e3040..2bed802bb 100644
--- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp
+++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp
@@ -15,6 +15,7 @@
// along with this program. If not, see .
#include
+#include
#include
#include
#include
@@ -163,11 +164,9 @@ LanguageNameInfo ScintillaEditView::_langNameInfoArray[L_EXTERNAL + 1] = {
};
-int getNbDigits(int aNum, int base)
+size_t getNbDigits(size_t aNum, size_t base)
{
- if (base <= 0) return 0;
-
- int nbDigits = 0;
+ size_t nbDigits = 0;
do
{
@@ -3658,92 +3657,6 @@ bool ScintillaEditView::expandWordSelection()
return false;
}
-TCHAR* int2str(TCHAR* str, int strLen, int number, int base, int nbDigits, ColumnEditorParam::leadingChoice lead)
-{
- if (nbDigits <= 0 || nbDigits >= strLen) return NULL;
-
- if (base == 2)
- {
- const unsigned int MASK_ULONG_BITFORT = 0x80000000;
- int nbBits = sizeof(unsigned int) * 8;
- int nbBit2Shift = (nbDigits >= nbBits) ? nbBits : (nbBits - nbDigits);
- unsigned long mask = MASK_ULONG_BITFORT >> nbBit2Shift;
- int i = 0;
- for (; mask > 0; ++i)
- {
- str[i] = (mask & number) ? '1' : '0';
- mask >>= 1;
- }
- str[i] = '\0';
- // str is now leading zero padded
-
- if (lead == ColumnEditorParam::spaceLeading)
- {
- // replace leading zeros with spaces
- for (TCHAR* j = str; *j != '\0'; ++j)
- {
- if ((*j == '1') || (*(j + 1) == '\0'))
- {
- break;
- }
- else
- {
- *j = ' ';
- }
- }
- }
- else if (lead != ColumnEditorParam::zeroLeading)
- {
- // left-align within the field width, i.e. pad on right with space
-
- // first, remove leading zeros
- for (TCHAR* j = str; *j != '\0'; ++j)
- {
- if (*j == '1' || *(j + 1) == '\0')
- {
- wcscpy_s(str, strLen, j);
- break;
- }
- }
- // add trailing spaces to pad out to field width
- int i = lstrlen(str);
- for (; i < nbDigits; ++i)
- {
- str[i] = ' ';
- }
- str[i] = '\0';
- }
- }
- else
- {
- constexpr size_t bufSize = 64;
- TCHAR f[bufSize] = { '\0' };
-
- TCHAR fStr[2] = TEXT("d");
- if (base == 16)
- fStr[0] = 'X';
- else if (base == 8)
- fStr[0] = 'o';
-
- if (lead == ColumnEditorParam::zeroLeading)
- {
- swprintf(f, bufSize, TEXT("%%.%d%s"), nbDigits, fStr);
- }
- else if (lead == ColumnEditorParam::spaceLeading)
- {
- swprintf(f, bufSize, TEXT("%%%d%s"), nbDigits, fStr);
- }
- else
- {
- // left-align within the field width, i.e. pad on right with space
- swprintf(f, bufSize, TEXT("%%-%d%s"), nbDigits, fStr);
- }
- // use swprintf (or sprintf) instead of wsprintf to make octal format work!
- swprintf(str, strLen, f, number);
- }
-
- return str;
-}
ColumnModeInfos ScintillaEditView::getColumnModeSelectInfo()
{
@@ -3821,7 +3734,7 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, const TCHAR *str)
}
}
-void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int incr, int repeat, UCHAR format, ColumnEditorParam::leadingChoice lead)
+void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, size_t initial, size_t incr, size_t repeat, UCHAR format, ColumnEditorParam::leadingChoice lead)
{
assert(repeat > 0);
@@ -3849,32 +3762,29 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int in
base = 2;
const int stringSize = 512;
- TCHAR str[stringSize];
+ char str[stringSize];
// Compute the numbers to be placed at each column.
- std::vector numbers;
+ std::vector numbers;
+
+ size_t curNumber = initial;
+ const size_t kiMaxSize = cmi.size();
+ while (numbers.size() < kiMaxSize)
{
- int curNumber = initial;
- const size_t kiMaxSize = cmi.size();
- while (numbers.size() < kiMaxSize)
+ for (size_t i = 0; i < repeat; i++)
{
- for (int i = 0; i < repeat; i++)
+ numbers.push_back(curNumber);
+ if (numbers.size() >= kiMaxSize)
{
- numbers.push_back(curNumber);
- if (numbers.size() >= kiMaxSize)
- {
- break;
- }
+ break;
}
- curNumber += incr;
}
+ curNumber += incr;
}
- assert(numbers.size()> 0);
-
- const int kibEnd = getNbDigits(*numbers.rbegin(), base);
- const int kibInit = getNbDigits(initial, base);
- const int kib = std::max(kibInit, kibEnd);
+ const size_t kibEnd = getNbDigits(*numbers.rbegin(), base);
+ const size_t kibInit = getNbDigits(initial, base);
+ const size_t kib = std::max(kibInit, kibEnd);
intptr_t totalDiff = 0;
const size_t len = cmi.size();
@@ -3888,7 +3798,7 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int in
cmi[i]._selLpos += totalDiff;
cmi[i]._selRpos += totalDiff;
- int2str(str, stringSize, numbers.at(i), base, kib, lead);
+ variedFormatNumber2String(str, stringSize, numbers.at(i), base, kib, lead);
const bool hasVirtualSpc = cmi[i]._nbVirtualAnchorSpc > 0;
if (hasVirtualSpc) // if virtual space is present, then insert space
@@ -3901,15 +3811,11 @@ void ScintillaEditView::columnReplace(ColumnModeInfos & cmi, int initial, int in
cmi[i]._selRpos += cmi[i]._nbVirtualCaretSpc;
}
execute(SCI_SETTARGETRANGE, cmi[i]._selLpos, cmi[i]._selRpos);
-
- WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance();
- size_t cp = execute(SCI_GETCODEPAGE);
- const char *strA = wmc.wchar2char(str, cp);
- execute(SCI_REPLACETARGET, static_cast(-1), reinterpret_cast(strA));
+ execute(SCI_REPLACETARGET, static_cast(-1), reinterpret_cast(str));
if (hasVirtualSpc)
{
- totalDiff += cmi[i]._nbVirtualAnchorSpc + lstrlen(str);
+ totalDiff += cmi[i]._nbVirtualAnchorSpc + strlen(str);
// Now there's no more virtual space
cmi[i]._nbVirtualAnchorSpc = 0;
cmi[i]._nbVirtualCaretSpc = 0;
diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h
index 396914cc8..ca837a34a 100644
--- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h
+++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h
@@ -245,10 +245,106 @@ const std::vector> g_nonPrintingChars =
{"\xEF\xBF\xBB", "IAT", "U+FFFB"} // U+FFFB : interlinear annotation terminator
};
-int getNbDigits(int aNum, int base);
-//HMODULE loadSciLexerDll();
+size_t getNbDigits(size_t aNum, size_t base);
-TCHAR* int2str(TCHAR* str, int strLen, int number, int base, int nbDigits, ColumnEditorParam::leadingChoice lead);
+template
+T* variedFormatNumber2String(T* str, size_t strLen, size_t number, size_t base, size_t nbDigits, ColumnEditorParam::leadingChoice lead)
+{
+ if (nbDigits == 0 || nbDigits >= strLen) return NULL;
+
+ //
+ // Reset the output string
+ //
+ memset(str, 0, sizeof(T) * strLen);
+
+ //
+ // Form number string according its base
+ //
+ std::string numberStr;
+
+ if (base == 2)
+ {
+ std::string tmpStr;
+ size_t aNum = number;
+ do
+ {
+ tmpStr += aNum % 2 ? "1" : "0";
+ aNum = aNum / 2;
+
+ } while (aNum != 0);
+
+ size_t i = 0;
+ size_t j = tmpStr.length() - 1;
+ for (; j >= 0 && i < tmpStr.length(); i++, j--)
+ {
+ numberStr += tmpStr[j];
+ }
+ }
+ else if (base == 8)
+ {
+ std::stringstream stream;
+ stream << std::oct << number;
+ numberStr = stream.str();
+ }
+ else if (base == 16)
+ {
+ std::stringstream stream;
+ stream << std::hex << number;
+ numberStr = stream.str();
+ }
+ else //if (base == 10)
+ {
+ numberStr = std::to_string(number);
+ }
+
+ size_t numberStrLen = numberStr.length();
+ size_t noneUsedZoneLen = nbDigits - numberStrLen;
+
+ size_t nbStart = 0;
+ size_t nbEnd = 0;
+
+ size_t noneUsedStart = 0;
+ size_t noneUsedEnd = 0;
+
+ T noUsedSymbol = ' ';
+
+ //
+ // Determinate leading zero/space or none
+ //
+ if (lead == ColumnEditorParam::spaceLeading)
+ {
+ noneUsedStart = 0;
+ noneUsedEnd = nbStart = noneUsedZoneLen;
+ nbEnd = nbDigits;
+ }
+ else if (lead == ColumnEditorParam::zeroLeading)
+ {
+ noUsedSymbol = '0';
+
+ noneUsedStart = 0;
+ noneUsedEnd = nbStart = noneUsedZoneLen;
+ nbEnd = nbDigits;
+ }
+ else //if (lead != ColumnEditorParam::noneLeading)
+ {
+ nbStart = 0;
+ nbEnd = noneUsedStart = numberStrLen;
+ noneUsedEnd = nbDigits;
+ }
+
+ //
+ // Fill str with the correct position
+ //
+ size_t i = 0;
+ for (size_t k = nbStart; k < nbEnd; ++k)
+ str[k] = numberStr[i++];
+
+ size_t j = 0;
+ for (j = noneUsedStart; j < noneUsedEnd; ++j)
+ str[j] = noUsedSymbol;
+
+ return str;
+}
typedef LRESULT (WINAPI *CallWindowProcFunc) (WNDPROC,HWND,UINT,WPARAM,LPARAM);
@@ -687,7 +783,7 @@ public:
ColumnModeInfos getColumnModeSelectInfo();
void columnReplace(ColumnModeInfos & cmi, const TCHAR *str);
- void columnReplace(ColumnModeInfos & cmi, int initial, int incr, int repeat, UCHAR format, ColumnEditorParam::leadingChoice lead);
+ void columnReplace(ColumnModeInfos & cmi, size_t initial, size_t incr, size_t repeat, UCHAR format, ColumnEditorParam::leadingChoice lead);
void clearIndicator(int indicatorNumber) {
size_t docStart = 0;
diff --git a/PowerEditor/src/ScintillaComponent/columnEditor.cpp b/PowerEditor/src/ScintillaComponent/columnEditor.cpp
index 420a88bf6..e415c67be 100644
--- a/PowerEditor/src/ScintillaComponent/columnEditor.cpp
+++ b/PowerEditor/src/ScintillaComponent/columnEditor.cpp
@@ -172,7 +172,7 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
(*_ppEditView)->execute(SCI_BEGINUNDOACTION);
constexpr int stringSize = 1024;
- TCHAR str[stringSize]{};
+ wchar_t str[stringSize]{};
bool isTextMode = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_COL_TEXT_RADIO, BM_GETCHECK, 0, 0));
@@ -239,13 +239,14 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
}
else
{
- int initialNumber = ::GetDlgItemInt(_hSelf, IDC_COL_INITNUM_EDIT, NULL, TRUE);
- int increaseNumber = ::GetDlgItemInt(_hSelf, IDC_COL_INCREASENUM_EDIT, NULL, TRUE);
- int repeat = ::GetDlgItemInt(_hSelf, IDC_COL_REPEATNUM_EDIT, NULL, TRUE);
- if (repeat <= 0)
+ size_t initialNumber = ::GetDlgItemInt(_hSelf, IDC_COL_INITNUM_EDIT, NULL, TRUE);
+ size_t increaseNumber = ::GetDlgItemInt(_hSelf, IDC_COL_INCREASENUM_EDIT, NULL, TRUE);
+ size_t repeat = ::GetDlgItemInt(_hSelf, IDC_COL_REPEATNUM_EDIT, NULL, TRUE);
+ if (repeat == 0)
{
repeat = 1; // Without this we might get an infinite loop while calculating the set "numbers" below.
}
+
UCHAR format = getFormat();
display(false);
@@ -272,31 +273,28 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
auto endLine = (*_ppEditView)->execute(SCI_LINEFROMPOSITION, endPos);
// Compute the numbers to be placed at each column.
- std::vector numbers;
+ std::vector numbers;
+
+ size_t curNumber = initialNumber;
+ const size_t kiMaxSize = 1 + (size_t)endLine - (size_t)cursorLine;
+ while (numbers.size() < kiMaxSize)
{
- int curNumber = initialNumber;
- const size_t kiMaxSize = 1 + (size_t)endLine - (size_t)cursorLine;
- while (numbers.size() < kiMaxSize)
+ for (size_t i = 0; i < repeat; i++)
{
- for (int i = 0; i < repeat; i++)
- {
- numbers.push_back(curNumber);
- if (numbers.size() >= kiMaxSize)
- {
- break;
- }
- }
- curNumber += increaseNumber;
+ numbers.push_back(curNumber);
+
+ if (numbers.size() >= kiMaxSize)
+ break;
}
+ curNumber += increaseNumber;
}
- assert(numbers.size() > 0);
constexpr int lineAllocatedLen = 1024;
TCHAR *line = new TCHAR[lineAllocatedLen];
UCHAR f = format & MASK_FORMAT;
- int base = 10;
+ size_t base = 10;
if (f == BASE_16)
base = 16;
else if (f == BASE_08)
@@ -304,10 +302,10 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
else if (f == BASE_02)
base = 2;
- int endNumber = *numbers.rbegin();
- int nbEnd = getNbDigits(endNumber, base);
- int nbInit = getNbDigits(initialNumber, base);
- int nb = std::max(nbInit, nbEnd);
+ size_t endNumber = *numbers.rbegin();
+ size_t nbEnd = getNbDigits(endNumber, base);
+ size_t nbInit = getNbDigits(initialNumber, base);
+ size_t nb = std::max(nbInit, nbEnd);
for (size_t i = cursorLine ; i <= size_t(endLine) ; ++i)
@@ -324,12 +322,13 @@ intptr_t CALLBACK ColumnEditorDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
line = new TCHAR[lineLen];
}
(*_ppEditView)->getGenericText(line, lineLen, lineBegin, lineEnd);
+
generic_string s2r(line);
//
// Calcule generic_string
//
- int2str(str, stringSize, numbers.at(i - cursorLine), base, nb, getLeading());
+ variedFormatNumber2String(str, stringSize, numbers.at(i - cursorLine), base, nb, getLeading());
if (lineEndCol < cursorCol)
{