summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.h
diff options
context:
space:
mode:
authorhobbs <hobbs>2000-05-19 21:30:15 (GMT)
committerhobbs <hobbs>2000-05-19 21:30:15 (GMT)
commit3140106e88c21ed304344360760f7bba8f54e7fc (patch)
tree4fb1f802b2917d98a9bf73ee85bd09237045cfbe /generic/tclIO.h
parentf7b89504bf385e5b1901c3ca9b75b5241e31ca21 (diff)
downloadtcl-3140106e88c21ed304344360760f7bba8f54e7fc.zip
tcl-3140106e88c21ed304344360760f7bba8f54e7fc.tar.gz
tcl-3140106e88c21ed304344360760f7bba8f54e7fc.tar.bz2
* generic/tclTest.c:
* generic/tclIO.c: moved channel test commands from tclIO.c to tclTest.c. * generic/tclIO.h: new file, split out from tclIO.c to allow test commands to be moved to tclTest.c. * generic/tclStubInit.c: * generic/tclIntDecls.h: * generic/tclInt.decls: removed TclTestChannel*Cmd from internal stubs table and added TclChannelEventScriptInvoker to the internal stubs table so it can be used from the test code.
Diffstat (limited to 'generic/tclIO.h')
-rw-r--r--generic/tclIO.h348
1 files changed, 348 insertions, 0 deletions
diff --git a/generic/tclIO.h b/generic/tclIO.h
new file mode 100644
index 0000000..b75aa5b
--- /dev/null
+++ b/generic/tclIO.h
@@ -0,0 +1,348 @@
+/*
+ * tclIO.h --
+ *
+ * This file provides the header information (those that are the same on
+ * all platforms and for all channel types) of Tcl's IO facilities.
+ * This is used by tclIO.c and tclTest.c.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 Scriptics Corporation
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tclIO.h,v 1.1 2000/05/19 21:30:17 hobbs Exp $
+ */
+
+/*
+ * Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not
+ * compile on systems where neither is defined. We want both defined so
+ * that we can test safely for both. In the code we still have to test for
+ * both because there may be systems on which both are defined and have
+ * different values.
+ */
+
+#if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN)))
+# define EWOULDBLOCK EAGAIN
+#endif
+#if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK)))
+# define EAGAIN EWOULDBLOCK
+#endif
+#if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK)))
+ error one of EWOULDBLOCK or EAGAIN must be defined
+#endif
+
+/*
+ * The following structure encapsulates the state for a background channel
+ * copy. Note that the data buffer for the copy will be appended to this
+ * structure.
+ */
+
+typedef struct CopyState {
+ struct Channel *readPtr; /* Pointer to input channel. */
+ struct Channel *writePtr; /* Pointer to output channel. */
+ int readFlags; /* Original read channel flags. */
+ int writeFlags; /* Original write channel flags. */
+ int toRead; /* Number of bytes to copy, or -1. */
+ int total; /* Total bytes transferred (written). */
+ Tcl_Interp *interp; /* Interp that started the copy. */
+ Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */
+ int bufSize; /* Size of appended buffer. */
+ char buffer[1]; /* Copy buffer, this must be the last
+ * field. */
+} CopyState;
+
+/*
+ * struct ChannelBuffer:
+ *
+ * Buffers data being sent to or from a channel.
+ */
+
+typedef struct ChannelBuffer {
+ int nextAdded; /* The next position into which a character
+ * will be put in the buffer. */
+ int nextRemoved; /* Position of next byte to be removed
+ * from the buffer. */
+ int bufLength; /* How big is the buffer? */
+ struct ChannelBuffer *nextPtr;
+ /* Next buffer in chain. */
+ char buf[4]; /* Placeholder for real buffer. The real
+ * buffer occuppies this space + bufSize-4
+ * bytes. This must be the last field in
+ * the structure. */
+} ChannelBuffer;
+
+#define CHANNELBUFFER_HEADER_SIZE (sizeof(ChannelBuffer) - 4)
+
+/*
+ * How much extra space to allocate in buffer to hold bytes from previous
+ * buffer (when converting to UTF-8) or to hold bytes that will go to
+ * next buffer (when converting from UTF-8).
+ */
+
+#define BUFFER_PADDING 16
+
+/*
+ * The following defines the *default* buffer size for channels.
+ */
+
+#define CHANNELBUFFER_DEFAULT_SIZE (1024 * 4)
+
+/*
+ * Structure to record a close callback. One such record exists for
+ * each close callback registered for a channel.
+ */
+
+typedef struct CloseCallback {
+ Tcl_CloseProc *proc; /* The procedure to call. */
+ ClientData clientData; /* Arbitrary one-word data to pass
+ * to the callback. */
+ struct CloseCallback *nextPtr; /* For chaining close callbacks. */
+} CloseCallback;
+
+/*
+ * The following structure describes the information saved from a call to
+ * "fileevent". This is used later when the event being waited for to
+ * invoke the saved script in the interpreter designed in this record.
+ */
+
+typedef struct EventScriptRecord {
+ struct Channel *chanPtr; /* The channel for which this script is
+ * registered. This is used only when an
+ * error occurs during evaluation of the
+ * script, to delete the handler. */
+ Tcl_Obj *scriptPtr; /* Script to invoke. */
+ Tcl_Interp *interp; /* In what interpreter to invoke script? */
+ int mask; /* Events must overlap current mask for the
+ * stored script to be invoked. */
+ struct EventScriptRecord *nextPtr;
+ /* Next in chain of records. */
+} EventScriptRecord;
+
+/*
+ * struct Channel:
+ *
+ * One of these structures is allocated for each open channel. It contains data
+ * specific to the channel but which belongs to the generic part of the Tcl
+ * channel mechanism, and it points at an instance specific (and type
+ * specific) * instance data, and at a channel type structure.
+ */
+
+typedef struct Channel {
+ char *channelName; /* The name of the channel instance in Tcl
+ * commands. Storage is owned by the generic IO
+ * code, is dynamically allocated. */
+ int flags; /* ORed combination of the flags defined
+ * below. */
+ Tcl_Encoding encoding; /* Encoding to apply when reading or writing
+ * data on this channel. NULL means no
+ * encoding is applied to data. */
+ Tcl_EncodingState inputEncodingState;
+ /* Current encoding state, used when converting
+ * input data bytes to UTF-8. */
+ int inputEncodingFlags; /* Encoding flags to pass to conversion
+ * routine when converting input data bytes to
+ * UTF-8. May be TCL_ENCODING_START before
+ * converting first byte and TCL_ENCODING_END
+ * when EOF is seen. */
+ Tcl_EncodingState outputEncodingState;
+ /* Current encoding state, used when converting
+ * UTF-8 to output data bytes. */
+ int outputEncodingFlags; /* Encoding flags to pass to conversion
+ * routine when converting UTF-8 to output
+ * data bytes. May be TCL_ENCODING_START
+ * before converting first byte and
+ * TCL_ENCODING_END when EOF is seen. */
+ Tcl_EolTranslation inputTranslation;
+ /* What translation to apply for end of line
+ * sequences on input? */
+ Tcl_EolTranslation outputTranslation;
+ /* What translation to use for generating
+ * end of line sequences in output? */
+ int inEofChar; /* If nonzero, use this as a signal of EOF
+ * on input. */
+ int outEofChar; /* If nonzero, append this to the channel
+ * when it is closed if it is open for
+ * writing. */
+ int unreportedError; /* Non-zero if an error report was deferred
+ * because it happened in the background. The
+ * value is the POSIX error code. */
+ ClientData instanceData; /* Instance-specific data provided by
+ * creator of channel. */
+
+ Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */
+ int refCount; /* How many interpreters hold references to
+ * this IO channel? */
+ CloseCallback *closeCbPtr; /* Callbacks registered to be called when the
+ * channel is closed. */
+ char *outputStage; /* Temporary staging buffer used when
+ * translating EOL before converting from
+ * UTF-8 to external form. */
+ ChannelBuffer *curOutPtr; /* Current output buffer being filled. */
+ ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */
+ ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */
+
+ ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates
+ * need to allocate a new buffer for "gets"
+ * that crosses buffer boundaries. */
+ ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
+ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
+
+ struct ChannelHandler *chPtr;/* List of channel handlers registered
+ * for this channel. */
+ int interestMask; /* Mask of all events this channel has
+ * handlers for. */
+ struct Channel *nextChanPtr;/* Next in list of channels currently open. */
+ EventScriptRecord *scriptRecordPtr;
+ /* Chain of all scripts registered for
+ * event handlers ("fileevent") on this
+ * channel. */
+ int bufSize; /* What size buffers to allocate? */
+ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */
+ CopyState *csPtr; /* State of background copy, or NULL. */
+ struct Channel* supercedes; /* Refers to channel this one was stacked upon.
+ This reference is NULL for normal channels.
+ See Tcl_StackChannel. */
+
+} Channel;
+
+/*
+ * Values for the flags field in Channel. Any ORed combination of the
+ * following flags can be stored in the field. These flags record various
+ * options and state bits about the channel. In addition to the flags below,
+ * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set.
+ */
+
+#define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in
+ * nonblocking mode. */
+#define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be
+ * flushed after every newline. */
+#define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always
+ * be flushed immediately. */
+#define BUFFER_READY (1<<6) /* Current output buffer (the
+ * curOutPtr field in the
+ * channel structure) should be
+ * output as soon as possible even
+ * though it may not be full. */
+#define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the
+ * queued output buffers has been
+ * scheduled. */
+#define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No
+ * further Tcl-level IO on the
+ * channel is allowed. */
+#define CHANNEL_EOF (1<<9) /* EOF occurred on this channel.
+ * This bit is cleared before every
+ * input operation. */
+#define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because
+ * we saw the input eofChar. This bit
+ * prevents clearing of the EOF bit
+ * before every input operation. */
+#define CHANNEL_BLOCKED (1<<11) /* EWOULDBLOCK or EAGAIN occurred
+ * on this channel. This bit is
+ * cleared before every input or
+ * output operation. */
+#define INPUT_SAW_CR (1<<12) /* Channel is in CRLF eol input
+ * translation mode and the last
+ * byte seen was a "\r". */
+#define INPUT_NEED_NL (1<<15) /* Saw a '\r' at end of last buffer,
+ * and there should be a '\n' at
+ * beginning of next buffer. */
+#define CHANNEL_DEAD (1<<13) /* The channel has been closed by
+ * the exit handler (on exit) but
+ * not deallocated. When any IO
+ * operation sees this flag on a
+ * channel, it does not call driver
+ * level functions to avoid referring
+ * to deallocated data. */
+#define CHANNEL_NEED_MORE_DATA (1<<14) /* The last input operation failed
+ * because there was not enough data
+ * to complete the operation. This
+ * flag is set when gets fails to
+ * get a complete line or when read
+ * fails to get a complete character.
+ * When set, file events will not be
+ * delivered for buffered data until
+ * the state of the channel changes. */
+
+/*
+ * For each channel handler registered in a call to Tcl_CreateChannelHandler,
+ * there is one record of the following type. All of records for a specific
+ * channel are chained together in a singly linked list which is stored in
+ * the channel structure.
+ */
+
+typedef struct ChannelHandler {
+ Channel *chanPtr; /* The channel structure for this channel. */
+ int mask; /* Mask of desired events. */
+ Tcl_ChannelProc *proc; /* Procedure to call in the type of
+ * Tcl_CreateChannelHandler. */
+ ClientData clientData; /* Argument to pass to procedure. */
+ struct ChannelHandler *nextPtr;
+ /* Next one in list of registered handlers. */
+} ChannelHandler;
+
+/*
+ * This structure keeps track of the current ChannelHandler being invoked in
+ * the current invocation of ChannelHandlerEventProc. There is a potential
+ * problem if a ChannelHandler is deleted while it is the current one, since
+ * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this
+ * problem, structures of the type below indicate the next handler to be
+ * processed for any (recursively nested) dispatches in progress. The
+ * nextHandlerPtr field is updated if the handler being pointed to is deleted.
+ * The nextPtr field is used to chain together all recursive invocations, so
+ * that Tcl_DeleteChannelHandler can find all the recursively nested
+ * invocations of ChannelHandlerEventProc and compare the handler being
+ * deleted against the NEXT handler to be invoked in that invocation; when it
+ * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr
+ * field of the structure to the next handler.
+ */
+
+typedef struct NextChannelHandler {
+ ChannelHandler *nextHandlerPtr; /* The next handler to be invoked in
+ * this invocation. */
+ struct NextChannelHandler *nestedHandlerPtr;
+ /* Next nested invocation of
+ * ChannelHandlerEventProc. */
+} NextChannelHandler;
+
+
+/*
+ * The following structure describes the event that is added to the Tcl
+ * event queue by the channel handler check procedure.
+ */
+
+typedef struct ChannelHandlerEvent {
+ Tcl_Event header; /* Standard header for all events. */
+ Channel *chanPtr; /* The channel that is ready. */
+ int readyMask; /* Events that have occurred. */
+} ChannelHandlerEvent;
+
+/*
+ * The following structure is used by Tcl_GetsObj() to encapsulates the
+ * state for a "gets" operation.
+ */
+
+typedef struct GetsState {
+ Tcl_Obj *objPtr; /* The object to which UTF-8 characters
+ * will be appended. */
+ char **dstPtr; /* Pointer into objPtr's string rep where
+ * next character should be stored. */
+ Tcl_Encoding encoding; /* The encoding to use to convert raw bytes
+ * to UTF-8. */
+ ChannelBuffer *bufPtr; /* The current buffer of raw bytes being
+ * emptied. */
+ Tcl_EncodingState state; /* The encoding state just before the last
+ * external to UTF-8 conversion in
+ * FilterInputBytes(). */
+ int rawRead; /* The number of bytes removed from bufPtr
+ * in the last call to FilterInputBytes(). */
+ int bytesWrote; /* The number of bytes of UTF-8 data
+ * appended to objPtr during the last call to
+ * FilterInputBytes(). */
+ int charsWrote; /* The corresponding number of UTF-8
+ * characters appended to objPtr during the
+ * last call to FilterInputBytes(). */
+ int totalChars; /* The total number of UTF-8 characters
+ * appended to objPtr so far, just before the
+ * last call to FilterInputBytes(). */
+} GetsState;