<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "mpr_internal.h"
#include "types_internal.h"

mpr_graph mpr_obj_get_graph(mpr_obj o)
{
    return o ? o->graph : 0;
}

mpr_type mpr_obj_get_type(mpr_obj o)
{
    return o ? o->type : 0;
}

void mpr_obj_increment_version(mpr_obj o)
{
    RETURN_UNLESS(o && o->props.staged);
    ++o->version;
    o->props.synced->dirty = 1;
}

int mpr_obj_get_num_props(mpr_obj o, int staged)
{
    int len = 0;
    if (o) {
        if (o->props.synced)
            len += mpr_tbl_get_size(o->props.synced);
        if (staged && o->props.staged)
            len += mpr_tbl_get_size(o->props.staged);
    }
    return len;
}

mpr_prop mpr_obj_get_prop_by_key(mpr_obj o, const char *s, int *l, mpr_type *t,
                                 const void **v, int *p)
{
    RETURN_UNLESS(o && s, 0);
    return mpr_tbl_get_prop_by_key(o->props.synced, s, l, t, v, p);
}

mpr_prop mpr_obj_get_prop_by_idx(mpr_obj o, mpr_prop p, const char **k, int *l,
                                 mpr_type *t, const void **v, int *pub)
{
    RETURN_UNLESS(o, 0);
    return mpr_tbl_get_prop_by_idx(o->props.synced, p | o->props.mask, k, l, t,
                                   v, pub);
}

int mpr_obj_get_prop_as_int32(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && 1 == r->len, 0);
    void *v = (r->flags & INDIRECT) ? *r->val : r->val;
    switch(r->type) {
        case MPR_BOOL:
        case MPR_INT32: return *(int*)v;
        case MPR_INT64: return (int)(*(int64_t*)v);
        case MPR_FLT:   return (int)(*(float*)v);
        case MPR_DBL:   return (int)(*(double*)v);
        case MPR_TYPE:  return (int)(*(mpr_type*)v);
        default:        return 0;
    }
}

float mpr_obj_get_prop_as_flt(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && 1 == r->len, 0);
    void *v = (r->flags & INDIRECT) ? *r->val : r->val;
    switch(r->type) {
        case MPR_BOOL:
        case MPR_INT32: return (float)(*(int*)v);
        case MPR_INT64: return (float)(*(int64_t*)v);
        case MPR_FLT:   return *(float*)v;
        case MPR_DBL:   return (float)(*(double*)v);
        default:        return 0;
    }
}

const char *mpr_obj_get_prop_as_str(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && MPR_STR == r->type && 1 == r->len, 0);
    return r->flags & INDIRECT ? *r->val : r->val;
}

const void *mpr_obj_get_prop_as_ptr(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && MPR_PTR == r->type && 1 == r->len, 0);
    return r->flags & INDIRECT ? *r->val : r->val;
}

mpr_obj mpr_obj_get_prop_as_obj(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && MPR_OBJ >= r->type && 1 == r->len, 0);
    return r->flags & INDIRECT ? *r->val : r->val;
}

mpr_list mpr_obj_get_prop_as_list(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && MPR_LIST == r->type && 1 == r->len, 0);
    mpr_list l = r->flags & INDIRECT ? *r->val : r->val;
    return l ? mpr_list_start(mpr_list_get_cpy(l)) : 0;
}

mpr_prop mpr_obj_set_prop(mpr_obj o, mpr_prop p, const char *s, int len,
                          mpr_type type, const void *val, int publish)
{
    RETURN_UNLESS(o, 0);
    // TODO: ensure ID property can't be changed by user code
    if (MPR_PROP_UNKNOWN == p || !MASK_PROP_BITFLAGS(p)) {
        if (!s || '@' == s[0])
            return MPR_PROP_UNKNOWN;
        p = mpr_prop_from_str(s);
    }

    // check if object represents local resource
    int local = o->props.staged ? 0 : 1;
    int flags = local ? LOCAL_MODIFY : REMOTE_MODIFY;
    if (!publish)
        flags |= LOCAL_ACCESS_ONLY;
    return mpr_tbl_set(local ? o->props.synced : o->props.staged,
                       p | o->props.mask, s, len, type, val, flags);
}

int mpr_obj_remove_prop(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    // check if object represents local resource
    int local = o->props.staged ? 0 : 1;
    if (MPR_PROP_UNKNOWN == p)
        p = mpr_prop_from_str(s);
    if (MPR_PROP_DATA == p || local)
        return mpr_tbl_remove(o->props.synced, p, s, LOCAL_MODIFY);
    else if (MPR_PROP_EXTRA == p)
        return mpr_tbl_set(o->props.staged, p | PROP_REMOVE, s, 0, 0, 0,
                           REMOTE_MODIFY);
    return 0;
}

void mpr_obj_push(mpr_obj o)
{
    RETURN_UNLESS(o);
    mpr_net n = &o->graph->net;

    if (MPR_DEV == o->type) {
        mpr_dev d = (mpr_dev)o;
        if (d->loc) {
            mpr_net_use_subscribers(n, d, o->type);
            mpr_dev_send_state(d, MSG_DEV);
        }
        else {
            mpr_net_use_bus(n);
            mpr_dev_send_state(d, MSG_DEV_MOD);
        }
    }
    else if (o->type & MPR_SIG) {
        mpr_sig s = (mpr_sig)o;
        if (s->loc) {
            mpr_type type = ((s->dir == MPR_DIR_OUT) ? MPR_SIG_OUT : MPR_SIG_IN);
            mpr_net_use_subscribers(n, s->dev, type);
            mpr_sig_send_state(s, MSG_SIG);
        }
        else {
            mpr_net_use_bus(n);
            mpr_sig_send_state(s, MSG_SIG_MOD);
        }
    }
    else if (o->type & MPR_MAP) {
        mpr_net_use_bus(n);
        mpr_map m = (mpr_map)o;
        if (m->status >= MPR_STATUS_ACTIVE)
            mpr_map_send_state(m, -1, MSG_MAP_MOD);
        else
            mpr_map_send_state(m, -1, MSG_MAP);
    }
    else {
        trace("mpr_obj_push(): unknown object type %d\n", o->type);
        return;
    }

    // clear the staged properties
    mpr_tbl_clear(o->props.staged);
}

void mpr_obj_print(mpr_obj o, int staged)
{
    RETURN_UNLESS(o && o->props.synced);
    int i = 0, len;
    mpr_prop p;
    const char *key;
    mpr_type type;
    const void *val;

    switch (o->type) {
        case MPR_DEV:
            printf("DEVICE: ");
            mpr_prop_print(1, MPR_DEV, o);
            break;
        case MPR_SIG:
            printf("SIGNAL: ");
            mpr_prop_print(1, MPR_SIG, o);
            break;
        case MPR_MAP: {
            printf("MAP: ");
            mpr_map m = (mpr_map)o;
            if (m->num_src > 1)
                printf("[");
            mpr_list l = mpr_map_get_sigs(m, MPR_LOC_SRC);
            while (l) {
                mpr_prop_print(1, MPR_SIG, *l);<commit_msg>Fixed memory access bug when setting properties of local objects.<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "mpr_internal.h"
#include "types_internal.h"

mpr_graph mpr_obj_get_graph(mpr_obj o)
{
    return o ? o->graph : 0;
}

mpr_type mpr_obj_get_type(mpr_obj o)
{
    return o ? o->type : 0;
}

void mpr_obj_increment_version(mpr_obj o)
{
    RETURN_UNLESS(o && o->props.staged);
    ++o->version;
    o->props.synced->dirty = 1;
}

int mpr_obj_get_num_props(mpr_obj o, int staged)
{
    int len = 0;
    if (o) {
        if (o->props.synced)
            len += mpr_tbl_get_size(o->props.synced);
        if (staged && o->props.staged)
            len += mpr_tbl_get_size(o->props.staged);
    }
    return len;
}

mpr_prop mpr_obj_get_prop_by_key(mpr_obj o, const char *s, int *l, mpr_type *t,
                                 const void **v, int *p)
{
    RETURN_UNLESS(o && s, 0);
    return mpr_tbl_get_prop_by_key(o->props.synced, s, l, t, v, p);
}

mpr_prop mpr_obj_get_prop_by_idx(mpr_obj o, mpr_prop p, const char **k, int *l,
                                 mpr_type *t, const void **v, int *pub)
{
    RETURN_UNLESS(o, 0);
    return mpr_tbl_get_prop_by_idx(o->props.synced, p | o->props.mask, k, l, t,
                                   v, pub);
}

int mpr_obj_get_prop_as_int32(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && 1 == r->len, 0);
    void *v = (r->flags & INDIRECT) ? *r->val : r->val;
    switch(r->type) {
        case MPR_BOOL:
        case MPR_INT32: return *(int*)v;
        case MPR_INT64: return (int)(*(int64_t*)v);
        case MPR_FLT:   return (int)(*(float*)v);
        case MPR_DBL:   return (int)(*(double*)v);
        case MPR_TYPE:  return (int)(*(mpr_type*)v);
        default:        return 0;
    }
}

float mpr_obj_get_prop_as_flt(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && 1 == r->len, 0);
    void *v = (r->flags & INDIRECT) ? *r->val : r->val;
    switch(r->type) {
        case MPR_BOOL:
        case MPR_INT32: return (float)(*(int*)v);
        case MPR_INT64: return (float)(*(int64_t*)v);
        case MPR_FLT:   return *(float*)v;
        case MPR_DBL:   return (float)(*(double*)v);
        default:        return 0;
    }
}

const char *mpr_obj_get_prop_as_str(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && MPR_STR == r->type && 1 == r->len, 0);
    return r->flags & INDIRECT ? *r->val : r->val;
}

const void *mpr_obj_get_prop_as_ptr(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && MPR_PTR == r->type && 1 == r->len, 0);
    return r->flags & INDIRECT ? *r->val : r->val;
}

mpr_obj mpr_obj_get_prop_as_obj(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && MPR_OBJ >= r->type && 1 == r->len, 0);
    return r->flags & INDIRECT ? *r->val : r->val;
}

mpr_list mpr_obj_get_prop_as_list(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    mpr_tbl_record r = mpr_tbl_get(o->props.synced, p, s);
    RETURN_UNLESS(r && r->val && MPR_LIST == r->type && 1 == r->len, 0);
    mpr_list l = r->flags & INDIRECT ? *r->val : r->val;
    return l ? mpr_list_start(mpr_list_get_cpy(l)) : 0;
}

mpr_prop mpr_obj_set_prop(mpr_obj o, mpr_prop p, const char *s, int len,
                          mpr_type type, const void *val, int publish)
{
    RETURN_UNLESS(o, 0);
    // TODO: ensure ID property can't be changed by user code
    if (MPR_PROP_UNKNOWN == p || !MASK_PROP_BITFLAGS(p)) {
        if (!s || '@' == s[0])
            return MPR_PROP_UNKNOWN;
        p = mpr_prop_from_str(s);
    }

    // check if object represents local resource
    int local = o->props.staged ? 0 : 1;
    int flags = local ? LOCAL_MODIFY : REMOTE_MODIFY;
    if (!publish)
        flags |= LOCAL_ACCESS_ONLY;
    return mpr_tbl_set(local ? o->props.synced : o->props.staged,
                       p | o->props.mask, s, len, type, val, flags);
}

int mpr_obj_remove_prop(mpr_obj o, mpr_prop p, const char *s)
{
    RETURN_UNLESS(o, 0);
    // check if object represents local resource
    int local = o->props.staged ? 0 : 1;
    if (MPR_PROP_UNKNOWN == p)
        p = mpr_prop_from_str(s);
    if (MPR_PROP_DATA == p || local)
        return mpr_tbl_remove(o->props.synced, p, s, LOCAL_MODIFY);
    else if (MPR_PROP_EXTRA == p)
        return mpr_tbl_set(o->props.staged, p | PROP_REMOVE, s, 0, 0, 0,
                           REMOTE_MODIFY);
    return 0;
}

void mpr_obj_push(mpr_obj o)
{
    RETURN_UNLESS(o);
    mpr_net n = &o->graph->net;

    if (MPR_DEV == o->type) {
        mpr_dev d = (mpr_dev)o;
        if (d->loc) {
            mpr_net_use_subscribers(n, d, o->type);
            mpr_dev_send_state(d, MSG_DEV);
        }
        else {
            mpr_net_use_bus(n);
            mpr_dev_send_state(d, MSG_DEV_MOD);
        }
    }
    else if (o->type & MPR_SIG) {
        mpr_sig s = (mpr_sig)o;
        if (s->loc) {
            mpr_type type = ((s->dir == MPR_DIR_OUT) ? MPR_SIG_OUT : MPR_SIG_IN);
            mpr_net_use_subscribers(n, s->dev, type);
            mpr_sig_send_state(s, MSG_SIG);
        }
        else {
            mpr_net_use_bus(n);
            mpr_sig_send_state(s, MSG_SIG_MOD);
        }
    }
    else if (o->type & MPR_MAP) {
        mpr_net_use_bus(n);
        mpr_map m = (mpr_map)o;
        if (m->status >= MPR_STATUS_ACTIVE)
            mpr_map_send_state(m, -1, MSG_MAP_MOD);
        else
            mpr_map_send_state(m, -1, MSG_MAP);
    }
    else {
        trace("mpr_obj_push(): unknown object type %d\n", o->type);
        return;
    }

    // clear the staged properties
    FUNC_IF(mpr_tbl_clear, o->props.staged);
}

void mpr_obj_print(mpr_obj o, int staged)
{
    RETURN_UNLESS(o && o->props.synced);
    int i = 0, len;
    mpr_prop p;
    const char *key;
    mpr_type type;
    const void *val;

    switch (o->type) {
        case MPR_DEV:
            printf("DEVICE: ");
            mpr_prop_print(1, MPR_DEV, o);
            break;
        case MPR_SIG:
            printf("SIGNAL: ");
            mpr_prop_print(1, MPR_SIG, o);
            break;
        case MPR_MAP: {
            printf("MAP: ");
            mpr_map m = (mpr_map)o;
            if (m->num_src > 1)
                printf("[");
            mpr_list l = mpr_map_get_sigs(m, MPR_LOC_SRC);
            while (l) {
                mpr_prop_print(1, MPR_SIG, *l);
{'fraction_non_alphanumeric': 0.1444582814445828, 'fraction_numerical': 0.0086440553805582, 'mean_word_length': 2.316812439261419, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 173, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4387357', 'n_tokens_mistral': 5717, 'n_tokens_neox': 5543, 'n_words': 1167}