Your task is to provide the missing implementation for functions and structures
in grep_impl.c
. The basic usage might look like this:
Grep *grep;
const char *paths[] = {"/path1", "/path2", "/some/other/path};
if (!(grep = GrepInit(recursive, paths, 3))) {
/* error */
}
if (GrepDo(grep, pattern, linenumber, filename, grepCallback) < 0) {
/* error */
}
GrepFree(grep);
Note: grepCallback() is a function that does the actual pattern matching. It's already implemented and provided for you.
The design of Grep
structure is completely up to you, just like algorithms
used. You can introduce new internal functions or macros you want. You can use
standard C library and GLib. If you allocate any memory, do not forget to free
it once no longer needed.
The GrepInit()
function allocates new Grep
structure and traverses given
paths. A path might be a file or a directory. If it's a directory and
recursive
is not zero then all files and directories within should be
traversed and added onto a list. Symlinks should not be followed. If a path is
-
then the standard input should be grepped.
If no path is given to GrepInit()
then either the standard input (recursive
= 0) or current working directory (recursive
!= 0) is grepped.
If an error occurred in GrepInit()
it should be printed out onto stderr and
the function shall return NULL.
For your convenience, example of path traversal function is provided in
grep_impl.c
.
The GrepDo()
then takes list of files generated by GrepInit()
and calls
grepCallback()
over each one of them. The grepCallback()
is in fact the
place where actual pattern matching takes place. Therefore, GrepDo()
should
pass path, pattern
, linenumber
and filename
to the callback. If the
callback fails, then no further files should be processed and GrepDo()
should
return an error. Moreover, GrepDo()
can be called multiple times (e.g. for
different patterns).
Please note, the grep callback accepts filename
variable which can have the
following values:
- 0: do NOT report filename
- 1: do report filename among with the matched line
However, when GrepDo()
is called the variable can have the following values:
- 0: default behaviour; if there is just one file to match do NOT report filename, otherwise do report it
- 1: do report filename
- 2: do NOT report filename, regardless of the number of files to match
It is up to GrepDo()
to translate given value for the callback.
For bonus points, GrepDo()
can spawn multiple threads and call the callback
in each of them, creating multithreaded grep. But remember proper locking.
Feel free to ask any questions.