Changeset 6be4142 in mainline for uspace/app/bithenge
- Timestamp:
- 2012-08-12T04:53:47Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1b6b76d
- Parents:
- 0153c87
- Location:
- uspace/app/bithenge
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bithenge/expression.c
r0153c87 r6be4142 464 464 rc = bithenge_node_get(node, self->key, out); 465 465 bithenge_node_dec_ref(node); 466 if (rc == ENOENT) 467 return bithenge_scope_error(scope, "No member %t", self->key); 466 468 return rc; 467 469 } … … 549 551 return rc; 550 552 } 551 return ENOENT;553 return bithenge_scope_error(scope, "No scope member %t", self->key); 552 554 } 553 555 -
uspace/app/bithenge/print.c
r0153c87 r6be4142 38 38 39 39 #include <errno.h> 40 #include <stdarg.h> 40 41 #include <stdio.h> 41 42 #include "blob.h" … … 47 48 bool first; 48 49 int depth; 50 char *buffer; 51 size_t buffer_size; 49 52 } state_t; 50 53 54 static void state_printf(state_t *state, const char *format, ...) 55 { 56 va_list ap; 57 va_start(ap, format); 58 if (state->buffer) { 59 int rc = vsnprintf(state->buffer, state->buffer_size, format, 60 ap); 61 if (rc > 0 && (size_t)rc >= state->buffer_size) 62 rc = state->buffer_size - 1; 63 if (rc > 0) { 64 state->buffer += rc; 65 state->buffer_size -= rc; 66 } 67 } else { 68 vprintf(format, ap); 69 } 70 va_end(ap); 71 } 72 51 73 static int print_node(state_t *, bithenge_node_t *); 52 74 53 75 static void newline(state_t *state) 54 76 { 55 printf("\n");77 state_printf(state, "\n"); 56 78 for (int i = 0; i < state->depth; i++) { 57 printf(" ");79 state_printf(state, " "); 58 80 } 59 81 } … … 74 96 int rc = EOK; 75 97 if (!state->first) 76 printf(",");98 state_printf(state, ","); 77 99 newline(state); 78 100 state->first = false; … … 80 102 && bithenge_node_type(key) != BITHENGE_NODE_STRING; 81 103 if (add_quotes) 82 printf("\"");104 state_printf(state, "\""); 83 105 rc = print_node(state, key); 84 106 if (rc != EOK) 85 107 goto end; 86 108 if (add_quotes) 87 printf("\"");88 printf(": ");109 state_printf(state, "\""); 110 state_printf(state, ": "); 89 111 rc = print_node(state, value); 90 112 if (rc != EOK) … … 99 121 { 100 122 int rc; 101 printf("{");123 state_printf(state, "{"); 102 124 increase_depth(state); 103 125 state->first = true; … … 109 131 newline(state); 110 132 state->first = false; 111 printf("}");133 state_printf(state, "}"); 112 134 return EOK; 113 135 } … … 118 140 switch (state->type) { 119 141 case BITHENGE_PRINT_PYTHON: 120 printf(value ? "True" : "False");142 state_printf(state, value ? "True" : "False"); 121 143 break; 122 144 case BITHENGE_PRINT_JSON: 123 printf(value ? "true" : "false");145 state_printf(state, value ? "true" : "false"); 124 146 break; 125 147 } … … 130 152 { 131 153 bithenge_int_t value = bithenge_integer_node_value(node); 132 printf("%" BITHENGE_PRId, value);154 state_printf(state, "%" BITHENGE_PRId, value); 133 155 return EOK; 134 156 } … … 137 159 { 138 160 const char *value = bithenge_string_node_value(node); 139 printf("\"");161 state_printf(state, "\""); 140 162 for (string_iterator_t i = string_iterator(value); !string_iterator_done(&i); ) { 141 163 wchar_t ch; … … 144 166 return rc; 145 167 if (ch == '"' || ch == '\\') { 146 printf("\\%lc", (wint_t) ch);168 state_printf(state, "\\%lc", (wint_t) ch); 147 169 } else if (ch <= 0x1f) { 148 printf("\\u%04x", (unsigned int) ch);170 state_printf(state, "\\u%04x", (unsigned int) ch); 149 171 } else { 150 printf("%lc", (wint_t) ch);172 state_printf(state, "%lc", (wint_t) ch); 151 173 } 152 174 } 153 printf("\"");175 state_printf(state, "\""); 154 176 return EOK; 155 177 } … … 162 184 aoff64_t size = sizeof(buffer); 163 185 int rc; 164 printf(state->type == BITHENGE_PRINT_PYTHON ? "b\"" : "\""); 186 state_printf(state, 187 state->type == BITHENGE_PRINT_PYTHON ? "b\"" : "\""); 165 188 do { 166 189 rc = bithenge_blob_read(blob, pos, buffer, &size); … … 168 191 return rc; 169 192 for (aoff64_t i = 0; i < size; i++) 170 printf("\\x%02x", (unsigned int)(uint8_t)buffer[i]); 193 state_printf(state, "\\x%02x", 194 (unsigned int)(uint8_t)buffer[i]); 171 195 pos += size; 172 196 } while (size == sizeof(buffer)); 173 printf("\"");197 state_printf(state, "\""); 174 198 return EOK; 175 199 } … … 192 216 } 193 217 194 /** Print a tree as text .218 /** Print a tree as text to stdout. 195 219 * @param type The format to use. 196 220 * @param tree The root node of the tree to print. … … 198 222 int bithenge_print_node(bithenge_print_type_t type, bithenge_node_t *tree) 199 223 { 200 state_t state = {type, true, 0 };224 state_t state = {type, true, 0, NULL, 0}; 201 225 return print_node(&state, tree); 202 226 } 203 227 228 /** Print a tree as text into a buffer. 229 * @param[in,out] str Holds a pointer to the buffer; changed to point to the 230 * null character. 231 * @param[in,out] size Holds the size of the buffer; changed to hold the 232 * remaining size. 233 * @param type The format to use. 234 * @param tree The root node of the tree to print. 235 * @return EOK on success or an error code from errno.h. */ 236 int bithenge_print_node_to_string(char **str, size_t *size, 237 bithenge_print_type_t type, bithenge_node_t *tree) 238 { 239 state_t state = {type, true, 0, *str, *size}; 240 int rc = print_node(&state, tree); 241 *str = state.buffer; 242 *size = state.buffer_size; 243 return rc; 244 } 245 204 246 /** @} 205 247 */ -
uspace/app/bithenge/print.h
r0153c87 r6be4142 51 51 52 52 int bithenge_print_node(bithenge_print_type_t, bithenge_node_t *); 53 int bithenge_print_node_to_string(char **, size_t *, bithenge_print_type_t, 54 bithenge_node_t *); 53 55 54 56 #endif -
uspace/app/bithenge/sequence.c
r0153c87 r6be4142 418 418 struct_node_t *node = node_as_struct(base); 419 419 420 /* We didn't inc_ref for the scope in struct_transform_make_node, so 421 * make sure it doesn't try to dec_ref. */ 422 seq_node_scope(struct_as_seq(node))->current_node = NULL; 423 seq_node_destroy(struct_as_seq(node)); 420 /* Treat the scope carefully because of the circular reference. In 421 * struct_transform_make_node, things are set up so node owns a 422 * reference to the scope, but scope doesn't own a reference to node, 423 * so node's reference count is too low. */ 424 bithenge_scope_t *scope = seq_node_scope(struct_as_seq(node)); 425 if (scope->refs == 1) { 426 /* Mostly normal destroy, but we didn't inc_ref(node) for the 427 * scope in struct_transform_make_node, so make sure it doesn't 428 * try to dec_ref. */ 429 scope->current_node = NULL; 430 seq_node_destroy(struct_as_seq(node)); 431 } else if (scope->refs > 1) { 432 /* The scope is still needed, but node isn't otherwise needed. 433 * Switch things around so scope owns a reference to node, but 434 * not vice versa, and scope's reference count is too low. */ 435 bithenge_node_inc_ref(base); 436 bithenge_scope_dec_ref(scope); 437 return; 438 } else { 439 /* This happens after the previous case, when scope is no 440 * longer used and is being destroyed. Since scope is already 441 * being destroyed, set it to NULL here so we don't try to 442 * destroy it twice. */ 443 struct_as_seq(node)->scope = NULL; 444 seq_node_destroy(struct_as_seq(node)); 445 } 424 446 425 447 bithenge_transform_dec_ref(struct_as_transform(node->transform)); -
uspace/app/bithenge/test.c
r0153c87 r6be4142 50 50 int rc; 51 51 if (argc < 3) { 52 // {True: {}, -1351: "\"false\"", "true": False, 0: b"..."} 53 const char data[] = "'Twas brillig, and the slithy toves"; 54 bithenge_node_t *node; 55 bithenge_node_t *subnodes[8]; 56 bithenge_new_boolean_node(&subnodes[0], true); 57 bithenge_new_simple_internal_node(&subnodes[1], NULL, 0, false); 58 bithenge_new_integer_node(&subnodes[2], -1351); 59 bithenge_new_string_node(&subnodes[3], "\"false\"", false); 60 bithenge_new_string_node(&subnodes[4], "true", false); 61 bithenge_new_boolean_node(&subnodes[5], false); 62 bithenge_new_integer_node(&subnodes[6], 0); 63 bithenge_new_blob_from_data(&subnodes[7], data, sizeof(data)); 64 bithenge_new_simple_internal_node(&node, subnodes, 4, false); 65 bithenge_print_node(BITHENGE_PRINT_PYTHON, node); 66 printf("\n"); 67 bithenge_print_node(BITHENGE_PRINT_JSON, node); 68 printf("\n"); 69 bithenge_node_dec_ref(node); 52 fprintf(stderr, "Usage: %s <script> <source>\n", argv[0]); 53 return 1; 70 54 } else { 71 55 bithenge_scope_t *scope = NULL; … … 96 80 rc = bithenge_transform_apply(transform, scope, node, &node2); 97 81 if (rc != EOK) { 98 printf("Error applying transform: %s\n", str_error(rc)); 82 const char *message = bithenge_scope_get_error(scope); 83 printf("Error applying transform: %s\n", 84 message ? message : str_error(rc)); 99 85 node2 = NULL; 100 86 goto error; … … 108 94 rc = bithenge_print_node(BITHENGE_PRINT_PYTHON, node2); 109 95 if (rc != EOK) { 110 printf("Error printing node: %s\n", str_error(rc)); 96 const char *message = bithenge_scope_get_error(scope); 97 printf("Error printing node: %s\n", 98 message ? message : str_error(rc)); 111 99 goto error; 112 100 } -
uspace/app/bithenge/transform.c
r0153c87 r6be4142 37 37 #include <assert.h> 38 38 #include <errno.h> 39 #include <stdarg.h> 39 40 #include <stdlib.h> 40 41 #include "blob.h" 42 #include "print.h" 41 43 #include "transform.h" 42 44 … … 187 189 bithenge_scope_inc_ref(outer); 188 190 self->outer = outer; 191 self->error = NULL; 189 192 self->barrier = false; 190 193 self->num_params = 0; … … 209 212 bithenge_scope_dec_ref(self->outer); 210 213 free(self->params); 214 free(self->error); 211 215 free(self); 212 216 } … … 218 222 { 219 223 return self->outer; 224 } 225 226 /** Get the error message stored in the scope, which may be NULL. The error 227 * message only exists as long as the scope does. 228 * @param scope The scope to get the error message from. 229 * @return The error message, or NULL. */ 230 const char *bithenge_scope_get_error(bithenge_scope_t *scope) 231 { 232 return scope->error; 233 } 234 235 /** Set the error message for the scope. The error message is stored in the 236 * outermost scope, but if any scope already has an error message this error 237 * message is ignored. 238 * @param scope The scope. 239 * @param format The format string. 240 * @return EINVAL normally, or another error code from errno.h. */ 241 int bithenge_scope_error(bithenge_scope_t *scope, const char *format, ...) 242 { 243 if (scope->error) 244 return EINVAL; 245 while (scope->outer) { 246 scope = scope->outer; 247 if (scope->error) 248 return EINVAL; 249 } 250 size_t space_left = 256; 251 scope->error = malloc(space_left); 252 if (!scope->error) 253 return ENOMEM; 254 char *out = scope->error; 255 va_list ap; 256 va_start(ap, format); 257 258 while (*format) { 259 if (format[0] == '%' && format[1] == 't') { 260 format += 2; 261 int rc = bithenge_print_node_to_string(&out, 262 &space_left, BITHENGE_PRINT_PYTHON, 263 va_arg(ap, bithenge_node_t *)); 264 if (rc != EOK) { 265 va_end(ap); 266 return rc; 267 } 268 } else { 269 const char *end = str_chr(format, '%'); 270 if (!end) 271 end = format + str_length(format); 272 size_t size = min((size_t)(end - format), 273 space_left - 1); 274 memcpy(out, format, size); 275 format = end; 276 out += size; 277 space_left -= size; 278 } 279 } 280 *out = '\0'; 281 282 va_end(ap); 283 return EINVAL; 220 284 } 221 285 -
uspace/app/bithenge/transform.h
r0153c87 r6be4142 54 54 unsigned int refs; 55 55 struct bithenge_scope *outer; 56 char *error; 56 57 bool barrier; 57 58 int num_params; … … 152 153 void bithenge_scope_dec_ref(bithenge_scope_t *); 153 154 bithenge_scope_t *bithenge_scope_outer(bithenge_scope_t *); 155 const char *bithenge_scope_get_error(bithenge_scope_t *); 156 int bithenge_scope_error(bithenge_scope_t *, const char *, ...); 154 157 bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *); 155 158 void bithenge_scope_set_current_node(bithenge_scope_t *, bithenge_node_t *);
Note:
See TracChangeset
for help on using the changeset viewer.