当前位置: 首页>>代码示例>>C++>>正文


C++ crm_is_true函数代码示例

本文整理汇总了C++中crm_is_true函数的典型用法代码示例。如果您正苦于以下问题:C++ crm_is_true函数的具体用法?C++ crm_is_true怎么用?C++ crm_is_true使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了crm_is_true函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: can_interleave_actions

bool can_interleave_actions(pe_action_t *first, pe_action_t *then) 
{
    bool interleave = FALSE;
    resource_t *rsc = NULL;
    const char *interleave_s = NULL;

    if(first->rsc == NULL || then->rsc == NULL) {
        crm_trace("Not interleaving %s with %s (both must be resources)", first->uuid, then->uuid);
        return FALSE;
    } else if(first->rsc == then->rsc) {
        crm_trace("Not interleaving %s with %s (must belong to different resources)", first->uuid, then->uuid);
        return FALSE;
    } else if(first->rsc->variant < pe_clone || then->rsc->variant < pe_clone) {
        crm_trace("Not interleaving %s with %s (both sides must be clones, masters, or bundles)", first->uuid, then->uuid);
        return FALSE;
    }

    if (crm_ends_with(then->uuid, "_stop_0") || crm_ends_with(then->uuid, "_demote_0")) {
        rsc = first->rsc;
    } else {
        rsc = then->rsc;
    }

    interleave_s = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_INTERLEAVE);
    interleave = crm_is_true(interleave_s);
    crm_trace("Interleave %s -> %s: %s (based on %s)",
              first->uuid, then->uuid, interleave ? "yes" : "no", rsc->id);

    return interleave;
}
开发者ID:beekhof,项目名称:pacemaker,代码行数:30,代码来源:container.c

示例2: pcmk_process_exit

static void
pcmk_process_exit(pcmk_child_t * child)
{
    child->pid = 0;
    child->active_before_startup = FALSE;

    /* Broadcast the fact that one of our processes died ASAP
     *
     * Try to get some logging of the cause out first though
     * because we're probably about to get fenced
     *
     * Potentially do this only if respawn_count > N
     * to allow for local recovery
     */
    update_node_processes(local_nodeid, NULL, get_process_list());

    child->respawn_count += 1;
    if (child->respawn_count > MAX_RESPAWN) {
        crm_err("Child respawn count exceeded by %s", child->name);
        child->respawn = FALSE;
    }

    if (shutdown_trigger) {
        mainloop_set_trigger(shutdown_trigger);
        update_node_processes(local_nodeid, NULL, get_process_list());

    } else if (child->respawn && crm_is_true(getenv("PCMK_fail_fast"))) {
        crm_err("Rebooting system because of %s", child->name);
        pcmk_panic(__FUNCTION__);

    } else if (child->respawn) {
        crm_notice("Respawning failed child process: %s", child->name);
        start_child(child);
    }
}
开发者ID:roidelapluie,项目名称:pacemaker,代码行数:35,代码来源:pacemaker.c

示例3: update_dc_expected

/*!
 * \internal
 * \brief Remember if DC is shutting down as we join
 *
 * If we're joining while the current DC is shutting down, update its expected
 * state, so we don't fence it if we become the new DC. (We weren't a peer
 * when it broadcast its shutdown request.)
 *
 * \param[in] msg  A join message from the DC
 */
static void
update_dc_expected(xmlNode *msg)
{
    if (fsa_our_dc && crm_is_true(crm_element_value(msg, F_CRM_DC_LEAVING))) {
        crm_node_t *dc_node = crm_get_peer(0, fsa_our_dc);

        crm_update_peer_expected(__FUNCTION__, dc_node, CRMD_JOINSTATE_DOWN);
    }
}
开发者ID:bubble75,项目名称:pacemaker,代码行数:19,代码来源:join_client.c

示例4: cluster_status

/*
 * Unpack everything
 * At the end you'll have:
 *  - A list of nodes
 *  - A list of resources (each with any dependencies on other resources)
 *  - A list of constraints between resources and nodes
 *  - A list of constraints between start/stop actions
 *  - A list of nodes that need to be stonith'd
 *  - A list of nodes that need to be shutdown
 *  - A list of the possible stop/start actions (without dependencies)
 */
gboolean
cluster_status(pe_working_set_t *data_set)
{
	xmlNode * config          = get_object_root(
		XML_CIB_TAG_CRMCONFIG,   data_set->input);
	xmlNode * cib_nodes       = get_object_root(
		XML_CIB_TAG_NODES,       data_set->input);
	xmlNode * cib_resources   = get_object_root(
		XML_CIB_TAG_RESOURCES,   data_set->input);
	xmlNode * cib_status      = get_object_root(
		XML_CIB_TAG_STATUS,      data_set->input);
 	const char *value = crm_element_value(
		data_set->input, XML_ATTR_HAVE_QUORUM);
	
	crm_debug_3("Beginning unpack");
	
	/* reset remaining global variables */
	
	if(data_set->input == NULL) {
		return FALSE;
	}

	if(data_set->now == NULL) {
	    data_set->now = new_ha_date(TRUE);
	}
	
	if(data_set->input != NULL
	   && crm_element_value(data_set->input, XML_ATTR_DC_UUID) != NULL) {
		/* this should always be present */
		data_set->dc_uuid = crm_element_value_copy(
			data_set->input, XML_ATTR_DC_UUID);
	}	
	
	clear_bit_inplace(data_set->flags, pe_flag_have_quorum);
	if(crm_is_true(value)) {
	    set_bit_inplace(data_set->flags, pe_flag_have_quorum);
	}

	data_set->op_defaults = get_object_root(XML_CIB_TAG_OPCONFIG, data_set->input);
	data_set->rsc_defaults = get_object_root(XML_CIB_TAG_RSCCONFIG, data_set->input);

 	unpack_config(config, data_set);
	
	if(is_set(data_set->flags, pe_flag_have_quorum) == FALSE
	   && data_set->no_quorum_policy != no_quorum_ignore) {
		crm_warn("We do not have quorum"
			 " - fencing and resource management disabled");
	}
	
 	unpack_nodes(cib_nodes, data_set);
 	unpack_resources(cib_resources, data_set);
 	unpack_status(cib_status, data_set);
	
	return TRUE;
}
开发者ID:ClusterLabs,项目名称:pacemaker-1.0,代码行数:66,代码来源:status.c

示例5: te_crm_command

static gboolean
te_crm_command(crm_graph_t *graph, crm_action_t *action)
{
	char *value = NULL;
	char *counter = NULL;
	HA_Message *cmd = NULL;		

	const char *id = NULL;
	const char *task = NULL;
	const char *on_node = NULL;

	gboolean ret = TRUE;

	id      = ID(action->xml);
	task    = crm_element_value(action->xml, XML_LRM_ATTR_TASK);
	on_node = crm_element_value(action->xml, XML_LRM_ATTR_TARGET);

	CRM_CHECK(on_node != NULL && strlen(on_node) != 0,
		  te_log_action(LOG_ERR, "Corrupted command (id=%s) %s: no node",
				crm_str(id), crm_str(task));
		  return FALSE);
	
	te_log_action(LOG_INFO, "Executing crm-event (%s): %s on %s",
		      crm_str(id), crm_str(task), on_node);
	
	cmd = create_request(task, NULL, on_node, CRM_SYSTEM_CRMD,
			     CRM_SYSTEM_TENGINE, NULL);
	
	counter = generate_transition_key(
		transition_graph->id, action->id, te_uuid);
	crm_xml_add(cmd, XML_ATTR_TRANSITION_KEY, counter);
	ret = send_ipc_message(crm_ch, cmd);
	crm_free(counter);
	crm_msg_del(cmd);
	
	value = g_hash_table_lookup(action->params, crm_meta_name(XML_ATTR_TE_NOWAIT));
	if(ret == FALSE) {
		crm_err("Action %d failed: send", action->id);
		return FALSE;
		
	} else if(crm_is_true(value)) {
		crm_info("Skipping wait for %d", action->id);
		action->confirmed = TRUE;
		update_graph(graph, action);
		trigger_graph();
		
	} else if(ret && action->timeout > 0) {
		crm_debug("Setting timer for action %d",action->id);
		action->timer->reason = timeout_action_warn;
		te_start_action_timer(action);
	}
	
	return TRUE;
}
开发者ID:sipwise,项目名称:heartbeat,代码行数:54,代码来源:actions.c

示例6: remote_state_from_cib

/*!
 * \internal
 * \brief Return node status based on a CIB status entry
 *
 * \param[in] node_state  XML of node state
 *
 * \return CRM_NODE_LOST if XML_NODE_IN_CLUSTER is false in node_state,
 *         CRM_NODE_MEMBER otherwise
 * \note Unlike most boolean XML attributes, this one defaults to true, for
 *       backward compatibility with older controllers that don't set it.
 */
static const char *
remote_state_from_cib(xmlNode *node_state)
{
    const char *status;

    status = crm_element_value(node_state, XML_NODE_IN_CLUSTER);
    if (status && !crm_is_true(status)) {
        status = CRM_NODE_LOST;
    } else {
        status = CRM_NODE_MEMBER;
    }
    return status;
}
开发者ID:dvance,项目名称:pacemaker,代码行数:24,代码来源:membership.c

示例7: uname_is_uuid

static gboolean uname_is_uuid(void) 
{
    static const char *uuid_pref = NULL;

    if(uuid_pref == NULL) {
        uuid_pref = getenv("PCMK_uname_is_uuid");
    }

    if(uuid_pref == NULL) {
        /* true is legacy mode */
        uuid_pref = "false";
    }

    return crm_is_true(uuid_pref);
}
开发者ID:smellman,项目名称:pacemaker,代码行数:15,代码来源:cluster.c

示例8: group_create_actions

void
group_create_actions(resource_t * rsc, pe_working_set_t * data_set)
{
    action_t *op = NULL;
    const char *value = NULL;
    GListPtr gIter = rsc->children;

    crm_debug_2("Creating actions for %s", rsc->id);

    for (; gIter != NULL; gIter = gIter->next) {
        resource_t *child_rsc = (resource_t *) gIter->data;

        child_rsc->cmds->create_actions(child_rsc, data_set);
        group_update_pseudo_status(rsc, child_rsc);
    }

    op = start_action(rsc, NULL, TRUE /* !group_data->child_starting */ );
    set_bit_inplace(op->flags, pe_action_pseudo | pe_action_runnable);

    op = custom_action(rsc, started_key(rsc),
                       RSC_STARTED, NULL, TRUE /* !group_data->child_starting */ , TRUE, data_set);
    set_bit_inplace(op->flags, pe_action_pseudo | pe_action_runnable);

    op = stop_action(rsc, NULL, TRUE /* !group_data->child_stopping */ );
    set_bit_inplace(op->flags, pe_action_pseudo | pe_action_runnable);

    op = custom_action(rsc, stopped_key(rsc),
                       RSC_STOPPED, NULL, TRUE /* !group_data->child_stopping */ , TRUE, data_set);
    set_bit_inplace(op->flags, pe_action_pseudo | pe_action_runnable);

    value = g_hash_table_lookup(rsc->meta, "stateful");
    if (crm_is_true(value)) {
        op = custom_action(rsc, demote_key(rsc), RSC_DEMOTE, NULL, TRUE, TRUE, data_set);
        set_bit_inplace(op->flags, pe_action_pseudo);
        set_bit_inplace(op->flags, pe_action_runnable);
        op = custom_action(rsc, demoted_key(rsc), RSC_DEMOTED, NULL, TRUE, TRUE, data_set);
        set_bit_inplace(op->flags, pe_action_pseudo);
        set_bit_inplace(op->flags, pe_action_runnable);

        op = custom_action(rsc, promote_key(rsc), RSC_PROMOTE, NULL, TRUE, TRUE, data_set);
        set_bit_inplace(op->flags, pe_action_pseudo);
        set_bit_inplace(op->flags, pe_action_runnable);
        op = custom_action(rsc, promoted_key(rsc), RSC_PROMOTED, NULL, TRUE, TRUE, data_set);
        set_bit_inplace(op->flags, pe_action_pseudo);
        set_bit_inplace(op->flags, pe_action_runnable);
    }
}
开发者ID:fghaas,项目名称:pacemaker,代码行数:47,代码来源:group.c

示例9: handle_remote_state

/*!
 * \brief Handle a CRM_OP_REMOTE_STATE message by updating remote peer cache
 *
 * \param[in] msg  Message XML
 *
 * \return Next FSA input
 */
static enum crmd_fsa_input
handle_remote_state(xmlNode *msg)
{
    const char *remote_uname = ID(msg);
    const char *remote_is_up = crm_element_value(msg, XML_NODE_IN_CLUSTER);
    crm_node_t *remote_peer;

    CRM_CHECK(remote_uname && remote_is_up, return I_NULL);

    remote_peer = crm_remote_peer_get(remote_uname);
    CRM_CHECK(remote_peer, return I_NULL);

    crm_update_peer_state(__FUNCTION__, remote_peer,
                          crm_is_true(remote_is_up)?
                          CRM_NODE_MEMBER : CRM_NODE_LOST, 0);
    return I_NULL;
}
开发者ID:miz-take,项目名称:pacemaker,代码行数:24,代码来源:messages.c

示例10: cib_new

cib_t *
cib_new(void)
{
    const char *value = getenv("CIB_shadow");

    if (value && value[0] != 0) {
        return cib_shadow_new(value);
    }

    value = getenv("CIB_file");
    if (value) {
        return cib_file_new(value);
    }

    value = getenv("CIB_port");
    if (value) {
        gboolean encrypted = TRUE;
        int port = crm_parse_int(value, NULL);
        const char *server = getenv("CIB_server");
        const char *user = getenv("CIB_user");
        const char *pass = getenv("CIB_passwd");

        value = getenv("CIB_encrypted");
        if (value && crm_is_true(value) == FALSE) {
            crm_info("Disabling TLS");
            encrypted = FALSE;
        }

        if (user == NULL) {
            user = CRM_DAEMON_USER;
            crm_info("Defaulting to user: %s", user);
        }

        if (server == NULL) {
            server = "localhost";
            crm_info("Defaulting to localhost");
        }

        return cib_remote_new(server, user, pass, port, encrypted);
    }

    return cib_native_new();
}
开发者ID:ClusterLabs,项目名称:pacemaker,代码行数:43,代码来源:cib_client.c

示例11: cib_prepare_diff

static int
cib_prepare_diff(xmlNode * request, xmlNode ** data, const char **section)
{
    xmlNode *input_fragment = NULL;
    const char *update = crm_element_value(request, F_CIB_GLOBAL_UPDATE);

    *data = NULL;
    *section = NULL;

    if (crm_is_true(update)) {
        input_fragment = get_message_xml(request, F_CIB_UPDATE_DIFF);

    } else {
        input_fragment = get_message_xml(request, F_CIB_CALLDATA);
    }

    CRM_CHECK(input_fragment != NULL, crm_log_xml_warn(request, "no input"));
    *data = cib_prepare_common(input_fragment, NULL);
    return pcmk_ok;
}
开发者ID:JamesGuthrie,项目名称:pacemaker,代码行数:20,代码来源:common.c

示例12: is_node_online

gboolean
is_node_online(xmlNode * node_state)
{
    const char *uname = crm_element_value(node_state, XML_ATTR_UNAME);
    const char *join_state = crm_element_value(node_state, XML_NODE_JOIN_STATE);
    const char *exp_state = crm_element_value(node_state, XML_NODE_EXPECTED);
    const char *crm_state = crm_element_value(node_state, XML_NODE_IS_PEER);
    const char *ccm_state = crm_element_value(node_state, XML_NODE_IN_CLUSTER);

    if (safe_str_neq(join_state, CRMD_JOINSTATE_DOWN)
        && crm_is_true(ccm_state)
        && safe_str_eq(crm_state, "online")) {
        crm_trace("Node %s is online", uname);
        return TRUE;
    }
    crm_trace("Node %s: ccm=%s join=%s exp=%s crm=%s",
                uname, crm_str(ccm_state),
                crm_str(join_state), crm_str(exp_state), crm_str(crm_state));
    crm_trace("Node %s is offline", uname);
    return FALSE;
}
开发者ID:Xarthisius,项目名称:pacemaker,代码行数:21,代码来源:crmadmin.c

示例13: is_node_online

gboolean
is_node_online(xmlNode * node_state)
{
    const char *uname = crm_element_value(node_state, XML_ATTR_UNAME);
    const char *join_state = crm_element_value(node_state, XML_CIB_ATTR_JOINSTATE);
    const char *exp_state = crm_element_value(node_state, XML_CIB_ATTR_EXPSTATE);
    const char *crm_state = crm_element_value(node_state, XML_CIB_ATTR_CRMDSTATE);
    const char *ha_state = crm_element_value(node_state, XML_CIB_ATTR_HASTATE);
    const char *ccm_state = crm_element_value(node_state, XML_CIB_ATTR_INCCM);

    if (safe_str_neq(join_state, CRMD_JOINSTATE_DOWN)
        && (ha_state == NULL || safe_str_eq(ha_state, "active"))
        && crm_is_true(ccm_state)
        && safe_str_eq(crm_state, "online")) {
        crm_trace("Node %s is online", uname);
        return TRUE;
    }
    crm_trace("Node %s: ha=%s ccm=%s join=%s exp=%s crm=%s",
                uname, crm_str(ha_state), crm_str(ccm_state),
                crm_str(join_state), crm_str(exp_state), crm_str(crm_state));
    crm_trace("Node %s is offline", uname);
    return FALSE;
}
开发者ID:esimone74,项目名称:pacemaker,代码行数:23,代码来源:crmadmin.c

示例14: read_config

gboolean
read_config(void)
{
    int rc = CS_OK;
    int retries = 0;
    gboolean have_log = FALSE;

    char *logging_debug = NULL;
    char *logging_logfile = NULL;
    char *logging_to_logfile = NULL;
    char *logging_to_syslog = NULL;
    char *logging_syslog_facility = NULL;    

    enum cluster_type_e stack = pcmk_cluster_unknown;

#if HAVE_CONFDB
    char *value = NULL;
    confdb_handle_t config;
    confdb_handle_t top_handle = 0;
    hdb_handle_t local_handle;
    static confdb_callbacks_t callbacks = { };

    do {
        rc = confdb_initialize(&config, &callbacks);
	if(rc < 0) {
	    retries++;
	    printf("Connection setup failed: %d.  Retrying in %ds\n", rc, retries);
	    sleep(retries);

	} else {
            break;
        }

    } while(retries < 5);
#elif HAVE_CMAP
    cmap_handle_t local_handle;

    /* There can be only one (possibility if confdb isn't around) */
    do {
        rc = cmap_initialize(&local_handle);
	if(rc < 0) {
	    retries++;
	    printf("Connection setup failed: %s.  Retrying in %ds\n",
                   cs_strerror(rc), retries);
	    sleep(retries);

	} else {
            break;
        }

    } while(retries < 5);
#endif

    if (rc != CS_OK) {
        printf("Could not initialize Cluster Configuration Database API instance, error %d\n", rc);
        return FALSE;
    }

    stack = get_cluster_type();
    crm_info("Reading configure for stack: %s", name_for_cluster_type(stack));
    
    /* =::=::= Should we be here =::=::= */
    if (stack == pcmk_cluster_corosync) {
        setenv("HA_cluster_type", "corosync", 1);
        setenv("HA_quorum_type",  "corosync", 1);

#if HAVE_CONFDB
    } else if (stack == pcmk_cluster_cman) {
        setenv("HA_cluster_type", "cman", 1);
        setenv("HA_quorum_type",  "cman", 1);
        enable_crmd_as_root(TRUE);
        use_cman = TRUE;

    } else if (stack == pcmk_cluster_classic_ais) {
        setenv("HA_cluster_type", "openais", 1);
        setenv("HA_quorum_type",  "pcmk", 1);

        /* Look for a service block to indicate our plugin is loaded */
        top_handle = config_find_init(config);
        local_handle = config_find_next(config, "service", top_handle);

        while (local_handle) {
            crm_free(value);
            get_config_opt(config, local_handle, "name", &value, NULL);
            if (safe_str_eq("pacemaker", value)) {
                crm_free(value);
                get_config_opt(config, local_handle, "ver", &value, "0");
                if (safe_str_eq(value, "1")) {
                    crm_free(value);
                    get_config_opt(config, local_handle, "use_logd", &value, "no");
                    setenv("HA_use_logd", value, 1);
                    setenv("HA_LOGD", value, 1);

                    crm_free(value);
                    get_config_opt(config, local_handle, "use_mgmtd", &value, "no");
                    enable_mgmtd(crm_is_true(value));

                } else {
                    crm_err("We can only start Pacemaker from init if using version 1"
                            " of the Pacemaker plugin for Corosync.  Terminating.");
//.........这里部分代码省略.........
开发者ID:esimone74,项目名称:pacemaker,代码行数:101,代码来源:corosync.c

示例15: te_rsc_command

static gboolean
te_rsc_command(crm_graph_t * graph, crm_action_t * action)
{
    /* never overwrite stop actions in the CIB with
     *   anything other than completed results
     *
     * Writing pending stops makes it look like the
     *   resource is running again
     */
    xmlNode *cmd = NULL;
    xmlNode *rsc_op = NULL;

    gboolean rc = TRUE;
    gboolean no_wait = FALSE;
    gboolean is_local = FALSE;

    char *counter = NULL;
    const char *task = NULL;
    const char *value = NULL;
    const char *on_node = NULL;
    const char *task_uuid = NULL;

    CRM_ASSERT(action != NULL);
    CRM_ASSERT(action->xml != NULL);

    action->executed = FALSE;
    on_node = crm_element_value(action->xml, XML_LRM_ATTR_TARGET);

    CRM_CHECK(on_node != NULL && strlen(on_node) != 0,
              te_log_action(LOG_ERR, "Corrupted command(id=%s) %s: no node",
                            ID(action->xml), crm_str(task));
              return FALSE);

    rsc_op = action->xml;
    task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK);
    task_uuid = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY);
    on_node = crm_element_value(rsc_op, XML_LRM_ATTR_TARGET);
    counter =
        generate_transition_key(transition_graph->id, action->id, get_target_rc(action), te_uuid);
    crm_xml_add(rsc_op, XML_ATTR_TRANSITION_KEY, counter);

    if (safe_str_eq(on_node, fsa_our_uname)) {
        is_local = TRUE;
    }

    value = crm_meta_value(action->params, XML_ATTR_TE_NOWAIT);
    if (crm_is_true(value)) {
        no_wait = TRUE;
    }

    crm_info("Initiating action %d: %s %s on %s%s%s",
             action->id, task, task_uuid, on_node,
             is_local ? " (local)" : "", no_wait ? " - no waiting" : "");

    cmd = create_request(CRM_OP_INVOKE_LRM, rsc_op, on_node,
                         CRM_SYSTEM_LRMD, CRM_SYSTEM_TENGINE, NULL);

    if (is_local) {
        /* shortcut local resource commands */
        ha_msg_input_t data = {
            .msg = cmd,
            .xml = rsc_op,
        };

        fsa_data_t msg = {
            .id = 0,
            .data = &data,
            .data_type = fsa_dt_ha_msg,
            .fsa_input = I_NULL,
            .fsa_cause = C_FSA_INTERNAL,
            .actions = A_LRM_INVOKE,
            .origin = __FUNCTION__,
        };

        do_lrm_invoke(A_LRM_INVOKE, C_FSA_INTERNAL, fsa_state, I_NULL, &msg);

    } else {
        rc = send_cluster_message(on_node, crm_msg_lrmd, cmd, TRUE);
    }

    crm_free(counter);
    free_xml(cmd);

    action->executed = TRUE;
    if (rc == FALSE) {
        crm_err("Action %d failed: send", action->id);
        return FALSE;

    } else if (no_wait) {
        action->confirmed = TRUE;
        update_graph(transition_graph, action);
        trigger_graph();

    } else {
        if (action->timeout <= 0) {
            crm_err("Action %d: %s %s on %s had an invalid timeout (%dms).  Using %dms instead",
                    action->id, task, task_uuid, on_node, action->timeout, graph->network_delay);
            action->timeout = graph->network_delay;
        }
        te_start_action_timer(graph, action);
//.........这里部分代码省略.........
开发者ID:fghaas,项目名称:pacemaker,代码行数:101,代码来源:te_actions.c


注:本文中的crm_is_true函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。