]> git.tdb.fi Git - gldbg.git/blob - source/glprint.c
Print the contents of arrays and references
[gldbg.git] / source / glprint.c
1 /* $Id$
2
3 This file is part of gldbg
4 Copyright © 2009  Mikko Rasa, Mikkosoft Productions
5 Distributed under the GPL
6 */
7
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include "arraysize.h"
12 #include "enums.h"
13 #include "glprint.h"
14 #include "tmpalloc.h"
15
16 typedef struct sGlPrintData
17 {
18         char *buffer;
19         unsigned bufsize;
20         int free_buf;
21 } GlPrintData;
22
23 static void init_print(GlDecoder *);
24 static void glprint_free(void *);
25 static void print_gldError(void *, GLenum);
26
27 GlDecoder *glprint_new(char *buffer, unsigned bufsize)
28 {
29         GlDecoder *dec;
30         GlPrintData *gpd;
31
32         gpd = (GlPrintData *)malloc(sizeof(GlPrintData));
33         gpd->buffer = buffer;
34         gpd->bufsize = bufsize;
35         gpd->free_buf = 0;
36         if(!gpd->buffer)
37         {
38                 if(!gpd->bufsize)
39                         gpd->bufsize = 1024;
40                 gpd->buffer = (char *)malloc(gpd->bufsize);
41                 gpd->free_buf = 1;
42         }
43         dec = gldecoder_new(gpd, glprint_free);
44
45         init_print(dec);
46         dec->gldError = print_gldError;
47
48         return dec;
49 }
50
51 char *glprint_get_buffer(GlDecoder *dec)
52 {
53         return ((GlPrintData *)dec->user_data)->buffer;
54 }
55
56 static void glprint_free(void *data)
57 {
58         GlPrintData *gpd = (GlPrintData *)data;
59         if(gpd->free_buf)
60         {
61                 free(gpd->buffer);
62                 free(gpd);
63         }
64         tmpfree();
65 }
66
67 static const char *print_array(const char *fmt, const void *data, unsigned elem_size, unsigned count)
68 {
69         const char *cptr;
70         char type = 0;
71         char *buffer;
72         unsigned buf_size;
73         char *ptr;
74         unsigned i;
75
76         for(cptr=fmt; (type<2 && *cptr); ++cptr)
77         {
78                 if(*cptr=='%')
79                         type = 1;
80                 else if(type==1 && isalpha(*cptr))
81                         type = *cptr;
82         }
83
84         count /= elem_size;
85         buf_size = count*20;
86         if(type=='s')
87                 buf_size *= 50;
88         buffer = tmpalloc(buf_size);
89         ptr = buffer;
90         *ptr++ = '{';
91         for(i=0; i<count; ++i)
92         {
93                 long long element = 0;
94                 unsigned len;
95
96                 if(i>0)
97                 {
98                         *ptr++ = ',';
99                         *ptr++ = ' ';
100                 }
101                 memcpy(&element, (const char *)data+i*elem_size, elem_size);
102                 if(type>='e' && type<='g' && elem_size==sizeof(float))
103                         *(double *)&element = *(float *)&element;
104                 len = snprintf(ptr, buf_size, fmt, element);
105                 ptr += len;
106                 buf_size -= len;
107         }
108         *ptr++ = '}';
109         *ptr = 0;
110
111         return buffer;
112 }
113
114 static const char *print_data(const void *data, unsigned size)
115 {
116         if(!data)
117                 return "NULL";
118         else if(!size)
119                 return "/* data */";
120         else
121         {
122                 char *buffer = tmpalloc(50);
123                 snprintf(buffer, 50, "/* data: %d bytes */", size);
124                 return buffer;
125         }
126 }
127
128 #include "glprint.funcs"
129
130 static void print_gldError(void *user_data, GLenum code)
131 {
132         GlPrintData *gpd = (GlPrintData *)user_data;
133         snprintf(gpd->buffer, gpd->bufsize, "ERROR: %s", describe_enum(code, "ErrorCode"));
134 }