diff --git a/.clang-tidy b/.clang-tidy index a3ecb80..72c7084 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -21,6 +21,7 @@ Checks: > -*-non-private-member-variables-in-classes, -*-magic-numbers, -concurrency-*, + -bugprone-easily-swappable-parameters, -clang-analyzer-security*, -Wpointer-bool-conversion diff --git a/samples/mini_grep.c b/samples/mini_grep.c index 801020e..34bf2f2 100644 --- a/samples/mini_grep.c +++ b/samples/mini_grep.c @@ -68,6 +68,7 @@ static bool match_line(size_t, str_view, str_view); static void search_directory(str_view, DIR *, enum io_method, str_view); static bool fill_path(char[static FILESYS_MAX_PATH], str_view, str_view); static struct file_buf get_file_buf(FILE *); +static void print_str_view(FILE *, str_view); int main(int argc, char **argv) @@ -181,7 +182,7 @@ search_directory(str_view dirname, DIR *d, enum io_method io, str_view needle) if (match_res) { (void)fprintf(stdout, PNK); - sv_print(stdout, path_view); + print_str_view(stdout, path_view); (void)fprintf(stdout, "\n\n" NONE); } } @@ -267,16 +268,16 @@ match_line(size_t lineno, str_view line, str_view needle) { (void)fprintf(stdout, CYAN "%zu:" NONE, lineno); } - sv_print(stdout, sv_substr(line, last_pos, pos - last_pos)); + print_str_view(stdout, sv_substr(line, last_pos, pos - last_pos)); (void)fprintf(stdout, RED); - sv_print(stdout, needle); + print_str_view(stdout, needle); (void)fprintf(stdout, NONE); last_pos = pos + sv_len(needle); ++pos; } if (last_pos) { - sv_print(stdout, sv_substr(line, last_pos, sv_len(line))); + print_str_view(stdout, sv_substr(line, last_pos, sv_len(line))); (void)fprintf(stdout, "\n"); } return last_pos != 0; @@ -321,3 +322,12 @@ get_file_buf(FILE *f) } return (struct file_buf){.buf = buf, .size = size}; } + +static void +print_str_view(FILE *const f, str_view const sv) +{ + if (!sv_empty(sv)) + { + (void)fwrite(sv_begin(sv), sizeof(char), sv_len(sv), f); + } +} diff --git a/str_view/str_view.c b/str_view/str_view.c index 4f2515a..bceb384 100644 --- a/str_view/str_view.c +++ b/str_view/str_view.c @@ -9,17 +9,12 @@ #include #include #include -#include #include /* Clang and GCC support static array parameter declarations while MSVC does not. This is how to solve the differing declaration signature requirements. */ #if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_LLVM_COMPILER) -/* Clang and GCC support static array parameter declarations while - MSVC does not. This is how to solve the differing declaration - signature requirements. */ - /* A static array parameter declaration helper. Function parameters may specify an array of a type of at least SIZE elements large, allowing compiler optimizations and safety errors. Specify @@ -171,18 +166,6 @@ sv_delim(char const *const str, char const *const delim) (str_view){.s = delim, .len = strlen(delim)}); } -void -sv_print(FILE *f, str_view const sv) -{ - if (!f || !sv.s || nil.s == sv.s || !sv.len) - { - return; - } - /* printf does not output the null terminator in normal strings so - as long as we output correct number of characters we do the same */ - (void)fwrite(sv.s, sizeof(char), sv.len, f); -} - str_view sv_copy(size_t const str_sz, char const *const src_str) { @@ -867,7 +850,7 @@ sv_rmemcmp(void const *const vl, void const *const vr, size_t n) /* strcspn is based on musl C-standard library implementation http://git.musl-libc.org/cgit/musl/tree/src/string/strcspn.c - A custom implemenatation is necessary because C standard library impls + A custom implementation is necessary because C standard library impls have no concept of a string view and will continue searching beyond the end of a view until null is found. This way, string searches are efficient and only within the range specified. */ @@ -1002,8 +985,6 @@ sv_rstrnstrn(ptrdiff_t const hay_sz, char const ARR_CONST_GEQ(hay, hay_sz), /*============== Post-Precomputation Two-Way Search =================*/ -/* NOLINTBEGIN(*easily-swappable*) */ - /* Definitions for Two-Way String-Matching taken from original authors: CROCHEMORE M., PERRIN D., 1991, Two-way string-matching, @@ -1342,8 +1323,6 @@ sv_rpos_normal(ptrdiff_t const hay_sz, char const ARR_CONST_GEQ(hay, hay_sz), return hay_sz; } -/* NOLINTEND(*easily-swappable*) */ - static inline struct sv_factorization sv_rmaximal_suffix(ptrdiff_t const needle_sz, char const ARR_CONST_GEQ(needle, needle_sz)) diff --git a/str_view/str_view.h b/str_view/str_view.h index a19393c..f1573c1 100644 --- a/str_view/str_view.h +++ b/str_view/str_view.h @@ -58,7 +58,6 @@ #include #include -#include /* A str_view is a read-only view of string data in C. It is modeled after the C++ std::string_view. It consists of a pointer to char const data @@ -67,7 +66,10 @@ and pass by copy whenever possible. Avoid accessing struct fields. */ typedef struct { + /* The read only data to which we point. */ char const *s; + /* The length, not including the NULL terminator position. However, it is + possible that a str_view is not NULL terminated at that position. */ size_t len; } str_view; @@ -393,9 +395,4 @@ SV_API size_t sv_find_last_of(str_view hay, str_view set) ATTRIB_PURE; in the str_view. An empty hay will return 0. */ SV_API size_t sv_find_last_not_of(str_view hay, str_view set) ATTRIB_PURE; -/*============================ Printing ==================================*/ - -/* Writes all characters in str_view to specified file such as stdout. */ -SV_API void sv_print(FILE *f, str_view sv); - #endif /* STR_VIEW */