Changeset 6be4142 in mainline
- 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
- Files:
-
- 8 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 *); -
uspace/dist/src/bithenge/fat.bh
r0153c87 r6be4142 27 27 # FAT filesystem script. 28 28 # Largely based on https://en.wikipedia.org/wiki/File_Allocation_Table 29 # Currently only FAT12 and FAT16 are supported. 29 30 30 31 transform u8 = uint8; … … 32 33 transform u32 = uint32le; 33 34 35 transform fat_attributes = struct { 36 .read_only <- bit; 37 .hidden <- bit; 38 .system <- bit; 39 .volume_label <- bit; 40 .subdirectory <- bit; 41 .archive <- bit; 42 .device <- bit; 43 .reserved <- bit; 44 } <- bits_le <- known_length(1); 45 34 46 transform fat_dir_entry(disk) = struct { 35 47 .filename <- known_length(8); 36 48 .extension <- known_length(3); 37 .attrs <- u8;49 .attrs <- fat_attributes; 38 50 .flags <- u8; 39 51 .ctime_fine <- u8; … … 79 91 }; 80 92 81 .num_sectors <- if (.bpb331.ignore) { 82 (.num_sectors_16) 83 } else { 84 (.bpb331.num_sectors_32) 85 }; 86 87 .first_root_sector <- (.num_reserved_sectors + .num_fats * .sectors_per_fat); 88 .first_data_sector <- (.first_root_sector + 89 (.num_root_entries * 32 + .bytes_per_sector - 1) // 90 .bytes_per_sector); 91 .num_clusters <- (2 + (.num_sectors - .first_data_sector) // .sectors_per_cluster); 92 .bits <- if (.num_clusters < 4085) { (12) } 93 else { if (.num_clusters < 65525) { (16) } else { (32) } }; 94 95 .fats <- partial(.num_reserved_sectors * .bytes_per_sector) { 96 repeat(.num_fats) { 97 fat_table(.bits, .num_clusters) <- 98 known_length(.sectors_per_fat * .bytes_per_sector) 99 } 100 } <- (disk); 101 102 .root <- partial(.first_root_sector * .bytes_per_sector) { 103 repeat(.num_root_entries) { fat_dir_entry(disk) } } <- (disk); 93 .drive_number <- u8; 94 .chkdsk_flags <- u8; 95 .extended_boot_signature <- u8; 96 if (.extended_boot_signature == 41) { 97 .volume_id <- u32; 98 .volume_label <- ascii <- known_length(11); 99 .type <- ascii <- known_length(8); 100 } 104 101 105 102 .boot_signature <- (disk[510,2]); # b"\x55\xaa"; TODO: what if .bytes_per_sector < 512? 106 103 }; 107 104 108 transform fat_filesystem = partial { fat_super(in) }; 105 transform fat_filesystem_tree(disk) = struct { 106 .super <- partial{fat_super(disk)} <- (disk); 107 108 .num_sectors <- if (.super.bpb331.ignore) { 109 (.super.num_sectors_16) 110 } else { 111 (.super.bpb331.num_sectors_32) 112 }; 113 114 .first_root_sector <- (.super.num_reserved_sectors + .super.num_fats * .super.sectors_per_fat); 115 .first_data_sector <- (.first_root_sector + 116 (.super.num_root_entries * 32 + .super.bytes_per_sector - 1) // 117 .super.bytes_per_sector); 118 .num_clusters <- (2 + (.num_sectors - .first_data_sector) // .super.sectors_per_cluster); 119 .bits <- if (.num_clusters < 4085) { (12) } 120 else { if (.num_clusters < 65525) { (16) } else { (32) } }; 121 122 .fats <- partial(.super.num_reserved_sectors * .super.bytes_per_sector) { 123 repeat(.super.num_fats) { 124 fat_table(.bits, .num_clusters) <- 125 known_length(.super.sectors_per_fat * .super.bytes_per_sector) 126 } 127 } <- (disk); 128 129 .root <- partial(.first_root_sector * .super.bytes_per_sector) { 130 repeat(.super.num_root_entries) { fat_dir_entry(disk) } } <- (disk); 131 }; 132 133 transform fat_filesystem = partial {fat_filesystem_tree(in)}; 109 134 110 135 transform main = fat_filesystem;
Note:
See TracChangeset
for help on using the changeset viewer.