Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix windows #26

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
/autoscan.log
/config*

tags
*.exe
*.o
.deps
.dirstamp
Expand Down
2 changes: 1 addition & 1 deletion include/ignore.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 0 additions & 2 deletions include/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions src/ignore.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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++;
Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/print.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
21 changes: 13 additions & 8 deletions src/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@ 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;
#else
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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}

Expand All @@ -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);
Expand Down
3 changes: 0 additions & 3 deletions src/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand Down