Modifications to allow compilation and execution on a windows system.

http://llvm-reviews.chandlerc.com/D1785

Files:
  tools/CMakeLists.txt
  tools/driver/CMakeLists.txt
  tools/driver/Driver.cpp
  tools/driver/Driver.h
  tools/driver/ELWrapper.cpp
  tools/driver/ELWrapper.h
  tools/driver/GetOptWrapper.cpp
  tools/driver/GetOptWrapper.h
  tools/driver/IOChannel.cpp
  tools/driver/IOChannel.h
  tools/driver/Mutex.cpp
  tools/driver/Platform.cpp
  tools/driver/Platform.h
Index: tools/CMakeLists.txt
===================================================================
--- tools/CMakeLists.txt
+++ tools/CMakeLists.txt
@@ -1,7 +1,7 @@
-if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
-  add_subdirectory(debugserver)
-endif()
-if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
-  add_subdirectory(driver)
-  add_subdirectory(lldb-platform)
-endif()
+if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
+  add_subdirectory(debugserver)
+endif()
+add_subdirectory(driver)
+if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
+  add_subdirectory(lldb-platform)
+endif()
Index: tools/driver/CMakeLists.txt
===================================================================
--- tools/driver/CMakeLists.txt
+++ tools/driver/CMakeLists.txt
@@ -1,18 +1,22 @@
-set(LLVM_NO_RTTI 1)
-add_lldb_executable(lldb
-  Driver.cpp
-  #DriverEvents.cpp
-  #DriverOptions.cpp
-  #DriverPosix.cpp
-  IOChannel.cpp
-  )
-
-target_link_libraries(lldb liblldb)
-# TODO: why isn't this done by add_lldb_executable?
-#target_link_libraries(lldb ${LLDB_USED_LIBS})
-#llvm_config(lldb ${LLVM_LINK_COMPONENTS})
-
-set_target_properties(lldb PROPERTIES VERSION ${LLDB_VERSION})
-
-install(TARGETS lldb
-  RUNTIME DESTINATION bin)
+set(LLVM_NO_RTTI 1)
+add_lldb_executable(lldb
+  Driver.cpp
+  #DriverEvents.cpp
+  #DriverOptions.cpp
+  #DriverPosix.cpp
+  IOChannel.cpp
+  ELWrapper.cpp
+  Mutex.cpp
+  Platform.cpp
+  GetOptWrapper.cpp
+  )
+
+target_link_libraries(lldb liblldb)
+# TODO: why isn't this done by add_lldb_executable?
+#target_link_libraries(lldb ${LLDB_USED_LIBS})
+#llvm_config(lldb ${LLVM_LINK_COMPONENTS})
+
+set_target_properties(lldb PROPERTIES VERSION ${LLDB_VERSION})
+
+install(TARGETS lldb
+  RUNTIME DESTINATION bin)
Index: tools/driver/Driver.cpp
===================================================================
--- tools/driver/Driver.cpp
+++ tools/driver/Driver.cpp
@@ -9,16 +9,11 @@
 
 #include "Driver.h"
 
-#include <getopt.h>
-#include <libgen.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <unistd.h>
+#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <limits.h>
 #include <fcntl.h>
-#include <inttypes.h>
 
 #include <string>
 
@@ -155,7 +150,9 @@
     // Write an End of File sequence to the file descriptor to ensure any
     // read functions can exit.
     char eof_str[] = "\x04";
-    ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
+    int mfd = m_editline_pty.GetMasterFileDescriptor();
+    if ( mfd != -1 )
+        ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
 
     m_editline_pty.CloseMasterFileDescriptor();
 
@@ -569,7 +566,7 @@
 // if the user only wanted help or version information.
 
 SBError
-Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit)
+Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exiting)
 {
     ResetOptionValues ();
 
@@ -802,12 +799,12 @@
     if (error.Fail() || m_option_data.m_print_help)
     {
         ShowUsage (out_fh, g_options, m_option_data);
-        exit = true;
+        exiting = true;
     }
     else if (m_option_data.m_print_version)
     {
         ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
-        exit = true;
+        exiting = true;
     }
     else if (m_option_data.m_print_python_path)
     {
@@ -825,7 +822,7 @@
         }
         else
             ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
-        exit = true;
+        exiting = true;
     }
     else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
     {
@@ -1311,6 +1308,12 @@
 void
 Driver::MainLoop ()
 {
+#if defined( _MSC_VER )
+    m_editline_slave_fh = stdin;
+    FILE *editline_output_slave_fh = stdout;
+    lldb_utility::PseudoTerminal editline_output_pty;
+#else
+
     char error_str[1024];
     if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
     {
@@ -1371,6 +1374,7 @@
             ::setbuf (editline_output_slave_fh, NULL);
         }
     }
+#endif
 
    // struct termios stdin_termios;
 
@@ -1780,15 +1784,15 @@
     {
         Driver driver;
 
-        bool exit = false;
-        SBError error (driver.ParseArgs (argc, argv, stdout, exit));
+        bool exiting = false;
+        SBError error (driver.ParseArgs (argc, argv, stdout, exiting));
         if (error.Fail())
         {
             const char *error_cstr = error.GetCString ();
             if (error_cstr)
                 ::fprintf (stderr, "error: %s\n", error_cstr);
         }
-        else if (!exit)
+        else if (!exiting)
         {
             driver.MainLoop ();
         }
Index: tools/driver/Driver.h
===================================================================
--- tools/driver/Driver.h
+++ tools/driver/Driver.h
@@ -10,6 +10,7 @@
 #ifndef lldb_Driver_h_
 #define lldb_Driver_h_
 
+#include "Platform.h"
 #include "lldb/Utility/PseudoTerminal.h"
 
 #include <set>
Index: tools/driver/ELWrapper.cpp
===================================================================
--- /dev/null
+++ tools/driver/ELWrapper.cpp
@@ -0,0 +1,398 @@
+//===-- ELWrapper.cpp -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// this file is only relevant for Visual C++
+#if defined( _MSC_VER )
+
+#include "lldb/Host/windows/windows.h"
+
+#include "ELWrapper.h"
+#include <vector>
+#include <assert.h>
+
+// index one of the variable arguments
+//  presuming "(EditLine *el, ..." is first in the argument list
+#define GETARG( X ) ( (void* ) *( ( (int**) &el ) + ((X) + 2) ) )
+
+// edit line EL_ADDFN function pointer type
+typedef unsigned char (*el_addfn_func)(EditLine *e, int ch);
+
+// edit line wrapper binding container
+struct el_binding
+{
+    //
+    const char   *name;
+    const char   *help;
+    // function pointer to callback routine
+    el_addfn_func func;
+    // ascii key this function is bound to
+    const char   *key;
+};
+
+// stored key bindings
+static std::vector<el_binding*> _bindings;
+
+//TODO: this should infact be related to the exact edit line context we create
+static void *clientData = NULL;
+
+// store the current prompt string
+// default to what we expect to receive anyway
+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;
+    // get the cursor position
+    CONSOLE_SCREEN_BUFFER_INFO info;
+    GetConsoleScreenBufferInfo( hout, &info );
+    // output this char
+    WriteConsoleOutputCharacterA( hout, &_in, 1, info.dwCursorPosition, &written );
+    // advance cursor position
+    info.dwCursorPosition.X++;
+    SetConsoleCursorPosition( hout, info.dwCursorPosition );
+}
+
+static void con_backspace( void )
+{
+    HANDLE hout = GetStdHandle( STD_OUTPUT_HANDLE );
+    DWORD written = 0;
+    // get cursor position
+    CONSOLE_SCREEN_BUFFER_INFO info;
+    GetConsoleScreenBufferInfo( hout, &info );
+    // nudge cursor backwards
+    info.dwCursorPosition.X--;
+    SetConsoleCursorPosition( hout, info.dwCursorPosition );
+    // blank out the last character
+    WriteConsoleOutputCharacterA( hout, " ", 1, info.dwCursorPosition, &written );
+}
+
+static void con_return( void )
+{
+    HANDLE hout = GetStdHandle( STD_OUTPUT_HANDLE );
+    DWORD written = 0;
+    // get cursor position
+    CONSOLE_SCREEN_BUFFER_INFO info;
+    GetConsoleScreenBufferInfo( hout, &info );
+    // move onto the new line
+    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;
+}
+
+// replacement get_s which is EL_BIND aware
+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 we didnt read a key
+        if ( _read == 0 )
+            continue;
+        // only interested in key events
+        if ( _record.EventType != KEY_EVENT )
+            continue;
+        // is the key down
+        if (! _record.Event.KeyEvent.bKeyDown )
+            continue;
+        // read the ascii key character
+        char _key = _record.Event.KeyEvent.uChar.AsciiChar;
+        // non ascii conformant key press
+        if ( _key == 0 )
+        {
+            // check the scan code
+            // if VK_UP scroll back through history
+            // if VK_DOWN scroll forward through history
+            continue;
+        }
+        // try to execute any bind this key may have
+        if ( runBind( _key ) )
+            continue;
+        // if we read a return key
+        if ( _key == '\n' || _key == '\r' )
+        {
+            con_return( );
+            break;
+        }
+        // key is backspace
+        if ( _key == 0x8 )
+        {
+            // avoid deleting past beginning
+            if ( head > buffer )
+            {
+                con_backspace( );
+                head--;
+            }
+            continue;
+        }
+
+        // add this key to the input buffer
+        if ( (head-buffer) < (chars-1) )
+        {
+            con_output( _key );
+            *(head++) = _key;
+        }
+    }
+    // insert end of line character
+    *head = '\0';
+
+    return buffer;
+}
+#endif
+
+// edit line initalise
+EditLine *el_init( const char *, FILE *, FILE *, FILE * )
+{
+    //
+    SetConsoleTitleA( "lldb" );
+    // return dummy handle
+    return (EditLine*) -1;
+}
+
+const char *el_gets( EditLine *el, int *length )
+{
+    // print the prompt if we have one
+    if ( _prompt != NULL )
+        printf( _prompt );
+    // create a buffer for the user input
+    char *buffer = new char[ 64 ];
+    // try to get user input string
+    if ( el_get_s( buffer, 64 ) )
+    {
+        // get the string length in 'length'
+        while ( buffer[ *length ] != '\0' )
+            (*length)++;
+        // return the input buffer
+        // remember that this memory has the be free'd somewhere
+        return buffer;
+    }
+    else
+    {
+        // on error
+        delete [] buffer;
+        return NULL;
+    }
+}
+
+int el_set( EditLine *el, int code, ... )
+{
+    int **arg = (int**) &el;
+    //
+    switch ( code )
+    {
+    // edit line set prompt message
+    case ( EL_PROMPT ):
+        {
+            // EL_PROMPT, char *(*f)( EditLine *)
+            //      define a prompt printing function as 'f', which is to return a string that
+            //      contains the prompt.
+
+            // get the function pointer from the arg list
+            void *func_vp = (void*) *(arg+2);
+            // cast to suitable prototype
+            const char* (*func_fp)(EditLine*) = (const char*(*)(EditLine *)) func_vp;
+            // call to get the prompt as a string
+            _prompt = func_fp( el );
+        }
+        break;
+    case ( EL_EDITOR ):
+        {
+            // EL_EDITOR, const char *mode
+            //      set editing mode to "emacs" or "vi"
+        }
+        break;
+    case ( EL_HIST ):
+        {
+            // EL_HIST, History *(*fun)(History *, int op, ... ), const char *ptr
+            //      defines which histroy function to use, which is usualy history(). Ptr should be the
+            //      value returned by history_init().
+        }
+        break;
+    case ( EL_ADDFN ):
+        {
+            // EL_ADDFN, const char *name, const char *help, unsigned char (*func)(EditLine *e, int ch)
+            //      add a user defined function, func), referred to as 'name' which is invoked when a key which is bound to 'name' is
+            //      entered. 'help' is a description of 'name'. at involcation time, 'ch' is the key which caused the invocation. the
+            //      return value of 'func()' should be one of:
+            //          CC_NORM         add a normal character
+            //          CC_NEWLINE      end of line was entered
+            //          CC_EOF          EOF was entered
+            //          CC_ARGHACK      expecting further command input as arguments, do nothing visually.
+            //          CC_REFRESH      refresh display.
+            //          CC_REFRESH_BEEP refresh display and beep.
+            //          CC_CURSOR       cursor moved so update and perform CC_REFRESH
+            //          CC_REDISPLAY        redisplay entire input line. this is usefull if a key binding outputs extra information.
+            //          CC_ERROR            an error occured. beep and flush tty.
+            //          CC_FATAL            fatal error, reset tty to known state.
+
+            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;
+            // add this to the bindings list
+            _bindings.push_back( binding );
+        }
+        break;
+    case ( EL_BIND ):
+        {
+            // EL_BIND, const char *, ..., NULL
+            //      perform the BIND buildin command.  Refer to editrc(5) for more information.
+
+            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 )
+{
+    // init edit line by reading the contents of 'file'
+    // nothing to do here on windows...
+    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 dummy handle
+    return (History*) -1;
+}
+
+void history_end( History * )
+{
+    assert( !"Not implemented!" );
+}
+
+int history( History *, HistEvent *, int op, ... )
+{
+    // perform operation 'op' on the history list with optional argumetns as needed by
+    // the operation.
+    return 0;
+}
+
+#endif
Index: tools/driver/ELWrapper.h
===================================================================
--- /dev/null
+++ tools/driver/ELWrapper.h
@@ -0,0 +1,122 @@
+//===-- ELWrapper.h ---------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#pragma once
+
+#include <stdio.h>
+
+// EditLine editor function return codes.
+// For user-defined function interface
+#define CC_NORM         0
+#define CC_NEWLINE      1
+#define CC_EOF          2
+#define CC_ARGHACK      3
+#define CC_REFRESH      4
+#define CC_CURSOR       5
+#define CC_ERROR        6
+#define CC_FATAL        7
+#define CC_REDISPLAY    8
+#define CC_REFRESH_BEEP 9
+
+// el_set/el_get parameters
+#define EL_PROMPT        0    // , el_pfunc_t
+#define EL_TERMINAL      1    // , const char *
+#define EL_EDITOR        2    // , const char *
+#define EL_SIGNAL        3    // , int);
+#define EL_BIND          4    // , const char *, ..., NULL
+#define EL_TELLTC        5    // , const char *, ..., NULL
+#define EL_SETTC         6    // , const char *, ..., NULL
+#define EL_ECHOTC        7    // , const char *, ..., NULL
+#define EL_SETTY         8    // , const char *, ..., NULL
+#define EL_ADDFN         9    // , const char *, const char *, el_func_t
+#define EL_HIST          10   // , hist_fun_t, const char *
+#define EL_EDITMODE      11   // , int
+#define EL_RPROMPT       12   // , el_pfunc_t
+#define EL_GETCFN        13   // , el_rfunc_t
+#define EL_CLIENTDATA    14   // , void *
+#define EL_UNBUFFERED    15   // , int
+#define EL_PREP_TERM     16   // , int
+#define EL_GETTC         17   // , const char *, ..., NULL
+#define EL_GETFP         18   // , int, FILE **
+#define EL_SETFP         19   // , int, FILE *
+#define EL_REFRESH       20   // , void
+
+#define EL_BUILTIN_GETCFN (NULL)
+
+// history defines
+#define H_FUNC           0    // , UTSL
+#define H_SETSIZE        1    // , const int
+#define H_GETSIZE        2    // , void
+#define H_FIRST          3    // , void
+#define H_LAST           4    // , void
+#define H_PREV           5    // , void
+#define H_NEXT           6    // , void
+#define H_CURR           8    // , const int
+#define H_SET            7    // , int
+#define H_ADD            9    // , const char *
+#define H_ENTER          10   // , const char *
+#define H_APPEND         11   // , const char *
+#define H_END            12   // , void
+#define H_NEXT_STR       13   // , const char *
+#define H_PREV_STR       14   // , const char *
+#define H_NEXT_EVENT     15   // , const int
+#define H_PREV_EVENT     16   // , const int
+#define H_LOAD           17   // , const char *
+#define H_SAVE           18   // , const char *
+#define H_CLEAR          19   // , void
+#define H_SETUNIQUE      20   // , int
+#define H_GETUNIQUE      21   // , void
+#define H_DEL            22   // , int
+
+struct EditLine
+{
+};
+
+struct LineInfo
+{
+    const char *buffer;
+    const char *cursor;
+    const char *lastchar;
+};
+
+struct History
+{
+};
+
+struct HistEvent
+{
+    int         num;
+    const char *str;
+};
+
+extern "C"
+{
+    // edit line API
+    EditLine        *el_init     ( const char *, FILE *, FILE *, FILE * );
+    const char      *el_gets     ( EditLine *, int * );
+    int              el_set      ( EditLine *, int, ... );
+
+    void             el_end      ( EditLine * );
+    void             el_reset    ( EditLine * );
+    int              el_getc     ( EditLine *, char * );
+    void             el_push     ( EditLine *, char * );
+    void             el_beep     ( EditLine * );
+    int              el_parse    ( EditLine *, int, const char ** );
+    int              el_get      ( EditLine *, int, ... );
+    int              el_source   ( EditLine *, const char * );
+    void             el_resize   ( EditLine * );
+    const LineInfo  *el_line     ( EditLine * );
+    int              el_insertstr( EditLine *, const char * );
+    void             el_deletestr( EditLine *, int );
+
+    // history API
+    History         *history_init( void );
+    void             history_end ( History * );
+    int              history     ( History *, HistEvent *, int, ... );
+};
\ No newline at end of file
Index: tools/driver/GetOptWrapper.cpp
===================================================================
--- /dev/null
+++ tools/driver/GetOptWrapper.cpp
@@ -0,0 +1,32 @@
+//===-- GetOptWrapper.cpp ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// this file is only relevant for Visual C++
+#if defined( _MSC_VER )
+
+#include "GetOptWrapper.h"
+
+/*
+
+// already defined in lldbHostCommon.lib due to 'getopt.inc'
+
+extern int getopt_long_only
+(
+    int                  ___argc,
+    char *const         *___argv,
+    const char          *__shortopts,
+    const struct option *__longopts,
+    int                 *__longind
+)
+{
+    return -1;
+}
+*/
+
+#endif
\ No newline at end of file
Index: tools/driver/GetOptWrapper.h
===================================================================
--- /dev/null
+++ tools/driver/GetOptWrapper.h
@@ -0,0 +1,49 @@
+//===-- GetOptWrapper.h -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_GetOptWrapper_h_
+#define lldb_GetOptWrapper_h_
+
+// from getopt.h
+#define no_argument       0
+#define required_argument 1
+#define optional_argument 2
+
+// defined int unistd.h
+extern int   optreset;
+
+// from getopt.h
+extern char *optarg;
+extern int   optind;
+extern int   opterr;
+extern int   optopt;
+
+// option structure
+struct option
+{
+    const char *name;
+    // has_arg can't be an enum because some compilers complain about
+    // type mismatches in all the code that assumes it is an int.
+    int  has_arg;
+    int *flag;
+    int  val;
+};
+
+// 
+extern int
+getopt_long_only
+(
+    int                  ___argc,
+    char *const         *___argv,
+    const char          *__shortopts,
+    const struct option *__longopts,
+    int                 *__longind
+);
+
+#endif // lldb_GetOptWrapper_h_
\ No newline at end of file
Index: tools/driver/IOChannel.cpp
===================================================================
--- tools/driver/IOChannel.cpp
+++ tools/driver/IOChannel.cpp
@@ -73,7 +73,8 @@
 IOChannel::EraseCharsBeforeCursor ()
 {
     const LineInfo *line_info  = el_line(m_edit_line);
-    el_deletestr(m_edit_line, line_info->cursor - line_info->buffer);
+    if ( line_info != NULL )
+        el_deletestr(m_edit_line, line_info->cursor - line_info->buffer);
 }
 
 unsigned char
@@ -242,19 +243,7 @@
     // Set up mutex to make sure OutErr, OutWrite and RefreshPrompt do not interfere
     // with each other when writing.
 
-    int error;
-    ::pthread_mutexattr_t attr;
-    error = ::pthread_mutexattr_init (&attr);
-    assert (error == 0);
-    error = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
-    assert (error == 0);
-    error = ::pthread_mutex_init (&m_output_mutex, &attr);
-    assert (error == 0);
-    error = ::pthread_mutexattr_destroy (&attr);
-    assert (error == 0);
-
-    error = ::pthread_cond_init (&m_output_cond, NULL);
-    assert (error == 0);
+    mutex_init( &m_output_mutex );
 
     // Initialize time that ::el_gets was last called.
 
@@ -279,8 +268,7 @@
         m_edit_line = NULL;
     }
 
-    ::pthread_cond_destroy (&m_output_cond);
-    ::pthread_mutex_destroy (&m_output_mutex);
+    mutex_free(&m_output_mutex);
 }
 
 void
@@ -347,7 +335,7 @@
         // Signal that we have finished all data up to the sync point.
         IOLocker locker (io_channel->m_output_mutex);
         io_channel->m_output_flushed = true;
-        pthread_cond_signal (&io_channel->m_output_cond);
+        condvar_signal( &io_channel->m_output_cond );
     }
 }
 
@@ -379,7 +367,7 @@
             // LibeditOutputBytesReceived has processed everything up till that mark.
             fputc (0, m_editline_out);
 
-            while (!m_output_flushed && pthread_cond_wait (&m_output_cond, &m_output_mutex))
+            while (!m_output_flushed && condvar_wait(&m_output_cond, &m_output_mutex))
             { /* wait */ }
         }
         
@@ -417,8 +405,8 @@
     return retval;
 }
 
-void *
-IOChannel::IOReadThread (void *ptr)
+thread_result_t
+IOChannel::IOReadThread( void *ptr )
 {
     IOChannel *myself = static_cast<IOChannel *> (ptr);
     myself->Run();
@@ -540,8 +528,7 @@
     if (IS_VALID_LLDB_HOST_THREAD(m_read_thread))
         return true;
 
-    m_read_thread = SBHostOS::ThreadCreate ("<lldb.driver.commandline_io>", IOChannel::IOReadThread, this,
-                                            NULL);
+    m_read_thread = SBHostOS::ThreadCreate( "<lldb.driver.commandline_io>", (lldb::thread_func_t) IOChannel::IOReadThread, this, NULL );
 
     return (IS_VALID_LLDB_HOST_THREAD(m_read_thread));
 }
@@ -670,16 +657,16 @@
     m_getting_command = new_value;
 }
 
-IOLocker::IOLocker (pthread_mutex_t &mutex) :
+IOLocker::IOLocker (lldb_mutex &mutex) :
     m_mutex_ptr (&mutex)
 {
     if (m_mutex_ptr)
-        ::pthread_mutex_lock (m_mutex_ptr);
+        mutex_lock (m_mutex_ptr);
         
 }
 
 IOLocker::~IOLocker ()
 {
     if (m_mutex_ptr)
-        ::pthread_mutex_unlock (m_mutex_ptr);
+        mutex_unlock (m_mutex_ptr);
 }
Index: tools/driver/IOChannel.h
===================================================================
--- tools/driver/IOChannel.h
+++ tools/driver/IOChannel.h
@@ -12,16 +12,6 @@
 
 #include <string>
 #include <queue>
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-#include <readline/readline.h>
-#else
-#include <editline/readline.h>
-#endif
-#include <histedit.h>
-#include <pthread.h>
-#include <sys/time.h>
-
 #include "Driver.h"
 
 class IOChannel : public lldb::SBBroadcaster
@@ -63,7 +53,7 @@
     bool
     Stop ();
 
-    static void *
+    static lldb::thread_result_t
     IOReadThread (void *);
 
     void
@@ -127,8 +117,8 @@
 
 private:
 
-    pthread_mutex_t m_output_mutex;
-    pthread_cond_t m_output_cond;
+    lldb_mutex m_output_mutex;
+    lldb_cond  m_output_cond;
     struct timeval m_enter_elgets_time;
 
     Driver *m_driver;
@@ -160,13 +150,13 @@
 {
 public:
 
-    IOLocker (pthread_mutex_t &mutex);
+    IOLocker (lldb_mutex &mutex);
 
     ~IOLocker ();
 
 protected:
 
-    pthread_mutex_t *m_mutex_ptr;
+    lldb_mutex *m_mutex_ptr;
 
 private:
 
Index: tools/driver/Mutex.cpp
===================================================================
--- /dev/null
+++ tools/driver/Mutex.cpp
@@ -0,0 +1,91 @@
+//===-- Mutex.cpp -----------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Platform.h"
+
+#if defined( _MSC_VER )
+
+// platform indepentent locking functions
+void mutex_init( lldb_mutex *mux )
+{
+    InitializeCriticalSection( mux );
+}
+
+void mutex_free( lldb_mutex *mux )
+{
+    DeleteCriticalSection( mux );
+}
+
+void mutex_lock( lldb_mutex *mux )
+{
+    EnterCriticalSection( mux );
+}
+
+void mutex_unlock( lldb_mutex *mux )
+{
+    LeaveCriticalSection( mux );
+}
+
+// condition variables
+int condvar_signal( lldb_cond *cv )
+{
+    return 0;
+}
+
+int condvar_wait( lldb_cond *cv, lldb_mutex *mux )
+{
+    return 0;
+}
+
+
+#else
+    #include <assert.h>
+
+// platform indepentent locking functions
+void mutex_init( lldb_mutex *mux )
+{
+    int error;
+    ::pthread_mutexattr_t attr;
+    error = ::pthread_mutexattr_init (&attr);
+    assert (error == 0);
+    error = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+    assert (error == 0);
+    error = ::pthread_mutex_init ( mux, &attr);
+    assert (error == 0);
+    error = ::pthread_mutexattr_destroy (&attr);
+    assert (error == 0);
+}
+
+void mutex_free( lldb_mutex *mux )
+{
+    ::pthread_mutex_destroy ( mux);
+}
+
+void mutex_lock( lldb_mutex *mux )
+{
+    ::pthread_mutex_lock( mux );
+}
+
+void mutex_unlock( lldb_mutex *mux )
+{
+    ::pthread_mutex_unlock( mux );
+}
+
+// condition variables
+int condvar_signal( lldb_cond *cv )
+{
+    return pthread_cond_signal( cv );
+}
+
+int condvar_wait( lldb_cond *cv, lldb_mutex *mux )
+{
+    return pthread_cond_wait( cv, mux );
+}
+
+#endif
\ No newline at end of file
Index: tools/driver/Platform.cpp
===================================================================
--- /dev/null
+++ tools/driver/Platform.cpp
@@ -0,0 +1,105 @@
+//===-- Platform.cpp --------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// this file is only relevant for Visual C++
+#if defined( _MSC_VER )
+
+#include <process.h>
+#include <assert.h>
+
+#include "Platform.h"
+
+// index one of the variable arguments
+//  presuming "(EditLine *el, ..." is first in the argument list
+#define GETARG( Y, X ) ( (void* ) *( ( (int**) &(Y) ) + (X) ) )
+
+// the control handler or SIGINT handler
+static sighandler_t _ctrlHandler = NULL;
+
+// the default console control handler
+BOOL WINAPI CtrlHandler( DWORD ctrlType )
+{
+    if ( _ctrlHandler != NULL )
+    {
+        _ctrlHandler( 0 );
+        return TRUE;
+    }
+    return FALSE;
+}
+
+int ioctl( int d, int request, ... )
+{
+    switch ( request )
+    {
+    // request the console windows size
+    case ( TIOCGWINSZ ):
+        {
+            // locate the window size structure on stack
+            winsize *ws = (winsize*) GETARG( d, 2 );
+            // get screen buffer information
+            CONSOLE_SCREEN_BUFFER_INFO info;
+            GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &info );
+            // fill in the columns
+            ws->ws_col = info.dwMaximumWindowSize.X;
+            //
+            return 0;
+        }
+        break;
+    default:
+        assert( !"Not implemented!" );
+    }
+    return -1;
+}
+
+int kill ( pid_t pid, int sig )
+{
+    // is the app trying to kill itself
+    if ( pid == getpid( ) )
+        exit( sig );
+    //
+    assert( !"Not implemented!" );
+    return -1;
+}
+
+int tcsetattr( int fd, int optional_actions, const struct termios *termios_p )
+{
+    assert( !"Not implemented!" );
+    return -1;
+}
+
+int tcgetattr( int fildes, struct termios *termios_p )
+{
+//  assert( !"Not implemented!" );
+    // error return value (0=success)
+    return -1;
+}
+
+sighandler_t signal( int sig, sighandler_t sigFunc )
+{
+    switch ( sig )
+    {
+    case ( SIGINT ):
+        {
+            _ctrlHandler = sigFunc;
+            SetConsoleCtrlHandler( CtrlHandler, TRUE );
+        }
+        break;
+    case ( SIGPIPE  ):
+    case ( SIGWINCH ):
+    case ( SIGTSTP  ):
+    case ( SIGCONT  ):
+        // ignore these for now
+        break;
+    default:
+        assert( !"Not implemented!" );
+    }
+    return 0;
+}
+
+#endif
\ No newline at end of file
Index: tools/driver/Platform.h
===================================================================
--- /dev/null
+++ tools/driver/Platform.h
@@ -0,0 +1,134 @@
+//===-- Platform.h ----------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_Platform_h_
+#define lldb_Platform_h_
+
+#if defined( _MSC_VER )
+
+	#define PRIu32 "u"
+	#define PRId64 "I64d"
+	#define PRIi64 "I64i"
+	#define PRIo64 "I64o"
+	#define PRIu64 "I64u"
+	#define PRIx64 "I64x"
+	#define PRIX64 "I64X"
+
+    // this will stop signal.h being included
+    #define _INC_SIGNAL
+
+    #include <io.h>
+    #include "ELWrapper.h"
+    #include "lldb/Host/windows/Windows.h"
+    #include "GetOptWrapper.h"
+
+    struct timeval
+    {
+        long tv_sec;
+        long tv_usec;
+    };
+
+    struct winsize
+    {
+        long ws_col;
+    };
+
+    typedef unsigned char   cc_t;
+    typedef unsigned int    speed_t;
+    typedef unsigned int    tcflag_t;
+
+    // fcntl.h
+    #define O_NOCTTY 0400
+
+    // ioctls.h
+    #define TIOCGWINSZ 0x5413
+
+    // signal.h
+    #define SIGPIPE  13
+    #define SIGCONT  18
+    #define SIGTSTP  20
+    #define SIGWINCH 28
+
+    // tcsetattr arguments
+    #define TCSANOW 0
+
+    #define NCCS 32
+    struct termios
+    {
+        tcflag_t c_iflag;  // input mode flags
+        tcflag_t c_oflag;  // output mode flags
+        tcflag_t c_cflag;  // control mode flags
+        tcflag_t c_lflag;  // local mode flags
+        cc_t c_line;       // line discipline
+        cc_t c_cc[NCCS];   // control characters
+        speed_t c_ispeed;  // input speed
+        speed_t c_ospeed;  // output speed
+    };
+
+    typedef long pid_t;
+    typedef CRITICAL_SECTION   lldb_mutex;
+    typedef CONDITION_VARIABLE lldb_cond;
+
+    #define STDIN_FILENO 0
+
+    #define PATH_MAX MAX_PATH
+    #define snprintf _snprintf
+
+    extern int  ioctl( int d, int request, ... );
+    extern int  kill ( pid_t pid, int sig      );
+    extern int  tcsetattr( int fd, int optional_actions, const struct termios *termios_p );
+    extern int  tcgetattr( int fildes, struct termios *termios_p );
+
+    // signal handler function pointer type
+    typedef void (*sighandler_t)(int);
+
+    // signal.h
+    #define SIGINT 2
+    // default handler
+    #define SIG_DFL ( (sighandler_t) -1 )
+    // ignored
+    #define SIG_IGN ( (sighandler_t) -2 )
+    extern sighandler_t signal( int sig, sighandler_t );
+
+#else
+
+    #if defined(__FreeBSD__)
+        #include <readline/readline.h>
+    #else
+        #include <editline/readline.h>
+    #endif
+
+	#include <inttypes.h>
+
+    #include <getopt.h>
+    #include <libgen.h>
+    #include <sys/ioctl.h>
+    #include <termios.h>
+    #include <unistd.h>
+
+    #include <histedit.h>
+    #include <pthread.h>
+    #include <sys/time.h>
+
+    typedef pthread_mutex_t lldb_mutex;
+    typedef pthread_cond_t  lldb_cond;
+
+#endif
+
+// platform independant locking functions
+extern void mutex_init  ( lldb_mutex *mux );
+extern void mutex_free  ( lldb_mutex *mux );
+extern void mutex_lock  ( lldb_mutex *mux );
+extern void mutex_unlock( lldb_mutex *mux );
+
+// platform independant condition variables
+extern int condvar_signal( lldb_cond *cnd );
+extern int condvar_wait  ( lldb_cond *cnd, lldb_mutex *mux );
+
+#endif // lldb_Platform_h_
\ No newline at end of file
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to