Untitled

 avatar
unknown
plain_text
10 months ago
3.9 kB
16
Indexable
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"

#define MAX_LINE 512

// Case-insensitive character comparison
int case_insensitive_cmp(char a, char b) {
    if (a >= 'A' && a <= 'Z') a = a - 'A' + 'a';
    if (b >= 'A' && b <= 'Z') b = b - 'A' + 'a';
    return a == b;
}

// Check if pattern matches in line (with case sensitivity option)
int matches(char *line, char *pattern, int case_insensitive) {
    char *l, *p, *l_start;
    
    for (l = line; *l; l++) {
        l_start = l;
        p = pattern;
        
        while (*p) {
            if (case_insensitive) {
                if (!case_insensitive_cmp(*l_start, *p)) break;
            } else {
                if (*l_start != *p) break;
            }
            
            l_start++;
            p++;
            
            // If we reached end of pattern, we have a match
            if (*p == '\0') return 1;
            
            // If we reached end of line, no match
            if (*l_start == '\0') break;
        }
    }
    
    return 0;
}

void grep_file(int fd, char *pattern, int flags, char *filename) {
    char buf[MAX_LINE];
    char line[MAX_LINE];
    int n, i, line_num = 1;
    int case_insensitive = flags & 1;
    int show_line_num = flags & 2;
    int invert_match = flags & 4;
    
    while ((n = read(fd, buf, sizeof(buf))) > 0) {
        for (i = 0; i < n; i++) {
            if (buf[i] == '
') {
                line[0] = '\0'; // Reset line
                int j = 0;
                
                // Read complete line
                while (j < MAX_LINE - 1 && i - j >= 0 && buf[i - j] != '
') {
                    j++;
                }
                
                if (j > 0) {
                    // Copy line content
                    int start = i - j + 1;
                    for (int k = 0; k < j; k++) {
                        line[k] = buf[start + k];
                    }
                    line[j] = '\0';
                }
                
                // Check if line matches pattern
                int match = matches(line, pattern, case_insensitive);
                if ((match && !invert_match) || (!match && invert_match)) {
                    if (show_line_num) {
                        printf("%d: ", line_num);
                    }
                    printf("%s
", line);
                }
                
                line_num++;
            }
        }
    }
}

int main(int argc, char *argv[]) {
    int flags = 0;
    char *pattern;
    int pattern_index = 1;
    
    // Parse flags
    while (pattern_index < argc && argv[pattern_index][0] == '-') {
        char *flag = argv[pattern_index];
        for (int i = 1; flag[i]; i++) {
            switch (flag[i]) {
                case 'i': flags |= 1; break;
                case 'n': flags |= 2; break;
                case 'v': flags |= 4; break;
                default:
                    printf("grep: invalid option -- '%c'
", flag[i]);
                    exit(1);
            }
        }
        pattern_index++;
    }
    
    if (pattern_index >= argc) {
        printf("Usage: grep [options] pattern [file]
");
        exit(1);
    }
    
    pattern = argv[pattern_index];
    pattern_index++;
    
    if (pattern_index < argc) {
        // Read from file
        for (; pattern_index < argc; pattern_index++) {
            int fd = open(argv[pattern_index], 0);
            if (fd < 0) {
                printf("grep: cannot open %s
", argv[pattern_index]);
                exit(1);
            }
            grep_file(fd, pattern, flags, argv[pattern_index]);
            close(fd);
        }
    } else {
        // Read from stdin (piping support)
        grep_file(0, pattern, flags, "");
    }
    
    exit(0);
}
Editor is loading...
Leave a Comment