static tb_object_ref_t tb_object_dictionary_copy(tb_object_ref_t object) { // check tb_object_dictionary_t* dictionary = tb_object_dictionary_cast(object); tb_assert_and_check_return_val(dictionary, tb_null); // init copy tb_object_dictionary_t* copy = (tb_object_dictionary_t*)tb_object_dictionary_init(dictionary->size, dictionary->incr); tb_assert_and_check_return_val(copy, tb_null); // walk copy tb_for_all (tb_object_dictionary_item_t*, item, tb_object_dictionary_itor((tb_object_ref_t)dictionary)) { if (item && item->key) { // refn++ if (item->val) tb_object_retain(item->val); // copy tb_object_dictionary_insert((tb_object_ref_t)copy, item->key, item->val); } } // ok return (tb_object_ref_t)copy; }
static tb_void_t tb_element_obj_dupl(tb_element_ref_t element, tb_pointer_t buff, tb_cpointer_t data) { // check tb_assert_and_check_return(element && buff); // refn++ if (data) tb_object_retain((tb_object_ref_t)data); // copy it *((tb_cpointer_t*)buff) = data; }
static tb_void_t tb_element_obj_repl(tb_element_ref_t element, tb_pointer_t buff, tb_cpointer_t data) { // check tb_assert_and_check_return(element && buff); // save the previous object tb_object_ref_t object = *((tb_object_ref_t*)buff); // refn++ if (data) tb_object_retain((tb_object_ref_t)data); // copy it *((tb_cpointer_t*)buff) = data; // refn-- if (object) tb_object_exit(object); }
tb_bool_t tb_option_done(tb_option_ref_t option, tb_size_t argc, tb_char_t** argv) { // check tb_option_impl_t* impl = (tb_option_impl_t*)option; tb_assert_and_check_return_val(impl && impl->list && impl->opts, tb_false); // walk arguments tb_size_t i = 0; tb_size_t more = 0; tb_option_item_t const* item = impl->opts; tb_option_item_t const* last = tb_null; for (i = 0; i < argc; i++) { // the argument tb_char_t* p = argv[i]; tb_char_t* e = p + tb_strlen(p); tb_assert_and_check_return_val(p && p < e, tb_false); // is long key? if (p + 2 < e && p[0] == '-' && p[1] == '-' && tb_isalpha(p[2])) { // the key tb_char_t key[512] = {0}; { tb_char_t* k = key; tb_char_t* e = key + 511; for (p += 2; *p && *p != '=' && k < e; p++, k++) *k = *p; } // the val tb_char_t* val = (*p == '=')? (p + 1) : tb_null; // trace tb_trace_d("[lname]: %s => %s", key, val); // find the item tb_option_item_t const* find = tb_option_item_find(impl->opts, key, '\0'); if (find) { // check key & val if (!val == !(find->mode == TB_OPTION_MODE_KEY_VAL)) { // has value? tb_object_ref_t object = tb_null; if (val) { // init the value object switch (find->type) { case TB_OPTION_TYPE_CSTR: object = tb_oc_string_init_from_cstr(val); break; case TB_OPTION_TYPE_INTEGER: tb_assert_and_check_return_val(tb_option_is_integer(val), tb_false); object = tb_oc_number_init_from_sint64(tb_atoll(val)); break; case TB_OPTION_TYPE_BOOL: tb_assert_and_check_return_val(tb_option_is_bool(val), tb_false); object = tb_oc_boolean_init(!tb_stricmp(val, "y")? tb_true : tb_false); break; #ifdef TB_CONFIG_TYPE_HAVE_FLOAT case TB_OPTION_TYPE_FLOAT: tb_assert_and_check_return_val(tb_option_is_float(val), tb_false); object = tb_oc_number_init_from_double(tb_atof(val)); break; #endif default: tb_assert_and_check_return_val(0, tb_false); break; } } else { // check tb_assert_and_check_return_val(find->type == TB_OPTION_TYPE_BOOL, tb_false); // key => true object = tb_oc_boolean_init(tb_true); } // add the value object if (object) { tb_oc_dictionary_insert(impl->list, key, object); if (tb_isalpha(find->sname)) { tb_char_t ch[2] = {0}; ch[0] = find->sname; tb_oc_dictionary_insert(impl->list, ch, object); tb_object_retain(object); } } } else if (val) { // print tb_trace_e("%s: unrecognized option value '--%s=%s'", impl->name, key, val); // next continue ; } else { // print tb_trace_e("%s: no option value '--%s='", impl->name, key); // next continue ; } } else { // print tb_trace_e("%s: unrecognized option '--%s'", impl->name, key); // next continue ; } } // is short key? else if (p + 1 < e && p[0] == '-' && tb_isalpha(p[1])) { // the key tb_char_t key[512] = {0}; { tb_char_t* k = key; tb_char_t* e = key + 511; for (p += 1; *p && *p != '=' && k < e; p++, k++) *k = *p; } // the val tb_char_t const* val = (*p == '=')? (p + 1) : tb_null; // trace tb_trace_d("[sname]: %s => %s", key, val); // is short name? if (tb_strlen(key) != 1) { // print tb_trace_e("%s: unrecognized option '-%s'", impl->name, key); // next continue ; } // find the item tb_option_item_t const* find = tb_option_item_find(impl->opts, tb_null, key[0]); if (find) { // check key & val if (!val == !(find->mode == TB_OPTION_MODE_KEY_VAL)) { // has value? tb_object_ref_t object = tb_null; if (val) { // add value switch (find->type) { case TB_OPTION_TYPE_CSTR: object = tb_oc_string_init_from_cstr(val); break; case TB_OPTION_TYPE_INTEGER: tb_assert_and_check_return_val(tb_option_is_integer(val), tb_false); object = tb_oc_number_init_from_sint64(tb_atoll(val)); break; case TB_OPTION_TYPE_BOOL: tb_assert_and_check_return_val(tb_option_is_bool(val), tb_false); object = tb_oc_boolean_init(!tb_stricmp(val, "y")? tb_true : tb_false); break; #ifdef TB_CONFIG_TYPE_HAVE_FLOAT case TB_OPTION_TYPE_FLOAT: tb_assert_and_check_return_val(tb_option_is_float(val), tb_false); object = tb_oc_number_init_from_double(tb_atof(val)); break; #endif default: tb_assert_and_check_return_val(0, tb_false); break; } } else { // check tb_assert_and_check_return_val(find->type == TB_OPTION_TYPE_BOOL, tb_false); // key => true object = tb_oc_boolean_init(tb_true); } // add the value object if (object) { tb_oc_dictionary_insert(impl->list, key, object); if (find->lname) { tb_oc_dictionary_insert(impl->list, find->lname, object); tb_object_retain(object); } } } else if (val) { // print tb_trace_e("%s: unrecognized option value '--%s=%s'", impl->name, key, val); // next continue ; } else { // print tb_trace_e("%s: no option value '--%s='", impl->name, key); // next continue ; } } else { // print tb_trace_e("%s: unrecognized option '-%s'", impl->name, key); // next continue ; } } // is value? else { // trace tb_trace_d("[val]: %s", p); // find the value item while (item && item->mode != TB_OPTION_MODE_VAL && item->mode != TB_OPTION_MODE_END && item->mode != TB_OPTION_MODE_MORE) item++; // has value item? if (item->mode == TB_OPTION_MODE_VAL) { // check tb_assert_and_check_return_val(item->lname, tb_false); // add value switch (item->type) { case TB_OPTION_TYPE_CSTR: tb_oc_dictionary_insert(impl->list, item->lname, tb_oc_string_init_from_cstr(p)); break; case TB_OPTION_TYPE_INTEGER: tb_assert_and_check_return_val(tb_option_is_integer(p), tb_false); tb_oc_dictionary_insert(impl->list, item->lname, tb_oc_number_init_from_sint64(tb_atoll(p))); break; case TB_OPTION_TYPE_BOOL: tb_assert_and_check_return_val(tb_option_is_bool(p), tb_false); tb_oc_dictionary_insert(impl->list, item->lname, tb_oc_boolean_init(!tb_stricmp(p, "y")? tb_true : tb_false)); break; #ifdef TB_CONFIG_TYPE_HAVE_FLOAT case TB_OPTION_TYPE_FLOAT: tb_assert_and_check_return_val(tb_option_is_float(p), tb_false); tb_oc_dictionary_insert(impl->list, item->lname, tb_oc_number_init_from_double(tb_atof(p))); break; #endif default: tb_assert_and_check_return_val(0, tb_false); break; } // save last last = item; // next item item++; } // has more item? else if (item->mode == TB_OPTION_MODE_MORE && last) { // the more name tb_char_t name[64] = {0}; tb_snprintf(name, 63, "more%lu", more); // add value switch (last->type) { case TB_OPTION_TYPE_CSTR: tb_oc_dictionary_insert(impl->list, name, tb_oc_string_init_from_cstr(p)); break; case TB_OPTION_TYPE_INTEGER: tb_assert_and_check_return_val(tb_option_is_integer(p), tb_false); tb_oc_dictionary_insert(impl->list, name, tb_oc_number_init_from_sint64(tb_atoll(p))); break; case TB_OPTION_TYPE_BOOL: tb_assert_and_check_return_val(tb_option_is_bool(p), tb_false); tb_oc_dictionary_insert(impl->list, name, tb_oc_boolean_init(!tb_stricmp(p, "y")? tb_true : tb_false)); break; #ifdef TB_CONFIG_TYPE_HAVE_FLOAT case TB_OPTION_TYPE_FLOAT: tb_assert_and_check_return_val(tb_option_is_float(p), tb_false); tb_oc_dictionary_insert(impl->list, name, tb_oc_number_init_from_double(tb_atof(p))); break; #endif default: tb_assert_and_check_return_val(0, tb_false); break; } // next more more++; } } } // ok return tb_true;//tb_option_check(impl); }