Changeset 10334c2e in mainline for uspace/app/bithenge/expression.c
- Timestamp:
- 2012-07-30T01:40:55Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 20ac1a4
- Parents:
- d1e580a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bithenge/expression.c
rd1e580a r10334c2e 417 417 } 418 418 419 typedef struct { 420 bithenge_transform_t base; 421 bithenge_expression_t *expr; 422 bithenge_transform_t *true_xform, *false_xform; 423 } if_transform_t; 424 425 static inline bithenge_transform_t *if_as_transform(if_transform_t *self) 426 { 427 return &self->base; 428 } 429 430 static inline if_transform_t *transform_as_if(bithenge_transform_t *base) 431 { 432 return (if_transform_t *)base; 433 } 434 435 static int if_transform_choose(if_transform_t *self, bithenge_scope_t *scope, 436 bool *out) 437 { 438 bithenge_node_t *cond_node; 439 int rc = bithenge_expression_evaluate(self->expr, scope, &cond_node); 440 if (rc != EOK) 441 return rc; 442 if (bithenge_node_type(cond_node) != BITHENGE_NODE_BOOLEAN) { 443 bithenge_node_dec_ref(cond_node); 444 return EINVAL; 445 } 446 *out = bithenge_boolean_node_value(cond_node); 447 bithenge_node_dec_ref(cond_node); 448 return EOK; 449 } 450 451 static int if_transform_apply(bithenge_transform_t *base, 452 bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out) 453 { 454 if_transform_t *self = transform_as_if(base); 455 bool cond; 456 int rc = if_transform_choose(self, scope, &cond); 457 if (rc != EOK) 458 return rc; 459 return bithenge_transform_apply( 460 cond ? self->true_xform : self->false_xform, scope, in, out); 461 } 462 463 static int if_transform_prefix_length(bithenge_transform_t *base, 464 bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out) 465 { 466 if_transform_t *self = transform_as_if(base); 467 bool cond; 468 int rc = if_transform_choose(self, scope, &cond); 469 if (rc != EOK) 470 return rc; 471 return bithenge_transform_prefix_length( 472 cond ? self->true_xform : self->false_xform, scope, in, out); 473 } 474 475 static void if_transform_destroy(bithenge_transform_t *base) 476 { 477 if_transform_t *self = transform_as_if(base); 478 bithenge_expression_dec_ref(self->expr); 479 bithenge_transform_dec_ref(self->true_xform); 480 bithenge_transform_dec_ref(self->false_xform); 481 free(self); 482 } 483 484 static const bithenge_transform_ops_t if_transform_ops = { 485 .apply = if_transform_apply, 486 .prefix_length = if_transform_prefix_length, 487 .destroy = if_transform_destroy, 488 }; 489 490 /** Create a transform that applies either of two transforms depending on a 491 * boolean expression. Takes references to @a expr, @a true_xform, and 492 * @a false_xform. 493 * @param[out] out Holds the new transform. 494 * @param expr The boolean expression to evaluate. 495 * @param true_xform The transform to apply if the expression is true. 496 * @param false_xform The transform to apply if the expression is false. */ 497 int bithenge_if_transform(bithenge_transform_t **out, 498 bithenge_expression_t *expr, bithenge_transform_t *true_xform, 499 bithenge_transform_t *false_xform) 500 { 501 int rc; 502 if_transform_t *self = malloc(sizeof(*self)); 503 if (!self) { 504 rc = ENOMEM; 505 goto error; 506 } 507 508 rc = bithenge_init_transform(if_as_transform(self), &if_transform_ops, 509 0); 510 if (rc != EOK) 511 goto error; 512 513 self->expr = expr; 514 self->true_xform = true_xform; 515 self->false_xform = false_xform; 516 *out = if_as_transform(self); 517 return EOK; 518 519 error: 520 free(self); 521 bithenge_expression_dec_ref(expr); 522 bithenge_transform_dec_ref(true_xform); 523 bithenge_transform_dec_ref(false_xform); 524 return rc; 525 } 526 419 527 /** @} 420 528 */
Note:
See TracChangeset
for help on using the changeset viewer.