示例#1
0
static tb_bool_t tb_directory_walk_impl(tb_char_t const* path, tb_bool_t recursion, tb_bool_t prefix, tb_directory_walk_func_t func, tb_cpointer_t priv)
{
    // check
    tb_assert_and_check_return_val(path && func, tb_false);

    // last
    tb_long_t       last = tb_strlen(path) - 1;
    tb_assert_and_check_return_val(last >= 0, tb_false);

    // done 
    tb_bool_t       ok = tb_true;
    tb_char_t       temp[4096] = {0};
    DIR*            directory = tb_null;
    if ((directory = opendir(path)))
    {
        // walk
        struct dirent* item = tb_null;
        while ((item = readdir(directory)))
        {
            // check
            tb_assert_and_check_continue(item->d_reclen);

            // the item name
            tb_char_t name[1024] = {0};
            tb_strncpy(name, item->d_name, tb_min(item->d_reclen, sizeof(name) - 1));
            if (tb_strcmp(name, ".") && tb_strcmp(name, ".."))
            {
                // the temp path
                tb_long_t n = tb_snprintf(temp, 4095, "%s%s%s", path, path[last] == '/'? "" : "/", name);
                if (n >= 0) temp[n] = '\0';

                // the file info
                tb_file_info_t info = {0};
                if (tb_file_info(temp, &info))
                {
                    // do callback
                    if (prefix) ok = func(temp, &info, priv);
                    tb_check_break(ok);

                    // walk to the next directory
                    if (info.type == TB_FILE_TYPE_DIRECTORY && recursion) ok = tb_directory_walk_impl(temp, recursion, prefix, func, priv);
                    tb_check_break(ok);
    
                    // do callback
                    if (!prefix) ok = func(temp, &info, priv);
                    tb_check_break(ok);
                }
            }
        }

        // exit directory
        closedir(directory);
    }

    // continue ?
    return ok;
}
示例#2
0
文件: str.c 项目: luxuan/tbox
static tb_long_t tb_element_str_comp(tb_element_ref_t element, tb_cpointer_t ldata, tb_cpointer_t rdata)
{
    // check
    tb_assert_and_check_return_val(element && ldata && rdata, 0);

    // compare it
    return element->flag? tb_strcmp((tb_char_t const*)ldata, (tb_char_t const*)rdata) : tb_stricmp((tb_char_t const*)ldata, (tb_char_t const*)rdata);
}
示例#3
0
文件: str.c 项目: siwuxian/xmake
/* //////////////////////////////////////////////////////////////////////////////////////
 * private implementation
 */
static tb_long_t tb_iterator_str_comp(tb_iterator_ref_t iterator, tb_cpointer_t litem, tb_cpointer_t ritem)
{
    // check
    tb_assert(litem && ritem);

    // compare it
    return tb_strcmp((tb_char_t const*)litem, (tb_char_t const*)ritem);
}
示例#4
0
tb_bool_t tb_ifaddrs_ipaddr(tb_ifaddrs_ref_t ifaddrs, tb_char_t const* name, tb_bool_t reload, tb_size_t family, tb_ipaddr_ref_t ipaddr)
{
    // check
    tb_assert_and_check_return_val(ifaddrs && ipaddr, tb_false);

    // clear it first
    tb_ipaddr_clear(ipaddr);

    // the iterator
    tb_iterator_ref_t iterator = tb_ifaddrs_itor(ifaddrs, reload);
    tb_assert_and_check_return_val(iterator, tb_false);

    // reload it if the cached interfaces is empty
    if (!reload && !tb_iterator_size(iterator)) iterator = tb_ifaddrs_itor(ifaddrs, tb_true);

    // the ipaddr flags
    tb_uint32_t ipflags = 0;
    if (family == TB_IPADDR_FAMILY_IPV4) ipflags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR4;
    else if (family == TB_IPADDR_FAMILY_IPV6) ipflags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR6;

    // done
    tb_bool_t ok = tb_false;
    tb_for_all_if (tb_ifaddrs_interface_ref_t, interface, iterator, interface)
    {
        // is this?
        if (    (name || !(interface->flags & TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK))
            &&  (interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR)
            &&  (!name || (interface->name && !tb_strcmp(interface->name, name))))
        {
            // ipv4?
            if (    interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR4
                &&  (!family || family == TB_IPADDR_FAMILY_IPV4))
            {
                // save ipaddr4
                tb_ipaddr_ipv4_set(ipaddr, &interface->ipaddr4);

                // ok
                ok = tb_true;
                break;
            }
            // ipv6?
            else if (    interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR6
                    &&  (!family || family == TB_IPADDR_FAMILY_IPV6))
            {
                // save ipaddr6
                tb_ipaddr_ipv6_set(ipaddr, &interface->ipaddr6);

                // ok
                ok = tb_true;
                break;
            }
        }
    }

    // ok?
    return ok;
}
示例#5
0
tb_bool_t tb_ifaddrs_hwaddr(tb_ifaddrs_ref_t ifaddrs, tb_char_t const* name, tb_bool_t reload, tb_hwaddr_ref_t hwaddr)
{
    // check
    tb_assert_and_check_return_val(ifaddrs && hwaddr, tb_false);

    // clear it first
    tb_hwaddr_clear(hwaddr);

    // the iterator
    tb_iterator_ref_t iterator = tb_ifaddrs_itor(ifaddrs, reload);
    tb_assert_and_check_return_val(iterator, tb_false);

    // reload it if the cached interfaces is empty
    if (!reload && !tb_iterator_size(iterator)) iterator = tb_ifaddrs_itor(ifaddrs, tb_true);

    // done
    tb_bool_t ok = tb_false;
    tb_for_all_if (tb_ifaddrs_interface_ref_t, interface, iterator, interface)
    {
        // get hwaddr from the given interface name?
        if (name)
        {
            // is this?
            if (    (interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR)
                &&  (interface->name && !tb_strcmp(interface->name, name)))
            {
                // save hwaddr
                tb_hwaddr_copy(hwaddr, &interface->hwaddr);

                // ok
                ok = tb_true;
                break;
            }
        }
        else
        {
            // is this?
            if (    (interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR)
                &&  (interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR)
                &&  !(interface->flags & TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK))
            {
                // save hwaddr
                tb_hwaddr_copy(hwaddr, &interface->hwaddr);

                // ok
                ok = tb_true;
                break;
            }
        }
    }

    // ok?
    return ok;
}
示例#6
0
/* //////////////////////////////////////////////////////////////////////////////////////
 * compare
 */
static tb_void_t tb_test_strcmp(tb_char_t const* s1, tb_char_t const* s2)
{
    __tb_volatile__ tb_long_t   n = 1000000;
    __tb_volatile__ tb_long_t   r = 0;
    tb_hong_t t = tb_mclock();
    while (n--)
    {
        r = tb_strcmp(s1, s2);
    }
    t = tb_mclock() - t;
    tb_printf("%lld ms, tb_test_strcmp(%s, %s) = %ld\n", t, s1, s2, r);
}
示例#7
0
文件: option.c 项目: waruqi/tbox
static __tb_inline__ tb_option_item_t const* tb_option_item_find(tb_option_item_t const* opts, tb_char_t const* lname, tb_char_t sname)
{
    // check
    tb_assert_and_check_return_val(opts, tb_null);

    // walk
    tb_bool_t                   ok = tb_false;
    tb_option_item_t const*     item = opts;
    while (item && !ok)
    {
        switch (item->mode)
        {
        case TB_OPTION_MODE_KEY:
        case TB_OPTION_MODE_KEY_VAL:
            {
                // find lname
                if (item->lname && lname && !tb_strcmp(lname, item->lname)) 
                {
                    ok = tb_true;
                    break;
                }

                // find sname
                if (item->sname && sname && (sname == item->sname) && (sname != '-')) 
                {
                    ok = tb_true;
                    break;
                }

                // next
                item++;
            }
            break;
        case TB_OPTION_MODE_VAL:
            item++;
            break;
        case TB_OPTION_MODE_MORE:
        case TB_OPTION_MODE_END:
        default:
            item = tb_null;
            break;
        }
    }

    // ok?
    return ok? item : tb_null;
}
示例#8
0
文件: sort.c 项目: richwu/tbox
static tb_void_t tb_sort_str_test_perf_heap(tb_size_t n)
{
    __tb_volatile__ tb_size_t i = 0;

    // init data
    tb_char_t** data = (tb_char_t**)tb_nalloc0(n, sizeof(tb_char_t*));
    tb_assert_and_check_return(data);

    // init iterator
    tb_array_iterator_t array_iterator;
    tb_iterator_ref_t   iterator = tb_iterator_make_for_str(&array_iterator, data, n);

    // make
    tb_random_clear(tb_null);
    tb_char_t s[256] = {0};
    for (i = 0; i < n; i++)
    {
        tb_long_t r = tb_snprintf(s, 256, "%x", tb_random_range(tb_null, 0, TB_MAXU32));
        s[r] = '\0';
        data[i] = tb_strdup(s);
    }

    // sort
    tb_hong_t time = tb_mclock();
    tb_heap_sort_all(iterator, tb_null);
    time = tb_mclock() - time;

    // time
    tb_trace_i("tb_heap_sort_str_all: %lld ms", time);

    // check
    for (i = 1; i < n; i++) tb_assert_and_check_break(tb_strcmp(data[i - 1], data[i]) <= 0);

    // free data
    for (i = 0; i < n; i++) tb_free(data[i]);
    tb_free(data);
}
示例#9
0
文件: find.c 项目: JamesLinus/xmake
/* //////////////////////////////////////////////////////////////////////////////////////
 * private implementation
 */
static tb_bool_t xm_os_find_walk(tb_char_t const* path, tb_file_info_t const* info, tb_cpointer_t priv)
{
    // check
    tb_value_ref_t tuple = (tb_value_ref_t)priv;
    tb_assert_and_check_return_val(path && info && tuple, tb_false);

    // the lua
    lua_State* lua = (lua_State*)tuple[0].ptr;
    tb_assert_and_check_return_val(lua, tb_false);

    // the pattern
    tb_char_t const* pattern = (tb_char_t const*)tuple[1].cstr;
    tb_assert_and_check_return_val(pattern, tb_false);

    // find directory?
    tb_bool_t findir = tuple[2].b;

    // the count
    tb_size_t* pcount = &(tuple[3].ul);

    // trace
    tb_trace_d("path[%c]: %s", info->type == TB_FILE_TYPE_DIRECTORY? 'd' : 'f', path);

    // find file or directory?
    if ((findir && info->type == TB_FILE_TYPE_DIRECTORY) || (!findir && info->type == TB_FILE_TYPE_FILE))
    {
        // done path:match(pattern)
        lua_getfield(lua, -1, "match");
        lua_pushstring(lua, path);
        lua_pushstring(lua, pattern);
        if (lua_pcall(lua, 2, 1, 0)) 
        {
            // trace
            tb_printf("error: call string.match(%s, %s) failed: %s!\n", path, pattern, lua_tostring(lua, -1));

            // failed
            return tb_false;
        }

        // match ok? 
        if (lua_isstring(lua, -1) && !tb_strcmp(path, lua_tostring(lua, -1)))
        {
            // exists excludes?
            tb_bool_t excluded = tb_false;
            if (lua_istable(lua, 5))
            {
                // the root directory
                size_t              rootlen = 0;
                tb_char_t const*    rootdir = luaL_checklstring(lua, 1, &rootlen);
                tb_assert_and_check_return_val(rootdir && rootlen, tb_false);

                // check
                tb_assert(!tb_strcmp(path, rootdir));
                tb_assert(rootlen + 1 <= tb_strlen(path));

                // skip the rootdir 
                path += rootlen + 1;

                // exclude pathes
                tb_size_t i = 0;
                tb_size_t count = luaL_getn(lua, 5);
                for (i = 0; i < count && !excluded; i++)
                {
                    // get exclude
                    lua_rawgeti(lua, 5, i + 1);
                    tb_char_t const* exclude = lua_tostring(lua, -1);
                    if (exclude) 
                    {
                        // done path:match(exclude)
                        lua_getfield(lua, -3, "match");
                        lua_pushstring(lua, path);
                        lua_pushstring(lua, exclude);
                        if (lua_pcall(lua, 2, 1, 0)) 
                        {
                            // trace
                            tb_printf("error: call string.match(%s, %s) failed: %s!\n", path, exclude, lua_tostring(lua, -1));
                        }

                        // matched?
                        excluded = lua_isstring(lua, -1) && !tb_strcmp(path, lua_tostring(lua, -1));

                        // pop the match result
                        lua_pop(lua, 1);
                    }

                    // pop exclude
                    lua_pop(lua, 1);
                }
            }

            // save this path
            if (!excluded) lua_rawseti(lua, -3, ++*pcount);
            // pop this return value
            else lua_pop(lua, 1);
        }
        // pop this return value
        else lua_pop(lua, 1);
    }

    // continue 
    return tb_true;
}
示例#10
0
文件: find.c 项目: waruqi/xmake
/* //////////////////////////////////////////////////////////////////////////////////////
 * private implementation
 */
static tb_bool_t xm_os_find_walk(tb_char_t const* path, tb_file_info_t const* info, tb_cpointer_t priv)
{
    // check
    tb_value_ref_t tuple = (tb_value_ref_t)priv;
    tb_assert_and_check_return_val(path && info && tuple, tb_false);

    // the lua
    lua_State* lua = (lua_State*)tuple[0].ptr;
    tb_assert_and_check_return_val(lua, tb_false);

    // the pattern
    tb_char_t const* pattern = (tb_char_t const*)tuple[1].cstr;
    tb_assert_and_check_return_val(pattern, tb_false);

    // remove ./ for path 
    if (path[0] == '.' && (path[1] == '/' || path[1] == '\\'))
        path = path + 2;

    // the match mode
    tb_long_t mode = tuple[2].l;

    // the count
    tb_size_t* pcount = &(tuple[3].ul);

    // trace
    tb_trace_d("path[%c]: %s", info->type == TB_FILE_TYPE_DIRECTORY? 'd' : 'f', path);

    // find file or directory?
    tb_size_t match = (mode == 1)? TB_FILE_TYPE_DIRECTORY : ((mode == 0)? TB_FILE_TYPE_FILE : (TB_FILE_TYPE_FILE | TB_FILE_TYPE_DIRECTORY));
    if (info->type & match)
    {
        // done path:match(pattern)
        lua_getfield(lua, -1, "match");
        lua_pushstring(lua, path);
        lua_pushstring(lua, pattern);
        if (lua_pcall(lua, 2, 1, 0)) 
        {
            // trace
            tb_printf("error: call string.match(%s, %s) failed: %s!\n", path, pattern, lua_tostring(lua, -1));

            // failed
            return tb_false;
        }

        // match ok? 
        if (lua_isstring(lua, -1) && !tb_strcmp(path, lua_tostring(lua, -1)))
        {
            // exists excludes?
            tb_bool_t excluded = tb_false;
            if (lua_istable(lua, 5))
            {
                // the root directory
                size_t              rootlen = 0;
                tb_char_t const*    rootdir = luaL_checklstring(lua, 1, &rootlen);
                tb_assert_and_check_return_val(rootdir && rootlen, tb_false);

                // check
                tb_assert(!tb_strcmp(path, rootdir));
                tb_assert(rootlen + 1 <= tb_strlen(path));

                // skip the rootdir if not "."
                if (tb_strcmp(rootdir, "."))
                    path += rootlen + 1;

                // exclude pathes
                tb_int_t i = 0;
                tb_int_t count = (tb_int_t)lua_objlen(lua, 5);
                for (i = 0; i < count && !excluded; i++)
                {
                    // get exclude
                    lua_rawgeti(lua, 5, i + 1);
                    tb_char_t const* exclude = lua_tostring(lua, -1);
                    if (exclude) 
                    {
                        // done path:match(exclude)
                        lua_getfield(lua, -3, "match");
                        lua_pushstring(lua, path);
                        lua_pushstring(lua, exclude);
                        if (lua_pcall(lua, 2, 1, 0)) 
                        {
                            // trace
                            tb_printf("error: call string.match(%s, %s) failed: %s!\n", path, exclude, lua_tostring(lua, -1));
                        }

                        // matched?
                        excluded = lua_isstring(lua, -1) && !tb_strcmp(path, lua_tostring(lua, -1));

                        // pop the match result
                        lua_pop(lua, 1);
                    }

                    // pop exclude
                    lua_pop(lua, 1);
                }
            }

            // does not exclude this path?
            if (!excluded)
            {
                // save it
                lua_rawseti(lua, -3, (tb_int_t)(++*pcount));

                // do callback function
                if (lua_isfunction(lua, 6))
                {
                    // do callback(path, isdir)
                    lua_pushvalue(lua, 6);
                    lua_pushstring(lua, path);
                    lua_pushboolean(lua, info->type == TB_FILE_TYPE_DIRECTORY);
                    lua_call(lua, 2, 1);

                    // is continue?
                    tb_bool_t is_continue = lua_toboolean(lua, -1);
                    lua_pop(lua, 1);
                    if (!is_continue) return tb_false;
                }
            }
            // pop this return value
            else lua_pop(lua, 1);
        }
        // pop this return value
        else lua_pop(lua, 1);
    }

    // continue 
    return tb_true;
}
示例#11
0
文件: select.c 项目: waruqi/xmake
/* select version
 *
 * local versioninfo, errors = semver.select(">=1.5.0 <1.6", {"1.5.0", "1.5.1"}, {"v1.5.0", ..}, {"lastest", "dev"})
 */
tb_int_t xm_semver_select(lua_State* lua)
{
    // check
    tb_assert_and_check_return_val(lua, 0);

    // select version
    tb_bool_t ok               = tb_false;
    tb_bool_t is_range         = tb_false;
    tb_char_t const* range_str = tb_null;
    semver_t semver            = {0};
    semvers_t matches          = {0};
    semver_range_t range       = {0};
    do
    {
        // get the version range string
        range_str = luaL_checkstring(lua, 1);
        tb_check_break(range_str);

        // get the range string length
        tb_size_t range_len = tb_strlen(range_str);

        // parse the version range string
        is_range = semver_rangen(&range, range_str, range_len) == 0;
        if (is_range) 
        {
            // attempt to select version from the versions list first
            if (xm_semver_select_from_versions_tags(lua, 2, &semver, &range, &matches)) 
            {
                ok = tb_true;
                break;
            }

            // attempt to select version from the tags list
            if (xm_semver_select_from_versions_tags(lua, 3, &semver, &range, &matches)) 
            {
                ok = tb_true;
                break;
            }
        }

        // attempt to select version from the branches
        if (xm_semver_select_from_branches(lua, 4, range_str, range_len))
        {
            ok = tb_true;
            break;
        }

        // select the lastest version from the tags and versions if be lastest
        if (!tb_strcmp(range_str, "lastest"))
        {
            // attempt to select lastest version from the versions list
            if (xm_semver_select_lastest_from_versions_tags(lua, 2, &semver, &matches)) 
            {
                ok = tb_true;
                break;
            }

            // attempt to select lastest version from the tags list
            if (xm_semver_select_lastest_from_versions_tags(lua, 3, &semver, &matches)) 
            {
                ok = tb_true;
                break;
            }
        }

    } while (0);

    // exit matches
    semvers_dtor(matches);

    // exit range
    semver_range_dtor(&range);

    // failed?
    if (!ok) 
    {
        if (!is_range) 
        {
            lua_pushnil(lua);
            lua_pushfstring(lua, "unable to parse semver range '%s'", range_str);
        }

        lua_pushnil(lua);
        lua_pushfstring(lua, "unable to select version for range '%s'", range_str);
        return 2;
    }
    
    // ok
    return 1;
}