Skip to content

Commit a16b547

Browse files
committed
Fix FlashStringHelper
1 parent 2dae289 commit a16b547

File tree

6 files changed

+631
-150
lines changed

6 files changed

+631
-150
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1919
- Replaced pipes with `Open3.capture3` to avoid deadlocks when commands have too much output
2020
- `ci_config.rb` now returns empty arrays (instead of nil) for undefined config keys
2121
- `pgmspace.h` explictly includes `<string.h>`
22+
- `__FlashStringHelper` should now be properly mocked for compilation
2223

2324
### Security
2425

cpp/arduino/ArduinoDefines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <avr/pgmspace.h>
4+
35
#define HIGH 0x1
46
#define LOW 0x0
57

cpp/arduino/Print.h

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ class Print
3232
virtual size_t write(uint8_t) = 0;
3333
size_t write(const char *str) { return str == NULL ? 0 : write((const uint8_t *)str, String(str).length()); }
3434

35-
size_t write(const __FlashStringHelper *str) { return write((const char *)str); }
3635

3736
virtual size_t write(const uint8_t *buffer, size_t size) {
3837
size_t n;
@@ -41,28 +40,30 @@ class Print
4140
}
4241
size_t write(const char *buffer, size_t size) { return write((const uint8_t *)buffer, size); }
4342

44-
size_t print(const String &s) { return write(s.c_str(), s.length()); }
45-
size_t print(const char* str) { return print(String(str)); }
46-
size_t print(char c) { return print(String(c)); }
47-
size_t print(unsigned char b, int base) { return print(String(b, base)); }
48-
size_t print(int n, int base) { return print(String(n, base)); }
49-
size_t print(unsigned int n, int base) { return print(String(n, base)); }
50-
size_t print(long n, int base) { return print(String(n, base)); }
51-
size_t print(unsigned long n, int base) { return print(String(n, base)); }
52-
size_t print(double n, int digits) { return print(String(n, digits)); }
53-
size_t print(const Printable& x) { return x.printTo(*this); }
43+
size_t print(const String &s) { return write(s.c_str(), s.length()); }
44+
size_t print(const __FlashStringHelper *str) { return print(reinterpret_cast<PGM_P>(str)); }
45+
size_t print(const char* str) { return print(String(str)); }
46+
size_t print(char c) { return print(String(c)); }
47+
size_t print(unsigned char b, int base) { return print(String(b, base)); }
48+
size_t print(int n, int base) { return print(String(n, base)); }
49+
size_t print(unsigned int n, int base) { return print(String(n, base)); }
50+
size_t print(long n, int base) { return print(String(n, base)); }
51+
size_t print(unsigned long n, int base) { return print(String(n, base)); }
52+
size_t print(double n, int digits) { return print(String(n, digits)); }
53+
size_t print(const Printable& x) { return x.printTo(*this); }
5454

55-
size_t println(void) { return print("\r\n"); }
56-
size_t println(const String &s) { return print(s) + println(); }
57-
size_t println(const char* c) { return println(String(c)); }
58-
size_t println(char c) { return println(String(c)); }
59-
size_t println(unsigned char b, int base) { return println(String(b, base)); }
60-
size_t println(int num, int base) { return println(String(num, base)); }
61-
size_t println(unsigned int num, int base) { return println(String(num, base)); }
62-
size_t println(long num, int base) { return println(String(num, base)); }
63-
size_t println(unsigned long num, int base) { return println(String(num, base)); }
64-
size_t println(double num, int digits) { return println(String(num, digits)); }
65-
size_t println(const Printable& x) { return print(x) + println(); }
55+
size_t println(void) { return print("\r\n"); }
56+
size_t println(const String &s) { return print(s) + println(); }
57+
size_t println(const __FlashStringHelper *str) { return println(reinterpret_cast<PGM_P>(str)); }
58+
size_t println(const char* c) { return println(String(c)); }
59+
size_t println(char c) { return println(String(c)); }
60+
size_t println(unsigned char b, int base) { return println(String(b, base)); }
61+
size_t println(int num, int base) { return println(String(num, base)); }
62+
size_t println(unsigned int num, int base) { return println(String(num, base)); }
63+
size_t println(long num, int base) { return println(String(num, base)); }
64+
size_t println(unsigned long num, int base) { return println(String(num, base)); }
65+
size_t println(double num, int digits) { return println(String(num, digits)); }
66+
size_t println(const Printable& x) { return print(x) + println(); }
6667

6768
virtual void flush() { }
6869

cpp/arduino/WString.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
#pragma once
22

33
#include <stdlib.h>
4-
#include <string>
4+
#include <string.h>
55
#include <algorithm>
66
#include <iostream>
77
#include "AvrMath.h"
88
#include "WCharacter.h"
99

1010
typedef std::string string;
1111

12-
//typedef const char __FlashStringHelper;
1312
class __FlashStringHelper;
1413
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
1514

@@ -44,8 +43,8 @@ class String: public string
4443

4544
static string dtoas(double val, int decimalPlaces) {
4645
double r = 0.5 * pow(0.1, decimalPlaces); // make sure that integer truncation will properly round
47-
if (::isnan(val)) return "nan";
48-
if (::isinf(val)) return "inf";
46+
if (std::isnan(val)) return "nan";
47+
if (std::isinf(val)) return "inf";
4948
val += val > 0 ? r : -r;
5049
if (val > 4294967040.0) return "ovf";
5150
if (val <-4294967040.0) return "ovf";

cpp/arduino/avr/pgmspace.h

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
#pragma once
22

3-
43
/*
54
def d(var_raw)
65
var = var_raw.split("_")[0]
7-
out = "#define #{var}_P(...) #{var}(__VA_ARGS__)\n"
6+
out = "#define #{var}_P(...) ::#{var}(__VA_ARGS__)\n"
87
IO.popen('pbcopy', 'w') { |f| f << out }
98
out
109
end
@@ -16,7 +15,7 @@ out.each { |l| puts d(l) }
1615
*/
1716

1817
#include <avr/io.h>
19-
#include <string>
18+
#include <string.h>
2019

2120
#define PROGMEM
2221

@@ -50,46 +49,46 @@ out.each { |l| puts d(l) }
5049
#define pgm_read_ptr(x) (x)
5150
#define pgm_get_far_address(x) (x)
5251

53-
#define memchr_P(...) memchr(__VA_ARGS__)
54-
#define memcmp_P(...) memcmp(__VA_ARGS__)
55-
#define memccpy_P(...) memccpy(__VA_ARGS__)
56-
#define memcpy_P(...) memcpy(__VA_ARGS__)
57-
#define memmem_P(...) memmem(__VA_ARGS__)
58-
#define memrchr_P(...) memrchr(__VA_ARGS__)
59-
#define strcat_P(...) strcat(__VA_ARGS__)
60-
#define strchr_P(...) strchr(__VA_ARGS__)
61-
#define strchrnul_P(...) strchrnul(__VA_ARGS__)
62-
#define strcmp_P(...) strcmp(__VA_ARGS__)
63-
#define strcpy_P(...) strcpy(__VA_ARGS__)
64-
#define strcasecmp_P(...) strcasecmp(__VA_ARGS__)
65-
#define strcasestr_P(...) strcasestr(__VA_ARGS__)
66-
#define strcspn_P(...) strcspn(__VA_ARGS__)
67-
#define strlcat_P(...) strlcat(__VA_ARGS__)
68-
#define strlcpy_P(...) strlcpy(__VA_ARGS__)
69-
#define strnlen_P(...) strnlen(__VA_ARGS__)
70-
#define strncmp_P(...) strncmp(__VA_ARGS__)
71-
#define strncasecmp_P(...) strncasecmp(__VA_ARGS__)
72-
#define strncat_P(...) strncat(__VA_ARGS__)
73-
#define strncpy_P(...) strncpy(__VA_ARGS__)
74-
#define strpbrk_P(...) strpbrk(__VA_ARGS__)
75-
#define strrchr_P(...) strrchr(__VA_ARGS__)
76-
#define strsep_P(...) strsep(__VA_ARGS__)
77-
#define strspn_P(...) strspn(__VA_ARGS__)
78-
#define strstr_P(...) strstr(__VA_ARGS__)
79-
#define strtok_P(...) strtok(__VA_ARGS__)
80-
#define strtok_P(...) strtok(__VA_ARGS__)
81-
#define strlen_P(...) strlen(__VA_ARGS__)
82-
#define strnlen_P(...) strnlen(__VA_ARGS__)
83-
#define memcpy_P(...) memcpy(__VA_ARGS__)
84-
#define strcpy_P(...) strcpy(__VA_ARGS__)
85-
#define strncpy_P(...) strncpy(__VA_ARGS__)
86-
#define strcat_P(...) strcat(__VA_ARGS__)
87-
#define strlcat_P(...) strlcat(__VA_ARGS__)
88-
#define strncat_P(...) strncat(__VA_ARGS__)
89-
#define strcmp_P(...) strcmp(__VA_ARGS__)
90-
#define strncmp_P(...) strncmp(__VA_ARGS__)
91-
#define strcasecmp_P(...) strcasecmp(__VA_ARGS__)
92-
#define strncasecmp_P(...) strncasecmp(__VA_ARGS__)
93-
#define strstr_P(...) strstr(__VA_ARGS__)
94-
#define strlcpy_P(...) strlcpy(__VA_ARGS__)
95-
#define memcmp_P(...) memcmp(__VA_ARGS__)
52+
#define memchr_P(...) ::memchr(__VA_ARGS__)
53+
#define memcmp_P(...) ::memcmp(__VA_ARGS__)
54+
#define memccpy_P(...) ::memccpy(__VA_ARGS__)
55+
#define memcpy_P(...) ::memcpy(__VA_ARGS__)
56+
#define memmem_P(...) ::memmem(__VA_ARGS__)
57+
#define memrchr_P(...) ::memrchr(__VA_ARGS__)
58+
#define strcat_P(...) ::strcat(__VA_ARGS__)
59+
#define strchr_P(...) ::strchr(__VA_ARGS__)
60+
#define strchrnul_P(...) ::strchrnul(__VA_ARGS__)
61+
#define strcmp_P(...) ::strcmp(__VA_ARGS__)
62+
#define strcpy_P(...) ::strcpy(__VA_ARGS__)
63+
#define strcasecmp_P(...) ::strcasecmp(__VA_ARGS__)
64+
#define strcasestr_P(...) ::strcasestr(__VA_ARGS__)
65+
#define strcspn_P(...) ::strcspn(__VA_ARGS__)
66+
#define strlcat_P(...) ::strlcat(__VA_ARGS__)
67+
#define strlcpy_P(...) ::strlcpy(__VA_ARGS__)
68+
#define strnlen_P(...) ::strnlen(__VA_ARGS__)
69+
#define strncmp_P(...) ::strncmp(__VA_ARGS__)
70+
#define strncasecmp_P(...) ::strncasecmp(__VA_ARGS__)
71+
#define strncat_P(...) ::strncat(__VA_ARGS__)
72+
#define strncpy_P(...) ::strncpy(__VA_ARGS__)
73+
#define strpbrk_P(...) ::strpbrk(__VA_ARGS__)
74+
#define strrchr_P(...) ::strrchr(__VA_ARGS__)
75+
#define strsep_P(...) ::strsep(__VA_ARGS__)
76+
#define strspn_P(...) ::strspn(__VA_ARGS__)
77+
#define strstr_P(...) ::strstr(__VA_ARGS__)
78+
#define strtok_P(...) ::strtok(__VA_ARGS__)
79+
#define strtok_P(...) ::strtok(__VA_ARGS__)
80+
#define strlen_P(...) ::strlen(__VA_ARGS__)
81+
#define strnlen_P(...) ::strnlen(__VA_ARGS__)
82+
#define memcpy_P(...) ::memcpy(__VA_ARGS__)
83+
#define strcpy_P(...) ::strcpy(__VA_ARGS__)
84+
#define strncpy_P(...) ::strncpy(__VA_ARGS__)
85+
#define strcat_P(...) ::strcat(__VA_ARGS__)
86+
#define strlcat_P(...) ::strlcat(__VA_ARGS__)
87+
#define strncat_P(...) ::strncat(__VA_ARGS__)
88+
#define strcmp_P(...) ::strcmp(__VA_ARGS__)
89+
#define strncmp_P(...) ::strncmp(__VA_ARGS__)
90+
#define strcasecmp_P(...) ::strcasecmp(__VA_ARGS__)
91+
#define strncasecmp_P(...) ::strncasecmp(__VA_ARGS__)
92+
#define strstr_P(...) ::strstr(__VA_ARGS__)
93+
#define strlcpy_P(...) ::strlcpy(__VA_ARGS__)
94+
#define memcmp_P(...) ::memcmp(__VA_ARGS__)

0 commit comments

Comments
 (0)