diff --git a/.gitignore b/.gitignore index 572a9d1..2b5aa6a 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,4 @@ vendor # C++ stuff *.bin -*.bin.dSYM \ No newline at end of file +*.bin.dSYM diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0a48ffc --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,28 @@ + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.0.1 # Use the ref you want to point at + hooks: + - id: trailing-whitespace + - id: check-merge-conflict + - id: check-yaml + - id: end-of-file-fixer + - id: mixed-line-ending + - id: trailing-whitespace + - id: check-added-large-files + args: ['--maxkb=123'] + +# Disabled clang formatting since it requires clang to be installed +# separately which isn't compatible with pre-commit cloud +# +# - repo: https://github.com/pocc/pre-commit-hooks +# rev: v1.3.4 +# hooks: +# - id: clang-format +# args: [--style=Google] +# - id: clang-tidy +# - id: oclint +# - id: uncrustify +# - id: cppcheck +# - id: cpplint +# - id: include-what-you-use diff --git a/.travis.yml b/.travis.yml index df60cfb7..a337cbd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ language: ruby script: - bundle install - - bundle exec arduino_ci_remote.rb \ No newline at end of file + - bundle exec arduino_ci_remote.rb diff --git a/Gemfile b/Gemfile index e8740e0..fb422d1 100644 --- a/Gemfile +++ b/Gemfile @@ -1,2 +1,2 @@ source 'https://rubygems.org' -gem 'arduino_ci' \ No newline at end of file +gem 'arduino_ci' diff --git a/LICENSE.txt b/LICENSE.txt index 30ace6a..9cecc1d 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read -. \ No newline at end of file +. diff --git a/README.md b/README.md index 5b32272..b82a382 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Overly Simplified File System (OSFS) ==================================== Provides an extremely basic, low footprint file system for EEPROM access in -an Arduino or other AVR microprocessor. Could be ported to other architectures very easily. +an Arduino or other AVR microprocessor. Could be ported to other architectures very easily. Note ---- @@ -19,12 +19,12 @@ and `writeNBytes` functions to interface the library with your storage medium. Usage ----- -The user must define interface functions to read / write from the memory in use. -This means that OSFS can be used for arbitrary storage media, including external -hardware interfaced by e.g. SPI. +The user must define interface functions to read / write from the memory in use. +This means that OSFS can be used for arbitrary storage media, including external +hardware interfaced by e.g. SPI. -To use OSFS with the Arduino EEPROM, copy the function definitions from the examples -into your program header. +To use OSFS with the Arduino EEPROM, copy the function definitions from the examples +into your program header. Datatypes can be stored using the command `newFile`, e.g. @@ -44,9 +44,9 @@ OSFS will refuse to deal with your ROM unless it has first been `format()`ed: OSFS::format(); -All OSFS functions return an `enum class result` which will give you more information -if they fail. E.g. - +All OSFS functions return an `enum class result` which will give you more information +if they fail. E.g. + using namespace OSFS; r = getFile("testInt", testInt); @@ -56,13 +56,13 @@ if they fail. E.g. else if (r == result::NO_ERROR) // File found else { - // Another error occurred. + // Another error occurred. // See OSFS.h for a full list of error codes int errCode = (int) r; } The OSFS functions `newFile` and `getFile` use templates to accept any data type, including -custom classes or structs. See the example `writeTest.ino` for details. +custom classes or structs. See the example `writeTest.ino` for details. Alternatively, `newFile` can write a given number of bytes into storage, starting at a given location. This is particularly useful for storing strings, e.g.: @@ -106,13 +106,13 @@ Each file has a header of n bytes: `Size of file` and `pointer to next` are both present because a file may not necessarily fill all the available space, e.g. if it has been overwritten with a smaller file. As of v1.2, overwriting with a larger file is supported if -there is a sufficiently large continuous space available to place it in. +there is a sufficiently large continuous space available to place it in. The first 4 bytes of EEPROM are reserved for information about this library: Bytes 1 to 4 = "OSFS" Bytes 5 to 6 = uint16_t containing version info. Unless these 6 bytes match their expected values, this library will consider -the EEPROM to be unformatted and will refuse to work with it until format() is called. +the EEPROM to be unformatted and will refuse to work with it until format() is called. Interface functions ------------------- @@ -124,37 +124,37 @@ backwards compatibility), these can be used to access any type of storage medium, not just EEPROM. The example files show how this can be done for accessing the built-in EEPROM on an AVR device. The tests show how to point them at a chunk of RAM instead (slightly pointless in real life, since the -contents would be lost on power-off). +contents would be lost on power-off). To define your own interface, copy the following definitions into your code: ``` // Here we define the four pieces of information that OSFS needs to make a filesystem: -// +// // 1) and 2) How large is the storage medium? uint16_t OSFS::startOfEEPROM = 1; uint16_t OSFS::endOfEEPROM = 1024; // 3) How do I read from the medium? void OSFS::readNBytes(uint16_t address, unsigned int num, byte* output) { - ... code that copies `num` bytes from your storage medium + ... code that copies `num` bytes from your storage medium at `address` into the waiting array `output` ... } // 4) How to I write to the medium? void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte* input) { - ... code that copies `num` bytes from the array `input` + ... code that copies `num` bytes from the array `input` into `address` on your storage medium ... } ``` -You don't need to include checks for overflowing your memory bounds in `readNBytes` and `writeNBytes` since OSFS will check `address` and `num` against the `startOfEEPROM` and `endOfEEPROM` constants you provide. +You don't need to include checks for overflowing your memory bounds in `readNBytes` and `writeNBytes` since OSFS will check `address` and `num` against the `startOfEEPROM` and `endOfEEPROM` constants you provide. Once these four components are defined, OSFS will now manage that chunk of your storage medium. Call `OSFS::format()` to get going and follow the examples for tips. Note that you don't have to provide OSFS with the whole thing: it's just as happy managing a small piece of your memory as it is -managing all of it. +managing all of it. diff --git a/examples/readTest/readTest.ino b/examples/readTest/readTest.ino index d80b54e..d5cb0d7 100644 --- a/examples/readTest/readTest.ino +++ b/examples/readTest/readTest.ino @@ -50,7 +50,7 @@ void setup() { //////////////////////////// Serial.println(F("Looking for testInt...")); - + int testInt; r = OSFS::getFile("testInt", testInt); @@ -67,7 +67,7 @@ void setup() { //////////////////////////// Serial.println(F("Looking for testStr...")); - + char testStr[15]; uint16_t filePtr, fileSize; r = OSFS::getFileInfo("testStr", filePtr, fileSize); @@ -95,7 +95,7 @@ void setup() { }; complexType testCplx; - + r = OSFS::getFile("testCplx", testCplx); if (r == notfound) diff --git a/examples/writeTest/writeTest.ino b/examples/writeTest/writeTest.ino index 8796918..df479b4 100644 --- a/examples/writeTest/writeTest.ino +++ b/examples/writeTest/writeTest.ino @@ -16,7 +16,7 @@ */ // Here we define the four pieces of information that OSFS needs to make a filesystem: -// +// // 1) and 2) How large is the storage medium? uint16_t OSFS::startOfEEPROM = 1; uint16_t OSFS::endOfEEPROM = 1024; @@ -38,7 +38,7 @@ void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte* input) { } -// The rest is your program as normal. +// The rest is your program as normal. void setup() { Serial.begin(57600); diff --git a/keywords.txt b/keywords.txt index 49fe42e..0beb058 100644 --- a/keywords.txt +++ b/keywords.txt @@ -32,4 +32,4 @@ isDeletedFile KEYWORD2 ####################################### # Constants (LITERAL1) -####################################### \ No newline at end of file +####################################### diff --git a/library.properties b/library.properties index 3ef26b6..54ce394 100644 --- a/library.properties +++ b/library.properties @@ -3,8 +3,8 @@ version=1.2.2 author=Charles Baynham maintainer=Charles Baynham sentence=An Overly Simplified FileSystem for storing things, e.g. in the Arduino's EEPROM -paragraph=Provides an extremely basic, low footprint file system for storage access in an Arduino or other AVR microprocessor. Could be ported to other architectures very easily. The examples provided show how to use OSFS with the Arduino's EEPROM, but it can be used with any sequentially addressed form of storage. +paragraph=Provides an extremely basic, low footprint file system for storage access in an Arduino or other AVR microprocessor. Could be ported to other architectures very easily. The examples provided show how to use OSFS with the Arduino's EEPROM, but it can be used with any sequentially addressed form of storage. category=Data Storage url=https://github.com/charlesbaynham/OSFS architectures=avr -includes=OSFS.h \ No newline at end of file +includes=OSFS.h diff --git a/src/OSFS.cpp b/src/OSFS.cpp index 7b91955..790c447 100644 --- a/src/OSFS.cpp +++ b/src/OSFS.cpp @@ -27,7 +27,7 @@ namespace OSFS { char paddedFilename[FILE_NAME_LENGTH]; padFilename(filename, paddedFilename); - // Loop through checking the file header until + // Loop through checking the file header until // a) we reach a NULL pointer, // b) we find a deleted file that can be overwritten // c) we get an OOL pointer somehow @@ -58,7 +58,7 @@ namespace OSFS { // If there's no next file if (workingHeader.nextFile == 0) { - + return result::FILE_NOT_FOUND; } @@ -73,7 +73,7 @@ namespace OSFS { // Header for new file fileHeader newHeader; - + // Store padded filename in newHeader padFilename(filename, newHeader.fileID); @@ -108,7 +108,7 @@ namespace OSFS { uint16_t workingAddress = startOfEEPROM + sizeof(FSInfo); uint16_t writeAddress; - // Loop through checking the file header until + // Loop through checking the file header until // a) we reach a NULL pointer (i.e. the end of the current files) // b) we find a deleted file that can be overwritten // c) we run out of space @@ -121,11 +121,11 @@ namespace OSFS { if (r != result::NO_ERROR) return r; - + // If there's no next file, calculate the start of the spare space and break the loop - // Note that we might find a file header with fileSize == 0 if there are no files on - // the filesystem at all. In this case, overwrite this "dummy header". - if (workingHeader.nextFile == 0) { + // Note that we might find a file header with fileSize == 0 if there are no files on + // the filesystem at all. In this case, overwrite this "dummy header". + if (workingHeader.nextFile == 0) { if (workingHeader.fileSize != 0) writeAddress = workingAddress + sizeof(workingHeader) + workingHeader.fileSize; else @@ -149,19 +149,19 @@ namespace OSFS { workingAddress = workingHeader.nextFile; } - // See if there's enough space in the EEPROM to fit our file in + // See if there's enough space in the EEPROM to fit our file in if (writeAddress + sizeRequired - 1 > endOfEEPROM) return result::INSUFFICIENT_SPACE; // We have a pointer to an address that has sufficient space to store our - // data, in writeAddress. - // + // data, in writeAddress. + // // We have a pointer to the previous header in workingAddress - // + // // We have a copy of the previous header in workingHeader // // First, constuct a header for this file: - + newHeader.fileSize = size; if (workingHeader.nextFile == 0) newHeader.nextFile = 0; @@ -179,7 +179,7 @@ namespace OSFS { } result deleteFile(const char * filename) { - + // Confirm that the EEPROM is managed by this version of OSFS result r = checkLibVersion(); @@ -194,7 +194,7 @@ namespace OSFS { fileHeader workingHeader; uint16_t workingAddress = startOfEEPROM + sizeof(FSInfo); - // Loop through checking the file header until + // Loop through checking the file header until // a) we reach a NULL pointer, // b) we find our file and it's not deleted // c) we get an OOL pointer somehow @@ -209,10 +209,9 @@ namespace OSFS { // Delete the file if it has the same name and isn't already deleted if (!isDeletedFile(workingHeader) && 0 == strncmp(workingHeader.fileID, filenamePadded, FILE_NAME_LENGTH)) { - workingHeader.flags = workingHeader.flags | 1< endOfEEPROM) return result::UNCAUGHT_OOR; if (address + num < startOfEEPROM || address + num > endOfEEPROM) return result::UNCAUGHT_OOR; @@ -303,7 +302,6 @@ namespace OSFS { // Pad filename to FILE_NAME_LENGTH chars bool ended = false; for (int i = 0; i bytes) * ----------------------- - * + * * and are both present because a file may not * necessarily fill all the available space, e.g. if it has been overwritten * with a smaller file. Overwriting with a larger file is not supported yet, @@ -34,7 +34,7 @@ * Bytes 1 to 4 = "OSFS" Bytes 5 to 6 = uint16_t containing version info. * * Unless these 6 bytes match their expected values, this library will consider - * the EEPROM to be unformatted and will refuse to work with it until format() is called. + * the EEPROM to be unformatted and will refuse to work with it until format() is called. */ #pragma once @@ -145,7 +145,7 @@ namespace OSFS { if (r != result::NO_ERROR) return r; - if (size != sizeof(buf)) + if (size != sizeof(buf)) return result::BUFFER_WRONG_SIZE; return readNBytesChk(add, size, &buf); @@ -164,10 +164,10 @@ namespace OSFS { * be ignored, less chars will be padded to 11. * @param data Pointer to the data to be stored. * @param size Number of bytes to store, starting at `data`. - * @param overwrite Overwrite the named file is it is present. Note that + * @param overwrite Overwrite the named file is it is present. Note that if you attempt to overwrite an existing file with a larger one but there is insufficient space, the original file will still - be deleted. + be deleted. * * @return Error status. */ @@ -183,10 +183,10 @@ namespace OSFS { * @param filename The filename. Should be 11 chars long. More chars will * be ignored, less chars will be padded to 11. * @param[in] buf The variable to be stored - * @param overwrite Overwrite the named file is it is present. Note that + * @param overwrite Overwrite the named file is it is present. Note that if you attempt to overwrite an existing file with a larger one but there is insufficient space, the original file will still - be deleted. + be deleted. * * @tparam T Type to be stored (autodetected) * @@ -215,7 +215,7 @@ namespace OSFS { * library. This does not actually erase the EEPROM, only writes to * the FSInfo header and the first file block. * - * @return Error status. + * @return Error status. */ result format(); @@ -223,7 +223,7 @@ namespace OSFS { * @brief Checks that the EEPROM is managed by this library * * @param[out] ver The version of the library managing this EEPROM. Returns UNFORMATTED if - * unformatted or WRONG_VERSION if the filesystem is formatted but by an + * unformatted or WRONG_VERSION if the filesystem is formatted but by an * incompatible version of OSFS. * * @return Error status diff --git a/test/RAM_storage.h b/test/RAM_storage.h index c36908d..066a428 100644 --- a/test/RAM_storage.h +++ b/test/RAM_storage.h @@ -3,7 +3,7 @@ // The arduino_ci mocking library does not cover EEPROM. But that's fine: I'll // just point OSFS at a location in RAM instead, and have it treat it create -// its filesystem there. +// its filesystem there. uint16_t OSFS::startOfEEPROM = 0; uint16_t OSFS::endOfEEPROM = 1023; @@ -30,4 +30,4 @@ void clear_storage() { for (unsigned int i = 0; i < SIZE_STORAGE; i++) { storage[i] = 0; } -} \ No newline at end of file +} diff --git a/test/test_write.cpp b/test/test_write.cpp index 6f51577..602110a 100644 --- a/test/test_write.cpp +++ b/test/test_write.cpp @@ -39,15 +39,15 @@ unittest(test_storage_header) unittest(test_file_header) { OSFS::format(); - + int testInt = 123; OSFS::newFile("testInt", testInt); - + for (int i=6; i<=21; i++) { printf("[%i],", (int)storage[i]); } putchar('\n'); - + // File name assertEqual(storage[6], 't'); assertEqual(storage[7], 'e'); @@ -60,15 +60,15 @@ unittest(test_file_header) assertEqual(storage[14], ' '); assertEqual(storage[15], ' '); assertEqual(storage[16], ' '); - + // File size assertEqual(storage[17], 0); assertEqual(storage[18], sizeof(int)); - + // Pointer to next file assertEqual(storage[19], 0); assertEqual(storage[20], 0); - + // Flags assertEqual(storage[21], 0); } @@ -139,7 +139,7 @@ unittest(test_overwrite_size_change) uint16_t filePointer, fileSize; uint16_t filePointer_smaller, fileSize_smaller; uint16_t filePointer_bigger, fileSize_bigger; - + obj o_write; OSFS::newFile("int1", testInt); @@ -184,7 +184,7 @@ unittest_main() -// // The rest is your program as normal. +// // The rest is your program as normal. // void setup() { // Serial.begin(57600);