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