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 | }>>>>>>\n"); |