Skip to content

Commit 0ffb974

Browse files
committed
Merge pull request #58 from facchinm/new_delete
Fixes to pass validation with test suite
2 parents b17f321 + 6f35dfd commit 0ffb974

File tree

8 files changed

+272
-108
lines changed

8 files changed

+272
-108
lines changed

cores/arduino/IPAddress.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,48 @@ IPAddress::IPAddress(const uint8_t *address)
4343
memcpy(_address.bytes, address, sizeof(_address.bytes));
4444
}
4545

46+
bool IPAddress::fromString(const char *address)
47+
{
48+
// TODO: add support for "a", "a.b", "a.b.c" formats
49+
50+
uint16_t acc = 0; // Accumulator
51+
uint8_t dots = 0;
52+
53+
while (*address)
54+
{
55+
char c = *address++;
56+
if (c >= '0' && c <= '9')
57+
{
58+
acc = acc * 10 + (c - '0');
59+
if (acc > 255) {
60+
// Value out of [0..255] range
61+
return false;
62+
}
63+
}
64+
else if (c == '.')
65+
{
66+
if (dots == 3) {
67+
// Too much dots (there must be 3 dots)
68+
return false;
69+
}
70+
_address.bytes[dots++] = acc;
71+
acc = 0;
72+
}
73+
else
74+
{
75+
// Invalid char
76+
return false;
77+
}
78+
}
79+
80+
if (dots != 3) {
81+
// Too few dots (there must be 3 dots)
82+
return false;
83+
}
84+
_address.bytes[3] = acc;
85+
return true;
86+
}
87+
4688
IPAddress& IPAddress::operator=(const uint8_t *address)
4789
{
4890
memcpy(_address.bytes, address, sizeof(_address.bytes));

cores/arduino/IPAddress.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
#define IPAddress_h
2222

2323
#include <stdint.h>
24-
#include <Printable.h>
24+
#include "Printable.h"
25+
#include "WString.h"
2526

2627
// A class to make it easier to handle and pass around IP addresses
2728

@@ -45,6 +46,9 @@ class IPAddress : public Printable {
4546
IPAddress(uint32_t address);
4647
IPAddress(const uint8_t *address);
4748

49+
bool fromString(const char *address);
50+
bool fromString(const String &address) { return fromString(address.c_str()); }
51+
4852
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
4953
// to a four-byte uint8_t array is expected
5054
operator uint32_t() const { return _address.dword; };
@@ -71,5 +75,4 @@ class IPAddress : public Printable {
7175

7276
const IPAddress INADDR_NONE(0,0,0,0);
7377

74-
7578
#endif

cores/arduino/WString.cpp

+61-27
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,8 @@
2929

3030
#include "WString.h"
3131
#include <stdio.h>
32+
#include "stdlib_noniso.h"
3233

33-
34-
// following the C++ standard operators with attributes in right
35-
// side must be defined globally
36-
String operator + ( const char *cstr, const String &str_arg)
37-
{
38-
String &str_arg_o = const_cast<String&>(str_arg);
39-
String aux = String(cstr);
40-
aux.concat(str_arg_o);
41-
return aux;
42-
}
4334
/*********************************************/
4435
/* Constructors */
4536
/*********************************************/
@@ -56,7 +47,13 @@ String::String(const String &value)
5647
*this = value;
5748
}
5849

59-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
50+
String::String(const __FlashStringHelper *pstr)
51+
{
52+
init();
53+
*this = pstr;
54+
}
55+
56+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
6057
String::String(String &&rval)
6158
{
6259
init();
@@ -162,7 +159,6 @@ inline void String::init(void)
162159
buffer = NULL;
163160
capacity = 0;
164161
len = 0;
165-
flags = 0;
166162
}
167163

168164
void String::invalidate(void)
@@ -197,18 +193,29 @@ unsigned char String::changeBuffer(unsigned int maxStrLen)
197193
/* Copy and Move */
198194
/*********************************************/
199195

200-
String & String::copy(const char *cstr, unsigned int _length)
196+
String & String::copy(const char *cstr, unsigned int length)
201197
{
202-
if (!reserve(_length)) {
198+
if (!reserve(length)) {
203199
invalidate();
204200
return *this;
205201
}
206-
len = _length;
202+
len = length;
207203
strcpy(buffer, cstr);
208204
return *this;
209205
}
210206

211-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
207+
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
208+
{
209+
if (!reserve(length)) {
210+
invalidate();
211+
return *this;
212+
}
213+
len = length;
214+
strcpy_P(buffer, (PGM_P)pstr);
215+
return *this;
216+
}
217+
218+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
212219
void String::move(String &rhs)
213220
{
214221
if (buffer) {
@@ -240,7 +247,7 @@ String & String::operator = (const String &rhs)
240247
return *this;
241248
}
242249

243-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
250+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
244251
String & String::operator = (String &&rval)
245252
{
246253
if (this != &rval) move(rval);
@@ -262,6 +269,14 @@ String & String::operator = (const char *cstr)
262269
return *this;
263270
}
264271

272+
String & String::operator = (const __FlashStringHelper *pstr)
273+
{
274+
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
275+
else invalidate();
276+
277+
return *this;
278+
}
279+
265280
/*********************************************/
266281
/* concat */
267282
/*********************************************/
@@ -359,6 +374,18 @@ unsigned char String::concat(double num)
359374
return concat(string, strlen(string));
360375
}
361376

377+
unsigned char String::concat(const __FlashStringHelper * str)
378+
{
379+
if (!str) return 0;
380+
int length = strlen_P((const char *) str);
381+
if (length == 0) return 1;
382+
unsigned int newlen = len + length;
383+
if (!reserve(newlen)) return 0;
384+
strcpy_P(buffer + len, (const char *) str);
385+
len = newlen;
386+
return 1;
387+
}
388+
362389
/*********************************************/
363390
/* Concatenate */
364391
/*********************************************/
@@ -447,6 +474,13 @@ StringSumHelper & operator + (const StringSumHelper &lhs, double num)
447474
return a;
448475
}
449476

477+
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
478+
{
479+
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
480+
if (!a.concat(rhs)) a.invalidate();
481+
return a;
482+
}
483+
450484
/*********************************************/
451485
/* Comparison */
452486
/*********************************************/
@@ -639,7 +673,7 @@ String String::substring(unsigned int left, unsigned int right) const
639673
left = temp;
640674
}
641675
String out;
642-
if (left > len) return out;
676+
if (left >= len) return out;
643677
if (right > len) right = len;
644678
char temp = buffer[right]; // save the replaced character
645679
buffer[right] = '\0';
@@ -652,33 +686,33 @@ String String::substring(unsigned int left, unsigned int right) const
652686
/* Modification */
653687
/*********************************************/
654688

655-
void String::replace(char find, char _replace)
689+
void String::replace(char find, char replace)
656690
{
657691
if (!buffer) return;
658692
for (char *p = buffer; *p; p++) {
659-
if (*p == find) *p = _replace;
693+
if (*p == find) *p = replace;
660694
}
661695
}
662696

663-
void String::replace(const String& find, const String& _replace)
697+
void String::replace(const String& find, const String& replace)
664698
{
665699
if (len == 0 || find.len == 0) return;
666-
int diff = _replace.len - find.len;
700+
int diff = replace.len - find.len;
667701
char *readFrom = buffer;
668702
char *foundAt;
669703
if (diff == 0) {
670704
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
671-
memcpy(foundAt, _replace.buffer, _replace.len);
672-
readFrom = foundAt + _replace.len;
705+
memcpy(foundAt, replace.buffer, replace.len);
706+
readFrom = foundAt + replace.len;
673707
}
674708
} else if (diff < 0) {
675709
char *writeTo = buffer;
676710
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
677711
unsigned int n = foundAt - readFrom;
678712
memcpy(writeTo, readFrom, n);
679713
writeTo += n;
680-
memcpy(writeTo, _replace.buffer, _replace.len);
681-
writeTo += _replace.len;
714+
memcpy(writeTo, replace.buffer, replace.len);
715+
writeTo += replace.len;
682716
readFrom = foundAt + find.len;
683717
len += diff;
684718
}
@@ -697,7 +731,7 @@ void String::replace(const String& find, const String& _replace)
697731
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
698732
len += diff;
699733
buffer[len] = 0;
700-
memcpy(buffer + index, _replace.buffer, _replace.len);
734+
memcpy(buffer + index, replace.buffer, replace.len);
701735
index--;
702736
}
703737
}

cores/arduino/WString.h

+12-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#include <string.h>
3232
#include <ctype.h>
3333
#include "stdlib_noniso.h"
34-
//#include <avr/pgmspace.h>
34+
#include <avr/pgmspace.h>
3535

3636
// When compiling programs with this class, the following gcc parameters
3737
// dramatically increase performance and memory (RAM) efficiency, typically
@@ -63,7 +63,8 @@ class String
6363
// be false).
6464
String(const char *cstr = "");
6565
String(const String &str);
66-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
66+
String(const __FlashStringHelper *str);
67+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
6768
String(String &&rval);
6869
String(StringSumHelper &&rval);
6970
#endif
@@ -91,7 +92,8 @@ class String
9192
// marked as invalid ("if (s)" will be false).
9293
String & operator = (const String &rhs);
9394
String & operator = (const char *cstr);
94-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
95+
String & operator = (const __FlashStringHelper *str);
96+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
9597
String & operator = (String &&rval);
9698
String & operator = (StringSumHelper &&rval);
9799
#endif
@@ -113,6 +115,7 @@ class String
113115
unsigned char concat(unsigned long long num);
114116
unsigned char concat(float num);
115117
unsigned char concat(double num);
118+
unsigned char concat(const __FlashStringHelper * str);
116119

117120
// if there's not enough memory for the concatenated value, the string
118121
// will be left unchanged (but this isn't signalled in any way)
@@ -128,6 +131,7 @@ class String
128131
String & operator += (unsigned long long num) {concat(num); return (*this);}
129132
String & operator += (float num) {concat(num); return (*this);}
130133
String & operator += (double num) {concat(num); return (*this);}
134+
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
131135

132136
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
133137
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
@@ -141,6 +145,7 @@ class String
141145
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long long num);
142146
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
143147
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
148+
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
144149

145150
// comparison (only works w/ Strings and "strings")
146151
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
@@ -196,19 +201,20 @@ class String
196201
float toFloat(void) const;
197202
char * getCSpec(int base, bool issigned, bool islong);
198203

204+
protected:
199205
char *buffer; // the actual char array
200206
unsigned int capacity; // the array length minus one (for the '\0')
201207
unsigned int len; // the String length (not counting the '\0')
202-
unsigned char flags; // unused, for future features
203-
208+
protected:
204209
void init(void);
205210
void invalidate(void);
206211
unsigned char changeBuffer(unsigned int maxStrLen);
207212
unsigned char concat(const char *cstr, unsigned int length);
208213

209214
// copy and move
210215
String & copy(const char *cstr, unsigned int length);
211-
#ifdef __GXX_EXPERIMENTAL_CXX0X__
216+
String & copy(const __FlashStringHelper *pstr, unsigned int length);
217+
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
212218
void move(String &rhs);
213219
#endif
214220
};

cores/arduino/new.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Copyright (c) 2014 Arduino. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#include <stdlib.h>
20+
#include "new.h"
21+
22+
void *operator new(size_t size) {
23+
return malloc(size);
24+
}
25+
26+
void *operator new[](size_t size) {
27+
return malloc(size);
28+
}
29+
30+
void operator delete(void * ptr) {
31+
free(ptr);
32+
}
33+
34+
void operator delete[](void * ptr) {
35+
free(ptr);
36+
}
37+
38+
extern "C" {
39+
__extension__ typedef int __guard __attribute__((mode (__DI__)));
40+
41+
int __cxa_guard_acquire(__guard g) {return !(char )(g);};
42+
void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
43+
};

0 commit comments

Comments
 (0)