Beispiel #1
0
 size_t read()
 {
     namespace uf = boost::locale::utf;
     if(!isatty_) {
         DWORD read_bytes = 0;
         if(!ReadFile(handle_,buffer_,buffer_size,&read_bytes,0))
             return 0;
         return read_bytes;
     }
     DWORD read_wchars = 0;
     size_t n = wbuffer_size - wsize_;
     if(!ReadConsoleW(handle_,wbuffer_,n,&read_wchars,0))
         return 0;
     wsize_ += read_wchars;
     char *out = buffer_;
     wchar_t *b = wbuffer_;
     wchar_t *e = b + wsize_;
     wchar_t *p = b;
     uf::code_point c;
     wsize_ = e-p;
     while(p < e && (c = uf::utf_traits<wchar_t>::decode(p,e))!=uf::illegal && c!=uf::incomplete) {
         out = uf::utf_traits<char>::encode(c,out);
         wsize_ = e-p;
     }
     
     if(c==uf::illegal)
         return -1;
     
     
     if(c==uf::incomplete) {
         memmove(b,e-wsize_,sizeof(wchar_t)*wsize_);
     }
     
     return out - buffer_;
 }
Beispiel #2
0
/* ask_confirm() adapted from programs/cmd/builtins.c */
static BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info)
{
    HMODULE hmod;
    WCHAR Ybuffer[4];
    WCHAR Nbuffer[4];
    WCHAR defval[32];
    WCHAR answer[MAX_PATH];
    DWORD count;

    hmod = GetModuleHandleW(NULL);
    LoadStringW(hmod, STRING_YES, Ybuffer, ARRAY_SIZE(Ybuffer));
    LoadStringW(hmod, STRING_NO,  Nbuffer, ARRAY_SIZE(Nbuffer));
    LoadStringW(hmod, STRING_DEFAULT_VALUE, defval, ARRAY_SIZE(defval));

    while (1)
    {
        output_message(msgid, reg_info ? reg_info : defval);
        output_message(STRING_YESNO);
        ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), answer, ARRAY_SIZE(answer), &count, NULL);
        answer[0] = toupperW(answer[0]);
        if (answer[0] == Ybuffer[0])
            return TRUE;
        if (answer[0] == Nbuffer[0])
            return FALSE;
    }
}
Beispiel #3
0
static int Twapi_ReadConsole(Tcl_Interp *interp, HANDLE conh, unsigned int numchars)
{
    WCHAR buf[300];
    WCHAR *bufP;
    DWORD  len;
    int status;

    if (numchars > ARRAYSIZE(buf))
        bufP = SWSPushFrame(numchars * sizeof(WCHAR), NULL);
    else
        bufP = buf;

    if (ReadConsoleW(conh, bufP, numchars, &len, NULL)) {
        ObjSetResult(interp, ObjFromWinCharsN(bufP, len));
        status = TCL_OK;
    } else {
        TwapiReturnSystemError(interp);
        status = TCL_ERROR;
    }

    if (bufP != buf)
        SWSPopFrame();

    return status;
}
Beispiel #4
0
int win32_getc(FILE *fp)
{
    const int fd = fileno(fp);
    HANDLE hStdin;
    DWORD ret;
    wchar_t wc[3];
    char mbc[5];
    int j;
    static wchar_t wcbuf = L'\0';

    if (!(fd == fileno(stdin) && _isatty(fd) && file_system_codepage == CP_UTF8))
        return getc(fp);

    if (getc_len == 0)
    {
        hStdin = GetStdHandle(STD_INPUT_HANDLE);
        if (wcbuf) {
            wc[0] = wcbuf;
            wcbuf = L'\0';
        }
        else if (ReadConsoleW(hStdin, wc, 1, &ret, NULL) == 0)
            return EOF;
        if (0xd800<=wc[0] && wc[0]<0xdc00) {
            if (ReadConsoleW(hStdin, wc+1, 1, &ret, NULL) == 0)
                return EOF;
            if (0xdc00<=wc[1] && wc[1]<0xe000) {
                wc[2]=L'\0';
            } else {
                wcbuf=wc[1];
                wc[0]=0xfffd;    /* illegal surrogate pair */
                wc[1]=L'\0';
            }
        } else if (0xdc00<=wc[0] && wc[0]<0xe000) {
            wc[0]=0xfffd;        /* illegal surrogate pair */
            wc[1]=L'\0';
        } else {
            wc[1]=L'\0';
        }
        get_utf8_from_wstring(wc,mbc);
        j=strlen(mbc)-1;
        while(j>=0) {
            getc_buff[getc_len++]=(int)mbc[j--];
        }
    }
    return getc_buff[--getc_len];
}
Beispiel #5
0
/***********************************************************************
 *            ReadConsoleA   (KERNEL32.@)
 */
BOOL WINAPI ReadConsoleA(HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead,
			 LPDWORD lpNumberOfCharsRead, LPVOID lpReserved)
{
    LPWSTR	ptr = HeapAlloc(GetProcessHeap(), 0, nNumberOfCharsToRead * sizeof(WCHAR));
    DWORD	ncr = 0;
    BOOL	ret;

    if ((ret = ReadConsoleW(hConsoleInput, ptr, nNumberOfCharsToRead, &ncr, NULL)))
	ncr = WideCharToMultiByte(CP_ACP, 0, ptr, ncr, lpBuffer, nNumberOfCharsToRead, NULL, NULL);

    if (lpNumberOfCharsRead) *lpNumberOfCharsRead = ncr;
    HeapFree(GetProcessHeap(), 0, ptr);

    return ret;
}
Beispiel #6
0
*/	DEVICE_CMD Read_IO(REBREQ *req)
/*
**		Low level "raw" standard input function.
**
**		The request buffer must be long enough to hold result.
**
**		Result is NOT terminated (the actual field has length.)
**
***********************************************************************/
{
    long total = 0;
    int len;
    BOOL ok;

    if (GET_FLAG(req->modes, RDM_NULL)) {
        req->data[0] = 0;
        return DR_DONE;
    }

    req->actual = 0;

    if (Std_Inp) {

        if (Redir_Inp) { // always UTF-8
            len = MIN(req->length, BUF_SIZE);
            ok = ReadFile(Std_Inp, req->data, len, &total, 0);
        }
        else {
            ok = ReadConsoleW(Std_Inp, Std_Buf, BUF_SIZE-1, &total, 0);
            if (ok) {
                total = WideCharToMultiByte(CP_UTF8, 0, Std_Buf, total, req->data, req->length, 0, 0);
                if (!total) ok = FALSE;
            }
        }

        if (!ok) {
            req->error = GetLastError();
            return DR_ERROR;
        }

        req->actual = total;
    }

    return DR_DONE;
}
Beispiel #7
0
static ssize_t
Sread_win32_console(void *handle, char *buffer, size_t size)
{ GET_LD
  ansi_stream *as = handle;
  BOOL rc;
  DWORD done;
  DWORD mode;
  int isRaw = FALSE;

  if ( Suser_input &&
       Suser_input->handle == handle &&
       PL_ttymode(Suser_input) == PL_RAWTTY )
  { if ( GetConsoleMode(as->hConsole, &mode) &&
	 SetConsoleMode(as->hConsole,
			mode & ~(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT)) )
      isRaw = TRUE;
  }

  if ( !PL_wait_for_console_input(as->hConsole) )
    goto error;

  rc = ReadConsoleW(as->hConsole,
		    buffer,
		    (DWORD)(size / sizeof(wchar_t)),
		    &done,
		    NULL);

  if ( rc )
  { if ( isRaw )
      SetConsoleMode(as->hConsole, mode);
    return done * sizeof(wchar_t);
  }

error:
  if ( isRaw )
    SetConsoleMode(as->hConsole, mode);

  return -1;
}
Beispiel #8
0
static DWORD WINAPI _stdinthreadproc(LPVOID lpParameter)
{
#define STDIN_WCHAR_BUF_SIZE (1024 * 2)
#define STDIN_CCHAR_BUF_SIZE (1024 * 4)
	WCHAR wbuf[STDIN_WCHAR_BUF_SIZE];
	char cbuf[STDIN_CCHAR_BUF_SIZE];
	HANDLE hconsolein = GetStdHandle(STD_INPUT_HANDLE);
	UINT oldcp = GetConsoleCP();
	SetConsoleCP(CP_UTF8);
	(void)lpParameter;
	do
	{
		DWORD cmode;
		if(GetConsoleMode(hconsolein, &cmode))
		{
			SetConsoleMode(hconsolein, cmode | ENABLE_LINE_INPUT);
		}
	}
	while(0);
	while(1)
	{
		DWORD read;
		int x;
		if(!ReadConsoleW(hconsolein, wbuf, STDIN_WCHAR_BUF_SIZE, &read, NULL))
			break;
		cbuf[0] = 0;
		_widetoutf8(wbuf, read, cbuf, STDIN_CCHAR_BUF_SIZE);
		_fix_stdinsockaddr();
		x = bind(_stdinsock, (struct sockaddr*)&_stdinsockaddr, sizeof(struct sockaddr_in));
		_fix_stdinsockaddr();
		x = sendto(_stdinsock, cbuf, strlen(cbuf), 0, (struct sockaddr*)&_stdinsockaddr, sizeof(struct sockaddr_in));
	}
	SetConsoleCP(oldcp);
	CloseHandle(hconsolein);
	return 0;
}
Beispiel #9
0
		BOOL _ReadConsole(HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead, LPDWORD lpNumberOfCharsRead, PCONSOLE_READCONSOLE_CONTROL pInputControl)
		{
			return ReadConsoleW(hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl);
		}
Beispiel #10
0
char* win32_cgets (char* buffer, int len)
{
	/* We use console ReadConsoleA / ReadConsoleW to be able to read
	   unicode from the win32 console and fallback if seomething fails. */

	HANDLE hIn=GetStdHandle (STD_INPUT_HANDLE);
	if(hIn
	  && (hIn!=INVALID_HANDLE_VALUE)
	    && p_WideCharToMultiByte && p_MultiByteToWideChar)
	{
		DWORD dwRead;
		wchar_t wszBuf[1024];
		char  szBuf[1024];

		// NT and unicode conversion.
		if(ReadConsoleW(hIn, wszBuf, 1024, &dwRead, NULL))
		{
			// Null terminate at end.
			if(wszBuf[dwRead-1]==L'\n')
			{
				wszBuf[dwRead-1]=L'\0';
				dwRead--;
			}

			if(wszBuf[dwRead-1]==L'\r')
			{
				wszBuf[dwRead-1]=L'\0';
				dwRead--;
			}

			wchar_2_UTF8(buffer, wszBuf, len);
			return buffer;
		}

		// Win 9x and unicode conversion.
		if(ReadConsoleA(hIn, szBuf, 1024, &dwRead, NULL))
		{
			// Null terminate at end.
			if(szBuf[dwRead-1]==L'\n')
			{
				szBuf[dwRead-1]=L'\0';
				dwRead--;
			}

			if(szBuf[dwRead-1]==L'\r')
			{
				szBuf[dwRead-1]=L'\0';
				dwRead--;
			}

			// Convert from ansii to wchar_t.
			p_MultiByteToWideChar(GetConsoleCP(),
				0, szBuf, -1, wszBuf, 1024);
			// Convert from wchar_t to UTF-8.
			if(wchar_2_UTF8(buffer, wszBuf, len))
				return buffer;
		}
	}

	// Fallback.
	if(fgets(buffer, len, stdin)) return buffer;
	return NULL;
}
Beispiel #11
0
static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
{
    static int ps;
    int ok;
    char result[BUFSIZ];
    int maxsize = BUFSIZ - 1;
#if !defined(OPENSSL_SYS_WINCE)
    char *p = NULL;
    int echo_eol = !echo;

    intr_signal = 0;
    ok = 0;
    ps = 0;

    pushsig();
    ps = 1;

    if (!echo && !noecho_console(ui))
        goto error;
    ps = 2;

    result[0] = '\0';
# if defined(_WIN32)
    if (is_a_tty) {
        DWORD numread;
#  if defined(CP_UTF8)
        if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) != 0) {
            WCHAR wresult[BUFSIZ];

            if (ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE),
                         wresult, maxsize, &numread, NULL)) {
                if (numread >= 2 &&
                    wresult[numread-2] == L'\r' &&
                    wresult[numread-1] == L'\n') {
                    wresult[numread-2] = L'\n';
                    numread--;
                }
                wresult[numread] = '\0';
                if (WideCharToMultiByte(CP_UTF8, 0, wresult, -1,
                                        result, sizeof(result), NULL, 0) > 0)
                    p = result;

                OPENSSL_cleanse(wresult, sizeof(wresult));
            }
        } else
#  endif
        if (ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE),
                         result, maxsize, &numread, NULL)) {
            if (numread >= 2 &&
                result[numread-2] == '\r' && result[numread-1] == '\n') {
                result[numread-2] = '\n';
                numread--;
            }
            result[numread] = '\0';
            p = result;
        }
    } else
# elif defined(OPENSSL_SYS_MSDOS)
    if (!echo) {
        noecho_fgets(result, maxsize, tty_in);
        p = result;             /* FIXME: noecho_fgets doesn't return errors */
    } else
# endif
    p = fgets(result, maxsize, tty_in);
    if (p == NULL)
        goto error;
    if (feof(tty_in))
        goto error;
    if (ferror(tty_in))
        goto error;
    if ((p = (char *)strchr(result, '\n')) != NULL) {
        if (strip_nl)
            *p = '\0';
    } else if (!read_till_nl(tty_in))
        goto error;
    if (UI_set_result(ui, uis, result) >= 0)
        ok = 1;

 error:
    if (intr_signal == SIGINT)
        ok = -1;
    if (echo_eol)
        fprintf(tty_out, "\n");
    if (ps >= 2 && !echo && !echo_console(ui))
        ok = 0;

    if (ps >= 1)
        popsig();
#else
    ok = 1;
#endif

    OPENSSL_cleanse(result, BUFSIZ);
    return ok;
}
Beispiel #12
0
errno_t __cdecl _cgetws_s (
        wchar_t *string,
        size_t sizeInWords,
        size_t * pSizeRead
        )
{
        ULONG oldstate;
        ULONG num_read;
        errno_t err = 0;

        _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE((string != NULL), EINVAL);
        _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE((sizeInWords > 0), EINVAL);
        _RESET_STRING(string, sizeInWords);

        _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE((pSizeRead != NULL), EINVAL);

        _mlock(_CONIO_LOCK);            /* lock the console */
        __TRY

            /*
             * We need to decrement sizeInWords because ReadConsole reads as
             * many characters as the parameter passed, doesn't null terminate
             */

            --sizeInWords;
            *pSizeRead = 0;

            /*
             * If the __console_whcar_buffer_used is set, then first fill the
             * buffered character and then proceed.
             */
            if (__console_wchar_buffer_used != 0 && sizeInWords > 0)
            {
                *string++ = __console_wchar_buffer;
                __console_wchar_buffer = 0;
                --sizeInWords;
                (*pSizeRead)++;
                if (__console_wchar_buffer == L'\0')
                    sizeInWords = 0;
            }

                        /* if the user only asked for one character, we have now filled their request
                        */
            if (sizeInWords != 0)
                        {
                                /*
                                * _coninpfh, the handle to the console input, is created the first
                                * time that either _getch() or _cgets() or _kbhit() is called.
                                */

                                if ( _coninpfh == -2 )
                                        __initconin();

                                if ( _coninpfh != -1 ) {

                                        GetConsoleMode( (HANDLE)_coninpfh, &oldstate );
                                        SetConsoleMode( (HANDLE)_coninpfh, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT );
                                        // First try usual way just as _cgets
                                        if ( bUseW)
                                        {
                                                if ( !ReadConsoleW( (HANDLE)_coninpfh,
                                                                                        (LPVOID)string,
                                                                                        (DWORD)sizeInWords,
                                                                                        &num_read,
                                                                                        NULL )
                                                        )
                                                {
                                                        if ( bUseW == 2 )
                                                        {
                                                                if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
                                                                        bUseW = FALSE;
                                                                else
                                                                        bUseW = TRUE;
                                                        }
                                                }
                                                else
                                                {
                                                        bUseW = TRUE;

                                                        /* set length of string and null terminate it */

                                                        if (string[num_read - 2] == L'\r') {
                                                                (*pSizeRead) += num_read - 2;
                                                                string[num_read - 2] = L'\0';
                                                        } else if ( (num_read == sizeInWords) &&
                                                                                (string[num_read - 1] == L'\r') ) {
                                                        /* special case 1 - \r\n straddles the boundary */
                                                                (*pSizeRead) += num_read -1;
                                                                string[num_read - 1] = L'\0';
                                                        } else if ( (num_read == 1) && (string[0] == L'\n') ) {
                                                                /* special case 2 - read a single '\n'*/
                                                                string[0] = L'\0';
                                                                (*pSizeRead) += 0;
                                                        } else {
                                                                (*pSizeRead) += num_read;
                                                                string[num_read] = L'\0';
                                                        }
                                                }
                                        }
                                        // If ReadConsoleW is not present, use ReadConsoleA and then convert
                                        // to Wide Char.
                                        if ( !bUseW)
                                        {
                                                static char AStr[BUF_MAX_LEN +1];
                                                static int in_buff = 0, was_buff_full = 0;
                                                unsigned int Copy, Sz, consoleCP;
                                                unsigned int last_read = 0, i;
                                                consoleCP = GetConsoleCP();
                                                do {
                                                        if (!in_buff)
                                                        {
                                                                if ( ReadConsoleA( (HANDLE)_coninpfh,
                                                                                                        (LPVOID)AStr,
                                                                                                        BUF_MAX_LEN,
                                                                                                        &num_read,
                                                                                   NULL) &&
                                                                     num_read <= BUF_MAX_LEN
                                                                        ) {
                                                                        if (num_read >= 2 && AStr[num_read -2] == '\r')
                                                                        {
                                                                                AStr[num_read -2] = '\0';
                                                                        }
                                                                        else if (num_read == BUF_MAX_LEN &&
                                                                                        AStr[num_read -1] == '\r')
                                                                                AStr[num_read -1] = '\0';
                                                                        else if (num_read == 1 && AStr[0] == '\n')
                                                                                AStr[0] = '\0';
                                                                        else
                                                                                AStr[num_read] = '\0';
                                                                } else {
                                                                        _dosmaperr(GetLastError());
                                                                        err = errno;
                                                                }
                                                        }
                                                        for ( i = 0; AStr[i] != '\0' &&
                                                                                i < (BUF_MAX_LEN) &&
                                                                                last_read < sizeInWords; i += Sz)
                                                        {
                                                                // Check if this character is lead byte. If yes, the size
                                                                // of this character is 2. Else 1.
                                                                if ( IsDBCSLeadByteEx( GetConsoleCP(), AStr[i]))
                                                                        Sz = 2;
                                                                else
                                                                        Sz = 1;
                                                                if ( (Copy = MultiByteToWideChar( consoleCP,
                                                                                                                                MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
                                                                                                                                &AStr[i],
                                                                                                                                Sz,
                                                                                                                                &string[last_read],
                                                                                                                                (int)sizeInWords - last_read)))
                                                                {
                                                                        last_read += Copy;
                                                                }
                                                        }
                                                        // Check if this conversion was from buffer. If yes, was
                                                        // buffer fully filled when it was first read using
                                                        // ReadConsoleA. If the buffer not fully filled, we don't need
                                                        // to read more from buffer. This is necessary to make it
                                                        // behave same as if we are reading using ReadConsoleW.
                                                        if ( in_buff && i == strlen(AStr))
                                                        {
                                                                in_buff = 0;
                                                                if ( was_buff_full)
                                                                {
                                                                        was_buff_full = 0;
                                                                        continue;
                                                                }
                                                                else
                                                                {
                                                                        break;
                                                                }
                                                        }
                                                        else if ( i < (BUF_MAX_LEN))
                                                                break;
                                                } while (last_read < sizeInWords);
                                                // We save the buffer to be used again.
                                                if ( i < strlen(AStr))
                                                {
                                                        in_buff = 1;
                                                        if ( strlen(AStr) == (BUF_MAX_LEN))
                                                                was_buff_full = 1;
                                                        memmove(AStr, &AStr[i], BUF_MAX_LEN +1 - i);
                                                }
                                                string[last_read] = '\0';
                                                (*pSizeRead) += last_read;
                                        }

                                        SetConsoleMode( (HANDLE)_coninpfh, oldstate );
                                } else {
                                        _dosmaperr(GetLastError());
                                        err = errno;
                                }
                        }

        __FINALLY
            _munlock(_CONIO_LOCK);          /* unlock the console */
        __END_TRY_FINALLY

        if (err != 0)
        {
            errno = err;
        }
        return err;
}
Beispiel #13
0
static BOOL
ReadString(
    IN UINT uIdResourcePrompt,
    IN OUT PWSTR Buffer,
    IN DWORD BufferLength,
    IN BOOL ShowString)
{
    DWORD count, i;
    WCHAR charToDisplay[] = { 0, UNICODE_NULL };

    if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0))
        return FALSE;

    if (!FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)))
        return FALSE;

    if (!DisplayResourceText(uIdResourcePrompt, FALSE))
        return FALSE;

    i = 0;
    for (;;)
    {
        WCHAR readChar;
        if (!ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), &readChar, 1, &count, NULL))
            return FALSE;
        if (readChar == '\r' || readChar == '\n')
        {
            /* End of string */
            charToDisplay[0] = L'\n';
            WriteConsoleW(
                GetStdHandle(STD_OUTPUT_HANDLE),
                charToDisplay,
                wcslen(charToDisplay),
                &count,
                NULL);
            break;
        }
        if (ShowString)
        {
            /* Display the char */
            charToDisplay[0] = readChar;
            WriteConsoleW(
                GetStdHandle(STD_OUTPUT_HANDLE),
                charToDisplay,
                wcslen(charToDisplay),
                &count,
                NULL);
        }
        Buffer[i++] = readChar;
        /* FIXME: buffer overflow if the user writes too many chars! */
        UNREFERENCED_PARAMETER(BufferLength);
        /* FIXME: handle backspace */
    }
    Buffer[i] = UNICODE_NULL;

    if (!ShowString)
    {
        /* Still display the \n */
        static LPCWSTR newLine = L"\n";
        DWORD result;
        WriteConsoleW(
            GetStdHandle(STD_OUTPUT_HANDLE),
            newLine,
            wcslen(newLine),
            &result,
            NULL);
    }
    return TRUE;
}
Beispiel #14
0
arx_error arx_query(arx_utf8 const **string)
{
    arx_error error = 0;
#ifndef __WINDOWS__
    int descriptor = -1;
    arx_handle codec = NULL;
    char terminal[L_ctermid + 1] = {0};
#else
    arx_handle utf16codec = NULL;
    arx_handle utf8codec = NULL;
    HANDLE descriptor = INVALID_HANDLE_VALUE;
#endif
    static arx_utf8 storage[8192] = {0};
    arx_utf8 *iter = storage;


    if (string == NULL)
        return arx_argerror();


#ifndef __WINDOWS__
    if (ctermid(terminal) == NULL) {
        error = arx_unixerror(ENOTTY);
        goto cleanup;
    }
    if ((descriptor = open(terminal, O_RDWR, (S_IRWXU | S_IRWXG | S_IRWXO))) == -1) {
        error = arx_unixerror(errno);
        goto cleanup;
    }
    if ((error = arx_utf8codec('s', &codec))) { goto cleanup; }
#else
    if ((descriptor = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) {
        return arx_winerror(GetLastError());
    }
    if ((error = arx_utf8codec('s', &utf8codec))) { goto cleanup; }
    if ((error = arx_utf16codec('s', arx_none, &utf16codec))) { goto cleanup; }
#endif


    memset(storage, 0, sizeof(storage));
    while (1) {
#ifdef __WINDOWS__
        DWORD wcount = 0;
        WCHAR wdata[ARX_QUERY_RUNES * sizeof(WCHAR)];
#endif
        arx_count total = 0;
        arx_count count = 0;
        arx_byte bytes[ARX_QUERY_BYTES];
        arx_rune runes[ARX_QUERY_RUNES];

#ifndef __WINDOWS__
        arx_count actual = 0;
        for (count = 1; count <= ARX_QUERY_BYTES; ++count) {
            actual = (arx_count)read(descriptor, &bytes[count - 1], 1);
            if (actual == (arx_count)-1) {
                error = arx_unixerror(errno);
                goto cleanup;
            } else if (actual == 0) { break; }
            if ((error = arx_decode(codec, bytes, count, runes, ARX_QUERY_RUNES, NULL))) {
                if (error != arx_ucerror(ARX_UCERROR_INCOMPLETE)) { goto cleanup; }
            } else { break; }
        }
#else
        for (wcount = 1; wcount <= (sizeof(wdata) / sizeof(WCHAR)); ++wcount) {
            DWORD actual = 0;
            if (!ReadConsoleW(descriptor, &wdata[wcount - 1], wcount, &actual, NULL)) {
                error = arx_winerror(GetLastError());
                goto cleanup;
            }
            memcpy(bytes, wdata, (count = (actual * sizeof(WCHAR))));
            if ((error = arx_decode(utf16codec, bytes, count, runes, ARX_QUERY_RUNES, &count))) {
                if (error != arx_ucerror(ARX_UCERROR_INCOMPLETE)) { goto cleanup; }
            } else { break; }
        }
        if ((error = arx_encode(utf8codec, runes, count, bytes, ARX_QUERY_BYTES, &count))) { goto cleanup; }
#endif

        if ((total + count) >= sizeof(storage)) {
            error = arx_memerror();
            goto cleanup;
        }
#ifndef __WINDOWS__
        if ((count == 1) && (bytes[0] == '\n')) { break; }
#else
        if ((count == 1) && (bytes[0] == '\n')) { *(--iter) = '\0'; break; }
#endif
        memcpy(iter, bytes, count);
        total += count;
        iter += count;
    }


cleanup:
    *iter = '\0';
    *string = storage;
#ifndef __WINDOWS__
    if (descriptor != -1) { close(descriptor); }
    arx_close(codec);
#else
    arx_close(utf16codec);
    arx_close(utf8codec);
#endif
    return error;
}
static bool
get_console_input_win32 (const char *prompt, const bool echo, char *input, const int capacity)
{
  HANDLE in = INVALID_HANDLE_VALUE;
  HANDLE err = INVALID_HANDLE_VALUE;
  DWORD len = 0;

  ASSERT (prompt);
  ASSERT (input);
  ASSERT (capacity > 0);

  input[0] = '\0';

  in = GetStdHandle (STD_INPUT_HANDLE);
  err = get_orig_stderr ();

  if (in != INVALID_HANDLE_VALUE
      && err != INVALID_HANDLE_VALUE
      && !win32_service_interrupt (&win32_signal)
      && WriteFile (err, prompt, strlen (prompt), &len, NULL))
    {
      bool is_console = (GetFileType (in) == FILE_TYPE_CHAR);
      DWORD flags_save = 0;
      int status = 0;
      WCHAR *winput;

      if (is_console)
	{
	  if (GetConsoleMode (in, &flags_save))
	    {
	      DWORD flags = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
	      if (echo)
		flags |= ENABLE_ECHO_INPUT;
	      SetConsoleMode (in, flags);
	    }
	  else
	    is_console = 0;
	}

      if (is_console)
        {
          winput = malloc (capacity * sizeof (WCHAR));
          if (winput == NULL)
            return false;

          status = ReadConsoleW (in, winput, capacity, &len, NULL);
          WideCharToMultiByte (CP_UTF8, 0, winput, len, input, capacity, NULL, NULL);
          free (winput);
        }
      else
        status = ReadFile (in, input, capacity, &len, NULL);

      string_null_terminate (input, (int)len, capacity);
      chomp (input);

      if (!echo)
	WriteFile (err, "\r\n", 2, &len, NULL);
      if (is_console)
	SetConsoleMode (in, flags_save);
      if (status && !win32_service_interrupt (&win32_signal))
	return true;
    }

  return false;
}
Beispiel #16
0
/* putc() with code conversion */
int putc2(int c, FILE *fp)
{
    static int num[NOFILE];
        /* 0    : not in Kanji
           1..4 : in JIS Kanji and num[] bytes are in store[][]
           -1   : in JIS Kanji and store[][] is empty */
    static unsigned char store[NOFILE][4];
    const int fd = fileno(fp);
    int ret = c, output_enc;

#ifdef WIN32
    if ((fp == stdout || fp == stderr) && (_isatty(fd) || !prior_file_enc)) {
        if (sjisterminal) {
            if (is_internalUPTEX())
                output_enc = ENC_UTF8;
            else
                output_enc = ENC_SJIS;
        } else
#else
    if ((fp == stdout || fp == stderr) && !prior_file_enc) {
#endif

        output_enc = get_terminal_enc();
    } else
        output_enc = get_file_enc();

    if (num[fd] > 0) {        /* multi-byte char */
        if (is_internalUPTEX() && iskanji1(c)) { /* error */
            ret = flush(store[fd], num[fd], fp);
            num[fd] = 0;
        }
        store[fd][num[fd]] = c;
        num[fd]++;
        if (multistrlen(store[fd], num[fd], 0) == num[fd]) {
            long i = fromBUFF(store[fd], num[fd], 0);
            ret = put_multibyte(toENC(i, output_enc), fp);
            num[fd] = -1;
        } else if ((is_internalUPTEX() && num[fd] == 4) ||
                   (!is_internalUPTEX() && num[fd] == 2)) { /* error */
            ret = flush(store[fd], num[fd], fp);
            num[fd] = -1;
        }
    } else if (iskanji1(c)) { /* first multi-byte char */
        if (num[fd] == 0 && output_enc == ENC_JIS) {
            ret = put_multibyte(KANJI_IN, fp);
        }
        store[fd][0] = c;
        num[fd] = 1;
    } else {                  /* ASCII */
        if (num[fd] < 0 && output_enc == ENC_JIS) {
            put_multibyte(KANJI_OUT, fp);
        }
        ret = putc(c, fp);
        num[fd] = 0;
    }
    return ret;
}

/* fputs() with code conversion */
int fputs2(const char *s, FILE *fp)
{
    while (*s != '\0') {
        int ret = putc2((unsigned char)*s, fp);
        if (ret == EOF) return EOF;
        s++;
    }
    return 1;
}


static struct unget_st {
    int size;
    int buff[4];
} ungetbuff[NOFILE];

static int getc4(FILE *fp)
{
    struct unget_st *p = &ungetbuff[fileno(fp)];

    if (p->size == 0)
#ifdef WIN32
    {
        const int fd = fileno(fp);
        HANDLE hStdin;
        DWORD ret;
        wchar_t wc[2];
        long c;
        static wchar_t wcbuf = L'\0';

        if (!(fd == fileno(stdin) && _isatty(fd) && is_internalUPTEX()))
            return getc(fp);

        hStdin = GetStdHandle(STD_INPUT_HANDLE);
        if (wcbuf) {
            wc[0] = wcbuf;
            wcbuf = L'\0';
        }
        else if (ReadConsoleW(hStdin, wc, 1, &ret, NULL) == 0)
            return EOF;
        if (0xd800<=wc[0] && wc[0]<0xdc00) {
            if (ReadConsoleW(hStdin, wc+1, 1, &ret, NULL) == 0)
                return EOF;
            if (0xdc00<=wc[1] && wc[1]<0xe000) {
                c = UTF16StoUTF32(wc[0], wc[1]);
            } else {
                wcbuf = wc[1];
                c = U_REPLACEMENT_CHARACTER;  /* illegal upper surrogate pair */
            }
        } else if (0xdc00<=wc[0] && wc[0]<0xe000) {
            c = U_REPLACEMENT_CHARACTER;      /* illegal lower surrogate pair */
        } else {
            c = wc[0];
        }
        c = UCStoUTF8(c);
        /* always */       p->buff[p->size++]=BYTE4(c);
        if (BYTE3(c) != 0) p->buff[p->size++]=BYTE3(c);
        if (BYTE2(c) != 0) p->buff[p->size++]=BYTE2(c);
        if (BYTE1(c) != 0) p->buff[p->size++]=BYTE1(c);
    }
#else
        return getc(fp);
#endif
    return p->buff[--p->size];
}

static int ungetc4(int c, FILE *fp)
{
    struct unget_st *p = &ungetbuff[fileno(fp)];

    if (p->size >= 4) return EOF;
    return p->buff[p->size++] = c;
}


static unsigned char *buffer;
static long first, last;
static boolean combin_voiced_sound(boolean semi)
{
    int i, mblen;

    mblen = is_internalUPTEX() ? 3 : 2;
    if (last-mblen < first) return false;
    if (multistrlen(buffer,last,last-mblen) != mblen) return false;
    i = toUCS(fromBUFF(buffer,last,last-mblen));
    i = get_voiced_sound(i, semi);
    if (i == 0) return false;
    i = toBUFF(fromUCS(i));
    if (BYTE2(i) != 0) buffer[last-3] = BYTE2(i);
    /* always */       buffer[last-2] = BYTE3(i);
    /* always */       buffer[last-1] = BYTE4(i);
    return true;
}
Beispiel #17
0
// reads at most maxlength chars without echoing to the terminal into buf
bool
read_from_keyboard(char* buf, int maxlength, bool echo) {
#if !defined(WIN32)
	int ch, ch_count;

	ch = ch_count = 0;
	fflush(stdout);

	const char end_char = '\n';
	if (!echo) echo_off();
			
	while ( ch_count < maxlength-1 ) {
		ch = getchar();
		if ( ch == end_char ) {
			break;
		} else if ( ch == '\b') { // backspace
			if ( ch_count > 0 ) { ch_count--; }
			continue;
		} else if ( ch == '\003' ) { // CTRL-C
			return FALSE;
		}
		buf[ch_count++] = (char) ch;
	}
	buf[ch_count] = '\0';

	if (!echo) echo_on();
#else
	/*
	The Windows method for getting keyboard input is very different due to
	issues encountered by British users trying to use the pound character in their
	passwords.  _getch did not accept any input from using the alt+#### method of
	inputting characters nor the pound symbol when using a British keyboard layout.
	The solution was to explicitly use ReadConsoleW, the unicode version of ReadConsole,
	to take in the password and down convert it into ascii.
	See Ticket #1639
	*/
	HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);

	/*
	There is a difference between the code page the console is reporting and
	the code page that needs to be used for the ascii conversion.  Below code
	acts to provide additional debug information should the need arise.
	*/
	//UINT cPage = GetConsoleCP();
	//printf("Console CP: %d\n", cPage);

	//Preserve the previous console mode and switch back once input is complete.
	DWORD oldMode;
	GetConsoleMode(hStdin, &oldMode);
	//Default entry method is to not echo back what is entered.
	DWORD newMode = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
	if(echo)
	{
		newMode |= ENABLE_ECHO_INPUT;
	}

	SetConsoleMode(hStdin, newMode);

	int cch;
	//maxlength is passed in even though it is a fairly constant value, so need to dynamically allocate.
	wchar_t *wbuffer = new wchar_t[maxlength];
	if(!wbuffer)
	{
		return FALSE;
	}
	ReadConsoleW(hStdin, wbuffer, maxlength, (DWORD*)&cch, NULL);
	SetConsoleMode(hStdin, oldMode);
	//Zero terminate the input.
	cch = min(cch, maxlength-1);
	wbuffer[cch] = '\0';

	--cch;
	//Strip out the newline and return that ReadConsoleW appends and zero terminate again.
	while (cch >= 0)
	{
		if(wbuffer[cch] == '\r' || wbuffer[cch] == '\n')
			wbuffer[cch] = '\0';
		else
			break;
		--cch;
	}

	//Down convert the input into ASCII.
	int converted = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, wbuffer, -1, buf, maxlength, NULL, NULL);

	delete[] wbuffer;
#endif

	return TRUE;
}