386BSD 0.1 development
[unix-history] / usr / othersrc / public / ghostscript-2.4.1 / idebug.c
CommitLineData
5aa04bbc
WJ
1/* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved.
2 Distributed by Free Software Foundation, Inc.
3
4This file is part of Ghostscript.
5
6Ghostscript is distributed in the hope that it will be useful, but
7WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
8to anyone for the consequences of using it or for whether it serves any
9particular purpose or works at all, unless he says so in writing. Refer
10to the Ghostscript General Public License for full details.
11
12Everyone is granted permission to copy, modify and redistribute
13Ghostscript, but only under the conditions described in the Ghostscript
14General Public License. A copy of this license is supposed to have been
15given to you along with Ghostscript so you can know your rights and
16responsibilities. It should be in a file named COPYING. Among other
17things, the copyright notice and this notice must be preserved on all
18copies. */
19
20/* idebug.c */
21/* Debugging support for Ghostscript interpreter */
22#include "string_.h"
23#include "ghost.h"
24#include "iutil.h"
25#include "dict.h"
26#include "name.h"
27#include "ostack.h" /* for opdef.h */
28#include "opdef.h"
29#include "packed.h"
30#include "store.h" /* for make_oper for opdef.h */
31
32/* Forward references */
33void debug_print_string(P2(const byte *, ushort));
34#define debug_print_name(pnref)\
35 debug_print_string((pnref)->value.pname->string_bytes,\
36 (pnref)->value.pname->string_size)
37
38/* Table of type name strings */
39static const char *type_strings[] = { type_print_strings };
40
41/* Print a ref */
42void debug_print_ref(P1(const ref *));
43void
44debug_print_full_ref(const ref *pref)
45{ unsigned size = r_size(pref);
46 ref nref;
47 dprintf1("(%x)", r_type_attrs(pref));
48 switch ( r_type(pref) )
49 {
50 case t_array:
51 dprintf2("array(%u)0x%lx", size, (ulong)pref->value.refs); break;
52 case t_boolean:
53 dprintf1("boolean %x", pref->value.index); break;
54 case t_color:
55 dprintf1("color 0x%lx", (ulong)pref->value.pcolor); break;
56 case t_condition:
57 dprintf1("condition 0x%lx", (ulong)pref->value.pcond); break;
58 case t_device:
59 dprintf1("device 0x%lx", (ulong)pref->value.pdevice); break;
60 case t_dictionary:
61 dprintf3("dict(%u/%u)0x%lx",
62 dict_length(pref), dict_maxlength(pref),
63 (ulong)pref->value.pdict);
64 break;
65 case t_file:
66 dprintf1("file 0x%lx", (ulong)pref->value.pfile); break;
67 case t_gstate:
68 dprintf1("gstate 0x%lx", (ulong)pref->value.pgstate); break;
69 case t_integer: dprintf1("int %ld", pref->value.intval); break;
70 case t_lock:
71 dprintf1("lock 0x%lx", (ulong)pref->value.plock); break;
72 case t_mark: dprintf("mark"); break;
73 case t_mixedarray:
74 dprintf2("mixed packedarray(%u)0x%lx", size,
75 (ulong)pref->value.packed); break;
76 case t_name:
77 dprintf2("name(0x%lx#%x)", (ulong)pref->value.pname,
78 pref->value.pname->index);
79 debug_print_name(pref);
80 break;
81 case t_null: dprintf("null"); break;
82 case t_oparray:
83 dprintf1("op_array(0x%x)", size);
84 name_index_ref(op_array_nx_table[size - op_def_count], &nref);
85 debug_print_name(&nref);
86 break;
87 case t_operator:
88 dprintf1("op(0x%x", size);
89 if ( size )
90 dprintf1(":%s", (const char *)(op_def_table[size]->oname + 1));
91 dprintf1(")0x%lx", (ulong)pref->value.opproc);
92 break;
93 case t_real: dprintf1("real %f", pref->value.realval); break;
94 case t_shortarray:
95 dprintf2("short packedarray(%u)0x%lx", size,
96 (ulong)pref->value.packed); break;
97 case t_string:
98 dprintf2("string(%u)0x%lx", size, (ulong)pref->value.bytes); break;
99 default: dprintf1("type 0x%x", r_type(pref));
100 }
101}
102void
103debug_print_packed_ref(const ref_packed *pref)
104{ ushort elt = *pref;
105 ref nref;
106 switch ( elt >> packed_type_shift )
107 {
108 case pt_executable_operator:
109 dprintf("<op_name>");
110 elt &= packed_int_mask;
111 op_index_ref(elt, &nref);
112 debug_print_ref(&nref);
113 break;
114 case pt_integer:
115 dprintf1("<int> %d", (elt & packed_int_mask) + packed_min_intval);
116 break;
117 case pt_literal_name: case pt_literal_name+1:
118 dprintf("<lit_name>"); elt &= packed_max_name_index; goto ptn;
119 case pt_executable_name: case pt_executable_name+1:
120 dprintf("<exec_name>"); elt &= packed_max_name_index;
121ptn: name_index_ref(elt, &nref);
122 dprintf2("(0x%lx#%x)", (ulong)nref.value.pname, elt);
123 debug_print_name(&nref);
124 break;
125 }
126}
127void
128debug_print_ref(const ref *pref)
129{ if ( r_is_packed(pref) )
130 debug_print_packed_ref((const ref_packed *)pref);
131 else
132 debug_print_full_ref(pref);
133}
134
135/* Print a string */
136void
137debug_print_string(const byte *chrs, ushort len)
138{ ushort i;
139 for ( i = 0; i < len; i++ )
140 dputc(chrs[i]);
141}
142
143/* Dump one ref */
144void
145debug_dump_one_ref(const ref *p)
146{ uint attrs = r_type_attrs(p);
147 uint btype = r_btype(p);
148 static const char *as = attr_print_string;
149 const char *ap = as;
150#define buf_size 30
151 char buf[buf_size + 1];
152 uint plen;
153 if ( btype >= t_next_index )
154 dprintf1("0x%02x?? ", btype);
155 else
156 dprintf1("%s ", type_strings[btype]);
157 for ( ; *ap; ap++, attrs >>= 1 )
158 if ( *ap != '.' )
159 dputc(((attrs & 1) ? *ap : '-'));
160 dprintf2(" 0x%04x 0x%08lx", r_size(p), *(const ulong *)&p->value);
161 if ( obj_cvs(p, (byte *)buf, buf_size, &plen) >= 0 &&
162 ((buf[plen] = 0), strcmp(buf, "--nostringval--"))
163 )
164 dprintf1(" = %s", buf);
165}
166
167/* Dump a region of memory containing refs */
168void
169debug_dump_refs(const ref *from, uint size, const char *msg)
170{ const ref *p = from;
171 uint count = size;
172 if ( size && msg )
173 dprintf2("%s at 0x%lx:\n", msg, (ulong)from);
174 while ( count-- )
175 { dprintf2("..%04x: 0x%02x ", (uint)p & 0xffff, r_type(p));
176 debug_dump_one_ref(p);
177 dputc('\n');
178 p++;
179 }
180}
181
182/* Dump a region of memory */
183void
184debug_dump_bytes(const byte *from, const byte *to, const char *msg)
185{ const byte *p = from;
186 if ( from < to && msg )
187 dprintf1("%s:\n", msg);
188 while ( p != to )
189 { const byte *q = min(p + 16, to);
190 dprintf1("%lx:", (ulong)p);
191 while ( p != q ) dprintf1(" %02x", *p++);
192 dputc('\n');
193 }
194}
195
196/* Dump an array. */
197void
198debug_dump_array(const ref *array)
199{ const ref_packed *pp;
200 unsigned int type = r_type(array);
201 uint len;
202
203 switch (type)
204 {
205 default:
206 dprintf2 ("%s at 0x%lx isn't an array.\n",
207 (type < countof(type_strings) ?
208 type_strings[type] : "????"),
209 (ulong)array);
210 return;
211 case t_oparray:
212 /* This isn't really an array, but we'd like to see */
213 /* its contents anyway. */
214 debug_dump_array(op_array_table.value.refs + op_index(array) -
215 op_def_count);
216 return;
217 case t_array:
218 case t_mixedarray:
219 case t_shortarray:
220 ;
221 }
222
223 /* This "packed" loop works for all array-types. */
224 for ( len = r_size (array), pp = array->value.packed;
225 len > 0;
226 len--, pp = packed_next(pp))
227 { ref temp;
228 packed_get(pp, &temp);
229 dprintf3("..%04x%c 0x%02x ",
230 (uint)pp & 0xffff,
231 ((r_is_packed(pp)) ? '*' : ':'),
232 r_type(&temp));
233 debug_dump_one_ref(&temp);
234 dputc ('\n');
235 }
236}