Tcl Source Code

Check-in [d937aa574e]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fixed console code to properly deal with pasting of uneven lines by reading entire lines from the console at once instead of reading one byte, then the rest of the line.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-1-branch-old
Files: files | file ages | folders
SHA1: d937aa574ed55572d8e35c05e32d3fe931c8ec7e
User & Date: redman 1999-04-01 00:56:12
Context
1999-04-01
21:52
Applied Jan's patch, fixed TCL_MEM_DEBUG. check-in: 8c0c86be64 user: redman tags: core-8-1-branch-old
00:56
Fixed console code to properly deal with pasting of uneven lines by reading entire lines from the co... check-in: d937aa574e user: redman tags: core-8-1-branch-old
00:38
Added new bitmap for 8.1b3 and modified text in Finished panel. check-in: 8c3361f3a6 user: redman tags: core-8-1-branch-old
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ChangeLog.

            1  +1999-03-31    <[email protected]>
            2  +
            3  +	* win/tclWinConsole.c: WinNT has a bug when reading a single
            4  +	character from the console.  Rewrote the code for the console to
            5  +	read an entire line at a time using the reader thread.
            6  +
     1      7   1999-03-30    <[email protected]>
     2      8   
     3      9   	* unix/Makefile.in: Removed trailing backslash that broke the
     4     10   	"depend" target.
     5     11   
     6     12   	* unix/tclUnixInit.c (TclpSetInitialEncodings): Changed to avoid
     7     13   	calling setlocale().  We now look directly at env(LANG) and

Changes to win/tclWinConsole.c.

     5      5    *	and the "console" channel driver.
     6      6    *
     7      7    * Copyright (c) 1999 by Scriptics Corp.
     8      8    *
     9      9    * See the file "license.terms" for information on usage and redistribution
    10     10    * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    11     11    *
    12         - * RCS: @(#) $Id: tclWinConsole.c,v 1.1.2.5 1999/03/27 00:39:31 redman Exp $
           12  + * RCS: @(#) $Id: tclWinConsole.c,v 1.1.2.6 1999/04/01 00:56:12 redman Exp $
    13     13    */
    14     14   
    15     15   #include "tclWinInt.h"
    16     16   
    17     17   #include <dos.h>
    18     18   #include <fcntl.h>
    19     19   #include <io.h>
................................................................................
    36     36   #define CONSOLE_ASYNC	(1<<1)	/* Channel is non-blocking. */
    37     37   
    38     38   /*
    39     39    * Bit masks used in the sharedFlags field of the ConsoleInfo structure below.
    40     40    */
    41     41   
    42     42   #define CONSOLE_EOF	  (1<<2)  /* Console has reached EOF. */
    43         -#define CONSOLE_EXTRABYTE (1<<3)  /* extra byte consumed while waiting for read
    44         -				     access */
           43  +#define CONSOLE_BUFFERED  (1<<3)  /* data was read into a buffer by the reader
           44  +				     thread */
           45  +
           46  +#define CONSOLE_BUFFER_SIZE (8*1024)
    45     47   /*
    46     48    * This structure describes per-instance data for a console based channel.
    47     49    */
    48     50   
    49     51   typedef struct ConsoleInfo {
    50     52       HANDLE handle;
    51     53       int type;
................................................................................
    88     90   				 * synchronized with the writable
    89     91   				 * object. */
    90     92       int toWrite;		/* Current amount to be written.  Access is
    91     93   				 * synchronized with the writable object. */
    92     94       int readFlags;		/* Flags that are shared with the reader
    93     95   				 * thread.  Access is synchronized with the
    94     96   				 * readable object.  */
    95         -    char extraByte;             /* Buffer for extra character consumed by reade
    96         -				   thread. */
           97  +    int bytesRead;              /* number of bytes in the buffer */
           98  +    int offset;                 /* number of bytes read out of the buffer */
           99  +    char buffer[CONSOLE_BUFFER_SIZE];
          100  +                                /* Data consumed by reader thread. */
    97    101   } ConsoleInfo;
    98    102   
    99    103   typedef struct ThreadSpecificData {
   100    104       /*
   101    105        * The following pointer refers to the head of the list of consoles
   102    106        * that are being watched for file events.
   103    107        */
................................................................................
   585    589        */
   586    590       
   587    591       if (result == -1) {
   588    592   	*errorCode = errno;
   589    593   	return -1;
   590    594       }
   591    595   
   592         -    if (infoPtr->readFlags & CONSOLE_EXTRABYTE) {
          596  +    if (infoPtr->readFlags & CONSOLE_BUFFERED) {
   593    597   	/*
   594         -	 * The reader thread consumed 1 byte.
          598  +	 * Data is stored in the buffer.
   595    599   	 */
   596    600   
   597         -	*buf = infoPtr->extraByte;
   598         -	infoPtr->readFlags &= ~CONSOLE_EXTRABYTE;
   599         -	buf++;
   600         -	bufSize--;
   601         -	bytesRead = 1;
          601  +	if (bufSize < (infoPtr->bytesRead - infoPtr->offset)) {
          602  +	    memcpy(buf, &infoPtr->buffer[infoPtr->offset], bufSize);
          603  +	    bytesRead = bufSize;
          604  +	    infoPtr->offset += bufSize;
          605  +	} else {
          606  +	    memcpy(buf, &infoPtr->buffer[infoPtr->offset], bufSize);
          607  +	    bytesRead = infoPtr->bytesRead - infoPtr->offset;
   602    608   
   603         -	/*
   604         -	 * If further read attempts would block, return what we have.
   605         -	 */
          609  +	    /*
          610  +	     * Reset the buffer
          611  +	     */
          612  +	    
          613  +	    infoPtr->readFlags &= ~CONSOLE_BUFFERED;
          614  +	    infoPtr->offset = 0;
          615  +	}
   606    616   
   607         -	if (result == 0) {
   608         -	    return bytesRead;
   609         -	}
          617  +	return bytesRead;
   610    618       }
   611    619       
   612    620       /*
   613    621        * Attempt to read bufSize bytes.  The read will return immediately
   614    622        * if there is any data available.  Otherwise it will block until
   615    623        * at least one byte is available or an EOF occurs.
   616    624        */
   617    625   
   618    626       if (ReadConsole(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &count,
   619    627   		    (LPOVERLAPPED) NULL) == TRUE) {
   620         -	return bytesRead + count;
   621         -    } else if (bytesRead) {
   622         -	/*
   623         -	 * Ignore errors if we have data to return.
   624         -	 */
   625         -	
   626         -	return bytesRead;
          628  +	buf[count] = '\0';
          629  +	return count;
   627    630       }
   628    631   
   629    632       return -1;
   630    633   }
   631    634   
   632    635   /*
   633    636    *----------------------------------------------------------------------
................................................................................
   975    978   		return 1;
   976    979   	    }
   977    980   
   978    981   	    /*
   979    982   	     * Ignore errors if there is data in the buffer.
   980    983   	     */
   981    984   	    
   982         -	    if (infoPtr->readFlags & CONSOLE_EXTRABYTE) {
          985  +	    if (infoPtr->readFlags & CONSOLE_BUFFERED) {
   983    986   		return 0;
   984    987   	    } else {
   985    988   		return -1;
   986    989   	    }
   987    990   	}
   988    991   
   989    992   	/*
   990    993   	 * If there is data in the buffer, the console must be
   991    994   	 * readable (since it is a line-oriented device).
   992    995   	 */
   993    996   
   994         -	if (infoPtr->readFlags & CONSOLE_EXTRABYTE) {
          997  +	if (infoPtr->readFlags & CONSOLE_BUFFERED) {
   995    998   	    return 1;
   996    999   	}
   997   1000   
   998   1001   	
   999   1002   	/*
  1000   1003   	 * There wasn't any data available, so reset the thread and
  1001   1004   	 * try again.
................................................................................
  1016   1019    *
  1017   1020    * Results:
  1018   1021    *	None.
  1019   1022    *
  1020   1023    * Side effects:
  1021   1024    *	Signals the main thread when input become available.  May
  1022   1025    *	cause the main thread to wake up by posting a message.  May
  1023         - *	consume one byte from the console for each wait operation.
         1026  + *	one line from the console for each wait operation.
  1024   1027    *
  1025   1028    *----------------------------------------------------------------------
  1026   1029    */
  1027   1030   
  1028   1031   static DWORD WINAPI
  1029   1032   ConsoleReaderThread(LPVOID arg)
  1030   1033   {
................................................................................
  1041   1044   
  1042   1045   	count = 0;
  1043   1046   
  1044   1047   	/* 
  1045   1048   	 * Look for data on the console, but first ignore any events
  1046   1049   	 * that are not KEY_EVENTs 
  1047   1050   	 */
  1048         -	if (ReadConsole(handle, &(infoPtr->extraByte), 1, &count, NULL)
  1049         -		!= FALSE) {
         1051  +	if (ReadConsole(handle, infoPtr->buffer, CONSOLE_BUFFER_SIZE,
         1052  +		&infoPtr->bytesRead, NULL) != FALSE) {
  1050   1053   	    /*
  1051         -	     * One byte was consumed as a side effect of waiting for the
  1052         -	     * console to become readable.
         1054  +	     * Data was stored in the buffer.
  1053   1055   	     */
  1054   1056   	    
  1055         -	    infoPtr->readFlags |= CONSOLE_EXTRABYTE;
         1057  +	    infoPtr->readFlags |= CONSOLE_BUFFERED;
  1056   1058   	} else {
  1057   1059   	    DWORD err;
  1058   1060   	    err = GetLastError();
  1059   1061   	    
  1060   1062   	    if (err == EOF) {
  1061   1063   		infoPtr->readFlags = CONSOLE_EOF;
  1062   1064   	    }