diff --git a/librz/core/cconfig.c b/librz/core/cconfig.c index 39e6ce9c35..f3a5ff4a4a 100644 --- a/librz/core/cconfig.c +++ b/librz/core/cconfig.c @@ -3314,7 +3314,6 @@ RZ_API int rz_core_config_init(RzCore *core) { SETBPREF("cfg.plugins", "true", "Load plugins at startup"); SETCB("time.fmt", "%Y-%m-%d %H:%M:%S %z", &cb_cfgdatefmt, "Date format (%Y-%m-%d %H:%M:%S %z)"); SETICB("time.zone", 0, &cb_timezone, "Time zone, in hours relative to GMT: +2, -1,.."); - SETBPREF("cfg.newtab", "false", "Show descriptions in command completion"); SETCB("cfg.debug", "false", &cb_cfgdebug, "Debugger mode"); p = rz_sys_getenv("EDITOR"); #if __WINDOWS__ diff --git a/librz/core/core.c b/librz/core/core.c index d196d9d1d0..737b9a61cb 100644 --- a/librz/core/core.c +++ b/librz/core/core.c @@ -862,802 +862,6 @@ RZ_API RzCore *rz_core_new(void) { return c; } -/*-----------------------------------*/ -#define rizin_argc (sizeof(rizin_argv) / sizeof(const char *) - 1) - -static const char *rizin_argv[] = { - "whereis", "which", "ls", "rm", "mkdir", "pwd", "cat", "sort", "uniq", "join", "less", "exit", "quit", - "#?", "#!", "#sha1", "#crc32", "#pcprint", "#sha256", "#sha512", "#md4", "#md5", - "#!python", "#!vala", "#!pipe", - "*?", "*", "$", - "(", "(*", "(-", "()", ".?", ".", "..", "...", ".:", ".--", ".-", ".!", ".(", "./", ".*", - "_?", "_", - "R?", "R", "R<", "R!", "R+", "R-", "R=", "R!=", "R=!", "R:", "R&:", - "Rg?", "Rg", "Rg!", "Rh?", "Rh", "Rh-", "Rh--", "Rh*", "Rh&", "RH?", "RH", "RH&", - "<", - "/?", "/", "/j", "/j!", "/j!x", "/+", "//", "/a", "/a1", "/ab", "/ad", "/aa", "/as", "/asl", "/at", "/atl", "/af", "/afl", "/ae", "/aej", "/ai", "/aij", - "/c", "/ca", "/car", "/d", "/e", "/E", "/Ej", "/f", "/F", "/g", "/gg", "/h", "/ht", "/i", "/m", "/mb", "/mm", - "/o", "/O", "/p", "/P", "/s", "/s*", "/r?", "/r", "/ra", "/rc", "/re", "/rr", "/rw", "/rc", - "/R", - "/v?", "/v", "/v1", "/v2", "/v4", "/v8", - "/V?", "/V", "/V1", "/V2", "/V4", "/V8", - "/w", "/wi", "/x", "/z", - "!?", "!", "!!", "!!!", "!!!-", "!-", "!-*", "!=!", - "a?", "a", "aa", "aa*", - "aaa", "aac", "aac*", "aad", "aae", "aaf", "aai", "aaij", "aan", "aang", "aao", "aap", - "aar?", "aar", "aar*", "aarj", "aas", "aat", "aaT", "aau", "aav", - "a8", "ab", - "acl", "acll", "aclj", "acl*", "ac?", "ac", "ac-", "acn", "acv", "acvf", "acv-", "acb", "acb-", "acm", "acm-", "acmn", - "aC?", "ad", "ad4", "ad8", "adf", "adfg", "adt", "adk", - "ae?", "ae??", "ae", "aea", "aeA", "aeaf", "aeAf", "aeC", "aec?", "aec", "aecb", "aecs", "aecc", "aecu", "aecue", - "aef", "aefa", - "aei", "aeim", "aeip", "aek", "aek-", "aeli", "aelir", "aep?", "aep", "aep-", "aepc", - "aets?", "aets+", "aets-", "aes", "aesp", "aesb", "aeso", "aesou", "aess", "aesu", "aesue", "aetr", "aex", - "aF", - "ag?", "ag", "aga", "agA", "agc", "agC", "agCi", "agF", "agd", "agf", "agi", "agr", "agR", "agx", "agg", "ag-", - "agn?", "agn", "agn-", "age?", "age", "age-", - "agl", "agfl", - "ah?", "ah", "ah.", "ah-", "ah*", "aha", "ahb", "ahc", "ahe", "ahf", "ahh", "ahi?", "ahi", "ahj", "aho", - "ahp", "ahr", "ahs", "ahS", "aht", - "ai", "aL", "an", - "ao?", "ao", "aoj", "aoe", "aor", "aos", "aom", "aod", "aoda", "aoc", "ao*", - "aO", "ap", - "ar?", "ar", "ar0", "ara?", "ara", "ara+", "ara-", "aras", "arA", "arC", "arr", "arrj", "ar=", - "arb", "arc", "ard", "arn", "aro", "arp?", "arp", "arpi", "arpg", "arp.", "arpj", - "ars", "art", "arw", - "as?", "as", "asc", "asca", "asf", "asj", "asl", "ask", - "av?", "av", "avj", "av*", "avr", "avra", "avraj", "avrr", "avrD", - "at", - "b?", "b", "b+", "b-", "bf", "bm", - "c?", "c", "c1", "c2", "c4", "c8", "cc", "ccd", "cf", "cg?", "cg", "cgf", "cgff", "cgfc", "cgfn", "cgo", - "cu?", "cu", "cu1", "cu2", "cu4", "cu8", "cud", - "cv", "cv1", "cv2", "cv4", "cv8", - "cV", "cV1", "cV2", "cV4", "cV8", - "cw?", "cw", "cw*", "cwr", "cwu", - "cx", "cx*", "cX", - "cl", "cls", "clear", - "d?", "db ", "db-", "db-*", "db.", "dbj", "dbc", "dbC", "dbd", "dbe", "dbs", "dbf", "dbm", "dbn", - "db?", "dbi", "dbi.", "dbix", "dbic", "dbie", "dbid", "dbis", "dbite", "dbitd", "dbits", "dbh", "dbh-", - "dbt", "dbt*", "dbt=", "dbtv", "dbtj", "dbta", "dbte", "dbtd", "dbts", "dbx", "dbw", - "dc?", "dc", "dca", "dcb", "dcc", "dccu", "dcf", "dck", "dcp", "dcr", "dcs", "dcs*", "dct", "dcu", "dcu.", - "dd?", "dd", "dd-", "dd*", "dds", "ddd", "ddr", "ddw", - "de", - "dg", - "dH", - "di?", "di", "di*", "diq", "dij", - "dk?", "dk", "dko", "dkj", - "dL?", "dL", "dLq", "dLj", - "dm?", "dm", "dm=", "dm.", "dm*", "dm-", "dmd", - "dmh?", "dmh", "dmha", "dmhb", "dmhbg", "dmhc", "dmhf", "dmhg", "dmhi", "dmhm", "dmht", - "dmi?", "dmi", "dmi*", "dmi.", "dmiv", - "dmj", - "dml?", "dml", - "dmm?", "dmm", "dmm*", "dmm.", "dmmj", - "dmp?", "dmp", - "dms?", "dms", "dmsj", "dms*", "dms-", "dmsA", "dmsC", "dmsd", "dmsw", "dmsa", "dmsf", "dmst", - "dmS", "dmS*", - "do?", "do", "dor", "doo", - "dp?", "dp", "dpj", "dpl", "dplj", "dp-", "dp=", "dpa", "dpc", "dpc*", "dpe", "dpf", "dpk", "dpn", "dptn", "dpt", - "dr?", "dr", "drpj", "drr", "drrj", "drs", "drs+", "drs-", "drt", "drt*", "drtj", "drw", "drx", "drx-", - ".dr*", ".dr-", - "ds?", "ds", "dsb", "dsf", "dsi", "dsl", "dso", "dsp", "dss", "dsu", "dsui", "dsuo", "dsue", "dsuf", - "dt?", "dt", "dt%", "dt*", "dt+", "dt-", "dt=", "dtD", "dta", "dtc", "dtd", "dte", "dte-*", "dtei", "dtek", - "dtg", "dtg*", "dtgi", - "dtr", - "dts?", "dts", "dts+", "dts-", "dtsf", "dtst", "dtsC", "dtt", - "dw", - "dx?", "dx", "dxa", "dxe", "dxr", "dxs", - "e?", "e", "e-", "e*", "e!", "ec", "ee?", "ee", "?ed", "ed", "ej", "env", "er", "es" - "et", - "ev", "evj", - "ec?", "ec", "ec*", "ecd", "ecr", "ecs", "ecj", "ecc", "eco", "ecp", "ecn", - "ecH?", "ecH", "ecHi", "ecHw", "ecH-", - "f?", "f", "f.", "f*", "f-", "f--", "f+", "f=", "fa", "fb", "fc?", "fc", "fC", "fe-", "fe", - "ff", "fi", "fg", "fj", - "fl", "fla", "fm", "fn", "fnj", "fo", "fO", "fr", "fR", "fR?", - "fV", "fx", "fq", - "g?", "g", "gw", "gc", "gl?", "gl", "gs", "gi", "gp", "ge", "gr", "gS", - "i?", "i", "ij", "iA", "ia", "ib", "ic", "icc", "iC", - "id?", "id", "idp", "idpi", "idpi*", "idpd", "iD", "ie", "iee", "iE", "iE.", - "ih", "iHH", "ii", "iI", "ik", "il", "iL", "im", "iM", "io", "iO?", "iO", - "ir", "iR", "is", "is.", "iS", "iS.", "iS=", "iSS", - "it", "iV", "iX", "iz", "izj", "izz", "izzz", "iz-", "iZ", - "k?", "k", "ko", "kd", "ks", "kj", - "l", - "L?", "L", "L-", "Ll", "LL", "La", "Lc", "Ld", "Lh", "Li", "Lo", - "o?", "o", "o-", "o--", "o+", "oa", "oa-", "oq", "o*", "o.", "o=", - "ob?", "ob", "ob*", "obo", "oba", "obf", "obj", "obr", "ob-", "ob-*", - "oc", "of", "oi", "oj", "oL", "om", "on", - "oo?", "oo", "oo+", "oob", "ood", "oom", "oon", "oon+", "oonn", "oonn+", - "op", "opn", "opp", "opr", "ox", - "p?", "p-", "p=", "p2", "p3", "p6?", "p6", "p6d", "p6e", "p8?", "p8", "p8f", "p8j", - "pa?", "paD", "pad", "pade", "pae", "pA", - "pb?", "pb", "pB", "pxb", "pB?", - "pc?", "pc", "pc*", "pca", "pcA", "pcd", "pch", "pcj", "pcp", "pcs", "pcS", "pcw", - "pC?", "pC", "pCa", "pCA", "pCc", "pCd", "pCD", "pCx", "pCw", - "pd?", "pd", "pd--", "pD", "pda", "pdb", "pdC", "pdf", "pdi", "pdj", "pdJ", - "pdk", "pdl", "pdp", "pdr", "pdr.", "pdR", "pds?", "pds", "pdsb", "pdsf", "pdt", - "pD", - "pf?", "pf", "pf??", "pf???", "pf.", "pfj", "pfj.", "pf*", "pf*.", "pfd", "pfd.", - "pfo", "pfq", "pfv", "pfv.", "pfs", "pfs.", - "pF?", "pF", "pFa", "pFaq", "pFo", "pFp", "pFx", - "pg?", "pg", "pg*", "pg-*", - "ph?", "ph", "ph=", - "pi?", "pi", "pia", "pib", "pie", "pif?", "pif", "pifc", "pifcj", "pifj", "pir", - "pI?", "pI", "pIa", "pIb", "pIe", "pIf?", "pIf", "pIfc", "pIfcj", "pIfj", "pIr", - "pj?", "pj", "pj.", "pj..", - "pk?", "pk", "pK?", "pK", - "pm?", "pm", - "pr?", "pr", "prc", "prx", "prg?", "prg", "prgi", "prgo", "prz", - "ps?", "ps", "psb", "psi", "psj", "psp", "pss", "psu", "psw", "psW", "psx", "psz", "ps+", - "pt?", "pt", "pt.", "ptd", "pth", "ptn", - "pu?", "pu", "puw", "pU", - "pv?", "pv", "pv1", "pv2", "pv4", "pv8", "pvz", "pvj", "pvh", "pv1j", "pv2j", "pv4j", "pv8j", - "pv1h", "pv2h", "pv4h", "pv8h", - "px?", "px", "px/", "px0", "pxa", "pxA?", "pxA", "pxb", "pxc", "pxd?", "pxd", "pxd2", "pxd4", "pxd8", - "pxe", "pxf", "pxh", "pxH", "pxi", "pxl", "pxo", "pxq", "pxq", "pxQ", "pxQq", "pxr", "pxrj", - "pxs", "pxt", "pxt*", "pxt.", "pxw", "pxW", "pxWq", "pxx", "pxX", - "pz?", "pz", "pzp", "pzf", "pzs", "pz0", "pzF", "pze", "pzh", - "P?", "P", "Pc", "Pd", "Pi", "Pn", "Pnj", "Po", "Ps", "PS", "P-", - "q?", "q", "q!", "q!!", "q!!!", "qy", "qn", "qyy", "qyn", "qny", "qnn", - "r?", "r", "r-", "r+", "rh", - "s?", "s", "s:", "s-", "s-*", "s--", "s+", "s++", "sj", "s*", "s=", "s!", "s/", "s/x", "s.", "sa", "sb", - "sC?", "sC", "sC*", - "sf", "sf.", "sg", "sG", "sl?", "sn", "sp", "so", "sr", "ss", - "t?", "t", "tj", "t*", "t-", "t-*", "ta", "tb", "tc", "te?", "te", "tej", "teb", "tec", - "td?", "td", "td-", "tf", "tk", "tl", "tn", "to", "tos", "tp", "tpx", "ts?", "ts", "tsj", "ts*", "tsc", "tss", - "tu?", "tu", "tuj", "tu*", "tuc", "tt?", "tt", "ttj", "ttc", - "T?", "T", "T*", "T-", "Tl", "Tj", "Tm", "Ts", "TT", "T=", "T=.", "T=&", - "u?", "u", "uw", "us", "uc", - "v", "V", "v!", "vv", "vV", "vVV", "VV", - "w?", "w", "w1+", "w1-", "w2+", "w2-", "w4+", "w4-", "w8+", "w8-", - "w0", "w", "w6", "w6d", "w6e", "wa", "wa*", "waf", "wao?", "wao", - "wA?", "wA", "wB", "wB-", "wc", "wcj", "wc-", "wc+", "wc*", "wcr", "wci", "wcp", "wcp*", "wcpi", - "wd", "we?", "we", "wen", "weN", "wes", "wex", "weX", - "wf?", "wf", "wff", "wfs", "wF", "wh", "wm", - "wo?", "wo", "wo2", "wo4", "woa", "woA", "wod", "woD", "woe", "woE", "wol", "wom", "woo", - "wop?", "wop", "wopD", "wopD*", "wopO", - "wp?", "wp", "wr", "ws", - "wt?", "wt", "wta", "wtf", "wtf!", "wtff", "wts", - "wu", - "wv?", "wv", "wv1", "wv2", "wv4", "wv8", - "ww", - "wx?", "wx", "wxf", "wxs", - "wz", - "x?", "x", "x/", "x0", "xa", "xA?", "xA", "xb", "xc", "xd?", "xd", "xd2", "xd4", "xd8", - "xe", "xf", "xh", "xH", "xi", "xl", "xo", "xq", "xq", "xQ", "xQq", "xr", "xrj", - "xs", "xt", "xt*", "xt.", "xw", "xW", "xWq", "xx", "xX", - "y?", "y", "yz", "yp", "yx", "ys", "yt", "ytf", "yf", "yfa", "yfx", "yw", "ywx", "yy", - "z?", "z", "z*", "zj", "z-", "z-*", - "za?", "za??", "za", "zaf", "zaF", "zg", - "zo?", "zo", "zoz", "zos", - "zf?", "zfd", "zfs", "zfz", - "z/?", "z/", "z/*", - "zc", - "zs?", "zs", "zs-", "zs-*", "zs+", "zsr", - "zi", - "?", "?v", "?$?", "?@?", "?>?", - NULL -}; - -static void autocomplete_process_path(RzLineCompletion *completion, const char *str, const char *path) { - char *lpath = NULL, *dirname = NULL, *basename = NULL; - char *home = NULL, *filename = NULL, *p = NULL; - int n = 0; - RzList *list; - RzListIter *iter; - - if (!path) { - goto out; - } - - lpath = rz_str_dup(path); -#if __WINDOWS__ - rz_str_replace_ch(lpath, '/', '\\', true); -#endif - p = (char *)rz_str_last(lpath, RZ_SYS_DIR); - if (p) { - *p = 0; - if (p == lpath) { // /xxx -#if __WINDOWS__ - dirname = strdup("\\.\\"); -#else - dirname = rz_str_dup(RZ_SYS_DIR); -#endif - } else if (lpath[0] == '~' && lpath[1]) { // ~/xxx/yyy - dirname = rz_str_home(lpath + 2); - } else if (lpath[0] == '~') { // ~/xxx - if (!(home = rz_str_home(NULL))) { - goto out; - } - dirname = rz_str_newf("%s%s", home, RZ_SYS_DIR); - free(home); - } else if (lpath[0] == '.' || lpath[0] == RZ_SYS_DIR[0]) { // ./xxx/yyy || /xxx/yyy - dirname = rz_str_newf("%s%s", lpath, RZ_SYS_DIR); - } else { // xxx/yyy - char *fmt = ".%s%s%s"; -#if __WINDOWS__ - if (strchr(path, ':')) { - fmt = "%.0s%s%s"; - } -#endif - dirname = rz_str_newf(fmt, RZ_SYS_DIR, lpath, RZ_SYS_DIR); - } - basename = rz_str_dup(p + 1); - } else { // xxx - dirname = rz_str_newf(".%s", RZ_SYS_DIR); - basename = rz_str_dup(lpath); - } - - if (!dirname || !basename) { - goto out; - } - - list = rz_sys_dir(dirname); - n = strlen(basename); - bool chgdir = !strncmp(str, "cd ", 3); - if (list) { - rz_list_foreach (list, iter, filename) { - if (*filename == '.') { - continue; - } - if (!basename[0] || !strncmp(filename, basename, n)) { - char *tmpstring = rz_str_newf("%s%s", dirname, filename); - if (rz_file_is_directory(tmpstring)) { - char *s = rz_str_newf("%s%s", tmpstring, RZ_SYS_DIR); - rz_line_completion_push(completion, s); - free(s); - } else if (!chgdir) { - rz_line_completion_push(completion, tmpstring); - } - free(tmpstring); - } - } - rz_list_free(list); - } -out: - free(lpath); - free(dirname); - free(basename); -} - -static void autocompleteFilename(RzLineCompletion *completion, RzLineBuffer *buf, char **extra_paths, int narg) { - char *args = NULL, *input = NULL; - int n = 0, i = 0; - char *pipe = strchr(buf->data, '>'); - if (pipe) { - args = rz_str_dup(pipe + 1); - } else { - args = rz_str_dup(buf->data); - } - if (!args) { - goto out; - } - - n = rz_str_word_set0(args); - if (n < narg) { - goto out; - } - - input = rz_str_dup(rz_str_word_get0(args, narg)); - if (!input) { - goto out; - } - const char *tinput = rz_str_trim_head_ro(input); - - autocomplete_process_path(completion, buf->data, tinput); - - if (input[0] == '/' || input[0] == '.' || !extra_paths) { - goto out; - } - - for (i = 0; extra_paths[i]; i++) { - char *s = rz_str_newf("%s%s%s", extra_paths[i], RZ_SYS_DIR, tinput); - if (!s) { - break; - } - autocomplete_process_path(completion, buf->data, s); - free(s); - } -out: - free(args); - free(input); -} - -#define ADDARG(x) \ - if (!strncmp(buf->data + chr, x, strlen(buf->data + chr))) { \ - rz_line_completion_push(completion, x); \ - } - -static void autocomplete_default(RZ_NULLABLE RzCore *core, RzLineCompletion *completion, RzLineBuffer *buf) { - RzCoreAutocomplete *a = core ? core->autocomplete : NULL; - int i; - if (a) { - for (i = 0; i < a->n_subcmds; i++) { - if (buf->data[0] == 0 || !strncmp(a->subcmds[i]->cmd, buf->data, a->subcmds[i]->length)) { - rz_line_completion_push(completion, a->subcmds[i]->cmd); - } - } - } else { - for (i = 0; i < rizin_argc && rizin_argv[i]; i++) { - int length = strlen(rizin_argv[i]); - if (!strncmp(rizin_argv[i], buf->data, length)) { - rz_line_completion_push(completion, rizin_argv[i]); - } - } - } -} - -static void autocomplete_evals(RzCore *core, RzLineCompletion *completion, const char *str) { - rz_return_if_fail(str); - RzConfigNode *bt; - RzListIter *iter; - const char *tmp = strrchr(str, ' '); - if (tmp) { - str = tmp + 1; - } - size_t n = strlen(str); - rz_list_foreach (core->config->nodes, iter, bt) { - if (!strncmp(bt->name, str, n)) { - rz_line_completion_push(completion, bt->name); - } - } -} - -static void autocomplete_minus(RzCore *core, RzLineCompletion *completion, const char *str) { - rz_return_if_fail(str); - int count; - int length = strlen(str); - char **keys = rz_cmd_alias_keys(core->rcmd, &count); - if (!keys) { - return; - } - int i; - for (i = 0; i < count; i++) { - if (!strncmp(keys[i], str, length)) { - rz_line_completion_push(completion, keys[i]); - } - } -} - -static void autocomplete_breakpoints(RzCore *core, RzLineCompletion *completion, const char *str) { - rz_return_if_fail(str); - RzListIter *iter; - RzBreakpoint *bp = core->dbg->bp; - RzBreakpointItem *b; - int n = strlen(str); - rz_list_foreach (bp->bps, iter, b) { - char *addr = rz_str_newf("0x%" PFMT64x "", b->addr); - if (!strncmp(addr, str, n)) { - rz_line_completion_push(completion, addr); - } - free(addr); - } -} - -static bool add_argv(RzFlagItem *fi, void *user) { - RzLineCompletion *completion = user; - rz_line_completion_push(completion, fi->name); - return true; -} - -static void autocomplete_flags(RzCore *core, RzLineCompletion *completion, const char *str) { - rz_return_if_fail(str); - int n = strlen(str); - rz_flag_foreach_prefix(core->flags, str, n, add_argv, completion); -} - -// TODO: Should be refactored -static void autocomplete_sdb(RzCore *core, RzLineCompletion *completion, const char *str) { - rz_return_if_fail(core && completion && str); - char *pipe = strchr(str, '>'); - Sdb *sdb = core->sdb; - char *lpath = NULL, *p1 = NULL, *out = NULL, *p2 = NULL; - char *cur_pos = NULL, *cur_cmd = NULL, *next_cmd = NULL; - char *temp_cmd = NULL, *temp_pos = NULL, *key = NULL; - if (pipe) { - str = rz_str_trim_head_ro(pipe + 1); - } - lpath = rz_str_dup(str); - p1 = strchr(lpath, '/'); - if (p1) { - *p1 = 0; - char *ns = p1 + 1; - p2 = strchr(ns, '/'); - if (!p2) { // analysis/m - char *tmp = p1 + 1; - int n = strlen(tmp); - out = sdb_querys(sdb, NULL, 0, "analysis/**"); - if (!out) { - return; - } - while (*out) { - cur_pos = strchr(out, '\n'); - if (!cur_pos) { - break; - } - cur_cmd = rz_str_ndup(out, cur_pos - out); - if (!strncmp(tmp, cur_cmd, n)) { - char *cmplt = rz_str_newf("analysis/%s/", cur_cmd); - rz_line_completion_push(completion, cmplt); - free(cmplt); - } - out += cur_pos - out + 1; - } - - } else { // analysis/meta/* - char *tmp = p2 + 1; - int n = strlen(tmp); - char *spltr = strchr(ns, '/'); - *spltr = 0; - next_cmd = rz_str_newf("analysis/%s/*", ns); - out = sdb_querys(sdb, NULL, 0, next_cmd); - if (!out) { - free(lpath); - return; - } - while (*out) { - temp_pos = strchr(out, '\n'); - if (!temp_pos) { - break; - } - temp_cmd = rz_str_ndup(out, temp_pos - out); // contains the key=value pair - key = strchr(temp_cmd, '='); - *key = 0; - if (!strncmp(tmp, temp_cmd, n)) { - char *cmplt = rz_str_newf("analysis/%s/%s", ns, temp_cmd); - rz_line_completion_push(completion, cmplt); - free(cmplt); - } - out += temp_pos - out + 1; - } - } - } else { - int n = strlen(lpath); - if (!strncmp(lpath, "analysis", n)) { - rz_line_completion_push(completion, "analysis/"); - } - } -} - -static void autocomplete_flagspaces(RzCore *core, RzLineCompletion *completion, const char *msg) { - rz_return_if_fail(msg); - int length = strlen(msg); - RzFlag *flag = core->flags; - RzSpaceIter it; - RzSpace *s; - rz_flag_space_foreach(flag, it, s) { - if (!strncmp(msg, s->name, length)) { - rz_line_completion_push(completion, s->name); - } - } - - if (strlen(msg) == 0) { - rz_line_completion_push(completion, "*"); - } -} - -static void autocomplete_functions(RzCore *core, RzLineCompletion *completion, const char *str) { - rz_return_if_fail(str); - RzListIter *iter; - RzAnalysisFunction *fcn; - int n = strlen(str); - rz_list_foreach (core->analysis->fcns, iter, fcn) { - if (fcn->name && !strncmp(fcn->name, str, n)) { - rz_line_completion_push(completion, fcn->name); - } - } -} - -static void autocomplete_file(RzLineCompletion *completion, const char *str) { - rz_return_if_fail(str); - char *pipe = strchr(str, '>'); - - if (pipe) { - str = rz_str_trim_head_ro(pipe + 1); - } - if (str && !*str) { - autocomplete_process_path(completion, str, "./"); - } else { - autocomplete_process_path(completion, str, str); - } -} - -static void autocomplete_theme(RzCore *core, RzLineCompletion *completion, const char *str) { - rz_return_if_fail(str); - int len = strlen(str); - char *theme; - RzListIter *iter; - RzList *themes = rz_core_theme_list(core); - rz_list_foreach (themes, iter, theme) { - if (!len || !strncmp(str, theme, len)) { - rz_line_completion_push(completion, theme); - } - } - rz_list_free(themes); -} - -static bool find_e_opts(RzCore *core, RzLineCompletion *completion, RzLineBuffer *buf) { - const char *pattern = "e (.*)="; - RzRegex *rx = rz_regex_new(pattern, RZ_REGEX_EXTENDED, 0); - bool ret = false; - - RzPVector *matches = rz_regex_match_all_not_grouped(rx, buf->data, buf->length, 0, RZ_REGEX_DEFAULT); - if (!matches || rz_pvector_empty(matches) || rz_pvector_len(matches) < 2) { - goto out; - } - int i; - char *str = NULL, *sp; - RzRegexMatch *m1 = rz_pvector_at(matches, 1); - for (i = m1->start; i < m1->start + m1->len; i++) { - str = rz_str_appendch(str, buf->data[i]); - } - if (!str) { - goto out; - } - if ((sp = strchr(str, ' '))) { - // if the name contains a space, just null - *sp = 0; - } - RzConfigNode *node = rz_config_node_get(core->config, str); - if (sp) { - // if nulled, then restore. - *sp = ' '; - } - if (!node) { - ret = false; - goto out; - } - RzListIter *iter; - char *option; - char *p = (char *)strchr(buf->data, '='); - p = rz_str_ichr(p + 1, ' '); - int n = strlen(p); - rz_list_foreach (node->options, iter, option) { - if (!strncmp(option, p, n)) { - rz_line_completion_push(completion, option); - } - } - completion->opt = true; - ret = true; - -out: - rz_regex_free(rx); - rz_pvector_free(matches); - return ret; -} - -static bool find_autocomplete(RzCore *core, RzLineCompletion *completion, RzLineBuffer *buf) { - RzCoreAutocomplete *child = NULL; - RzCoreAutocomplete *parent = core->autocomplete; - const char *p = buf->data; - if (!*p) { - return false; - } - char arg[256]; - arg[0] = 0; - while (*p) { - const char *e = rz_str_trim_head_wp(p); - if (!e || (e - p) >= 256 || e == p) { - return false; - } - memcpy(arg, p, e - p); - arg[e - p] = 0; - child = rz_core_autocomplete_find(parent, arg, false); - if (child && child->length < buf->length && p[child->length] == ' ') { - // if is spaced then i can provide the - // next subtree as suggestion.. - p = rz_str_trim_head_ro(p + child->length); - if (child->type == RZ_CORE_AUTOCMPLT_OPTN) { - continue; - } - parent = child; - } else { - break; - } - } - int i; - /* if something went wrong this will prevent bad behavior */ - rz_line_completion_clear(completion); - switch (parent->type) { - case RZ_CORE_AUTOCMPLT_SEEK: - autocomplete_functions(core, completion, p); - // fallthrough - case RZ_CORE_AUTOCMPLT_FLAG: - autocomplete_flags(core, completion, p); - break; - case RZ_CORE_AUTOCMPLT_FLSP: - autocomplete_flagspaces(core, completion, p); - break; - case RZ_CORE_AUTOCMPLT_FCN: - autocomplete_functions(core, completion, p); - break; - case RZ_CORE_AUTOCMPLT_EVAL: - autocomplete_evals(core, completion, p); - break; - case RZ_CORE_AUTOCMPLT_MINS: - autocomplete_minus(core, completion, p); - break; - case RZ_CORE_AUTOCMPLT_BRKP: - autocomplete_breakpoints(core, completion, p); - break; - case RZ_CORE_AUTOCMPLT_FILE: - autocomplete_file(completion, p); - break; - case RZ_CORE_AUTOCMPLT_THME: - autocomplete_theme(core, completion, p); - break; - case RZ_CORE_AUTOCMPLT_SDB: - autocomplete_sdb(core, completion, p); - break; - case RZ_CORE_AUTOCMPLT_OPTN: - // handled before - break; - default: - if (rz_config_get_i(core->config, "cfg.newtab")) { - RzCmdDescriptor *desc = &core->root_cmd_descriptor; - for (i = 0; arg[i] && desc; i++) { - ut8 c = arg[i]; - desc = c < RZ_ARRAY_SIZE(desc->sub) ? desc->sub[c] : NULL; - } - if (desc && desc->help_msg) { - rz_core_cmd_help(core, desc->help_msg); - rz_cons_flush(); - return true; - } - // fallback to command listing - } - int length = strlen(arg); - for (i = 0; i < parent->n_subcmds; i++) { - if (!strncmp(arg, parent->subcmds[i]->cmd, length)) { - rz_line_completion_push(completion, parent->subcmds[i]->cmd); - } - } - break; - } - return true; -} - -RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *completion, RzLineBuffer *buf, RzLinePromptType prompt_type) { - if (!core) { - autocomplete_default(core, completion, buf); - return; - } - rz_line_completion_clear(completion); - char *pipe = strchr(buf->data, '>'); - char *ptr = strchr(buf->data, '@'); - if (pipe && strchr(pipe + 1, ' ') && buf->data + buf->index >= pipe) { - autocompleteFilename(completion, buf, NULL, 1); - } else if (ptr && strchr(ptr + 1, ' ') && buf->data + buf->index >= ptr) { - int sdelta, n; - ptr = (char *)rz_str_trim_head_ro(ptr + 1); - n = strlen(ptr); //(buf->data+sdelta); - sdelta = (int)(size_t)(ptr - buf->data); - rz_flag_foreach_prefix(core->flags, buf->data + sdelta, n, add_argv, completion); - } else if (!strncmp(buf->data, "#!pipe ", 7)) { - if (strchr(buf->data + 7, ' ')) { - autocompleteFilename(completion, buf, NULL, 2); - } else { - int chr = 7; - ADDARG("node"); - ADDARG("vala"); - ADDARG("ruby"); - ADDARG("newlisp"); - ADDARG("perl"); - ADDARG("python"); - } - } else if (!strncmp(buf->data, "ec ", 3)) { - if (strchr(buf->data + 3, ' ')) { - autocompleteFilename(completion, buf, NULL, 2); - } else { - int chr = 3; - ADDARG("comment") - ADDARG("usrcmt") - ADDARG("args") - ADDARG("fname") - ADDARG("floc") - ADDARG("fline") - ADDARG("flag") - ADDARG("label") - ADDARG("help") - ADDARG("flow") - ADDARG("prompt") - ADDARG("offset") - ADDARG("input") - ADDARG("invalid") - ADDARG("other") - ADDARG("b0x00") - ADDARG("b0x7f") - ADDARG("b0xff") - ADDARG("math") - ADDARG("bin") - ADDARG("btext") - ADDARG("push") - ADDARG("pop") - ADDARG("crypto") - ADDARG("jmp") - ADDARG("cjmp") - ADDARG("call") - ADDARG("nop") - ADDARG("ret") - ADDARG("trap") - ADDARG("swi") - ADDARG("cmp") - ADDARG("reg") - ADDARG("creg") - ADDARG("num") - ADDARG("mov") - ADDARG("func_var") - ADDARG("func_var_type") - ADDARG("func_var_addr") - ADDARG("widget_bg") - ADDARG("widget_sel") - ADDARG("ai.read") - ADDARG("ai.write") - ADDARG("ai.exec") - ADDARG("ai.seq") - ADDARG("ai.ascii") - ADDARG("ai.unmap") - ADDARG("graph.box") - ADDARG("graph.box2") - ADDARG("graph.box3") - ADDARG("graph.box4") - ADDARG("graph.true") - ADDARG("graph.false") - ADDARG("graph.ujump") - ADDARG("graph.current") - ADDARG("graph.traced") - ADDARG("gui.cflow") - ADDARG("gui.dataoffset") - ADDARG("gui.background") - ADDARG("gui.alt_background") - ADDARG("gui.border") - } - } else if ((!strncmp(buf->data, "afvn ", 5)) || (!strncmp(buf->data, "afan ", 5))) { - RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0); - RzList *vars; - if (!strncmp(buf->data, "afvn ", 5)) { - vars = rz_analysis_var_list(fcn, RZ_ANALYSIS_VAR_STORAGE_STACK); - } else { - vars = rz_list_new(); // TODO rz_analysis_var_list (fcn, RZ_ANALYSIS_VAR_KIND_ARG); - } - const char *f_ptr, *l_ptr; - RzAnalysisVar *var; - int len = strlen(buf->data); - - f_ptr = rz_sub_str_lchr(buf->data, 0, buf->index, ' '); - f_ptr = f_ptr != NULL ? f_ptr + 1 : buf->data; - l_ptr = rz_sub_str_rchr(buf->data, buf->index, len, ' '); - if (!l_ptr) { - l_ptr = buf->data + len; - } - RzListIter *iter; - rz_list_foreach (vars, iter, var) { - if (!strncmp(f_ptr, var->name, l_ptr - f_ptr)) { - rz_line_completion_push(completion, var->name); - } - } - rz_list_free(vars); - } else if (!strncmp(buf->data, "$", 1)) { - int i; - for (i = 0; i < core->rcmd->aliases.count; i++) { - const char *key = core->rcmd->aliases.keys[i]; - int len = strlen(buf->data); - if (!len || !strncmp(buf->data, key, len)) { - rz_line_completion_push(completion, key); - } - } - } else if (find_e_opts(core, completion, buf)) { - return; - } else if (prompt_type == RZ_LINE_PROMPT_OFFSET) { - autocomplete_flags(core, completion, buf->data); - } else if (prompt_type == RZ_LINE_PROMPT_FILE) { - autocomplete_file(completion, buf->data); - } else if (!find_autocomplete(core, completion, buf)) { - autocomplete_default(core, completion, buf); - } -} - static RzLineNSCompletionResult *rzshell_autocomplete(RzLineBuffer *buf, RzLinePromptType prompt_type, void *user) { return rz_core_autocomplete_rzshell((RzCore *)user, buf, prompt_type); } @@ -2110,73 +1314,6 @@ static void rz_core_sleep_end(RzCore *core, void *user) { } } -static void __foreach(RzCore *core, const char **cmds, int type) { - int i; - for (i = 0; cmds[i]; i++) { - rz_core_autocomplete_add(core->autocomplete, cmds[i], type, true); - } -} - -static void __init_autocomplete_default(RzCore *core) { - const char *fcns[] = { - "afcf", "afn", NULL - }; - const char *seeks[] = { - "s", NULL - }; - const char *flags[] = { - "*", "s", "s+", "b", "f", "fg", "?", "?v", "ad", "bf", "c1", "db", "dbw", - "f-", "fr", "tf", "/a", "/v", "/r", "/re", "aav", "aep", "aef", - "afc", "axg", "axt", "axf", "dcu", "ag", "agfl", "aecu", "aesu", "aeim", NULL - }; - const char *evals[] = { - "e", "ee", "et", "e?", "e!", "ev", "evj", NULL - }; - const char *breaks[] = { - "db-", "dbc", "dbC", "dbd", "dbe", "dbs", "dbi", "dbte", "dbtd", "dbts", NULL - }; - const char *files[] = { - ".", "..", ".*", "/F", "/m", "!", "!!", "#!c", "#!v", "#!cpipe", "#!vala", - "#!rust", "#!zig", "#!pipe", "#!python", "aeli", "arp", "arpg", "dmd", "drp", "drpg", "o", - "idp", "idpi", "L", "obf", "o+", "oc", - "rizin", "rz-asm", "rz-ax", "rz-bin", "rz-diff", "rz-find", "rz-gg", "rz-hash", "rz-run", "rz-sign", - "cd", "ls", "on", "op", "wf", "rm", "wF", "wp", "Sd", "Sl", "to", "pm", - "/m", "zos", "zfd", "zfs", "zfz", "cat", "wta", "wtf", "wxf", "dml", "vi", - "less", "head", "Ps", "Pl", NULL - }; - __foreach(core, flags, RZ_CORE_AUTOCMPLT_FLAG); - __foreach(core, seeks, RZ_CORE_AUTOCMPLT_SEEK); - __foreach(core, fcns, RZ_CORE_AUTOCMPLT_FCN); - __foreach(core, evals, RZ_CORE_AUTOCMPLT_EVAL); - __foreach(core, breaks, RZ_CORE_AUTOCMPLT_BRKP); - __foreach(core, files, RZ_CORE_AUTOCMPLT_FILE); - - rz_core_autocomplete_add(core->autocomplete, "-", RZ_CORE_AUTOCMPLT_MINS, true); - rz_core_autocomplete_add(core->autocomplete, "fs", RZ_CORE_AUTOCMPLT_FLSP, true); - rz_core_autocomplete_add( - rz_core_autocomplete_add(core->autocomplete, "ls", RZ_CORE_AUTOCMPLT_DFLT, true), - "-l", RZ_CORE_AUTOCMPLT_FILE, true); - rz_core_autocomplete_add(core->autocomplete, "eco", RZ_CORE_AUTOCMPLT_THME, true); - rz_core_autocomplete_add(core->autocomplete, "k", RZ_CORE_AUTOCMPLT_SDB, true); - /* macros */ - rz_core_autocomplete_add(core->autocomplete, ".(", RZ_CORE_AUTOCMPLT_MACR, true); - rz_core_autocomplete_add(core->autocomplete, "(-", RZ_CORE_AUTOCMPLT_MACR, true); - /* just for hints */ - int i; - for (i = 0; i < rizin_argc && rizin_argv[i]; i++) { - if (!rz_core_autocomplete_find(core->autocomplete, rizin_argv[i], true)) { - rz_core_autocomplete_add(core->autocomplete, rizin_argv[i], RZ_CORE_AUTOCMPLT_DFLT, true); - } - } -} - -static void __init_autocomplete(RzCore *core) { - core->autocomplete = RZ_NEW0(RzCoreAutocomplete); - if (core->autocomplete_type == AUTOCOMPLETE_DEFAULT) { - __init_autocomplete_default(core); - } -} - static const char *colorfor_cb(void *user, ut64 addr, bool verbose) { return rz_core_analysis_optype_colorfor((RzCore *)user, addr, verbose); } @@ -2214,12 +1351,6 @@ static RzFlagItem *core_flg_fcn_set(RzFlag *f, const char *name, ut64 addr, ut32 return res; } -RZ_API void rz_core_autocomplete_reload(RzCore *core) { - rz_return_if_fail(core); - rz_core_autocomplete_free(core->autocomplete); - __init_autocomplete(core); -} - RZ_API RzFlagItem *rz_core_flag_get_by_spaces(RzFlag *f, ut64 off) { return rz_flag_get_by_spaces(f, off, RZ_FLAGS_FS_FUNCTIONS, @@ -2534,7 +1665,6 @@ RZ_API bool rz_core_init(RzCore *core) { } } rz_core_analysis_type_init(core); - __init_autocomplete(core); return 0; } @@ -2580,7 +1710,6 @@ RZ_API void rz_core_fini(RzCore *c) { RZ_FREE(c->lastcmd); RZ_FREE(c->stkcmd); RZ_FREE(c->block); - RZ_FREE_CUSTOM(c->autocomplete, rz_core_autocomplete_free); RZ_FREE_CUSTOM(c->gadgets, rz_list_free); RZ_FREE_CUSTOM(c->num, rz_num_free); @@ -3258,89 +2387,6 @@ RZ_API RzBuffer *rz_core_syscall(RzCore *core, const char *name, const char *arg return rz_egg_get_bin(core->egg); } -RZ_API RzCoreAutocomplete *rz_core_autocomplete_add(RzCoreAutocomplete *parent, const char *cmd, int type, bool lock) { - if (!parent || !cmd || type < 0 || type >= RZ_CORE_AUTOCMPLT_END) { - return NULL; - } - RzCoreAutocomplete *autocmpl = RZ_NEW0(RzCoreAutocomplete); - if (!autocmpl) { - return NULL; - } - RzCoreAutocomplete **updated = realloc(parent->subcmds, (parent->n_subcmds + 1) * sizeof(RzCoreAutocomplete *)); - if (!updated) { - free(autocmpl); - return NULL; - } - parent->subcmds = updated; - parent->subcmds[parent->n_subcmds] = autocmpl; - parent->n_subcmds++; - autocmpl->cmd = strdup(cmd); - autocmpl->locked = lock; - autocmpl->type = type; - autocmpl->length = strlen(cmd); - return autocmpl; -} - -RZ_API void rz_core_autocomplete_free(RzCoreAutocomplete *obj) { - if (!obj) { - return; - } - int i; - for (i = 0; i < obj->n_subcmds; i++) { - rz_core_autocomplete_free(obj->subcmds[i]); - obj->subcmds[i] = NULL; - } - free(obj->subcmds); - free((char *)obj->cmd); - free(obj); -} - -RZ_API RzCoreAutocomplete *rz_core_autocomplete_find(RzCoreAutocomplete *parent, const char *cmd, bool exact) { - if (!parent || !cmd) { - return false; - } - int len = strlen(cmd); - int i; - for (i = 0; i < parent->n_subcmds; i++) { - if (exact && len == parent->subcmds[i]->length && !strncmp(cmd, parent->subcmds[i]->cmd, len)) { - return parent->subcmds[i]; - } else if (!exact && !strncmp(cmd, parent->subcmds[i]->cmd, len)) { - return parent->subcmds[i]; - } - } - return NULL; -} - -RZ_API bool rz_core_autocomplete_remove(RzCoreAutocomplete *parent, const char *cmd) { - if (!parent || !cmd) { - return false; - } - int i, j; - for (i = 0; i < parent->n_subcmds; i++) { - RzCoreAutocomplete *ac = parent->subcmds[i]; - if (ac->locked) { - continue; - } - // if (!strncmp (parent->subcmds[i]->cmd, cmd, parent->subcmds[i]->length)) { - if (rz_str_glob(ac->cmd, cmd)) { - for (j = i + 1; j < parent->n_subcmds; j++) { - parent->subcmds[j - 1] = parent->subcmds[j]; - parent->subcmds[j] = NULL; - } - rz_core_autocomplete_free(ac); - RzCoreAutocomplete **updated = realloc(parent->subcmds, (parent->n_subcmds - 1) * sizeof(RzCoreAutocomplete *)); - if (!updated && (parent->n_subcmds - 1) > 0) { - RZ_LOG_ERROR("core: autocomplete: something really bad has happen.. this should never ever happen..\n"); - return false; - } - parent->subcmds = updated; - parent->n_subcmds--; - i--; - } - } - return false; -} - RZ_API RzTable *rz_core_table(RzCore *core) { RzTable *table = rz_table_new(); if (table) { diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index 46a31b2098..4c3a83de93 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -1224,11 +1224,6 @@ RZ_API void rz_core_task_list(RzCore *core, int mode); RZ_API bool rz_core_task_is_cmd(RzCore *core, int id); RZ_API void rz_core_task_del_all_done(RzCore *core); -RZ_API RzCoreAutocomplete *rz_core_autocomplete_add(RzCoreAutocomplete *parent, const char *cmd, int type, bool lock); -RZ_API void rz_core_autocomplete_free(RzCoreAutocomplete *obj); -RZ_API void rz_core_autocomplete_reload(RzCore *core); -RZ_API RzCoreAutocomplete *rz_core_autocomplete_find(RzCoreAutocomplete *parent, const char *cmd, bool exact); -RZ_API bool rz_core_autocomplete_remove(RzCoreAutocomplete *parent, const char *cmd); RZ_API void rz_core_analysis_propagate_noreturn(RzCore *core, ut64 addr); RZ_API bool rz_core_flirt_dump_file(RZ_NONNULL const char *flirt_file);