Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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, "<NULL>");
  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, "<unknown object>");
  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. }
  336.