RZ_DEPRECATE RZ_API int rz_core_analysis_fcn_list(RzCore *core, const char *input, const char *rad) {
	rz_return_val_if_fail(core && core->analysis, 0);
	char temp[64];
	RzList *fcnlist = rz_analysis_function_list(core->analysis);
	if (rz_list_empty(fcnlist)) {
		if (*rad == 'j') {
			PJ *pj = pj_new();
			if (!pj) {
				return -1;
			}
			pj_a(pj);
			pj_end(pj);
			rz_cons_println(pj_string(pj));
			pj_free(pj);
		}
		return 0;
	}
	if (*rad == '.') {
		RzList *fcns = rz_analysis_get_functions_in(core->analysis, core->offset);
		if (!fcns || rz_list_empty(fcns)) {
			eprintf("No functions at current address.\n");
			rz_list_free(fcns);
			return -1;
		}
		fcn_list_default(core, fcns, false);
		rz_list_free(fcns);
		return 0;
	}

	if (rad && (*rad == 'l' || *rad == 'j')) {
		fcnlist_gather_metadata(core->analysis, fcnlist);
	}

	const char *name = input;
	ut64 addr = core->offset;
	if (input && *input) {
		name = input + 1;
		addr = rz_num_math(core->num, name);
	}

	RzList *fcns = rz_list_newf(NULL);
	if (!fcns) {
		return -1;
	}
	RzListIter *iter;
	RzAnalysisFunction *fcn;
	rz_list_foreach (fcnlist, iter, fcn) {
		if (!input || rz_analysis_function_contains(fcn, addr) || (!strcmp(name, fcn->name))) {
			rz_list_append(fcns, fcn);
		}
	}

	// rz_list_sort (fcns, &cmpfcn);
	if (!rad) {
		fcn_list_default(core, fcns, false);
		rz_list_free(fcns);
		return 0;
	}
	switch (*rad) {
	case '+':
		rz_core_analysis_fcn_list_size(core);
		break;
	case '=': { // afl=
		rz_list_sort(fcns, fcn_cmpaddr);
		RzList *flist = rz_list_newf((RzListFree)rz_listinfo_free);
		if (!flist) {
			rz_list_free(fcns);
			return -1;
		}
		ls_foreach (fcns, iter, fcn) {
			RzInterval inter = { rz_analysis_function_min_addr(fcn), rz_analysis_function_linear_size(fcn) };
			char *fcn_name = rz_core_analysis_fcn_name(core, fcn);
			RzListInfo *info = rz_listinfo_new(fcn_name, inter, inter, -1, sdb_itoa(fcn->bits, temp, 10));
			free(fcn_name);
			if (!info) {
				break;
			}
			rz_list_append(flist, info);
		}
		RzTable *table = rz_core_table(core);
		rz_table_visual_list(table, flist, core->offset, core->blocksize,
			rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
		rz_cons_printf("\n%s\n", rz_table_tostring(table));
		rz_table_free(table);
		rz_list_free(flist);
		break;
	}
	case 't': // "aflt" "afltj"
		if (rad[1] == 'j') {
			fcn_list_table(core, rz_str_trim_head_ro(rad + 2), 'j');
		} else {
			fcn_list_table(core, rz_str_trim_head_ro(rad + 1), rad[1]);
		}
		break;
	case 'l': // "afll" "afllj"
		if (rad[1] == 'j') {
			fcn_list_verbose_json(core, fcns);
		} else {
			char *sp = strchr(rad, ' ');
			fcn_list_verbose(core, fcns, sp ? sp + 1 : NULL);
		}
		break;
	case 'q':
		if (rad[1] == 'j') {
			fcn_list_json(core, fcns, true);
		} else {
			fcn_list_default(core, fcns, true);
		}
		break;
	case 'j':
		fcn_list_json(core, fcns, false);
		break;
	case '*':
		fcn_list_detail(core, fcns);
		break;
	case 'm': // "aflm"
	{
		char mode = 'm';
		if (rad[1] != 0) {
			if (rad[1] == 'j') { // "aflmj"
				mode = 'j';
			} else if (rad[1] == 'q') { // "aflmq"
				mode = 'q';
			}
		}
		fcn_print_makestyle(core, fcns, mode);
		break;
	}
	case 1:
		fcn_list_legacy(core, fcns);
		break;
	default:
		fcn_list_default(core, fcns, false);
		break;
	}
	rz_list_free(fcns);
	return 0;
}
RZ_DEPRECATE RZ_API int rz_core_analysis_fcn_list(RzCore *core, const char *input, const char *rad) {
	rz_return_val_if_fail(core && core->analysis, 0);
	char temp[64];
	RzList *fcnlist = rz_analysis_function_list(core->analysis);
	if (rz_list_empty(fcnlist)) {
		if (*rad == 'j') {
			PJ *pj = pj_new();
			if (!pj) {
				return -1;
			}
			pj_a(pj);
			pj_end(pj);
			rz_cons_println(pj_string(pj));
			pj_free(pj);
		}
		return 0;
	}
	if (*rad == '.') {
		RzList *fcns = rz_analysis_get_functions_in(core->analysis, core->offset);
		if (!fcns || rz_list_empty(fcns)) {
			eprintf("No functions at current address.\n");
			rz_list_free(fcns);
			return -1;
		}
		fcn_list_default(core, fcns, false);
		rz_list_free(fcns);
		return 0;
	}

	if (rad && (*rad == 'l' || *rad == 'j')) {
		fcnlist_gather_metadata(core->analysis, fcnlist);
	}

	const char *name = input;
	ut64 addr = core->offset;
	if (input && *input) {
		name = input + 1;
		addr = rz_num_math(core->num, name);
	}

	RzList *fcns = rz_list_newf(NULL);
	if (!fcns) {
		return -1;
	}
	RzListIter *iter;
	RzAnalysisFunction *fcn;
	rz_list_foreach (fcnlist, iter, fcn) {
		if (!input || rz_analysis_function_contains(fcn, addr) || (!strcmp(name, fcn->name))) {
			rz_list_append(fcns, fcn);
		}
	}

	 
	if (!rad) {
		fcn_list_default(core, fcns, false);
		rz_list_free(fcns);
		return 0;
	}
	switch (*rad) {
	case '+':
		rz_core_analysis_fcn_list_size(core);
		break;
	case '=': {  
		rz_list_sort(fcns, fcn_cmpaddr);
		RzList *flist = rz_list_newf((RzListFree)rz_listinfo_free);
		if (!flist) {
			rz_list_free(fcns);
			return -1;
		}
		ls_foreach (fcns, iter, fcn) {
			RzInterval inter = { rz_analysis_function_min_addr(fcn), rz_analysis_function_linear_size(fcn) };
			char *fcn_name = rz_core_analysis_fcn_name(core, fcn);
			RzListInfo *info = rz_listinfo_new(fcn_name, inter, inter, -1, sdb_itoa(fcn->bits, temp, 10));
			free(fcn_name);
			if (!info) {
				break;
			}
			rz_list_append(flist, info);
		}
		RzTable *table = rz_core_table(core);
		rz_table_visual_list(table, flist, core->offset, core->blocksize,
			rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
		rz_cons_printf("\n%s\n", rz_table_tostring(table));
		rz_table_free(table);
		rz_list_free(flist);
		break;
	}
	case 't':  
		if (rad[1] == 'j') {
			fcn_list_table(core, rz_str_trim_head_ro(rad + 2), 'j');
		} else {
			fcn_list_table(core, rz_str_trim_head_ro(rad + 1), rad[1]);
		}
		break;
	case 'l':  
		if (rad[1] == 'j') {
			fcn_list_verbose_json(core, fcns);
		} else {
			char *sp = strchr(rad, ' ');
			fcn_list_verbose(core, fcns, sp ? sp + 1 : NULL);
		}
		break;
	case 'q':
		if (rad[1] == 'j') {
			fcn_list_json(core, fcns, true);
		} else {
			fcn_list_default(core, fcns, true);
		}
		break;
	case 'j':
		fcn_list_json(core, fcns, false);
		break;
	case '*':
		fcn_list_detail(core, fcns);
		break;
	case 'm':  
	{
		char mode = 'm';
		if (rad[1] != 0) {
			if (rad[1] == 'j') {  
				mode = 'j';
			} else if (rad[1] == 'q') {  
				mode = 'q';
			}
		}
		fcn_print_makestyle(core, fcns, mode);
		break;
	}
	case 1:
		fcn_list_legacy(core, fcns);
		break;
	default:
		fcn_list_default(core, fcns, false);
		break;
	}
	rz_list_free(fcns);
	return 0;
}