diff --git a/bp.c b/bp.c index 85f7176..e7fd949 100644 --- a/bp.c +++ b/bp.c @@ -4,6 +4,7 @@ // See `man ./bp.1` for more details // +#include #include #include #include @@ -96,12 +97,14 @@ __attribute__((nonnull)) static char *getflag(const char *flag, char *argv[], int *i) { size_t n = strlen(flag); - check(argv[*i], "Attempt to get flag from NULL argument"); + if (!argv[*i]) + errx(EXIT_FAILURE, "Attempt to get flag from NULL argument"); if (strncmp(argv[*i], flag, n) == 0) { if (argv[*i][n] == '=') { return &argv[*i][n+1]; } else if (argv[*i][n] == '\0') { - check(argv[*i+1], "Expected argument after '%s'\n\n%s", flag, usage); + if (!argv[*i+1]) + errx(EXIT_FAILURE, "Expected argument after '%s'\n\n%s", flag, usage); ++(*i); return argv[*i]; } @@ -116,7 +119,8 @@ static char *getflag(const char *flag, char *argv[], int *i) __attribute__((nonnull)) static int boolflag(const char *flag, char *argv[], int *i) { - check(argv[*i], "Attempt to get flag from NULL argument"); + if (!argv[*i]) + errx(EXIT_FAILURE, "Attempt to get flag from NULL argument"); if (streq(argv[*i], flag)) return 1; if (flag[0] == '-' && flag[1] != '-' && flag[2] == '\0' && argv[*i][0] == '-' && argv[*i][1] != '-') { char *p = strchr(argv[*i], flag[1]); @@ -287,10 +291,11 @@ static int inplace_modify_file(def_t *defs, file_t *f, pat_t *pattern) exit(EXIT_FAILURE); // Lazy-open file for writing upon first match: if (inplace_file == NULL) { - check(snprintf(tmp_filename, PATH_MAX, "%s.tmp.XXXXXX", f->filename) <= (int)PATH_MAX, - "Failed to build temporary file template"); + if (snprintf(tmp_filename, PATH_MAX, "%s.tmp.XXXXXX", f->filename) > (int)PATH_MAX) + errx(EXIT_FAILURE, "Failed to build temporary file template"); int out_fd = mkstemp(tmp_filename); - check(out_fd >= 0, "Failed to create temporary inplace file"); + if (out_fd < 0) + err(EXIT_FAILURE, "Failed to create temporary inplace file"); in_use_tempfile = tmp_filename; inplace_file = fdopen(out_fd, "w"); if (confirm == CONFIRM_ASK && f->filename) @@ -309,8 +314,8 @@ static int inplace_modify_file(def_t *defs, file_t *f, pat_t *pattern) // TODO: if I want to implement backup files then add a line like this: // if (backup) rename(f->filename, f->filename + ".bak"); - check(rename(tmp_filename, f->filename) == 0, - "Failed to write file replacement for %s", f->filename); + if (rename(tmp_filename, f->filename) != 0) + err(EXIT_FAILURE, "Failed to write file replacement for %s", f->filename); in_use_tempfile = NULL; } @@ -386,7 +391,8 @@ static int process_file(def_t *defs, const char *filename, pat_t *pattern) } #ifdef DEBUG_HEAP - check(recycle_all_matches() == 0, "Memory leak: there should no longer be any matches in use at this point."); + if (recycle_all_matches() != 0) + errx("Memory leak: there should no longer be any matches in use at this point."); #endif destroy_file(&f); (void)fflush(stdout); @@ -402,11 +408,11 @@ static int process_dir(def_t *defs, const char *dirname, pat_t *pattern) int matches = 0; glob_t globbuf; char globpath[PATH_MAX+1] = {'\0'}; - check(snprintf(globpath, PATH_MAX, "%s/*", dirname) <= (int)PATH_MAX, - "Filename is too long: %s/*", dirname); + if (snprintf(globpath, PATH_MAX, "%s/*", dirname) > (int)PATH_MAX) + errx(EXIT_FAILURE, "Filename is too long: %s/*", dirname); int status = glob(globpath, 0, NULL, &globbuf); - check(status != GLOB_ABORTED && status != GLOB_NOSPACE, - "Failed to get directory contents: %s", dirname); + if (status == GLOB_ABORTED || status == GLOB_NOSPACE) + err(EXIT_FAILURE, "Failed to get directory contents: %s", dirname); if (status != GLOB_NOMATCH) { struct stat statbuf; for (size_t i = 0; i < globbuf.gl_pathc; i++) { @@ -465,12 +471,14 @@ int main(int argc, char *argv[]) } else if (BOOLFLAG("-l") || BOOLFLAG("--list-files")) { mode = MODE_LISTFILES; } else if (FLAG("-r") || FLAG("--replace")) { - check(pattern, "No pattern has been defined for replacement to operate on"); + if (!pattern) + errx(EXIT_FAILURE, "No pattern has been defined for replacement to operate on"); // TODO: spoof file as sprintf("pattern => '%s'", flag) // except that would require handling edge cases like quotation marks etc. file_t *replace_file = spoof_file(&loaded_files, "", flag); pattern = bp_replacement(replace_file, pattern, replace_file->contents); - check(pattern, "Replacement failed to compile: %s", flag); + if (!pattern) + errx(EXIT_FAILURE, "Replacement failed to compile: %s", flag); } else if (FLAG("-g") || FLAG("--grammar")) { file_t *f = NULL; if (strlen(flag) > 3 && strncmp(&flag[strlen(flag)-3], ".bp", 3) == 0) @@ -479,7 +487,8 @@ int main(int argc, char *argv[]) f = load_filef(&loaded_files, "%s/.config/"BP_NAME"/%s.bp", getenv("HOME"), flag); if (f == NULL) f = load_filef(&loaded_files, "/etc/xdg/"BP_NAME"/%s.bp", flag); - check(f != NULL, "Couldn't find grammar: %s", flag); + if (f == NULL) + errx(EXIT_FAILURE, "Couldn't find grammar: %s", flag); defs = load_grammar(defs, f); // Keep in memory for debug output } else if (FLAG("-p") || FLAG("--pattern")) { file_t *arg_file = spoof_file(&loaded_files, "", flag); @@ -524,7 +533,8 @@ int main(int argc, char *argv[]) if (pattern != NULL) break; file_t *arg_file = spoof_file(&loaded_files, "", argv[argi]); pat_t *p = bp_stringpattern(arg_file, arg_file->contents); - check(p, "Pattern failed to compile: %s", argv[argi]); + if (!p) + errx(EXIT_FAILURE, "Pattern failed to compile: %s", argv[argi]); pattern = chain_together(arg_file, pattern, p); } else { printf("Unrecognized flag: %s\n\n%s\n", argv[argi], usage); @@ -545,10 +555,12 @@ int main(int argc, char *argv[]) int signals[] = {SIGTERM, SIGINT, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGSEGV, SIGTSTP}; struct sigaction sa = {.sa_handler = &sig_handler, .sa_flags = (int)(SA_NODEFER | SA_RESETHAND)}; for (size_t i = 0; i < sizeof(signals)/sizeof(signals[0]); i++) - check(sigaction(signals[i], &sa, NULL) == 0, "Failed to set signal handler"); + if (sigaction(signals[i], &sa, NULL) != 0) + err(EXIT_FAILURE, "Failed to set signal handler"); // Handle exit() calls gracefully: - check(atexit(&cleanup) == 0, "Failed to set cleanup handler at exit"); + if (atexit(&cleanup) != 0) + err(EXIT_FAILURE, "Failed to set cleanup handler at exit"); // User input/output is handled through /dev/tty so that normal unix pipes // can work properly while simultaneously asking for user input. @@ -562,7 +574,8 @@ int main(int argc, char *argv[]) (void)fflush(tty_out); char *patstr = NULL; size_t len = 0; - check(getline(&patstr, &len, tty_in) > 0, "No pattern provided"); + if (getline(&patstr, &len, tty_in) <= 0) + err(EXIT_FAILURE, "No pattern provided"); file_t *arg_file = spoof_file(&loaded_files, "", patstr); for (const char *str = arg_file->contents; str < arg_file->end; ) { def_t *d = bp_definition(defs, arg_file, str); @@ -583,7 +596,8 @@ int main(int argc, char *argv[]) free(patstr); } - check(pattern != NULL, "No pattern was given"); + if (pattern == NULL) + errx(EXIT_FAILURE, "No pattern was given"); // To ensure recursion (and left recursion in particular) works properly, // we need to define a rule called "pattern" with the value of whatever @@ -596,24 +610,29 @@ int main(int argc, char *argv[]) if (mode == MODE_JSON) printf("["); if (git_mode) { // Get the list of files from `git --ls-files ...` int fds[2]; - check(pipe(fds) == 0, "Failed to create pipe"); + if (pipe(fds) != 0) + err(EXIT_FAILURE, "Failed to create pipe"); pid_t child = fork(); - check(child != -1, "Failed to fork"); + if (child == -1) + err(EXIT_FAILURE, "Failed to fork"); if (child == 0) { char **git_args = memcheck(calloc((size_t)(2+(argc-argi)+1), sizeof(char*))); int g = 0; git_args[g++] = "git"; git_args[g++] = "ls-files"; while (argi < argc) git_args[g++] = argv[argi++]; - check(dup2(fds[STDOUT_FILENO], STDOUT_FILENO) == STDOUT_FILENO, - "Failed to hook up pipe to stdout"); - check(close(fds[STDIN_FILENO]) == 0, "Failed to close read end of pipe"); + if (dup2(fds[STDOUT_FILENO], STDOUT_FILENO) != STDOUT_FILENO) + err(EXIT_FAILURE, "Failed to hook up pipe to stdout"); + if (close(fds[STDIN_FILENO]) != 0) + err(EXIT_FAILURE, "Failed to close read end of pipe"); (void)execvp("git", git_args); _exit(EXIT_FAILURE); } - check(close(fds[STDOUT_FILENO]) == 0, "Failed to close write end of pipe"); + if (close(fds[STDOUT_FILENO]) != 0) + err(EXIT_FAILURE, "Failed to close write end of pipe"); FILE *fp = fdopen(fds[STDIN_FILENO], "r"); - check(fp != NULL, "Could not open file descriptor"); + if (fp == NULL) + err(EXIT_FAILURE, "Could not open file descriptor"); char *path = NULL; size_t size = 0; ssize_t len = 0; @@ -622,11 +641,12 @@ int main(int argc, char *argv[]) found += process_file(defs, path, pattern); } if (path) xfree(&path); - check(fclose(fp) == 0, "Failed to close read end of pipe"); + if (fclose(fp) != 0) + err(EXIT_FAILURE, "Failed to close read end of pipe"); int status; while (waitpid(child, &status, 0) != child) continue; - check((WIFEXITED(status) == 1) && (WEXITSTATUS(status) == 0), - "`git --ls-files` failed. Do you have git installed?"); + if (!((WIFEXITED(status) == 1) && (WEXITSTATUS(status) == 0))) + errx(EXIT_FAILURE, "`git --ls-files` failed. Do you have git installed?"); } else if (argi < argc) { // Files pass in as command line args: struct stat statbuf; diff --git a/definitions.c b/definitions.c index ca22b2e..c60df0d 100644 --- a/definitions.c +++ b/definitions.c @@ -2,6 +2,7 @@ // definitions.c - Code for defining named pattern rules // +#include #include #include @@ -39,7 +40,8 @@ def_t *load_grammar(def_t *defs, file_t *f) exit(EXIT_FAILURE); } size_t namelen = (size_t)(src - name); - check(matchchar(&src, ':'), "Expected ':' in definition"); + if (!matchchar(&src, ':')) + errx(EXIT_FAILURE, "Expected ':' in definition"); pat_t *pat = bp_pattern(f, src); if (pat == NULL) break; defs = with_def(defs, namelen, name, pat); diff --git a/files.c b/files.c index 0d4664a..4218c56 100644 --- a/files.c +++ b/files.c @@ -3,6 +3,7 @@ // #include +#include #include #include #include @@ -51,8 +52,8 @@ file_t *load_filef(file_t **files, const char *fmt, ...) char filename[PATH_MAX+1] = {'\0'}; va_list args; va_start(args, fmt); - check(vsnprintf(filename, PATH_MAX, fmt, args) <= (int)PATH_MAX, - "File name is too large"); + if (vsnprintf(filename, PATH_MAX, fmt, args) > (int)PATH_MAX) + errx(EXIT_FAILURE, "File name is too large"); va_end(args); return load_file(files, filename); } @@ -93,7 +94,10 @@ file_t *load_file(file_t **files, const char *filename) } finished_loading: - if (fd != STDIN_FILENO) check(close(fd) == 0, "Failed to close file"); + if (fd != STDIN_FILENO) { + if (close(fd) != 0) + err(EXIT_FAILURE, "Failed to close file"); + } f->end = &f->contents[length]; populate_lines(f); if (files != NULL) { @@ -137,8 +141,8 @@ void destroy_file(file_t **f) if ((*f)->contents) { if ((*f)->mmapped) { - check(munmap((*f)->contents, (size_t)((*f)->end - (*f)->contents)) == 0, - "Failure to un-memory-map some memory"); + if (munmap((*f)->contents, (size_t)((*f)->end - (*f)->contents)) != 0) + err(EXIT_FAILURE, "Failure to un-memory-map some memory"); (*f)->contents = NULL; } else { xfree(&((*f)->contents)); diff --git a/match.c b/match.c index c57bfcf..aac0520 100644 --- a/match.c +++ b/match.c @@ -3,6 +3,7 @@ // #include +#include #include #include #include @@ -313,7 +314,8 @@ static match_t *match(def_t *defs, file_t *f, const char *str, pat_t *pat, bool } case BP_AFTER: { ssize_t backtrack = pat->args.pat->len; - check(backtrack != -1, "'<' is only allowed for fixed-length operations"); + if (backtrack == -1) + errx(EXIT_FAILURE, "'<' is only allowed for fixed-length operations"); if (str - backtrack < f->contents) return NULL; match_t *before = match(defs, f, str - backtrack, pat->args.pat, ignorecase); if (before == NULL) return NULL; @@ -426,7 +428,8 @@ static match_t *match(def_t *defs, file_t *f, const char *str, pat_t *pat, bool } case BP_REF: { def_t *def = lookup(defs, pat->args.name.len, pat->args.name.name); - check(def != NULL, "Unknown identifier: '%.*s'", (int)pat->args.name.len, pat->args.name.name); + if (def == NULL) + errx(EXIT_FAILURE, "Unknown identifier: '%.*s'", (int)pat->args.name.len, pat->args.name.name); pat_t *ref = def->pat; pat_t rec_op = { @@ -474,7 +477,8 @@ static match_t *match(def_t *defs, file_t *f, const char *str, pat_t *pat, bool --m->refcount; } - check(m, "Match should be non-null at this point"); + if (!m) + errx(EXIT_FAILURE, "Match should be non-null at this point"); // This match wrapper mainly exists for record-keeping purposes and // does not affect correctness. It also helps with visualization of // match results. diff --git a/pattern.c b/pattern.c index ff9841f..5ecd774 100644 --- a/pattern.c +++ b/pattern.c @@ -3,6 +3,7 @@ // #include +#include #include #include #include @@ -180,7 +181,8 @@ static pat_t *bp_simplepattern(file_t *f, const char *str) pat_t *pat = _bp_simplepattern(f, str); if (pat == NULL) return pat; - check(pat->end != NULL, "pat->end is uninitialized!"); + if (pat->end == NULL) + errx(EXIT_FAILURE, "pat->end is uninitialized!"); // Expand postfix operators (if any) str = after_spaces(pat->end); @@ -503,7 +505,8 @@ pat_t *bp_stringpattern(file_t *f, const char *str) // etc.) or \\, then check for an interpolated value: if (e != str[1] || e == '\\' || e == 'N') { interp = bp_simplepattern(f, str); - check(interp, "Failed to match pattern %.*s", 2, str); + if (!interp) + errx(EXIT_FAILURE, "Failed to match pattern %.*s", 2, str); break; } else { interp = bp_simplepattern(f, str + 1); diff --git a/utils.c b/utils.c index 63a06fe..997223c 100644 --- a/utils.c +++ b/utils.c @@ -3,6 +3,7 @@ // #include +#include #include #include @@ -123,10 +124,8 @@ char unescapechar(const char *escaped, const char **end) // void *memcheck(void *p) { - if (p == NULL) { - fprintf(stderr, "memory allocation failure\n"); - exit(EXIT_FAILURE); - } + if (p == NULL) + err(EXIT_FAILURE, "memory allocation failure"); return p; } @@ -147,10 +146,8 @@ int memicmp(const void *v1, const void *v2, size_t n) // void xfree(void *p) { - if (*(void**)p == NULL) { - fprintf(stderr, "Attempt to free(NULL)\n"); - exit(EXIT_FAILURE); - } + if (*(void**)p == NULL) + errx(EXIT_FAILURE, "attempt to free(NULL)"); free(*(void**)p); p = NULL; } diff --git a/utils.h b/utils.h index 17da86e..96b1aeb 100644 --- a/utils.h +++ b/utils.h @@ -13,7 +13,6 @@ #include "match.h" #define streq(a, b) (strcmp(a, b) == 0) -#define check(cond, ...) do { if (!(cond)) { (void)fprintf(stderr, __VA_ARGS__); (void)fwrite("\n", 1, 1, stderr); exit(EXIT_FAILURE); } } while(false) #define new(t) memcheck(calloc(1, sizeof(t))) #define xcalloc(a,b) memcheck(calloc(a,b)) #define xrealloc(a,b) memcheck(realloc(a,b))