#include "script_store.h" #include "string.h" #include namespace Code { ScriptStore::ScriptStore() : m_numberOfScripts(0), m_lastEditedStringPosition(0) { for (int i = 0; i= 0 && i < numberOfScripts()); cleanAndMoveFreeSpaceAfterScriptContent(i); int beginningOfScriptContent = indexOfScriptContent(i); // Compute the size of the script, including the free space of m_history int sizeOfEditableScript = 0; for (int j=beginningOfScriptContent; j= 0 && i < numberOfScripts()); int beginningOfScriptContent = indexOfScriptContent(i); return Script(&m_history[beginningOfScriptContent], strlen(&m_history[beginningOfScriptContent]) + 1); } Script ScriptStore::script(const char * name) { for (int i=0; i= 0 && i < numberOfScripts()); cleanAndMoveFreeSpaceAfterScriptName(i); return &m_history[indexOfScript(i)+1]; } int ScriptStore::sizeOfEditableNameOfScript(int i) { int namePosition = indexOfScript(i)+1; int contentPosition = indexOfScriptContent(i); return contentPosition-namePosition; } int ScriptStore::numberOfScripts() const { return m_numberOfScripts; } bool ScriptStore::addNewScript() { int sizeFreeSpace = sizeOfFreeSpace(); if (sizeFreeSpace < 4) { return false; } cleanAndMoveFreeSpaceAfterScriptContent(numberOfScripts()-1); int beginningNewScript = indexOfFirstFreeSpaceMarker(); m_history[beginningNewScript] = AutoImportationMarker; if (copyName(beginningNewScript + 1)) { if (copyDefaultScriptOnFreeSpace()) { m_numberOfScripts++; m_lastEditedStringPosition = indexOfScriptContent(numberOfScripts()-1); return true; } } for (int i = beginningNewScript; i= 0 && i < numberOfScripts()); cleanAndMoveFreeSpaceAfterScriptContent(i); int indexOfCharToDelete = indexOfScript(i); while (m_history[indexOfCharToDelete] != FreeSpaceMarker) { m_history[indexOfCharToDelete] = FreeSpaceMarker; indexOfCharToDelete++; } m_numberOfScripts--; } void ScriptStore::deleteAll() { for (int i = 0; i sizeOfFreeSpace() - 1) { // We keep at keast one free char. return false; } memcpy(&m_history[position], name, len+1); return true; } else { const char newName[] = "script.py"; int len = strlen(newName); if (len > sizeOfFreeSpace() - 1) { // We keep at keast one free char. return false; } memcpy(&m_history[position], &newName, len+1); return true; } } int ScriptStore::indexOfScriptContent(int i) const { int indexOfScriptContent = indexOfScript(i)+1; while (m_history[indexOfScriptContent] != 0 ) { indexOfScriptContent++; } indexOfScriptContent++; return indexOfScriptContent; } int ScriptStore::indexOfScript(int i) const { assert (i >= 0 && i < numberOfScripts()); int currentScriptNumber = 0; int beginningOfScript = 0; while (m_history[beginningOfScript] == FreeSpaceMarker) { beginningOfScript++; } if (i == 0) { return beginningOfScript; } bool goingThroughName = true; for (int j=beginningOfScript; j 0) { return sizeOfFreeSpace; } } } return sizeOfFreeSpace; } void ScriptStore::cleanFreeSpace() { if (m_history[m_lastEditedStringPosition] == FreeSpaceMarker || m_history[m_lastEditedStringPosition] == AutoImportationMarker || m_history[m_lastEditedStringPosition] == NoAutoImportationMarker) { return; } int indexOfCharToChangeIntoFreeSpaceMarker = m_lastEditedStringPosition + strlen (&m_history[m_lastEditedStringPosition]) + 1; while (m_history[indexOfCharToChangeIntoFreeSpaceMarker] != FreeSpaceMarker) { m_history[indexOfCharToChangeIntoFreeSpaceMarker] = FreeSpaceMarker; indexOfCharToChangeIntoFreeSpaceMarker ++; } } void ScriptStore::moveFreeSpaceAfterScriptContent(int i) { int indexOfFreeSpace = indexOfFirstFreeSpaceMarker(); int newFreeSpacePosition = lastIndexOfScript(i) + 1; if (indexOfFreeSpace < newFreeSpacePosition) { newFreeSpacePosition -= sizeOfFreeSpace(); } moveFreeSpaceAtPosition(newFreeSpacePosition); } void ScriptStore::moveFreeSpaceAfterScriptName(int i) { int newFreeSpacePosition = indexOfScript(i); while (m_history[newFreeSpacePosition] != 0) { newFreeSpacePosition++; } newFreeSpacePosition++; moveFreeSpaceAtPosition(newFreeSpacePosition); } void ScriptStore::moveFreeSpaceAtPosition(int i) { int indexOfFreeSpace = indexOfFirstFreeSpaceMarker(); if (indexOfFreeSpace != i){ // First, move the chars that would be overriden by the free space. int freeSpaceSize = sizeOfFreeSpace(); int len, src, dst; // The indexes depend on the relative positions of the free space and the // new destination. if (indexOfFreeSpace > i) { len = indexOfFreeSpace - i; src = i; dst = i + freeSpaceSize; } else { src = indexOfFreeSpace + freeSpaceSize; len = i + freeSpaceSize - src; dst = indexOfFreeSpace; } memmove(&m_history[dst], &m_history[src], len); // Then move the free space. for (int j = i ; j 1 && m_history[m_lastEditedStringPosition-1] != 0) { m_lastEditedStringPosition--; } if (m_lastEditedStringPosition <= 1) { m_lastEditedStringPosition = 0; } } void ScriptStore::cleanAndMoveFreeSpaceAfterScriptContent(int i) { if (i >= 0 && i= 0 && i sizeOfFreeSpace() - 1) { // We keep at keast one free char. return false; } memcpy(&m_history[indexOfFirstFreeSpaceMarker()], script, len+1); return true; } bool ScriptStore::copyDefaultScriptOnFreeSpace() { const char script[] = R"(def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) )"; int len = strlen(script); if (len + 1 > sizeOfFreeSpace() - 1) { // We keep at keast one free char. return false; } memcpy(&m_history[indexOfFirstFreeSpaceMarker()], script, len+1); return true; } int ScriptStore::indexBeginningFilename(const char * path) { int beginningFilename = strlen(path)-1; while (beginningFilename > 0 && path[beginningFilename - 1] != '\\') { beginningFilename--; } return beginningFilename; } }