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
|
/* Copyright (c) 1996--1999 Geoff Pike. */
/* All rights reserved. */
/* Floater is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
/* This software is provided "as is" and comes with absolutely no */
/* warranties. Geoff Pike is not liable for damages under any */
/* circumstances. Support is not provided. Use at your own risk. */
/* Personal, non-commercial use is allowed. Attempting to make money */
/* from Floater or products or code derived from Floater is not allowed */
/* without prior written consent from Geoff Pike. Anything that remotely */
/* involves commercialism, including (but not limited to) systems that */
/* show advertisements while being used and systems that collect */
/* information on users that is later sold or traded require prior */
/* written consent from Geoff Pike. */
#include <tcl.h>
#include <malloc.h>
#include <stdio.h>
#include <assert.h>
#include "floater.h"
/* like malloc, but die gracefully if out of memory */
char *salloc(unsigned t)
{
char *w;
if ((w = malloc(t)) != NULL) return w;
fatal("Out of memory! Goodbye.\n", -3);
return NULL; /* never reached */
}
/* like salloc, but zero out the region */
char *zsalloc(unsigned t)
{
char *w = salloc(t);
while (t-- > 0) w[t] = 0;
return w;
}
/*****************************************************************************/
static stringlist *garbage = NULL;
/* free everything on the garbage list */
void destroygarbage(void)
{
while (garbage != NULL) garbage = freestringlist(garbage);
}
/* mark something as garbage (it will be freed later) */
char *markgarbage(char *x)
{
garbage = consstringlist(x, garbage);
return x;
}
int floaterentrypoint(ClientData clientData, Tcl_Interp *interp,
int argc, char *argv[])
{
extern void tasks(void);
int ret;
/* "unnecessary," but retained to check "impossible" conditions */
static int entry = 0;
assert(entry == 0);
/* recursion is not allowed between DISALLOW_REENTRY() and ALLOW_REENTRY() */
DISALLOW_REENTRY();
entry++;
if (entry > 100)
fatal("Excessive recursion caused by user's command",
(entry > 101) ? 102 : 101);
UIsetstatusline();
ret = (*((Tcl_CmdProc *) clientData))((ClientData) NULL, interp, argc, argv);
if (entry == 1) tasks();
UIsetstatusline();
if (--entry == 0) destroygarbage();
ALLOW_REENTRY();
return ret;
}
|