function alias_eval(alias, name, type) { text = alias "() { " if (type == "function") { text = text name " \"${@}\"" } else if (type == "variable") { text = text "echo \"${" name "}\"" } print text "; }" } function append(line) { if (doc) { doc = doc "\n" } doc = doc line } function extract(string, type) { if (type == "alias") { split(string, array, "#=") return trim(array[2]) } else if (type == "command") { split(string, array, "#/") return trim(array[2]) } else if (type == "doc") { split(string, array, "#") return trim(array[2]) } else if (type == "function") { split(string, array, "(") return trim(array[1]) } else if (type == "module") { split(string, array, "#\\.") return trim(array[2]) } else if (type == "shebang") { split(string, array, "#!") return trim(array[2]) } else if ((type == "constant") || (type == "variable")) { split(string, array, "=") return trim(array[1]) } } function output(name, type) { print "↙ " type print name print doc exit } function reset() { if (f == "") { doc = "" } } function trim(string) { text = string sub("^[\t ]*", "", text) sub("[\t ]*$", "", text) return text } BEGIN { RE_ANY = "(.*)" RE_BEGIN = "^" RE_CONST = "([_A-Z][_0-9A-Z]*)" RE_SET = "=.*" RE_SPACE = "[[:space:]]" RE_TSK = "(FIXME|TODO)" RE_VAR = "([_a-z][_0-9a-z]*)" RE_SPACES = RE_SPACE "*" RE_END = RE_SPACES "$" RE_FUNC = RE_SPACES "\\(" RE_SPACES "\\)" RE_SPACES "{" re["alias"] = RE_BEGIN "#=" RE_SPACES RE_VAR RE_END re["binary"] = RE_BEGIN "#\\|" RE_SPACES RE_VAR RE_END RE_CLOSE = RE_BEGIN "}" RE_SPACES RE_END re["command"] = RE_BEGIN "#/" RE_SPACES RE_VAR RE_END RE_COMMENT = RE_BEGIN "#" RE_ANY RE_END re["constant"] = RE_BEGIN RE_CONST RE_SET RE_END RE_DOC = RE_BEGIN RE_SPACES "#" RE_SPACE RE_ANY RE_END re["function"] = RE_BEGIN RE_VAR RE_FUNC RE_END RE_MODULE = RE_BEGIN "#\\." RE_SPACES RE_ANY RE_END RE_SHEBANG = RE_BEGIN "#!" RE_SPACES RE_ANY RE_END RE_TASK = RE_BEGIN RE_SPACES "#" RE_SPACES RE_TSK RE_ANY RE_END re["variable"] = RE_BEGIN RE_VAR RE_SET RE_END f = "" match_alias = 0 match_command = 0 match_module = 0 match_task = 0 reset() } { if (action == "filter") { if (match($0, re[target])) { unique[extract($0, target)] = "" } } else if (action == "tasks") { if (match($0, RE_MODULE)) { if (output_tasks) { print "" print output_module print output_tasks output_tasks = "" } doc = "" match_task = 0 output_module = ". " extract($0, "module") } else if (match($0, RE_TASK)) { if (target) { if (target == extract($0, "task")) { match_task = 1 } } else { match_task = 1 } append($0) } else if (match($0, RE_COMMENT)) { append($0) } else { if (match_task) { output_tasks = output_tasks "\n" doc } doc = "" match_task = 0 } } else if (action == "eval") { if (match($0, re[target])) { append(extract($0, target)) } else if (match($0, re["function"])) { split(doc, array, "\n") for (item in array) { alias_eval(array[item], extract($0, "function"), "function") } reset() } else { reset() } } else if (action == "function") { if (match($0, re["command"])) { append(extract($0, "command")) } else if (match($0, re["function"])) { split(doc, array, "\n") for (item in array) { if (array[item] == target) { print extract($0, "function") exit } } reset() } else { reset() } } else if (action == "doc") { # doc if (match($0, RE_SHEBANG)) { append("! " extract($0, "shebang")) } else if (match($0, RE_DOC)) { if (f) { append($0) } else { append(extract($0, "doc")) } } else if (match($0, re["alias"])) { matched = extract($0, "alias") append("= " matched) if (matched == target) { match_alias = 1 } } else if (match($0, re["command"])) { matched = extract($0, "command") append("/ " matched) if (matched == target) { match_command = 1 } # set } else if (match($0, re["constant"])) { matched = extract($0, "constant") if (matched == target) { output(matched, "constant") } else { reset() } } else if (match($0, re["variable"])) { matched = extract($0, "variable") if (matched == target) { output(matched, "variable") } else { reset() } # others } else if (match($0, RE_MODULE, m)) { reset() if (m[1] == target) { match_module = 1 } } else if (match($0, re["function"], m)) { f = m[1] } else if (match($0, RE_CLOSE, m)) { if (match_alias) { print "= " target output(f, "function") } else if (match_command) { print "/ " target output(f, "function") } else if (f == target) { output(f, "function") } else { f = "" reset() } } else { if (match_module) { output(target, "module") } else { reset() } } } } END { if (action == "filter") { for (item in unique) { print item } } }