Changeset c3437d9 in mainline
- Timestamp:
- 2012-08-04T03:51:15Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0ce0103
- Parents:
- e3f2765
- Location:
- uspace
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bithenge/script.c
re3f2765 rc3437d9 59 59 60 60 /* Keywords */ 61 TOKEN_DO, 61 62 TOKEN_ELSE, 62 63 TOKEN_FALSE, … … 67 68 TOKEN_TRANSFORM, 68 69 TOKEN_TRUE, 70 TOKEN_WHILE, 69 71 } token_type_t; 70 72 … … 211 213 if (!value) { 212 214 error_errno(state, ENOMEM); 215 } else if (!str_cmp(value, "do")) { 216 state->token = TOKEN_DO; 217 free(value); 213 218 } else if (!str_cmp(value, "else")) { 214 219 state->token = TOKEN_ELSE; … … 234 239 } else if (!str_cmp(value, "true")) { 235 240 state->token = TOKEN_TRUE; 241 free(value); 242 } else if (!str_cmp(value, "while")) { 243 state->token = TOKEN_WHILE; 236 244 free(value); 237 245 } else { … … 686 694 } 687 695 696 static bithenge_transform_t *parse_do_while(state_t *state) 697 { 698 expect(state, TOKEN_DO); 699 expect(state, '{'); 700 bithenge_transform_t *xform = parse_transform(state); 701 expect(state, '}'); 702 expect(state, TOKEN_WHILE); 703 expect(state, '('); 704 bithenge_expression_t *expr = parse_expression(state); 705 expect(state, ')'); 706 707 if (state->error != EOK) { 708 bithenge_expression_dec_ref(expr); 709 bithenge_transform_dec_ref(xform); 710 return NULL; 711 } 712 713 bithenge_transform_t *do_while_xform; 714 int rc = bithenge_do_while_transform(&do_while_xform, xform, expr); 715 if (rc != EOK) { 716 error_errno(state, rc); 717 return NULL; 718 } 719 return do_while_xform; 720 } 721 688 722 /* The TOKEN_STRUCT and '{' must already have been skipped. */ 689 723 static bithenge_transform_t *parse_struct(state_t *state) … … 740 774 static bithenge_transform_t *parse_transform_no_compose(state_t *state) 741 775 { 742 if (state->token == TOKEN_IDENTIFIER) { 776 if (state->token == TOKEN_DO) { 777 return parse_do_while(state); 778 } else if (state->token == TOKEN_IDENTIFIER) { 743 779 return parse_invocation(state); 744 780 } else if (state->token == TOKEN_IF) { -
uspace/app/bithenge/sequence.c
re3f2765 rc3437d9 44 44 45 45 46 /***************** seq_node *****************/ 47 46 48 typedef struct { 47 49 bithenge_node_t base; … … 236 238 bithenge_blob_dec_ref(self->blob); 237 239 free(self->ends); 240 } 241 242 static void seq_node_set_num_xforms(seq_node_t *self, 243 bithenge_int_t num_xforms) 244 { 245 self->num_xforms = num_xforms; 238 246 } 239 247 … … 270 278 271 279 280 /***************** bithenge_new_struct *****************/ 281 272 282 typedef struct { 273 283 bithenge_transform_t base; … … 581 591 582 592 593 /***************** bithenge_repeat_transform *****************/ 594 583 595 typedef struct { 584 596 bithenge_transform_t base; … … 636 648 rc = seq_node_subtransform(repeat_as_seq(self), 637 649 &subxform_result, i); 638 if (rc != EOK && self->count == -1) { 650 if ((rc == EINVAL || rc == ENOENT) && self->count == -1) { 651 self->count = i; 652 seq_node_set_num_xforms(repeat_as_seq(self), 653 self->count); 639 654 rc = EOK; 640 655 break; … … 845 860 } 846 861 862 863 864 /***************** bithenge_do_while_transform *****************/ 865 866 typedef struct { 867 bithenge_transform_t base; 868 bithenge_expression_t *expr; 869 bithenge_transform_t *xform; 870 } do_while_transform_t; 871 872 static inline bithenge_transform_t *do_while_as_transform( 873 do_while_transform_t *self) 874 { 875 return &self->base; 876 } 877 878 static inline do_while_transform_t *transform_as_do_while( 879 bithenge_transform_t *base) 880 { 881 return (do_while_transform_t *)base; 882 } 883 884 typedef struct { 885 seq_node_t base; 886 bool prefix; 887 bithenge_expression_t *expr; 888 bithenge_transform_t *xform; 889 bithenge_int_t count; 890 } do_while_node_t; 891 892 static seq_node_t *do_while_as_seq(do_while_node_t *self) 893 { 894 return &self->base; 895 } 896 897 static do_while_node_t *seq_as_do_while(seq_node_t *base) 898 { 899 return (do_while_node_t *)base; 900 } 901 902 static bithenge_node_t *do_while_as_node(do_while_node_t *self) 903 { 904 return seq_as_node(do_while_as_seq(self)); 905 } 906 907 static do_while_node_t *node_as_do_while(bithenge_node_t *base) 908 { 909 return seq_as_do_while(node_as_seq(base)); 910 } 911 912 static int do_while_node_for_each(bithenge_node_t *base, 913 bithenge_for_each_func_t func, void *data) 914 { 915 int rc = EOK; 916 do_while_node_t *self = node_as_do_while(base); 917 918 for (bithenge_int_t i = 0; ; i++) { 919 bithenge_node_t *subxform_result; 920 rc = seq_node_subtransform(do_while_as_seq(self), 921 &subxform_result, i); 922 if (rc != EOK) 923 return rc; 924 925 bithenge_node_t *key_node; 926 rc = bithenge_new_integer_node(&key_node, i); 927 if (rc != EOK) { 928 bithenge_node_dec_ref(subxform_result); 929 return rc; 930 } 931 bithenge_node_inc_ref(subxform_result); 932 rc = func(key_node, subxform_result, data); 933 if (rc != EOK) { 934 bithenge_node_dec_ref(subxform_result); 935 return rc; 936 } 937 938 bithenge_scope_t scope; 939 bithenge_scope_init(&scope); 940 rc = bithenge_scope_copy(&scope, 941 seq_node_scope(do_while_as_seq(self))); 942 bithenge_scope_set_current_node(&scope, subxform_result); 943 if (rc != EOK) { 944 bithenge_scope_destroy(&scope); 945 return rc; 946 } 947 bithenge_node_t *expr_result; 948 rc = bithenge_expression_evaluate(self->expr, &scope, 949 &expr_result); 950 bithenge_scope_destroy(&scope); 951 if (rc != EOK) 952 return rc; 953 if (bithenge_node_type(expr_result) != BITHENGE_NODE_BOOLEAN) { 954 bithenge_node_dec_ref(expr_result); 955 return EINVAL; 956 } 957 bool cond = bithenge_boolean_node_value(expr_result); 958 bithenge_node_dec_ref(expr_result); 959 if (!cond) { 960 self->count = i + 1; 961 seq_node_set_num_xforms(do_while_as_seq(self), 962 self->count); 963 break; 964 } 965 } 966 967 if (!self->prefix) { 968 bool complete; 969 rc = seq_node_complete(do_while_as_seq(self), &complete); 970 if (rc != EOK) 971 return rc; 972 if (!complete) 973 return EINVAL; 974 } 975 976 return rc; 977 } 978 979 static void do_while_node_destroy(bithenge_node_t *base) 980 { 981 do_while_node_t *self = node_as_do_while(base); 982 seq_node_destroy(do_while_as_seq(self)); 983 bithenge_expression_dec_ref(self->expr); 984 bithenge_transform_dec_ref(self->xform); 985 free(self); 986 } 987 988 static const bithenge_internal_node_ops_t do_while_node_ops = { 989 .for_each = do_while_node_for_each, 990 .destroy = do_while_node_destroy, 991 }; 992 993 static int do_while_node_get_transform(seq_node_t *base, 994 bithenge_transform_t **out, bithenge_int_t index) 995 { 996 do_while_node_t *self = seq_as_do_while(base); 997 *out = self->xform; 998 bithenge_transform_inc_ref(*out); 999 return EOK; 1000 } 1001 1002 static const seq_node_ops_t do_while_node_seq_ops = { 1003 .get_transform = do_while_node_get_transform, 1004 }; 1005 1006 static int do_while_transform_make_node(do_while_transform_t *self, 1007 bithenge_node_t **out, bithenge_scope_t *scope, bithenge_blob_t *blob, 1008 bool prefix) 1009 { 1010 do_while_node_t *node = malloc(sizeof(*node)); 1011 if (!node) 1012 return ENOMEM; 1013 1014 int rc = bithenge_init_internal_node(do_while_as_node(node), 1015 &do_while_node_ops); 1016 if (rc != EOK) { 1017 free(node); 1018 return rc; 1019 } 1020 1021 rc = seq_node_init(do_while_as_seq(node), &do_while_node_seq_ops, 1022 scope, blob, -1, false); 1023 if (rc != EOK) { 1024 free(node); 1025 return rc; 1026 } 1027 1028 bithenge_transform_inc_ref(self->xform); 1029 node->xform = self->xform; 1030 bithenge_expression_inc_ref(self->expr); 1031 node->expr = self->expr; 1032 node->prefix = prefix; 1033 node->count = -1; 1034 *out = do_while_as_node(node); 1035 return EOK; 1036 } 1037 1038 static int do_while_transform_apply(bithenge_transform_t *base, 1039 bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out) 1040 { 1041 do_while_transform_t *self = transform_as_do_while(base); 1042 if (bithenge_node_type(in) != BITHENGE_NODE_BLOB) 1043 return EINVAL; 1044 return do_while_transform_make_node(self, out, scope, 1045 bithenge_node_as_blob(in), false); 1046 } 1047 1048 static int for_each_noop(bithenge_node_t *key, bithenge_node_t *value, 1049 void *data) 1050 { 1051 bithenge_node_dec_ref(key); 1052 bithenge_node_dec_ref(value); 1053 return EOK; 1054 } 1055 1056 static int do_while_transform_prefix_apply(bithenge_transform_t *base, 1057 bithenge_scope_t *scope, bithenge_blob_t *blob, bithenge_node_t **out_node, 1058 aoff64_t *out_size) 1059 { 1060 do_while_transform_t *self = transform_as_do_while(base); 1061 int rc = do_while_transform_make_node(self, out_node, scope, blob, 1062 true); 1063 if (rc != EOK) 1064 return rc; 1065 1066 rc = bithenge_node_for_each(*out_node, for_each_noop, NULL); 1067 if (rc != EOK) { 1068 bithenge_node_dec_ref(*out_node); 1069 return rc; 1070 } 1071 1072 rc = seq_node_field_offset(node_as_seq(*out_node), out_size, 1073 node_as_do_while(*out_node)->count); 1074 if (rc != EOK) { 1075 bithenge_node_dec_ref(*out_node); 1076 return rc; 1077 } 1078 1079 return EOK; 1080 } 1081 1082 static void do_while_transform_destroy(bithenge_transform_t *base) 1083 { 1084 do_while_transform_t *self = transform_as_do_while(base); 1085 bithenge_transform_dec_ref(self->xform); 1086 bithenge_expression_dec_ref(self->expr); 1087 free(self); 1088 } 1089 1090 static const bithenge_transform_ops_t do_while_transform_ops = { 1091 .apply = do_while_transform_apply, 1092 .prefix_apply = do_while_transform_prefix_apply, 1093 .destroy = do_while_transform_destroy, 1094 }; 1095 1096 /** Create a transform that applies its subtransform while an expression on the 1097 * result returns true. Takes a reference to @a xform and @a expr. 1098 * @param[out] out Holds the new transform. 1099 * @param xform The subtransform to apply repeatedly. 1100 * @param expr Applied in the result of each application of @a xform to 1101 * determine whether there will be more. 1102 * @return EOK on success or an error code from errno.h. */ 1103 int bithenge_do_while_transform(bithenge_transform_t **out, 1104 bithenge_transform_t *xform, bithenge_expression_t *expr) 1105 { 1106 int rc; 1107 do_while_transform_t *self = malloc(sizeof(*self)); 1108 if (!self) { 1109 rc = ENOMEM; 1110 goto error; 1111 } 1112 1113 rc = bithenge_init_transform(do_while_as_transform(self), 1114 &do_while_transform_ops, 0); 1115 if (rc != EOK) 1116 goto error; 1117 1118 self->expr = expr; 1119 self->xform = xform; 1120 *out = do_while_as_transform(self); 1121 return EOK; 1122 1123 error: 1124 free(self); 1125 bithenge_expression_dec_ref(expr); 1126 bithenge_transform_dec_ref(xform); 1127 return rc; 1128 } 1129 847 1130 /** @} 848 1131 */ -
uspace/app/bithenge/sequence.h
re3f2765 rc3437d9 44 44 int bithenge_repeat_transform(bithenge_transform_t **, bithenge_transform_t *, 45 45 bithenge_expression_t *); 46 int bithenge_do_while_transform(bithenge_transform_t **, 47 bithenge_transform_t *, bithenge_expression_t *); 46 48 47 49 #endif -
uspace/app/bithenge/transform.c
re3f2765 rc3437d9 201 201 for (int i = 0; i < out->num_params; i++) 202 202 bithenge_node_inc_ref(out->params[i]); 203 bithenge_node_dec_ref(out->current_node); 203 204 out->current_node = scope->current_node; 204 205 if (out->current_node) … … 474 475 bithenge_transform_t bithenge_known_length_transform = { 475 476 &known_length_ops, 1, 1 477 }; 478 479 static int nonzero_boolean_apply(bithenge_transform_t *self, 480 bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out) 481 { 482 if (bithenge_node_type(in) != BITHENGE_NODE_INTEGER) 483 return EINVAL; 484 bool value = bithenge_integer_node_value(in) != 0; 485 return bithenge_new_boolean_node(out, value); 486 } 487 488 static const bithenge_transform_ops_t nonzero_boolean_ops = { 489 .apply = nonzero_boolean_apply, 490 .destroy = transform_indestructible, 491 }; 492 493 /** A transform that converts integers to booleans, true if nonzero. */ 494 bithenge_transform_t bithenge_nonzero_boolean_transform = { 495 &nonzero_boolean_ops, 1, 0 476 496 }; 477 497 … … 602 622 {"ascii", &bithenge_ascii_transform}, 603 623 {"known_length", &bithenge_known_length_transform}, 624 {"nonzero_boolean", &bithenge_nonzero_boolean_transform}, 604 625 {"uint8", &bithenge_uint8_transform}, 605 626 {"uint16le", &bithenge_uint16le_transform}, -
uspace/app/bithenge/transform.h
re3f2765 rc3437d9 112 112 113 113 extern bithenge_transform_t bithenge_ascii_transform; 114 extern bithenge_transform_t bithenge_invalid_transform; 114 115 extern bithenge_transform_t bithenge_known_length_transform; 115 extern bithenge_transform_t bithenge_ invalid_transform;116 extern bithenge_transform_t bithenge_nonzero_boolean_transform; 116 117 extern bithenge_transform_t bithenge_uint8_transform; 117 118 extern bithenge_transform_t bithenge_uint16le_transform; -
uspace/dist/src/bithenge/test-repeat.bh
re3f2765 rc3437d9 7 7 8 8 transform without_count = struct { 9 . error <- repeat { uint8 <- zero_terminated };10 . end <- repeat { uint8 };9 .until_error <- repeat { uint8 <- zero_terminated }; 10 .until_end <- repeat { uint8 }; 11 11 }; 12 13 transform do_while = do { 14 struct { 15 .valid <- nonzero_boolean <- uint8; 16 .val <- uint8; 17 } 18 } while (.valid); 12 19 13 20 transform main = struct { 14 21 .with_count <- with_count; 15 .without_count <- without_count; 22 .without_count <- without_count <- known_length(9); 23 .do_while <- do_while; 16 24 };
Note:
See TracChangeset
for help on using the changeset viewer.