From d49024cfdf13bd891099c5485af3c8349d9de6fe Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 11 Mar 2016 09:47:49 +0300 Subject: [PATCH] Implement strstr_P, add pgmspace tests (#1749) --- cores/esp8266/pgmspace.cpp | 35 +++++++++++++++- cores/esp8266/pgmspace.h | 21 +++++++++- tests/host/Makefile | 2 + tests/host/common/pgmspace.h | 78 ------------------------------------ 4 files changed, 54 insertions(+), 82 deletions(-) delete mode 100644 tests/host/common/pgmspace.h diff --git a/cores/esp8266/pgmspace.cpp b/cores/esp8266/pgmspace.cpp index 7f03de402..75de541d0 100644 --- a/cores/esp8266/pgmspace.cpp +++ b/cores/esp8266/pgmspace.cpp @@ -18,6 +18,10 @@ */ #include +#include +#include +#include +#include #include "pgmspace.h" size_t strnlen_P(PGM_P s, size_t size) { @@ -26,6 +30,33 @@ size_t strnlen_P(PGM_P s, size_t size) { return (size_t) (cp - s); } +char* strstr_P(const char* haystack, PGM_P needle) +{ + const char* pn = reinterpret_cast(needle); + if (haystack[0] == 0) { + if (pgm_read_byte(pn)) { + return NULL; + } + return (char*) haystack; + } + + while (*haystack) { + size_t i = 0; + while (true) { + char n = pgm_read_byte(pn + i); + if (n == 0) { + return (char *) haystack; + } + if (n != haystack[i]) { + break; + } + ++i; + } + ++haystack; + } + return NULL; +} + void* memcpy_P(void* dest, PGM_VOID_P src, size_t count) { const uint8_t* read = reinterpret_cast(src); uint8_t* write = reinterpret_cast(dest); @@ -203,7 +234,7 @@ int printf_P(PGM_P formatP, ...) { char* format = new char[fmtLen + 1]; strcpy_P(format, formatP); - ret = os_printf(format, arglist); + ret = printf(format, arglist); delete[] format; @@ -240,7 +271,7 @@ int vsnprintf_P(char* str, size_t strSize, PGM_P formatP, va_list ap) { char* format = new char[fmtLen + 1]; strcpy_P(format, formatP); - ret = ets_vsnprintf(str, strSize, format, ap); + ret = vsnprintf(str, strSize, format, ap); delete[] format; diff --git a/cores/esp8266/pgmspace.h b/cores/esp8266/pgmspace.h index c9e83fa05..bb2244999 100644 --- a/cores/esp8266/pgmspace.h +++ b/cores/esp8266/pgmspace.h @@ -1,11 +1,14 @@ #ifndef __PGMSPACE_H_ #define __PGMSPACE_H_ +#include +#include + +#ifdef __ets__ + #ifdef __cplusplus extern "C" { #endif -#include -#include #include "ets_sys.h" #include "osapi.h" #ifdef __cplusplus @@ -16,6 +19,13 @@ extern "C" { #define PGM_P const char * #define PGM_VOID_P const void * #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) +#else //__ets__ +#define PROGMEM +#define PGM_P const char * +#define PGM_VOID_P const void * +#define PSTR(s) (s) + +#endif // __ets__ #define _SFR_BYTE(n) (n) @@ -62,6 +72,8 @@ int strncasecmp_P(const char* str1, PGM_P str2P, size_t size); size_t strnlen_P(PGM_P s, size_t size); #define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT) +char* strstr_P(const char* haystack, PGM_P needle); + int printf_P(PGM_P formatP, ...) __attribute__((format(printf, 1, 2))); int sprintf_P(char *str, PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); int snprintf_P(char *str, size_t strSize, PGM_P formatP, ...) __attribute__((format(printf, 3, 4))); @@ -74,6 +86,7 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut // b3, b2, b1, b0 // w1, w0 +#ifdef __ets__ #define pgm_read_byte(addr) \ (__extension__({ \ PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \ @@ -91,6 +104,10 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut uint16_t __result = ((*__addr32) >> (__offset * 8)); \ __result; \ })) +#else //__ets__ +#define pgm_read_byte(addr) (*reinterpret_cast(addr)) +#define pgm_read_word(addr) (*reinterpret_cast(addr)) +#endif //__ets__ #define pgm_read_dword(addr) (*reinterpret_cast(addr)) #define pgm_read_float(addr) (*reinterpret_cast(addr)) diff --git a/tests/host/Makefile b/tests/host/Makefile index e0a3e143b..b57aef018 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -17,6 +17,7 @@ CORE_CPP_FILES := $(addprefix $(CORE_PATH)/,\ Print.cpp \ FS.cpp \ spiffs_api.cpp \ + pgmspace.cpp \ ) CORE_C_FILES := $(addprefix $(CORE_PATH)/,\ @@ -41,6 +42,7 @@ INC_PATHS += $(addprefix -I, \ TEST_CPP_FILES := \ fs/test_fs.cpp \ + core/test_pgmspace.cpp \ CXXFLAGS += -std=c++11 -Wall -coverage -O0 CFLAGS += -std=c99 -Wall -coverage -O0 diff --git a/tests/host/common/pgmspace.h b/tests/host/common/pgmspace.h deleted file mode 100644 index 7bdd80963..000000000 --- a/tests/host/common/pgmspace.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - pgmspace.cpp - PROGMEM stubs for host-side tests - Copyright © 2016 Ivan Grokhotkov - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - */ -#ifndef __PGMSPACE_H_ -#define __PGMSPACE_H_ - -#include -#include - -#define PROGMEM -#define PGM_P const char * -#define PGM_VOID_P const void * -#define PSTR(s) (s) - - -#define _SFR_BYTE(n) (n) - -typedef void prog_void; -typedef char prog_char; -typedef unsigned char prog_uchar; -typedef int8_t prog_int8_t; -typedef uint8_t prog_uint8_t; -typedef int16_t prog_int16_t; -typedef uint16_t prog_uint16_t; -typedef int32_t prog_int32_t; -typedef uint32_t prog_uint32_t; - -#define memcmp_P memcmp -#define memccpy_P memccpy -#define memmem_P memmem -#define memcpy_P memcpy - -#define strncpy_P strncpy -#define strcpy_P strcpy - -#define strncat_P strncat -#define strcat_P strcat - -#define strncmp_P strncmp -#define strcmp_P strcmp - -#define strncasecmp_P strncasecmp -#define strcasecmp_P strcasecmp - -#define strnlen_P strnlen -#define strlen_P strlen - -#define printf_P printf -#define sprintf_P sprintf -#define snprintf_P snprintf -#define vsnprintf_P vsnprintf - -#define pgm_read_byte(addr) (*reinterpret_cast(addr)) -#define pgm_read_word(addr) (*reinterpret_cast(addr)) -#define pgm_read_float(addr) (*reinterpret_cast(addr)) -#define pgm_read_dword(addr) (*reinterpret_cast(addr)) - -#define pgm_read_byte_near(addr) pgm_read_byte(addr) -#define pgm_read_word_near(addr) pgm_read_word(addr) -#define pgm_read_dword_near(addr) pgm_read_dword(addr) -#define pgm_read_float_near(addr) pgm_read_float(addr) -#define pgm_read_byte_far(addr) pgm_read_byte(addr) -#define pgm_read_word_far(addr) pgm_read_word(addr) -#define pgm_read_dword_far(addr) pgm_read_dword(addr) -#define pgm_read_float_far(addr) pgm_read_float(addr) - -#endif //__PGMSPACE_H_