From: Mikko Rasa Date: Fri, 30 Oct 2009 15:01:31 +0000 (+0000) Subject: Print the contents of arrays and references X-Git-Url: http://git.tdb.fi/?p=gldbg.git;a=commitdiff_plain;h=3c32a221de1435ae7af8d96182560e8b28f1a4c0 Print the contents of arrays and references Specialized string array handling Move the *size functions to their own file --- diff --git a/Makefile b/Makefile index b6cb945..a653678 100644 --- a/Makefile +++ b/Makefile @@ -9,19 +9,19 @@ LIBS_gldbg = $(shell pkg-config --libs $(PACKAGES_gldbg)) -lreadline all: glwrap.so gldump gldbg -glwrap.so: source/glwrap.o +glwrap.so: source/glwrap.o source/arraysize.o $(CC) -shared -o $@ $^ $(LIBS) $(LDFLAGS) -gldump: source/gldecoder.o source/gldump.o source/glprint.o source/enums.o +gldump: source/gldecoder.o source/gldump.o source/glprint.o source/enums.o source/arraysize.o source/tmpalloc.o $(CC) -o $@ $^ $(LIBS) $(LDFLAGS) -gldbg: source/gldbg.o source/gldecoder.o source/glprint.o source/commandinterpreter.o source/tracer.o source/process.o source/enums.o +gldbg: source/gldbg.o source/gldecoder.o source/glprint.o source/commandinterpreter.o source/tracer.o source/process.o source/enums.o source/arraysize.o source/tmpalloc.o $(CXX) -o $@ $^ $(LIBS_gldbg) $(LIBS) $(LDFLAGS) source/glwrap.o: source/functions.h gensrc/functions.enum gensrc/glwrap.funcs source/gldecoder.o: source/functions.h gensrc/gldecoder.struct gensrc/gldecoder.funcs gensrc/gldecoder.funcs source/gldump.o: source/gldecoder.h gensrc/gldecoder.struct source/glprint.h -source/glprint.o: gensrc/glprint.funcs gensrc/gldecoder.struct +source/glprint.o: source/arraysize.h gensrc/glprint.funcs gensrc/gldecoder.struct source/enums.o: gensrc/enums.table source/gldbg.o: source/gldbg.cpp source/gldbg.h source/gldecoder.h source/tracer.h diff --git a/genwrap.py b/genwrap.py index e614ab7..1ee97ce 100755 --- a/genwrap.py +++ b/genwrap.py @@ -125,11 +125,11 @@ class Function: if self.kind=="value": if self.base_ctype.startswith("const "): self.base_ctype = self.base_ctype[6:] - self.io = iomap[self.base_ctype] else: if self.direction=="in": self.ctype = "const "+self.ctype self.ctype = self.ctype+" *" + self.io = iomap[self.base_ctype] def derive_csize(self): if self.kind=="array" and self.size is not None: @@ -138,6 +138,8 @@ class Function: self.csize = "%d*sizeof(%s)"%(self.size, self.base_ctype) elif self.size.startswith("COMPSIZE("): self.csize = self.func.compsize(self.size[9:-1], self.base_ctype) + elif self.size=="pname": + self.csize = "paramsize(pname)*sizeof(%s)"%self.base_ctype else: s = self.func.get_param(self.size.split('*')[0]) if (s.type=="SizeI" or s.type.endswith("Int32") or s.type.startswith("BufferSize")) and s.kind=="value": @@ -185,7 +187,7 @@ class Function: have_type = True elif cn.endswith("Format"): res += "formatsize(%s)"%param.name - elif cn.endswith(("Parameter", "ParameterPName", "ParameterName")) or cn=="GetPName": + elif param.name=="pname" or cn.endswith("Parameter"): res += "paramsize(%s)"%param.name elif cn=="MapTarget": res += "mapsize(%s)"%param.name diff --git a/gl.io b/gl.io index da5386d..027845b 100644 --- a/gl.io +++ b/gl.io @@ -12,6 +12,7 @@ sizei, int, %i intptr, int, %i sizeiptr, int, %i handle, int, %i +int64, longlong, %lli uint64, longlong, %llu half, short, %#x float, float, %g @@ -21,3 +22,5 @@ clampd, double, %g ubyte *, string, \"%s\" char *, string, \"%s\" void *, pointer, %p +void* const, pointer, %p +boolean *, pointer, %p diff --git a/glx.io b/glx.io index e30ff09..8fcad27 100644 --- a/glx.io +++ b/glx.io @@ -3,6 +3,8 @@ boolean, char, %i int, int, %i uint, int, %u unsigned int, int, %u +int32_t, int, %i +long, long, %li unsigned long, long, %lu int64_t, longlong, %lli sizei, int, %i diff --git a/glx.tm b/glx.tm index 0a865bd..c0c81a1 100644 --- a/glx.tm +++ b/glx.tm @@ -30,7 +30,7 @@ GLenum,*,*, GLenum,*,* GLfunction,*,*, GLfunction,*,* GLint,*,*, GLint,*,* GLsizei,*,*, GLsizei,*,* -GLubyte,*,reference, GLubyte *,*,value +GLubyte,*,reference, GLubyte *,*,value GLuint,*,*, GLuint,*,* Pixmap,*,*, Pixmap,*,* Status,*,*, Status,*,* @@ -40,7 +40,7 @@ VLPath,*,*, VLPath,*,* VLServer,*,*, VLServer,*,* Window,*,*, Window,*,* Font,*,*, Font,*,* -XVisualInfo,*,*, XVisualInfo,*,* +XVisualInfo,*,reference, XVisualInfo *,*,value XVisualInfoPointer,*,*, XVisualInfo *,*,* float,*,*, float,*,* int,*,*, int,*,* diff --git a/source/arraysize.c b/source/arraysize.c new file mode 100644 index 0000000..2e88139 --- /dev/null +++ b/source/arraysize.c @@ -0,0 +1,96 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#include "arraysize.h" + +int typesize(GLenum type) +{ + switch(type) + { + case GL_BYTE: return sizeof(GLbyte); + case GL_SHORT: return sizeof(GLshort); + case GL_INT: return sizeof(GLint); + case GL_UNSIGNED_BYTE: return sizeof(GLubyte); + case GL_UNSIGNED_SHORT: return sizeof(GLushort); + case GL_UNSIGNED_INT: return sizeof(GLuint); + case GL_FLOAT: return sizeof(GLfloat); + case GL_DOUBLE: return sizeof(GLdouble); + // Short and byte packed types are broken + default: return 1; + } +} + +int formatsize(GLenum format) +{ + switch(format) + { + case GL_COLOR_INDEX: return 1; + case GL_STENCIL_INDEX: return 1; + case GL_DEPTH_COMPONENT: return 1; + case GL_RED: return 1; + case GL_GREEN: return 1; + case GL_BLUE: return 1; + case GL_ALPHA: return 1; + case GL_RGB: return 3; + case GL_RGBA: return 4; + case GL_BGR: return 3; + case GL_BGRA: return 4; + case GL_LUMINANCE: return 1; + case GL_LUMINANCE_ALPHA: return 2; + default: return 1; + } +} + +int paramsize(GLenum pname) +{ + switch(pname) + { + // Lighting and material + case GL_AMBIENT: return 4; + case GL_DIFFUSE: return 4; + case GL_AMBIENT_AND_DIFFUSE: return 4; + case GL_SPECULAR: return 4; + case GL_EMISSION: return 4; + case GL_SHININESS: return 1; + case GL_COLOR_INDEXES: return 3; + case GL_POSITION: return 4; + case GL_SPOT_DIRECTION: return 3; + case GL_SPOT_EXPONENT: return 1; + case GL_SPOT_CUTOFF: return 1; + case GL_CONSTANT_ATTENUATION: return 1; + case GL_LINEAR_ATTENUATION: return 1; + case GL_QUADRATIC_ATTENUATION: return 1; + case GL_LIGHT_MODEL_AMBIENT: return 4; + case GL_LIGHT_MODEL_LOCAL_VIEWER: return 1; + case GL_LIGHT_MODEL_TWO_SIDE: return 1; + case GL_LIGHT_MODEL_COLOR_CONTROL: return 1; + + // Texture + case GL_TEXTURE_WRAP_S: return 1; + case GL_TEXTURE_WRAP_T: return 1; + case GL_TEXTURE_WRAP_R: return 1; + case GL_TEXTURE_MIN_FILTER: return 1; + case GL_TEXTURE_MAG_FILTER: return 1; + case GL_TEXTURE_BORDER_COLOR: return 4; + case GL_TEXTURE_MIN_LOD: return 1; + case GL_TEXTURE_MAX_LOD: return 1; + case GL_TEXTURE_BASE_LEVEL: return 1; + case GL_TEXTURE_MAX_LEVEL: return 1; + case GL_TEXTURE_LOD_BIAS: return 1; + case GL_DEPTH_TEXTURE_MODE: return 1; + case GL_TEXTURE_COMPARE_MODE: return 1; + case GL_TEXTURE_COMPARE_FUNC: return 1; + case GL_GENERATE_MIPMAP: return 1; + default: return 1; + } +} + +int mapsize(GLenum target) +{ + // XXX Implement this + return 1; +} diff --git a/source/arraysize.h b/source/arraysize.h new file mode 100644 index 0000000..7202136 --- /dev/null +++ b/source/arraysize.h @@ -0,0 +1,18 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#ifndef ARRAYSIZE_H_ +#define ARRAYSIZE_H_ + +#include + +extern int typesize(GLenum); +extern int formatsize(GLenum); +extern int paramsize(GLenum); +extern int mapsize(GLenum); + +#endif diff --git a/source/enums.c b/source/enums.c index 4875aa3..25fdaef 100644 --- a/source/enums.c +++ b/source/enums.c @@ -8,6 +8,7 @@ Distributed under the GPL #include #include #include "enums.h" +#include "tmpalloc.h" typedef struct sEnumInfo { @@ -18,21 +19,6 @@ typedef struct sEnumInfo #include "enums.table" -char *buffer = 0; -unsigned buf_pos = 0; - -static char *buf_reserve(unsigned size) -{ - char *ptr; - if(!buffer) - buffer = (char *)malloc(2048); - if(buf_pos+size>2048) - buf_pos = 0; - ptr = buffer+buf_pos; - buf_pos += size; - return ptr; -} - const char *describe_enum(GLenum value, const char *categ) { unsigned low = 0; @@ -64,7 +50,7 @@ const char *describe_enum(GLenum value, const char *categ) if(enums[high].value==value) return enums[high].name; - ptr = buf_reserve(20); + ptr = (char *)tmpalloc(20); snprintf(ptr, 20, "GLenum(0x%X)", value); return ptr; } @@ -72,7 +58,7 @@ const char *describe_enum(GLenum value, const char *categ) const char *describe_bitfield(int mask, const char *categ) { int bit; - char *buf = buf_reserve(200); + char *buf = (char *)tmpalloc(200); char *ptr = buf; for(bit=1; bit; bit<<=1) diff --git a/source/gldecoder.c b/source/gldecoder.c index 6e90373..863be92 100644 --- a/source/gldecoder.c +++ b/source/gldecoder.c @@ -130,6 +130,18 @@ static unsigned read_string(const unsigned char **v, const char *data) return read_data((const void **)v, data); } +static unsigned read_string_array(const unsigned char ***v, const char *data) +{ + int count; + unsigned pos = 0; + int i; + pos += read_int(&count, data); + *v = (const unsigned char **)tmpalloc(count*sizeof(const unsigned char *)); + for(i=0; i #include +#include +#include "arraysize.h" #include "enums.h" #include "glprint.h" +#include "tmpalloc.h" typedef struct sGlPrintData { char *buffer; unsigned bufsize; + int free_buf; } GlPrintData; static void init_print(GlDecoder *); -static void glprint_data_free(void *); +static void glprint_free(void *); static void print_gldError(void *, GLenum); GlDecoder *glprint_new(char *buffer, unsigned bufsize) @@ -28,15 +32,15 @@ GlDecoder *glprint_new(char *buffer, unsigned bufsize) gpd = (GlPrintData *)malloc(sizeof(GlPrintData)); gpd->buffer = buffer; gpd->bufsize = bufsize; + gpd->free_buf = 0; if(!gpd->buffer) { if(!gpd->bufsize) gpd->bufsize = 1024; gpd->buffer = (char *)malloc(gpd->bufsize); - dec = gldecoder_new(gpd, glprint_data_free); + gpd->free_buf = 1; } - else - dec = gldecoder_new(gpd, free); + dec = gldecoder_new(gpd, glprint_free); init_print(dec); dec->gldError = print_gldError; @@ -49,17 +53,82 @@ char *glprint_get_buffer(GlDecoder *dec) return ((GlPrintData *)dec->user_data)->buffer; } -static void glprint_data_free(void *data) +static void glprint_free(void *data) { GlPrintData *gpd = (GlPrintData *)data; - free(gpd->buffer); - free(gpd); + if(gpd->free_buf) + { + free(gpd->buffer); + free(gpd); + } + tmpfree(); } +static const char *print_array(const char *fmt, const void *data, unsigned elem_size, unsigned count) +{ + const char *cptr; + char type = 0; + char *buffer; + unsigned buf_size; + char *ptr; + unsigned i; + + for(cptr=fmt; (type<2 && *cptr); ++cptr) + { + if(*cptr=='%') + type = 1; + else if(type==1 && isalpha(*cptr)) + type = *cptr; + } + + count /= elem_size; + buf_size = count*20; + if(type=='s') + buf_size *= 50; + buffer = tmpalloc(buf_size); + ptr = buffer; + *ptr++ = '{'; + for(i=0; i0) + { + *ptr++ = ','; + *ptr++ = ' '; + } + memcpy(&element, (const char *)data+i*elem_size, elem_size); + if(type>='e' && type<='g' && elem_size==sizeof(float)) + *(double *)&element = *(float *)&element; + len = snprintf(ptr, buf_size, fmt, element); + ptr += len; + buf_size -= len; + } + *ptr++ = '}'; + *ptr = 0; + + return buffer; +} + +static const char *print_data(const void *data, unsigned size) +{ + if(!data) + return "NULL"; + else if(!size) + return "/* data */"; + else + { + char *buffer = tmpalloc(50); + snprintf(buffer, 50, "/* data: %d bytes */", size); + return buffer; + } +} + +#include "glprint.funcs" + static void print_gldError(void *user_data, GLenum code) { GlPrintData *gpd = (GlPrintData *)user_data; snprintf(gpd->buffer, gpd->bufsize, "ERROR: %s", describe_enum(code, "ErrorCode")); } - -#include "glprint.funcs" diff --git a/source/glprint.funcs.t b/source/glprint.funcs.t index 9c62ee0..db626c0 100644 --- a/source/glprint.funcs.t +++ b/source/glprint.funcs.t @@ -13,9 +13,14 @@ for p in params: if not first: w(', ') if p.kind=="value": - w("%s", p.io[1]) - else: - w("%%p") + w('%s', p.io[1]) + elif p.kind=="reference": + if p.io: + w('{%s}', p.io[1]) + else: + w('', p.type) + elif p.kind=="array": + w('%%s') first = False w(')') if ret.ctype!="void": @@ -23,11 +28,22 @@ if ret.ctype!="void": w('"') for p in params+[ret]: if p.ctype!="void": - if p.io and len(p.io)>=3 and p.io[2]: - f = p.io[2].split(':') - w(', %s(%s)', f[0], ", ".join(eval(x) for x in f[1:])) - else: - w(', %s', p.name) + if p.kind=="value": + if len(p.io)>=3 and p.io[2]: + f = p.io[2].split(':') + w(', %s(%s)', f[0], ", ".join(eval(x) for x in f[1:])) + else: + w(', %s', p.name) + elif p.kind=="reference": + if p.io: + w(', *%s', p.name) + elif p.kind=="array": + if not p.csize: + w(', print_data(%s, 0)', p.name) + elif p.base_ctype=="GLvoid" or p.base_ctype=="void": + w(', print_data(%s, %s)', p.name, p.csize) + else: + w(', print_array("%s", %s, sizeof(%s), %s)', p.io[1], p.name, p.base_ctype, p.csize) wl(');') wl('}') :static void init_print(GlDecoder *dec) diff --git a/source/glwrap.c b/source/glwrap.c index 0673b5a..79d6404 100644 --- a/source/glwrap.c +++ b/source/glwrap.c @@ -13,6 +13,7 @@ Distributed under the GPL #include #include #include +#include "arraysize.h" #include "functions.h" static inline void *glsym(const char *sym) @@ -121,6 +122,15 @@ static inline void write_string(const unsigned char *s) write_data(s, strlen(s)+1); } +static inline void write_string_array(const unsigned char **sa, unsigned size) +{ + unsigned i; + size /= sizeof(const unsigned char *); + write_int(size); + for(i=0; i +#include "tmpalloc.h" + +void *buffer = 0; +unsigned buf_size = 8192; +unsigned offset = 0; + +void *tmpalloc(unsigned size) +{ + void *ptr; + if(!buffer) + buffer = malloc(buf_size); + if(offset+size>buf_size) + offset = 0; + ptr = (char *)buffer+offset; + offset += size; + return ptr; +} + +void tmpfree() +{ + free(buffer); + buffer = 0; + offset = 0; +} diff --git a/source/tmpalloc.h b/source/tmpalloc.h new file mode 100644 index 0000000..dc673ca --- /dev/null +++ b/source/tmpalloc.h @@ -0,0 +1,23 @@ +/* $Id$ + +This file is part of gldbg +Copyright © 2009 Mikko Rasa, Mikkosoft Productions +Distributed under the GPL +*/ + +#ifndef TMPALLOC_H_ +#define TMPALLOC_H_ + +/** +Allocates a temporary memory region. The returned memory comes from a shared +pool and will get reused eventually. +*/ +extern void *tmpalloc(unsigned); + +/** +Frees the shared pool used by tmpalloc. It will be recreated if tmpalloc is +called again. +*/ +extern void tmpfree(); + +#endif