Skip to content

Commit

Permalink
llvm fsdir, + unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kuro337 committed Apr 19, 2024
1 parent 29d3bfe commit c6e6b8c
Show file tree
Hide file tree
Showing 8 changed files with 454 additions and 164 deletions.
30 changes: 19 additions & 11 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# options: https://clang.llvm.org/docs/ClangFormatStyleOptions.html
# clang-format -i <filename> to run in place - and validate Config
BasedOnStyle: LLVM
IndentWidth: 4
ColumnLimit: 120
SpaceAfterCStyleCast: true
UseTab: Never
AlignTrailingComments: true
AlignConsecutiveMacros: Consecutive
AlignConsecutiveBitFields: true
UseCRLF: false
AlignAfterOpenBracket: Align
BinPackArguments: false # false -> if fn call args exceed will be on newlines each
BinPackParameters: false # false -> if params exceed theyll be on newlines each
BreakBeforeBraces: Custom
SpaceBeforeParens: ControlStatements
PointerAlignment: Right
Expand Down Expand Up @@ -42,8 +46,9 @@ AllowShortLambdasOnASingleLine: None
AllowShortLoopsOnASingleLine: false
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true

AllowAllParametersOfDeclarationOnNextLine: true
AllowAllArgumentsOnNextLine: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
Expand All @@ -56,31 +61,34 @@ BraceWrapping:
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: true
SplitEmptyFunction: true
SplitEmptyNamespace: true
SplitEmptyRecord: true
# IndentBraces: true indents if statements to be non aligned within the body

BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
BreakStringLiterals: true
ColumnLimit: 160

### Nests Namespaces namespace Foo { namespace Bar {
CompactNamespaces: true

Cpp11BracedListStyle: true
DeriveLineEnding: false
DerivePointerAlignment: false
FixNamespaceComments: true
IncludeBlocks: Merge
# LineEnding: LF # line ending style : \n or \r\n
DerivePointerAlignment: false ## analyze for most common alignment of & and * and override PointerAlignment if diff
FixNamespaceComments: true # adds namespace comments such as // naemspace a
IncludeBlocks: Merge # sort and merge imports
IndentCaseLabels: true
IndentPPDirectives: None
IndentWrappedFunctionNames: true
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
PenaltyBreakAssignment: 16
PenaltyBreakBeforeFirstCallParameter: 2
PenaltyBreakString: 64
PenaltyExcessCharacter: 0
PenaltyBreakBeforeFirstCallParameter: 0
PenaltyBreakString: 64 # sets extra allowed cols before strings are broken onto newlines
# PenaltyExcessCharacter: 0 # sets penalty for chars once exceeding Col Limit
PenaltyReturnTypeOnItsOwnLine: 0
ReflowComments: true
16 changes: 14 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# add_compile_options(-Wno-deprecated-declarations)

# Creates header file with path to images folder
# set(IMAGE_FOLDER_PATH "images")
# configure_file(
# "${CMAKE_CURRENT_SOURCE_DIR}/image_folder_path.h.in"
# "${CMAKE_CURRENT_BINARY_DIR}/image_folder_path.h"
# @ONLY
# )

# ensure LLVM_DIR is set
macro(add_llvm_support)
set(llvm_components core support irreader)
Expand All @@ -16,6 +24,7 @@ macro(add_llvm_support)
endforeach()
endmacro()

# include_directories(${CMAKE_SOURCE_DIR}/src)

include_directories(${CMAKE_SOURCE_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
Expand Down Expand Up @@ -105,10 +114,13 @@ endif()

enable_testing()

set(TEST_EXECUTABLES tesseractparallel_test bulk_test pdf_test textractapi_tests ocr_test atomic_test similarity_test threadlocal_test)
set(TEST_EXECUTABLES fs_test
tesseractparallel_test bulk_test pdf_test
textractapi_tests ocr_test atomic_test similarity_test
threadlocal_test)

foreach(TEST_EXECUTABLE IN LISTS TEST_EXECUTABLES)
add_executable(${TEST_EXECUTABLE} tests/${TEST_EXECUTABLE}.cc)
add_executable(${TEST_EXECUTABLE} tests/${TEST_EXECUTABLE}.cc src/fs.cc)
set_target_properties(${TEST_EXECUTABLE} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests"
)
Expand Down
16 changes: 16 additions & 0 deletions docs/headers/including.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Including Headers

`src/fs.cc` and `src/fs.h`

- `.cc` must have the fn impl - (non-inline) or Visibility is Private
- `.cc` must include the Header def file `#include <fs.h>`

## Files that need Access to Funcs

- Simply add the `.cc` file to the `Add Executable` so that CMake will compile
it along with the Files

```bash
add_executable(${TEST_EXECUTABLE} tests/${TEST_EXECUTABLE}.cc src/fs.cc)

```
63 changes: 63 additions & 0 deletions src/fs.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

#include "fs.h"
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/FormatVariadic.h>
#include <llvm/Support/Path.h>

auto getFilePaths(const llvm::Twine &directoryPath) -> llvm::Expected<std::vector<std::string>> {
std::error_code ERR;
llvm::sys::fs::directory_iterator dirIt(directoryPath, ERR);

if (ERR) {
return llvm::make_error<llvm::StringError>(ERR.message(), ERR);
}

llvm::sys::fs::directory_iterator dirEnd;
std::vector<std::string> filePaths;

for (; dirIt != dirEnd && !ERR; dirIt.increment(ERR)) {
if (ERR) {
return llvm::make_error<llvm::StringError>(ERR.message(), ERR);
}
filePaths.push_back(dirIt->path());
}

return filePaths;
}
auto getFileInfo(const llvm::Twine &Path) -> llvm::Expected<llvm::sys::fs::file_status> {
llvm::sys::fs::file_status Status;
if (std::error_code ERR = llvm::sys::fs::status(Path, Status)) {
return llvm::make_error<llvm::StringError>(ERR.message(), ERR);
}
return Status;
}

auto createDirectories(const llvm::Twine &path) -> llvm::Expected<bool> {
if (auto err = llvm::sys::fs::create_directories(path); err) {
return llvm::make_error<llvm::StringError>(err.message(), err);
}
return true;
}

auto createDirectoryForFile(const llvm::Twine &filePath) -> llvm::Expected<bool> {
llvm::SmallString<256> fullPathStorage;
filePath.toVector(fullPathStorage);

llvm::StringRef fullPathRef(fullPathStorage);

llvm::StringRef directoryPathRef = llvm::sys::path::parent_path(fullPathRef);

llvm::SmallString<256> directoryPath(directoryPathRef);

if (llvm::sys::fs::exists(directoryPath)) {
return true;
}

if (auto err = llvm::sys::fs::create_directories(directoryPath); err) {
llvm::errs() << "Error creating directory '" << directoryPath << "': " << err.message() << "\n";
return llvm::make_error<llvm::StringError>(
llvm::formatv("Error creating directory {0}: {1}", directoryPath.str(), err.message()), err);
}

return true;
}
15 changes: 15 additions & 0 deletions src/fs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// fs.h
#ifndef FS_H
#define FS_H

#include <llvm/Support/FileSystem.h>

auto getFilePaths(const llvm::Twine &directoryPath) -> llvm::Expected<std::vector<std::string>>;

auto getFileInfo(const llvm::Twine &Path) -> llvm::Expected<llvm::sys::fs::file_status>;

auto createDirectories(const llvm::Twine &path) -> llvm::Expected<bool>;

auto createDirectoryForFile(const llvm::Twine &filePath) -> llvm::Expected<bool>;

#endif // FS_H
87 changes: 87 additions & 0 deletions tests/fs_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include <gtest/gtest.h>
#include <llvm/Support/Error.h>
#include <src/fs.h>

template <typename T>
auto ErrorExists(llvm::Expected<T> &expected, const std::string &errorMessage) -> bool {
if (!expected) {
llvm::Error err = expected.takeError();
std::cerr << "Assert Failure:" << errorMessage << ": " << llvm::toString(std::move(err)) << '\n';
return true;
}
return false;
}

class LLVMFsTests: public ::testing::Test {
protected:
void SetUp() override {
}

void TearDown() override {
}

public:
const std::string validFolder = "../../images";
const std::string emptyFolder = "../../empty";
};

TEST_F(LLVMFsTests, GetFilePathsEmpty) {
auto result = getFilePaths(emptyFolder);

ASSERT_FALSE(ErrorExists(result, "Expected valid result, but got an error"));

if (!result) {
llvm::Error err = result.takeError();
llvm::consumeError(std::move(err));
FAIL() << "Expected valid result, but got error.";
}
ASSERT_TRUE(result->empty()) << "Expected empty directory.";
}

TEST_F(LLVMFsTests, GetFilePaths) {
auto result = getFilePaths(validFolder);
ASSERT_FALSE(ErrorExists(result, "Valid Folder expected no Error"));

auto emptyPathResult = getFilePaths(emptyFolder);
ASSERT_FALSE(ErrorExists(emptyPathResult, "Empty Dir should cause no Errors"));

auto invalidPathResult = getFilePaths("path/to/non/existing/directory");

ASSERT_TRUE(ErrorExists(invalidPathResult, "Invalid Dir should return an Error"));
}

TEST_F(LLVMFsTests, GetFileInfo) {
auto fileInfoResult = getFileInfo(validFolder + "/imgtext.jpeg");
ASSERT_FALSE(ErrorExists(fileInfoResult, "File Info Valid"));

auto directoryInfoResult = getFileInfo(validFolder);
ASSERT_FALSE(ErrorExists(directoryInfoResult, "Dir Info Valid"));

auto nonExistentResult = getFileInfo("/path/to/non/existent/file.txt");
ASSERT_TRUE(ErrorExists(nonExistentResult, "Non Existent should Return an Error"));
}

TEST_F(LLVMFsTests, DirectoryCreationTests) {
auto existingDirResult = createDirectories(validFolder);

ASSERT_FALSE(ErrorExists(existingDirResult, "Creating existing directory should not error"));
ASSERT_TRUE(*existingDirResult);

auto newDirResult = createDirectories("llvmtest");

ASSERT_FALSE(ErrorExists(newDirResult, "Creating new directory should succeed"));
ASSERT_TRUE(*newDirResult);

auto fileInNewDir = createDirectoryForFile("llvmfiletest/mock.txt");
ASSERT_FALSE(ErrorExists(fileInNewDir, "Creating directory for new file should succeed"));
ASSERT_TRUE(*fileInNewDir);

auto fileInExistingDir = createDirectoryForFile("llvmfiletest/mock.txt");
ASSERT_FALSE(ErrorExists(fileInExistingDir, "Creating directory for an existing file should still succeed"));
ASSERT_TRUE(*fileInExistingDir);
}

auto main(int argc, char **argv) -> int {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Loading

0 comments on commit c6e6b8c

Please sign in to comment.