#if defined( _MSC_VER )
#include "lldb/Host/windows/windows.h"
#include "ELWrapper.h"
#include <vector>
#include <assert.h>
#define GETARG( X ) ( (void* ) *( ( (int**) &el ) + ((X) + 2) ) )
typedef unsigned char (*el_addfn_func)(EditLine *e, int ch);
struct el_binding
{
const char *name;
const char *help;
el_addfn_func func;
const char *key;
};
static std::vector<el_binding*> _bindings;
static void *clientData = NULL;
static const char *_prompt = "(lldb) ";
#if !defined( _WIP_INPUT_METHOD )
static char *
el_get_s (char *buffer, int chars)
{
return gets_s(buffer, chars);
}
#else
static void
con_output (char _in)
{
HANDLE hout = GetStdHandle( STD_OUTPUT_HANDLE );
DWORD written = 0;
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo( hout, &info );
WriteConsoleOutputCharacterA( hout, &_in, 1, info.dwCursorPosition, &written );
info.dwCursorPosition.X++;
SetConsoleCursorPosition( hout, info.dwCursorPosition );
}
static void
con_backspace (void)
{
HANDLE hout = GetStdHandle( STD_OUTPUT_HANDLE );
DWORD written = 0;
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo( hout, &info );
info.dwCursorPosition.X--;
SetConsoleCursorPosition( hout, info.dwCursorPosition );
WriteConsoleOutputCharacterA( hout, " ", 1, info.dwCursorPosition, &written );
}
static void
con_return (void)
{
HANDLE hout = GetStdHandle( STD_OUTPUT_HANDLE );
DWORD written = 0;
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo( hout, &info );
info.dwCursorPosition.X = 0;
info.dwCursorPosition.Y++;
SetConsoleCursorPosition( hout, info.dwCursorPosition );
}
static bool
runBind (char _key)
{
for ( int i=0; i<_bindings.size(); i++ )
{
el_binding *bind = _bindings[i];
if ( bind->key[0] == _key )
{
bind->func( (EditLine*) -1, _key );
return true;
}
}
return false;
}
static char *
el_get_s (char *buffer, int chars)
{
char *head = buffer;
for ( ;; Sleep( 10 ) )
{
INPUT_RECORD _record;
DWORD _read = 0;
if ( ReadConsoleInputA( GetStdHandle( STD_INPUT_HANDLE ), &_record, 1, &_read ) == FALSE )
break;
if ( _read == 0 )
continue;
if ( _record.EventType != KEY_EVENT )
continue;
if (! _record.Event.KeyEvent.bKeyDown )
continue;
char _key = _record.Event.KeyEvent.uChar.AsciiChar;
if ( _key == 0 )
{
continue;
}
if ( runBind( _key ) )
continue;
if ( _key == '\n' || _key == '\r' )
{
con_return( );
break;
}
if ( _key == 0x8 )
{
if ( head > buffer )
{
con_backspace( );
head--;
}
continue;
}
if ( (head-buffer) < (chars-1) )
{
con_output( _key );
*(head++) = _key;
}
}
*head = '\0';
return buffer;
}
#endif
EditLine *
el_init (const char *, FILE *, FILE *, FILE *)
{
SetConsoleTitleA( "lldb" );
return (EditLine*) -1;
}
const char *
el_gets (EditLine *el, int *length)
{
if ( _prompt != NULL )
printf( _prompt );
char *buffer = new char[ MAX_PATH ];
if ( el_get_s( buffer, MAX_PATH ) )
{
while ( buffer[ *length ] != '\0' )
(*length)++;
return buffer;
}
else
{
delete [] buffer;
return NULL;
}
}
int
el_set (EditLine *el, int code, ...)
{
int **arg = (int**) ⪙
switch ( code )
{
case ( EL_PROMPT ):
{
void *func_vp = (void*) *(arg+2);
const char* (*func_fp)(EditLine*) = (const char*(*)(EditLine *)) func_vp;
_prompt = func_fp( el );
}
break;
case ( EL_EDITOR ):
{
}
break;
case ( EL_HIST ):
{
}
break;
case ( EL_ADDFN ):
{
el_binding *binding = new el_binding;
binding->name = (const char *) GETARG( 0 );
binding->help = (const char *) GETARG( 1 );
binding->func = (el_addfn_func) GETARG( 2 );
binding->key = 0;
_bindings.push_back( binding );
}
break;
case ( EL_BIND ):
{
const char *name = (const char*) GETARG( 1 );
for ( int i=0; i<_bindings.size(); i++ )
{
el_binding *bind = _bindings[i];
if ( strcmp( bind->name, name ) == 0 )
{
bind->key = (const char *) GETARG( 0 );
break;
}
}
}
break;
case ( EL_CLIENTDATA ):
{
clientData = GETARG( 0 );
}
break;
default:
assert( !"Not Implemented!" );
}
return 0;
}
void
el_end (EditLine *el)
{
assert( !"Not implemented!" );
}
void
el_reset (EditLine *)
{
assert( !"Not implemented!" );
}
int
el_getc (EditLine *, char *)
{
assert( !"Not implemented!" );
return 0;
}
void
el_push (EditLine *, char *)
{
assert( !"Not implemented!" );
}
void
el_beep (EditLine *)
{
Beep( 1000, 500 );
}
int
el_parse (EditLine *, int, const char **)
{
assert( !"Not implemented!" );
return 0;
}
int
el_get (EditLine *el, int code, ...)
{
switch ( code )
{
case ( EL_CLIENTDATA ):
{
void **dout = (void**) GETARG( 0 );
*dout = clientData;
}
break;
default:
assert( !"Not implemented!" );
}
return 0;
}
int
el_source (EditLine *el, const char *file)
{
return 0;
}
void
el_resize (EditLine *)
{
assert( !"Not implemented!" );
}
const LineInfo *
el_line (EditLine *el)
{
assert( !"Not implemented!" );
return 0;
}
int
el_insertstr (EditLine *, const char *)
{
assert( !"Not implemented!" );
return 0;
}
void
el_deletestr (EditLine *, int)
{
assert( !"Not implemented!" );
}
History *
history_init (void)
{
return (History*) -1;
}
void
history_end (History *)
{
assert( !"Not implemented!" );
}
int
history (History *, HistEvent *, int op, ...)
{
return 0;
}
#endif