static void cmd_anal_graph(RCore *core, const char *input) {
	RList *list;
	const char *arg;
	switch (input[0]) {
	case 'f': // "agf"
		switch (input[1]) {
		case 't':// "agft" - tiny graph
			r_core_visual_graph (core, NULL, NULL, 2);
			break;
		case 0:
			r_core_visual_graph (core, NULL, NULL, false);
			break;
		default:
			eprintf ("Usage: agf or agft (for tiny)\n");
			break;
		}
		break;
	case '-': // "ag-"
		r_agraph_reset (core->graph);
		break;
	case 'n': // "agn"
		cmd_agraph_node (core, input + 1);
		break;
	case 'e': // "age"
		cmd_agraph_edge (core, input + 1);
		break;
	case 'g': // "agg"
		cmd_agraph_print (core, input + 1);
		break;
	case 's': // "ags"
		r_core_anal_graph (core, r_num_math (core->num, input + 1), 0);
		break;
	case 't': // "agt"
		list = r_core_anal_graph_to (core, r_num_math (core->num, input + 1), 0);
		if (list) {
			RListIter *iter, *iter2;
			RList *list2;
			RAnalBlock *bb;
			r_list_foreach (list, iter, list2) {
				r_list_foreach (list2, iter2, bb) {
					r_cons_printf ("-> 0x%08" PFMT64x "\n", bb->addr);
				}
			}
			r_list_purge (list);
			free (list);
		}
		break;
	case 'C': // "agC"
		r_core_anal_coderefs (core, UT64_MAX, input[1] == 'j'? 2: 1);
		break;
	case 'r': // "refs"
		switch (input[1]) {
		case '*':
		case 'j':
		case ' ':
		case 0:
			{
				ut64 addr = input[2]? r_num_math (core->num, input + 2): core->offset;
				r_core_anal_codexrefs (core, addr, '*');
			}
			break;
		default:
			eprintf ("|ERROR| Usage: agr[*j]\n");
			break;
		}
		break;
	case 'c': // "agc"
		if (input[1] == '*') {
			ut64 addr = input[2]? r_num_math (core->num, input + 2): UT64_MAX;
			r_core_anal_coderefs (core, addr, '*');
		} else if (input[1] == 'j') {
			ut64 addr = input[2]? r_num_math (core->num, input + 2): UT64_MAX;
			r_core_anal_coderefs (core, addr, 2);
		} else if (input[1] == ' ') {
			ut64 addr = input[2]? r_num_math (core->num, input + 1): UT64_MAX;
			r_core_anal_coderefs (core, addr, 1);
		} else {
			eprintf ("|ERROR| Usage: agc[j*] ([addr])\n");
		}
		break;
	case 'j': // "agj"
		r_core_anal_graph (core, r_num_math (core->num, input + 1), R_CORE_ANAL_JSON);
		break;
	case 'J': // "agJ"
		r_core_anal_graph (core, r_num_math (core->num, input + 1), R_CORE_ANAL_JSON | R_CORE_ANAL_JSON_FORMAT_DISASM);
		break;
	case 'k': // "agk"
		r_core_anal_graph (core, r_num_math (core->num, input + 1), R_CORE_ANAL_KEYVALUE);
		break;
	case 'l': // "agl"
		r_core_anal_graph (core, r_num_math (core->num, input + 1), R_CORE_ANAL_GRAPHLINES);
		break;
	case 'a': // "aga"
		r_core_anal_graph (core, r_num_math (core->num, input + 1), 0);
		break;
	case 'd': // "agd"
		r_core_anal_graph (core, r_num_math (core->num, input + 1),
				R_CORE_ANAL_GRAPHBODY | R_CORE_ANAL_GRAPHDIFF);
		break;
	case 'v': // "agv"
		if (r_config_get_i (core->config, "graph.web")) {
			r_core_cmd0 (core, "=H /graph/");
		} else {
			const char *cmd = r_config_get (core->config, "cmd.graph");
			if (cmd && *cmd) {
				r_core_cmd0 (core, cmd);
			} else {
				r_core_cmd0 (core, "agf");
			}
		}
		break;
	case '?': // "ag?"
		r_core_cmd_help (core, help_msg_ag);
		break;
	case ' ': // "ag"
		arg = strchr (input, ' ');
		r_core_anal_graph (core, r_num_math (core->num, arg? arg + 1: NULL),
				R_CORE_ANAL_GRAPHBODY);
		break;
	case 0:
		eprintf ("|ERROR| Usage: ag [addr]\n");
		break;
	default:
		eprintf ("See ag?\n");
		break;
	}
}