Listing 9 Extract from whereis.cpp
* Copyright (C) 2002, Synesis Software Pty Ltd.
* Copyright (C) 1987-2002, Digital Mars.
*
* www: http://www.synesis.com.au
* http://www.digitalmars.com/
*
*/
// struct trace_file
//
// This functional traces individual file records to stdout.
struct trace_file
: public unary_function<findfile_sequence_a::value_type const&, void>
{
public:
trace_file(bool bVerbose)
: m_bVerbose(bVerbose)
{}
void operator ()(findfile_sequence_a::value_type const &value)
{
if(m_bVerbose)
{
...
}
else
{
fprintf(stdout, "%s\n", c_str_ptr(value));
}
}
// Members
protected:
ws_bool_t m_bVerbose;
};
// struct process_searchspec
//
// This functional processes a search-spec within a given directory,
// passing any file to be processed by trace_file.
struct process_searchspec
: public unary_function<tokeniser_type::value_type const&, void>
{
public:
process_searchspec(char const *path, ws_bool_t bVerbose)
: m_path(path)
, m_bVerbose(bVerbose)
{}
void operator ()(tokeniser_type::value_type const &value)
{
findfile_sequence_a files(m_path, c_str_ptr(value),
findfile_sequence_a::files);
for_each(files.begin(), files.end(), trace_file(m_bVerbose));
}
// Members
protected:
char const *const m_path;
ws_bool_t m_bVerbose;
};
// struct process_path
//
// This functional creates a search sequence for each path, and
// then processes each one with the trace_file functional.
struct process_path
: public unary_function<searchpath_sequence_a::value_type const&, void>
{
public:
process_path(char const *searchSpec, ws_bool_t bVerbose)
: m_searchSpec(searchSpec)
, m_bVerbose(bVerbose)
{}
void operator ()(searchpath_sequence_a::value_type const &value)
{
// Now split with the string_tokeniser into all the constituent
tokeniser_type specs(m_searchSpec, ';');
for_each(specs.begin(), specs.end(),
process_searchspec(value, m_bVerbose));
}
// Members
protected:
char const *const m_searchSpec;
ws_bool_t m_bVerbose;
};
// struct trace_dir
//
// This functional provides processing of a directory, used by the
// recursive option. It processes the current directory (via
// process_path), and then all subdirectories (via process_path),
// before calling itself recursively.
struct trace_dir
: public unary_function<char const *, void>
{
public:
trace_dir(char const *searchSpec, ws_bool_t bVerbose)
: m_searchSpec(searchSpec)
, m_bVerbose(bVerbose)
{}
void operator ()(char const *value)
{
process_path f(m_searchSpec, m_bVerbose);
f(value);
findfile_sequence_a directories(value, "*.*",
findfile_sequence_a::directories);
for_each(directories.begin(), directories.end(),
process_path(m_searchSpec, m_bVerbose));
for_each(directories.begin(), directories.end(),
trace_dir(m_searchSpec, m_bVerbose));
}
protected:
char const *const m_searchSpec;
ws_bool_t m_bVerbose;
};
int main(int argc, char **argv)
{
...
if(bSearchPathsOnly)
{
typedef vector<searchpath_sequence_a::value_type> searchpath_vector;
// Get the search paths sequence ...
searchpath_sequence_a paths;
// ... and copy all the elements into a vector
searchpath_vector sorted(paths.begin(), paths.end());
// Remove any duplicates. This is necessary since the
// PATH environment variable may contain duplicate elements
remove_duplicates_from_unordered_sequence(sorted,
compare_path<searchpath_sequence_a::char_type>());
// Now execute over the duplicate-free (but still in the correct search
// order) sequence, applying the process_path functional to each one.
for_each(sorted.begin(), sorted.end(), process_path(searchSpec, bVerbose));
}
...
}