1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-22 08:22:04 +03:00

Implement strstr_P, add pgmspace tests (#1749)

This commit is contained in:
Ivan Grokhotkov
2016-03-11 09:47:49 +03:00
parent 0a320b9fb5
commit d49024cfdf
4 changed files with 54 additions and 82 deletions

View File

@ -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;

View File

@ -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))