trace.c revision 1.1.1.2 1 1.1 mrg /* Support for diagnostic traces.
2 1.1 mrg
3 1.1 mrg Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation,
4 1.1 mrg Inc.
5 1.1 mrg
6 1.1.1.2 mrg This file is part of the GNU MP Library test suite.
7 1.1 mrg
8 1.1.1.2 mrg The GNU MP Library test suite is free software; you can redistribute it
9 1.1.1.2 mrg and/or modify it under the terms of the GNU General Public License as
10 1.1.1.2 mrg published by the Free Software Foundation; either version 3 of the License,
11 1.1.1.2 mrg or (at your option) any later version.
12 1.1.1.2 mrg
13 1.1.1.2 mrg The GNU MP Library test suite is distributed in the hope that it will be
14 1.1.1.2 mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1.1.2 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 1.1.1.2 mrg Public License for more details.
17 1.1 mrg
18 1.1.1.2 mrg You should have received a copy of the GNU General Public License along with
19 1.1.1.2 mrg the GNU MP Library test suite. If not, see http://www.gnu.org/licenses/. */
20 1.1 mrg
21 1.1 mrg
22 1.1 mrg /* Future: Would like commas printed between limbs in hex or binary, but
23 1.1 mrg perhaps not always since it might upset cutting and pasting into bc or
24 1.1 mrg whatever. */
25 1.1 mrg
26 1.1 mrg
27 1.1 mrg #include <stdio.h>
28 1.1 mrg #include <stdlib.h>
29 1.1 mrg #include <string.h> /* for strlen */
30 1.1 mrg
31 1.1 mrg #include "gmp.h"
32 1.1 mrg #include "gmp-impl.h"
33 1.1 mrg
34 1.1 mrg #include "tests.h"
35 1.1 mrg
36 1.1 mrg
37 1.1 mrg /* Number base for the various trace printing routines.
38 1.1 mrg Set this in main() or with the debugger.
39 1.1 mrg If hexadecimal is going to be fed into GNU bc, remember to use -16
40 1.1 mrg because bc requires upper case. */
41 1.1 mrg
42 1.1 mrg int mp_trace_base = 10;
43 1.1 mrg
44 1.1 mrg
45 1.1 mrg void
46 1.1 mrg mp_trace_start (const char *name)
47 1.1 mrg {
48 1.1 mrg if (name != NULL && name[0] != '\0')
49 1.1 mrg printf ("%s=", name);
50 1.1 mrg
51 1.1 mrg switch (ABS (mp_trace_base)) {
52 1.1 mrg case 2: printf ("bin:"); break;
53 1.1 mrg case 8: printf ("oct:"); break;
54 1.1 mrg case 10: break;
55 1.1 mrg case 16: printf ("0x"); break;
56 1.1 mrg default: printf ("base%d:", ABS (mp_trace_base)); break;
57 1.1 mrg }
58 1.1 mrg }
59 1.1 mrg
60 1.1 mrg /* Print "name=value\n" to stdout for an mpq_t value. */
61 1.1 mrg void
62 1.1 mrg mpq_trace (const char *name, mpq_srcptr q)
63 1.1 mrg {
64 1.1 mrg mp_trace_start (name);
65 1.1 mrg if (q == NULL)
66 1.1 mrg {
67 1.1 mrg printf ("NULL\n");
68 1.1 mrg return;
69 1.1 mrg }
70 1.1 mrg
71 1.1 mrg mpq_out_str (stdout, mp_trace_base, q);
72 1.1 mrg printf ("\n");
73 1.1 mrg }
74 1.1 mrg
75 1.1 mrg
76 1.1 mrg /* Print "name=value\n" to stdout for an mpz_t value. */
77 1.1 mrg void
78 1.1 mrg mpz_trace (const char *name, mpz_srcptr z)
79 1.1 mrg {
80 1.1 mrg mpq_t q;
81 1.1 mrg mp_limb_t one;
82 1.1 mrg
83 1.1 mrg if (z == NULL)
84 1.1 mrg {
85 1.1 mrg mpq_trace (name, NULL);
86 1.1 mrg return;
87 1.1 mrg }
88 1.1 mrg
89 1.1 mrg q->_mp_num._mp_alloc = ALLOC(z);
90 1.1 mrg q->_mp_num._mp_size = SIZ(z);
91 1.1 mrg q->_mp_num._mp_d = PTR(z);
92 1.1 mrg
93 1.1 mrg one = 1;
94 1.1 mrg q->_mp_den._mp_alloc = 1;
95 1.1 mrg q->_mp_den._mp_size = 1;
96 1.1 mrg q->_mp_den._mp_d = &one;
97 1.1 mrg
98 1.1 mrg mpq_trace(name, q);
99 1.1 mrg }
100 1.1 mrg
101 1.1 mrg
102 1.1 mrg /* Print "name=value\n" to stdout for an mpf_t value. */
103 1.1 mrg void
104 1.1 mrg mpf_trace (const char *name, mpf_srcptr f)
105 1.1 mrg {
106 1.1 mrg mp_trace_start (name);
107 1.1 mrg if (f == NULL)
108 1.1 mrg {
109 1.1 mrg printf ("NULL\n");
110 1.1 mrg return;
111 1.1 mrg }
112 1.1 mrg
113 1.1 mrg mpf_out_str (stdout, ABS (mp_trace_base), 0, f);
114 1.1 mrg printf ("\n");
115 1.1 mrg }
116 1.1 mrg
117 1.1 mrg
118 1.1 mrg /* Print "namenum=value\n" to stdout for an mpz_t value.
119 1.1 mrg "name" should have a "%d" to get the number. */
120 1.1 mrg void
121 1.1 mrg mpz_tracen (const char *name, int num, mpz_srcptr z)
122 1.1 mrg {
123 1.1 mrg if (name != NULL && name[0] != '\0')
124 1.1 mrg {
125 1.1 mrg printf (name, num);
126 1.1 mrg putchar ('=');
127 1.1 mrg }
128 1.1 mrg mpz_trace (NULL, z);
129 1.1 mrg }
130 1.1 mrg
131 1.1 mrg
132 1.1 mrg /* Print "name=value\n" to stdout for an mpn style ptr,size. */
133 1.1 mrg void
134 1.1 mrg mpn_trace (const char *name, mp_srcptr ptr, mp_size_t size)
135 1.1 mrg {
136 1.1 mrg mpz_t z;
137 1.1 mrg if (ptr == NULL)
138 1.1 mrg {
139 1.1 mrg mpz_trace (name, NULL);
140 1.1 mrg return;
141 1.1 mrg }
142 1.1 mrg MPN_NORMALIZE (ptr, size);
143 1.1 mrg PTR(z) = (mp_ptr) ptr;
144 1.1 mrg SIZ(z) = size;
145 1.1 mrg ALLOC(z) = size;
146 1.1 mrg mpz_trace (name, z);
147 1.1 mrg }
148 1.1 mrg
149 1.1 mrg /* Print "name=value\n" to stdout for a limb, nail doesn't have to be zero. */
150 1.1 mrg void
151 1.1 mrg mp_limb_trace (const char *name, mp_limb_t n)
152 1.1 mrg {
153 1.1 mrg #if GMP_NAIL_BITS != 0
154 1.1 mrg mp_limb_t a[2];
155 1.1 mrg a[0] = n & GMP_NUMB_MASK;
156 1.1 mrg a[1] = n >> GMP_NUMB_BITS;
157 1.1 mrg mpn_trace (name, a, (mp_size_t) 2);
158 1.1 mrg #else
159 1.1 mrg mpn_trace (name, &n, (mp_size_t) 1);
160 1.1 mrg #endif
161 1.1 mrg }
162 1.1 mrg
163 1.1 mrg
164 1.1 mrg /* Print "namenum=value\n" to stdout for an mpn style ptr,size.
165 1.1 mrg "name" should have a "%d" to get the number. */
166 1.1 mrg void
167 1.1 mrg mpn_tracen (const char *name, int num, mp_srcptr ptr, mp_size_t size)
168 1.1 mrg {
169 1.1 mrg if (name != NULL && name[0] != '\0')
170 1.1 mrg {
171 1.1 mrg printf (name, num);
172 1.1 mrg putchar ('=');
173 1.1 mrg }
174 1.1 mrg mpn_trace (NULL, ptr, size);
175 1.1 mrg }
176 1.1 mrg
177 1.1 mrg
178 1.1 mrg /* Print "namenum=value\n" to stdout for an array of mpn style ptr,size.
179 1.1 mrg
180 1.1 mrg "a" is an array of pointers, each a[i] is a pointer to "size" many limbs.
181 1.1 mrg The formal parameter isn't mp_srcptr because that causes compiler
182 1.1 mrg warnings, but the values aren't modified.
183 1.1 mrg
184 1.1 mrg "name" should have a printf style "%d" to get the array index. */
185 1.1 mrg
186 1.1 mrg void
187 1.1 mrg mpn_tracea (const char *name, const mp_ptr *a, int count, mp_size_t size)
188 1.1 mrg {
189 1.1 mrg int i;
190 1.1 mrg for (i = 0; i < count; i++)
191 1.1 mrg mpn_tracen (name, i, a[i], size);
192 1.1 mrg }
193 1.1 mrg
194 1.1 mrg
195 1.1 mrg /* Print "value\n" to a file for an mpz_t value. Any previous contents of
196 1.1 mrg the file are overwritten, so you need different file names each time this
197 1.1 mrg is called.
198 1.1 mrg
199 1.1 mrg Overwriting the file is a feature, it means you get old data replaced
200 1.1 mrg when you run a test program repeatedly. */
201 1.1 mrg
202 1.1 mrg void
203 1.1 mrg mpn_trace_file (const char *filename, mp_srcptr ptr, mp_size_t size)
204 1.1 mrg {
205 1.1 mrg FILE *fp;
206 1.1 mrg mpz_t z;
207 1.1 mrg
208 1.1 mrg fp = fopen (filename, "w");
209 1.1 mrg if (fp == NULL)
210 1.1 mrg {
211 1.1 mrg perror ("fopen");
212 1.1 mrg abort();
213 1.1 mrg }
214 1.1 mrg
215 1.1 mrg MPN_NORMALIZE (ptr, size);
216 1.1 mrg PTR(z) = (mp_ptr) ptr;
217 1.1 mrg SIZ(z) = (int) size;
218 1.1 mrg
219 1.1 mrg mpz_out_str (fp, mp_trace_base, z);
220 1.1 mrg fprintf (fp, "\n");
221 1.1 mrg
222 1.1 mrg if (ferror (fp) || fclose (fp) != 0)
223 1.1 mrg {
224 1.1 mrg printf ("error writing %s\n", filename);
225 1.1 mrg abort();
226 1.1 mrg }
227 1.1 mrg }
228 1.1 mrg
229 1.1 mrg
230 1.1 mrg /* Print "value\n" to a set of files, one file for each element of the given
231 1.1 mrg array of mpn style ptr,size. Any previous contents of the files are
232 1.1 mrg overwritten, so you need different file names each time this is called.
233 1.1 mrg Each file is "filenameN" where N is 0 to count-1.
234 1.1 mrg
235 1.1 mrg "a" is an array of pointers, each a[i] is a pointer to "size" many limbs.
236 1.1 mrg The formal parameter isn't mp_srcptr because that causes compiler
237 1.1 mrg warnings, but the values aren't modified.
238 1.1 mrg
239 1.1 mrg Overwriting the files is a feature, it means you get old data replaced
240 1.1 mrg when you run a test program repeatedly. The output style isn't
241 1.1 mrg particularly pretty, but at least it gets something out, and you can cat
242 1.1 mrg the files into bc, or whatever. */
243 1.1 mrg
244 1.1 mrg void
245 1.1 mrg mpn_tracea_file (const char *filename,
246 1.1 mrg const mp_ptr *a, int count, mp_size_t size)
247 1.1 mrg {
248 1.1 mrg char *s;
249 1.1 mrg int i;
250 1.1 mrg TMP_DECL;
251 1.1 mrg
252 1.1 mrg TMP_MARK;
253 1.1 mrg s = (char *) TMP_ALLOC (strlen (filename) + 50);
254 1.1 mrg
255 1.1 mrg for (i = 0; i < count; i++)
256 1.1 mrg {
257 1.1 mrg sprintf (s, "%s%d", filename, i);
258 1.1 mrg mpn_trace_file (s, a[i], size);
259 1.1 mrg }
260 1.1 mrg
261 1.1 mrg TMP_FREE;
262 1.1 mrg }
263 1.1 mrg
264 1.1 mrg
265 1.1 mrg void
266 1.1 mrg byte_trace (const char *name, const void *ptr, mp_size_t size)
267 1.1 mrg {
268 1.1.1.2 mrg const char *fmt;
269 1.1 mrg mp_size_t i;
270 1.1 mrg
271 1.1 mrg mp_trace_start (name);
272 1.1 mrg
273 1.1 mrg switch (mp_trace_base) {
274 1.1 mrg case 8: fmt = " %o"; break;
275 1.1 mrg case 10: fmt = " %d"; break;
276 1.1 mrg case 16: fmt = " %x"; break;
277 1.1 mrg case -16: fmt = " %X"; break;
278 1.1 mrg default: printf ("Oops, unsupported base in byte_trace\n"); abort (); break;
279 1.1 mrg }
280 1.1 mrg
281 1.1 mrg for (i = 0; i < size; i++)
282 1.1 mrg printf (fmt, (int) ((unsigned char *) ptr)[i]);
283 1.1 mrg printf ("\n");
284 1.1 mrg }
285 1.1 mrg
286 1.1 mrg void
287 1.1 mrg byte_tracen (const char *name, int num, const void *ptr, mp_size_t size)
288 1.1 mrg {
289 1.1 mrg if (name != NULL && name[0] != '\0')
290 1.1 mrg {
291 1.1 mrg printf (name, num);
292 1.1 mrg putchar ('=');
293 1.1 mrg }
294 1.1 mrg byte_trace (NULL, ptr, size);
295 1.1 mrg }
296 1.1 mrg
297 1.1 mrg
298 1.1 mrg void
299 1.1 mrg d_trace (const char *name, double d)
300 1.1 mrg {
301 1.1 mrg union {
302 1.1 mrg double d;
303 1.1 mrg unsigned char b[sizeof(double)];
304 1.1 mrg } u;
305 1.1 mrg int i;
306 1.1 mrg
307 1.1 mrg if (name != NULL && name[0] != '\0')
308 1.1 mrg printf ("%s=", name);
309 1.1 mrg
310 1.1 mrg u.d = d;
311 1.1 mrg printf ("[");
312 1.1 mrg for (i = 0; i < sizeof (u.b); i++)
313 1.1 mrg {
314 1.1 mrg if (i != 0)
315 1.1 mrg printf (" ");
316 1.1 mrg printf ("%02X", (int) u.b[i]);
317 1.1 mrg }
318 1.1 mrg printf ("] %.20g\n", d);
319 1.1 mrg }
320