Skip to content

Support for dtostrf() #309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 53 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
0750d59
Set all text files to have endings
jgfoster Feb 15, 2021
32a0218
Update workflow to test on push.
jgfoster Feb 15, 2021
aed9f38
Add to CHANGELOG.md
jgfoster Feb 15, 2021
9a76e70
Update CHANGELOG.md to describe line endings change.
jgfoster Feb 15, 2021
c88d7d7
Update to more descriptive line ending handling.
jgfoster Feb 16, 2021
4648fda
Use `before(:each)` rather than `before(:all)` as recommended [here](…
jgfoster Feb 16, 2021
90c5504
Hide build artifacts.
jgfoster Feb 23, 2021
86c8e95
Add note to CHANGELOG.md.
jgfoster Feb 23, 2021
a516e7c
Reeplace deprecated function call.
jgfoster Feb 23, 2021
4667db9
Speed up tests by building a shared library with everything but the t…
jgfoster Mar 24, 2021
2284f1d
Add meaningful comments and remove commented-out code.
jgfoster Mar 24, 2021
452cf08
See if this fixes the lint complaints.
jgfoster Mar 24, 2021
24c37b6
Build single test executable if we don't have a shared library.
jgfoster Mar 24, 2021
432828f
Use `File.exist?()` instead of `File.exists?()`.
jgfoster Mar 24, 2021
009f732
Set LD_LIBRARY_PATH to directory with shared library.
jgfoster Mar 24, 2021
e24ec9e
Fix formatting (lint) issue.
jgfoster Mar 24, 2021
2f5153f
Should find LD_LIBRARY_PATH on Linux.
jgfoster Mar 24, 2021
ea4b72f
Merge branch 'master' into line-endings
ianfixes Apr 6, 2021
aa2ad44
Update gitattributes as per PR discussion
ianfixes Apr 6, 2021
e67d2e9
Stream::readStreamUntil() should not return delimiter.
Jun 4, 2021
a12369b
Update CHANGELOG.md
Jun 4, 2021
1864596
Merge branch 'test_on_push' of github.com:jgfoster/arduino_ci
jgfoster Jun 17, 2021
c348146
Merge branch 'line-endings' of github.com:jgfoster/arduino_ci
jgfoster Jun 17, 2021
1fd65a2
Merge branch 'report_compile_errors' of github.com:jgfoster/arduino_ci
jgfoster Jun 17, 2021
b9b45e4
Merge branch 'hide_build_artifacts' of github.com:jgfoster/arduino_ci
jgfoster Jun 17, 2021
8228104
Merge branch 'shared_library' of github.com:jgfoster/arduino_ci
jgfoster Jun 17, 2021
b201781
Merge branch 'readStringUntil' of github.com:jgfoster/arduino_ci
jgfoster Jun 17, 2021
ba00749
Fix test run problem from merge.
jgfoster Jun 17, 2021
1cfccdf
Fix problem with hiding build artifacts.
jgfoster Jun 17, 2021
5f9db70
Replace `#define yield() _NOP()` with `inline void yield() { _NOP(); …
jgfoster Jul 1, 2021
e52667e
CHANGELOG.md
jgfoster Jul 1, 2021
4f287f2
Merge branch 'yield'
jgfoster Jul 1, 2021
6762e63
Add `_BV()` macro.
jgfoster Jul 1, 2021
c70ecf2
Merge branch 'BV_macro'
jgfoster Jul 1, 2021
7ad4a74
Add `avr/wdt.h` and simple test that ensures the header can be found …
Jul 8, 2021
f7bb619
Merge branch 'watch-dog-timer' into main
Jul 8, 2021
f8ab8b8
Rule of three: if you have a custom destructor, then you probably nee…
Aug 19, 2021
cec111c
Merge branch 'Client_assignment_operator'
Aug 19, 2021
4be329e
Remove debugging output.
Aug 19, 2021
6b17c08
Merge branch 'Client_assignment_operator'
Aug 19, 2021
a9ac410
Fix memory leak in copy constructor and copy assignment operator.
jgfoster Aug 25, 2021
f7eec1a
Merge branch 'Client_assignment_operator'
jgfoster Aug 25, 2021
e323378
Further work to address copy assignment memory leak.
jgfoster Aug 25, 2021
175a82c
Merge branch 'Client_assignment_operator'
jgfoster Aug 25, 2021
362cf15
* Report output from compile.
jgfoster Aug 27, 2021
c23fbd0
Add in missed code.
jgfoster Aug 27, 2021
361629b
Merge branch 'free_memory'
jgfoster Aug 27, 2021
8d58657
Do not use parenthesis for method calls with no arguments.
jgfoster Aug 27, 2021
ea9b1fa
Merge branch 'free_memory'
jgfoster Aug 27, 2021
c299364
Another parenthesis with no arguments!
jgfoster Aug 27, 2021
b3e0bd7
Merge branch 'free_memory'
jgfoster Aug 27, 2021
9c61a44
Fix problem with warnings (https://github.com/Arduino-CI/arduino_ci/p…
Sep 2, 2021
4a3f8de
Add support for `dtostrf()`.
Sep 2, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,40 @@
# https://docs.github.com/en/github/using-git/configuring-git-to-handle-line-endings
# https://git-scm.com/docs/gitattributes
# https://git-scm.com/docs/git-config
# https://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/

# Configure this repository to use Git's type detection algorithm to guess
# whether a file is text or binary. Text files will have line endings converted
# as if you had set
# eol=native
# That is, on Windows text files will have CRLF line endings in your working
# directory while on Linux and macOS your text files will have LF line endings
# in your working directory. In either case, they will have LF line endings in
# the Git repository itself.

# Set the default behavior, in case people don't have core.autocrlf set.
* text eol=lf
* text=auto

# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout. Git would likely get these right, but
# we can be sure by adding them here.
*.ino text diff=cpp
*.c text diff=c
*.cc text diff=cpp
*.cxx text diff=cpp
*.cpp text diff=cpp
*.c++ text diff=cpp
*.hpp text diff=cpp
*.h text diff=c
*.h++ text diff=cpp
*.hh text diff=cpp

*.md text
*.yaml text
*.yml text


# Denote all files that are truly binary and should not be modified.
# Even if we don't have any of these, they make a good example.
*.png binary
*.jpg binary
2 changes: 1 addition & 1 deletion .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ In this project, we define a workflow for each target platform. **If you're loo

The reason that all platforms are tested in _this_ project is to ensure that, as a framework, `arduino_ci` will run properly on any developer's personal workstation (regardless of OS).

For testing an individual Arduino library in the context of GitHub, [Linux is the cheapest option](https://docs.github.com/en/free-pro-team@latest/github/setting-up-and-managing-billing-and-payments-on-github/about-billing-for-github-actions) and produces results identical to the other OSes.
For testing an individual Arduino library in the context of GitHub, [Linux is the cheapest option](https://docs.github.com/en/free-pro-team@latest/github/setting-up-and-managing-billing-and-payments-on-github/about-billing-for-github-actions) and should produce results identical to the other OSes.
2 changes: 1 addition & 1 deletion .github/workflows/linux.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This is the name of the workflow, visible on GitHub UI
name: linux

on: [pull_request]
on: [push, pull_request]

jobs:
"unittest_lint_sampleproject":
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/macos.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This is the name of the workflow, visible on GitHub UI
name: macos

on: [pull_request]
on: [push, pull_request]

jobs:
"unittest_lint_sampleproject":
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/windows.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This is the name of the workflow, visible on GitHub UI
name: windows

on: [pull_request]
on: [push, pull_request]

jobs:
"unittest_lint_sampleproject":
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.arduino_ci
/.bundle/
/.yardoc
Gemfile.lock
Expand All @@ -15,3 +16,5 @@ vendor
# C++ stuff
*.bin
*.bin.dSYM
*.so
*.so.dSYM
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Added
- Show output from successful compile
- `--min-free-space=N` command-line argument to fail if free space is below requred value
- Support for `dtostrf()`

### Changed
- Change 266 files from CRLF to LF.
- Run tests on push as well as on a pull request so developers can see impact
- Update .gitattributes so we have consistent line endings
- Put build artifacts in a separate directory to reduce clutter.
- We now compile a shared library to be used for each test
- Replace `#define yield() _NOP()` with `inline void yield() { _NOP(); }` so that other code can define a `yield()` function.
- Add `_BV()` macro.
- Apply "rule of three" to Client copy constructor and copy assignment operator

### Deprecated

Expand All @@ -24,9 +34,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added
- Better indications of the build phases in the test runner `arduino_ci.rb`
- Better indications of which example sketch is being compiled as part of testing
- Allow use of watchdog timer in application code (though it doesn't do anything)

### Changed
- Topmost installtion instructions now suggest `gem install arduino_ci` instead of using a `Gemfile`. Reasons for using a `Gemfile` are listed and discussed separately further down the README.
- Stream::readStreamUntil() no longer returns delimiter

### Removed
- scanning of `library.properties`; this can and should now be performed by the standalone [`arduino-lint` tool](https://arduino.github.io/arduino-lint).
Expand Down
15 changes: 15 additions & 0 deletions SampleProjects/TestSomething/.arduino-ci.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
platforms:
uno:
board: arduino:avr:uno
package: arduino:avr
gcc:
features:
defines:
- __AVR__
- __AVR_ATmega328P__
- ARDUINO_ARCH_AVR
- ARDUINO_AVR_UNO
warnings:
- no-unknown-attributes
flags:

unittest:
platforms:
- uno
Expand Down
7 changes: 7 additions & 0 deletions SampleProjects/TestSomething/test/clientServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ unittest(Client) {
assertEqual(outData + "\r\n", inData);
}

unittest(Client_copy_constructor) {
Client client1;
Client client2;
client2 = client1;
assertTrue(true);
}

unittest(IPAddress) {
IPAddress ipAddress0;
assertEqual(0, ipAddress0.asWord());
Expand Down
8 changes: 8 additions & 0 deletions SampleProjects/TestSomething/test/stdlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,12 @@ unittest(library_tests_itoa)

}

unittest(library_tests_dtostrf)
{
float num = 123.456;
char buffer[10];
dtostrf(num, 7, 3, buffer);
assertEqual(strncmp(buffer, "123.456", sizeof(buffer)), 0);
}

unittest_main()
12 changes: 12 additions & 0 deletions SampleProjects/TestSomething/test/stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,16 @@ unittest(stream_parse)

}

unittest(readStringUntil) {
String data = "";
unsigned long micros = 100;
data = "abc:def";

Stream s;
s.mGodmodeDataIn = &data;
s.mGodmodeMicrosDelay = &micros;
// result should not include delimiter
assertEqual("abc", s.readStringUntil(':'));
assertEqual("def", s.readStringUntil(':'));
}
unittest_main()
12 changes: 12 additions & 0 deletions SampleProjects/TestSomething/test/wdt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <Arduino.h>
#include <ArduinoUnitTests.h>
#include <avr/wdt.h>

unittest(wdt) {
wdt_disable();
wdt_enable(WDTO_8S);
wdt_reset();
assertTrue(true);
}

unittest_main()
15 changes: 6 additions & 9 deletions cpp/arduino/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ typedef uint8_t byte;
#define highByte(w) ((uint8_t) ((w) >> 8))
#define lowByte(w) ((uint8_t) ((w) & 0xff))

// might as well use that NO-op macro for these, while unit testing
// you need interrupts? interrupt yourself
#define yield() _NOP()
#define interrupts() _NOP()
#define noInterrupts() _NOP()
// using #define for these makes it impossible for other code to use as function
// names!
inline void yield() { _NOP(); }
inline void interrupts() { _NOP(); }
inline void noInterrupts() { _NOP(); }

// TODO: correctly establish this per-board!
#define F_CPU 1000000UL
Expand All @@ -50,10 +50,7 @@ typedef uint8_t byte;

typedef unsigned int word;

#define bit(b) (1UL << (b))



#define _BV(bit) (1 << (bit))

// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
Expand Down
21 changes: 20 additions & 1 deletion cpp/arduino/Client.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include <Stream.h>
#include <IPAddress.h>
#include <Stream.h>

class Client : public Stream {
public:
Expand All @@ -11,6 +11,25 @@ class Client : public Stream {
mGodmodeDataIn = new String;
}
}
Client(const Client &client) { // copy constructor
if (this != &client) { // not a self-assignment
if (mGodmodeDataIn &&
client.mGodmodeDataIn) { // replace what we previously had
delete mGodmodeDataIn; // get rid of previous value
mGodmodeDataIn = new String(client.mGodmodeDataIn->c_str());
}
}
}
Client &operator=(const Client &client) { // copy assignment operator
if (this != &client) { // not a self-assignment
if (mGodmodeDataIn &&
client.mGodmodeDataIn) { // replace what we previously had
delete mGodmodeDataIn; // get rid of previous value
mGodmodeDataIn = new String(client.mGodmodeDataIn->c_str());
}
}
return *this;
}
~Client() {
if (mGodmodeDataIn) {
delete mGodmodeDataIn;
Expand Down
2 changes: 1 addition & 1 deletion cpp/arduino/Stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class Stream : public Print
ret = String(*mGodmodeDataIn);
mGodmodeDataIn->clear();
} else {
ret = mGodmodeDataIn->substring(0, idxTrm + 1);
ret = mGodmodeDataIn->substring(0, idxTrm);
fastforward(idxTrm + 1);
}
return ret;
Expand Down
16 changes: 16 additions & 0 deletions cpp/arduino/avr/wdt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Stub for testing that doesn't do anything (but at least compiles!)

#define wdt_disable() (void)0
#define wdt_enable(timeout) (void)0
#define wdt_reset() (void)0

#define WDTO_15MS 0
#define WDTO_30MS 1
#define WDTO_60MS 2
#define WDTO_120MS 3
#define WDTO_250MS 4
#define WDTO_500MS 5
#define WDTO_1S 6
#define WDTO_2S 7
#define WDTO_4S 8
#define WDTO_8S 9
20 changes: 20 additions & 0 deletions cpp/arduino/stdlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
** is out of range.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Expand Down Expand Up @@ -59,3 +60,22 @@ char *itoa(int N, char *str, int base)
return str;
}
#endif

/*
The dtostrf() function converts the double value passed in val into
an ASCII representationthat will be stored under s. The caller is
responsible for providing sufficient storage in s.

Conversion is done in the format “[-]d.ddd”. The minimum field width
of the output string (including the ‘.’ and the possible sign for
negative values) is given in width, and prec determines the number of
digits after the decimal sign. width is signed value, negative for
left adjustment.

The dtostrf() function returns the pointer to the converted string s.
*/

char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s) {
sprintf(__s, "%*.*f", __width, __prec, __val);
return __s;
}
3 changes: 3 additions & 0 deletions cpp/arduino/stdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@
* https://stackoverflow.com/questions/190229/where-is-the-itoa-function-in-linux
*/
char *itoa(int val, char *s, int radix);

// another function provided by Arduino
char * dtostrf(double __val, signed char __width, unsigned char __prec, char *__s);
43 changes: 38 additions & 5 deletions exe/arduino_ci.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def self.parse(options)
ci_config: {
"unittest" => unit_config
},
min_free_space: 0,
}

opt_parser = OptionParser.new do |opts|
Expand All @@ -49,6 +50,10 @@ def self.parse(options)
unit_config["testfiles"]["reject"] << p
end

opts.on("--min-free-space=VALUE", "Minimum free SRAM memory for stack/heap") do |p|
output_options[:min_free_space] = p.to_i
end

opts.on("-h", "--help", "Prints this help") do
puts opts
puts
Expand Down Expand Up @@ -416,9 +421,27 @@ def perform_unit_tests(cpp_library, file_config)

platforms.each do |p|
puts
config.allowable_unittest_files(cpp_library.test_files).each do |unittest_path|
unittest_name = unittest_path.basename.to_s
compilers.each do |gcc_binary|
compilers.each do |gcc_binary|
# before compiling the tests, build a shared library of everything except the test code
attempt_multiline("Build shared library with #{gcc_binary} for #{p}") do
exe = cpp_library.build_for_test_with_configuration(
nil, # nil is a flag that we are building the shared library with everything else
config.aux_libraries_for_unittest,
gcc_binary,
config.gcc_config(p)
)
puts
unless exe
puts "Last command: #{cpp_library.last_cmd}"
puts cpp_library.last_out
puts cpp_library.last_err
next false
end
true
end
# now build and run each test using the shared library build above
config.allowable_unittest_files(cpp_library.test_files).each do |unittest_path|
unittest_name = unittest_path.basename.to_s
attempt_multiline("Unit testing #{unittest_name} with #{gcc_binary} for #{p}") do
exe = cpp_library.build_for_test_with_configuration(
unittest_path,
Expand Down Expand Up @@ -478,8 +501,18 @@ def perform_example_compilation_tests(cpp_library, config)
board = ovr_config.platform_info[p][:board]
attempt("Compiling #{example_name} for #{board}") do
ret = @backend.compile_sketch(example_path, board)
unless ret
puts
puts
if ret
output = @backend.last_msg
puts output
i = output.index("leaving")
free_space = output[i + 8..-1].to_i
min_free_space = @cli_options[:min_free_space]
if free_space < min_free_space
puts "Free space of #{free_space} is less than minimum of #{min_free_space}"
ret = false
end
else
puts "Last command: #{@backend.last_msg}"
puts @backend.last_err
end
Expand Down
Loading