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 <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#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<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) {
|
||||
const uint8_t* read = reinterpret_cast<const uint8_t*>(src);
|
||||
uint8_t* write = reinterpret_cast<uint8_t*>(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;
|
||||
|
||||
|
@ -1,11 +1,14 @@
|
||||
#ifndef __PGMSPACE_H_
|
||||
#define __PGMSPACE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __ets__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#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<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_float(addr) (*reinterpret_cast<const float*>(addr))
|
||||
|
@ -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
|
||||
|
@ -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