Mercurial > libpst
annotate src/debug.c @ 286:ea7b2e4f474f
update COPYING with FSF current address
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Tue, 24 May 2011 16:29:41 -0700 |
parents | 156cf548c764 |
children | cc8ee701f190 |
rev | line source |
---|---|
48 | 1 #include "define.h" |
16 | 2 |
33
12cac756bc05
enable -d option, but if not specified, don't generate a debug file
carl
parents:
31
diff
changeset
|
3 |
46 | 4 struct pst_debug_func { |
5 char * name; | |
6 struct pst_debug_func *next; | |
172
6954d315aaa8
move version-info into main configure.in, and set it properly.
Carl Byington <carl@five-ten-sg.com>
parents:
129
diff
changeset
|
7 }; |
6954d315aaa8
move version-info into main configure.in, and set it properly.
Carl Byington <carl@five-ten-sg.com>
parents:
129
diff
changeset
|
8 |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
9 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
10 #define NUM_COL 32 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
11 #define MAX_DEPTH 32 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
12 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
13 static struct pst_debug_func *func_head = NULL; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
14 static int func_depth = 0; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
15 static char indent[MAX_DEPTH*4+1]; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
16 static FILE *debug_fp = NULL; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
17 #ifdef HAVE_SEMAPHORE_H |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
18 static sem_t* debug_mutex = NULL; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
19 #endif |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
20 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
21 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
22 void pst_debug_lock() |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
23 { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
24 #ifdef HAVE_SEMAPHORE_H |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
25 if (debug_mutex) sem_wait(debug_mutex); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
26 #endif |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
27 } |
16 | 28 |
29 | |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
30 void pst_debug_unlock() |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
31 { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
32 #ifdef HAVE_SEMAPHORE_H |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
33 if (debug_mutex) sem_post(debug_mutex); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
34 #endif |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
35 } |
16 | 36 |
176
ac6e22c8a9cf
build separate libpst, libpst-libs, libpst-devel rpms.
Carl Byington <carl@five-ten-sg.com>
parents:
172
diff
changeset
|
37 |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
38 void pst_debug_init(const char* fname, void* output_mutex) { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
39 #ifdef HAVE_SEMAPHORE_H |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
40 debug_mutex = (sem_t*)output_mutex; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
41 #endif |
260
156cf548c764
adding more debug code
Carl Byington <carl@five-ten-sg.com>
parents:
202
diff
changeset
|
42 memset(indent, ' ', MAX_DEPTH*4); |
156cf548c764
adding more debug code
Carl Byington <carl@five-ten-sg.com>
parents:
202
diff
changeset
|
43 indent[MAX_DEPTH*4] = '\0'; |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
44 if (debug_fp) pst_debug_close(); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
45 if (!fname) return; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
46 if ((debug_fp = fopen(fname, "wb")) == NULL) { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
47 fprintf(stderr, "Opening of file %s failed\n", fname); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
48 exit(1); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
49 } |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
50 } |
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
51 |
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
52 |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
53 void pst_debug_func(const char* function) { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
54 struct pst_debug_func *func_ptr = pst_malloc (sizeof(struct pst_debug_func)); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
55 func_ptr->name = strdup(function); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
56 func_ptr->next = func_head; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
57 func_head = func_ptr; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
58 func_depth++; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
59 } |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
60 |
16 | 61 |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
62 void pst_debug_func_ret() { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
63 //remove the head item |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
64 struct pst_debug_func *func_ptr = func_head; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
65 if (func_head) { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
66 func_head = func_head->next; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
67 free(func_ptr->name); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
68 free(func_ptr); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
69 func_depth--; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
70 } else { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
71 DIE(("function list is empty!\n")); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
72 } |
16 | 73 } |
74 | |
33
12cac756bc05
enable -d option, but if not specified, don't generate a debug file
carl
parents:
31
diff
changeset
|
75 |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
76 static void pst_debug_info(int line, const char* file); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
77 static void pst_debug_info(int line, const char* file) { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
78 int le = (func_depth > MAX_DEPTH) ? MAX_DEPTH : func_depth; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
79 if (le > 0) le--; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
80 char *func = (func_head ? func_head->name : "No Function"); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
81 pst_debug_lock(); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
82 fprintf(debug_fp, "%06d %.*s%s %s(%d) ", getpid(), le*4, indent, func, file, line); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
83 } |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
84 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
85 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
86 void pst_debug(int line, const char* file, const char *fmt, ...) { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
87 if (debug_fp) { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
88 pst_debug_info(line, file); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
89 va_list ap; |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
90 va_start(ap,fmt); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
91 vfprintf(debug_fp, fmt, ap); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
92 va_end(ap); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
93 fflush(debug_fp); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
94 pst_debug_unlock(); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
95 } |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
96 } |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
97 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
98 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
99 void pst_debug_hexdump(int line, const char *file, const char *buf, size_t size, int cols, int delta) { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
100 if (debug_fp) { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
101 pst_debug_info(line, file); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
102 pst_debug_hexdumper(debug_fp, buf, size, cols, delta); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
103 pst_debug_unlock(); |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
104 } |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
105 } |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
106 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
107 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
108 void pst_debug_hexdumper(FILE *out, const char *buf, size_t size, int cols, int delta) { |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
109 int le = (func_depth > MAX_DEPTH) ? MAX_DEPTH : func_depth; |
70
b12f4e50e2e8
Patch from Joachim Metz <joachim.metz@gmail.com> for 64 bit compile.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
110 size_t off = 0, toff; |
46 | 111 int count = 0; |
16 | 112 |
46 | 113 if (!out) return; // no file |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
114 |
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
115 if (cols == -1) cols = NUM_COL; |
46 | 116 fprintf(out, "\n"); |
117 while (off < size) { | |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
118 fprintf(out, "%06d %.*s%06"PRIx64"\t:", getpid(), le*4, indent, (int64_t)(off+delta)); |
46 | 119 toff = off; |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
120 while (count < cols && off < size) { |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
121 fprintf(out, "%02hhx ", (unsigned char)buf[off]); |
46 | 122 off++; count++; |
123 } | |
124 off = toff; | |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
125 while (count < cols) { |
46 | 126 // only happens at end of block to pad the text over to the text column |
127 fprintf(out, " "); | |
128 count++; | |
129 } | |
130 count = 0; | |
131 fprintf(out, ":"); | |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
132 while (count < cols && off < size) { |
46 | 133 fprintf(out, "%c", isgraph(buf[off])?buf[off]:'.'); |
134 off++; count ++; | |
135 } | |
16 | 136 |
46 | 137 fprintf(out, "\n"); |
138 count=0; | |
139 } | |
33
12cac756bc05
enable -d option, but if not specified, don't generate a debug file
carl
parents:
31
diff
changeset
|
140 |
46 | 141 fprintf(out, "\n"); |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
142 fflush(out); |
16 | 143 } |
144 | |
33
12cac756bc05
enable -d option, but if not specified, don't generate a debug file
carl
parents:
31
diff
changeset
|
145 |
46 | 146 void pst_debug_close(void) { |
147 while (func_head) { | |
202
2f38c4ce606f
remove readpstlog, switch to plain ascii debug log files
Carl Byington <carl@five-ten-sg.com>
parents:
176
diff
changeset
|
148 struct pst_debug_func *func_ptr = func_head; |
46 | 149 func_head = func_head->next; |
150 free(func_ptr->name); | |
151 free(func_ptr); | |
152 } | |
153 if (debug_fp) fclose(debug_fp); | |
154 debug_fp = NULL; | |
33
12cac756bc05
enable -d option, but if not specified, don't generate a debug file
carl
parents:
31
diff
changeset
|
155 } |
16 | 156 |
157 | |
172
6954d315aaa8
move version-info into main configure.in, and set it properly.
Carl Byington <carl@five-ten-sg.com>
parents:
129
diff
changeset
|
158 void *pst_malloc(size_t size) { |
46 | 159 void *mem = malloc(size); |
160 if (!mem) { | |
172
6954d315aaa8
move version-info into main configure.in, and set it properly.
Carl Byington <carl@five-ten-sg.com>
parents:
129
diff
changeset
|
161 fprintf(stderr, "pst_malloc: Out Of memory [req: %ld]\n", (long)size); |
46 | 162 exit(1); |
163 } | |
164 return mem; | |
33
12cac756bc05
enable -d option, but if not specified, don't generate a debug file
carl
parents:
31
diff
changeset
|
165 } |
12cac756bc05
enable -d option, but if not specified, don't generate a debug file
carl
parents:
31
diff
changeset
|
166 |