Changeset 5925


Ignore:
Timestamp:
Mar 21, 2018, 4:53:30 PM (14 months ago)
Author:
cameron
Message:

File processing for wc - recursive option

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/wc.cpp

    r5924 r5925  
    11/*
    2  *  Copyright (c) 2015 International Characters.
     2 *  Copyright (c) 2018 International Characters.
    33 *  This software is licensed to the public under the Open Software License 3.0.
    44 *  icgrep is a trademark of International Characters.
     
    77#include <iostream>
    88#include <iomanip>
    9 #include <sstream>
     9#include <vector>
     10#include <string>
    1011#include <toolchain/toolchain.h>
    1112#include <llvm/IR/Function.h>
     
    2425#include <toolchain/cpudriver.h>
    2526#include <fcntl.h>
     27#include <boost/filesystem.hpp>
    2628
    2729using namespace llvm;
     
    2931static cl::OptionCategory wcFlags("Command Flags", "wc options");
    3032
    31 cl::list<std::string> inputFiles(cl::Positional, cl::desc("<input file ...>"), cl::OneOrMore, cl::cat(wcFlags));
     33static cl::list<std::string> inputFiles(cl::Positional, cl::desc("<input file ...>"), cl::OneOrMore, cl::cat(wcFlags));
     34
     35std::vector<std::string> allFiles;
    3236
    3337enum CountOptions {
     
    4448static std::string wc_modes = "";
    4549
    46 static int defaultFieldWidth = 7;  // default field width
     50static int defaultDisplayColumnWidth = 7;  // default field width
     51
     52
     53bool RecursiveFlag;
     54static cl::opt<bool, true> RecursiveOption("r", cl::location(RecursiveFlag), cl::desc("Recursively process files within directories, (but follow only top-level symlinks unless -R)."), cl::cat(wcFlags), cl::Grouping);
     55static cl::alias RecursiveAlias("recursive", cl::desc("Alias for -r"), cl::aliasopt(RecursiveOption));
     56
     57bool DereferenceRecursiveFlag;
     58static cl::opt<bool, true> DereferenceRecursiveOption("R", cl::location(DereferenceRecursiveFlag), cl::desc("Recursively process files within directories, following symlinks at all levels."), cl::cat(wcFlags), cl::Grouping);
     59static cl::alias DereferenceRecursiveAlias("dereference-recursive", cl::desc("Alias for -R"), cl::aliasopt(DereferenceRecursiveOption));
     60
     61
     62// This is a stub, to be expanded later.
     63bool excludeDirectory(boost::filesystem::path dirpath) { return dirpath.filename() == ".svn";}
     64
     65// Determine whether to skip a path based on -D skip or -d skip settings.
     66bool skip_path(boost::filesystem::path p) {
     67    using namespace boost::filesystem;
     68    switch (status(p).type()) {
     69        case directory_file: return !(RecursiveFlag|DereferenceRecursiveFlag);
     70        case block_file:
     71        case character_file:
     72        case fifo_file:
     73        case socket_file:
     74            return true;
     75        default:
     76            return false;
     77    }
     78}
     79
     80
     81std::vector<std::string> getFullFileList(cl::list<std::string> & inputFiles) {
     82    using namespace boost::filesystem;
     83    symlink_option follow_symlink = DereferenceRecursiveFlag ? symlink_option::recurse : symlink_option::none;
     84    std::vector<std::string> expanded_paths;
     85    boost::system::error_code errc;
     86    for (const std::string & f : inputFiles) {
     87        //        if (f == "-") {
     88        //            continue;
     89        //        }
     90        path p(f);
     91        if (skip_path(p)) {
     92            continue;
     93        }
     94        if (LLVM_UNLIKELY((RecursiveFlag || DereferenceRecursiveFlag) && is_directory(p))) {
     95            if (!excludeDirectory(p)) {
     96                recursive_directory_iterator di(p, follow_symlink, errc), end;
     97                if (errc) {
     98                    // If we cannot enter the directory, keep it in the list of files.
     99                    expanded_paths.push_back(f);
     100                    continue;
     101                }
     102                while (di != end) {
     103                    auto & e = di->path();
     104                    if (is_directory(e)) {
     105                        if (LLVM_UNLIKELY(excludeDirectory(e))) {
     106                            di.no_push();
     107                        }
     108                    } else {
     109                        if (!skip_path(e)) expanded_paths.push_back(e.string());
     110                    }
     111                    di.increment(errc);
     112                    if (errc) {
     113                        expanded_paths.push_back(e.string());
     114                    }
     115                }
     116            }
     117        } else {
     118            expanded_paths.push_back(p.string());
     119        }
     120    }
     121    return expanded_paths;
     122}
     123
     124
     125
    47126
    48127
     
    202281
    203282void wc(WordCountFunctionType fn_ptr, const int64_t fileIdx) {
    204     std::string fileName = inputFiles[fileIdx];
     283    std::string fileName = allFiles[fileIdx];
    205284    const int fd = open(fileName.c_str(), O_RDONLY);
    206285    if (LLVM_UNLIKELY(fd == -1)) {
     
    241320    auto wordCountFunctionPtr = reinterpret_cast<WordCountFunctionType>(pxDriver.getMain());
    242321
    243     const auto fileCount = inputFiles.size();
     322    allFiles = getFullFileList(inputFiles);
     323    const auto fileCount = allFiles.size();
    244324    lineCount.resize(fileCount);
    245325    wordCount.resize(fileCount);
     
    259339   
    260340   
    261     int fieldWidth = std::to_string(maxCount).size() + 1;
    262     if (fieldWidth < defaultFieldWidth) fieldWidth = defaultFieldWidth;
    263 
    264     for (unsigned i = 0; i < inputFiles.size(); ++i) {
    265         std::cout << std::setw(fieldWidth-1);
     341    int displayColumnWidth = std::to_string(maxCount).size() + 1;
     342    if (displayColumnWidth < defaultDisplayColumnWidth) displayColumnWidth = defaultDisplayColumnWidth;
     343
     344    for (unsigned i = 0; i < fileCount; ++i) {
     345        std::cout << std::setw(displayColumnWidth-1);
    266346        if (CountLines) {
    267             std::cout << lineCount[i] << std::setw(fieldWidth);
     347            std::cout << lineCount[i] << std::setw(displayColumnWidth);
    268348        }
    269349        if (CountWords) {
    270             std::cout << wordCount[i] << std::setw(fieldWidth);
     350            std::cout << wordCount[i] << std::setw(displayColumnWidth);
    271351        }
    272352        if (CountChars) {
    273             std::cout << charCount[i] << std::setw(fieldWidth);
     353            std::cout << charCount[i] << std::setw(displayColumnWidth);
    274354        }
    275355        if (CountBytes) {
    276356            std::cout << byteCount[i];
    277357        }
    278         std::cout << " " << inputFiles[i] << std::endl;
     358        std::cout << " " << allFiles[i] << std::endl;
    279359    }
    280360    if (inputFiles.size() > 1) {
    281         std::cout << std::setw(fieldWidth-1);
     361        std::cout << std::setw(displayColumnWidth-1);
    282362        if (CountLines) {
    283             std::cout << TotalLines << std::setw(fieldWidth);
     363            std::cout << TotalLines << std::setw(displayColumnWidth);
    284364        }
    285365        if (CountWords) {
    286             std::cout << TotalWords << std::setw(fieldWidth);
     366            std::cout << TotalWords << std::setw(displayColumnWidth);
    287367        }
    288368        if (CountChars) {
    289             std::cout << TotalChars << std::setw(fieldWidth);
     369            std::cout << TotalChars << std::setw(displayColumnWidth);
    290370        }
    291371        if (CountBytes) {
Note: See TracChangeset for help on using the changeset viewer.