source: mainline/uspace/app/bithenge/print.c@ 84e8a70

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 84e8a70 was 842ed146, checked in by Sean Bartell <wingedtachikoma@…>, 13 years ago

Bithenge: use indentation in tree output

  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[11b9ad7]1/*
2 * Copyright (c) 2012 Sean Bartell
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup bithenge
30 * @{
31 */
32/**
33 * @file
34 * Write a tree as JSON or other text formats.
[842ed146]35 * @todo Allow more control over the printing style, and handle printing in
36 * limited space.
[11b9ad7]37 */
38
39#include <errno.h>
40#include <stdio.h>
[5c925ce]41#include "blob.h"
[11b9ad7]42#include "print.h"
43#include "tree.h"
44
45typedef struct {
46 bithenge_print_type_t type;
47 bool first;
[842ed146]48 int depth;
49} state_t;
[11b9ad7]50
[842ed146]51static int print_node(state_t *, bithenge_node_t *);
52
53static void newline(state_t *state)
54{
55 printf("\n");
56 for (int i = 0; i < state->depth; i++) {
57 printf(" ");
58 }
59}
60
61static void increase_depth(state_t *state)
62{
63 state->depth++;
64}
65
66static void decrease_depth(state_t *state)
67{
68 state->depth--;
69}
70
71static int print_internal_func(bithenge_node_t *key, bithenge_node_t *value, void *data)
[11b9ad7]72{
[842ed146]73 state_t *state = (state_t *)data;
[04a7435f]74 int rc = EOK;
[842ed146]75 if (!state->first)
76 printf(",");
77 newline(state);
78 state->first = false;
79 bool add_quotes = state->type == BITHENGE_PRINT_JSON
[11b9ad7]80 && bithenge_node_type(key) != BITHENGE_NODE_STRING;
81 if (add_quotes)
82 printf("\"");
[842ed146]83 rc = print_node(state, key);
[11b9ad7]84 if (rc != EOK)
[04a7435f]85 goto end;
[11b9ad7]86 if (add_quotes)
87 printf("\"");
88 printf(": ");
[842ed146]89 rc = print_node(state, value);
[11b9ad7]90 if (rc != EOK)
[04a7435f]91 goto end;
92end:
93 bithenge_node_dec_ref(key);
94 bithenge_node_dec_ref(value);
95 return rc;
[11b9ad7]96}
97
[842ed146]98static int print_internal(state_t *state, bithenge_node_t *node)
[11b9ad7]99{
100 int rc;
101 printf("{");
[842ed146]102 increase_depth(state);
103 state->first = true;
104 rc = bithenge_node_for_each(node, print_internal_func, state);
[11b9ad7]105 if (rc != EOK)
106 return rc;
[842ed146]107 decrease_depth(state);
108 if (!state->first)
109 newline(state);
110 state->first = false;
[11b9ad7]111 printf("}");
112 return EOK;
113}
114
[842ed146]115static int print_boolean(state_t *state, bithenge_node_t *node)
[11b9ad7]116{
117 bool value = bithenge_boolean_node_value(node);
[842ed146]118 switch (state->type) {
[11b9ad7]119 case BITHENGE_PRINT_PYTHON:
120 printf(value ? "True" : "False");
121 break;
122 case BITHENGE_PRINT_JSON:
123 printf(value ? "true" : "false");
124 break;
125 }
126 return EOK;
127}
128
[842ed146]129static int print_integer(state_t *state, bithenge_node_t *node)
[11b9ad7]130{
131 bithenge_int_t value = bithenge_integer_node_value(node);
132 printf("%" BITHENGE_PRId, value);
133 return EOK;
134}
135
[842ed146]136static int print_string(state_t *state, bithenge_node_t *node)
[11b9ad7]137{
138 const char *value = bithenge_string_node_value(node);
139 printf("\"");
[da0fef6]140 for (string_iterator_t i = string_iterator(value); !string_iterator_done(&i); ) {
141 wchar_t ch;
142 int rc = string_iterator_next(&i, &ch);
143 if (rc != EOK)
144 return rc;
[11b9ad7]145 if (ch == '"' || ch == '\\') {
146 printf("\\%lc", (wint_t) ch);
147 } else if (ch <= 0x1f) {
148 printf("\\u%04x", (unsigned int) ch);
149 } else {
150 printf("%lc", (wint_t) ch);
151 }
152 }
153 printf("\"");
154 return EOK;
155}
156
[842ed146]157static int print_blob(state_t *state, bithenge_node_t *node)
[5c925ce]158{
159 bithenge_blob_t *blob = bithenge_node_as_blob(node);
160 aoff64_t pos = 0;
161 char buffer[1024];
162 aoff64_t size = sizeof(buffer);
163 int rc;
[842ed146]164 printf(state->type == BITHENGE_PRINT_PYTHON ? "b\"" : "\"");
[5c925ce]165 do {
166 rc = bithenge_blob_read(blob, pos, buffer, &size);
167 if (rc != EOK)
168 return rc;
169 for (aoff64_t i = 0; i < size; i++)
[da0fef6]170 printf("\\x%02x", (unsigned int)(uint8_t)buffer[i]);
[5c925ce]171 pos += size;
172 } while (size == sizeof(buffer));
173 printf("\"");
174 return EOK;
175}
176
[842ed146]177static int print_node(state_t *state, bithenge_node_t *tree)
[11b9ad7]178{
179 switch (bithenge_node_type(tree)) {
180 case BITHENGE_NODE_INTERNAL:
[842ed146]181 return print_internal(state, tree);
[11b9ad7]182 case BITHENGE_NODE_BOOLEAN:
[842ed146]183 return print_boolean(state, tree);
[11b9ad7]184 case BITHENGE_NODE_INTEGER:
[842ed146]185 return print_integer(state, tree);
[11b9ad7]186 case BITHENGE_NODE_STRING:
[842ed146]187 return print_string(state, tree);
[5c925ce]188 case BITHENGE_NODE_BLOB:
[842ed146]189 return print_blob(state, tree);
[11b9ad7]190 }
191 return ENOTSUP;
192}
[8375d0eb]193
[842ed146]194/** Print a tree as text.
195 * @param type The format to use.
196 * @param tree The root node of the tree to print.
197 * @return EOK on success or an error code from errno.h. */
198int bithenge_print_node(bithenge_print_type_t type, bithenge_node_t *tree)
199{
200 state_t state = {type, true, 0};
201 return print_node(&state, tree);
202}
203
[8375d0eb]204/** @}
205 */
Note: See TracBrowser for help on using the repository browser.