blob: 84a832a556ff8995e9ec3c3b23abdba672803e51 [file] [log] [blame]
Alexandre Julliard94613ab2000-11-05 04:51:34 +00001/*
2 * Management of the debugging channels
3 *
4 * Copyright 2000 Alexandre Julliard
5 */
6
7#include <stdlib.h>
8#include <string.h>
9#include <unistd.h>
10#include <ctype.h>
11
12struct dll
13{
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 */
18};
19
20static struct dll *first_dll;
21
22struct option
23{
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" */
28};
29
30static struct option *first_option;
31static struct option *last_option;
32
33
34static int cmp_name( const void *p1, const void *p2 )
35{
36 const char *name = p1;
37 const char * const *chan = p2;
38 return strcmp( name, *chan + 1 );
39}
40
41/* apply a debug option to the channels of a given dll */
42static void apply_option( struct dll *dll, const struct option *opt )
43{
44 if (opt->name[0])
45 {
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;
49 }
50 else /* all */
51 {
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;
55 }
56}
57
58/* register a new set of channels for a dll */
Alexandre Julliarde0875082000-11-08 04:33:20 +000059void *__wine_dbg_register( char * const *channels, int nb )
Alexandre Julliard94613ab2000-11-05 04:51:34 +000060{
61 struct option *opt = first_option;
62 struct dll *dll = malloc( sizeof(*dll) );
63 if (dll)
64 {
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;
70
71 /* apply existing options to this dll */
72 while (opt)
73 {
74 apply_option( dll, opt );
75 opt = opt->next;
76 }
77 }
78 return dll;
79}
80
81
82/* unregister a set of channels; must pass the pointer obtained from wine_dbg_register */
Alexandre Julliarde0875082000-11-08 04:33:20 +000083void __wine_dbg_unregister( void *channel )
Alexandre Julliard94613ab2000-11-05 04:51:34 +000084{
85 struct dll *dll = channel;
86 if (dll)
87 {
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 );
92 }
93}
94
95
96/* add a new debug option at the end of the option list */
97void wine_dbg_add_option( const char *name, unsigned char set, unsigned char clear )
98{
99 struct dll *dll = first_dll;
100 struct option *opt;
101
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;
111
112 /* apply option to all existing dlls */
113 while (dll)
114 {
115 apply_option( dll, opt );
116 dll = dll->next;
117 }
118}