mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +03:00
Implement strstr_P, add pgmspace tests (#1749)
This commit is contained in:
parent
0a320b9fb5
commit
d49024cfdf
@ -18,6 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include "pgmspace.h"
|
#include "pgmspace.h"
|
||||||
|
|
||||||
size_t strnlen_P(PGM_P s, size_t size) {
|
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);
|
return (size_t) (cp - s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* strstr_P(const char* haystack, PGM_P needle)
|
||||||
|
{
|
||||||
|
const char* pn = reinterpret_cast<const char*>(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) {
|
void* memcpy_P(void* dest, PGM_VOID_P src, size_t count) {
|
||||||
const uint8_t* read = reinterpret_cast<const uint8_t*>(src);
|
const uint8_t* read = reinterpret_cast<const uint8_t*>(src);
|
||||||
uint8_t* write = reinterpret_cast<uint8_t*>(dest);
|
uint8_t* write = reinterpret_cast<uint8_t*>(dest);
|
||||||
@ -203,7 +234,7 @@ int printf_P(PGM_P formatP, ...) {
|
|||||||
char* format = new char[fmtLen + 1];
|
char* format = new char[fmtLen + 1];
|
||||||
strcpy_P(format, formatP);
|
strcpy_P(format, formatP);
|
||||||
|
|
||||||
ret = os_printf(format, arglist);
|
ret = printf(format, arglist);
|
||||||
|
|
||||||
delete[] format;
|
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];
|
char* format = new char[fmtLen + 1];
|
||||||
strcpy_P(format, formatP);
|
strcpy_P(format, formatP);
|
||||||
|
|
||||||
ret = ets_vsnprintf(str, strSize, format, ap);
|
ret = vsnprintf(str, strSize, format, ap);
|
||||||
|
|
||||||
delete[] format;
|
delete[] format;
|
||||||
|
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
#ifndef __PGMSPACE_H_
|
#ifndef __PGMSPACE_H_
|
||||||
#define __PGMSPACE_H_
|
#define __PGMSPACE_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __ets__
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "ets_sys.h"
|
#include "ets_sys.h"
|
||||||
#include "osapi.h"
|
#include "osapi.h"
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -16,6 +19,13 @@ extern "C" {
|
|||||||
#define PGM_P const char *
|
#define PGM_P const char *
|
||||||
#define PGM_VOID_P const void *
|
#define PGM_VOID_P const void *
|
||||||
#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
|
#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)
|
#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);
|
size_t strnlen_P(PGM_P s, size_t size);
|
||||||
#define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT)
|
#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 printf_P(PGM_P formatP, ...) __attribute__((format(printf, 1, 2)));
|
||||||
int sprintf_P(char *str, PGM_P formatP, ...) __attribute__((format(printf, 2, 3)));
|
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)));
|
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
|
// b3, b2, b1, b0
|
||||||
// w1, w0
|
// w1, w0
|
||||||
|
|
||||||
|
#ifdef __ets__
|
||||||
#define pgm_read_byte(addr) \
|
#define pgm_read_byte(addr) \
|
||||||
(__extension__({ \
|
(__extension__({ \
|
||||||
PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
|
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)); \
|
uint16_t __result = ((*__addr32) >> (__offset * 8)); \
|
||||||
__result; \
|
__result; \
|
||||||
}))
|
}))
|
||||||
|
#else //__ets__
|
||||||
|
#define pgm_read_byte(addr) (*reinterpret_cast<const uint8_t*>(addr))
|
||||||
|
#define pgm_read_word(addr) (*reinterpret_cast<const uint16_t*>(addr))
|
||||||
|
#endif //__ets__
|
||||||
|
|
||||||
#define pgm_read_dword(addr) (*reinterpret_cast<const uint32_t*>(addr))
|
#define pgm_read_dword(addr) (*reinterpret_cast<const uint32_t*>(addr))
|
||||||
#define pgm_read_float(addr) (*reinterpret_cast<const float*>(addr))
|
#define pgm_read_float(addr) (*reinterpret_cast<const float*>(addr))
|
||||||
|
@ -17,6 +17,7 @@ CORE_CPP_FILES := $(addprefix $(CORE_PATH)/,\
|
|||||||
Print.cpp \
|
Print.cpp \
|
||||||
FS.cpp \
|
FS.cpp \
|
||||||
spiffs_api.cpp \
|
spiffs_api.cpp \
|
||||||
|
pgmspace.cpp \
|
||||||
)
|
)
|
||||||
|
|
||||||
CORE_C_FILES := $(addprefix $(CORE_PATH)/,\
|
CORE_C_FILES := $(addprefix $(CORE_PATH)/,\
|
||||||
@ -41,6 +42,7 @@ INC_PATHS += $(addprefix -I, \
|
|||||||
|
|
||||||
TEST_CPP_FILES := \
|
TEST_CPP_FILES := \
|
||||||
fs/test_fs.cpp \
|
fs/test_fs.cpp \
|
||||||
|
core/test_pgmspace.cpp \
|
||||||
|
|
||||||
CXXFLAGS += -std=c++11 -Wall -coverage -O0
|
CXXFLAGS += -std=c++11 -Wall -coverage -O0
|
||||||
CFLAGS += -std=c99 -Wall -coverage -O0
|
CFLAGS += -std=c99 -Wall -coverage -O0
|
||||||
|
@ -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 <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#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<const uint8_t*>(addr))
|
|
||||||
#define pgm_read_word(addr) (*reinterpret_cast<const uint16_t*>(addr))
|
|
||||||
#define pgm_read_float(addr) (*reinterpret_cast<const float*>(addr))
|
|
||||||
#define pgm_read_dword(addr) (*reinterpret_cast<const uint32_t*>(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_
|
|
Loading…
x
Reference in New Issue
Block a user