Numworks Epsilon  1.4.1
Graphing Calculator Operating System
console_store.cpp
Go to the documentation of this file.
1 #include "console_store.h"
2 #include <assert.h>
3 #include <string.h>
4 
5 namespace Code {
6 
8  m_history{0}
9 {
10 }
11 
13  assert(k_historySize > 0);
14  m_history[0] = 0;
15 }
16 
18  if (k_historySize < 1) {
19  return;
20  }
21 
22  m_history[0] = makePrevious(m_history[0]);
23 
24  for (int i = 0; i < k_historySize - 1; i++) {
25  if (m_history[i] == 0) {
26  if (m_history[i+1] == 0) {
27  return ;
28  }
29  m_history[i+1] = makePrevious(m_history[i+1]);
30  }
31  }
32 }
33 
35  assert(i >= 0 && i < numberOfLines());
36  int currentLineIndex = 0;
37  for (int j=0; j<k_historySize; j++) {
38  if (m_history[j] == 0) {
39  currentLineIndex++;
40  j++;
41  }
42  if (currentLineIndex == i) {
43  return ConsoleLine(lineTypeForMarker(m_history[j]), m_history+j+1);
44  }
45  }
46  assert(false);
47  return ConsoleLine();
48 }
49 
51  if (m_history[0] == 0) {
52  return 0;
53  }
54  int result = 0;
55  for (int i = 0; i < k_historySize - 1; i++) {
56  if (m_history[i] == 0) {
57  result++;
58  if (m_history[i+1] == 0) {
59  return result;
60  }
61  }
62  }
63  assert(false);
64  return 0;
65 }
66 
67 void ConsoleStore::pushCommand(const char * text, size_t length) {
68  push(CurrentSessionCommandMarker, text, length);
69 }
70 
71 void ConsoleStore::pushResult(const char * text, size_t length) {
72  push(CurrentSessionResultMarker, text, length);
73 }
74 
76  ConsoleLine lastLine = lineAtIndex(numberOfLines()-1);
77  char lastLineFirstChar = lastLine.text()[0];
78  if (lastLineFirstChar == 0 || lastLineFirstChar == '\n') {
79  deleteLastLine();
80  }
81 }
82 
84  int numberOfLinesAtStart = numberOfLines();
85  assert(index >= 0 && index < numberOfLinesAtStart);
86  int indexOfLineToDelete = index;
87  while (indexOfLineToDelete < numberOfLinesAtStart - 1) {
88  if (lineAtIndex(indexOfLineToDelete + 1).isCommand()) {
89  break;
90  }
91  indexOfLineToDelete++;
92  }
93  ConsoleLine lineToDelete = lineAtIndex(indexOfLineToDelete);
94  while (indexOfLineToDelete > 0 && !lineAtIndex(indexOfLineToDelete).isCommand()) {
95  deleteLineAtIndex(indexOfLineToDelete);
96  indexOfLineToDelete--;
97  lineToDelete = lineAtIndex(indexOfLineToDelete);
98  }
99  deleteLineAtIndex(indexOfLineToDelete);
100  return indexOfLineToDelete;
101 }
102 
103 void ConsoleStore::push(const char marker, const char * text, size_t length) {
104  size_t textLength = length;
105  if (ConsoleLine::sizeOfConsoleLine(length) > k_historySize - 1) {
106  textLength = k_historySize - 1 - 1 - 1; // Marker, null termination and null marker.
107  }
108  int i = indexOfNullMarker();
109  // If needed, make room for the text we want to push.
110  while (i + ConsoleLine::sizeOfConsoleLine(textLength) > k_historySize - 1) {
111  deleteFirstLine();
112  i = indexOfNullMarker();
113  }
114  m_history[i] = marker;
115  strlcpy(&m_history[i+1], text, textLength+1);
116  m_history[i+1+length+1] = 0;
117 }
118 
119 ConsoleLine::Type ConsoleStore::lineTypeForMarker(char marker) const {
120  assert(marker == CurrentSessionCommandMarker || marker == CurrentSessionResultMarker || marker == PreviousSessionCommandMarker || marker == PreviousSessionResultMarker);
121  return static_cast<ConsoleLine::Type>(marker-1);
122 }
123 
124 int ConsoleStore::indexOfNullMarker() const {
125  if (m_history[0] == 0) {
126  return 0;
127  }
128  for (int i=0; i<k_historySize; i++) {
129  if (m_history[i] == 0 && m_history[i+1] == 0) {
130  return (i+1);
131  }
132  }
133  assert(false);
134  return 0;
135 }
136 
137 void ConsoleStore::deleteLineAtIndex(int index) {
138  assert(index >=0 && index < numberOfLines());
139  int currentLineIndex = 0;
140  for (int i = 0; i < k_historySize - 1; i++) {
141  if (m_history[i] == 0) {
142  currentLineIndex++;
143  continue;
144  }
145  if (currentLineIndex == index) {
146  int nextLineStart = i;
147  while (m_history[nextLineStart] != 0 && nextLineStart < k_historySize - 2) {
148  nextLineStart++;
149  }
150  nextLineStart++;
151  memcpy(&m_history[i], &m_history[nextLineStart], (k_historySize - 1) - nextLineStart + 1);
152  return;
153  }
154  }
155 }
156 
157 void ConsoleStore::deleteFirstLine() {
158  if (m_history[0] == 0) {
159  return;
160  }
161  int secondLineMarkerIndex = 1;
162  while (m_history[secondLineMarkerIndex] != 0) {
163  secondLineMarkerIndex++;
164  }
165  secondLineMarkerIndex++;
166  for (int i=0; i<k_historySize - secondLineMarkerIndex; i++) {
167  m_history[i] = m_history[secondLineMarkerIndex+i];
168  }
169 }
170 
171 void ConsoleStore::deleteLastLine() {
172  int lineCount = numberOfLines();
173  if (lineCount < 0) {
174  return;
175  }
176  if (lineCount == 1) {
177  deleteFirstLine();
178  return;
179  }
180  int currentLineIndex = 1;
181  int lastLineMarkerIndex = 0;
182  for (int i=0; i<k_historySize; i++) {
183  if (m_history[i] == 0) {
184  currentLineIndex++;
185  if (currentLineIndex == lineCount) {
186  lastLineMarkerIndex = i+1;
187  break;
188  }
189  }
190  }
191  m_history[lastLineMarkerIndex] = 0;
192 }
193 
194 }
static size_t sizeOfConsoleLine(size_t textLength)
Definition: console_line.h:23
int deleteCommandAndResultsAtIndex(int index)
int numberOfLines() const
#define assert(e)
Definition: assert.h:9
size_t strlcpy(char *dst, const char *src, size_t len)
Definition: strlcpy.c:3
Definition: app.cpp:7
const char * text() const
Definition: console_line.h:19
void pushCommand(const char *text, size_t length)
void pushResult(const char *text, size_t length)
ConsoleLine lineAtIndex(int i) const
void * memcpy(void *dst, const void *src, size_t n)
Definition: memcpy.c:3