os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclIO.h
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/generic/tclIO.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,417 @@
1.4 +/*
1.5 + * tclIO.h --
1.6 + *
1.7 + * This file provides the generic portions (those that are the same on
1.8 + * all platforms and for all channel types) of Tcl's IO facilities.
1.9 + *
1.10 + * Copyright (c) 1998-2000 Ajuba Solutions
1.11 + * Copyright (c) 1995-1997 Sun Microsystems, Inc.
1.12 + *
1.13 + * See the file "license.terms" for information on usage and redistribution
1.14 + * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
1.15 + *
1.16 + * RCS: @(#) $Id: tclIO.h,v 1.5.4.2 2004/07/15 20:46:19 andreas_kupries Exp $
1.17 + */
1.18 +
1.19 +/*
1.20 + * Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not
1.21 + * compile on systems where neither is defined. We want both defined so
1.22 + * that we can test safely for both. In the code we still have to test for
1.23 + * both because there may be systems on which both are defined and have
1.24 + * different values.
1.25 + */
1.26 +
1.27 +#if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN)))
1.28 +# define EWOULDBLOCK EAGAIN
1.29 +#endif
1.30 +#if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK)))
1.31 +# define EAGAIN EWOULDBLOCK
1.32 +#endif
1.33 +#if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK)))
1.34 +error one of EWOULDBLOCK or EAGAIN must be defined
1.35 +#endif
1.36 +
1.37 +/*
1.38 + * The following structure encapsulates the state for a background channel
1.39 + * copy. Note that the data buffer for the copy will be appended to this
1.40 + * structure.
1.41 + */
1.42 +
1.43 +typedef struct CopyState {
1.44 + struct Channel *readPtr; /* Pointer to input channel. */
1.45 + struct Channel *writePtr; /* Pointer to output channel. */
1.46 + int readFlags; /* Original read channel flags. */
1.47 + int writeFlags; /* Original write channel flags. */
1.48 + int toRead; /* Number of bytes to copy, or -1. */
1.49 + int total; /* Total bytes transferred (written). */
1.50 + Tcl_Interp *interp; /* Interp that started the copy. */
1.51 + Tcl_Obj *cmdPtr; /* Command to be invoked at completion. */
1.52 + int bufSize; /* Size of appended buffer. */
1.53 + char buffer[1]; /* Copy buffer, this must be the last
1.54 + * field. */
1.55 +} CopyState;
1.56 +
1.57 +/*
1.58 + * struct ChannelBuffer:
1.59 + *
1.60 + * Buffers data being sent to or from a channel.
1.61 + */
1.62 +
1.63 +typedef struct ChannelBuffer {
1.64 + int nextAdded; /* The next position into which a character
1.65 + * will be put in the buffer. */
1.66 + int nextRemoved; /* Position of next byte to be removed
1.67 + * from the buffer. */
1.68 + int bufLength; /* How big is the buffer? */
1.69 + struct ChannelBuffer *nextPtr;
1.70 + /* Next buffer in chain. */
1.71 + char buf[4]; /* Placeholder for real buffer. The real
1.72 + * buffer occuppies this space + bufSize-4
1.73 + * bytes. This must be the last field in
1.74 + * the structure. */
1.75 +} ChannelBuffer;
1.76 +
1.77 +#define CHANNELBUFFER_HEADER_SIZE (sizeof(ChannelBuffer) - 4)
1.78 +
1.79 +/*
1.80 + * How much extra space to allocate in buffer to hold bytes from previous
1.81 + * buffer (when converting to UTF-8) or to hold bytes that will go to
1.82 + * next buffer (when converting from UTF-8).
1.83 + */
1.84 +
1.85 +#define BUFFER_PADDING 16
1.86 +
1.87 +/*
1.88 + * The following defines the *default* buffer size for channels.
1.89 + */
1.90 +
1.91 +#define CHANNELBUFFER_DEFAULT_SIZE (1024 * 4)
1.92 +
1.93 +/*
1.94 + * Structure to record a close callback. One such record exists for
1.95 + * each close callback registered for a channel.
1.96 + */
1.97 +
1.98 +typedef struct CloseCallback {
1.99 + Tcl_CloseProc *proc; /* The procedure to call. */
1.100 + ClientData clientData; /* Arbitrary one-word data to pass
1.101 + * to the callback. */
1.102 + struct CloseCallback *nextPtr; /* For chaining close callbacks. */
1.103 +} CloseCallback;
1.104 +
1.105 +/*
1.106 + * The following structure describes the information saved from a call to
1.107 + * "fileevent". This is used later when the event being waited for to
1.108 + * invoke the saved script in the interpreter designed in this record.
1.109 + */
1.110 +
1.111 +typedef struct EventScriptRecord {
1.112 + struct Channel *chanPtr; /* The channel for which this script is
1.113 + * registered. This is used only when an
1.114 + * error occurs during evaluation of the
1.115 + * script, to delete the handler. */
1.116 + Tcl_Obj *scriptPtr; /* Script to invoke. */
1.117 + Tcl_Interp *interp; /* In what interpreter to invoke script? */
1.118 + int mask; /* Events must overlap current mask for the
1.119 + * stored script to be invoked. */
1.120 + struct EventScriptRecord *nextPtr;
1.121 + /* Next in chain of records. */
1.122 +} EventScriptRecord;
1.123 +
1.124 +/*
1.125 + * struct Channel:
1.126 + *
1.127 + * One of these structures is allocated for each open channel. It contains data
1.128 + * specific to the channel but which belongs to the generic part of the Tcl
1.129 + * channel mechanism, and it points at an instance specific (and type
1.130 + * specific) * instance data, and at a channel type structure.
1.131 + */
1.132 +
1.133 +typedef struct Channel {
1.134 + struct ChannelState *state; /* Split out state information */
1.135 +
1.136 + ClientData instanceData; /* Instance-specific data provided by
1.137 + * creator of channel. */
1.138 + Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */
1.139 +
1.140 + struct Channel *downChanPtr;/* Refers to channel this one was stacked
1.141 + * upon. This reference is NULL for normal
1.142 + * channels. See Tcl_StackChannel. */
1.143 + struct Channel *upChanPtr; /* Refers to the channel above stacked this
1.144 + * one. NULL for the top most channel. */
1.145 +
1.146 + /*
1.147 + * Intermediate buffers to hold pre-read data for consumption by a
1.148 + * newly stacked transformation. See 'Tcl_StackChannel'.
1.149 + */
1.150 + ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
1.151 + ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
1.152 +} Channel;
1.153 +
1.154 +/*
1.155 + * struct ChannelState:
1.156 + *
1.157 + * One of these structures is allocated for each open channel. It contains data
1.158 + * specific to the channel but which belongs to the generic part of the Tcl
1.159 + * channel mechanism, and it points at an instance specific (and type
1.160 + * specific) * instance data, and at a channel type structure.
1.161 + */
1.162 +
1.163 +typedef struct ChannelState {
1.164 + CONST char *channelName; /* The name of the channel instance in Tcl
1.165 + * commands. Storage is owned by the generic IO
1.166 + * code, is dynamically allocated. */
1.167 + int flags; /* ORed combination of the flags defined
1.168 + * below. */
1.169 + Tcl_Encoding encoding; /* Encoding to apply when reading or writing
1.170 + * data on this channel. NULL means no
1.171 + * encoding is applied to data. */
1.172 + Tcl_EncodingState inputEncodingState;
1.173 + /* Current encoding state, used when converting
1.174 + * input data bytes to UTF-8. */
1.175 + int inputEncodingFlags; /* Encoding flags to pass to conversion
1.176 + * routine when converting input data bytes to
1.177 + * UTF-8. May be TCL_ENCODING_START before
1.178 + * converting first byte and TCL_ENCODING_END
1.179 + * when EOF is seen. */
1.180 + Tcl_EncodingState outputEncodingState;
1.181 + /* Current encoding state, used when converting
1.182 + * UTF-8 to output data bytes. */
1.183 + int outputEncodingFlags; /* Encoding flags to pass to conversion
1.184 + * routine when converting UTF-8 to output
1.185 + * data bytes. May be TCL_ENCODING_START
1.186 + * before converting first byte and
1.187 + * TCL_ENCODING_END when EOF is seen. */
1.188 + TclEolTranslation inputTranslation;
1.189 + /* What translation to apply for end of line
1.190 + * sequences on input? */
1.191 + TclEolTranslation outputTranslation;
1.192 + /* What translation to use for generating
1.193 + * end of line sequences in output? */
1.194 + int inEofChar; /* If nonzero, use this as a signal of EOF
1.195 + * on input. */
1.196 + int outEofChar; /* If nonzero, append this to the channel
1.197 + * when it is closed if it is open for
1.198 + * writing. */
1.199 + int unreportedError; /* Non-zero if an error report was deferred
1.200 + * because it happened in the background. The
1.201 + * value is the POSIX error code. */
1.202 + int refCount; /* How many interpreters hold references to
1.203 + * this IO channel? */
1.204 +
1.205 + CloseCallback *closeCbPtr; /* Callbacks registered to be called when the
1.206 + * channel is closed. */
1.207 + char *outputStage; /* Temporary staging buffer used when
1.208 + * translating EOL before converting from
1.209 + * UTF-8 to external form. */
1.210 + ChannelBuffer *curOutPtr; /* Current output buffer being filled. */
1.211 + ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */
1.212 + ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */
1.213 +
1.214 + ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates
1.215 + * need to allocate a new buffer for "gets"
1.216 + * that crosses buffer boundaries. */
1.217 + ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
1.218 + ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
1.219 +
1.220 + struct ChannelHandler *chPtr;/* List of channel handlers registered
1.221 + * for this channel. */
1.222 + int interestMask; /* Mask of all events this channel has
1.223 + * handlers for. */
1.224 + EventScriptRecord *scriptRecordPtr;
1.225 + /* Chain of all scripts registered for
1.226 + * event handlers ("fileevent") on this
1.227 + * channel. */
1.228 +
1.229 + int bufSize; /* What size buffers to allocate? */
1.230 + Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */
1.231 + CopyState *csPtr; /* State of background copy, or NULL. */
1.232 + Channel *topChanPtr; /* Refers to topmost channel in a stack.
1.233 + * Never NULL. */
1.234 + Channel *bottomChanPtr; /* Refers to bottommost channel in a stack.
1.235 + * This channel can be relied on to live as
1.236 + * long as the channel state. Never NULL. */
1.237 + struct ChannelState *nextCSPtr;
1.238 + /* Next in list of channels currently open. */
1.239 + Tcl_ThreadId managingThread; /* TIP #10: Id of the thread managing
1.240 + * this stack of channels. */
1.241 +} ChannelState;
1.242 +
1.243 +/*
1.244 + * Values for the flags field in Channel. Any ORed combination of the
1.245 + * following flags can be stored in the field. These flags record various
1.246 + * options and state bits about the channel. In addition to the flags below,
1.247 + * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set.
1.248 + */
1.249 +
1.250 +#define CHANNEL_NONBLOCKING (1<<3) /* Channel is currently in
1.251 + * nonblocking mode. */
1.252 +#define CHANNEL_LINEBUFFERED (1<<4) /* Output to the channel must be
1.253 + * flushed after every newline. */
1.254 +#define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always
1.255 + * be flushed immediately. */
1.256 +#define BUFFER_READY (1<<6) /* Current output buffer (the
1.257 + * curOutPtr field in the
1.258 + * channel structure) should be
1.259 + * output as soon as possible even
1.260 + * though it may not be full. */
1.261 +#define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the
1.262 + * queued output buffers has been
1.263 + * scheduled. */
1.264 +#define CHANNEL_CLOSED (1<<8) /* Channel has been closed. No
1.265 + * further Tcl-level IO on the
1.266 + * channel is allowed. */
1.267 +#define CHANNEL_EOF (1<<9) /* EOF occurred on this channel.
1.268 + * This bit is cleared before every
1.269 + * input operation. */
1.270 +#define CHANNEL_STICKY_EOF (1<<10) /* EOF occurred on this channel because
1.271 + * we saw the input eofChar. This bit
1.272 + * prevents clearing of the EOF bit
1.273 + * before every input operation. */
1.274 +#define CHANNEL_BLOCKED (1<<11) /* EWOULDBLOCK or EAGAIN occurred
1.275 + * on this channel. This bit is
1.276 + * cleared before every input or
1.277 + * output operation. */
1.278 +#define INPUT_SAW_CR (1<<12) /* Channel is in CRLF eol input
1.279 + * translation mode and the last
1.280 + * byte seen was a "\r". */
1.281 +#define INPUT_NEED_NL (1<<15) /* Saw a '\r' at end of last buffer,
1.282 + * and there should be a '\n' at
1.283 + * beginning of next buffer. */
1.284 +#define CHANNEL_DEAD (1<<13) /* The channel has been closed by
1.285 + * the exit handler (on exit) but
1.286 + * not deallocated. When any IO
1.287 + * operation sees this flag on a
1.288 + * channel, it does not call driver
1.289 + * level functions to avoid referring
1.290 + * to deallocated data. */
1.291 +#define CHANNEL_NEED_MORE_DATA (1<<14) /* The last input operation failed
1.292 + * because there was not enough data
1.293 + * to complete the operation. This
1.294 + * flag is set when gets fails to
1.295 + * get a complete line or when read
1.296 + * fails to get a complete character.
1.297 + * When set, file events will not be
1.298 + * delivered for buffered data until
1.299 + * the state of the channel changes. */
1.300 +#define CHANNEL_RAW_MODE (1<<16) /* When set, notes that the Raw API is
1.301 + * being used. */
1.302 +#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
1.303 +#define CHANNEL_TIMER_FEV (1<<17) /* When set the event we are
1.304 + * notified by is a fileevent
1.305 + * generated by a timer. We
1.306 + * don't know if the driver
1.307 + * has more data and should
1.308 + * not try to read from it. If
1.309 + * the system needs more than
1.310 + * is in the buffers out read
1.311 + * routines will simulate a
1.312 + * short read (0 characters
1.313 + * read) */
1.314 +#define CHANNEL_HAS_MORE_DATA (1<<18) /* Set by NotifyChannel for a
1.315 + * channel if and only if the
1.316 + * channel is configured
1.317 + * non-blocking, the driver
1.318 + * for said channel has no
1.319 + * blockmodeproc, and data has
1.320 + * arrived for reading at the
1.321 + * OS level). A GetInput will
1.322 + * pass reading from the
1.323 + * driver if the channel is
1.324 + * non-blocking, without
1.325 + * blockmode proc and the flag
1.326 + * has not been set. A read
1.327 + * will be performed if the
1.328 + * flag is set. This will
1.329 + * reset the flag as well. */
1.330 +#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
1.331 +
1.332 +#define CHANNEL_INCLOSE (1<<19) /* Channel is currently being
1.333 + * closed. Its structures are
1.334 + * still live and usable, but
1.335 + * it may not be closed again
1.336 + * from within the close handler.
1.337 + */
1.338 +
1.339 +/*
1.340 + * For each channel handler registered in a call to Tcl_CreateChannelHandler,
1.341 + * there is one record of the following type. All of records for a specific
1.342 + * channel are chained together in a singly linked list which is stored in
1.343 + * the channel structure.
1.344 + */
1.345 +
1.346 +typedef struct ChannelHandler {
1.347 + Channel *chanPtr; /* The channel structure for this channel. */
1.348 + int mask; /* Mask of desired events. */
1.349 + Tcl_ChannelProc *proc; /* Procedure to call in the type of
1.350 + * Tcl_CreateChannelHandler. */
1.351 + ClientData clientData; /* Argument to pass to procedure. */
1.352 + struct ChannelHandler *nextPtr;
1.353 + /* Next one in list of registered handlers. */
1.354 +} ChannelHandler;
1.355 +
1.356 +/*
1.357 + * This structure keeps track of the current ChannelHandler being invoked in
1.358 + * the current invocation of ChannelHandlerEventProc. There is a potential
1.359 + * problem if a ChannelHandler is deleted while it is the current one, since
1.360 + * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this
1.361 + * problem, structures of the type below indicate the next handler to be
1.362 + * processed for any (recursively nested) dispatches in progress. The
1.363 + * nextHandlerPtr field is updated if the handler being pointed to is deleted.
1.364 + * The nextPtr field is used to chain together all recursive invocations, so
1.365 + * that Tcl_DeleteChannelHandler can find all the recursively nested
1.366 + * invocations of ChannelHandlerEventProc and compare the handler being
1.367 + * deleted against the NEXT handler to be invoked in that invocation; when it
1.368 + * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr
1.369 + * field of the structure to the next handler.
1.370 + */
1.371 +
1.372 +typedef struct NextChannelHandler {
1.373 + ChannelHandler *nextHandlerPtr; /* The next handler to be invoked in
1.374 + * this invocation. */
1.375 + struct NextChannelHandler *nestedHandlerPtr;
1.376 + /* Next nested invocation of
1.377 + * ChannelHandlerEventProc. */
1.378 +} NextChannelHandler;
1.379 +
1.380 +
1.381 +/*
1.382 + * The following structure describes the event that is added to the Tcl
1.383 + * event queue by the channel handler check procedure.
1.384 + */
1.385 +
1.386 +typedef struct ChannelHandlerEvent {
1.387 + Tcl_Event header; /* Standard header for all events. */
1.388 + Channel *chanPtr; /* The channel that is ready. */
1.389 + int readyMask; /* Events that have occurred. */
1.390 +} ChannelHandlerEvent;
1.391 +
1.392 +/*
1.393 + * The following structure is used by Tcl_GetsObj() to encapsulates the
1.394 + * state for a "gets" operation.
1.395 + */
1.396 +
1.397 +typedef struct GetsState {
1.398 + Tcl_Obj *objPtr; /* The object to which UTF-8 characters
1.399 + * will be appended. */
1.400 + char **dstPtr; /* Pointer into objPtr's string rep where
1.401 + * next character should be stored. */
1.402 + Tcl_Encoding encoding; /* The encoding to use to convert raw bytes
1.403 + * to UTF-8. */
1.404 + ChannelBuffer *bufPtr; /* The current buffer of raw bytes being
1.405 + * emptied. */
1.406 + Tcl_EncodingState state; /* The encoding state just before the last
1.407 + * external to UTF-8 conversion in
1.408 + * FilterInputBytes(). */
1.409 + int rawRead; /* The number of bytes removed from bufPtr
1.410 + * in the last call to FilterInputBytes(). */
1.411 + int bytesWrote; /* The number of bytes of UTF-8 data
1.412 + * appended to objPtr during the last call to
1.413 + * FilterInputBytes(). */
1.414 + int charsWrote; /* The corresponding number of UTF-8
1.415 + * characters appended to objPtr during the
1.416 + * last call to FilterInputBytes(). */
1.417 + int totalChars; /* The total number of UTF-8 characters
1.418 + * appended to objPtr so far, just before the
1.419 + * last call to FilterInputBytes(). */
1.420 +} GetsState;