mygrep.c 3.53 KB
Newer Older
1
#define _GNU_SOURCE // in order for strcasestr to work
Ivaylo Ivanov's avatar
Ivaylo Ivanov committed
2
#include <stdio.h>
3 4
#include <stdlib.h>
#include <unistd.h>
5
#include <string.h>
6
#include "mygrep.h"
Ivaylo Ivanov's avatar
Ivaylo Ivanov committed
7

8 9 10 11 12 13 14 15 16
void main(int argc, char *argv[]) {
    check_opts_number(argc, argv);

    int iflag = 0;
    char *ofile = NULL;
    char *keyword = NULL;
    char *filename = NULL;
    int c;

17
    // Get the options
18 19 20 21 22 23 24 25 26
    while((c = getopt(argc, argv, "io:h")) != -1) {
        switch(c) {
            case 'i':
                iflag = 1;
                break;
            case 'o':
                ofile = optarg;
                break;
            case 'h':
27
                printf("Command usage:\n");
28
                print_usage();
29
                exit(EXIT_SUCCESS);
30 31 32 33 34 35 36 37 38
                break;
            case '?':
                print_usage();
                exit(EXIT_FAILURE);
            default:
                abort();
        }
    }

39
     // Check if the required argument is there
40 41 42 43 44 45 46 47 48
    if(argv[optind] == NULL) {
        printf("Mandatory argument 'keyword' missing.\n");
        print_usage();
        exit(EXIT_FAILURE);
    } else {
        keyword = argv[optind];
        filename = argv[optind + 1];
    }

49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
    // Get user input if there is no input file defined
    while(filename == NULL) {
        size_t len; // Define an unsigned string length value

        if(getline(&filename, &len, stdin)) {  // Read until new line
            check_for_string(filename, keyword, iflag, ofile);
            filename = NULL; // Reset the input
        }
    }

    // Get data from input file
    if(filename != NULL) {
        FILE *in;
        if((in = fopen(filename, "r")) == NULL) {
            printf("Error opening the file %s\n", filename);
            exit(EXIT_FAILURE);
        }

        size_t len;
        char *line = NULL; // Define a pointer to hold our value

        // Read the file line by line and execute check_for_string for each line
        while(getline(&line, &len, in) != -1) {
            check_for_string(line, keyword, iflag, ofile);
        }
74 75 76 77 78 79 80 81 82
    }

    exit(EXIT_SUCCESS);
}

void print_usage() {
    printf("mygrep [-i] [-o outfile] keyword [file...]\n");
}

83
// Check for coorect number of options
84 85 86 87 88 89 90 91 92 93 94 95
void check_opts_number(int argc, char *argv[]) {
    if(argc <= 1) {
        fprintf(stderr, "At least one argument expected.\n");
        print_usage();
        exit(EXIT_FAILURE);
    } else if(argc > 6) {
        fprintf(stderr, "Too many arguments supplied.\n");
        print_usage();
        exit(EXIT_FAILURE);
    }
}

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
void check_for_string(char *to_check, char *to_find, int iflag, char *ofile) {
    if(ofile == NULL) {
        /**
         * Find the first occurance of needle in haystack and return it as a pointer.
         * If found, print haystack
         **/
        if(iflag == 0 && strstr(to_check, to_find) != NULL)  printf("%s", to_check);
        else if(iflag == 1 && strcasestr(to_check, to_find)) printf("%s", to_check);
    } else {
        /**
         * Open the specified file for appending
         * Find the first occurance of needle in haystack and return it as a pointer.
         * If found, append haystack to the end of the file
         * Close the file
         **/
        FILE *out;

        // Check if the file was opened successfully
        if((out = fopen(ofile, "a")) == NULL) {
            printf("Error opening the file %s\n", ofile);
            exit(EXIT_FAILURE);
        }

        if(iflag == 0 && strstr(to_check, to_find)) fprintf(out, "%s", to_check);
        else if(iflag == 1 && strcasestr(to_check, to_find)) fprintf(out, "%s", to_check);

        fclose(out);
    }
Ivaylo Ivanov's avatar
Ivaylo Ivanov committed
124
}