Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset b8d45e9e in mainline


Ignore:
Timestamp:
2012-08-02T21:06:59Z (9 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master
Children:
0f8062a4
Parents:
cb4a66d2
Message:

Bithenge: make each transform definition have its own scope

Location:
uspace/app/bithenge
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bithenge/expression.c

    rcb4a66d2 rb8d45e9e  
    670670 * @param expr The boolean expression to evaluate.
    671671 * @param true_xform The transform to apply if the expression is true.
    672  * @param false_xform The transform to apply if the expression is false. */
     672 * @param false_xform The transform to apply if the expression is false.
     673 * @return EOK on success or an error code from errno.h. */
    673674int bithenge_if_transform(bithenge_transform_t **out,
    674675    bithenge_expression_t *expr, bithenge_transform_t *true_xform,
  • uspace/app/bithenge/script.c

    rcb4a66d2 rb8d45e9e  
    785785        expect(state, ';');
    786786
    787         if (state->error == EOK && state->num_params) {
    788                 int rc = bithenge_new_param_transform(&xform, xform,
     787        if (state->error == EOK) {
     788                int rc = bithenge_new_scope_transform(&xform, xform,
    789789                    state->num_params);
    790790                if (rc != EOK) {
  • uspace/app/bithenge/transform.c

    rcb4a66d2 rb8d45e9e  
    165165}
    166166
     167/** Initialize a transform scope. It must be destroyed with @a
     168 * bithenge_scope_destroy after it is used.
     169 * @param[out] scope The scope to initialize. */
     170void bithenge_scope_init(bithenge_scope_t *scope)
     171{
     172        scope->num_params = 0;
     173        scope->params = NULL;
     174        scope->current_node = NULL;
     175}
     176
     177/** Destroy a transform scope.
     178 * @param scope The scope to destroy.
     179 * @return EOK on success or an error code from errno.h. */
     180void bithenge_scope_destroy(bithenge_scope_t *scope)
     181{
     182        bithenge_node_dec_ref(scope->current_node);
     183        for (int i = 0; i < scope->num_params; i++)
     184                bithenge_node_dec_ref(scope->params[i]);
     185        free(scope->params);
     186}
     187
     188/** Copy a scope.
     189 * @param[out] out The scope to fill in; must have been initialized with @a
     190 * bithenge_scope_init.
     191 * @param scope The scope to copy.
     192 * @return EOK on success or an error code from errno.h. */
     193int bithenge_scope_copy(bithenge_scope_t *out, bithenge_scope_t *scope)
     194{
     195        out->params = malloc(sizeof(*out->params) * scope->num_params);
     196        if (!out->params)
     197                return ENOMEM;
     198        memcpy(out->params, scope->params, sizeof(*out->params) *
     199            scope->num_params);
     200        out->num_params = scope->num_params;
     201        for (int i = 0; i < out->num_params; i++)
     202                bithenge_node_inc_ref(out->params[i]);
     203        out->current_node = scope->current_node;
     204        if (out->current_node)
     205                bithenge_node_inc_ref(out->current_node);
     206        return EOK;
     207}
     208
     209/** Set the current node being created. Takes a reference to @a node.
     210 * @param scope The scope to set the current node in.
     211 * @param node The current node being created, or NULL.
     212 * @return EOK on success or an error code from errno.h. */
     213void bithenge_scope_set_current_node(bithenge_scope_t *scope,
     214    bithenge_node_t *node)
     215{
     216        bithenge_node_dec_ref(scope->current_node);
     217        scope->current_node = node;
     218}
     219
     220/** Get the current node being created, which may be NULL.
     221 * @param scope The scope to get the current node from.
     222 * @return The node being created, or NULL. */
     223bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *scope)
     224{
     225        if (scope->current_node)
     226                bithenge_node_inc_ref(scope->current_node);
     227        return scope->current_node;
     228}
     229
     230/** Allocate parameters. The parameters must then be set with @a
     231 * bithenge_scope_set_param. This must not be called on a scope that already
     232 * has parameters.
     233 * @param scope The scope in which to allocate parameters.
     234 * @param num_params The number of parameters to allocate.
     235 * @return EOK on success or an error code from errno.h. */
     236int bithenge_scope_alloc_params(bithenge_scope_t *scope, int num_params)
     237{
     238        scope->params = malloc(sizeof(*scope->params) * num_params);
     239        if (!scope->params)
     240                return ENOMEM;
     241        scope->num_params = num_params;
     242        for (int i = 0; i < num_params; i++)
     243                scope->params[i] = NULL;
     244        return EOK;
     245}
     246
     247/** Set a parameter. Takes a reference to @a value. Note that range checking is
     248 * not done in release builds.
     249 * @param scope The scope in which to allocate parameters.
     250 * @param i The index of the parameter to set.
     251 * @param value The value to store in the parameter.
     252 * @return EOK on success or an error code from errno.h. */
     253int bithenge_scope_set_param( bithenge_scope_t *scope, int i,
     254    bithenge_node_t *node)
     255{
     256        assert(scope);
     257        assert(i >= 0 && i < scope->num_params);
     258        scope->params[i] = node;
     259        return EOK;
     260}
     261
     262/** Get a parameter. Note that range checking is not done in release builds.
     263 * @param scope The scope to get the parameter from.
     264 * @param i The index of the parameter to set.
     265 * @param[out] out Stores a new reference to the parameter.
     266 * @return EOK on success or an error code from errno.h. */
     267int bithenge_scope_get_param(bithenge_scope_t *scope, int i,
     268    bithenge_node_t **out)
     269{
     270        assert(scope);
     271        assert(i >= 0 && i < scope->num_params);
     272        *out = scope->params[i];
     273        bithenge_node_inc_ref(*out);
     274        return EOK;
     275}
     276
    167277typedef struct {
    168278        bithenge_transform_t base;
    169279        bithenge_transform_t *transform;
    170 } param_transform_t;
    171 
    172 static inline param_transform_t *transform_as_param(
     280} scope_transform_t;
     281
     282static inline scope_transform_t *transform_as_param(
    173283    bithenge_transform_t *base)
    174284{
    175         return (param_transform_t *)base;
     285        return (scope_transform_t *)base;
    176286}
    177287
    178288static inline bithenge_transform_t *param_as_transform(
    179     param_transform_t *self)
     289    scope_transform_t *self)
    180290{
    181291        return &self->base;
    182292}
    183293
    184 static int param_transform_apply(bithenge_transform_t *base,
     294static int scope_transform_apply(bithenge_transform_t *base,
    185295    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
    186296{
    187         param_transform_t *self = transform_as_param(base);
    188         return bithenge_transform_apply(self->transform, scope, in, out);
    189 }
    190 
    191 static int param_transform_prefix_length(bithenge_transform_t *base,
     297        scope_transform_t *self = transform_as_param(base);
     298        bithenge_scope_t inner_scope;
     299        bithenge_scope_init(&inner_scope);
     300        int rc = bithenge_scope_copy(&inner_scope, scope);
     301        if (rc != EOK)
     302                goto error;
     303        bithenge_scope_set_current_node(&inner_scope, NULL);
     304        rc = bithenge_transform_apply(self->transform, scope, in, out);
     305error:
     306        bithenge_scope_destroy(&inner_scope);
     307        return rc;
     308}
     309
     310static int scope_transform_prefix_length(bithenge_transform_t *base,
    192311    bithenge_scope_t *scope, bithenge_blob_t *in, aoff64_t *out)
    193312{
    194         param_transform_t *self = transform_as_param(base);
     313        scope_transform_t *self = transform_as_param(base);
    195314        return bithenge_transform_prefix_length(self->transform, scope, in,
    196315            out);
    197316}
    198317
    199 static void param_transform_destroy(bithenge_transform_t *base)
    200 {
    201         param_transform_t *self = transform_as_param(base);
     318static void scope_transform_destroy(bithenge_transform_t *base)
     319{
     320        scope_transform_t *self = transform_as_param(base);
    202321        bithenge_transform_dec_ref(self->transform);
    203322        free(self);
    204323}
    205324
    206 static const bithenge_transform_ops_t param_transform_ops = {
    207         .apply = param_transform_apply,
    208         .prefix_length = param_transform_prefix_length,
    209         .destroy = param_transform_destroy,
    210 };
    211 
    212 /** Create a wrapper transform with a different number of parameters. Takes a
    213  * reference to @a transform, which it will use for all operations.
     325static const bithenge_transform_ops_t scope_transform_ops = {
     326        .apply = scope_transform_apply,
     327        .prefix_length = scope_transform_prefix_length,
     328        .destroy = scope_transform_destroy,
     329};
     330
     331/** Create a wrapper transform that creates a new outer scope. This ensures
     332 * nothing from the transform's users is passed in, other than parameters. The
     333 * wrapper may have a different value for num_params. Takes a reference to
     334 * @a transform, which it will use for all operations.
    214335 * @param[out] out Holds the created transform.
    215336 * @param transform The transform to wrap.
    216  * @param num_params The number of parameters to require.
     337 * @param num_params The number of parameters to require, which may be 0.
    217338 * @return EOK on success or an error code from errno.h. */
    218 int bithenge_new_param_transform(bithenge_transform_t **out,
     339int bithenge_new_scope_transform(bithenge_transform_t **out,
    219340    bithenge_transform_t *transform, int num_params)
    220341{
    221342        assert(transform);
    222343        assert(bithenge_transform_num_params(transform) == 0);
    223         assert(num_params != 0);
    224344
    225345        int rc;
    226         param_transform_t *self = malloc(sizeof(*self));
     346        scope_transform_t *self = malloc(sizeof(*self));
    227347        if (!self) {
    228348                rc = ENOMEM;
     
    230350        }
    231351        rc = bithenge_init_transform(param_as_transform(self),
    232             &param_transform_ops, num_params);
     352            &scope_transform_ops, num_params);
    233353        if (rc != EOK)
    234354                goto error;
     
    497617
    498618typedef struct {
     619        bithenge_transform_t base;
     620        bithenge_named_transform_t *subtransforms;
     621        size_t num_subtransforms;
     622} struct_transform_t;
     623
     624typedef struct {
    499625        bithenge_node_t base;
    500626        bithenge_scope_t scope;
    501         struct struct_transform *transform;
     627        struct_transform_t *transform;
    502628        bithenge_blob_t *blob;
    503629        aoff64_t *ends;
     
    505631        bool prefix;
    506632} struct_node_t;
    507 
    508 typedef struct struct_transform {
    509         bithenge_transform_t base;
    510         bithenge_named_transform_t *subtransforms;
    511         size_t num_subtransforms;
    512 } struct_transform_t;
    513633
    514634static bithenge_node_t *struct_as_node(struct_node_t *node)
  • uspace/app/bithenge/transform.h

    rcb4a66d2 rb8d45e9e  
    7676} bithenge_transform_ops_t;
    7777
    78 /** Initialize a transform scope. It must be destroyed with @a
    79  * bithenge_scope_destroy after it is used.
    80  * @param[out] scope The scope to initialize. */
    81 static inline void bithenge_scope_init(bithenge_scope_t *scope)
    82 {
    83         scope->num_params = 0;
    84         scope->params = NULL;
    85         scope->current_node = NULL;
    86 }
    87 
    88 /** Destroy a transform scope.
    89  * @param scope The scope to destroy.
    90  * @return EOK on success or an error code from errno.h. */
    91 static inline void bithenge_scope_destroy(bithenge_scope_t *scope)
    92 {
    93         bithenge_node_dec_ref(scope->current_node);
    94         for (int i = 0; i < scope->num_params; i++)
    95                 bithenge_node_dec_ref(scope->params[i]);
    96         free(scope->params);
    97 }
    98 
    99 /** Copy a scope.
    100  * @param[out] out The scope to fill in; must have been initialized with @a
    101  * bithenge_scope_init.
    102  * @param scope The scope to copy.
    103  * @return EOK on success or an error code from errno.h. */
    104 static inline int bithenge_scope_copy(bithenge_scope_t *out,
    105     bithenge_scope_t *scope)
    106 {
    107         out->params = malloc(sizeof(*out->params) * scope->num_params);
    108         if (!out->params)
    109                 return ENOMEM;
    110         memcpy(out->params, scope->params, sizeof(*out->params) *
    111             scope->num_params);
    112         out->num_params = scope->num_params;
    113         for (int i = 0; i < out->num_params; i++)
    114                 bithenge_node_inc_ref(out->params[i]);
    115         out->current_node = scope->current_node;
    116         if (out->current_node)
    117                 bithenge_node_inc_ref(out->current_node);
    118         return EOK;
    119 }
    120 
    121 /** Set the current node being created. Takes a reference to @a node.
    122  * @param scope The scope to set the current node in.
    123  * @param node The current node being created.
    124  * @return EOK on success or an error code from errno.h. */
    125 static inline void bithenge_scope_set_current_node(bithenge_scope_t *scope,
    126     bithenge_node_t *node)
    127 {
    128         bithenge_node_dec_ref(scope->current_node);
    129         scope->current_node = node;
    130 }
    131 
    132 /** Get the current node being created, which may be NULL.
    133  * @param scope The scope to get the current node from.
    134  * @return The node being created, or NULL. */
    135 static inline bithenge_node_t *bithenge_scope_get_current_node(
    136     bithenge_scope_t *scope)
    137 {
    138         if (scope->current_node)
    139                 bithenge_node_inc_ref(scope->current_node);
    140         return scope->current_node;
    141 }
    142 
    143 /** Allocate parameters. The parameters must then be set with @a
    144  * bithenge_scope_set_param. This must not be called on a scope that already
    145  * has parameters.
    146  * @param scope The scope in which to allocate parameters.
    147  * @param num_params The number of parameters to allocate.
    148  * @return EOK on success or an error code from errno.h. */
    149 static inline int bithenge_scope_alloc_params(bithenge_scope_t *scope,
    150     int num_params)
    151 {
    152         scope->params = malloc(sizeof(*scope->params) * num_params);
    153         if (!scope->params)
    154                 return ENOMEM;
    155         scope->num_params = num_params;
    156         for (int i = 0; i < num_params; i++)
    157                 scope->params[i] = NULL;
    158         return EOK;
    159 }
    160 
    161 /** Set a parameter. Takes a reference to @a value. Note that range checking is
    162  * not done in release builds.
    163  * @param scope The scope in which to allocate parameters.
    164  * @param i The index of the parameter to set.
    165  * @param value The value to store in the parameter.
    166  * @return EOK on success or an error code from errno.h. */
    167 static inline int bithenge_scope_set_param( bithenge_scope_t *scope, int i,
    168     bithenge_node_t *node)
    169 {
    170         assert(scope);
    171         assert(i >= 0 && i < scope->num_params);
    172         scope->params[i] = node;
    173         return EOK;
    174 }
    175 
    176 /** Get a parameter. Note that range checking is not done in release builds.
    177  * @param scope The scope to get the parameter from.
    178  * @param i The index of the parameter to set.
    179  * @param[out] out Stores a new reference to the parameter.
    180  * @return EOK on success or an error code from errno.h. */
    181 static inline int bithenge_scope_get_param(bithenge_scope_t *scope, int i,
    182     bithenge_node_t **out)
    183 {
    184         assert(scope);
    185         assert(i >= 0 && i < scope->num_params);
    186         *out = scope->params[i];
    187         bithenge_node_inc_ref(*out);
    188         return EOK;
    189 }
    190 
    19178/** Get the number of parameters required by a transform. This number is used
    19279 * by the parser and param-wrapper. Takes ownership of nothing.
     
    245132int bithenge_transform_prefix_apply(bithenge_transform_t *, bithenge_scope_t *,
    246133    bithenge_blob_t *, bithenge_node_t **, aoff64_t *);
    247 int bithenge_new_param_transform(bithenge_transform_t **,
     134int bithenge_new_scope_transform(bithenge_transform_t **,
    248135    bithenge_transform_t *, int);
    249136int bithenge_new_struct(bithenge_transform_t **,
     
    252139    bithenge_transform_t **, size_t);
    253140
     141void bithenge_scope_init(bithenge_scope_t *);
     142void bithenge_scope_destroy(bithenge_scope_t *);
     143int bithenge_scope_copy(bithenge_scope_t *, bithenge_scope_t *);
     144void bithenge_scope_set_current_node(bithenge_scope_t *, bithenge_node_t *);
     145bithenge_node_t *bithenge_scope_get_current_node(bithenge_scope_t *);
     146int bithenge_scope_alloc_params(bithenge_scope_t *, int);
     147int bithenge_scope_set_param(bithenge_scope_t *, int, bithenge_node_t *);
     148int bithenge_scope_get_param(bithenge_scope_t *, int, bithenge_node_t **);
     149
    254150#endif
    255151
Note: See TracChangeset for help on using the changeset viewer.