From a2a39cb2287a29767fa3bc98d05f01430c668362 Mon Sep 17 00:00:00 2001 From: Elis Eriksson Date: Thu, 26 Mar 2026 19:08:03 +0100 Subject: slight changes, idk how to write proper commit messages hehe --- lang.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 lang.c (limited to 'lang.c') diff --git a/lang.c b/lang.c new file mode 100644 index 0000000..c828be2 --- /dev/null +++ b/lang.c @@ -0,0 +1,169 @@ +#define USE_THE_REPOSITORY_VARIABLE + +#include "cgit.h" +#include "html.h" +#include "ui-shared.h" +#include "ui-tree.h" +#include +#include + +/* Mapping of file extensions to languages */ +struct lang_extension { + const char *ext; + const char *lang; +}; + +static const struct lang_extension lang_map[] = {{"c", "C"}, + {"h", "C"}, + {"js", "JavaScript"}, + {"jsx", "JavaScript"}, + {"py", "Python"}, + {"go", "Go"}, + {"rs", "Rust"}, + {"rb", "Ruby"}, + {"java", "Java"}, + {"ts", "TypeScript"}, + {"tsx", "TypeScript"}, + {"cpp", "C++"}, + {"cc", "C++"}, + {"cxx", "C++"}, + {"cs", "C#"}, + {"php", "PHP"}, + {"sh", "Shell"}, + {"bash", "Shell"}, + {"lua", "Lua"}, + {"vim", "VimL"}, + {"clj", "Clojure"}, + {"scala", "Scala"}, + {"kt", "Kotlin"}, + {"swift", "Swift"}, + {"m", "Objective-C"}, + {"pl", "Perl"}, + {"r", "R"}, + {"sql", "SQL"}, + {"html", "HTML"}, + {"htm", "HTML"}, + {"css", "CSS"}, + {"scss", "SCSS"}, + {"json", "JSON"}, + {"yaml", "YAML"}, + {"yml", "YAML"}, + {"md", "Markdown"}, + {"rst", "ReStructuredText"}, + {NULL, NULL}}; + +struct lang_count { + const char *lang; + int count; +}; + +struct lang_detect_context { + struct lang_count counts[100]; + int count_nr; + int total_files; + int max_count; + const char *primary_lang; +}; + +static const char *get_lang_from_ext(const char *filename) { + const char *ext = strrchr(filename, '.'); + if (!ext || ext == filename) + return NULL; + + ext++; /* skip the dot */ + + for (int i = 0; lang_map[i].ext; i++) { + if (!strcasecmp(ext, lang_map[i].ext)) + return lang_map[i].lang; + } + return NULL; +} + +static void count_language(struct lang_detect_context *ctx, const char *lang) { + int i, found = 0; + + if (!lang) + return; + + ctx->total_files++; + + /* Find or add language in counts */ + for (i = 0; i < ctx->count_nr; i++) { + if (!strcmp(ctx->counts[i].lang, lang)) { + ctx->counts[i].count++; + if (ctx->counts[i].count > ctx->max_count) { + ctx->max_count = ctx->counts[i].count; + ctx->primary_lang = ctx->counts[i].lang; + } + found = 1; + break; + } + } + + if (!found && ctx->count_nr < 100) { + ctx->counts[ctx->count_nr].lang = lang; + ctx->counts[ctx->count_nr].count = 1; + if (1 > ctx->max_count) { + ctx->max_count = 1; + ctx->primary_lang = lang; + } + ctx->count_nr++; + } +} + +static int count_files_cb(const struct object_id *oid, struct strbuf *base, + const char *pathname, unsigned mode, void *cbdata) { + struct lang_detect_context *ctx = cbdata; + const char *lang; + + /* Skip directories */ + if (S_ISDIR(mode)) + return READ_TREE_RECURSIVE; + + /* Skip hidden files */ + if (pathname[0] == '.') + return 0; + + lang = get_lang_from_ext(pathname); + count_language(ctx, lang); + + return 0; +} + +void detect_repo_languages(struct cgit_repo *repo) { + struct object_id oid; + struct commit *commit; + struct tree *tree; + struct pathspec paths = {.nr = 0}; + struct lang_detect_context ctx; + + if (!repo->defbranch) + return; + + memset(&ctx, 0, sizeof(ctx)); + + /* Get the commit for the default branch */ + if (repo_get_oid(the_repository, repo->defbranch, &oid)) + return; + + commit = lookup_commit_reference(the_repository, &oid); + if (!commit) + return; + + if (repo_parse_commit(the_repository, commit)) + return; + + tree = repo_get_commit_tree(the_repository, commit); + if (!tree) + return; + + /* Walk the tree and count file extensions */ + read_tree(the_repository, tree, &paths, count_files_cb, &ctx); + + /* Store results in repo */ + if (ctx.primary_lang) { + repo->primary_lang = xstrdup(ctx.primary_lang); + repo->lang_confidence = + ctx.total_files > 0 ? (100 * ctx.max_count) / ctx.total_files : 0; + } +} -- cgit v1.3-7-ge9ab