Use snprintf to prevent buffer overflows in format_exception_msg.
[wine/multimedia.git] / library / debug.c
blob84a832a556ff8995e9ec3c3b23abdba672803e51
1 /*
2 * Management of the debugging channels
4 * Copyright 2000 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <ctype.h>
12 struct dll
14 struct dll *next; /* linked list of dlls */
15 struct dll *prev;
16 char * const *channels; /* array of channels */
17 int nb_channels; /* number of channels in array */
20 static struct dll *first_dll;
22 struct option
24 struct option *next; /* next option in list */
25 unsigned char set; /* bits to set */
26 unsigned char clear; /* bits to clear */
27 char name[14]; /* channel name, or empty for "all" */
30 static struct option *first_option;
31 static struct option *last_option;
34 static int cmp_name( const void *p1, const void *p2 )
36 const char *name = p1;
37 const char * const *chan = p2;
38 return strcmp( name, *chan + 1 );
41 /* apply a debug option to the channels of a given dll */
42 static void apply_option( struct dll *dll, const struct option *opt )
44 if (opt->name[0])
46 char **dbch = bsearch( opt->name, dll->channels, dll->nb_channels,
47 sizeof(*dll->channels), cmp_name );
48 if (dbch) **dbch = (**dbch & ~opt->clear) | opt->set;
50 else /* all */
52 int i;
53 for (i = 0; i < dll->nb_channels; i++)
54 dll->channels[i][0] = (dll->channels[i][0] & ~opt->clear) | opt->set;
58 /* register a new set of channels for a dll */
59 void *__wine_dbg_register( char * const *channels, int nb )
61 struct option *opt = first_option;
62 struct dll *dll = malloc( sizeof(*dll) );
63 if (dll)
65 dll->channels = channels;
66 dll->nb_channels = nb;
67 dll->prev = NULL;
68 if ((dll->next = first_dll)) dll->next->prev = dll;
69 first_dll = dll;
71 /* apply existing options to this dll */
72 while (opt)
74 apply_option( dll, opt );
75 opt = opt->next;
78 return dll;
82 /* unregister a set of channels; must pass the pointer obtained from wine_dbg_register */
83 void __wine_dbg_unregister( void *channel )
85 struct dll *dll = channel;
86 if (dll)
88 if (dll->next) dll->next->prev = dll->prev;
89 if (dll->prev) dll->prev->next = dll->next;
90 else first_dll = dll->next;
91 free( dll );
96 /* add a new debug option at the end of the option list */
97 void wine_dbg_add_option( const char *name, unsigned char set, unsigned char clear )
99 struct dll *dll = first_dll;
100 struct option *opt;
102 if (!(opt = malloc( sizeof(*opt) ))) return;
103 opt->next = NULL;
104 opt->set = set;
105 opt->clear = clear;
106 strncpy( opt->name, name, sizeof(opt->name) );
107 opt->name[sizeof(opt->name)-1] = 0;
108 if (last_option) last_option->next = opt;
109 else first_option = opt;
110 last_option = opt;
112 /* apply option to all existing dlls */
113 while (dll)
115 apply_option( dll, opt );
116 dll = dll->next;