static tb_object_ref_t tb_oc_number_copy(tb_object_ref_t object) { // check tb_oc_number_t* number = (tb_oc_number_t*)object; tb_assert_and_check_return_val(number, tb_null); // copy switch (number->type) { case TB_OC_NUMBER_TYPE_UINT64: return tb_oc_number_init_from_uint64(number->v.u64); case TB_OC_NUMBER_TYPE_SINT64: return tb_oc_number_init_from_sint64(number->v.s64); case TB_OC_NUMBER_TYPE_UINT32: return tb_oc_number_init_from_uint32(number->v.u32); case TB_OC_NUMBER_TYPE_SINT32: return tb_oc_number_init_from_sint32(number->v.s32); case TB_OC_NUMBER_TYPE_UINT16: return tb_oc_number_init_from_uint16(number->v.u16); case TB_OC_NUMBER_TYPE_SINT16: return tb_oc_number_init_from_sint16(number->v.s16); case TB_OC_NUMBER_TYPE_UINT8: return tb_oc_number_init_from_uint8(number->v.u8); case TB_OC_NUMBER_TYPE_SINT8: return tb_oc_number_init_from_sint8(number->v.s8); #ifdef TB_CONFIG_TYPE_HAVE_FLOAT case TB_OC_NUMBER_TYPE_FLOAT: return tb_oc_number_init_from_float(number->v.f); case TB_OC_NUMBER_TYPE_DOUBLE: return tb_oc_number_init_from_double(number->v.d); #endif default: break; } return tb_null; }
static tb_object_ref_t tb_oc_xplist_reader_func_number(tb_oc_xplist_reader_t* reader, tb_size_t event) { // check tb_assert_and_check_return_val(reader && reader->reader && event, tb_null); // empty? if (event == TB_XML_READER_EVENT_ELEMENT_EMPTY) return tb_oc_number_init_from_uint32(0); // done tb_bool_t leave = tb_false; tb_object_ref_t number = tb_null; while (!leave && (event = tb_xml_reader_next(reader->reader))) { switch (event) { case TB_XML_READER_EVENT_ELEMENT_END: { // name tb_char_t const* name = tb_xml_reader_element(reader->reader); tb_assert_and_check_break_state(name, leave, tb_true); // is end? if (!tb_stricmp(name, "integer") || !tb_stricmp(name, "real")) leave = tb_true; } break; case TB_XML_READER_EVENT_TEXT: { // text tb_char_t const* text = tb_xml_reader_text(reader->reader); tb_assert_and_check_break_state(text, leave, tb_true); tb_trace_d("number: %s", text); // has sign? is float? tb_size_t s = 0; tb_size_t f = 0; tb_char_t const* p = text; for (; *p; p++) { if (!s && *p == '-') s = 1; if (!f && *p == '.') f = 1; if (s && f) break; } // number #ifdef TB_CONFIG_TYPE_HAVE_FLOAT if (f) number = tb_oc_number_init_from_double(tb_atof(text)); #else if (f) tb_trace_noimpl(); #endif else number = s? tb_oc_number_init_from_sint64(tb_stoi64(text)) : tb_oc_number_init_from_uint64(tb_stou64(text)); tb_assert_and_check_break_state(number, leave, tb_true); } break; default: break; } } // ok? return number; }
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); }