static int anal_fcn_list_bb(RCore *core, const char *input, bool one) {
	RDebugTracepoint *tp = NULL;
	RListIter *iter;
	RAnalBlock *b;
	int mode = 0;
	ut64 addr, bbaddr = UT64_MAX;
	bool firstItem = true;

	if (*input == '.') {
		one = true;
		input++;
	}
	if (*input) {
		mode = *input;
		input++;
	}
	if (*input == '.') {
		one = true;
		input++;
	}
	if (input && *input) {
		addr = bbaddr = r_num_math (core->num, input);
	} else {
		addr = core->offset;
	}
	if (one) {
		bbaddr = addr;
	}
	RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, addr, 0);
	if (!fcn) {
		return false;
	}
	switch (mode) {
	case 'j':
		r_cons_printf ("[");
		break;
	case '*':
		r_cons_printf ("fs blocks\n");
		break;
	}
	r_list_sort (fcn->bbs, bb_cmp);
	r_list_foreach (fcn->bbs, iter, b) {
		if (one) {
			if (bbaddr != UT64_MAX && (bbaddr < b->addr || bbaddr >= (b->addr + b->size))) {
				continue;
			}
		}
		switch (mode) {
		case 'r':
			if (b->jump == UT64_MAX) {
				ut64 retaddr = b->addr;
				if (b->op_pos) {
					retaddr += b->op_pos[b->ninstr - 2];
				}
				if (!strcmp (input, "*")) {
					r_cons_printf ("db 0x%08"PFMT64x"\n", retaddr);
				} else if (!strcmp (input, "-*")) {
					r_cons_printf ("db-0x%08"PFMT64x"\n", retaddr);
				} else {
					r_cons_printf ("0x%08"PFMT64x"\n", retaddr);
				}
			}
			break;
		case '*':
			r_cons_printf ("f bb.%05" PFMT64x " = 0x%08" PFMT64x "\n",
				b->addr & 0xFFFFF, b->addr);
			break;
		case 'q':
			r_cons_printf ("0x%08" PFMT64x "\n", b->addr);
			break;
		case 'j':
			//r_cons_printf ("%" PFMT64u "%s", b->addr, iter->n? ",": "");
			{
			RListIter *iter2;
			RAnalBlock *b2;
			int inputs = 0;
			int outputs = 0;
			r_list_foreach (fcn->bbs, iter2, b2) {
				if (b2->jump == b->addr) {
					inputs++;
				}
				if (b2->fail == b->addr) {
					inputs++;
				}
			}
			if (b->jump != UT64_MAX) {
				outputs ++;
			}
			if (b->fail != UT64_MAX) {
				outputs ++;
			}
			r_cons_printf ("%s{", firstItem? "": ",");
			firstItem = false;
			if (b->jump != UT64_MAX) {
				r_cons_printf ("\"jump\":%"PFMT64u",", b->jump);
			}
			if (b->fail != UT64_MAX) {
				r_cons_printf ("\"fail\":%"PFMT64u",", b->fail);
			}
			if (b->switch_op) {
				r_cons_print ("\"switch_op\":{");
				r_cons_printf ("\"addr\":%"PFMT64u",", b->switch_op->addr);
				r_cons_printf ("\"min_val\":%"PFMT64u",", b->switch_op->min_val);
				r_cons_printf ("\"def_val\":%"PFMT64u",", b->switch_op->def_val);
				r_cons_printf ("\"max_val\":%"PFMT64u",", b->switch_op->max_val);
				r_cons_print ("\"cases\":[");
				{
					RListIter *case_op_iter;
					RAnalCaseOp *case_op;
					r_list_foreach (b->switch_op->cases, case_op_iter, case_op) {
						r_cons_printf ("%s{", case_op_iter->p ? "," : "");
						r_cons_printf ("\"addr\":%"PFMT64u",", case_op->addr);
						r_cons_printf ("\"jump\":%"PFMT64u",", case_op->jump);
						r_cons_printf ("\"value\":%"PFMT64u",", case_op->value);
						r_cons_printf ("\"cond\":%"PFMT32u",", case_op->cond);
						r_cons_printf ("\"bb_ref_to\":%"PFMT64u",", case_op->bb_ref_to);
						r_cons_printf ("\"bb_ref_from\":%"PFMT64u"", case_op->bb_ref_from);
						r_cons_print ("}");
					}
				}
				r_cons_print ("]},");
			}
			r_cons_printf ("\"addr\":%" PFMT64u ",\"size\":%d,\"inputs\":%d,\"outputs\":%d,\"ninstr\":%d,\"traced\":%s}",
				b->addr, b->size, inputs, outputs, b->ninstr, r_str_bool (b->traced));
			}
			break;
		case 'i':
			{
			RListIter *iter2;
			RAnalBlock *b2;
			int inputs = 0;
			int outputs = 0;
			r_list_foreach (fcn->bbs, iter2, b2) {
				if (b2->jump == b->addr) {
					inputs++;
				}
				if (b2->fail == b->addr) {
					inputs++;
				}
			}
			if (b->jump != UT64_MAX) {
				outputs ++;
			}
			if (b->fail != UT64_MAX) {
				outputs ++;
			}
			firstItem = false;
			if (b->jump != UT64_MAX) {
				r_cons_printf ("jump: 0x%08"PFMT64x"\n", b->jump);
			}
			if (b->fail != UT64_MAX) {
				r_cons_printf ("fail: 0x%08"PFMT64x"\n", b->fail);
			}
			r_cons_printf ("addr: 0x%08"PFMT64x"\nsize: %d\ninputs: %d\noutputs: %d\nninstr: %d\ntraced: %s\n",
				b->addr, b->size, inputs, outputs, b->ninstr, r_str_bool (b->traced));
			}
			break;
		default:
			tp = r_debug_trace_get (core->dbg, b->addr);
			r_cons_printf ("0x%08" PFMT64x " 0x%08" PFMT64x " %02X:%04X %d",
				b->addr, b->addr + b->size,
				tp? tp->times: 0, tp? tp->count: 0,
				b->size);
			if (b->jump != UT64_MAX) {
				r_cons_printf (" j 0x%08" PFMT64x, b->jump);
			}
			if (b->fail != UT64_MAX) {
				r_cons_printf (" f 0x%08" PFMT64x, b->fail);
			}
			r_cons_newline ();
			break;
		}
	}
	if (mode == 'j') {
		r_cons_printf ("]\n");
	}
	return true;
}