Update change log and spec for wrt-plugins-tizen_0.4.49
[framework/web/wrt-plugins-tizen.git] / src / Common / StandaloneConsole / StandaloneConsole.cpp
index d384d65..3aba307 100755 (executable)
@@ -24,6 +24,9 @@
 #include <GlobalContextManager.h>
 #include <string>
 #include <vector>
+#include <iostream>
+#include <termios.h>
+#include <JSUtil.h>
 
 #undef LOG_TAG
 #define LOG_TAG "TIZEN_DEVICEAPI"
@@ -31,7 +34,6 @@
 using namespace std;
 using namespace DeviceAPI::Common;
 
-
 namespace DeviceAPI {
 namespace Test {
 
@@ -290,6 +292,10 @@ JSContextRef StandaloneConsole::getGlobalContext(){
 
 JSValueRef StandaloneConsole::RunLineEx(const char* line, JSValueRef *exception){
     JSStringRef jsScript = JSStringCreateWithUTF8CString(line);
+    int size = strlen(line);
+    if( size != static_cast <int>(JSStringGetLength(jsScript))){
+        cout <<"error - fail to converting JSStringRef"<<endl;
+    }
     JSValueRef ret = JSEvaluateScript(mGlobalContext, jsScript, NULL, NULL, 0, exception);
     JSStringRelease(jsScript);
     return ret;
@@ -308,8 +314,8 @@ JSValueRef StandaloneConsole::RunScriptEx(const char* path, JSValueRef *exceptio
 
     if( length > 0 )
     {
-        char buff[length];
-        memset(buff, 0, length);
+        char buff[length+1];
+        memset(buff, 0, length+1);
         int r = fread(buff, 1, length, f);
         fclose(f);
 
@@ -374,24 +380,196 @@ void StandaloneConsole::appendModule(const char * name, JSObjectRef module){
     setProperty(mGlobalContext, mGlobalObject, name, module, kJSPropertyAttributeReadOnly);
 }
 
+
+int getch(void)
+{
+    int ch;
+    struct termios buf;
+    struct termios save;
+
+    tcgetattr(0, &save);
+    buf = save;
+    buf.c_lflag &= ~(ICANON|ECHO);
+    buf.c_cc[VMIN] = 1;
+    buf.c_cc[VTIME] = 0;
+    tcsetattr(0, TCSAFLUSH, &buf);
+    ch = getchar();
+    tcsetattr(0, TCSAFLUSH, &save);
+    return ch;
+}
+
+struct termios gSave;
+
+void onExit(void)
+{
+    tcsetattr(0, TCSAFLUSH, &gSave);
+}
+
+class LineBuffer{
+    vector<string> mHistory;
+    string mLine;
+    int mHistoryIndex;
+    unsigned int mCurrentPos;
+    unsigned int mCurrentPosTmp;
+    int mLineLength;
+public:
+    LineBuffer():mHistoryIndex(0), mCurrentPos(0){
+        tcgetattr(0, &gSave);
+        atexit(onExit);
+    }
+    ~LineBuffer(){
+        tcsetattr(0, TCSAFLUSH, &gSave);
+    }
+
+    void backSpace( int length ){
+        for( int i =0 ; i < length ; i++){
+            putchar('\b');
+            putchar(' ');
+            putchar('\b');
+        }
+    }
+
+    void cleanLine(){
+        int diff = mLineLength - mCurrentPosTmp;
+        while( diff-- > 0 ){
+            moveCursor(false);
+        }
+        backSpace(mLineLength);
+    }
+
+    void applyHistory( unsigned int index ){
+        if( mHistory.size() > index ){
+            mLine = mHistory[index];
+            mCurrentPos = mLine.size();
+        }
+    }
+
+    void moveCursor( bool Left ){
+        putchar(27);putchar(91);
+        if( Left )
+            putchar(68);
+        else
+            putchar(67);
+    }
+
+    void moveCurrentCursorPosition(){
+        int diff = mLine.size() - mCurrentPos;
+
+        while( diff-- > 0 ){
+            moveCursor(true);
+        }
+    }
+
+    bool checkSpecialKeys(int a){
+        if( a == 8 ){
+            if( mLine.size() != 0 && mCurrentPos != 0){
+                mCurrentPos--;
+                mLine.erase(mCurrentPos,1);
+            }
+            return true;
+        }
+        if( a == 27 ){
+            a = getch(); // 91
+            a = getch();
+            switch( a ){
+                case 65:
+                    //UP
+                    if( mHistoryIndex > 0 ){
+                        applyHistory(--mHistoryIndex);
+                    }
+                    break;
+                case 66:
+                    //DOWN
+                    if( (unsigned)mHistoryIndex < mHistory.size() ){
+                        applyHistory(++mHistoryIndex);
+                    }
+                    break;
+                case 67:
+                    //RIGHT
+                    if( mCurrentPos < mLine.size())
+                        mCurrentPos++;
+                    break;
+                case 68:
+                    //LEFT
+                    if( mCurrentPos > 0 )
+                        mCurrentPos--;
+                    break;
+                case 51:
+                    //delete
+                    getch();
+                    if( mCurrentPos < mLine.size())
+                        mLine.erase(mCurrentPos,1);
+                    break;
+                case 52:
+                    //end
+                    getch();
+                    mCurrentPos = mLine.size();
+                    break;
+                case 49:
+                    //home
+                    mCurrentPos = 0;
+                    a = getch();
+                    break;
+                default:
+                    a = getch();
+            }
+
+            return true;
+        }
+        return false;
+    }
+
+    string Prompt(const char * prompt){
+        printf("%s", prompt);
+        mCurrentPos = 0;
+        mLine.clear();
+        mLineLength = mLine.size();
+        mCurrentPosTmp = mCurrentPos;
+        while(1){
+            int a = getch();
+            cleanLine();
+            if( a == 10 )
+                break;
+
+            if(!checkSpecialKeys(a)){
+                mLine.insert(mCurrentPos,1, a);
+                mCurrentPos++;
+            }
+            cout << mLine;
+            moveCurrentCursorPosition();
+            mLineLength = mLine.size();
+            mCurrentPosTmp = mCurrentPos;
+        }
+        cout << mLine;
+        if( mLine.size() > 0 ){
+            mHistory.push_back(mLine);
+            mHistoryIndex = mHistory.size();
+        }
+        return mLine;
+    }
+
+};
+
+
+
 void StandaloneConsole::commandline(StandaloneConsole* console){
     pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
     pthread_mutex_lock(&lock);
     printf("command line mode ( \"quit\" for exit  )\n");
+    LineBuffer linebuff;
     while(1){
-        char line[1024];
-        printf(">");
-        if( gets(line) == NULL )
-            break;
-        if( strcmp(line, "quit") == 0 )
+        string line = linebuff.Prompt(">");
+        printf("\n");
+
+        if( line == "quit" )
             break;
-        if( strcmp(line, "gc") == 0 ){
+        if( line == "gc" ){
             console->GarbageCollect();
             continue;
         }
-        if( strcmp(line, "") == 0 )
+        if( line.size() == 0 )
             continue;
-        _Command *cmd = new _Command(line, console, &lock);
+        _Command *cmd = new _Command(line.c_str(), console, &lock);
         // for thread safety
         ecore_idler_add(commandDispath, cmd);
         pthread_mutex_lock(&lock);