File: standard.patch

package info (click to toggle)
tcltrf 2.1.4-dfsg3-8
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,656 kB
  • sloc: ansic: 73,139; sh: 3,155; tcl: 1,343; makefile: 182; exp: 22
file content (546 lines) | stat: -rw-r--r-- 18,001 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
*** ./tcl.decls.orig	Sat Apr 10 17:50:50 1999
--- ./tcl.decls	Mon Apr 19 19:58:16 1999
***************
*** 967,977 ****
      void Tcl_InitMemory(Tcl_Interp *interp)
  }
  
  # Reserved for future use (8.0.x vs. 8.1)
- #  declare 281 generic {
- #  }
- #  declare 282 generic {
- #  }
  #  declare 283 generic {
  #  }
  #  declare 284 generic {
--- 967,996 ----
      void Tcl_InitMemory(Tcl_Interp *interp)
  }
  
+ # Andreas Kupries <andreas_kupries@users.sourceforge.net>, 03/21/1999
+ # "Trf-Patch for filtering channels"
+ #
+ # C-Level API for (un)stacking of channels. This allows the introduction
+ # of filtering channels with relatively little changes to the core.
+ # This patch was created in cooperation with Jan Nijtmans <nijtmans@wxs.nl>
+ # and is therefore part of his plus-patches too.
+ #
+ # It would have been possible to place the following definitions according
+ # to the alphabetical order used elsewhere in this file, but I decided
+ # against that to ease the maintenance of the patch across new tcl versions
+ # (patch usually has no problems to integrate the patch file for the last
+ # version into the new one).
+ 
+ declare 281 generic {
+     Tcl_Channel Tcl_ReplaceChannel(Tcl_Interp *interp, \
+ 	    Tcl_ChannelType *typePtr, ClientData instanceData, \
+ 	    int mask, Tcl_Channel prevChan)
+ }
+ declare 282 generic {
+     void Tcl_UndoReplaceChannel(Tcl_Interp *interp, Tcl_Channel chan)
+ }
+ 
  # Reserved for future use (8.0.x vs. 8.1)
  #  declare 283 generic {
  #  }
  #  declare 284 generic {
*** ./tclDecls.h.orig	Sat Apr 10 17:50:50 1999
--- ./tclDecls.h	Mon Apr 19 19:58:16 1999
***************
*** 875,882 ****
  				int * patchLevel, int * type));
  /* 280 */
  EXTERN void		Tcl_InitMemory _ANSI_ARGS_((Tcl_Interp * interp));
! /* Slot 281 is reserved */
! /* Slot 282 is reserved */
  /* Slot 283 is reserved */
  /* Slot 284 is reserved */
  /* Slot 285 is reserved */
--- 875,888 ----
  				int * patchLevel, int * type));
  /* 280 */
  EXTERN void		Tcl_InitMemory _ANSI_ARGS_((Tcl_Interp * interp));
! /* 281 */
! EXTERN Tcl_Channel	Tcl_ReplaceChannel _ANSI_ARGS_((Tcl_Interp * interp, 
! 				Tcl_ChannelType * typePtr, 
! 				ClientData instanceData, int mask, 
! 				Tcl_Channel prevChan));
! /* 282 */
! EXTERN void		Tcl_UndoReplaceChannel _ANSI_ARGS_((
! 				Tcl_Interp * interp, Tcl_Channel chan));
  /* Slot 283 is reserved */
  /* Slot 284 is reserved */
  /* Slot 285 is reserved */
***************
*** 1434,1441 ****
      void (*tcl_PanicVA) _ANSI_ARGS_((char * format, va_list argList)); /* 278 */
      void (*tcl_GetVersion) _ANSI_ARGS_((int * major, int * minor, int * patchLevel, int * type)); /* 279 */
      void (*tcl_InitMemory) _ANSI_ARGS_((Tcl_Interp * interp)); /* 280 */
!     void *reserved281;
!     void *reserved282;
      void *reserved283;
      void *reserved284;
      void *reserved285;
--- 1440,1447 ----
      void (*tcl_PanicVA) _ANSI_ARGS_((char * format, va_list argList)); /* 278 */
      void (*tcl_GetVersion) _ANSI_ARGS_((int * major, int * minor, int * patchLevel, int * type)); /* 279 */
      void (*tcl_InitMemory) _ANSI_ARGS_((Tcl_Interp * interp)); /* 280 */
!     Tcl_Channel (*tcl_ReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_ChannelType * typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan)); /* 281 */
!     void (*tcl_UndoReplaceChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 282 */
      void *reserved283;
      void *reserved284;
      void *reserved285;
***************
*** 2657,2664 ****
  #define Tcl_InitMemory \
  	(tclStubsPtr->tcl_InitMemory) /* 280 */
  #endif
! /* Slot 281 is reserved */
! /* Slot 282 is reserved */
  /* Slot 283 is reserved */
  /* Slot 284 is reserved */
  /* Slot 285 is reserved */
--- 2663,2676 ----
  #define Tcl_InitMemory \
  	(tclStubsPtr->tcl_InitMemory) /* 280 */
  #endif
! #ifndef Tcl_ReplaceChannel
! #define Tcl_ReplaceChannel \
! 	(tclStubsPtr->tcl_ReplaceChannel) /* 281 */
! #endif
! #ifndef Tcl_UndoReplaceChannel
! #define Tcl_UndoReplaceChannel \
! 	(tclStubsPtr->tcl_UndoReplaceChannel) /* 282 */
! #endif
  /* Slot 283 is reserved */
  /* Slot 284 is reserved */
  /* Slot 285 is reserved */
*** ./tclIO.c.orig	Sat Apr 10 17:50:52 1999
--- ./tclIO.c	Mon Apr 19 19:58:16 1999
***************
*** 202,207 ****
--- 202,229 ----
      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. */
+ 
+   /* Andreas Kupries <andreas_kupries@users.sourceforge.net>, 12/13/1998
+    * "Trf-Patch for filtering channels"
+    *
+    * The single change to the internal datastructures of the core. Every
+    * channel now maintains a reference to the channel he is stacked upon.
+    * This reference is NULL for normal channels. Only the two exported
+    * procedures (Tcl_ReplaceChannel and Tcl_UndoReplaceChannel, see at the
+    * end of 'tcl.h') use this field in a non-trivial way.
+    *
+    * Of the existing procedures the only following are affected by this
+    * change:
+    *
+    * - Tcl_RegisterChannel
+    * - Tcl_CreateChannel
+    * - CloseChannel
+    *
+    * The why is explained at the changed locations.
+    */
+ 
+   struct Channel* supercedes; /* Refers to channel this one was stacked upon */
+ 
  } Channel;
      
  /*
***************
*** 1038,1044 ****
              if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) {
                  return;
              }
!             panic("Tcl_RegisterChannel: duplicate channel names");
          }
          Tcl_SetHashValue(hPtr, (ClientData) chanPtr);
      }
--- 1060,1080 ----
              if (chan == (Tcl_Channel) Tcl_GetHashValue(hPtr)) {
                  return;
              }
! 
! 	    /* Andreas Kupries <andreas_kupries@users.sourceforge.net>, 12/13/1998
! 	     * "Trf-Patch for filtering channels"
! 	     *
! 	     * This is the change to 'Tcl_RegisterChannel'.
! 	     *
! 	     * Explanation:
! 	     *		The moment a channel is stacked upon another he
! 	     *		takes the identity of the channel he supercedes,
! 	     *		i.e. he gets the *same* name. Because of this we
! 	     *		cannot check for duplicate names anymore, they
! 	     *		have to be allowed now.
! 	     */
! 
! 	    /* panic("Tcl_RegisterChannel: duplicate channel names"); */
          }
          Tcl_SetHashValue(hPtr, (ClientData) chanPtr);
      }
***************
*** 1297,1302 ****
--- 1333,1352 ----
      chanPtr->timer = NULL;
      chanPtr->csPtr = NULL;
  
+     /* Andreas Kupries <andreas_kupries@users.sourceforge.net>, 12/13/1998
+      * "Trf-Patch for filtering channels"
+      *
+      * This is the change to 'Tcl_CreateChannel'.
+      *
+      * Explanation:
+      *	It is of course necessary to initialize the new field
+      *	in the Channel structure. The chosen value indicates
+      *	that the created channel is a normal one, and not
+      *	stacked upon another.
+      */
+ 
+     chanPtr->supercedes = (Channel*) NULL;
+ 
      chanPtr->outputStage = NULL;
      if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) {
  	chanPtr->outputStage = (char *)
***************
*** 1330,1335 ****
--- 1380,1622 ----
      return (Tcl_Channel) chanPtr;
  }
  
+ /* Andreas Kupries <andreas_kupries@users.sourceforge.net>, 12/13/1998
+  * "Trf-Patch for filtering channels"
+  *
+  * The following two procedures are the new, exported ones. They
+  * - create a channel stacked upon an existing one and
+  * - pop a stacked channel off, thus revealing the superceded one.
+  *
+  * Please read the following completely.
+  */
+ 
+ /*
+  *----------------------------------------------------------------------
+  *
+  * Tcl_ReplaceChannel --
+  *
+  *	Replaces an entry in the hash table for a Tcl_Channel
+  *	record. The replacement is a new channel with same name,
+  *	it supercedes the replaced channel. Input and output of
+  *	the superceded channel is now going through the newly
+  *	created channel and allows the arbitrary filtering/manipulation
+  *	of the dataflow.
+  *
+  * Results:
+  *	Returns the new Tcl_Channel.
+  *
+  * Side effects:
+  *	See above.
+  *
+  *----------------------------------------------------------------------
+  */
+ 
+ Tcl_Channel
+ Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan)
+     Tcl_Interp*      interp;       /* The interpreter we are working in */
+     Tcl_ChannelType *typePtr;	   /* The channel type record for the new
+ 				    * channel. */
+     ClientData       instanceData; /* Instance specific data for the new
+ 				    * channel. */
+     int              mask;	   /* TCL_READABLE & TCL_WRITABLE to indicate
+ 				    * if the channel is readable, writable. */
+     Tcl_Channel      prevChan;	   /* The channel structure to replace */
+ {
+   ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+   Channel            *chanPtr, *pt, *prevPt;
+ 
+   /*
+    * Find the given channel in the list of all channels, compute enough
+    * information to allow easy removal after the conditions are met.
+    */
+ 
+   prevPt = (Channel*) NULL;
+   pt     = (Channel*) tsdPtr->firstChanPtr;
+ 
+   while (pt != (Channel *) prevChan) {
+     prevPt = pt;
+     pt     = pt->nextChanPtr;
+   }
+ 
+   /*
+    * 'pt == prevChan' now
+    */
+ 
+   if (!pt) {
+     return (Tcl_Channel) NULL;
+   }
+ 
+   /*
+    * Here we check if the given "mask" matches the "flags"
+    * of the already existing channel.
+    *
+    *	  | - | R | W | RW |
+    *	--+---+---+---+----+	<=>  0 != (chan->mask & prevChan->mask)
+    *	- |   |   |   |    |
+    *	R |   | + |   | +  |	The superceding channel is allowed to
+    *	W |   |   | + | +  |	restrict the capabilities of the
+    *	RW|   | + | + | +  |	superceded one !
+    *	--+---+---+---+----+
+    */
+ 
+   if ((mask & Tcl_GetChannelMode (prevChan)) == 0) {
+     return (Tcl_Channel) NULL;
+   }
+ 
+ 
+   chanPtr = (Channel *) ckalloc((unsigned) sizeof(Channel));
+   chanPtr->flags = mask;
+ 
+   /*
+    * Set the channel up initially in no Input translation mode and
+    * no Output translation mode.
+    */
+ 
+   chanPtr->inputTranslation = TCL_TRANSLATE_LF;
+   chanPtr->outputTranslation = TCL_TRANSLATE_LF;
+   chanPtr->inEofChar = 0;
+   chanPtr->outEofChar = 0;
+ 
+   chanPtr->unreportedError = 0;
+   chanPtr->instanceData = instanceData;
+   chanPtr->typePtr = typePtr;
+   chanPtr->refCount = 0;
+   chanPtr->closeCbPtr = (CloseCallback *) NULL;
+   chanPtr->curOutPtr = (ChannelBuffer *) NULL;
+   chanPtr->outQueueHead = (ChannelBuffer *) NULL;
+   chanPtr->outQueueTail = (ChannelBuffer *) NULL;
+   chanPtr->saveInBufPtr = (ChannelBuffer *) NULL;
+   chanPtr->inQueueHead = (ChannelBuffer *) NULL;
+   chanPtr->inQueueTail = (ChannelBuffer *) NULL;
+   chanPtr->chPtr = (ChannelHandler *) NULL;
+   chanPtr->interestMask = 0;
+   chanPtr->scriptRecordPtr = (EventScriptRecord *) NULL;
+   chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE;
+   chanPtr->timer = NULL;
+   chanPtr->csPtr = NULL;
+ 
+   /* 06/12/1998: New for Tcl 8.1
+    *
+    * Take over the encoding from the superceded channel, so that it will be
+    * executed in the future despite the replacement, and at the proper time
+    * (*after* / *before* our transformation, depending on the direction of
+    * the dataflow).
+    *
+    * *Important*
+    * The I/O functionality of the filtering channel has to use 'Tcl_Read' to
+    * get at the underlying information. This will circumvent the de/encoder
+    * stage [*] in the superceded channel and removes the need to trouble
+    * ourselves with 'ByteArray's too.
+    *
+    * [*] I'm talking about the conversion between UNICODE and other
+    *     representations, like ASCII.
+    */
+ 
+   chanPtr->encoding=Tcl_GetEncoding(interp,Tcl_GetEncodingName(pt->encoding));
+   chanPtr->inputEncodingState  = pt->inputEncodingState;
+   chanPtr->inputEncodingFlags  = pt->inputEncodingFlags;
+   chanPtr->outputEncodingState = pt->outputEncodingState;
+   chanPtr->outputEncodingFlags = pt->outputEncodingFlags;
+ 
+   chanPtr->outputStage = NULL;
+ 
+   if ((chanPtr->encoding != NULL) && (chanPtr->flags & TCL_WRITABLE)) {
+     chanPtr->outputStage = (char *)
+       ckalloc((unsigned) (chanPtr->bufSize + 2));
+   }
+ 
+   chanPtr->supercedes = (Channel*) prevChan;
+ 
+   chanPtr->channelName = (char *) ckalloc (strlen(pt->channelName)+1);
+   strcpy (chanPtr->channelName, pt->channelName);
+ 
+   if (prevPt) {
+     prevPt->nextChanPtr = chanPtr;
+   } else {
+     tsdPtr->firstChanPtr = chanPtr;
+   }
+ 
+   chanPtr->nextChanPtr = pt->nextChanPtr;
+ 
+   Tcl_RegisterChannel (interp, (Tcl_Channel) chanPtr);
+ 
+   /*
+    * The superceded channel is effectively unregistered
+    */
+ 
+   /*chanPtr->supercedes->refCount --;*/
+ 
+   return (Tcl_Channel) chanPtr;
+ }
+ 
+ /*
+  *----------------------------------------------------------------------
+  *
+  * Tcl_UndoReplaceChannel --
+  *
+  *	Unstacks an entry in the hash table for a Tcl_Channel
+  *	record. This is the reverse to 'Tcl_ReplaceChannel'.
+  *	The old, superceded channel is uncovered and re-registered
+  *	in the appropriate datastructures.
+  *
+  * Results:
+  *	Returns the old Tcl_Channel, i.e. the one which was stacked over.
+  *
+  * Side effects:
+  *	See above.
+  *
+  *----------------------------------------------------------------------
+  */
+ 
+ void
+ Tcl_UndoReplaceChannel (interp, chan)
+ Tcl_Interp* interp; /* The interpreter we are working in */
+ Tcl_Channel chan;   /* The channel to unstack */
+ {
+   ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+   Channel* chanPtr = (Channel*) chan;
+ 
+   if (chanPtr->supercedes != (Channel*) NULL) {
+     Tcl_HashTable *hTblPtr;	/* Hash table of channels. */
+     Tcl_HashEntry *hPtr;	/* Search variable. */
+     int new;			/* Is the hash entry new or does it exist? */
+ 
+     /*
+      * Insert the channel we were stacked upon back into
+      * the list of open channels. Place it back into the hashtable too.
+      * Correct 'refCount', as this actually unregisters 'chan'.
+      */
+ 
+     chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr;
+     tsdPtr->firstChanPtr             = chanPtr->supercedes;
+ 
+     hTblPtr = GetChannelTable (interp);
+     hPtr    = Tcl_CreateHashEntry (hTblPtr, chanPtr->channelName, &new);
+ 
+     Tcl_SetHashValue(hPtr, (ClientData) chanPtr->supercedes);
+     chanPtr->refCount --;
+ 
+     /*
+      * The superceded channel is effectively registered again
+      */
+ 
+     /*chanPtr->supercedes->refCount ++;*/
+   }
+ 
+   /*
+    * Disconnect the channels, then do a regular close upon the
+    * stacked one, the filtering channel. This may cause flushing
+    * of data into the superceded channel (if the filtering channel
+    * ('chan') remembered its parent in itself).
+    */
+ 
+   chanPtr->supercedes = NULL;
+ 
+   if (chanPtr->refCount == 0) {
+     Tcl_Close (interp, chan);
+   }
+ }
+ 
  /*
   *----------------------------------------------------------------------
   *
***************
*** 2003,2008 ****
--- 2290,2330 ----
          if (errorCode != 0) {
              Tcl_SetErrno(errorCode);
          }
+     }
+ 
+     /* Andreas Kupries <andreas_kupries@users.sourceforge.net>, 12/13/1998
+      * "Trf-Patch for filtering channels"
+      *
+      * This is the change to 'CloseChannel'.
+      *
+      * Explanation
+      *		Closing a filtering channel closes the one it
+      *		superceded too. This basically ripples through
+      *		the whole chain of filters until it reaches
+      *		the underlying normal channel.
+      *
+      *		This is done by reintegrating the superceded
+      *		channel into the (thread) global list of open
+      *		channels and then invoking a regular close.
+      *		There is no need to handle the complexities of
+      *		this process by ourselves.
+      *
+      *		*Note*
+      *		This has to be done after the call to the
+      *		'closeProc' of the filtering channel to allow
+      *		that one the flushing of internal buffers into
+      *		the underlying channel.
+      */
+ 
+     if (chanPtr->supercedes != (Channel*) NULL) {
+       /* Insert the channel we were stacked upon back into
+        * the list of open channels, then do a regular close.
+        */
+ 
+       chanPtr->supercedes->nextChanPtr = tsdPtr->firstChanPtr;
+       tsdPtr->firstChanPtr             = chanPtr->supercedes;
+       chanPtr->supercedes->refCount --; /* is deregistered */
+       Tcl_Close (interp, (Tcl_Channel) chanPtr->supercedes);
      }
  
      /*
*** ./tclStubInit.c.orig	Sat Apr 10 17:50:52 1999
--- ./tclStubInit.c	Mon Apr 19 19:58:16 1999
***************
*** 350,357 ****
      Tcl_PanicVA, /* 278 */
      Tcl_GetVersion, /* 279 */
      Tcl_InitMemory, /* 280 */
!     NULL, /* 281 */
!     NULL, /* 282 */
      NULL, /* 283 */
      NULL, /* 284 */
      NULL, /* 285 */
--- 350,357 ----
      Tcl_PanicVA, /* 278 */
      Tcl_GetVersion, /* 279 */
      Tcl_InitMemory, /* 280 */
!     Tcl_ReplaceChannel, /* 281 */
!     Tcl_UndoReplaceChannel, /* 282 */
      NULL, /* 283 */
      NULL, /* 284 */
      NULL, /* 285 */
*** ./tclStubs.c.orig	Sat Apr 10 17:50:52 1999
--- ./tclStubs.c	Mon Apr 19 19:58:16 1999
***************
*** 3263,3267 ****
--- 3263,3288 ----
      (tclStubsPtr->tcl_ServiceModeHook)(mode);
  }
  
+ /* Slot 345 */
+ Tcl_Channel
+ Tcl_ReplaceChannel(interp, typePtr, instanceData, mask, prevChan)
+     Tcl_Interp * interp;
+     Tcl_ChannelType * typePtr;
+     ClientData instanceData;
+     int mask;
+     Tcl_Channel prevChan;
+ {
+     return (tclStubsPtr->tcl_ReplaceChannel)(interp, typePtr, instanceData, mask, prevChan);
+ }
+ 
+ /* Slot 346 */
+ void
+ Tcl_UndoReplaceChannel(interp, chan)
+     Tcl_Interp * interp;
+     Tcl_Channel chan;
+ {
+     (tclStubsPtr->tcl_UndoReplaceChannel)(interp, chan);
+ }
+ 
  
  /* !END!: Do not edit above this line. */