From 81c7f243a76289b46c552274e8227ac093cf2fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Rolim?= Date: Mon, 22 Feb 2021 04:42:18 -0300 Subject: [PATCH] Add framework to display detected programming languages. Very dumb initial C detection. --- Makefile | 2 +- ep.c | 17 ++++++++++++-- ep.h | 16 ++++++++++++++ git.c | 51 ++++++++++++++++++++++++++++++++++++------ lang.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 lang.c diff --git a/Makefile b/Makefile index ff80b03..713c84a 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ bindir = $(PREFIX)/bin all: ep -ep: ep.c out.c path.c git.c $(LANGUAGE) +ep: ep.c out.c path.c git.c lang.c $(LANGUAGE) install: ep install -m755 $< $(bindir)/ep diff --git a/ep.c b/ep.c index 2e29bf5..710d15a 100644 --- a/ep.c +++ b/ep.c @@ -46,9 +46,17 @@ int main(int argc, char **argv) } /* start threads for long(er) running steps */ + struct threaded_task root_lang_task = { .task = task_launch_root_lang }; pthread_t git_handle; - if (pthread_create(&git_handle, NULL, git_thread, NULL)) { - e(WARN, "couldn't create git thread", errno); + if (pthread_create(&git_handle, NULL, git_thread, &root_lang_task)) { + e(ERROR, "couldn't create git thread", errno); + return 1; + } + + pthread_t pwd_lang_handle; + if (pthread_create(&pwd_lang_handle, NULL, lang_thread, NULL)) { + e(ERROR, "couldn't create lang thread", errno); + return 1; } if (chroot) @@ -69,6 +77,11 @@ int main(int argc, char **argv) pthread_join(git_handle, NULL); print_git(); + /* programming languages */ + pthread_join(pwd_lang_handle, NULL); + if (root_lang_task.launched) pthread_join(root_lang_task.handle, NULL); + print_lang(); + /* print currently active shell jobs */ if (shell_jobs) { int n = atoi(shell_jobs); diff --git a/ep.h b/ep.h index 2f313bb..9ddb413 100644 --- a/ep.h +++ b/ep.h @@ -2,6 +2,18 @@ #define EP_H #include +#include +#include + +enum task_identity { + task_launch_root_lang, +}; + +struct threaded_task { + pthread_t handle; + sig_atomic_t launched; + enum task_identity task; +}; /* from out.c */ extern FILE *out, *outerr; @@ -18,4 +30,8 @@ void print_pwd(const char *); void *git_thread(void *); void print_git(void); +/* from lang.c */ +void *lang_thread(void *); +void print_lang(void); + #endif diff --git a/git.c b/git.c index 0f61a73..b5f454b 100644 --- a/git.c +++ b/git.c @@ -1,10 +1,11 @@ #include #include #include +#include #include "ep.h" -static char *git_branch_name, *git_status; +static char *git_branch_name, *git_status, *git_root; void print_git(void) { if (git_branch_name) { @@ -26,20 +27,29 @@ struct rlfc_data { int status; }; -static void read_line_from_command(const char *c, struct rlfc_data *d) +static void read_line_from_command(const char *cmd, struct rlfc_data *d) { - FILE *f = popen("git rev-parse --abbrev-ref HEAD 2>/dev/null", "re"); + FILE *f = popen(cmd, "re"); if (!f) return; d->l = getline(&d->line, &d->n, f); d->status = pclose(f); + + if (d->l > 0) { + d->line[d->l-1] = 0; + } } -static char *get_git_status(void); +static void *get_git_status(void *); +static void *get_git_root(void *); void *git_thread(void *arg) { + struct threaded_task *root_lang_task = arg; + /* only knows how to launch this task */ + if (root_lang_task->task != task_launch_root_lang) root_lang_task = NULL; + struct rlfc_data c = { 0 }; read_line_from_command("git rev-parse --abbrev-ref HEAD 2>/dev/null", &c); @@ -48,7 +58,7 @@ void *git_thread(void *arg) if (c.l > 0) { /* TODO: treat case where it reads HEAD */ - c.line[c.l-1] = 0; + /* line ownserhip goes to outside this function */ git_branch_name = c.line; } @@ -59,8 +69,20 @@ void *git_thread(void *arg) /* since we are in a repo, read git status; * if we add more stuff to do in repos, launch more threads */ - get_git_status(); + pthread_t status_handle, root_handle; + if (pthread_create(&status_handle, NULL, get_git_status, NULL)) + goto status_create_error; + if (pthread_create(&root_handle, NULL, get_git_root, NULL)) + goto root_create_error; + void *local_git_root; + pthread_join(root_handle, &local_git_root); + if (root_lang_task) { + root_lang_task->launched = !pthread_create(&root_lang_task->handle, NULL, lang_thread, local_git_root); + } +root_create_error: + pthread_join(status_handle, NULL); +status_create_error: return NULL; } @@ -72,8 +94,10 @@ struct statuses { }; enum status_index { added, deleted, modified_unstaged, modified_staged, untracked, status_index_n }; -static char *get_git_status(void) +static void *get_git_status(void *arg) { + (void)arg; + FILE *f = popen("git status --porcelain=v1 -z 2>/dev/null", "re"); if (!f) return NULL; @@ -116,3 +140,16 @@ static char *get_git_status(void) return git_status; } + +static void *get_git_root(void *arg) +{ + (void)arg; + + struct rlfc_data c = { 0 }; + read_line_from_command("git rev-parse --show-toplevel 2>/dev/null", &c); + + if (c.l > 0) + git_root = c.line; + + return git_root; +} diff --git a/lang.c b/lang.c new file mode 100644 index 0000000..100f97f --- /dev/null +++ b/lang.c @@ -0,0 +1,67 @@ +#include +#include +#include + +#include "ep.h" + +enum lang_index { + c_lang, + //cpp_lang, + //python_lang, + //go_lang, + lang_index_n +}; +static int c_lang_check(const char *, unsigned char); + +struct lang_check { + int (*check)(const char *, unsigned char); + char display[8]; +}; + +struct lang_check l[] = { + [c_lang] = { .check = c_lang_check, .display = " C" }, +}; + +/* bitmap of 1<d_name, item->d_type) << i; + } + } + + return NULL; +} + +static inline int isfile(unsigned char t) { return t & (DT_REG | DT_LNK); } + +static int c_lang_check(const char *s, unsigned char t) +{ + return isfile(t) && !fnmatch("*.c", s, 0); +}