mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[Python] Modified the paste effect in script and shell area
When a formula is pasted in a script or in the shell, some symbols are replaced by their equivalent in python : x turns into * ^ turns into ** √ turns into sqrt etc Change-Id: If6f2a22d4f3c148c2655e0892023b0e28058a9a6
This commit is contained in:
committed by
Émilie Feral
parent
4b965a0ff6
commit
8f97a332f6
@@ -85,11 +85,13 @@ App::App(Snapshot * snapshot) :
|
||||
m_codeStackViewController(&m_modalViewController, &m_listFooter),
|
||||
m_variableBoxController(snapshot->scriptStore())
|
||||
{
|
||||
Clipboard::sharedClipboard()->enterPython();
|
||||
}
|
||||
|
||||
App::~App() {
|
||||
assert(!m_consoleController.inputRunLoopActive());
|
||||
deinitPython();
|
||||
Clipboard::sharedClipboard()->exitPython();
|
||||
}
|
||||
|
||||
bool App::handleEvent(Ion::Events::Event event) {
|
||||
|
||||
@@ -1,44 +1,20 @@
|
||||
#include "helpers.h"
|
||||
#include <string.h>
|
||||
#include <ion/unicode/code_point.h>
|
||||
#include <ion.h>
|
||||
#include <escher/clipboard.h>
|
||||
|
||||
namespace Code {
|
||||
namespace Helpers {
|
||||
|
||||
class EventTextPair {
|
||||
public:
|
||||
constexpr EventTextPair(Ion::Events::Event event, const char * text) : m_event(event), m_text(text) {}
|
||||
Ion::Events::Event event() const { return m_event; }
|
||||
const char * text() const { return m_text; }
|
||||
private:
|
||||
const Ion::Events::Event m_event;
|
||||
const char * m_text;
|
||||
};
|
||||
|
||||
static_assert('\x11' == UCodePointEmpty, "Unicode error");
|
||||
static constexpr EventTextPair sEventTextMap[] = {
|
||||
EventTextPair(Ion::Events::XNT, "x"),
|
||||
EventTextPair(Ion::Events::Exp, "exp(\x11)"),
|
||||
EventTextPair(Ion::Events::Ln, "log(\x11)"),
|
||||
EventTextPair(Ion::Events::Log, "log10(\x11)"),
|
||||
EventTextPair(Ion::Events::Imaginary, "1j"),
|
||||
EventTextPair(Ion::Events::Power, "**"),
|
||||
EventTextPair(Ion::Events::Pi, "pi"),
|
||||
EventTextPair(Ion::Events::Sqrt, "sqrt(\x11)"),
|
||||
EventTextPair(Ion::Events::Square, "**2"),
|
||||
EventTextPair(Ion::Events::Multiplication, "*"),
|
||||
EventTextPair(Ion::Events::EE, "e"),
|
||||
};
|
||||
|
||||
const char * PythonTextForEvent(Ion::Events::Event event) {
|
||||
for (size_t i=0; i<sizeof(sEventTextMap)/sizeof(sEventTextMap[0]); i++) {
|
||||
if (event == sEventTextMap[i].event()) {
|
||||
return sEventTextMap[i].text();
|
||||
for (size_t i=0; i<NumberOfPythonTextPairs; i++) {
|
||||
UTF8Helper::TextPair pair = PythonTextPairs[i];
|
||||
if (event.text() == pair.firstString()) {
|
||||
return pair.secondString();
|
||||
}
|
||||
if (event == Ion::Events::XNT) {
|
||||
return "x";
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ escher_src += $(addprefix escher/src/,\
|
||||
)
|
||||
|
||||
tests_src += $(addprefix escher/test/,\
|
||||
clipboard.cpp \
|
||||
layout_field.cpp\
|
||||
)
|
||||
|
||||
|
||||
@@ -3,15 +3,43 @@
|
||||
|
||||
#include <escher/text_field.h>
|
||||
#include <poincare/layout.h>
|
||||
#include <ion/unicode/utf8_helper.h>
|
||||
|
||||
class Clipboard {
|
||||
public:
|
||||
static Clipboard * sharedClipboard();
|
||||
void store(const char * storedText, int length = -1);
|
||||
const char * storedText() const { return m_textBuffer; }
|
||||
const char * storedText() { return m_textBuffer; }
|
||||
void reset();
|
||||
void enterPython() { replaceCharForPython(true); }
|
||||
void exitPython() { replaceCharForPython(false); }
|
||||
static constexpr int k_bufferSize = TextField::maxBufferSize();
|
||||
private:
|
||||
char m_textBuffer[TextField::maxBufferSize()];
|
||||
char m_textBuffer[k_bufferSize];
|
||||
void replaceCharForPython(bool entersPythonApp);
|
||||
};
|
||||
|
||||
|
||||
/* The order in which the text pairs are stored is important. Indeed when leaving
|
||||
* python, the text stored in the buffer is converted into an input for other
|
||||
* apps. Therefore if we want to convert "3**3" into "3^3", the function must
|
||||
* look for "**" paterns before "*". Otherwise, we will get "3××3". */
|
||||
static constexpr int NumberOfPythonTextPairs = 12;
|
||||
static constexpr UTF8Helper::TextPair PythonTextPairs[NumberOfPythonTextPairs] = {
|
||||
UTF8Helper::TextPair("√(\x11)", "sqrt(\x11)", true),
|
||||
UTF8Helper::TextPair("ℯ^(\x11)", "exp(\x11)", true),
|
||||
UTF8Helper::TextPair("log(\x11)", "log10(\x11)", true),
|
||||
UTF8Helper::TextPair("ln(\x11)", "log(\x11)", true),
|
||||
UTF8Helper::TextPair("ᴇ", "e"),
|
||||
UTF8Helper::TextPair("𝐢", "1j"),
|
||||
/* Since textPairs are also used to pair events, we need to keep both ^2 and ^
|
||||
* to get the desired behavior in python when using power or square key*/
|
||||
UTF8Helper::TextPair("^2", "**2"),
|
||||
UTF8Helper::TextPair("^", "**"),
|
||||
UTF8Helper::TextPair("π", "pi"),
|
||||
UTF8Helper::TextPair("×", "*"),
|
||||
UTF8Helper::TextPair("·", "*"),
|
||||
UTF8Helper::TextPair("][", "], ["),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <escher/clipboard.h>
|
||||
#include <escher/text_field.h>
|
||||
#include <algorithm>
|
||||
|
||||
static Clipboard s_clipboard;
|
||||
@@ -14,3 +15,7 @@ void Clipboard::store(const char * storedText, int length) {
|
||||
void Clipboard::reset() {
|
||||
strlcpy(m_textBuffer, "", 1);
|
||||
}
|
||||
|
||||
void Clipboard::replaceCharForPython(bool entersPythonApp) {
|
||||
UTF8Helper::tryAndReplacePatternsInStringByPatterns((char *)m_textBuffer, TextField::maxBufferSize(), (UTF8Helper::TextPair *)&PythonTextPairs, NumberOfPythonTextPairs, entersPythonApp);
|
||||
}
|
||||
@@ -123,6 +123,7 @@ bool TextField::ContentView::insertTextAtLocation(const char * text, char * loca
|
||||
assert(m_isEditing);
|
||||
|
||||
size_t textLength = textLen < 0 ? strlen(text) : (size_t)textLen;
|
||||
// TODO when paste fails because of a too big message, create a pop-up
|
||||
if (m_currentDraftTextLength + textLength >= m_draftTextBufferSize || textLength == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
21
escher/test/clipboard.cpp
Normal file
21
escher/test/clipboard.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <quiz.h>
|
||||
#include <string.h>
|
||||
#include <escher/clipboard.h>
|
||||
|
||||
void assert_clipboard_enters_and_exits_python(const char * string, const char * stringResult) {
|
||||
Clipboard * clipboard = Clipboard::sharedClipboard();
|
||||
clipboard->store(string);
|
||||
clipboard->enterPython();
|
||||
quiz_assert(strcmp(clipboard->storedText(), stringResult) == 0);
|
||||
clipboard->exitPython();
|
||||
quiz_assert(strcmp(clipboard->storedText(), string) == 0);
|
||||
}
|
||||
|
||||
QUIZ_CASE(escher_clipboard_enters_and_exits_python) {
|
||||
assert_clipboard_enters_and_exits_python("4×4", "4*4");
|
||||
assert_clipboard_enters_and_exits_python("ℯ^(ln(4))", "exp(log(4))");
|
||||
assert_clipboard_enters_and_exits_python("ln(log(ln(π)))^𝐢", "log(log10(log(pi)))**1j");
|
||||
assert_clipboard_enters_and_exits_python("√(1ᴇ10)", "sqrt(1e10)");
|
||||
assert_clipboard_enters_and_exits_python("1×𝐢^2", "1*1j**2");
|
||||
assert_clipboard_enters_and_exits_python("12^(1/4)×(π/6)×(12×π)^(1/4)", "12**(1/4)*(pi/6)*(12*pi)**(1/4)");
|
||||
}
|
||||
@@ -6,6 +6,19 @@
|
||||
|
||||
namespace UTF8Helper {
|
||||
|
||||
class TextPair {
|
||||
public:
|
||||
constexpr TextPair(const char * firstString, const char * secondString, bool removeParenthesesExtention = false) : m_firstString(firstString), m_secondString(secondString), m_removeParenthesesExtention(removeParenthesesExtention){}
|
||||
const char * firstString() { return m_firstString; }
|
||||
const char * secondString() { return m_secondString; }
|
||||
bool removeParenthesesExtention() { return m_removeParenthesesExtention; }
|
||||
static constexpr int k_maxLength = 20;
|
||||
private:
|
||||
const char * m_firstString;
|
||||
const char * m_secondString;
|
||||
bool m_removeParenthesesExtention;
|
||||
};
|
||||
|
||||
// Returns the number of occurences of a code point in a string
|
||||
int CountOccurrences(const char * s, CodePoint c);
|
||||
|
||||
@@ -28,6 +41,25 @@ bool CopyAndRemoveCodePoints(char * dst, size_t dstSize, const char * src, CodeP
|
||||
* points where removed before it. Ensure null-termination of dst. */
|
||||
void RemoveCodePoint(char * buffer, CodePoint c, const char * * indexToUpdate = nullptr, const char * stoppingPosition = nullptr);
|
||||
|
||||
/* Slides a string by a number of chars. If slidingSize < 0, the string is slided
|
||||
* to the left losing the first chars. Returns true if successful.
|
||||
* Exemples :
|
||||
* slideStringByNumberOfChar("12345", 2, 7) gives "1212345"
|
||||
* slideStringByNumberOfChar("12345", 2, 5) gives "12123"
|
||||
* slideStringByNumberOfChar("12345", -2, 5) gives "34545"*/
|
||||
bool slideStringByNumberOfChar(char * text, int slidingSize, int textMaxLength);
|
||||
|
||||
/* Looks for patterns in a string. If a pattern is found, it is replaced by
|
||||
* the one associated in the TextPair struct.
|
||||
* - firstToSecond defines if replace the first string of a TextPair by the second
|
||||
* or the other way around.
|
||||
* - indexToUpdate is a pointer to a char in the string. It will be updated to
|
||||
* point to the same place after calling the function.
|
||||
* - stoppingPosition allows partial replacement in the string.
|
||||
*
|
||||
* Ensure null termination of the string or set the value of stoppingPosition*/
|
||||
void tryAndReplacePatternsInStringByPatterns(char * text, int textMaxSize, TextPair * textPairs, int numberOfPairs, bool firstToSecond, const char * * indexToUpdate = nullptr, const char * stoppingPosition = nullptr);
|
||||
|
||||
/* Copy src into dst until end of dst or code point c, with null termination. Return the length of the copy */
|
||||
size_t CopyUntilCodePoint(char * dst, size_t dstSize, const char * src, CodePoint c);
|
||||
|
||||
|
||||
@@ -132,37 +132,104 @@ bool CopyAndRemoveCodePoints(char * dst, size_t dstSize, const char * src, CodeP
|
||||
}
|
||||
|
||||
void RemoveCodePoint(char * buffer, CodePoint c, const char * * pointerToUpdate, const char * stoppingPosition) {
|
||||
UTF8Decoder decoder(buffer);
|
||||
const char * currentPointer = buffer;
|
||||
CodePoint codePoint = decoder.nextCodePoint();
|
||||
const char * initialPointerToUpdate = *pointerToUpdate;
|
||||
const char * nextPointer = decoder.stringPosition();
|
||||
size_t bufferIndex = 0;
|
||||
constexpr int patternMaxSize = CodePoint::MaxCodePointCharLength + 1; // +1 for null terminating char
|
||||
char pattern[patternMaxSize];
|
||||
int codePointCharSize = UTF8Decoder::CharSizeOfCodePoint(c);
|
||||
(void)codePointCharSize; // Silence compilation warning about unused variable.
|
||||
UTF8Decoder::CodePointToChars(c, pattern, codePointCharSize);
|
||||
pattern[codePointCharSize] = '\0';
|
||||
TextPair pair(pattern, "");
|
||||
tryAndReplacePatternsInStringByPatterns(buffer, strlen(buffer), &pair, 1, true, pointerToUpdate, stoppingPosition);
|
||||
}
|
||||
|
||||
while (codePoint != UCodePointNull && (stoppingPosition == nullptr || currentPointer < stoppingPosition)) {
|
||||
if (codePoint != c) {
|
||||
int copySize = nextPointer - currentPointer;
|
||||
memmove(buffer + bufferIndex, currentPointer, copySize);
|
||||
bufferIndex+= copySize;
|
||||
} else if (pointerToUpdate != nullptr && currentPointer < initialPointerToUpdate) {
|
||||
assert(*pointerToUpdate - buffer >= codePointCharSize);
|
||||
*pointerToUpdate = *pointerToUpdate - codePointCharSize;
|
||||
}
|
||||
currentPointer = nextPointer;
|
||||
codePoint = decoder.nextCodePoint();
|
||||
nextPointer = decoder.stringPosition();
|
||||
bool slideStringByNumberOfChar(char * text, int slidingSize, int textMaxLength) {
|
||||
int lenText = strlen(text);
|
||||
if (lenText + slidingSize > textMaxLength || lenText + slidingSize < 0) {
|
||||
return false;
|
||||
}
|
||||
if (codePoint == UCodePointNull) {
|
||||
*(buffer + bufferIndex) = 0;
|
||||
} else {
|
||||
assert(stoppingPosition != nullptr);
|
||||
// Find the null-terminating code point
|
||||
const char * nullTermination = currentPointer + strlen(currentPointer);
|
||||
/* Copy what remains of the buffer after the stopping position for code
|
||||
* point removal */
|
||||
memmove(buffer + bufferIndex, stoppingPosition, nullTermination - stoppingPosition + 1);
|
||||
if (slidingSize > 0) {
|
||||
memmove(text+slidingSize, text, strlen(text)+1);
|
||||
} else if (slidingSize < 0) {
|
||||
memmove(text, text-slidingSize, strlen(text)+1);
|
||||
}
|
||||
// In case slidingSize = 0, there is nothing to do
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Replaces the first chars of a string by other ones. If the sizes are different
|
||||
* the rest of the string will be moved right after the replacement chars.
|
||||
* If successful returns true.*/
|
||||
static bool replaceFirstCharsByPattern(char * text, int lengthOfPatternToRemove, const char * replacementPattern, int textMaxLength) {
|
||||
int lengthOfReplacementPattern = strlen(replacementPattern);
|
||||
if (lengthOfPatternToRemove <= strlen(text) && slideStringByNumberOfChar(text, lengthOfReplacementPattern-lengthOfPatternToRemove, textMaxLength)) {
|
||||
for (int i = 0; i < lengthOfReplacementPattern; i++) {
|
||||
text[i] = replacementPattern[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void tryAndReplacePatternsInStringByPatterns(char * text, int textMaxLength, TextPair * textPairs, int numberOfPairs, bool firstToSecond, const char * * pointerToUpdate, const char * stoppingPosition) {
|
||||
size_t i = 0;
|
||||
size_t iPrev = 0;
|
||||
size_t textLength = strlen(text);
|
||||
size_t lengthOfParenthesisExtention = strlen("(\x11)");
|
||||
while(i < textLength) {
|
||||
iPrev = i;
|
||||
bool didReplace = false;
|
||||
for (int j = 0; j < numberOfPairs; j++) {
|
||||
TextPair p = textPairs[j];
|
||||
size_t firstStringLength = strlen(p.firstString());
|
||||
size_t secondStringLength = strlen(p.secondString());
|
||||
/* Instead of storing TextPair("√(\x11)", "sqrt(\x11)") for the keyboard
|
||||
* events and TextPair("√", "sqrt") for the copy paste, we store just the
|
||||
* first and register it as "function". Therefore we can decide to remove
|
||||
* the (\x11) part or not depending on the application. This process is
|
||||
* repeated for all 4 function keys usable in python (√, ℯ, ln, log)*/
|
||||
if (p.removeParenthesesExtention()) {
|
||||
firstStringLength -= lengthOfParenthesisExtention;
|
||||
secondStringLength -= lengthOfParenthesisExtention;
|
||||
}
|
||||
char firstString[TextPair::k_maxLength];
|
||||
char secondString[TextPair::k_maxLength];
|
||||
// Getting rid of the eventual (\x11) part
|
||||
strlcpy((char *)firstString, p.firstString(), firstStringLength+1);
|
||||
strlcpy((char *)secondString, p.secondString(), secondStringLength+1);
|
||||
|
||||
char * matchedString = firstToSecond ? firstString : secondString;
|
||||
size_t matchedStringLength = strlen(matchedString);
|
||||
char * replacingString = firstToSecond ? secondString : firstString;
|
||||
size_t replacingStringLength = strlen(replacingString);
|
||||
|
||||
if (strncmp(&text[i], matchedString, matchedStringLength) == 0) {
|
||||
didReplace = replaceFirstCharsByPattern(&text[i], matchedStringLength, replacingString, textMaxLength);
|
||||
if (didReplace) {
|
||||
int delta = replacingStringLength - matchedStringLength;
|
||||
textLength += delta;
|
||||
if (pointerToUpdate != nullptr && &text[i] < *pointerToUpdate) {
|
||||
// We still have to update the pointer as the modification cursor has not yet exceeded it.
|
||||
*pointerToUpdate = *pointerToUpdate + delta;
|
||||
}
|
||||
if (stoppingPosition != nullptr) {
|
||||
stoppingPosition = stoppingPosition + delta;
|
||||
}
|
||||
if (replacingStringLength != 0) {
|
||||
i += replacingStringLength - 1;
|
||||
/* When working with multiple TextPairs at the same time, it can be
|
||||
* usefull to go back by one char. That is the case for empty matrixes
|
||||
* Indeed, in the string ",,]", ",," is replaced by ",\x11,".
|
||||
* The ",]" pattern right after would be missed if not for the -1.*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (iPrev == i && !didReplace) {
|
||||
// In case no pattern matched with the text, we go to the next char.
|
||||
i++;
|
||||
}
|
||||
if ((stoppingPosition != nullptr) && (&text[i] >= stoppingPosition)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,9 +53,8 @@ void assert_copy_and_remove_code_points_gives(char * dst, size_t dstSize, const
|
||||
quiz_assert(dst[i] == result[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int bufferSize = 100;
|
||||
QUIZ_CASE(ion_utf8_copy_and_remove_code_point) {
|
||||
constexpr int bufferSize = 100;
|
||||
char buffer[bufferSize];
|
||||
|
||||
const char * s = "12345";
|
||||
@@ -116,7 +115,6 @@ void assert_remove_code_point_gives(char * buffer, CodePoint c, const char * * i
|
||||
}
|
||||
|
||||
QUIZ_CASE(ion_utf8_remove_code_point) {
|
||||
constexpr int bufferSize = 100;
|
||||
char buffer[bufferSize];
|
||||
|
||||
const char * s = "2345";
|
||||
@@ -165,13 +163,77 @@ QUIZ_CASE(ion_utf8_remove_code_point) {
|
||||
assert_remove_code_point_gives(buffer, c, &indexToUpdate, stoppingPosition, indexToUpdateResult, result);
|
||||
}
|
||||
|
||||
void assert_slide_string_by_number_of_char_gives(const char * string, int slidingSize, bool successResult, const char * stringResult = nullptr) {
|
||||
char buffer[bufferSize];
|
||||
strlcpy(buffer, string, bufferSize);
|
||||
bool success = UTF8Helper::slideStringByNumberOfChar((char *)buffer, slidingSize, bufferSize);
|
||||
quiz_assert(success == successResult);
|
||||
if (successResult) {
|
||||
quiz_assert(strncmp(buffer, stringResult, bufferSize) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QUIZ_CASE(ion_utf8_move_string_from_index_by_number_of_char) {
|
||||
const char * string1 = "12345";
|
||||
assert_slide_string_by_number_of_char_gives(string1, 1, true, "112345");
|
||||
const char * string2 = "(1+3)";
|
||||
assert_slide_string_by_number_of_char_gives(string2, 3, true, "(1+(1+3)");
|
||||
assert_slide_string_by_number_of_char_gives(string2, bufferSize - strlen(string2)/2, false);
|
||||
const char * string3 = "exp(3+4)";
|
||||
assert_slide_string_by_number_of_char_gives(string3, -3, true, "(3+4)");
|
||||
assert_slide_string_by_number_of_char_gives(string3, -(strlen(string3)+3), false);
|
||||
assert_slide_string_by_number_of_char_gives(string3, -8, true, "");
|
||||
}
|
||||
|
||||
void assert_try_and_replace_pattern_in_string_by_pattern_gives(char * buffer, int bufferSize, UTF8Helper::TextPair * textPairs, int numberOfPairs, bool firstToSecond, const char * stringResult, const char ** indexToUpdate = nullptr, const char * indexToUpdateResult = nullptr, const char * stoppingPosition = nullptr) {
|
||||
UTF8Helper::tryAndReplacePatternsInStringByPatterns(buffer, bufferSize, textPairs, numberOfPairs, firstToSecond, indexToUpdate, stoppingPosition);
|
||||
quiz_assert(strncmp(buffer, stringResult, bufferSize) == 0);
|
||||
if (indexToUpdateResult != nullptr) {
|
||||
quiz_assert(*indexToUpdate == indexToUpdateResult);
|
||||
}
|
||||
}
|
||||
|
||||
QUIZ_CASE(ion_utf8_try_and_replace_pattern_in_string_by_pattern) {
|
||||
constexpr int numberOfPairs = 2;
|
||||
constexpr UTF8Helper::TextPair textPairs[numberOfPairs] = {
|
||||
UTF8Helper::TextPair("12", "2.3"),
|
||||
UTF8Helper::TextPair("exp", "ln"),
|
||||
};
|
||||
|
||||
char buffer[bufferSize];
|
||||
const char * string = "1234512";
|
||||
strlcpy(buffer, string, bufferSize);
|
||||
const char * indexToUpdate = buffer + 3;
|
||||
const char * indexToUpdateResult = indexToUpdate + 1;
|
||||
const char * result = "2.33452.3";
|
||||
const char * stoppingPosition = nullptr;
|
||||
assert_try_and_replace_pattern_in_string_by_pattern_gives(buffer, bufferSize, (UTF8Helper::TextPair *)&textPairs, numberOfPairs, true, result, &indexToUpdate, indexToUpdateResult);
|
||||
|
||||
string = "exp(2.3)12";
|
||||
strlcpy(buffer, string, bufferSize);
|
||||
indexToUpdate = buffer + 3;
|
||||
indexToUpdateResult = indexToUpdate - 1;
|
||||
result = "ln(2.3)12";
|
||||
stoppingPosition = buffer + 5;
|
||||
assert_try_and_replace_pattern_in_string_by_pattern_gives(buffer, bufferSize, (UTF8Helper::TextPair *)&textPairs, numberOfPairs, true, result, &indexToUpdate, indexToUpdateResult, stoppingPosition);
|
||||
|
||||
string = "12*ln(7)+ln";
|
||||
strlcpy(buffer, string, bufferSize);
|
||||
indexToUpdate = buffer + 7;
|
||||
indexToUpdateResult = indexToUpdate + 1;
|
||||
result = "12*exp(7)+ln";
|
||||
stoppingPosition = buffer + 7;
|
||||
assert_try_and_replace_pattern_in_string_by_pattern_gives(buffer, bufferSize, (UTF8Helper::TextPair *)&textPairs, numberOfPairs, false, result, &indexToUpdate, indexToUpdateResult, stoppingPosition);
|
||||
|
||||
}
|
||||
|
||||
void assert_string_copy_until_code_point_gives(char * dst, size_t dstSize, const char * src, CodePoint c, const char * result, size_t returnedResult) {
|
||||
quiz_assert(UTF8Helper::CopyUntilCodePoint(dst, dstSize, src, c) == returnedResult);
|
||||
quiz_assert(strcmp(dst, result) == 0);
|
||||
}
|
||||
|
||||
QUIZ_CASE(ion_utf8_helper_copy_until_code_point) {
|
||||
constexpr int bufferSize = 100;
|
||||
char buffer[bufferSize];
|
||||
|
||||
const char * s = "1234";
|
||||
@@ -217,7 +279,6 @@ void assert_string_remove_previous_glyph_gives(const char * text, char * locatio
|
||||
}
|
||||
|
||||
QUIZ_CASE(ion_utf8_helper_remove_previous_glyph) {
|
||||
constexpr int bufferSize = 100;
|
||||
char buffer[bufferSize];
|
||||
// 3é4
|
||||
buffer[0] = '3';
|
||||
|
||||
Reference in New Issue
Block a user