/* * runfile - rf * * a no-dependancy, minimal * POSIX C99 Make/justfile * alternative to run commands. * * czjstmax * * * check MAINTAINERS file */ #define _POSIX_C_SOURCE 200809L #define RUNFILE_VER_MAJ 1 /* anything that changes how rfile are written in the slightest */ #define RUNFILE_VER_MIN 1 /* anything that varies the UX of the program (i.e. CLI flags) */ #define RUNFILE_VER_FIX 20 /* optimizations, slight logic tweaks, anything that is not */ /* noticeable by the user but impacts the dev experience enough */ #include /* to be important */ #include #include #include #include #include #include #include void usage(); int main(int argc, char **argv) { char *section = NULL; bool in_section = false; bool should_run = false; // check cli arguments // if (argc < 2) { // printf(" not enough arguments.\n"); // usage(); // return 1; // } if (argc >= 2) { for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { usage(); return 0; } } } FILE *f = fopen("rfile", "r"); if (!f) { fprintf(stderr, "no rfile found.\n"); return 1; } wordexp_t p; char *line = NULL; size_t len = 0; while (getline(&line, &len, f) != -1) { line[strcspn(line, "\n")] = '\0'; char *cmd = line; while (isspace(*cmd)) cmd++; if (*cmd == '\0') continue; else if (cmd[0] == '#') continue; else if (strncmp(cmd, "@:", 2) == 0) { for (size_t i = 0; i < strlen(cmd); i++) printf("-"); printf("\n%s\n", cmd); for (size_t i = 0; i < strlen(cmd); i++) printf("-"); printf("\n\n"); continue; } else if (strcmp(cmd, "}") == 0 || strcmp(line, "}") == 0) { in_section = false; free(section); section = NULL; continue; } char *brace = strchr(cmd, '{'); if (brace) { *brace = '\0'; size_t l = strlen(cmd); while (l > 0 && (cmd[l-1] == ' ' || cmd[l-1] == '\t')) { cmd[l-1] = '\0'; l--; } free(section); section = strdup(cmd); in_section = true; continue; } should_run = false; if (argc == 1) { should_run = !in_section; } else { should_run = in_section && section && strcmp(argv[1], section) == 0; } if (!should_run) continue; printf("$ %s\n", cmd); if (wordexp(cmd, &p, 0) != 0) { fprintf(stderr, "wordexp failed\n"); continue; } pid_t pid = fork(); if (pid == 0) { execvp(p.we_wordv[0], p.we_wordv); perror("failed to run command"); fclose(f); _exit(1); } waitpid(pid, NULL, 0); wordfree(&p); } free(line); fclose(f); return 0; } void usage() { printf( "runfile usage - version %d.%d.%d\n" "syn: rf [section]\n" , RUNFILE_VER_MAJ, RUNFILE_VER_MIN, RUNFILE_VER_FIX ); }