Changeset 4056ad0 in mainline
- Timestamp:
- 2012-07-28T01:57:31Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 32eb01b
- Parents:
- 03cad47
- Location:
- uspace/app/bithenge
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bithenge/expression.c
r03cad47 r4056ad0 231 231 232 232 error: 233 bithenge_node_dec_ref(in);234 233 bithenge_scope_destroy(&inner); 235 234 return rc; 236 235 } 237 238 236 239 237 static int param_wrapper_prefix_length(bithenge_transform_t *base, … … 252 250 253 251 error: 254 bithenge_blob_dec_ref(in);255 252 bithenge_scope_destroy(&inner); 256 253 return rc; 257 254 } 255 258 256 static void param_wrapper_destroy(bithenge_transform_t *base) 259 257 { -
uspace/app/bithenge/helenos/os.h
r03cad47 r4056ad0 33 33 #include <byteorder.h> 34 34 #include <errno.h> 35 #include <inttypes.h> 35 36 #include <macros.h> 36 37 #include <mem.h> … … 38 39 #include <str.h> 39 40 #include <str_error.h> 41 42 typedef int64_t bithenge_int_t; 43 #define BITHENGE_PRId PRId64 40 44 41 45 typedef struct { … … 76 80 } 77 81 82 static inline int bithenge_parse_int(const char *start, bithenge_int_t *result) 83 { 84 return str_uint64_t(start, NULL, 10, false, result); 85 } 86 78 87 #endif -
uspace/app/bithenge/linux/os.h
r03cad47 r4056ad0 32 32 #include <endian.h> 33 33 #include <errno.h> 34 #include <inttypes.h> 34 35 #include <memory.h> 35 36 #include <stdbool.h> 36 #include <std int.h>37 #include <stdlib.h> 37 38 #include <string.h> 38 39 #include <wchar.h> … … 44 45 #define ELIMIT EINVAL 45 46 47 typedef intmax_t bithenge_int_t; 48 #define BITHENGE_PRId PRIdMAX 46 49 typedef uint64_t aoff64_t; 47 48 50 typedef const char *string_iterator_t; 49 51 … … 130 132 } 131 133 134 static inline int bithenge_parse_int(const char *start, bithenge_int_t *result) 135 { 136 errno = 0; 137 *result = strtoll(start, NULL, 10); 138 return errno; 139 } 140 132 141 #endif -
uspace/app/bithenge/script.c
r03cad47 r4056ad0 38 38 #include <stdio.h> 39 39 #include <stdlib.h> 40 #include "expression.h" 40 41 #include "os.h" 41 42 #include "script.h" … … 53 54 TOKEN_EOF, 54 55 TOKEN_IDENTIFIER, 56 TOKEN_INTEGER, 55 57 TOKEN_LEFT_ARROW, 56 58 … … 95 97 * NULL, it will be freed when the next token is read. */ 96 98 char *token_string; 99 /** The value of a TOKEN_INTEGER token. */ 100 bithenge_int_t token_int; 97 101 }; 98 102 } state_t; … … 202 206 state->token_string = value; 203 207 } 208 } else if (isdigit(ch)) { 209 while (isdigit(state->buffer[state->buffer_pos])) 210 state->buffer_pos++; 211 state->token = TOKEN_INTEGER; 212 int rc = bithenge_parse_int(state->buffer + 213 state->old_buffer_pos, &state->token_int); 214 if (rc != EOK) 215 error_errno(state, rc); 204 216 } else if (ch == '<') { 205 217 state->token = ch; … … 307 319 308 320 static bithenge_transform_t *parse_transform(state_t *state); 321 322 static bithenge_expression_t *parse_expression(state_t *state) 323 { 324 if (state->token == TOKEN_INTEGER) { 325 bithenge_int_t val = state->token_int; 326 next_token(state); 327 bithenge_node_t *node; 328 int rc = bithenge_new_integer_node(&node, val); 329 if (rc != EOK) { 330 error_errno(state, rc); 331 return NULL; 332 } 333 334 bithenge_expression_t *expr; 335 rc = bithenge_const_expression(&expr, node); 336 if (rc != EOK) { 337 error_errno(state, rc); 338 return NULL; 339 } 340 341 return expr; 342 } else { 343 syntax_error(state, "expression expected"); 344 return NULL; 345 } 346 } 347 348 // state->token must be TOKEN_IDENTIFIER when this is called 349 static bithenge_transform_t *parse_invocation(state_t *state) 350 { 351 bithenge_transform_t *result = get_named_transform(state, 352 state->token_string); 353 if (!result) 354 syntax_error(state, "transform not found"); 355 next_token(state); 356 357 bithenge_expression_t **params = NULL; 358 int num_params = 0; 359 if (state->token == '(') { 360 next_token(state); 361 while (state->error == EOK && state->token != ')') { 362 if (num_params) 363 expect(state, ','); 364 params = state_realloc(state, params, 365 (num_params + 1)*sizeof(*params)); 366 if (state->error != EOK) 367 break; 368 params[num_params] = parse_expression(state); 369 num_params++; 370 } 371 expect(state, ')'); 372 } 373 374 /* TODO: show correct error position */ 375 if (state->error == EOK 376 && bithenge_transform_num_params(result) != num_params) 377 syntax_error(state, "incorrect number of parameters before"); 378 379 if (state->error != EOK) { 380 while (num_params--) 381 bithenge_expression_dec_ref(params[num_params]); 382 free(params); 383 bithenge_transform_dec_ref(result); 384 return NULL; 385 } 386 387 if (num_params) { 388 int rc = bithenge_param_wrapper(&result, result, params); 389 if (rc != EOK) { 390 error_errno(state, rc); 391 result = NULL; 392 } 393 } 394 395 return result; 396 } 309 397 310 398 static bithenge_transform_t *parse_struct(state_t *state) … … 358 446 { 359 447 if (state->token == TOKEN_IDENTIFIER) { 360 bithenge_transform_t *result = get_named_transform(state, 361 state->token_string); 362 if (!result) 363 syntax_error(state, "transform not found"); 364 next_token(state); 365 return result; 448 return parse_invocation(state); 366 449 } else if (state->token == TOKEN_STRUCT) { 367 450 return parse_struct(state); -
uspace/app/bithenge/transform.c
r03cad47 r4056ad0 47 47 * transform will get its own context with parameters, probably provided by a 48 48 * param_wrapper. If this is zero, the existing outer context will be used with 49 * whatever parameters it has. 49 * whatever parameters it has, so they can be passed to any param_wrappers 50 * within. 50 51 * @return EOK or an error code from errno.h. */ 51 52 int bithenge_init_transform(bithenge_transform_t *self, … … 64 65 { 65 66 assert(false); 67 } 68 69 typedef struct { 70 bithenge_transform_t base; 71 bithenge_transform_t *transform; 72 } param_transform_t; 73 74 static inline param_transform_t *transform_as_param( 75 bithenge_transform_t *base) 76 { 77 return (param_transform_t *)base; 78 } 79 80 static inline bithenge_transform_t *param_as_transform( 81 param_transform_t *self) 82 { 83 return &self->base; 84 } 85 86 static int param_transform_apply(bithenge_transform_t *base, 87 bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out) 88 { 89 param_transform_t *self = transform_as_param(base); 90 return bithenge_transform_apply(self->transform, scope, in, out); 91 } 92 93 static int param_transform_prefix_length(bithenge_transform_t *base, 94 bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out) 95 { 96 param_transform_t *self = transform_as_param(base); 97 return bithenge_transform_prefix_length(self->transform, scope, in, 98 out); 99 } 100 101 static void param_transform_destroy(bithenge_transform_t *base) 102 { 103 param_transform_t *self = transform_as_param(base); 104 bithenge_transform_dec_ref(self->transform); 105 free(self); 106 } 107 108 static const bithenge_transform_ops_t param_transform_ops = { 109 .apply = param_transform_apply, 110 .prefix_length = param_transform_prefix_length, 111 .destroy = param_transform_destroy, 112 }; 113 114 /** Create a wrapper transform with a different number of parameters. Takes a 115 * reference to @a transform, which it will use for all operations. 116 * @param[out] out Holds the created transform. 117 * @param transform The transform to wrap. 118 * @param num_params The number of parameters to require. 119 * @return EOK on success or an error code from errno.h. */ 120 int bithenge_new_param_transform(bithenge_transform_t **out, 121 bithenge_transform_t *transform, int num_params) 122 { 123 assert(transform); 124 assert(bithenge_transform_num_params(transform) == 0); 125 assert(num_params != 0); 126 127 int rc; 128 param_transform_t *self = malloc(sizeof(*self)); 129 if (!self) { 130 rc = ENOMEM; 131 goto error; 132 } 133 rc = bithenge_init_transform(param_as_transform(self), 134 ¶m_transform_ops, num_params); 135 if (rc != EOK) 136 goto error; 137 self->transform = transform; 138 *out = param_as_transform(self); 139 return EOK; 140 error: 141 bithenge_transform_dec_ref(transform); 142 free(self); 143 return rc; 66 144 } 67 145 … … 105 183 bithenge_transform_t bithenge_ascii_transform = { 106 184 &ascii_ops, 1, 0 185 }; 186 187 static int known_length_apply(bithenge_transform_t *self, 188 bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out) 189 { 190 bithenge_node_t *length_node; 191 int rc = bithenge_scope_get_param(scope, 0, &length_node); 192 if (rc != EOK) 193 return rc; 194 if (bithenge_node_type(length_node) != BITHENGE_NODE_INTEGER) { 195 bithenge_node_dec_ref(length_node); 196 return EINVAL; 197 } 198 bithenge_int_t length = bithenge_integer_node_value(length_node); 199 bithenge_node_dec_ref(length_node); 200 201 if (bithenge_node_type(in) != BITHENGE_NODE_BLOB) 202 return EINVAL; 203 aoff64_t size; 204 rc = bithenge_blob_size(bithenge_node_as_blob(in), &size); 205 if (rc != EOK) 206 return rc; 207 if (length != (bithenge_int_t)size) 208 return EINVAL; 209 210 bithenge_node_inc_ref(in); 211 *out = in; 212 return EOK; 213 } 214 215 static int known_length_prefix_length(bithenge_transform_t *self, 216 bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out) 217 { 218 bithenge_node_t *length_node; 219 int rc = bithenge_scope_get_param(scope, 0, &length_node); 220 if (rc != EOK) 221 return rc; 222 if (bithenge_node_type(length_node) != BITHENGE_NODE_INTEGER) { 223 bithenge_node_dec_ref(length_node); 224 return EINVAL; 225 } 226 bithenge_int_t length = bithenge_integer_node_value(length_node); 227 bithenge_node_dec_ref(length_node); 228 229 *out = (aoff64_t)length; 230 return EOK; 231 } 232 233 static const bithenge_transform_ops_t known_length_ops = { 234 .apply = known_length_apply, 235 .prefix_length = known_length_prefix_length, 236 .destroy = transform_indestructible, 237 }; 238 239 /** Pass through a blob, but require its length to equal the first argument. */ 240 bithenge_transform_t bithenge_known_length_transform = { 241 &known_length_ops, 1, 1 107 242 }; 108 243 … … 232 367 static bithenge_named_transform_t primitive_transforms[] = { 233 368 {"ascii", &bithenge_ascii_transform}, 369 {"known_length", &bithenge_known_length_transform}, 234 370 {"uint8", &bithenge_uint8_transform}, 235 371 {"uint16le", &bithenge_uint16le_transform}, -
uspace/app/bithenge/transform.h
r03cad47 r4056ad0 207 207 208 208 extern bithenge_transform_t bithenge_ascii_transform; 209 extern bithenge_transform_t bithenge_known_length_transform; 209 210 extern bithenge_transform_t bithenge_uint8_transform; 210 211 extern bithenge_transform_t bithenge_uint16le_transform; … … 217 218 extern bithenge_named_transform_t *bithenge_primitive_transforms; 218 219 219 int bithenge_init_transform(bithenge_transform_t *self, 220 const bithenge_transform_ops_t *ops, int num_params); 221 int bithenge_new_struct(bithenge_transform_t **out, 222 bithenge_named_transform_t *subtransforms); 220 int bithenge_init_transform(bithenge_transform_t *, 221 const bithenge_transform_ops_t *, int); 222 int bithenge_new_param_transform(bithenge_transform_t **, 223 bithenge_transform_t *, int); 224 int bithenge_new_struct(bithenge_transform_t **, 225 bithenge_named_transform_t *); 223 226 int bithenge_new_composed_transform(bithenge_transform_t **, 224 227 bithenge_transform_t **, size_t); -
uspace/app/bithenge/tree.h
r03cad47 r4056ad0 39 39 40 40 #include <assert.h> 41 #include <inttypes.h>42 41 #include <sys/types.h> 43 42 #include "os.h" 44 45 #ifdef INTMAX_MAX46 typedef intmax_t bithenge_int_t;47 #define BITHENGE_PRId PRIdMAX48 #else49 typedef int64_t bithenge_int_t;50 #define BITHENGE_PRId PRId6451 #endif52 43 53 44 /** Indicates the type of a tree node. */
Note:
See TracChangeset
for help on using the changeset viewer.