Skip to content

Commit

Permalink
Add a C++ example: simple grep
Browse files Browse the repository at this point in the history
  • Loading branch information
dr8co committed Apr 11, 2024
1 parent f31e937 commit 4accd1a
Showing 1 changed file with 88 additions and 0 deletions.
88 changes: 88 additions & 0 deletions examples/cheap_grep.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <iostream>
#include <cstdint>
#include <fstream>
#include <iomanip>
#include "../lite_string.h"

/**
* @brief A simple emulation of the grep command.
*
* This function reads the input stream line by line and prints the lines that contain the specified pattern.
*
* @param pattern The pattern to search for.
* @param input The input stream to read from.
* @param ignoreCase Whether to ignore the case of the characters.
* @return 0 if the pattern is found, 1 otherwise.
*/
int cheap_grep(const lite_string *pattern, std::istream &input, bool ignoreCase) {
char line[4096];
int ret = 1;

lite_string *s = string_new();
lite_string *patternCopy = string_new();
lite_string *lineCopy = string_new();

string_copy(pattern, patternCopy);
if (ignoreCase) string_to_lower(patternCopy);


while (input.getline(line, sizeof line)) {
string_append_cstr(s, line);
string_copy(s, lineCopy);

if (ignoreCase) string_to_lower(lineCopy);

if (string_find_substr(lineCopy, patternCopy) != SIZE_MAX) {
ret = 0;
std::cout << line << '\n';
}

string_clear(s);
}
// The strings must be freed after use.
string_free(s);
string_free(patternCopy);
string_free(lineCopy);

return ret;
}

int main(int argc, char *argv[]) {
if (argc < 3) {
std::cerr << "Usage: " << argv[0] << " [-i] <pattern> <filename>\n";
return 1;
}

bool ignoreCase = false;
int argIndex = 1;
lite_string *firstArg = string_new_cstr(argv[1]);

if (argc > 3 && string_compare_cstr(firstArg, "-i")) {
ignoreCase = true;
argIndex = 2;
}

lite_string *pattern = string_new_cstr(argv[argIndex]);
lite_string *filename = string_new_cstr(argv[argIndex + 1]);
int ret = 0;

// If the filename is "-", read from stdin.
if (string_compare_cstr(filename, "-")) {
ret = cheap_grep(pattern, std::cin, ignoreCase);
} else {
std::ifstream file(string_cstr(filename));
if (!file.is_open()) {
std::cerr << "Error: Unable to open file: " << std::quoted(string_cstr(filename)) << std::endl;
ret = 1;
goto CLEANUP;
}
ret = cheap_grep(pattern, file, ignoreCase);
}

CLEANUP: // Free the strings to release the memory.
string_free(firstArg);
string_free(pattern);
string_free(filename);

return ret;
}

0 comments on commit 4accd1a

Please sign in to comment.