125 lines
3.5 KiB
C
125 lines
3.5 KiB
C
#define _GNU_SOURCE // in order for strcasestr to work
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include "mygrep.h"
|
|
|
|
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;
|
|
|
|
// Get the options
|
|
while((c = getopt(argc, argv, "io:h")) != -1) {
|
|
switch(c) {
|
|
case 'i':
|
|
iflag = 1;
|
|
break;
|
|
case 'o':
|
|
ofile = optarg;
|
|
break;
|
|
case 'h':
|
|
printf("Command usage:\n");
|
|
print_usage();
|
|
exit(EXIT_SUCCESS);
|
|
break;
|
|
case '?':
|
|
print_usage();
|
|
exit(EXIT_FAILURE);
|
|
default:
|
|
abort();
|
|
}
|
|
}
|
|
|
|
// Check if the required argument is there
|
|
if(argv[optind] == NULL) {
|
|
printf("Mandatory argument 'keyword' missing.\n");
|
|
print_usage();
|
|
exit(EXIT_FAILURE);
|
|
} else {
|
|
keyword = argv[optind];
|
|
filename = argv[optind + 1];
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
void print_usage() {
|
|
printf("mygrep [-i] [-o outfile] keyword [file...]\n");
|
|
}
|
|
|
|
// Check for coorect number of options
|
|
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);
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|