tr_dump.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  *
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  *
00026  **************************************************************************/
00027 
00028 
00041 #include "pipe/p_config.h"
00042 
00043 #if defined(PIPE_OS_LINUX)
00044 #include <stdlib.h>
00045 #endif
00046 
00047 #include "pipe/p_compiler.h"
00048 #include "pipe/p_thread.h"
00049 #include "pipe/p_debug.h"
00050 #include "util/u_memory.h"
00051 #include "util/u_string.h"
00052 #include "util/u_stream.h"
00053 
00054 #include "tr_dump.h"
00055 
00056 
00057 static struct util_stream *stream = NULL;
00058 static unsigned refcount = 0;
00059 static pipe_mutex call_mutex;
00060 static long unsigned call_no = 0;
00061 
00062 
00063 static INLINE void 
00064 trace_dump_write(const char *buf, size_t size)
00065 {
00066    if(stream)
00067       util_stream_write(stream, buf, size);
00068 }
00069 
00070 
00071 static INLINE void 
00072 trace_dump_writes(const char *s)
00073 {
00074    trace_dump_write(s, strlen(s));
00075 }
00076 
00077 
00078 static INLINE void 
00079 trace_dump_writef(const char *format, ...)
00080 {
00081    static char buf[1024];
00082    unsigned len;
00083    va_list ap;
00084    va_start(ap, format);
00085    len = util_vsnprintf(buf, sizeof(buf), format, ap);
00086    va_end(ap);
00087    trace_dump_write(buf, len);
00088 }
00089 
00090 
00091 static INLINE void 
00092 trace_dump_escape(const char *str) 
00093 {
00094    const unsigned char *p = (const unsigned char *)str;
00095    unsigned char c;
00096    while((c = *p++) != 0) {
00097       if(c == '<')
00098          trace_dump_writes("&lt;");
00099       else if(c == '>')
00100          trace_dump_writes("&gt;");
00101       else if(c == '&')
00102          trace_dump_writes("&amp;");
00103       else if(c == '\'')
00104          trace_dump_writes("&apos;");
00105       else if(c == '\"')
00106          trace_dump_writes("&quot;");
00107       else if(c >= 0x20 && c <= 0x7e)
00108          trace_dump_writef("%c", c);
00109       else
00110          trace_dump_writef("&#%u;", c);
00111    }
00112 }
00113 
00114 
00115 static INLINE void 
00116 trace_dump_indent(unsigned level)
00117 {
00118    unsigned i;
00119    for(i = 0; i < level; ++i)
00120       trace_dump_writes("\t");
00121 }
00122 
00123 
00124 static INLINE void 
00125 trace_dump_newline(void) 
00126 {
00127    trace_dump_writes("\n");
00128 }
00129 
00130 
00131 static INLINE void 
00132 trace_dump_tag(const char *name)
00133 {
00134    trace_dump_writes("<");
00135    trace_dump_writes(name);
00136    trace_dump_writes("/>");
00137 }
00138 
00139 
00140 static INLINE void 
00141 trace_dump_tag_begin(const char *name)
00142 {
00143    trace_dump_writes("<");
00144    trace_dump_writes(name);
00145    trace_dump_writes(">");
00146 }
00147 
00148 static INLINE void 
00149 trace_dump_tag_begin1(const char *name, 
00150                       const char *attr1, const char *value1)
00151 {
00152    trace_dump_writes("<");
00153    trace_dump_writes(name);
00154    trace_dump_writes(" ");
00155    trace_dump_writes(attr1);
00156    trace_dump_writes("='");
00157    trace_dump_escape(value1);
00158    trace_dump_writes("'>");
00159 }
00160 
00161 
00162 static INLINE void 
00163 trace_dump_tag_begin2(const char *name, 
00164                       const char *attr1, const char *value1,
00165                       const char *attr2, const char *value2)
00166 {
00167    trace_dump_writes("<");
00168    trace_dump_writes(name);
00169    trace_dump_writes(" ");
00170    trace_dump_writes(attr1);
00171    trace_dump_writes("=\'");
00172    trace_dump_escape(value1);
00173    trace_dump_writes("\' ");
00174    trace_dump_writes(attr2);
00175    trace_dump_writes("=\'");
00176    trace_dump_escape(value2);
00177    trace_dump_writes("\'>");
00178 }
00179 
00180 
00181 static INLINE void 
00182 trace_dump_tag_begin3(const char *name, 
00183                       const char *attr1, const char *value1,
00184                       const char *attr2, const char *value2,
00185                       const char *attr3, const char *value3)
00186 {
00187    trace_dump_writes("<");
00188    trace_dump_writes(name);
00189    trace_dump_writes(" ");
00190    trace_dump_writes(attr1);
00191    trace_dump_writes("=\'");
00192    trace_dump_escape(value1);
00193    trace_dump_writes("\' ");
00194    trace_dump_writes(attr2);
00195    trace_dump_writes("=\'");
00196    trace_dump_escape(value2);
00197    trace_dump_writes("\' ");
00198    trace_dump_writes(attr3);
00199    trace_dump_writes("=\'");
00200    trace_dump_escape(value3);
00201    trace_dump_writes("\'>");
00202 }
00203 
00204 
00205 static INLINE void
00206 trace_dump_tag_end(const char *name)
00207 {
00208    trace_dump_writes("</");
00209    trace_dump_writes(name);
00210    trace_dump_writes(">");
00211 }
00212 
00213 static void 
00214 trace_dump_trace_close(void)
00215 {
00216    if(stream) {
00217       trace_dump_writes("</trace>\n");
00218       util_stream_close(stream);
00219       stream = NULL;
00220       refcount = 0;
00221       call_no = 0;
00222       pipe_mutex_destroy(call_mutex);
00223    }
00224 }
00225 
00226 boolean trace_dump_trace_begin()
00227 {
00228    const char *filename;
00229    
00230    filename = debug_get_option("GALLIUM_TRACE", NULL);
00231    if(!filename)
00232       return FALSE;
00233    
00234    if(!stream) {
00235    
00236       stream = util_stream_create(filename, 0);
00237       if(!stream)
00238          return FALSE;
00239       
00240       pipe_mutex_init(call_mutex);
00241 
00242       trace_dump_writes("<?xml version='1.0' encoding='UTF-8'?>\n");
00243       trace_dump_writes("<?xml-stylesheet type='text/xsl' href='trace.xsl'?>\n");
00244       trace_dump_writes("<trace version='0.1'>\n");
00245       
00246 #if defined(PIPE_OS_LINUX)
00247       /* Linux applications rarely cleanup GL / Gallium resources so catch 
00248        * application exit here */ 
00249       atexit(trace_dump_trace_close);
00250 #endif
00251    }
00252    
00253    ++refcount;
00254    
00255    return TRUE;
00256 }
00257 
00258 boolean trace_dump_enabled(void)
00259 {
00260    return stream ? TRUE : FALSE;
00261 }
00262 
00263 void trace_dump_trace_end(void)
00264 {
00265    if(stream)
00266       if(!--refcount)
00267          trace_dump_trace_close();
00268 }
00269 
00270 void trace_dump_call_begin(const char *klass, const char *method)
00271 {
00272    pipe_mutex_lock(call_mutex);
00273    ++call_no;
00274    trace_dump_indent(1);
00275    trace_dump_writes("<call no=\'");
00276    trace_dump_writef("%lu", call_no);
00277    trace_dump_writes("\' class =\'");
00278    trace_dump_escape(klass);
00279    trace_dump_writes("\' method=\'");
00280    trace_dump_escape(method);
00281    trace_dump_writes("\'>");
00282    trace_dump_newline();
00283 }
00284 
00285 void trace_dump_call_end(void)
00286 {
00287    trace_dump_indent(1);
00288    trace_dump_tag_end("call");
00289    trace_dump_newline();
00290    util_stream_flush(stream);
00291    pipe_mutex_unlock(call_mutex);
00292 }
00293 
00294 void trace_dump_arg_begin(const char *name)
00295 {
00296    trace_dump_indent(2);
00297    trace_dump_tag_begin1("arg", "name", name);
00298 }
00299 
00300 void trace_dump_arg_end(void)
00301 {
00302    trace_dump_tag_end("arg");
00303    trace_dump_newline();
00304 }
00305 
00306 void trace_dump_ret_begin(void)
00307 {
00308    trace_dump_indent(2);
00309    trace_dump_tag_begin("ret");
00310 }
00311 
00312 void trace_dump_ret_end(void)
00313 {
00314    trace_dump_tag_end("ret");
00315    trace_dump_newline();
00316 }
00317 
00318 void trace_dump_bool(int value)
00319 {
00320    trace_dump_writef("<bool>%c</bool>", value ? '1' : '0');
00321 }
00322 
00323 void trace_dump_int(long long int value)
00324 {
00325    trace_dump_writef("<int>%lli</int>", value);
00326 }
00327 
00328 void trace_dump_uint(long long unsigned value)
00329 {
00330    trace_dump_writef("<uint>%llu</uint>", value);
00331 }
00332 
00333 void trace_dump_float(double value)
00334 {
00335    trace_dump_writef("<float>%g</float>", value);
00336 }
00337 
00338 void trace_dump_bytes(const void *data,
00339                       long unsigned size)
00340 {
00341    static const char hex_table[16] = "0123456789ABCDEF";
00342    const uint8_t *p = data;
00343    long unsigned i;
00344    trace_dump_writes("<bytes>");
00345    for(i = 0; i < size; ++i) {
00346       uint8_t byte = *p++;
00347       char hex[2];
00348       hex[0] = hex_table[byte >> 4];
00349       hex[1] = hex_table[byte & 0xf];
00350       trace_dump_write(hex, 2);
00351    }
00352    trace_dump_writes("</bytes>");
00353 }
00354 
00355 void trace_dump_string(const char *str)
00356 {
00357    trace_dump_writes("<string>");
00358    trace_dump_escape(str);
00359    trace_dump_writes("</string>");
00360 }
00361 
00362 void trace_dump_enum(const char *value)
00363 {
00364    trace_dump_writes("<enum>");
00365    trace_dump_escape(value);
00366    trace_dump_writes("</enum>");
00367 }
00368 
00369 void trace_dump_array_begin(void)
00370 {
00371    trace_dump_writes("<array>");
00372 }
00373 
00374 void trace_dump_array_end(void)
00375 {
00376    trace_dump_writes("</array>");
00377 }
00378 
00379 void trace_dump_elem_begin(void)
00380 {
00381    trace_dump_writes("<elem>");
00382 }
00383 
00384 void trace_dump_elem_end(void)
00385 {
00386    trace_dump_writes("</elem>");
00387 }
00388 
00389 void trace_dump_struct_begin(const char *name)
00390 {
00391    trace_dump_writef("<struct name='%s'>", name);
00392 }
00393 
00394 void trace_dump_struct_end(void)
00395 {
00396    trace_dump_writes("</struct>");
00397 }
00398 
00399 void trace_dump_member_begin(const char *name)
00400 {
00401    trace_dump_writef("<member name='%s'>", name);
00402 }
00403 
00404 void trace_dump_member_end(void)
00405 {
00406    trace_dump_writes("</member>");
00407 }
00408 
00409 void trace_dump_null(void)
00410 {
00411    trace_dump_writes("<null/>");
00412 }
00413 
00414 void trace_dump_ptr(const void *value)
00415 {
00416    if(value)
00417       trace_dump_writef("<ptr>0x%08lx</ptr>", (unsigned long)(uintptr_t)value);
00418    else
00419       trace_dump_null();
00420 }

Generated on Tue Sep 29 06:25:17 2009 for Gallium3D by  doxygen 1.5.4