1 #ifndef MEMCHAN_H
2 /*
3  * memchanInt.h --
4  *
5  *	Internal definitions.
6  *
7  * Copyright (C) 1996-1999 Andreas Kupries (a.kupries@westend.com)
8  * All rights reserved.
9  *
10  * Permission is hereby granted, without written agreement and without
11  * license or royalty fees, to use, copy, modify, and distribute this
12  * software and its documentation for any purpose, provided that the
13  * above copyright notice and the following two paragraphs appear in
14  * all copies of this software.
15  *
16  * IN NO EVENT SHALL I BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
17  * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
18  * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE
19  * POSSIBILITY OF SUCH DAMAGE.
20  *
21  * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
24  * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
25  * ENHANCEMENTS, OR MODIFICATIONS.
26  *
27  * CVS: $Id: memchanInt.h,v 1.25 2010/12/09 18:18:02 andreas_kupries Exp $
28  */
29 
30 
31 #include <errno.h>
32 #include <string.h> /* strncmp */
33 #define USE_NON_CONST
34 #include <tcl.h>
35 #ifdef HAVE_STDINT_H
36 #include <stdint.h>
37 #endif
38 #ifdef HAVE_INTTYPES_H
39 #include <inttypes.h>
40 #endif
41 #ifdef STDC_HEADERS
42 #include <stddef.h>
43 #endif
44 
45 /*
46  * Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not
47  * compile on systems where neither is defined. We want both defined so
48  * that we can test safely for both. In the code we still have to test for
49  * both because there may be systems on which both are defined and have
50  * different values.
51  *
52  * Taken from tcl/generic/tclIO.h
53  * Might be better if the 'tclPort' headers were public.
54  */
55 
56 #if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN)))
57 #   define EWOULDBLOCK EAGAIN
58 #endif
59 #if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK)))
60 #   define EAGAIN EWOULDBLOCK
61 #endif
62 #if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK)))
63 error one of EWOULDBLOCK or EAGAIN must be defined
64 #endif
65 
66 #ifdef __cplusplus
67 extern "C" {
68 #endif
69 
70 /*
71  * Number of bytes used to extend a storage area found to small.
72  */
73 
74 #define INCREMENT (512)
75 
76 /*
77  * Number of milliseconds to wait between polls of channel state,
78  * e.g. generation of readable/writable events.
79  *
80  * Relevant for only Tcl 8.0 and beyond.
81  */
82 
83 #define DELAY (5)
84 
85 /* Detect Tcl 8.1 and beyond => Stubs, panic <-> Tcl_Panic
86  */
87 
88 #define GT81 ((TCL_MAJOR_VERSION > 8) || \
89 ((TCL_MAJOR_VERSION == 8) && \
90  (TCL_MINOR_VERSION >= 1)))
91 
92 /* Detect Tcl 8.4 and beyond => API CONSTification
93  */
94 
95 #define GT84 ((TCL_MAJOR_VERSION > 8) || \
96 ((TCL_MAJOR_VERSION == 8) && \
97  (TCL_MINOR_VERSION >= 4)))
98 
99 /* There are currently two cases to consider
100  *
101  * 1. An API function called with a const string, which was non-const
102  *    in the relevant argument before 8.4 and is now const in that
103  *    argument. This meanst that before 8.4 the actual parameter
104  *    required a cast to unconst the value and doesn't require the
105  *    cast for 8.4 and beyond.
106  *
107  *    This is solved by the macro MC_UNCONSTB84
108  *    = MemChan unCONST Before 8.4
109  *
110  * 2. The result of an API function was non-const before 8.4 and is
111  *    now const, and is assinged to a non-const string pointer.
112  */
113 
114 #if GT84
115 #define MC_UNCONSTB84
116 #else
117 #define MC_UNCONSTB84   (char*)
118 #endif /* GT84 */
119 
120 #ifndef CONST84
121 #define CONST84
122 #endif
123 
124 /*
125  * Pre-8.3 the Tcl_ChannelTypeVersion was not defined.
126  */
127 #if ((TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION < 3))
128 typedef Tcl_DriverBlockModeProc* Tcl_ChannelTypeVersion;
129 #endif
130 
131 #if ! (GT81)
132 /* Enable use of procedure internal to tcl. Necessary only
133  * for versions of tcl below 8.1.
134  */
135 
136 EXTERN void
137 panic _ANSI_ARGS_ (TCL_VARARGS(char*, format));
138 
139 #undef  Tcl_Panic
140 #define Tcl_Panic panic
141 #endif
142 
143 #undef HAVE_LTOA /* Forcing 'sprintf'. HP ltoa function signature may diverge */
144 #ifdef HAVE_LTOA
145 #define LTOA(x,str) ltoa (x, str, 10)
146 #else
147 #define LTOA(x,str) sprintf (str, "%lu", (unsigned long) (x))
148 #endif
149 
150 /*
151  * Macros used to cast between pointers and integers (e.g. when storing an int
152  * in ClientData), on 64-bit architectures they avoid gcc warning about "cast
153  * to/from pointer from/to integer of different size".
154  *
155  * Copied from tclInt.h.
156  */
157 
158 #if !defined(INT2PTR) && !defined(PTR2INT)
159 #   if defined(HAVE_INTPTR_T) || defined(intptr_t)
160 #       define INT2PTR(p) ((void *)(intptr_t)(p))
161 #       define PTR2INT(p) ((int)(intptr_t)(p))
162 #   else
163 #       define INT2PTR(p) ((void *)(p))
164 #       define PTR2INT(p) ((int)(p))
165 #   endif
166 #endif
167 #if !defined(UINT2PTR) && !defined(PTR2UINT)
168 #   if defined(HAVE_UINTPTR_T) || defined(uintptr_t)
169 #       define UINT2PTR(p) ((void *)(uintptr_t)(p))
170 #       define PTR2UINT(p) ((unsigned int)(uintptr_t)(p))
171 #   else
172 #       define UINT2PTR(p) ((void *)(p))
173 #       define PTR2UINT(p) ((unsigned int)(p))
174 #   endif
175 #endif
176 
177 
178 /* Internal command visible to other parts of the package.
179  */
180 
181 extern int
182 MemchanCmd _ANSI_ARGS_ ((ClientData notUsed,
183 			 Tcl_Interp* interp,
184 			 int objc, Tcl_Obj*CONST objv[]));
185 
186 extern int
187 MemchanFifoCmd _ANSI_ARGS_ ((ClientData notUsed,
188 			     Tcl_Interp* interp,
189 			     int objc, Tcl_Obj*CONST objv[]));
190 
191 extern int
192 MemchanFifo2Cmd _ANSI_ARGS_ ((ClientData notUsed,
193 			      Tcl_Interp* interp,
194 			      int objc, Tcl_Obj*CONST objv[]));
195 
196 extern int
197 MemchanNullCmd _ANSI_ARGS_ ((ClientData notUsed,
198 			     Tcl_Interp* interp,
199 			     int objc, Tcl_Obj*CONST objv[]));
200 
201 extern int
202 MemchanRandomCmd _ANSI_ARGS_ ((ClientData notUsed,
203                   Tcl_Interp* interp,
204 			      int objc, Tcl_Obj*CONST objv[]));
205 
206 extern int
207 MemchanZeroCmd _ANSI_ARGS_ ((ClientData notUsed,
208                   Tcl_Interp* interp,
209 			      int objc, Tcl_Obj*CONST objv[]));
210 
211 /* Generator procedure for handles. Handles mutex issues for a thread
212  * enabled version of tcl.
213  */
214 
215 extern Tcl_Obj*
216 MemchanGenHandle _ANSI_ARGS_ ((CONST char* prefix));
217 
218 #ifdef __cplusplus
219 }
220 #endif /* C++ */
221 
222 /*
223  * Exported functionality.
224  */
225 
226 #include "memchan.h"
227 
228 #endif /* MEMCHAN_H */
229