* Extended X interface: pixmap objects, colormap objects visual objects,

image objects, and lots of new methods.
* Added counting of allocations and deallocations of builtin types if
  COUNT_ALLOCS is defined.  Had to move calls to NEWREF down in some
  files.
* Bug fix in sorting lists.
This commit is contained in:
Sjoerd Mullender 1993-10-11 12:54:31 +00:00
parent 35fe6ec4cf
commit a9c3c22c33
12 changed files with 150 additions and 18 deletions

View File

@ -198,6 +198,13 @@ typedef struct _typeobject {
/* More standard operations (at end for binary compatibility) */ /* More standard operations (at end for binary compatibility) */
long (*tp_hash) FPROTO((object *)); long (*tp_hash) FPROTO((object *));
#ifdef COUNT_ALLOCS
/* these must be last */
int tp_alloc;
int tp_free;
int tp_maxalloc;
struct _typeobject *tp_next;
#endif
} typeobject; } typeobject;
extern typeobject Typetype; /* The type of type objects */ extern typeobject Typetype; /* The type of type objects */
@ -253,15 +260,27 @@ environment the global variable trick is not safe.)
#endif #endif
#ifndef TRACE_REFS #ifndef TRACE_REFS
#ifdef COUNT_ALLOCS
#define DELREF(op) ((op)->ob_type->tp_free++, (*(op)->ob_type->tp_dealloc)((object *)(op)))
#else
#define DELREF(op) (*(op)->ob_type->tp_dealloc)((object *)(op)) #define DELREF(op) (*(op)->ob_type->tp_dealloc)((object *)(op))
#endif
#define UNREF(op) /*empty*/ #define UNREF(op) /*empty*/
#endif #endif
#ifdef COUNT_ALLOCS
extern void inc_count PROTO((typeobject *));
#endif
#ifdef REF_DEBUG #ifdef REF_DEBUG
extern long ref_total; extern long ref_total;
#ifndef TRACE_REFS #ifndef TRACE_REFS
#ifdef COUNT_ALLOCS
#define NEWREF(op) (inc_count((op)->ob_type), ref_total++, (op)->ob_refcnt = 1)
#else
#define NEWREF(op) (ref_total++, (op)->ob_refcnt = 1) #define NEWREF(op) (ref_total++, (op)->ob_refcnt = 1)
#endif #endif
#endif
#define INCREF(op) (ref_total++, (op)->ob_refcnt++) #define INCREF(op) (ref_total++, (op)->ob_refcnt++)
#define DECREF(op) \ #define DECREF(op) \
if (--ref_total, --(op)->ob_refcnt > 0) \ if (--ref_total, --(op)->ob_refcnt > 0) \
@ -269,7 +288,11 @@ extern long ref_total;
else \ else \
DELREF(op) DELREF(op)
#else #else
#ifdef COUNT_ALLOCS
#define NEWREF(op) (inc_count((op)->ob_type), (op)->ob_refcnt = 1)
#else
#define NEWREF(op) ((op)->ob_refcnt = 1) #define NEWREF(op) ((op)->ob_refcnt = 1)
#endif
#define INCREF(op) ((op)->ob_refcnt++) #define INCREF(op) ((op)->ob_refcnt++)
#define DECREF(op) \ #define DECREF(op) \
if (--(op)->ob_refcnt > 0) \ if (--(op)->ob_refcnt > 0) \

View File

@ -252,10 +252,10 @@ newarrayobject(size, descr)
return err_nomem(); return err_nomem();
} }
} }
NEWREF(op);
op->ob_type = &Arraytype; op->ob_type = &Arraytype;
op->ob_size = size; op->ob_size = size;
op->ob_descr = descr; op->ob_descr = descr;
NEWREF(op);
return (object *) op; return (object *) op;
} }

View File

@ -310,6 +310,9 @@ extern void initGlx();
#ifdef USE_HTML #ifdef USE_HTML
extern void initHTML(); extern void initHTML();
#endif #endif
#ifdef USE_XLIB
extern void initXlib();
#endif
/* -- ADDMODULE MARKER 1 -- */ /* -- ADDMODULE MARKER 1 -- */
struct { struct {
@ -485,6 +488,10 @@ struct {
{"HTML", initHTML}, {"HTML", initHTML},
#endif #endif
#ifdef USE_XLIB
{"Xlib", initXlib},
#endif
/* -- ADDMODULE MARKER 2 -- */ /* -- ADDMODULE MARKER 2 -- */
{0, 0} /* Sentinel */ {0, 0} /* Sentinel */

View File

@ -542,9 +542,15 @@ imageop_rgb2rgb8(self, args)
for ( i=0; i < nlen; i++ ) { for ( i=0; i < nlen; i++ ) {
/* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */ /* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */
value = *cp++; value = *cp++;
#if 0
r = (value >> 5) & 7; r = (value >> 5) & 7;
g = (value >> 13) & 7; g = (value >> 13) & 7;
b = (value >> 22) & 3; b = (value >> 22) & 3;
#else
r = (int) ((value & 0xff) / 255. * 7. + .5);
g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5);
b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5);
#endif
nvalue = (r<<5) | (b<<3) | g; nvalue = (r<<5) | (b<<3) | g;
*ncp++ = nvalue; *ncp++ = nvalue;
} }

View File

@ -43,6 +43,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
static object * ImgfileError; /* Exception we raise for various trouble */ static object * ImgfileError; /* Exception we raise for various trouble */
static int top_to_bottom; /* True if we want top-to-bottom images */
/* The image library does not always call the error hander :-(, /* The image library does not always call the error hander :-(,
therefore we have a global variable indicating that it was called. therefore we have a global variable indicating that it was called.
@ -86,6 +87,20 @@ imgfile_open(fname)
return image; return image;
} }
static object *
imgfile_ttob(self, args)
object *self;
object *args;
{
int newval;
object *rv;
if (!getargs(args, "i", &newval))
return NULL;
rv = newintobject(top_to_bottom);
top_to_bottom = newval;
return rv;
}
static object * static object *
imgfile_read(self, args) imgfile_read(self, args)
@ -100,7 +115,8 @@ imgfile_read(self, args)
static short rs[8192], gs[8192], bs[8192]; static short rs[8192], gs[8192], bs[8192];
int x, y; int x, y;
IMAGE *image; IMAGE *image;
int yfirst, ylast, ystep;
if ( !getargs(args, "s", &fname) ) if ( !getargs(args, "s", &fname) )
return NULL; return NULL;
@ -139,7 +155,17 @@ imgfile_read(self, args)
} }
cdatap = getstringvalue(rv); cdatap = getstringvalue(rv);
idatap = (long *)cdatap; idatap = (long *)cdatap;
for ( y=0; y < ysize && !error_called; y++ ) {
if (top_to_bottom) {
yfirst = ysize-1;
ylast = -1;
ystep = -1;
} else {
yfirst = 0;
ylast = ysize;
ystep = 1;
}
for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
if ( zsize == 1 ) { if ( zsize == 1 ) {
getrow(image, rs, y, 0); getrow(image, rs, y, 0);
for(x=0; x<xsize; x++ ) for(x=0; x<xsize; x++ )
@ -164,14 +190,17 @@ imgfile_read(self, args)
static IMAGE *glob_image; static IMAGE *glob_image;
static long *glob_datap; static long *glob_datap;
static int glob_width, glob_z; static int glob_width, glob_z, glob_ysize;
static static
xs_get(buf, y) xs_get(buf, y)
short *buf; short *buf;
int y; int y;
{ {
getrow(glob_image, buf, y, glob_z); if (top_to_bottom)
getrow(glob_image, buf, (glob_ysize-1-y), glob_z);
else
getrow(glob_image, buf, y, glob_z);
} }
static static
@ -221,6 +250,7 @@ xscale(image, xsize, ysize, zsize, datap, xnew, ynew, fmode, blur)
glob_image = image; glob_image = image;
glob_datap = datap; glob_datap = datap;
glob_width = xnew; glob_width = xnew;
glob_ysize = ysize;
if ( zsize == 1 ) { if ( zsize == 1 ) {
glob_z = 0; glob_z = 0;
filterzoom(xs_get, xs_put_c, xsize, ysize, xnew, ynew, fmode, blur); filterzoom(xs_get, xs_put_c, xsize, ysize, xnew, ynew, fmode, blur);
@ -255,6 +285,7 @@ imgfile_readscaled(self, args)
double blur; double blur;
int extended; int extended;
int fmode; int fmode;
int yfirst, ylast, ystep;
/* /*
** Parse args. Funny, since arg 4 and 5 are optional ** Parse args. Funny, since arg 4 and 5 are optional
@ -331,7 +362,16 @@ imgfile_readscaled(self, args)
if ( extended ) { if ( extended ) {
xscale(image, xsize, ysize, zsize, idatap, xwtd, ywtd, fmode, blur); xscale(image, xsize, ysize, zsize, idatap, xwtd, ywtd, fmode, blur);
} else { } else {
for ( y=0; y < ywtd && !error_called; y++ ) { if (top_to_bottom) {
yfirst = ywtd-1;
ylast = -1;
ystep = -1;
} else {
yfirst = 0;
ylast = ywtd;
ystep = 1;
}
for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
yorig = (int)(y*yfac); yorig = (int)(y*yfac);
if ( zsize == 1 ) { if ( zsize == 1 ) {
getrow(image, rs, yorig, 0); getrow(image, rs, yorig, 0);
@ -392,6 +432,8 @@ imgfile_write(self, args)
short r, g, b; short r, g, b;
long rgb; long rgb;
int x, y; int x, y;
int yfirst, ylast, ystep;
if ( !getargs(args, "(ss#iii)", if ( !getargs(args, "(ss#iii)",
&fname, &cdatap, &len, &xsize, &ysize, &zsize) ) &fname, &cdatap, &len, &xsize, &ysize, &zsize) )
@ -425,7 +467,16 @@ imgfile_write(self, args)
idatap = (long *)cdatap; idatap = (long *)cdatap;
for( y=0; y<ysize && !error_called; y++ ) { if (top_to_bottom) {
yfirst = ysize-1;
ylast = -1;
ystep = -1;
} else {
yfirst = 0;
ylast = ysize;
ystep = 1;
}
for ( y=yfirst; y != ylast && !error_called; y += ystep ) {
if ( zsize == 1 ) { if ( zsize == 1 ) {
for( x=0; x<xsize; x++ ) for( x=0; x<xsize; x++ )
rs[x] = *cdatap++; rs[x] = *cdatap++;
@ -459,6 +510,7 @@ static struct methodlist imgfile_methods[] = {
{ "read", imgfile_read }, { "read", imgfile_read },
{ "readscaled", imgfile_readscaled, 1}, { "readscaled", imgfile_readscaled, 1},
{ "write", imgfile_write }, { "write", imgfile_write },
{ "ttob", imgfile_ttob },
{ NULL, NULL } /* Sentinel */ { NULL, NULL } /* Sentinel */
}; };

View File

@ -60,9 +60,9 @@ newfloatobject(fval)
register floatobject *op = (floatobject *) malloc(sizeof(floatobject)); register floatobject *op = (floatobject *) malloc(sizeof(floatobject));
if (op == NULL) if (op == NULL)
return err_nomem(); return err_nomem();
NEWREF(op);
op->ob_type = &Floattype; op->ob_type = &Floattype;
op->ob_fval = fval; op->ob_fval = fval;
NEWREF(op);
return (object *) op; return (object *) op;
} }

View File

@ -87,9 +87,9 @@ newintobject(ival)
} }
v = free_list; v = free_list;
free_list = *(intobject **)free_list; free_list = *(intobject **)free_list;
NEWREF(v);
v->ob_type = &Inttype; v->ob_type = &Inttype;
v->ob_ival = ival; v->ob_ival = ival;
NEWREF(v);
return (object *) v; return (object *) v;
} }

View File

@ -58,11 +58,11 @@ newlistobject(size)
return err_nomem(); return err_nomem();
} }
} }
NEWREF(op);
op->ob_type = &Listtype; op->ob_type = &Listtype;
op->ob_size = size; op->ob_size = size;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
op->ob_item[i] = NULL; op->ob_item[i] = NULL;
NEWREF(op);
return (object *) op; return (object *) op;
} }
@ -520,7 +520,7 @@ cmp(v, w)
return cmpobject(* (object **) v, * (object **) w); return cmpobject(* (object **) v, * (object **) w);
/* Call the user-supplied comparison function */ /* Call the user-supplied comparison function */
t = mkvalue("OO", v, w); t = mkvalue("OO", * (object **) v, * (object **) w);
if (t == NULL) if (t == NULL)
return 0; return 0;
res = call_object(cmpfunc, t); res = call_object(cmpfunc, t);

View File

@ -34,6 +34,36 @@ long ref_total;
These are used by the individual routines for object creation. These are used by the individual routines for object creation.
Do not call them otherwise, they do not initialize the object! */ Do not call them otherwise, they do not initialize the object! */
#ifdef COUNT_ALLOCS
static typeobject *type_list;
void
dump_counts()
{
typeobject *tp;
for (tp = type_list; tp; tp = tp->tp_next)
printf("%s %d %d %d\n", tp->tp_name, tp->tp_alloc, tp->tp_free,
tp->tp_maxalloc);
}
void
inc_count(tp)
typeobject *tp;
{
if (tp->tp_alloc == 0) {
/* first time; hang in linked list */
if (tp->tp_next != NULL) /* sanity check */
abort();
tp->tp_next = type_list;
type_list = tp;
}
tp->tp_alloc++;
if (tp->tp_alloc - tp->tp_free > tp->tp_maxalloc)
tp->tp_maxalloc = tp->tp_alloc - tp->tp_free;
}
#endif
object * object *
newobject(tp) newobject(tp)
typeobject *tp; typeobject *tp;
@ -41,8 +71,8 @@ newobject(tp)
object *op = (object *) malloc(tp->tp_basicsize); object *op = (object *) malloc(tp->tp_basicsize);
if (op == NULL) if (op == NULL)
return err_nomem(); return err_nomem();
NEWREF(op);
op->ob_type = tp; op->ob_type = tp;
NEWREF(op);
return op; return op;
} }
@ -55,9 +85,9 @@ newvarobject(tp, size)
malloc(tp->tp_basicsize + size * tp->tp_itemsize); malloc(tp->tp_basicsize + size * tp->tp_itemsize);
if (op == NULL) if (op == NULL)
return (varobject *)err_nomem(); return (varobject *)err_nomem();
NEWREF(op);
op->ob_type = tp; op->ob_type = tp;
op->ob_size = size; op->ob_size = size;
NEWREF(op);
return op; return op;
} }
@ -301,6 +331,9 @@ NEWREF(op)
op->_ob_prev = &refchain; op->_ob_prev = &refchain;
refchain._ob_next->_ob_prev = op; refchain._ob_next->_ob_prev = op;
refchain._ob_next = op; refchain._ob_next = op;
#ifdef COUNT_ALLOCS
inc_count(op->ob_type);
#endif
} }
UNREF(op) UNREF(op)
@ -335,6 +368,9 @@ DELREF(op)
object *op; object *op;
{ {
UNREF(op); UNREF(op);
#ifdef COUNT_ALLOCS
op->ob_type->tp_free++;
#endif
(*(op)->ob_type->tp_dealloc)(op); (*(op)->ob_type->tp_dealloc)(op);
op->ob_type = NULL; op->ob_type = NULL;
} }

View File

@ -35,9 +35,9 @@ newsizedstringobject(str, size)
malloc(sizeof(stringobject) + size * sizeof(char)); malloc(sizeof(stringobject) + size * sizeof(char));
if (op == NULL) if (op == NULL)
return err_nomem(); return err_nomem();
NEWREF(op);
op->ob_type = &Stringtype; op->ob_type = &Stringtype;
op->ob_size = size; op->ob_size = size;
NEWREF(op);
if (str != NULL) if (str != NULL)
memcpy(op->ob_sval, str, size); memcpy(op->ob_sval, str, size);
op->ob_sval[size] = '\0'; op->ob_sval[size] = '\0';
@ -53,9 +53,9 @@ newstringobject(str)
malloc(sizeof(stringobject) + size * sizeof(char)); malloc(sizeof(stringobject) + size * sizeof(char));
if (op == NULL) if (op == NULL)
return err_nomem(); return err_nomem();
NEWREF(op);
op->ob_type = &Stringtype; op->ob_type = &Stringtype;
op->ob_size = size; op->ob_size = size;
NEWREF(op);
strcpy(op->ob_sval, str); strcpy(op->ob_sval, str);
return (object *) op; return (object *) op;
} }
@ -187,9 +187,9 @@ string_concat(a, bb)
malloc(sizeof(stringobject) + size * sizeof(char)); malloc(sizeof(stringobject) + size * sizeof(char));
if (op == NULL) if (op == NULL)
return err_nomem(); return err_nomem();
NEWREF(op);
op->ob_type = &Stringtype; op->ob_type = &Stringtype;
op->ob_size = size; op->ob_size = size;
NEWREF(op);
memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size); memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size);
memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size); memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size);
op->ob_sval[size] = '\0'; op->ob_sval[size] = '\0';
@ -216,9 +216,9 @@ string_repeat(a, n)
malloc(sizeof(stringobject) + size * sizeof(char)); malloc(sizeof(stringobject) + size * sizeof(char));
if (op == NULL) if (op == NULL)
return err_nomem(); return err_nomem();
NEWREF(op);
op->ob_type = &Stringtype; op->ob_type = &Stringtype;
op->ob_size = size; op->ob_size = size;
NEWREF(op);
for (i = 0; i < size; i += a->ob_size) for (i = 0; i < size; i += a->ob_size)
memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size); memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
op->ob_sval[size] = '\0'; op->ob_sval[size] = '\0';

View File

@ -40,11 +40,11 @@ newtupleobject(size)
malloc(sizeof(tupleobject) + size * sizeof(object *)); malloc(sizeof(tupleobject) + size * sizeof(object *));
if (op == NULL) if (op == NULL)
return err_nomem(); return err_nomem();
NEWREF(op);
op->ob_type = &Tupletype; op->ob_type = &Tupletype;
op->ob_size = size; op->ob_size = size;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
op->ob_item[i] = NULL; op->ob_item[i] = NULL;
NEWREF(op);
return (object *) op; return (object *) op;
} }

View File

@ -417,12 +417,20 @@ cleanup()
flushline(); flushline();
} }
#ifdef COUNT_ALLOCS
extern void dump_counts PROTO((void));
#endif
void void
goaway(sts) goaway(sts)
int sts; int sts;
{ {
cleanup(); cleanup();
#ifdef COUNT_ALLOCS
dump_counts();
#endif
#ifdef USE_THREAD #ifdef USE_THREAD
/* Other threads may still be active, so skip most of the /* Other threads may still be active, so skip most of the