diff --git a/.gitignore b/.gitignore index 3f7764f..67054cb 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ /autoscan.log /config* +tags +*.exe *.o .deps .dirstamp diff --git a/include/ignore.h b/include/ignore.h index 43df5a9..ee164f6 100644 --- a/include/ignore.h +++ b/include/ignore.h @@ -26,7 +26,7 @@ typedef struct _ignore_hash { ignore_node *accept; } ignore_hash; -bool is_ignore(ignore_hash *hash, const char *path, const struct dirent *entry); +bool is_ignore(ignore_hash *hash, const char *path, bool is_dir, const struct dirent *entry); ignore_hash *merge_ignore_hash(ignore_hash *hash, const char *base, const char *path, int depth); ignore_hash *load_ignore_hash(const char *base, const char *path, int depth); void free_ignore_hash(ignore_hash *hash, int depth); diff --git a/include/util.h b/include/util.h index 299b3c6..f0cbb00 100644 --- a/include/util.h +++ b/include/util.h @@ -15,10 +15,8 @@ #define IS_STDOUT_REDIRECT (!isatty(STDOUT_FILENO)) #ifndef _WIN32 -#define ENTRY_ISDIR(e) (e->d_type == DT_DIR) #define IS_PATHSEP(c) (c == '/') #else -#define ENTRY_ISDIR(e) (GetFileAttributes(e->d_name) & FILE_ATTRIBUTE_DIRECTORY) #define IS_PATHSEP(c) (c == '/' || c == '\\') typedef int rlim_t; #endif diff --git a/src/ignore.c b/src/ignore.c index 37e26a0..53b4f8c 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -108,10 +108,10 @@ ignore_hash *load_ignore_hash(const char *base, const char *path, int depth) return merge_ignore_hash(NULL, base, path, depth); } -bool match_path(ignore_node *node, const char *path, const struct dirent *entry) +bool match_path(ignore_node *node, const char *path, bool base_is_dir, const struct dirent *entry) { while (node) { - if (node->is_dir && !ENTRY_ISDIR(entry)) { + if (node->is_dir && !base_is_dir) { node = node->next; continue; } @@ -137,15 +137,15 @@ bool match_path(ignore_node *node, const char *path, const struct dirent *entry) return false; } -bool is_ignore(ignore_hash *hash, const char *path, const struct dirent *entry) +bool is_ignore(ignore_hash *hash, const char *path, bool is_dir, const struct dirent *entry) { - if (match_path(hash->accept, path, entry)) { + if (match_path(hash->accept, path, is_dir, entry)) { return false; } ignore_node *node; - if (!ENTRY_ISDIR(entry)) { + if (!is_dir) { char *ext = rindex(path, '.'); if (ext && ext[1] != '\0') { ext++; @@ -161,7 +161,7 @@ bool is_ignore(ignore_hash *hash, const char *path, const struct dirent *entry) node = hash->path[(unsigned char)path[0]]; while (node) { - bool is_skip = (node->is_dir && !ENTRY_ISDIR(entry)) || + bool is_skip = (node->is_dir && !is_dir) || !node->is_root; if (is_skip) { node = node->next; @@ -176,7 +176,7 @@ bool is_ignore(ignore_hash *hash, const char *path, const struct dirent *entry) node = hash->path[(unsigned char)entry->d_name[0]]; while (node) { - bool is_skip = (node->is_dir && !ENTRY_ISDIR(entry)) || + bool is_skip = (node->is_dir && !is_dir) || !node->is_no_dir || node->is_root; if (is_skip) { @@ -190,7 +190,7 @@ bool is_ignore(ignore_hash *hash, const char *path, const struct dirent *entry) node = node->next; } - return match_path(hash->glob, path, entry); + return match_path(hash->glob, path, is_dir, entry); } ignore_node *free_ignore_hash_by_depth(ignore_node *node, int depth) diff --git a/src/print.c b/src/print.c index 7f7e12e..da2ff46 100644 --- a/src/print.c +++ b/src/print.c @@ -23,7 +23,7 @@ void print_filename(const char *filename) void print_line_number(match_line_node *match_line, int max_digit) { - char *color, sep; + char *color = NULL, sep = 0; switch (match_line->context) { case CONTEXT_NONE: color = op.color_line_number; diff --git a/src/scan.c b/src/scan.c index 8b855cd..8473b9d 100644 --- a/src/scan.c +++ b/src/scan.c @@ -29,7 +29,7 @@ void enqueue_file_exclusively(file_queue *queue, const char *filename) * Check if the directory entry is ignored by the highway. The directory is ignored if it is the * current directory or upper directory or hidden directory (started directory name with dot `.`). */ -bool is_skip_entry(const struct dirent *entry) +bool is_skip_entry(bool is_dir, const struct dirent *entry) { #ifdef HAVE_STRUCT_DIRENT_D_NAMLEN size_t len = entry->d_namlen; @@ -37,7 +37,6 @@ bool is_skip_entry(const struct dirent *entry) size_t len = strlen(entry->d_name); #endif - bool is_dir = ENTRY_ISDIR(entry); bool cur = len == 1 && entry->d_name[0] == '.'; bool up = len == 2 && entry->d_name[0] == '.' && entry->d_name[1] == '.'; bool hidden = len > 1 && entry->d_name[0] == '.' && !op.all_files; @@ -126,12 +125,14 @@ void scan_target(file_queue *queue, const char *dir_path, ignore_hash *ignores, } } + bool is_dir; struct dirent *entry; while ((entry = readdir(dir)) != NULL) { + sprintf(buf, "%s%s", base, entry->d_name); + // Some file systems ( ex. xfs ) don't support d_type, so override d_type by `lstat`. #ifndef _WIN32 if (entry->d_type == DT_UNKNOWN) { - sprintf(buf, "%s%s", base, entry->d_name); struct stat st; lstat(buf, &st); switch (st.st_mode & S_IFMT) { @@ -146,16 +147,20 @@ void scan_target(file_queue *queue, const char *dir_path, ignore_hash *ignores, } #endif +#ifndef _WIN32 + is_dir = entry->d_type == DT_DIR +#else + is_dir = GetFileAttributes(buf) & FILE_ATTRIBUTE_DIRECTORY; +#endif + // `readdir` returns also current or upper directory, but we don't need that directories, // so skip them. And also hidden directory doesn't need. - if (is_skip_entry(entry)) { + if (is_skip_entry(is_dir, entry)) { continue; } - sprintf(buf, "%s%s", base, entry->d_name); - // Check whether if the file is ignored by gitignore. If it is ignored, skip finding. - if (!op.all_files && ignores != NULL && is_ignore(ignores, buf, entry)) { + if (!op.all_files && ignores != NULL && is_ignore(ignores, buf, is_dir, entry)) { continue; } @@ -170,7 +175,7 @@ void scan_target(file_queue *queue, const char *dir_path, ignore_hash *ignores, } #endif - if (ENTRY_ISDIR(entry)) { + if (is_dir) { scan_target(queue, buf, ignores, depth + 1); } else if (is_search_target_by_entry(entry)) { enqueue_file_exclusively(queue, buf); diff --git a/src/search.c b/src/search.c index 6248612..8aae54f 100644 --- a/src/search.c +++ b/src/search.c @@ -403,7 +403,6 @@ int search(int fd, ssize_t read_len; int buf_offset = 0; int match_count = 0; - bool do_search = false; char *buf = (char *)hw_calloc(n + 1, SIZE_OF_CHAR); char *last_new_line_scan_pos = buf; char *last_line_end; @@ -432,8 +431,6 @@ int search(int fd, search_len = last_line_end - buf; } - do_search = true; - // Search the pattern and construct matching results. The results will be stored to list // `match_lines`. int count = search_buffer(