FIX FieldExp management through assign.
[scilab.git] / scilab / modules / console / src / c / windows / TermLine.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2008 - DIGITEO - Allan CORNET
4
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution.  The terms
8 * are also available at    
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10 *
11 */
12
13 /*--------------------------------------------------------------------------*/
14 #include <windows.h>
15 #include <wincon.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include "stack-def.h"
19 #include "TermLine.h"
20 #include "HistoryManager.h"
21 #include "TermConsole.h"
22 #include "localization.h"
23 #include "MALLOC.h"
24 #include "TermPosition.h"
25 #include "../../../windows_tools/src/c/scilab_windows/console.h"
26 #include "os_strdup.h"
27 /*--------------------------------------------------------------------------*/
28 static int CURRENT_MAX_LINE_SIZE = bsiz;
29 static char *cur_line = NULL;   /* current contents of the line */      
30 static char *currentPrompt = NULL;
31 static int cur_pos = 0;         /* current position of the cursor */
32 static int max_pos = 0;
33 /*--------------------------------------------------------------------------*/
34 /* do backspace on line */
35 static void backSpace(void);
36 static void initializeLineBuffer(void);
37 static void reallocLineBuffer(void);
38 /*--------------------------------------------------------------------------*/
39 static void initializeLineBuffer(void)
40 {
41         int i = 0;
42         if (cur_line)
43         {
44                 FREE(cur_line);
45                 cur_line = NULL;
46         }
47         cur_line = (char*) MALLOC(sizeof(char)*CURRENT_MAX_LINE_SIZE);
48         if (cur_line)
49         {
50                 for (i = 0; i < CURRENT_MAX_LINE_SIZE; i++) cur_line[i] = '\0';
51         }
52         else
53         {
54                 fprintf(stderr, "Error: Buffer line allocation.\n");
55                 exit(1);
56         }
57 }
58 /*--------------------------------------------------------------------------*/
59 static void reallocLineBuffer(void)
60 {
61         if (cur_line)
62         {
63                 if ( max_pos > (CURRENT_MAX_LINE_SIZE - 1) )
64                 {
65                         char *ptrBackup = cur_line;
66                         int newCURRENT_MAX_LINE_SIZE = CURRENT_MAX_LINE_SIZE * 2;
67                         cur_line = (char*)REALLOC(cur_line, sizeof(char)*(newCURRENT_MAX_LINE_SIZE));
68                         if (cur_line == NULL)
69                         {
70                                 cur_line = ptrBackup;
71                         }
72                         else
73                         {
74                                 CURRENT_MAX_LINE_SIZE = newCURRENT_MAX_LINE_SIZE;
75                         }
76                 }
77         }
78         else
79         {
80                 initializeLineBuffer();
81         }
82 }
83 /*--------------------------------------------------------------------------*/
84 void moveBeginningLine(void)
85 {
86         reallocLineBuffer();
87         while (cur_pos > 0)
88         {
89                 cur_pos -= 1;
90                 backSpace();
91         }
92 }
93 /*--------------------------------------------------------------------------*/
94 void moveEndLine(void)
95 {
96         reallocLineBuffer();
97         while (cur_pos < max_pos)
98         {
99                 TerminalPutc (cur_line[cur_pos]);
100                 cur_pos += 1;
101         }
102 }
103 /*--------------------------------------------------------------------------*/
104 void moveBackSingleChar(void)
105 {
106         reallocLineBuffer();
107         if (cur_pos > 0)
108         {
109                 cur_pos -= 1;
110                 backSpace();
111         }
112 }
113 /*--------------------------------------------------------------------------*/
114 void moveForwardSingleChar(void)
115 {
116         reallocLineBuffer();
117         if (cur_pos < max_pos)
118         {
119                 TerminalPutc(cur_line[cur_pos]);
120                 cur_pos += 1;
121         }
122 }
123 /*--------------------------------------------------------------------------*/
124 void moveBackSingleWord(void)
125 {
126         reallocLineBuffer();
127         while ((cur_pos > 0) && (isspace(cur_line[cur_pos - 1]) ))
128         {
129                 cur_pos -= 1;
130                 backSpace ();
131         }
132         while ((cur_pos > 0) && ( !isspace(cur_line[cur_pos - 1]) ))
133         {
134                 cur_pos -= 1;
135                 backSpace ();
136         }
137         refreshLine();
138 }
139 /*--------------------------------------------------------------------------*/
140 void moveForwardSingleWord(void)
141 {
142         reallocLineBuffer();
143         while ( !isspace(cur_line[cur_pos]) && (cur_pos < max_pos) ) 
144         {
145                 TerminalPutc(cur_line[cur_pos]);
146                 cur_pos++;
147         }
148         while ( isspace(cur_line[cur_pos]) && (cur_pos < max_pos) ) 
149         {
150                 TerminalPutc(cur_line[cur_pos]);
151                 cur_pos++;
152         }
153         refreshLine();
154 }
155 /*--------------------------------------------------------------------------*/
156 void killCurrentPositionToEndLine(void)
157 {
158         int i = 0;
159         reallocLineBuffer();
160         for (i = cur_pos; i < max_pos; i++)  cur_line[i] = '\0';
161         for (i = cur_pos; i < max_pos; i++) TerminalPutc(VK_SPACE);
162         for (i = cur_pos; i < max_pos; i++) backSpace ();
163         max_pos = cur_pos;
164 }
165 /*--------------------------------------------------------------------------*/
166 void deletePreviousChar(void)
167 {
168         reallocLineBuffer();
169         if (cur_pos > 0)
170         {
171                 int i = 0;
172                 cur_pos -= 1;
173                 backSpace ();
174                 for (i = cur_pos; i < max_pos; i++) cur_line[i] = cur_line[i + 1];
175                 max_pos -= 1;
176                 refreshLine();
177         setSearchedTokenInScilabHistory(cur_line);
178         }
179         else TerminalBeep();
180 }
181 /*--------------------------------------------------------------------------*/
182 void deleteCurrentChar(void)
183 {
184         reallocLineBuffer();
185         if (max_pos == 0) 
186         {
187                 TerminalBeep();
188         }
189         else
190         {
191                 if (cur_pos < max_pos)
192                 {
193                         int i =0;
194                         for (i = cur_pos; i < max_pos; i++) cur_line[i] = cur_line[i + 1];
195                         max_pos -= 1;
196                         refreshLine();
197             setSearchedTokenInScilabHistory(cur_line);
198                 }
199         }
200 }
201 /*--------------------------------------------------------------------------*/
202 void moveBackHistory(void)
203 {
204         char *newline = NULL;
205
206         reallocLineBuffer();
207
208         cur_line[max_pos + 1] = '\0';
209         if (cur_line[0]== '\0')
210         {
211                 resetSearchedTokenInScilabHistory();
212                 setSearchedTokenInScilabHistory(NULL);
213         }
214
215         newline = getPreviousLineInScilabHistory();
216
217         if (newline)
218         {
219                 clearCurrentLine();
220                 copyLine(newline);
221                 FREE(newline);
222                 newline = NULL;
223         }
224 }
225 /*--------------------------------------------------------------------------*/
226 void moveForwardHistory(void)
227 {
228         char *newline = NULL;
229
230         reallocLineBuffer();
231
232         cur_line[max_pos + 1] = '\0';
233         if (cur_line[0]== '\0')
234         {
235                 resetSearchedTokenInScilabHistory();
236                 setSearchedTokenInScilabHistory(NULL);
237         }
238
239         newline = getNextLineInScilabHistory();
240
241         if (newline)
242         {
243                 clearCurrentLine();
244                 copyLine(newline);
245                 FREE(newline);
246                 newline = NULL;
247         }
248 }
249 /*--------------------------------------------------------------------------*/
250 void redrawLine(void)
251 {
252         int i =0;
253         char *line = getCurrentLine();
254
255         displayPrompt();
256         for (i = max_pos; i > cur_pos; i--)  backSpace ();
257         if (line)
258         {
259                 copyLine(line);
260                 FREE(line);
261                 line = NULL;
262         }
263 }
264 /*--------------------------------------------------------------------------*/
265 void copyLine(char *line)
266 {
267         reallocLineBuffer();
268
269         if (line)
270         {
271                 TerminalPrintf(line);
272                 CharToOem(line,cur_line);
273                 cur_pos = max_pos = (int)strlen (cur_line);
274         }
275 }
276 /*--------------------------------------------------------------------------*/
277 void killLastWord(void)
278 {
279         reallocLineBuffer();
280
281         while ((cur_pos > 0) && (cur_line[cur_pos - 1] == VK_SPACE))
282         {
283                 cur_pos -= 1;
284                 backSpace ();
285         }
286         while ((cur_pos > 0) && (cur_line[cur_pos - 1] != VK_SPACE))
287         {
288                 cur_pos -= 1;
289                 backSpace ();
290         }
291
292         killCurrentPositionToEndLine();
293 }
294 /*--------------------------------------------------------------------------*/
295 void newLine(void)
296 {
297         reallocLineBuffer();
298
299         cur_line[0] = '\0';
300         cur_pos = 0;
301         max_pos = 0;
302 }
303 /*--------------------------------------------------------------------------*/
304 void refreshLine(void)
305 {
306         int i = 0;
307
308         reallocLineBuffer();
309
310         /* write tail of string */
311         for (i = cur_pos; i < max_pos; i++) TerminalPutc(cur_line[i]);
312
313         /* write a space at the end of the line in case we deleted one */
314         TerminalPutc(VK_SPACE);
315
316         /* backup to original position */
317         for (i = max_pos + 1; i > cur_pos; i--) backSpace ();
318
319 }
320 /*--------------------------------------------------------------------------*/
321 void clearCurrentLine(void)
322 {
323         int i = 0;
324
325         reallocLineBuffer();
326
327         for (i = 0; i < max_pos; i++) cur_line[i] = '\0';
328
329         moveBeginningLine();
330         
331         for (i = 0; i < max_pos; i++) TerminalPutc(VK_SPACE);
332
333         TerminalPutc('\r');
334         displayPrompt();
335
336         newLine();
337 }
338 /*--------------------------------------------------------------------------*/
339 static void backSpace(void)
340 {
341         int X = 0, Y = 0;
342         reallocLineBuffer();
343
344         TermGetPosition(&X, &Y);
345         if ( (X - 1) < 0 )
346         {
347                 X = getXConsoleScreenSize();
348                 Y = Y - 1;
349                 TermSetPosition(X, Y);
350         }
351         else TerminalPutc(VK_BACK);
352 }
353 /*--------------------------------------------------------------------------*/
354 static char *getCurrentPrompt(void)
355 {
356         return currentPrompt;
357 }
358 /*--------------------------------------------------------------------------*/
359 void setCurrentPrompt(char *prompt)
360 {
361         currentPrompt = prompt;
362 }
363 /*--------------------------------------------------------------------------*/
364 void displayPrompt(void)
365 {
366         int X = 0, Y = 0;
367
368         /* check position */
369         TermGetPosition(&X, &Y);
370         if (X) TerminalPrintf("\n");
371
372         TerminalPrintf(getCurrentPrompt());
373 }
374 /*--------------------------------------------------------------------------*/
375 char *getCurrentLine(void)
376 {
377         char *line = NULL;
378
379         reallocLineBuffer();
380
381         cur_line[max_pos + 1] = '\0';
382         line = os_strdup(cur_line);
383         if (line) OemToChar(cur_line, line);
384         return line;
385 }
386 /*--------------------------------------------------------------------------*/
387 char *getLineBeforeCaret(void)
388 {
389         char *line = NULL;
390
391         reallocLineBuffer();
392         line = os_strdup(cur_line);
393         line[cur_pos] = '\0';
394         return line;
395 }
396 /*--------------------------------------------------------------------------*/
397 char *getLineAfterCaret(void)
398 {
399         char *line = NULL;
400
401         reallocLineBuffer();
402         if (cur_pos != max_pos)
403         {
404                 line = os_strdup(&cur_line[cur_pos]);
405                 line[(max_pos - cur_pos) + 1] = '\0';
406         }
407         else
408         {
409                 line = os_strdup("");
410         }
411         return line;
412 }
413 /*--------------------------------------------------------------------------*/
414 void addCharacterCurrentLine(unsigned char ch)
415 {
416         int i = 0;
417
418         reallocLineBuffer();
419
420         for (i = max_pos; i > cur_pos; i--) cur_line[i] = cur_line[i - 1];
421
422         cur_line[cur_pos] = ch;
423         cur_pos += 1;
424         max_pos += 1;
425         cur_line[max_pos] = '\0';
426
427         setSearchedTokenInScilabHistory(cur_line);
428
429         if (cur_pos < max_pos) refreshLine();
430 }
431 /*--------------------------------------------------------------------------*/
432 BOOL isHistorySearch(void)
433 {
434         return (cur_line[0] == '!');
435 }
436 /*--------------------------------------------------------------------------*/
437 void putLineSearchedHistory(void)
438 {
439         char *line = NULL;
440         char *token = getCurrentLine();
441
442         if (token)
443         {
444                 if ( (int)strlen(token) > 1 )
445                 {
446                         setSearchedTokenInScilabHistory(&token[1]);
447                         line = getNextLineInScilabHistory();
448                 }
449                 FREE(token);
450                 token = NULL;
451         }
452
453         clearCurrentLine();
454
455         if (line)
456         {
457                 copyLine(line);
458                 FREE(line);
459                 line = NULL;
460         }
461 }
462 /*--------------------------------------------------------------------------*/
463 void pasteClipBoard(void)
464 {
465         HGLOBAL hGMem = NULL;
466         LPSTR lpMem; /* Ptr on clipboard */
467
468         int typeClipboard = CF_TEXT;
469
470         OpenClipboard(NULL);
471
472         hGMem = GetClipboardData (typeClipboard);
473         if (hGMem)
474         {
475                 
476                 char *CurrentLine = getCurrentLine();
477
478                 lpMem  = GlobalLock( hGMem );
479                 if (lpMem)
480                 {
481                         char *newline = (char*)MALLOC(sizeof(char)*(strlen(CurrentLine)+ strlen(lpMem)));
482                         strncpy(newline, CurrentLine, cur_pos);
483                         strcat(newline, lpMem);
484                         strcat(newline, &CurrentLine[cur_pos]);
485
486                         clearCurrentLine();
487                         copyLine(newline);
488                         FREE(newline);
489                 }
490                 GlobalUnlock (hGMem);
491                 FREE(CurrentLine);
492         }
493
494         CloseClipboard ();
495 }
496 /*--------------------------------------------------------------------------*/