amath  1.6.2
Simple command line calculator
aengine.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
27 #include "clib.h"
28 #include "lib/charbuf.h"
29 #include "lib/charval.h"
30 #include "lib/aengine.h"
31 
32 AnsiConoleEngine::AnsiConoleEngine(const char *prompt, CharValidator *validator)
33 {
34  this->validator = validator;
35  AllocAndCopy(&this->prompt, prompt);
36  linebuf = new CharBuffer();
37  out = new CharBuffer();
38 
39  lines = new char*[maxLines];
40 
41  for (int i = 0; i < maxLines; i++) {
42  lines[i] = NOMEM;
43  }
44 
45  editline = NOMEM;
46  curline = -1;
47 }
48 
50 {
51  for (int i = 0; i < maxLines; i++) {
52  if (lines[i] != NOMEM) {
53  delete [] lines[i];
54  }
55  }
56 
57  delete [] lines;
58  delete linebuf;
59  delete out;
60  delete prompt;
61 }
62 
64 {
66  len = lineSize;
68  endpos = cursor;
69  *endpos = '\0';
70 
71  lineswap = false;
72  escmode = false;
73  csimode = false;
74  delmode = false;
75  linedone = false;
76 }
77 
78 //#include <real.h>
79 //#include <numb.h>
80 //#include <ntext.h>
81 
82 const char* AnsiConoleEngine::ProcessChar(const unsigned char character)
83 {
84  unsigned char ch = character;
86 
87  /*
88  // -------------- DEUG ------------------
89  Number *d = new RealNumber((int)ch);
90  NumeralSystem *ns = new DecimalSystem(0);
91  const char *dtext = ns->GetText(d);
92  StrCopy(out->buf, dtext);
93  StrConcat(out->buf, SPACE);
94  delete ns;
95  delete d;
96  return out->buf;
97  // -------------- DEUG ------------------
98  */
99 
100  if (len == 0) {
101  // TODO: double buffer
102  }
103 
104  bool processed = false;
105 
106  if (ch == 0) {
107  processed = true;
108  } else if (ch == 27) {
109  escmode = true;
110  processed = true;
111  } else if (ch == 155 || (escmode && ch == 91)) {
112  csimode = true;
113  processed = true;
114  } else if (csimode) {
115  switch (ch) {
116  case 65: // Arrow up (27 91 65)
117  ShowLast();
118  break;
119  case 66: // Arrow down (27 91 66)
120  ShowNext();
121  break;
122  case 67: // Arrow right (27 91 67)
123  if (cursor != endpos) {
124  cursor++;
126  }
127  break;
128  case 68: // Arrow left (27 91 68)
129  if (cursor != linebuf->buf) {
130  cursor--;
132  }
133  break;
134  case 51: // DEL 27 91 51 126
135  delmode = true;
136  default:
137  // F1 27 79 80
138  // F2 27 79 81
139  break;
140  }
141 
142  escmode = false;
143  csimode = false;
144  processed = true;
145  } else {
146  escmode = false;
147  csimode = false;
148  }
149 
150  // Delete one character to the right
151  if (delmode && ch == 126) {
152  if (cursor != endpos) {
153  char *i = cursor;
154  do {
155  *i = *(i + 1);
156  i++;
157  } while (i != endpos);
158 
159  len++;
161  endpos--;
163  }
164 
165  processed = true;
166  delmode = false;
167  }
168 
169  if (processed) {
170  return out->GetString();
171  }
172 
173  if (ch == 13 || ch == 10) {
176  CopyLine();
177  linedone = true;
178  } else if (cursor != linebuf->buf && (ch == 8 || ch == 127)) {
179  // Deleting in middle of line
180  if (cursor != endpos) {
181  char *i = cursor - 1;
182  do {
183  *i = *(i + 1);
184  i++;
185  } while (i != endpos);
186 
187  }
188 
189  len++;
192  cursor--;
193  endpos--;
195  } else if (validator->Validate(ch)) {
196  // Insert in middle of line
197  if (cursor != endpos) {
198  char *i = endpos;
199  do {
200  *i = *(i - 1);
201  i--;
202  } while (i != cursor);
204  }
205 
206  len--;
207  out->Append(ch);
208  *cursor++ = ch;
209  endpos++;
211  }
212 
213  return out->GetString();
214 }
215 
217 {
218  curline++;
219 
220  if (curline == maxLines) {
221  curline--;
222 
223  delete [] lines[0];
224  for (int i = 0; i < maxLines - 1; i++) {
225  lines[i] = lines[i + 1];
226  }
227  }
228 
230 
231  if (editline != NOMEM) {
232  delete [] editline;
233  editline = NOMEM;
234  }
235 }
236 
238 {
239  if (curline == -1) {
240  return;
241  }
242 
243  if (!lineswap) {
245  lineswap = true;
246  showline = curline + 1;
247  } else if (showline == curline + 1) {
248  delete editline;
250  }
251 
252  showline--;
253  if (showline < 0) {
254  showline = 0;
255  }
256 
257  out->Empty();
262 
266 
270 
271  unsigned int linelen = StrLen(linebuf->GetString());
272  cursor = linebuf->buf + linelen;
273  endpos = cursor;
274  len = lineSize - linelen;
275 }
276 
278 {
279  if (!lineswap) {
280  return;
281  }
282 
283  showline++;
284  if (showline > curline + 1) {
285  showline = curline + 1;
286  return;
287  }
288 
289  out->Empty();
292 
293  if (showline > curline) {
296 
300  } else {
303 
307  }
308 
309  unsigned int linelen = StrLen(linebuf->GetString());
310  cursor = linebuf->buf + linelen;
311  endpos = cursor;
312  len = lineSize - linelen;
313 }
314 
316 {
317  return linedone;
318 }
319 
320 const char* AnsiConoleEngine::GetLine()
321 {
322  return linebuf->GetString();
323 }
324 
325 void AnsiConoleEngine::SetPrompt(const char* string)
326 {
327  delete prompt;
328  AllocAndCopy(&prompt, string);
329 }
void Append(const char c)
Definition: charbuf.cpp:195
char ** lines
Definition: aengine.h:65
unsigned int len
Definition: aengine.h:68
const char * GetLine()
Definition: aengine.cpp:320
void Empty()
Definition: charbuf.cpp:168
#define DELETE1CHAR
Definition: platform.h:306
bool InputDone()
Definition: aengine.cpp:315
char * endpos
Definition: aengine.h:70
void Append(const char *source)
Definition: charbuf.cpp:211
CharBuffer()
Initialize without allocating memory.
Definition: charbuf.cpp:38
#define CURSORBACKWARD
Definition: platform.h:303
#define CURSORFORWARD
Definition: platform.h:302
CharBuffer * linebuf
Definition: aengine.h:66
unsigned int AllocAndCopy(char **destination, const char *source)
Allocate memory and copy a string into the array.
Definition: alloccpy.c:34
ANSI console controller.
Definition: aengine.h:45
#define NOMEM
Definition: platform.h:43
AnsiConoleEngine(const char *prompt, CharValidator *validator)
Definition: aengine.cpp:32
CharBuffer * out
Definition: aengine.h:81
char * GetString()
Definition: charbuf.cpp:250
#define INSERT1CHAR
Definition: platform.h:305
#define DELETELINE
Definition: platform.h:307
static const int maxLines
Definition: aengine.h:63
void StartInput()
Definition: aengine.cpp:63
void SetPrompt(const char *string)
Definition: aengine.cpp:325
CharValidator * validator
Definition: aengine.h:67
void EnsureGrowth(unsigned int size)
Definition: charbuf.cpp:158
int StrLen(const char *string)
Get the length of a null terminated string.
Definition: strlen.c:31
const char * ProcessChar(const unsigned char character)
Definition: aengine.cpp:82
static const int lineSize
Definition: aengine.h:64
char * prompt
Definition: aengine.h:61
char * ptr
Definition: charbuf.h:77
#define NEWLINE
Definition: platform.h:40
char * buf
Definition: charbuf.h:76
char * cursor
Definition: aengine.h:69
Encapsulate an character array which can be used as a string.
Definition: charbuf.h:43
void EnsureSize(unsigned int size)
Ensure a memory block of speficied size is allocated.
Definition: charbuf.cpp:112
virtual bool Validate(char c)=0
char * editline
Definition: aengine.h:75
void ClearAndAlloc(unsigned int size)
Release memory and allocate new size.
Definition: charbuf.cpp:91