/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2008 - DIGITEO - Allan CORNET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt * */ /*--------------------------------------------------------------------------*/ #include #include #include #include #include "stack-def.h" #include "TermLine.h" #include "HistoryManager.h" #include "TermConsole.h" #include "localization.h" #include "MALLOC.h" #include "strdup_windows.h" #include "TermPosition.h" #include "../../../windows_tools/src/c/scilab_windows/console.h" #include "strdup_windows.h" /*--------------------------------------------------------------------------*/ static int CURRENT_MAX_LINE_SIZE = bsiz; static char *cur_line = NULL; /* current contents of the line */ static char *currentPrompt = NULL; static int cur_pos = 0; /* current position of the cursor */ static int max_pos = 0; /*--------------------------------------------------------------------------*/ /* do backspace on line */ static void backSpace(void); static void initializeLineBuffer(void); static void reallocLineBuffer(void); /*--------------------------------------------------------------------------*/ static void initializeLineBuffer(void) { int i = 0; if (cur_line) { FREE(cur_line); cur_line = NULL; } cur_line = (char*) MALLOC(sizeof(char) * CURRENT_MAX_LINE_SIZE); if (cur_line) { for (i = 0; i < CURRENT_MAX_LINE_SIZE; i++) { cur_line[i] = '\0'; } } else { fprintf(stderr, "Error: Buffer line allocation.\n"); exit(1); } } /*--------------------------------------------------------------------------*/ static void reallocLineBuffer(void) { if (cur_line) { if ( max_pos > (CURRENT_MAX_LINE_SIZE - 1) ) { char *ptrBackup = cur_line; int newCURRENT_MAX_LINE_SIZE = CURRENT_MAX_LINE_SIZE * 2; cur_line = (char*)REALLOC(cur_line, sizeof(char) * (newCURRENT_MAX_LINE_SIZE)); if (cur_line == NULL) { cur_line = ptrBackup; } else { CURRENT_MAX_LINE_SIZE = newCURRENT_MAX_LINE_SIZE; } } } else { initializeLineBuffer(); } } /*--------------------------------------------------------------------------*/ void moveBeginningLine(void) { reallocLineBuffer(); while (cur_pos > 0) { cur_pos -= 1; backSpace(); } } /*--------------------------------------------------------------------------*/ void moveEndLine(void) { reallocLineBuffer(); while (cur_pos < max_pos) { TerminalPutc (cur_line[cur_pos]); cur_pos += 1; } } /*--------------------------------------------------------------------------*/ void moveBackSingleChar(void) { reallocLineBuffer(); if (cur_pos > 0) { cur_pos -= 1; backSpace(); } } /*--------------------------------------------------------------------------*/ void moveForwardSingleChar(void) { reallocLineBuffer(); if (cur_pos < max_pos) { TerminalPutc(cur_line[cur_pos]); cur_pos += 1; } } /*--------------------------------------------------------------------------*/ void moveBackSingleWord(void) { reallocLineBuffer(); while ((cur_pos > 0) && (isspace(cur_line[cur_pos - 1]) )) { cur_pos -= 1; backSpace (); } while ((cur_pos > 0) && ( !isspace(cur_line[cur_pos - 1]) )) { cur_pos -= 1; backSpace (); } refreshLine(); } /*--------------------------------------------------------------------------*/ void moveForwardSingleWord(void) { reallocLineBuffer(); while ( !isspace(cur_line[cur_pos]) && (cur_pos < max_pos) ) { TerminalPutc(cur_line[cur_pos]); cur_pos++; } while ( isspace(cur_line[cur_pos]) && (cur_pos < max_pos) ) { TerminalPutc(cur_line[cur_pos]); cur_pos++; } refreshLine(); } /*--------------------------------------------------------------------------*/ void killCurrentPositionToEndLine(void) { int i = 0; reallocLineBuffer(); for (i = cur_pos; i < max_pos; i++) { cur_line[i] = '\0'; } for (i = cur_pos; i < max_pos; i++) { TerminalPutc(VK_SPACE); } for (i = cur_pos; i < max_pos; i++) { backSpace (); } max_pos = cur_pos; } /*--------------------------------------------------------------------------*/ void deletePreviousChar(void) { reallocLineBuffer(); if (cur_pos > 0) { int i = 0; cur_pos -= 1; backSpace (); for (i = cur_pos; i < max_pos; i++) { cur_line[i] = cur_line[i + 1]; } max_pos -= 1; refreshLine(); } else { TerminalBeep(); } } /*--------------------------------------------------------------------------*/ void deleteCurrentChar(void) { reallocLineBuffer(); if (max_pos == 0) { TerminalBeep(); } else { if (cur_pos < max_pos) { int i = 0; for (i = cur_pos; i < max_pos; i++) { cur_line[i] = cur_line[i + 1]; } max_pos -= 1; refreshLine(); } } } /*--------------------------------------------------------------------------*/ void moveBackHistory(void) { char *newline = NULL; reallocLineBuffer(); cur_line[max_pos + 1] = '\0'; if (cur_line[0] == '\0') { resetSearchedTokenInScilabHistory(); setSearchedTokenInScilabHistory(NULL); } newline = getPreviousLineInScilabHistory(); if (newline) { clearCurrentLine(); copyLine(newline); FREE(newline); newline = NULL; } } /*--------------------------------------------------------------------------*/ void moveForwardHistory(void) { char *newline = NULL; reallocLineBuffer(); cur_line[max_pos + 1] = '\0'; if (cur_line[0] == '\0') { resetSearchedTokenInScilabHistory(); setSearchedTokenInScilabHistory(NULL); } newline = getNextLineInScilabHistory(); if (newline) { clearCurrentLine(); copyLine(newline); FREE(newline); newline = NULL; } } /*--------------------------------------------------------------------------*/ void redrawLine(void) { int i = 0; char *line = getCurrentLine(); displayPrompt(); for (i = max_pos; i > cur_pos; i--) { backSpace (); } if (line) { copyLine(line); FREE(line); line = NULL; } } /*--------------------------------------------------------------------------*/ void copyLine(char *line) { reallocLineBuffer(); if (line) { TerminalPrintf(line); CharToOem(line, cur_line); cur_pos = max_pos = (int)strlen (cur_line); } } /*--------------------------------------------------------------------------*/ void killLastWord(void) { reallocLineBuffer(); while ((cur_pos > 0) && (cur_line[cur_pos - 1] == VK_SPACE)) { cur_pos -= 1; backSpace (); } while ((cur_pos > 0) && (cur_line[cur_pos - 1] != VK_SPACE)) { cur_pos -= 1; backSpace (); } killCurrentPositionToEndLine(); } /*--------------------------------------------------------------------------*/ void newLine(void) { reallocLineBuffer(); cur_line[0] = '\0'; cur_pos = 0; max_pos = 0; } /*--------------------------------------------------------------------------*/ void refreshLine(void) { int i = 0; reallocLineBuffer(); /* write tail of string */ for (i = cur_pos; i < max_pos; i++) { TerminalPutc(cur_line[i]); } /* write a space at the end of the line in case we deleted one */ TerminalPutc(VK_SPACE); /* backup to original position */ for (i = max_pos + 1; i > cur_pos; i--) { backSpace (); } } /*--------------------------------------------------------------------------*/ void clearCurrentLine(void) { int i = 0; reallocLineBuffer(); for (i = 0; i < max_pos; i++) { cur_line[i] = '\0'; } moveBeginningLine(); for (i = 0; i < max_pos; i++) { TerminalPutc(VK_SPACE); } TerminalPutc('\r'); displayPrompt(); newLine(); } /*--------------------------------------------------------------------------*/ static void backSpace(void) { int X = 0, Y = 0; reallocLineBuffer(); TermGetPosition(&X, &Y); if ( (X - 1) < 0 ) { X = getXConsoleScreenSize(); Y = Y - 1; TermSetPosition(X, Y); } else { TerminalPutc(VK_BACK); } } /*--------------------------------------------------------------------------*/ static char *getCurrentPrompt(void) { return currentPrompt; } /*--------------------------------------------------------------------------*/ void setCurrentPrompt(char *prompt) { currentPrompt = prompt; } /*--------------------------------------------------------------------------*/ void displayPrompt(void) { int X = 0, Y = 0; /* check position */ TermGetPosition(&X, &Y); if (X) { TerminalPrintf("\n"); } TerminalPrintf(getCurrentPrompt()); } /*--------------------------------------------------------------------------*/ char *getCurrentLine(void) { char *line = NULL; reallocLineBuffer(); cur_line[max_pos + 1] = '\0'; line = strdup_windows(cur_line); if (line) { OemToChar(cur_line, line); } return line; } /*--------------------------------------------------------------------------*/ char *getLineBeforeCaret(void) { char *line = NULL; reallocLineBuffer(); line = strdup_windows(cur_line); line[cur_pos] = '\0'; return line; } /*--------------------------------------------------------------------------*/ char *getLineAfterCaret(void) { char *line = NULL; reallocLineBuffer(); if (cur_pos != max_pos) { line = strdup_windows(&cur_line[cur_pos]); line[(max_pos - cur_pos) + 1] = '\0'; } else { line = strdup_windows(""); } return line; } /*--------------------------------------------------------------------------*/ void addCharacterCurrentLine(unsigned char ch) { int i = 0; reallocLineBuffer(); for (i = max_pos; i > cur_pos; i--) { cur_line[i] = cur_line[i - 1]; } cur_line[cur_pos] = ch; cur_pos += 1; max_pos += 1; cur_line[max_pos] = '\0'; setSearchedTokenInScilabHistory(cur_line); if (cur_pos < max_pos) { refreshLine(); } } /*--------------------------------------------------------------------------*/ BOOL isHistorySearch(void) { return (cur_line[0] == '!'); } /*--------------------------------------------------------------------------*/ void putLineSearchedHistory(void) { char *line = NULL; char *token = getCurrentLine(); if (token) { if ( (int)strlen(token) > 1 ) { setSearchedTokenInScilabHistory(&token[1]); line = getNextLineInScilabHistory(); } FREE(token); token = NULL; } clearCurrentLine(); if (line) { copyLine(line); FREE(line); line = NULL; } } /*--------------------------------------------------------------------------*/ void pasteClipBoard(void) { HGLOBAL hGMem = NULL; LPSTR lpMem; /* Ptr on clipboard */ int typeClipboard = CF_TEXT; OpenClipboard(NULL); hGMem = GetClipboardData (typeClipboard); if (hGMem) { char *CurrentLine = getCurrentLine(); lpMem = (LPSTR)GlobalLock( hGMem ); if (lpMem) { char *newline = (char*)MALLOC(sizeof(char) * (strlen(CurrentLine) + strlen(lpMem) + 1)); memset(newline, 0x00, strlen(CurrentLine) + strlen(lpMem) + 1); strncpy(newline, CurrentLine, cur_pos); strcat(newline, lpMem); clearCurrentLine(); copyLine(newline); FREE(newline); } GlobalUnlock (hGMem); FREE(CurrentLine); } CloseClipboard (); } /*--------------------------------------------------------------------------*/