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