Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
#include "fitz.h"
2
 
3
struct fmt
4
{
5
	char *buf;
6
	int cap;
7
	int len;
8
	int indent;
9
	int tight;
10
	int col;
11
	int sep;
12
	int last;
13
};
14
 
15
static void fmt_obj(struct fmt *fmt, fz_obj *obj);
16
 
17
static inline int iswhite(int ch)
18
{
19
	return
20
		ch == '\000' ||
21
		ch == '\011' ||
22
		ch == '\012' ||
23
		ch == '\014' ||
24
		ch == '\015' ||
25
		ch == '\040';
26
}
27
 
28
static inline int isdelim(int ch)
29
{
30
	return	ch == '(' || ch == ')' ||
31
		ch == '<' || ch == '>' ||
32
		ch == '[' || ch == ']' ||
33
		ch == '{' || ch == '}' ||
34
		ch == '/' ||
35
		ch == '%';
36
}
37
 
38
static inline void fmt_putc(struct fmt *fmt, int c)
39
{
40
	if (fmt->sep && !isdelim(fmt->last) && !isdelim(c)) {
41
		fmt->sep = 0;
42
		fmt_putc(fmt, ' ');
43
	}
44
	fmt->sep = 0;
45
 
46
	if (fmt->buf && fmt->len < fmt->cap)
47
		fmt->buf[fmt->len] = c;
48
 
49
	if (c == '\n')
50
		fmt->col = 0;
51
	else
52
		fmt->col ++;
53
 
54
	fmt->len ++;
55
 
56
	fmt->last = c;
57
}
58
 
59
static inline void fmt_indent(struct fmt *fmt)
60
{
61
	int i = fmt->indent;
62
	while (i--) {
63
		fmt_putc(fmt, ' ');
64
		fmt_putc(fmt, ' ');
65
	}
66
}
67
 
68
static inline void fmt_puts(struct fmt *fmt, char *s)
69
{
70
	while (*s)
71
		fmt_putc(fmt, *s++);
72
}
73
 
74
static inline void fmt_sep(struct fmt *fmt)
75
{
76
	fmt->sep = 1;
77
}
78
 
79
static void fmt_str(struct fmt *fmt, fz_obj *obj)
80
{
81
	char *s = fz_to_str_buf(obj);
82
	int n = fz_to_str_len(obj);
83
	int i, c;
84
 
85
	fmt_putc(fmt, '(');
86
	for (i = 0; i < n; i++)
87
	{
88
		c = (unsigned char)s[i];
89
		if (c == '\n')
90
			fmt_puts(fmt, "\\n");
91
		else if (c == '\r')
92
			fmt_puts(fmt, "\\r");
93
		else if (c == '\t')
94
			fmt_puts(fmt, "\\t");
95
		else if (c == '\b')
96
			fmt_puts(fmt, "\\b");
97
		else if (c == '\f')
98
			fmt_puts(fmt, "\\f");
99
		else if (c == '(')
100
			fmt_puts(fmt, "\\(");
101
		else if (c == ')')
102
			fmt_puts(fmt, "\\)");
103
		else if (c < 32 || c >= 127) {
104
			char buf[16];
105
			fmt_putc(fmt, '\\');
106
			sprintf(buf, "%03o", c);
107
			fmt_puts(fmt, buf);
108
		}
109
		else
110
			fmt_putc(fmt, c);
111
	}
112
	fmt_putc(fmt, ')');
113
}
114
 
115
static void fmt_hex(struct fmt *fmt, fz_obj *obj)
116
{
117
	char *s = fz_to_str_buf(obj);
118
	int n = fz_to_str_len(obj);
119
	int i, b, c;
120
 
121
	fmt_putc(fmt, '<');
122
	for (i = 0; i < n; i++) {
123
		b = (unsigned char) s[i];
124
		c = (b >> 4) & 0x0f;
125
		fmt_putc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA);
126
		c = (b) & 0x0f;
127
		fmt_putc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA);
128
	}
129
	fmt_putc(fmt, '>');
130
}
131
 
132
static void fmt_name(struct fmt *fmt, fz_obj *obj)
133
{
134
	unsigned char *s = (unsigned char *) fz_to_name(obj);
135
	int i, c;
136
 
137
	fmt_putc(fmt, '/');
138
 
139
	for (i = 0; s[i]; i++)
140
	{
141
		if (isdelim(s[i]) || iswhite(s[i]) ||
142
			s[i] == '#' || s[i] < 32 || s[i] >= 127)
143
		{
144
			fmt_putc(fmt, '#');
145
			c = (s[i] >> 4) & 0xf;
146
			fmt_putc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA);
147
			c = s[i] & 0xf;
148
			fmt_putc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA);
149
		}
150
		else
151
		{
152
			fmt_putc(fmt, s[i]);
153
		}
154
	}
155
}
156
 
157
static void fmt_array(struct fmt *fmt, fz_obj *obj)
158
{
159
	int i;
160
 
161
	if (fmt->tight) {
162
		fmt_putc(fmt, '[');
163
		for (i = 0; i < fz_array_len(obj); i++) {
164
			fmt_obj(fmt, fz_array_get(obj, i));
165
			fmt_sep(fmt);
166
		}
167
		fmt_putc(fmt, ']');
168
	}
169
	else {
170
		fmt_puts(fmt, "[ ");
171
		for (i = 0; i < fz_array_len(obj); i++) {
172
			if (fmt->col > 60) {
173
				fmt_putc(fmt, '\n');
174
				fmt_indent(fmt);
175
			}
176
			fmt_obj(fmt, fz_array_get(obj, i));
177
			fmt_putc(fmt, ' ');
178
		}
179
		fmt_putc(fmt, ']');
180
		fmt_sep(fmt);
181
	}
182
}
183
 
184
static void fmt_dict(struct fmt *fmt, fz_obj *obj)
185
{
186
	int i;
187
	fz_obj *key, *val;
188
 
189
	if (fmt->tight) {
190
		fmt_puts(fmt, "<<");
191
		for (i = 0; i < fz_dict_len(obj); i++) {
192
			fmt_obj(fmt, fz_dict_get_key(obj, i));
193
			fmt_sep(fmt);
194
			fmt_obj(fmt, fz_dict_get_val(obj, i));
195
			fmt_sep(fmt);
196
		}
197
		fmt_puts(fmt, ">>");
198
	}
199
	else {
200
		fmt_puts(fmt, "<<\n");
201
		fmt->indent ++;
202
		for (i = 0; i < fz_dict_len(obj); i++) {
203
			key = fz_dict_get_key(obj, i);
204
			val = fz_dict_get_val(obj, i);
205
			fmt_indent(fmt);
206
			fmt_obj(fmt, key);
207
			fmt_putc(fmt, ' ');
208
			if (!fz_is_indirect(val) && fz_is_array(val))
209
				fmt->indent ++;
210
			fmt_obj(fmt, val);
211
			fmt_putc(fmt, '\n');
212
			if (!fz_is_indirect(val) && fz_is_array(val))
213
				fmt->indent --;
214
		}
215
		fmt->indent --;
216
		fmt_indent(fmt);
217
		fmt_puts(fmt, ">>");
218
	}
219
}
220
 
221
static void fmt_obj(struct fmt *fmt, fz_obj *obj)
222
{
223
	char buf[256];
224
 
225
	if (!obj)
226
		fmt_puts(fmt, "");
227
	else if (fz_is_indirect(obj))
228
	{
229
		sprintf(buf, "%d %d R", fz_to_num(obj), fz_to_gen(obj));
230
		fmt_puts(fmt, buf);
231
	}
232
	else if (fz_is_null(obj))
233
		fmt_puts(fmt, "null");
234
	else if (fz_is_bool(obj))
235
		fmt_puts(fmt, fz_to_bool(obj) ? "true" : "false");
236
	else if (fz_is_int(obj))
237
	{
238
		sprintf(buf, "%d", fz_to_int(obj));
239
		fmt_puts(fmt, buf);
240
	}
241
	else if (fz_is_real(obj))
242
	{
243
		sprintf(buf, "%g", fz_to_real(obj));
244
		if (strchr(buf, 'e')) /* bad news! */
245
			sprintf(buf, fabsf(fz_to_real(obj)) > 1 ? "%1.1f" : "%1.8f", fz_to_real(obj));
246
		fmt_puts(fmt, buf);
247
	}
248
	else if (fz_is_string(obj))
249
	{
250
		char *str = fz_to_str_buf(obj);
251
		int len = fz_to_str_len(obj);
252
		int added = 0;
253
		int i, c;
254
		for (i = 0; i < len; i++) {
255
			c = (unsigned char)str[i];
256
			if (strchr("()\\\n\r\t\b\f", c))
257
				added ++;
258
			else if (c < 32 || c >= 127)
259
				added += 3;
260
		}
261
		if (added < len)
262
			fmt_str(fmt, obj);
263
		else
264
			fmt_hex(fmt, obj);
265
	}
266
	else if (fz_is_name(obj))
267
		fmt_name(fmt, obj);
268
	else if (fz_is_array(obj))
269
		fmt_array(fmt, obj);
270
	else if (fz_is_dict(obj))
271
		fmt_dict(fmt, obj);
272
	else
273
		fmt_puts(fmt, "");
274
}
275
 
276
static int
277
fz_sprint_obj(char *s, int n, fz_obj *obj, int tight)
278
{
279
	struct fmt fmt;
280
 
281
	fmt.indent = 0;
282
	fmt.col = 0;
283
	fmt.sep = 0;
284
	fmt.last = 0;
285
 
286
	fmt.tight = tight;
287
	fmt.buf = s;
288
	fmt.cap = n;
289
	fmt.len = 0;
290
	fmt_obj(&fmt, obj);
291
 
292
	if (fmt.buf && fmt.len < fmt.cap)
293
		fmt.buf[fmt.len] = '\0';
294
 
295
	return fmt.len;
296
}
297
 
298
int
299
fz_fprint_obj(FILE *fp, fz_obj *obj, int tight)
300
{
301
	char buf[1024];
302
	char *ptr;
303
	int n;
304
 
305
	n = fz_sprint_obj(NULL, 0, obj, tight);
306
	if ((n + 1) < sizeof buf)
307
	{
308
		fz_sprint_obj(buf, sizeof buf, obj, tight);
309
		fputs(buf, fp);
310
		fputc('\n', fp);
311
	}
312
	else
313
	{
314
		ptr = fz_malloc(n + 1);
315
		fz_sprint_obj(ptr, n + 1, obj, tight);
316
		fputs(ptr, fp);
317
		fputc('\n', fp);
318
		fz_free(ptr);
319
	}
320
	return n;
321
}
322
 
323
void
324
fz_debug_obj(fz_obj *obj)
325
{
326
	fz_fprint_obj(stdout, obj, 0);
327
}
328
 
329
void
330
fz_debug_ref(fz_obj *ref)
331
{
332
	fz_obj *obj;
333
	obj = fz_resolve_indirect(ref);
334
	fz_debug_obj(obj);
335
}