mirror of
https://github.com/esp8266/Arduino.git
synced 2025-12-09 08:01:38 +03:00
Migrate from astyle to clang-format (#8464)
This commit is contained in:
committed by
Max Prokhorov
parent
46190b61f1
commit
19b7a29720
@@ -1,32 +0,0 @@
|
||||
# Code formatting rules for Arduino examples, taken from:
|
||||
#
|
||||
# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf
|
||||
#
|
||||
|
||||
mode=c
|
||||
lineend=linux
|
||||
style=allman
|
||||
|
||||
# 4 spaces indentation
|
||||
indent=spaces=4
|
||||
|
||||
# also indent macros
|
||||
#indent-preprocessor
|
||||
|
||||
# indent classes, switches (and cases), comments starting at column 1
|
||||
indent-col1-comments
|
||||
|
||||
# put a space around operators
|
||||
pad-oper
|
||||
|
||||
# put a space after if/for/while
|
||||
pad-header
|
||||
|
||||
# if you like one-liners, keep them
|
||||
keep-one-line-statements
|
||||
|
||||
attach-closing-while
|
||||
unpad-paren
|
||||
pad-oper
|
||||
remove-comment-prefix
|
||||
add-braces
|
||||
@@ -1,44 +0,0 @@
|
||||
# Code formatting rules for Arduino examples, taken from:
|
||||
#
|
||||
# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf
|
||||
#
|
||||
|
||||
mode=c
|
||||
lineend=linux
|
||||
|
||||
# 2 spaces indentation
|
||||
indent=spaces=2
|
||||
|
||||
# also indent macros
|
||||
#indent-preprocessor
|
||||
|
||||
# indent classes, switches (and cases), comments starting at column 1
|
||||
indent-classes
|
||||
indent-switches
|
||||
indent-cases
|
||||
indent-col1-comments
|
||||
|
||||
# put a space around operators
|
||||
pad-oper
|
||||
|
||||
# put a space after if/for/while
|
||||
pad-header
|
||||
|
||||
# if you like one-liners, keep them
|
||||
keep-one-line-statements
|
||||
add-braces
|
||||
|
||||
style=java
|
||||
attach-namespaces
|
||||
attach-classes
|
||||
attach-inlines
|
||||
attach-extern-c
|
||||
indent-modifiers
|
||||
indent-namespaces
|
||||
indent-labels
|
||||
#indent-preproc-block
|
||||
#indent-preproc-define
|
||||
#indent-preproc-cond
|
||||
unpad-paren
|
||||
add-braces
|
||||
remove-comment-prefix
|
||||
@@ -2,12 +2,12 @@
|
||||
#
|
||||
# CI job for checking examples style
|
||||
|
||||
set -ev
|
||||
set -e -x
|
||||
|
||||
org=$(cd ${0%/*}; pwd)
|
||||
${org}/../restyle.sh
|
||||
root=$(git rev-parse --show-toplevel)
|
||||
${root}/tests/restyle.sh
|
||||
|
||||
# Revert changes which astyle might have done to the submodules,
|
||||
# Revert changes which formatter might have done to the submodules,
|
||||
# as we don't want to fail the build because of the 3rd party libraries
|
||||
git --version || true
|
||||
git submodule foreach --recursive 'git reset --hard'
|
||||
|
||||
149
tests/clang-format-arduino.yaml
Normal file
149
tests/clang-format-arduino.yaml
Normal file
@@ -0,0 +1,149 @@
|
||||
# Taken from https://github.com/arduino/arduino-language-server/blob/e453c5fbd059bae673bb21d028f5ca8e690744be/handler/handler.go#L1769-L1952
|
||||
# Which will be used in the IDE 2.0+ when 'format sketch' option is selected
|
||||
|
||||
Language: Cpp
|
||||
# LLVM is the default style setting, used when a configuration option is not set here
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveBitFields: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveMacros: false
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: Always
|
||||
AllowShortLambdasOnASingleLine: Empty
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: No
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
# Only used when "BreakBeforeBraces" set to "Custom"
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
#AfterObjCDeclaration:
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
# Java-specific
|
||||
#BreakAfterJavaFieldAnnotations:
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakStringLiterals: false
|
||||
# v12 has various problems with this set to 0 (no limit)
|
||||
# possible workaround is to set this to 4294967295 aka some large number
|
||||
# see https://reviews.llvm.org/D96896
|
||||
ColumnLimit: 0
|
||||
# "" matches none
|
||||
CommentPragmas: ""
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 2
|
||||
ContinuationIndentWidth: 2
|
||||
Cpp11BracedListStyle: false
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: true
|
||||
DisableFormat: false
|
||||
# Docs say "Do not use this in config files". The default (LLVM 11.0.1) is "false".
|
||||
#ExperimentalAutoDetectBinPacking:
|
||||
FixNamespaceComments: false
|
||||
ForEachMacros: []
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories: []
|
||||
# "" matches none
|
||||
IncludeIsMainRegex: ""
|
||||
IncludeIsMainSourceRegex: ""
|
||||
IndentCaseBlocks: true
|
||||
IndentCaseLabels: true
|
||||
IndentExternBlock: Indent
|
||||
IndentGotoLabels: false
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertTrailingCommas: None
|
||||
# Java-specific
|
||||
#JavaImportGroups:
|
||||
# JavaScript-specific
|
||||
#JavaScriptQuotes:
|
||||
#JavaScriptWrapImports
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ""
|
||||
MacroBlockEnd: ""
|
||||
# Set to a large number to effectively disable
|
||||
MaxEmptyLinesToKeep: 100000
|
||||
NamespaceIndentation: None
|
||||
NamespaceMacros: []
|
||||
# Objective C-specific
|
||||
#ObjCBinPackProtocolList:
|
||||
#ObjCBlockIndentWidth:
|
||||
#ObjCBreakBeforeNestedBlockParam:
|
||||
#ObjCSpaceAfterProperty:
|
||||
#ObjCSpaceBeforeProtocolList
|
||||
PenaltyBreakAssignment: 1
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 1
|
||||
PenaltyBreakFirstLessLess: 1
|
||||
PenaltyBreakString: 1
|
||||
PenaltyBreakTemplateDeclaration: 1
|
||||
PenaltyExcessCharacter: 1
|
||||
PenaltyReturnTypeOnItsOwnLine: 1
|
||||
# Used as a fallback if alignment style can't be detected from code (DerivePointerAlignment: true)
|
||||
PointerAlignment: Right
|
||||
RawStringFormats: []
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Auto
|
||||
StatementMacros: []
|
||||
TabWidth: 2
|
||||
TypenameMacros: []
|
||||
# Default to LF if line endings can't be detected from the content (DeriveLineEnding).
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
WhitespaceSensitiveMacros: []
|
||||
29
tests/clang-format-core.yaml
Normal file
29
tests/clang-format-core.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
BasedOnStyle: WebKit
|
||||
AlignTrailingComments: true
|
||||
SortIncludes: false
|
||||
ColumnLimit: 100
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeInheritanceColon: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
AlignTrailingComments: true
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: Empty
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlignConsecutiveAssignments: Consecutive
|
||||
AlignConsecutiveBitFields: Consecutive
|
||||
AlignConsecutiveDeclarations: Consecutive
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignOperands: Align
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakBeforeConceptDeclarations: true
|
||||
FixNamespaceComments: true
|
||||
NamespaceIndentation: Inner
|
||||
BreakBeforeBraces: Allman
|
||||
IndentWidth: 4
|
||||
IndentCaseLabels: false
|
||||
@@ -7,29 +7,30 @@ namespace bs
|
||||
class ArduinoIOHelper
|
||||
{
|
||||
public:
|
||||
ArduinoIOHelper(Stream& stream) : m_stream(stream)
|
||||
{
|
||||
}
|
||||
ArduinoIOHelper(Stream& stream) : m_stream(stream) { }
|
||||
|
||||
size_t printf(const char *format, ...)
|
||||
size_t printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
char temp[128];
|
||||
char* buffer = temp;
|
||||
size_t len = vsnprintf(temp, sizeof(temp), format, arg);
|
||||
char temp[128];
|
||||
char* buffer = temp;
|
||||
size_t len = vsnprintf(temp, sizeof(temp), format, arg);
|
||||
va_end(arg);
|
||||
if (len > sizeof(temp) - 1) {
|
||||
if (len > sizeof(temp) - 1)
|
||||
{
|
||||
buffer = new char[len + 1];
|
||||
if (!buffer) {
|
||||
if (!buffer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
va_start(arg, format);
|
||||
ets_vsnprintf(buffer, len + 1, format, arg);
|
||||
va_end(arg);
|
||||
}
|
||||
len = m_stream.write((const uint8_t*) buffer, len);
|
||||
if (buffer != temp) {
|
||||
len = m_stream.write((const uint8_t*)buffer, len);
|
||||
if (buffer != temp)
|
||||
{
|
||||
delete[] buffer;
|
||||
}
|
||||
return len;
|
||||
@@ -40,16 +41,20 @@ public:
|
||||
size_t len = 0;
|
||||
// Can't use Stream::readBytesUntil here because it can't tell the
|
||||
// difference between timing out and receiving the terminator.
|
||||
while (len < dest_size - 1) {
|
||||
while (len < dest_size - 1)
|
||||
{
|
||||
int c = m_stream.read();
|
||||
if (c < 0) {
|
||||
if (c < 0)
|
||||
{
|
||||
delay(1);
|
||||
continue;
|
||||
}
|
||||
if (c == '\r') {
|
||||
if (c == '\r')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (c == '\n') {
|
||||
if (c == '\n')
|
||||
{
|
||||
dest[len] = 0;
|
||||
break;
|
||||
}
|
||||
@@ -64,10 +69,11 @@ protected:
|
||||
|
||||
typedef ArduinoIOHelper IOHelper;
|
||||
|
||||
inline void fatal() {
|
||||
inline void fatal()
|
||||
{
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
} // namespace bs
|
||||
} // namespace bs
|
||||
|
||||
#endif //BS_ARDUINO_H
|
||||
#endif // BS_ARDUINO_H
|
||||
|
||||
@@ -18,134 +18,162 @@ namespace protocol
|
||||
|
||||
#define SS_FLAG_ESCAPE 0x8
|
||||
|
||||
typedef enum {
|
||||
/* parsing the space between arguments */
|
||||
SS_SPACE = 0x0,
|
||||
/* parsing an argument which isn't quoted */
|
||||
SS_ARG = 0x1,
|
||||
/* parsing a quoted argument */
|
||||
SS_QUOTED_ARG = 0x2,
|
||||
/* parsing an escape sequence within unquoted argument */
|
||||
SS_ARG_ESCAPED = SS_ARG | SS_FLAG_ESCAPE,
|
||||
/* parsing an escape sequence within a quoted argument */
|
||||
SS_QUOTED_ARG_ESCAPED = SS_QUOTED_ARG | SS_FLAG_ESCAPE,
|
||||
} split_state_t;
|
||||
typedef enum
|
||||
{
|
||||
/* parsing the space between arguments */
|
||||
SS_SPACE = 0x0,
|
||||
/* parsing an argument which isn't quoted */
|
||||
SS_ARG = 0x1,
|
||||
/* parsing a quoted argument */
|
||||
SS_QUOTED_ARG = 0x2,
|
||||
/* parsing an escape sequence within unquoted argument */
|
||||
SS_ARG_ESCAPED = SS_ARG | SS_FLAG_ESCAPE,
|
||||
/* parsing an escape sequence within a quoted argument */
|
||||
SS_QUOTED_ARG_ESCAPED = SS_QUOTED_ARG | SS_FLAG_ESCAPE,
|
||||
} split_state_t;
|
||||
|
||||
/* helper macro, called when done with an argument */
|
||||
#define END_ARG() do { \
|
||||
char_out = 0; \
|
||||
argv[argc++] = next_arg_start; \
|
||||
state = SS_SPACE; \
|
||||
} while(0);
|
||||
#define END_ARG() \
|
||||
do \
|
||||
{ \
|
||||
char_out = 0; \
|
||||
argv[argc++] = next_arg_start; \
|
||||
state = SS_SPACE; \
|
||||
} while (0);
|
||||
|
||||
/**
|
||||
* @brief Split command line into arguments in place
|
||||
*
|
||||
* - This function finds whitespace-separated arguments in the given input line.
|
||||
*
|
||||
* 'abc def 1 20 .3' -> [ 'abc', 'def', '1', '20', '.3' ]
|
||||
*
|
||||
* - Argument which include spaces may be surrounded with quotes. In this case
|
||||
* spaces are preserved and quotes are stripped.
|
||||
*
|
||||
* 'abc "123 456" def' -> [ 'abc', '123 456', 'def' ]
|
||||
*
|
||||
* - Escape sequences may be used to produce backslash, double quote, and space:
|
||||
*
|
||||
* 'a\ b\\c\"' -> [ 'a b\c"' ]
|
||||
*
|
||||
* Pointers to at most argv_size - 1 arguments are returned in argv array.
|
||||
* The pointer after the last one (i.e. argv[argc]) is set to NULL.
|
||||
*
|
||||
* @param line pointer to buffer to parse; it is modified in place
|
||||
* @param argv array where the pointers to arguments are written
|
||||
* @param argv_size number of elements in argv_array (max. number of arguments will be argv_size
|
||||
* - 1)
|
||||
* @return number of arguments found (argc)
|
||||
*/
|
||||
inline size_t split_args(char* line, char** argv, size_t argv_size)
|
||||
{
|
||||
const int QUOTE = '"';
|
||||
const int ESCAPE = '\\';
|
||||
const int SPACE = ' ';
|
||||
split_state_t state = SS_SPACE;
|
||||
size_t argc = 0;
|
||||
char* next_arg_start = line;
|
||||
char* out_ptr = line;
|
||||
for (char* in_ptr = line; argc < argv_size - 1; ++in_ptr)
|
||||
{
|
||||
int char_in = (unsigned char)*in_ptr;
|
||||
if (char_in == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
int char_out = -1;
|
||||
|
||||
/**
|
||||
* @brief Split command line into arguments in place
|
||||
*
|
||||
* - This function finds whitespace-separated arguments in the given input line.
|
||||
*
|
||||
* 'abc def 1 20 .3' -> [ 'abc', 'def', '1', '20', '.3' ]
|
||||
*
|
||||
* - Argument which include spaces may be surrounded with quotes. In this case
|
||||
* spaces are preserved and quotes are stripped.
|
||||
*
|
||||
* 'abc "123 456" def' -> [ 'abc', '123 456', 'def' ]
|
||||
*
|
||||
* - Escape sequences may be used to produce backslash, double quote, and space:
|
||||
*
|
||||
* 'a\ b\\c\"' -> [ 'a b\c"' ]
|
||||
*
|
||||
* Pointers to at most argv_size - 1 arguments are returned in argv array.
|
||||
* The pointer after the last one (i.e. argv[argc]) is set to NULL.
|
||||
*
|
||||
* @param line pointer to buffer to parse; it is modified in place
|
||||
* @param argv array where the pointers to arguments are written
|
||||
* @param argv_size number of elements in argv_array (max. number of arguments will be argv_size - 1)
|
||||
* @return number of arguments found (argc)
|
||||
*/
|
||||
inline size_t split_args(char *line, char **argv, size_t argv_size)
|
||||
{
|
||||
const int QUOTE = '"';
|
||||
const int ESCAPE = '\\';
|
||||
const int SPACE = ' ';
|
||||
split_state_t state = SS_SPACE;
|
||||
size_t argc = 0;
|
||||
char *next_arg_start = line;
|
||||
char *out_ptr = line;
|
||||
for (char *in_ptr = line; argc < argv_size - 1; ++in_ptr) {
|
||||
int char_in = (unsigned char) *in_ptr;
|
||||
if (char_in == 0) {
|
||||
break;
|
||||
switch (state)
|
||||
{
|
||||
case SS_SPACE:
|
||||
if (char_in == SPACE)
|
||||
{
|
||||
/* skip space */
|
||||
}
|
||||
else if (char_in == QUOTE)
|
||||
{
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_QUOTED_ARG;
|
||||
}
|
||||
else if (char_in == ESCAPE)
|
||||
{
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_ARG_ESCAPED;
|
||||
}
|
||||
else
|
||||
{
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_ARG;
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_QUOTED_ARG:
|
||||
if (char_in == QUOTE)
|
||||
{
|
||||
END_ARG();
|
||||
}
|
||||
else if (char_in == ESCAPE)
|
||||
{
|
||||
state = SS_QUOTED_ARG_ESCAPED;
|
||||
}
|
||||
else
|
||||
{
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_ARG_ESCAPED:
|
||||
case SS_QUOTED_ARG_ESCAPED:
|
||||
if (char_in == ESCAPE || char_in == QUOTE || char_in == SPACE)
|
||||
{
|
||||
char_out = char_in;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unrecognized escape character, skip */
|
||||
}
|
||||
state = (split_state_t)(state & (~SS_FLAG_ESCAPE));
|
||||
break;
|
||||
|
||||
case SS_ARG:
|
||||
if (char_in == SPACE)
|
||||
{
|
||||
END_ARG();
|
||||
}
|
||||
else if (char_in == ESCAPE)
|
||||
{
|
||||
state = SS_ARG_ESCAPED;
|
||||
}
|
||||
else
|
||||
{
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* need to output anything? */
|
||||
if (char_out >= 0)
|
||||
{
|
||||
*out_ptr = char_out;
|
||||
++out_ptr;
|
||||
}
|
||||
}
|
||||
int char_out = -1;
|
||||
|
||||
switch (state) {
|
||||
case SS_SPACE:
|
||||
if (char_in == SPACE) {
|
||||
/* skip space */
|
||||
} else if (char_in == QUOTE) {
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_QUOTED_ARG;
|
||||
} else if (char_in == ESCAPE) {
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_ARG_ESCAPED;
|
||||
} else {
|
||||
next_arg_start = out_ptr;
|
||||
state = SS_ARG;
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_QUOTED_ARG:
|
||||
if (char_in == QUOTE) {
|
||||
END_ARG();
|
||||
} else if (char_in == ESCAPE) {
|
||||
state = SS_QUOTED_ARG_ESCAPED;
|
||||
} else {
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_ARG_ESCAPED:
|
||||
case SS_QUOTED_ARG_ESCAPED:
|
||||
if (char_in == ESCAPE || char_in == QUOTE || char_in == SPACE) {
|
||||
char_out = char_in;
|
||||
} else {
|
||||
/* unrecognized escape character, skip */
|
||||
}
|
||||
state = (split_state_t) (state & (~SS_FLAG_ESCAPE));
|
||||
break;
|
||||
|
||||
case SS_ARG:
|
||||
if (char_in == SPACE) {
|
||||
END_ARG();
|
||||
} else if (char_in == ESCAPE) {
|
||||
state = SS_ARG_ESCAPED;
|
||||
} else {
|
||||
char_out = char_in;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* need to output anything? */
|
||||
if (char_out >= 0) {
|
||||
*out_ptr = char_out;
|
||||
++out_ptr;
|
||||
/* make sure the final argument is terminated */
|
||||
*out_ptr = 0;
|
||||
/* finalize the last argument */
|
||||
if (state != SS_SPACE && argc < argv_size - 1)
|
||||
{
|
||||
argv[argc++] = next_arg_start;
|
||||
}
|
||||
/* add a NULL at the end of argv */
|
||||
argv[argc] = NULL;
|
||||
|
||||
return argc;
|
||||
}
|
||||
/* make sure the final argument is terminated */
|
||||
*out_ptr = 0;
|
||||
/* finalize the last argument */
|
||||
if (state != SS_SPACE && argc < argv_size - 1) {
|
||||
argv[argc++] = next_arg_start;
|
||||
}
|
||||
/* add a NULL at the end of argv */
|
||||
argv[argc] = NULL;
|
||||
|
||||
return argc;
|
||||
}
|
||||
} // namespace protocol
|
||||
|
||||
} // namespace bs
|
||||
} // namespace bs
|
||||
|
||||
} // namespace protocol
|
||||
|
||||
#endif //BS_ARGS_H
|
||||
#endif // BS_ARGS_H
|
||||
|
||||
@@ -11,108 +11,120 @@ namespace bs
|
||||
{
|
||||
namespace protocol
|
||||
{
|
||||
template<typename IO>
|
||||
void output_test_start(IO& io, const char* file, size_t line, const char* name, const char* desc)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "start file=\"%s\" line=%d name=\"%s\" desc=\"%s\"\n", file, line, name, desc);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_check_failure(IO& io, size_t line)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "check_failure line=%d\n", line);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_test_end(IO& io, bool success, size_t checks, size_t failed_checks, size_t line=0)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "end line=%d result=%d checks=%d failed_checks=%d\n", line, success, checks, failed_checks);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_begin(IO& io)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "menu_begin\n");
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_item(IO& io, int index, const char* name, const char* desc)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "item id=%d name=\"%s\" desc=\"%s\"\n", index, name, desc);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_end(IO& io)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "menu_end\n");
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_setenv_result(IO& io, const char* key, const char* value)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "setenv key=\"%s\" value=\"%s\"\n", key, value);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_getenv_result(IO& io, const char* key, const char* value)
|
||||
{
|
||||
(void) key;
|
||||
io.printf(BS_LINE_PREFIX "getenv value=\"%s\"\n", value);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_pretest_result(IO& io, bool res)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "pretest result=%d\n", res?1:0);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
bool input_handle(IO& io, char* line_buf, size_t line_buf_size, int& test_num)
|
||||
{
|
||||
int cb_read = io.read_line(line_buf, line_buf_size);
|
||||
if (cb_read == 0 || line_buf[0] == '\n') {
|
||||
return false;
|
||||
template<typename IO>
|
||||
void output_test_start(IO& io, const char* file, size_t line, const char* name,
|
||||
const char* desc)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "start file=\"%s\" line=%d name=\"%s\" desc=\"%s\"\n", file, line,
|
||||
name, desc);
|
||||
}
|
||||
char* argv[4];
|
||||
size_t argc = split_args(line_buf, argv, sizeof(argv)/sizeof(argv[0]));
|
||||
if (argc == 0) {
|
||||
return false;
|
||||
|
||||
template<typename IO>
|
||||
void output_check_failure(IO& io, size_t line)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "check_failure line=%d\n", line);
|
||||
}
|
||||
if (strcmp(argv[0], "setenv") == 0) {
|
||||
if (argc != 3) {
|
||||
|
||||
template<typename IO>
|
||||
void output_test_end(IO& io, bool success, size_t checks, size_t failed_checks, size_t line = 0)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "end line=%d result=%d checks=%d failed_checks=%d\n", line,
|
||||
success, checks, failed_checks);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_begin(IO& io)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "menu_begin\n");
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_item(IO& io, int index, const char* name, const char* desc)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "item id=%d name=\"%s\" desc=\"%s\"\n", index, name, desc);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_menu_end(IO& io)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "menu_end\n");
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_setenv_result(IO& io, const char* key, const char* value)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "setenv key=\"%s\" value=\"%s\"\n", key, value);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_getenv_result(IO& io, const char* key, const char* value)
|
||||
{
|
||||
(void)key;
|
||||
io.printf(BS_LINE_PREFIX "getenv value=\"%s\"\n", value);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
void output_pretest_result(IO& io, bool res)
|
||||
{
|
||||
io.printf(BS_LINE_PREFIX "pretest result=%d\n", res ? 1 : 0);
|
||||
}
|
||||
|
||||
template<typename IO>
|
||||
bool input_handle(IO& io, char* line_buf, size_t line_buf_size, int& test_num)
|
||||
{
|
||||
int cb_read = io.read_line(line_buf, line_buf_size);
|
||||
if (cb_read == 0 || line_buf[0] == '\n')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
setenv(argv[1], argv[2], 1);
|
||||
output_setenv_result(io, argv[1], argv[2]);
|
||||
test_num = -1;
|
||||
return false; /* we didn't get the test number yet, so return false */
|
||||
}
|
||||
if (strcmp(argv[0], "getenv") == 0) {
|
||||
if (argc != 2) {
|
||||
char* argv[4];
|
||||
size_t argc = split_args(line_buf, argv, sizeof(argv) / sizeof(argv[0]));
|
||||
if (argc == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const char* value = getenv(argv[1]);
|
||||
output_getenv_result(io, argv[1], (value != NULL) ? value : "");
|
||||
return false;
|
||||
}
|
||||
if (strcmp(argv[0], "pretest") == 0) {
|
||||
if (argc != 1) {
|
||||
if (strcmp(argv[0], "setenv") == 0)
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
setenv(argv[1], argv[2], 1);
|
||||
output_setenv_result(io, argv[1], argv[2]);
|
||||
test_num = -1;
|
||||
return false; /* we didn't get the test number yet, so return false */
|
||||
}
|
||||
if (strcmp(argv[0], "getenv") == 0)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const char* value = getenv(argv[1]);
|
||||
output_getenv_result(io, argv[1], (value != NULL) ? value : "");
|
||||
return false;
|
||||
}
|
||||
bool res = ::pretest();
|
||||
output_pretest_result(io, res);
|
||||
return false;
|
||||
if (strcmp(argv[0], "pretest") == 0)
|
||||
{
|
||||
if (argc != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool res = ::pretest();
|
||||
output_pretest_result(io, res);
|
||||
return false;
|
||||
}
|
||||
/* not one of the commands, try to parse as test number */
|
||||
char* endptr;
|
||||
test_num = (int)strtol(argv[0], &endptr, 10);
|
||||
if (endptr != argv[0] + strlen(argv[0]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/* not one of the commands, try to parse as test number */
|
||||
char* endptr;
|
||||
test_num = (int) strtol(argv[0], &endptr, 10);
|
||||
if (endptr != argv[0] + strlen(argv[0])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // ::protocol
|
||||
} // ::bs
|
||||
} // namespace protocol
|
||||
} // namespace bs
|
||||
|
||||
#endif //BS_PROTOCOL_H
|
||||
#endif // BS_PROTOCOL_H
|
||||
|
||||
@@ -9,11 +9,9 @@ namespace bs
|
||||
class StdIOHelper
|
||||
{
|
||||
public:
|
||||
StdIOHelper()
|
||||
{
|
||||
}
|
||||
StdIOHelper() { }
|
||||
|
||||
size_t printf(const char *format, ...)
|
||||
size_t printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
@@ -25,11 +23,13 @@ public:
|
||||
size_t read_line(char* dest, size_t dest_size)
|
||||
{
|
||||
char* res = fgets(dest, dest_size, stdin);
|
||||
if (res == NULL) {
|
||||
if (res == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
size_t len = strlen(dest);
|
||||
if (dest[len - 1] == '\n') {
|
||||
if (dest[len - 1] == '\n')
|
||||
{
|
||||
dest[len - 1] = 0;
|
||||
len--;
|
||||
}
|
||||
@@ -39,10 +39,11 @@ public:
|
||||
|
||||
typedef StdIOHelper IOHelper;
|
||||
|
||||
inline void fatal() {
|
||||
inline void fatal()
|
||||
{
|
||||
throw std::runtime_error("fatal error");
|
||||
}
|
||||
|
||||
} // namespace bs
|
||||
} // namespace bs
|
||||
|
||||
#endif //BS_STDIO_H
|
||||
#endif // BS_STDIO_H
|
||||
|
||||
@@ -20,15 +20,18 @@
|
||||
|
||||
namespace bs
|
||||
{
|
||||
typedef void(*test_case_func_t)();
|
||||
typedef void (*test_case_func_t)();
|
||||
|
||||
class TestCase
|
||||
{
|
||||
public:
|
||||
TestCase(TestCase* prev, test_case_func_t func, const char* file, size_t line, const char* name, const char* desc)
|
||||
: m_func(func), m_file(file), m_line(line), m_name(name), m_desc(desc)
|
||||
TestCase(TestCase* prev, test_case_func_t func, const char* file, size_t line, const char* name,
|
||||
const char* desc) :
|
||||
m_func(func),
|
||||
m_file(file), m_line(line), m_name(name), m_desc(desc)
|
||||
{
|
||||
if (prev) {
|
||||
if (prev)
|
||||
{
|
||||
prev->m_next = this;
|
||||
}
|
||||
}
|
||||
@@ -60,36 +63,40 @@ public:
|
||||
|
||||
const char* desc() const
|
||||
{
|
||||
return (m_desc)?m_desc:"";
|
||||
return (m_desc) ? m_desc : "";
|
||||
}
|
||||
|
||||
protected:
|
||||
TestCase* m_next = nullptr;
|
||||
TestCase* m_next = nullptr;
|
||||
test_case_func_t m_func;
|
||||
const char* m_file;
|
||||
size_t m_line;
|
||||
const char* m_name;
|
||||
const char* m_desc;
|
||||
const char* m_file;
|
||||
size_t m_line;
|
||||
const char* m_name;
|
||||
const char* m_desc;
|
||||
};
|
||||
|
||||
struct Registry {
|
||||
void add(test_case_func_t func, const char* file, size_t line, const char* name, const char* desc)
|
||||
struct Registry
|
||||
{
|
||||
void add(test_case_func_t func, const char* file, size_t line, const char* name,
|
||||
const char* desc)
|
||||
{
|
||||
TestCase* tc = new TestCase(m_last, func, file, line, name, desc);
|
||||
if (!m_first) {
|
||||
if (!m_first)
|
||||
{
|
||||
m_first = tc;
|
||||
}
|
||||
m_last = tc;
|
||||
}
|
||||
TestCase* m_first = nullptr;
|
||||
TestCase* m_last = nullptr;
|
||||
TestCase* m_last = nullptr;
|
||||
};
|
||||
|
||||
struct Env {
|
||||
std::function<void(void)> m_check_pass;
|
||||
struct Env
|
||||
{
|
||||
std::function<void(void)> m_check_pass;
|
||||
std::function<void(size_t)> m_check_fail;
|
||||
std::function<void(size_t)> m_fail;
|
||||
Registry m_registry;
|
||||
Registry m_registry;
|
||||
};
|
||||
|
||||
extern Env g_env;
|
||||
@@ -98,25 +105,27 @@ template<typename IO>
|
||||
class Runner
|
||||
{
|
||||
typedef Runner<IO> Tself;
|
||||
|
||||
public:
|
||||
Runner(IO& io) : m_io(io)
|
||||
{
|
||||
g_env.m_check_pass = std::bind(&Tself::check_pass, this);
|
||||
g_env.m_check_fail = std::bind(&Tself::check_fail, this, std::placeholders::_1);
|
||||
g_env.m_fail = std::bind(&Tself::fail, this, std::placeholders::_1);
|
||||
g_env.m_fail = std::bind(&Tself::fail, this, std::placeholders::_1);
|
||||
}
|
||||
|
||||
~Runner()
|
||||
{
|
||||
g_env.m_check_pass = 0;
|
||||
g_env.m_check_fail = 0;
|
||||
g_env.m_fail = 0;
|
||||
g_env.m_fail = 0;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
do {
|
||||
} while(do_menu());
|
||||
do
|
||||
{
|
||||
} while (do_menu());
|
||||
}
|
||||
|
||||
void check_pass()
|
||||
@@ -132,7 +141,8 @@ public:
|
||||
|
||||
void fail(size_t line)
|
||||
{
|
||||
protocol::output_test_end(m_io, false, m_check_pass_count + m_check_fail_count, m_check_fail_count, line);
|
||||
protocol::output_test_end(m_io, false, m_check_pass_count + m_check_fail_count,
|
||||
m_check_fail_count, line);
|
||||
bs::fatal();
|
||||
}
|
||||
|
||||
@@ -141,22 +151,28 @@ protected:
|
||||
{
|
||||
protocol::output_menu_begin(m_io);
|
||||
int id = 1;
|
||||
for (TestCase* tc = g_env.m_registry.m_first; tc; tc = tc->next(), ++id) {
|
||||
for (TestCase* tc = g_env.m_registry.m_first; tc; tc = tc->next(), ++id)
|
||||
{
|
||||
protocol::output_menu_item(m_io, id, tc->name(), tc->desc());
|
||||
}
|
||||
protocol::output_menu_end(m_io);
|
||||
while(true) {
|
||||
int id;
|
||||
while (true)
|
||||
{
|
||||
int id;
|
||||
char line_buf[BS_LINE_BUF_SIZE];
|
||||
if (!protocol::input_handle(m_io, line_buf, sizeof(line_buf), id)) {
|
||||
if (!protocol::input_handle(m_io, line_buf, sizeof(line_buf), id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (id < 0) {
|
||||
if (id < 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
TestCase* tc = g_env.m_registry.m_first;
|
||||
for (int i = 0; i != id - 1 && tc; ++i, tc = tc->next());
|
||||
if (!tc) {
|
||||
for (int i = 0; i != id - 1 && tc; ++i, tc = tc->next())
|
||||
;
|
||||
if (!tc)
|
||||
{
|
||||
bs::fatal();
|
||||
}
|
||||
m_check_pass_count = 0;
|
||||
@@ -164,12 +180,13 @@ protected:
|
||||
protocol::output_test_start(m_io, tc->file(), tc->line(), tc->name(), tc->desc());
|
||||
tc->run();
|
||||
bool success = m_check_fail_count == 0;
|
||||
protocol::output_test_end(m_io, success, m_check_pass_count + m_check_fail_count, m_check_fail_count);
|
||||
protocol::output_test_end(m_io, success, m_check_pass_count + m_check_fail_count,
|
||||
m_check_fail_count);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
IO& m_io;
|
||||
IO& m_io;
|
||||
size_t m_check_pass_count;
|
||||
size_t m_check_fail_count;
|
||||
};
|
||||
@@ -177,7 +194,8 @@ protected:
|
||||
class AutoReg
|
||||
{
|
||||
public:
|
||||
AutoReg(test_case_func_t func, const char* file, size_t line, const char* name, const char* desc = nullptr)
|
||||
AutoReg(test_case_func_t func, const char* file, size_t line, const char* name,
|
||||
const char* desc = nullptr)
|
||||
{
|
||||
g_env.m_registry.add(func, file, line, name, desc);
|
||||
}
|
||||
@@ -185,39 +203,59 @@ public:
|
||||
|
||||
inline void check(bool condition, size_t line)
|
||||
{
|
||||
if (!condition) {
|
||||
if (!condition)
|
||||
{
|
||||
g_env.m_check_fail(line);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_env.m_check_pass();
|
||||
}
|
||||
}
|
||||
|
||||
inline void require(bool condition, size_t line)
|
||||
{
|
||||
if (!condition) {
|
||||
if (!condition)
|
||||
{
|
||||
g_env.m_check_fail(line);
|
||||
g_env.m_fail(line);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
g_env.m_check_pass();
|
||||
}
|
||||
}
|
||||
|
||||
} // ::bs
|
||||
} // namespace bs
|
||||
|
||||
#define BS_NAME_LINE2( name, line ) name##line
|
||||
#define BS_NAME_LINE( name, line ) BS_NAME_LINE2( name, line )
|
||||
#define BS_UNIQUE_NAME( name ) BS_NAME_LINE( name, __LINE__ )
|
||||
#define BS_NAME_LINE2(name, line) name##line
|
||||
#define BS_NAME_LINE(name, line) BS_NAME_LINE2(name, line)
|
||||
#define BS_UNIQUE_NAME(name) BS_NAME_LINE(name, __LINE__)
|
||||
|
||||
#define TEST_CASE( ... ) \
|
||||
static void BS_UNIQUE_NAME( TEST_FUNC__ )(); \
|
||||
namespace{ bs::AutoReg BS_UNIQUE_NAME( test_autoreg__ )( &BS_UNIQUE_NAME( TEST_FUNC__ ), __FILE__, __LINE__, __VA_ARGS__ ); }\
|
||||
static void BS_UNIQUE_NAME( TEST_FUNC__ )()
|
||||
#define TEST_CASE(...) \
|
||||
static void BS_UNIQUE_NAME(TEST_FUNC__)(); \
|
||||
namespace \
|
||||
{ \
|
||||
bs::AutoReg BS_UNIQUE_NAME(test_autoreg__)(&BS_UNIQUE_NAME(TEST_FUNC__), __FILE__, \
|
||||
__LINE__, __VA_ARGS__); \
|
||||
} \
|
||||
static void BS_UNIQUE_NAME(TEST_FUNC__)()
|
||||
|
||||
#define CHECK(condition) bs::check((condition), __LINE__)
|
||||
#define REQUIRE(condition) bs::require((condition), __LINE__)
|
||||
#define FAIL() bs::g_env.m_fail(__LINE__)
|
||||
|
||||
#define BS_ENV_DECLARE() namespace bs { Env g_env; }
|
||||
#define BS_RUN(...) do { bs::IOHelper helper = bs::IOHelper(__VA_ARGS__); bs::Runner<bs::IOHelper> runner(helper); runner.run(); } while(0);
|
||||
#define BS_ENV_DECLARE() \
|
||||
namespace bs \
|
||||
{ \
|
||||
Env g_env; \
|
||||
}
|
||||
#define BS_RUN(...) \
|
||||
do \
|
||||
{ \
|
||||
bs::IOHelper helper = bs::IOHelper(__VA_ARGS__); \
|
||||
bs::Runner<bs::IOHelper> runner(helper); \
|
||||
runner.run(); \
|
||||
} while (0);
|
||||
|
||||
#endif //BSTEST_H
|
||||
#endif // BSTEST_H
|
||||
|
||||
@@ -3,21 +3,23 @@
|
||||
|
||||
BS_ENV_DECLARE();
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
while(true) {
|
||||
try{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
BS_RUN();
|
||||
return 0;
|
||||
}catch(...) {
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
printf("Exception\n\n");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("this test runs successfully", "[bluesmoke]")
|
||||
{
|
||||
CHECK(1 + 1 == 2);
|
||||
@@ -38,17 +40,12 @@ TEST_CASE("another test which fails and crashes", "[bluesmoke][fail]")
|
||||
REQUIRE(false);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("third test which should be skipped", "[.]")
|
||||
{
|
||||
FAIL();
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("this test also runs successfully", "[bluesmoke]")
|
||||
{
|
||||
|
||||
}
|
||||
TEST_CASE("this test also runs successfully", "[bluesmoke]") { }
|
||||
|
||||
TEST_CASE("environment variables can be set and read from python", "[bluesmoke]")
|
||||
{
|
||||
@@ -57,4 +54,3 @@ TEST_CASE("environment variables can be set and read from python", "[bluesmoke]"
|
||||
CHECK(strcmp(res, "42") == 0);
|
||||
setenv("VAR_FROM_TEST", "24", 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
|
||||
#define memcmp memcmp_P
|
||||
#define memcpy memcpy_P
|
||||
#define memmem memmem_P
|
||||
@@ -18,416 +16,404 @@
|
||||
#define strcmp strcmp_P
|
||||
#define strncmp strncmp_P
|
||||
|
||||
|
||||
_CONST char *it = "<UNSET>"; /* Routine name for message routines. */
|
||||
static int errors = 0;
|
||||
_CONST char* it = "<UNSET>"; /* Routine name for message routines. */
|
||||
static int errors = 0;
|
||||
|
||||
/* Complain if condition is not true. */
|
||||
#define check(thing) checkit(thing, __LINE__)
|
||||
|
||||
static void
|
||||
_DEFUN(checkit,(ok,l),
|
||||
int ok _AND
|
||||
int l )
|
||||
static void _DEFUN(checkit, (ok, l), int ok _AND int l)
|
||||
|
||||
{
|
||||
// newfunc(it);
|
||||
// line(l);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
printf("string.c:%d %s\n", l, it);
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
// newfunc(it);
|
||||
// line(l);
|
||||
|
||||
|
||||
|
||||
/* Complain if first two args don't strcmp as equal. */
|
||||
#define equal(a, b) funcqual(a,b,__LINE__);
|
||||
|
||||
static void
|
||||
_DEFUN(funcqual,(a,b,l),
|
||||
char *a _AND
|
||||
char *b _AND
|
||||
int l)
|
||||
{
|
||||
// newfunc(it);
|
||||
|
||||
// line(l);
|
||||
if (a == NULL && b == NULL) return;
|
||||
if (strcmp(a,b)) {
|
||||
printf("string.c:%d (%s)\n", l, it);
|
||||
if (!ok)
|
||||
{
|
||||
printf("string.c:%d %s\n", l, it);
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
|
||||
/* Complain if first two args don't strcmp as equal. */
|
||||
#define equal(a, b) funcqual(a, b, __LINE__);
|
||||
|
||||
static void _DEFUN(funcqual, (a, b, l), char* a _AND char* b _AND int l)
|
||||
{
|
||||
// newfunc(it);
|
||||
|
||||
// line(l);
|
||||
if (a == NULL && b == NULL)
|
||||
return;
|
||||
if (strcmp(a, b))
|
||||
{
|
||||
printf("string.c:%d (%s)\n", l, it);
|
||||
}
|
||||
}
|
||||
|
||||
static char one[50];
|
||||
static char two[50];
|
||||
|
||||
|
||||
void libm_test_string()
|
||||
{
|
||||
/* Test strcmp first because we use it to test other things. */
|
||||
it = "strcmp";
|
||||
check(strcmp("", "") == 0); /* Trivial case. */
|
||||
check(strcmp("a", "a") == 0); /* Identity. */
|
||||
check(strcmp("abc", "abc") == 0); /* Multicharacter. */
|
||||
check(strcmp("abc", "abcd") < 0); /* Length mismatches. */
|
||||
check(strcmp("abcd", "abc") > 0);
|
||||
check(strcmp("abcd", "abce") < 0); /* Honest miscompares. */
|
||||
check(strcmp("abce", "abcd") > 0);
|
||||
check(strcmp("a\103", "a") > 0); /* Tricky if char signed. */
|
||||
check(strcmp("a\103", "a\003") > 0);
|
||||
/* Test strcmp first because we use it to test other things. */
|
||||
it = "strcmp";
|
||||
check(strcmp("", "") == 0); /* Trivial case. */
|
||||
check(strcmp("a", "a") == 0); /* Identity. */
|
||||
check(strcmp("abc", "abc") == 0); /* Multicharacter. */
|
||||
check(strcmp("abc", "abcd") < 0); /* Length mismatches. */
|
||||
check(strcmp("abcd", "abc") > 0);
|
||||
check(strcmp("abcd", "abce") < 0); /* Honest miscompares. */
|
||||
check(strcmp("abce", "abcd") > 0);
|
||||
check(strcmp("a\103", "a") > 0); /* Tricky if char signed. */
|
||||
check(strcmp("a\103", "a\003") > 0);
|
||||
|
||||
/* Test strcpy next because we need it to set up other tests. */
|
||||
it = "strcpy";
|
||||
check(strcpy(one, "abcd") == one); /* Returned value. */
|
||||
equal(one, "abcd"); /* Basic test. */
|
||||
/* Test strcpy next because we need it to set up other tests. */
|
||||
it = "strcpy";
|
||||
check(strcpy(one, "abcd") == one); /* Returned value. */
|
||||
equal(one, "abcd"); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "x");
|
||||
equal(one, "x"); /* Writeover. */
|
||||
equal(one+2, "cd"); /* Wrote too much? */
|
||||
(void)strcpy(one, "x");
|
||||
equal(one, "x"); /* Writeover. */
|
||||
equal(one + 2, "cd"); /* Wrote too much? */
|
||||
|
||||
(void) strcpy(two, "hi there");
|
||||
(void) strcpy(one, two);
|
||||
equal(one, "hi there"); /* Basic test encore. */
|
||||
equal(two, "hi there"); /* Stomped on source? */
|
||||
(void)strcpy(two, "hi there");
|
||||
(void)strcpy(one, two);
|
||||
equal(one, "hi there"); /* Basic test encore. */
|
||||
equal(two, "hi there"); /* Stomped on source? */
|
||||
|
||||
(void) strcpy(one, "");
|
||||
equal(one, ""); /* Boundary condition. */
|
||||
(void)strcpy(one, "");
|
||||
equal(one, ""); /* Boundary condition. */
|
||||
|
||||
/* strcat. */
|
||||
it = "strcat";
|
||||
(void) strcpy(one, "ijk");
|
||||
check(strcat(one, "lmn") == one); /* Returned value. */
|
||||
equal(one, "ijklmn"); /* Basic test. */
|
||||
/* strcat. */
|
||||
it = "strcat";
|
||||
(void)strcpy(one, "ijk");
|
||||
check(strcat(one, "lmn") == one); /* Returned value. */
|
||||
equal(one, "ijklmn"); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "x");
|
||||
(void) strcat(one, "yz");
|
||||
equal(one, "xyz"); /* Writeover. */
|
||||
equal(one+4, "mn"); /* Wrote too much? */
|
||||
(void)strcpy(one, "x");
|
||||
(void)strcat(one, "yz");
|
||||
equal(one, "xyz"); /* Writeover. */
|
||||
equal(one + 4, "mn"); /* Wrote too much? */
|
||||
|
||||
(void) strcpy(one, "gh");
|
||||
(void) strcpy(two, "ef");
|
||||
(void) strcat(one, two);
|
||||
equal(one, "ghef"); /* Basic test encore. */
|
||||
equal(two, "ef"); /* Stomped on source? */
|
||||
(void)strcpy(one, "gh");
|
||||
(void)strcpy(two, "ef");
|
||||
(void)strcat(one, two);
|
||||
equal(one, "ghef"); /* Basic test encore. */
|
||||
equal(two, "ef"); /* Stomped on source? */
|
||||
|
||||
(void) strcpy(one, "");
|
||||
(void) strcat(one, "");
|
||||
equal(one, ""); /* Boundary conditions. */
|
||||
(void) strcpy(one, "ab");
|
||||
(void) strcat(one, "");
|
||||
equal(one, "ab");
|
||||
(void) strcpy(one, "");
|
||||
(void) strcat(one, "cd");
|
||||
equal(one, "cd");
|
||||
(void)strcpy(one, "");
|
||||
(void)strcat(one, "");
|
||||
equal(one, ""); /* Boundary conditions. */
|
||||
(void)strcpy(one, "ab");
|
||||
(void)strcat(one, "");
|
||||
equal(one, "ab");
|
||||
(void)strcpy(one, "");
|
||||
(void)strcat(one, "cd");
|
||||
equal(one, "cd");
|
||||
|
||||
/* strncat - first test it as strcat, with big counts,
|
||||
then test the count mechanism. */
|
||||
it = "strncat";
|
||||
(void) strcpy(one, "ijk");
|
||||
check(strncat(one, "lmn", 99) == one); /* Returned value. */
|
||||
equal(one, "ijklmn"); /* Basic test. */
|
||||
/* strncat - first test it as strcat, with big counts,
|
||||
then test the count mechanism. */
|
||||
it = "strncat";
|
||||
(void)strcpy(one, "ijk");
|
||||
check(strncat(one, "lmn", 99) == one); /* Returned value. */
|
||||
equal(one, "ijklmn"); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "x");
|
||||
(void) strncat(one, "yz", 99);
|
||||
equal(one, "xyz"); /* Writeover. */
|
||||
equal(one+4, "mn"); /* Wrote too much? */
|
||||
(void)strcpy(one, "x");
|
||||
(void)strncat(one, "yz", 99);
|
||||
equal(one, "xyz"); /* Writeover. */
|
||||
equal(one + 4, "mn"); /* Wrote too much? */
|
||||
|
||||
(void) strcpy(one, "gh");
|
||||
(void) strcpy(two, "ef");
|
||||
(void) strncat(one, two, 99);
|
||||
equal(one, "ghef"); /* Basic test encore. */
|
||||
equal(two, "ef"); /* Stomped on source? */
|
||||
(void)strcpy(one, "gh");
|
||||
(void)strcpy(two, "ef");
|
||||
(void)strncat(one, two, 99);
|
||||
equal(one, "ghef"); /* Basic test encore. */
|
||||
equal(two, "ef"); /* Stomped on source? */
|
||||
|
||||
(void) strcpy(one, "");
|
||||
(void) strncat(one, "", 99);
|
||||
equal(one, ""); /* Boundary conditions. */
|
||||
(void) strcpy(one, "ab");
|
||||
(void) strncat(one, "", 99);
|
||||
equal(one, "ab");
|
||||
(void) strcpy(one, "");
|
||||
(void) strncat(one, "cd", 99);
|
||||
equal(one, "cd");
|
||||
(void)strcpy(one, "");
|
||||
(void)strncat(one, "", 99);
|
||||
equal(one, ""); /* Boundary conditions. */
|
||||
(void)strcpy(one, "ab");
|
||||
(void)strncat(one, "", 99);
|
||||
equal(one, "ab");
|
||||
(void)strcpy(one, "");
|
||||
(void)strncat(one, "cd", 99);
|
||||
equal(one, "cd");
|
||||
|
||||
(void) strcpy(one, "ab");
|
||||
(void) strncat(one, "cdef", 2);
|
||||
equal(one, "abcd"); /* Count-limited. */
|
||||
(void)strcpy(one, "ab");
|
||||
(void)strncat(one, "cdef", 2);
|
||||
equal(one, "abcd"); /* Count-limited. */
|
||||
|
||||
(void) strncat(one, "gh", 0);
|
||||
equal(one, "abcd"); /* Zero count. */
|
||||
(void)strncat(one, "gh", 0);
|
||||
equal(one, "abcd"); /* Zero count. */
|
||||
|
||||
(void) strncat(one, "gh", 2);
|
||||
equal(one, "abcdgh"); /* Count _AND length equal. */
|
||||
it = "strncmp";
|
||||
/* strncmp - first test as strcmp with big counts";*/
|
||||
check(strncmp("", "", 99) == 0); /* Trivial case. */
|
||||
check(strncmp("a", "a", 99) == 0); /* Identity. */
|
||||
check(strncmp("abc", "abc", 99) == 0); /* Multicharacter. */
|
||||
check(strncmp("abc", "abcd", 99) < 0); /* Length unequal. */
|
||||
check(strncmp("abcd", "abc",99) > 0);
|
||||
check(strncmp("abcd", "abce", 99) < 0); /* Honestly unequal. */
|
||||
check(strncmp("abce", "abcd",99)>0);
|
||||
check(strncmp("abce", "abcd", 3) == 0); /* Count limited. */
|
||||
check(strncmp("abce", "abc", 3) == 0); /* Count == length. */
|
||||
check(strncmp("abcd", "abce", 4) < 0); /* Nudging limit. */
|
||||
check(strncmp("abc", "def", 0) == 0); /* Zero count. */
|
||||
(void)strncat(one, "gh", 2);
|
||||
equal(one, "abcdgh"); /* Count _AND length equal. */
|
||||
it = "strncmp";
|
||||
/* strncmp - first test as strcmp with big counts";*/
|
||||
check(strncmp("", "", 99) == 0); /* Trivial case. */
|
||||
check(strncmp("a", "a", 99) == 0); /* Identity. */
|
||||
check(strncmp("abc", "abc", 99) == 0); /* Multicharacter. */
|
||||
check(strncmp("abc", "abcd", 99) < 0); /* Length unequal. */
|
||||
check(strncmp("abcd", "abc", 99) > 0);
|
||||
check(strncmp("abcd", "abce", 99) < 0); /* Honestly unequal. */
|
||||
check(strncmp("abce", "abcd", 99) > 0);
|
||||
check(strncmp("abce", "abcd", 3) == 0); /* Count limited. */
|
||||
check(strncmp("abce", "abc", 3) == 0); /* Count == length. */
|
||||
check(strncmp("abcd", "abce", 4) < 0); /* Nudging limit. */
|
||||
check(strncmp("abc", "def", 0) == 0); /* Zero count. */
|
||||
|
||||
/* strncpy - testing is a bit different because of odd semantics. */
|
||||
it = "strncpy";
|
||||
check(strncpy(one, "abc", 4) == one); /* Returned value. */
|
||||
equal(one, "abc"); /* Did the copy go right? */
|
||||
/* strncpy - testing is a bit different because of odd semantics. */
|
||||
it = "strncpy";
|
||||
check(strncpy(one, "abc", 4) == one); /* Returned value. */
|
||||
equal(one, "abc"); /* Did the copy go right? */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strncpy(one, "xyz", 2);
|
||||
equal(one, "xycdefgh"); /* Copy cut by count. */
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
(void)strncpy(one, "xyz", 2);
|
||||
equal(one, "xycdefgh"); /* Copy cut by count. */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strncpy(one, "xyz", 3); /* Copy cut just before NUL. */
|
||||
equal(one, "xyzdefgh");
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
(void)strncpy(one, "xyz", 3); /* Copy cut just before NUL. */
|
||||
equal(one, "xyzdefgh");
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strncpy(one, "xyz", 4); /* Copy just includes NUL. */
|
||||
equal(one, "xyz");
|
||||
equal(one+4, "efgh"); /* Wrote too much? */
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
(void)strncpy(one, "xyz", 4); /* Copy just includes NUL. */
|
||||
equal(one, "xyz");
|
||||
equal(one + 4, "efgh"); /* Wrote too much? */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strncpy(one, "xyz", 5); /* Copy includes padding. */
|
||||
equal(one, "xyz");
|
||||
equal(one+4, "");
|
||||
equal(one+5, "fgh");
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
(void)strncpy(one, "xyz", 5); /* Copy includes padding. */
|
||||
equal(one, "xyz");
|
||||
equal(one + 4, "");
|
||||
equal(one + 5, "fgh");
|
||||
|
||||
(void) strcpy(one, "abc");
|
||||
(void) strncpy(one, "xyz", 0); /* Zero-length copy. */
|
||||
equal(one, "abc");
|
||||
(void)strcpy(one, "abc");
|
||||
(void)strncpy(one, "xyz", 0); /* Zero-length copy. */
|
||||
equal(one, "abc");
|
||||
|
||||
(void) strncpy(one, "", 2); /* Zero-length source. */
|
||||
equal(one, "");
|
||||
equal(one+1, "");
|
||||
equal(one+2, "c");
|
||||
(void)strncpy(one, "", 2); /* Zero-length source. */
|
||||
equal(one, "");
|
||||
equal(one + 1, "");
|
||||
equal(one + 2, "c");
|
||||
|
||||
(void) strcpy(one, "hi there");
|
||||
(void) strncpy(two, one, 9);
|
||||
equal(two, "hi there"); /* Just paranoia. */
|
||||
equal(one, "hi there"); /* Stomped on source? */
|
||||
(void)strcpy(one, "hi there");
|
||||
(void)strncpy(two, one, 9);
|
||||
equal(two, "hi there"); /* Just paranoia. */
|
||||
equal(one, "hi there"); /* Stomped on source? */
|
||||
|
||||
/* strlen. */
|
||||
it = "strlen";
|
||||
check(strlen("") == 0); /* Empty. */
|
||||
check(strlen("a") == 1); /* Single char. */
|
||||
check(strlen("abcd") == 4); /* Multiple chars. */
|
||||
/* strlen. */
|
||||
it = "strlen";
|
||||
check(strlen("") == 0); /* Empty. */
|
||||
check(strlen("a") == 1); /* Single char. */
|
||||
check(strlen("abcd") == 4); /* Multiple chars. */
|
||||
|
||||
/* strchr. */
|
||||
it = "strchr";
|
||||
check(strchr("abcd", 'z') == NULL); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(strchr(one, 'c') == one+2); /* Basic test. */
|
||||
check(strchr(one, 'd') == one+3); /* End of string. */
|
||||
check(strchr(one, 'a') == one); /* Beginning. */
|
||||
check(strchr(one, '\0') == one+4); /* Finding NUL. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(strchr(one, 'b') == one+1); /* Finding first. */
|
||||
(void) strcpy(one, "");
|
||||
check(strchr(one, 'b') == NULL); /* Empty string. */
|
||||
check(strchr(one, '\0') == one); /* NUL in empty string. */
|
||||
/* strchr. */
|
||||
it = "strchr";
|
||||
check(strchr("abcd", 'z') == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(strchr(one, 'c') == one + 2); /* Basic test. */
|
||||
check(strchr(one, 'd') == one + 3); /* End of string. */
|
||||
check(strchr(one, 'a') == one); /* Beginning. */
|
||||
check(strchr(one, '\0') == one + 4); /* Finding NUL. */
|
||||
(void)strcpy(one, "ababa");
|
||||
check(strchr(one, 'b') == one + 1); /* Finding first. */
|
||||
(void)strcpy(one, "");
|
||||
check(strchr(one, 'b') == NULL); /* Empty string. */
|
||||
check(strchr(one, '\0') == one); /* NUL in empty string. */
|
||||
|
||||
/* index - just like strchr. */
|
||||
it = "index";
|
||||
check(index("abcd", 'z') == NULL); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(index(one, 'c') == one+2); /* Basic test. */
|
||||
check(index(one, 'd') == one+3); /* End of string. */
|
||||
check(index(one, 'a') == one); /* Beginning. */
|
||||
check(index(one, '\0') == one+4); /* Finding NUL. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(index(one, 'b') == one+1); /* Finding first. */
|
||||
(void) strcpy(one, "");
|
||||
check(index(one, 'b') == NULL); /* Empty string. */
|
||||
check(index(one, '\0') == one); /* NUL in empty string. */
|
||||
/* index - just like strchr. */
|
||||
it = "index";
|
||||
check(index("abcd", 'z') == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(index(one, 'c') == one + 2); /* Basic test. */
|
||||
check(index(one, 'd') == one + 3); /* End of string. */
|
||||
check(index(one, 'a') == one); /* Beginning. */
|
||||
check(index(one, '\0') == one + 4); /* Finding NUL. */
|
||||
(void)strcpy(one, "ababa");
|
||||
check(index(one, 'b') == one + 1); /* Finding first. */
|
||||
(void)strcpy(one, "");
|
||||
check(index(one, 'b') == NULL); /* Empty string. */
|
||||
check(index(one, '\0') == one); /* NUL in empty string. */
|
||||
|
||||
/* strrchr. */
|
||||
it = "strrchr";
|
||||
check(strrchr("abcd", 'z') == NULL); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(strrchr(one, 'c') == one+2); /* Basic test. */
|
||||
check(strrchr(one, 'd') == one+3); /* End of string. */
|
||||
check(strrchr(one, 'a') == one); /* Beginning. */
|
||||
check(strrchr(one, '\0') == one+4); /* Finding NUL. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(strrchr(one, 'b') == one+3); /* Finding last. */
|
||||
(void) strcpy(one, "");
|
||||
check(strrchr(one, 'b') == NULL); /* Empty string. */
|
||||
check(strrchr(one, '\0') == one); /* NUL in empty string. */
|
||||
/* strrchr. */
|
||||
it = "strrchr";
|
||||
check(strrchr("abcd", 'z') == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(strrchr(one, 'c') == one + 2); /* Basic test. */
|
||||
check(strrchr(one, 'd') == one + 3); /* End of string. */
|
||||
check(strrchr(one, 'a') == one); /* Beginning. */
|
||||
check(strrchr(one, '\0') == one + 4); /* Finding NUL. */
|
||||
(void)strcpy(one, "ababa");
|
||||
check(strrchr(one, 'b') == one + 3); /* Finding last. */
|
||||
(void)strcpy(one, "");
|
||||
check(strrchr(one, 'b') == NULL); /* Empty string. */
|
||||
check(strrchr(one, '\0') == one); /* NUL in empty string. */
|
||||
|
||||
/* rindex - just like strrchr. */
|
||||
it = "rindex";
|
||||
check(rindex("abcd", 'z') == NULL); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(rindex(one, 'c') == one+2); /* Basic test. */
|
||||
check(rindex(one, 'd') == one+3); /* End of string. */
|
||||
check(rindex(one, 'a') == one); /* Beginning. */
|
||||
check(rindex(one, '\0') == one+4); /* Finding NUL. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(rindex(one, 'b') == one+3); /* Finding last. */
|
||||
(void) strcpy(one, "");
|
||||
check(rindex(one, 'b') == NULL); /* Empty string. */
|
||||
check(rindex(one, '\0') == one); /* NUL in empty string. */
|
||||
/* rindex - just like strrchr. */
|
||||
it = "rindex";
|
||||
check(rindex("abcd", 'z') == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(rindex(one, 'c') == one + 2); /* Basic test. */
|
||||
check(rindex(one, 'd') == one + 3); /* End of string. */
|
||||
check(rindex(one, 'a') == one); /* Beginning. */
|
||||
check(rindex(one, '\0') == one + 4); /* Finding NUL. */
|
||||
(void)strcpy(one, "ababa");
|
||||
check(rindex(one, 'b') == one + 3); /* Finding last. */
|
||||
(void)strcpy(one, "");
|
||||
check(rindex(one, 'b') == NULL); /* Empty string. */
|
||||
check(rindex(one, '\0') == one); /* NUL in empty string. */
|
||||
|
||||
/* strpbrk - somewhat like strchr. */
|
||||
it = "strpbrk";
|
||||
check(strpbrk("abcd", "z") == NULL); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(strpbrk(one, "c") == one+2); /* Basic test. */
|
||||
check(strpbrk(one, "d") == one+3); /* End of string. */
|
||||
check(strpbrk(one, "a") == one); /* Beginning. */
|
||||
check(strpbrk(one, "") == NULL); /* Empty search list. */
|
||||
check(strpbrk(one, "cb") == one+1); /* Multiple search. */
|
||||
(void) strcpy(one, "abcabdea");
|
||||
check(strpbrk(one, "b") == one+1); /* Finding first. */
|
||||
check(strpbrk(one, "cb") == one+1); /* With multiple search. */
|
||||
check(strpbrk(one, "db") == one+1); /* Another variant. */
|
||||
(void) strcpy(one, "");
|
||||
check(strpbrk(one, "bc") == NULL); /* Empty string. */
|
||||
check(strpbrk(one, "") == NULL); /* Both strings empty. */
|
||||
/* strpbrk - somewhat like strchr. */
|
||||
it = "strpbrk";
|
||||
check(strpbrk("abcd", "z") == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(strpbrk(one, "c") == one + 2); /* Basic test. */
|
||||
check(strpbrk(one, "d") == one + 3); /* End of string. */
|
||||
check(strpbrk(one, "a") == one); /* Beginning. */
|
||||
check(strpbrk(one, "") == NULL); /* Empty search list. */
|
||||
check(strpbrk(one, "cb") == one + 1); /* Multiple search. */
|
||||
(void)strcpy(one, "abcabdea");
|
||||
check(strpbrk(one, "b") == one + 1); /* Finding first. */
|
||||
check(strpbrk(one, "cb") == one + 1); /* With multiple search. */
|
||||
check(strpbrk(one, "db") == one + 1); /* Another variant. */
|
||||
(void)strcpy(one, "");
|
||||
check(strpbrk(one, "bc") == NULL); /* Empty string. */
|
||||
check(strpbrk(one, "") == NULL); /* Both strings empty. */
|
||||
|
||||
/* strstr - somewhat like strchr. */
|
||||
it = "strstr";
|
||||
check(strstr("z", "abcd") == NULL); /* Not found. */
|
||||
check(strstr("abx", "abcd") == NULL); /* Dead end. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(strstr(one,"c") == one+2); /* Basic test. */
|
||||
check(strstr(one, "bc") == one+1); /* Multichar. */
|
||||
check(strstr(one,"d") == one+3); /* End of string. */
|
||||
check(strstr(one,"cd") == one+2); /* Tail of string. */
|
||||
check(strstr(one,"abc") == one); /* Beginning. */
|
||||
check(strstr(one,"abcd") == one); /* Exact match. */
|
||||
check(strstr(one,"de") == NULL); /* Past end. */
|
||||
check(strstr(one,"") == one); /* Finding empty. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(strstr(one,"ba") == one+1); /* Finding first. */
|
||||
(void) strcpy(one, "");
|
||||
check(strstr(one, "b") == NULL); /* Empty string. */
|
||||
check(strstr(one,"") == one); /* Empty in empty string. */
|
||||
(void) strcpy(one, "bcbca");
|
||||
check(strstr(one,"bca") == one+2); /* False start. */
|
||||
(void) strcpy(one, "bbbcabbca");
|
||||
check(strstr(one,"bbca") == one+1); /* With overlap. */
|
||||
/* strstr - somewhat like strchr. */
|
||||
it = "strstr";
|
||||
check(strstr("z", "abcd") == NULL); /* Not found. */
|
||||
check(strstr("abx", "abcd") == NULL); /* Dead end. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(strstr(one, "c") == one + 2); /* Basic test. */
|
||||
check(strstr(one, "bc") == one + 1); /* Multichar. */
|
||||
check(strstr(one, "d") == one + 3); /* End of string. */
|
||||
check(strstr(one, "cd") == one + 2); /* Tail of string. */
|
||||
check(strstr(one, "abc") == one); /* Beginning. */
|
||||
check(strstr(one, "abcd") == one); /* Exact match. */
|
||||
check(strstr(one, "de") == NULL); /* Past end. */
|
||||
check(strstr(one, "") == one); /* Finding empty. */
|
||||
(void)strcpy(one, "ababa");
|
||||
check(strstr(one, "ba") == one + 1); /* Finding first. */
|
||||
(void)strcpy(one, "");
|
||||
check(strstr(one, "b") == NULL); /* Empty string. */
|
||||
check(strstr(one, "") == one); /* Empty in empty string. */
|
||||
(void)strcpy(one, "bcbca");
|
||||
check(strstr(one, "bca") == one + 2); /* False start. */
|
||||
(void)strcpy(one, "bbbcabbca");
|
||||
check(strstr(one, "bbca") == one + 1); /* With overlap. */
|
||||
|
||||
/* strspn. */
|
||||
it = "strspn";
|
||||
check(strspn("abcba", "abc") == 5); /* Whole string. */
|
||||
check(strspn("abcba", "ab") == 2); /* Partial. */
|
||||
check(strspn("abc", "qx") == 0); /* None. */
|
||||
check(strspn("", "ab") == 0); /* Null string. */
|
||||
check(strspn("abc", "") == 0); /* Null search list. */
|
||||
/* strspn. */
|
||||
it = "strspn";
|
||||
check(strspn("abcba", "abc") == 5); /* Whole string. */
|
||||
check(strspn("abcba", "ab") == 2); /* Partial. */
|
||||
check(strspn("abc", "qx") == 0); /* None. */
|
||||
check(strspn("", "ab") == 0); /* Null string. */
|
||||
check(strspn("abc", "") == 0); /* Null search list. */
|
||||
|
||||
/* strcspn. */
|
||||
it = "strcspn";
|
||||
check(strcspn("abcba", "qx") == 5); /* Whole string. */
|
||||
check(strcspn("abcba", "cx") == 2); /* Partial. */
|
||||
check(strcspn("abc", "abc") == 0); /* None. */
|
||||
check(strcspn("", "ab") == 0); /* Null string. */
|
||||
check(strcspn("abc", "") == 3); /* Null search list. */
|
||||
/* strcspn. */
|
||||
it = "strcspn";
|
||||
check(strcspn("abcba", "qx") == 5); /* Whole string. */
|
||||
check(strcspn("abcba", "cx") == 2); /* Partial. */
|
||||
check(strcspn("abc", "abc") == 0); /* None. */
|
||||
check(strcspn("", "ab") == 0); /* Null string. */
|
||||
check(strcspn("abc", "") == 3); /* Null search list. */
|
||||
|
||||
/* strtok - the hard one. */
|
||||
it = "strtok";
|
||||
(void) strcpy(one, "first, second, third");
|
||||
equal(strtok(one, ", "), "first"); /* Basic test. */
|
||||
equal(one, "first");
|
||||
equal(strtok((char *)NULL, ", "), "second");
|
||||
equal(strtok((char *)NULL, ", "), "third");
|
||||
check(strtok((char *)NULL, ", ") == NULL);
|
||||
(void) strcpy(one, ", first, ");
|
||||
equal(strtok(one, ", "), "first"); /* Extra delims, 1 tok. */
|
||||
check(strtok((char *)NULL, ", ") == NULL);
|
||||
(void) strcpy(one, "1a, 1b; 2a, 2b");
|
||||
equal(strtok(one, ", "), "1a"); /* Changing delim lists. */
|
||||
equal(strtok((char *)NULL, "; "), "1b");
|
||||
equal(strtok((char *)NULL, ", "), "2a");
|
||||
(void) strcpy(two, "x-y");
|
||||
equal(strtok(two, "-"), "x"); /* New string before done. */
|
||||
equal(strtok((char *)NULL, "-"), "y");
|
||||
check(strtok((char *)NULL, "-") == NULL);
|
||||
(void) strcpy(one, "a,b, c,, ,d");
|
||||
equal(strtok(one, ", "), "a"); /* Different separators. */
|
||||
equal(strtok((char *)NULL, ", "), "b");
|
||||
equal(strtok((char *)NULL, " ,"), "c"); /* Permute list too. */
|
||||
equal(strtok((char *)NULL, " ,"), "d");
|
||||
check(strtok((char *)NULL, ", ") == NULL);
|
||||
check(strtok((char *)NULL, ", ") == NULL); /* Persistence. */
|
||||
(void) strcpy(one, ", ");
|
||||
check(strtok(one, ", ") == NULL); /* No tokens. */
|
||||
(void) strcpy(one, "");
|
||||
check(strtok(one, ", ") == NULL); /* Empty string. */
|
||||
(void) strcpy(one, "abc");
|
||||
equal(strtok(one, ", "), "abc"); /* No delimiters. */
|
||||
check(strtok((char *)NULL, ", ") == NULL);
|
||||
(void) strcpy(one, "abc");
|
||||
equal(strtok(one, ""), "abc"); /* Empty delimiter list. */
|
||||
check(strtok((char *)NULL, "") == NULL);
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strcpy(one, "a,b,c");
|
||||
equal(strtok(one, ","), "a"); /* Basics again... */
|
||||
equal(strtok((char *)NULL, ","), "b");
|
||||
equal(strtok((char *)NULL, ","), "c");
|
||||
check(strtok((char *)NULL, ",") == NULL);
|
||||
equal(one+6, "gh"); /* Stomped past end? */
|
||||
equal(one, "a"); /* Stomped old tokens? */
|
||||
equal(one+2, "b");
|
||||
equal(one+4, "c");
|
||||
/* strtok - the hard one. */
|
||||
it = "strtok";
|
||||
(void)strcpy(one, "first, second, third");
|
||||
equal(strtok(one, ", "), "first"); /* Basic test. */
|
||||
equal(one, "first");
|
||||
equal(strtok((char*)NULL, ", "), "second");
|
||||
equal(strtok((char*)NULL, ", "), "third");
|
||||
check(strtok((char*)NULL, ", ") == NULL);
|
||||
(void)strcpy(one, ", first, ");
|
||||
equal(strtok(one, ", "), "first"); /* Extra delims, 1 tok. */
|
||||
check(strtok((char*)NULL, ", ") == NULL);
|
||||
(void)strcpy(one, "1a, 1b; 2a, 2b");
|
||||
equal(strtok(one, ", "), "1a"); /* Changing delim lists. */
|
||||
equal(strtok((char*)NULL, "; "), "1b");
|
||||
equal(strtok((char*)NULL, ", "), "2a");
|
||||
(void)strcpy(two, "x-y");
|
||||
equal(strtok(two, "-"), "x"); /* New string before done. */
|
||||
equal(strtok((char*)NULL, "-"), "y");
|
||||
check(strtok((char*)NULL, "-") == NULL);
|
||||
(void)strcpy(one, "a,b, c,, ,d");
|
||||
equal(strtok(one, ", "), "a"); /* Different separators. */
|
||||
equal(strtok((char*)NULL, ", "), "b");
|
||||
equal(strtok((char*)NULL, " ,"), "c"); /* Permute list too. */
|
||||
equal(strtok((char*)NULL, " ,"), "d");
|
||||
check(strtok((char*)NULL, ", ") == NULL);
|
||||
check(strtok((char*)NULL, ", ") == NULL); /* Persistence. */
|
||||
(void)strcpy(one, ", ");
|
||||
check(strtok(one, ", ") == NULL); /* No tokens. */
|
||||
(void)strcpy(one, "");
|
||||
check(strtok(one, ", ") == NULL); /* Empty string. */
|
||||
(void)strcpy(one, "abc");
|
||||
equal(strtok(one, ", "), "abc"); /* No delimiters. */
|
||||
check(strtok((char*)NULL, ", ") == NULL);
|
||||
(void)strcpy(one, "abc");
|
||||
equal(strtok(one, ""), "abc"); /* Empty delimiter list. */
|
||||
check(strtok((char*)NULL, "") == NULL);
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
(void)strcpy(one, "a,b,c");
|
||||
equal(strtok(one, ","), "a"); /* Basics again... */
|
||||
equal(strtok((char*)NULL, ","), "b");
|
||||
equal(strtok((char*)NULL, ","), "c");
|
||||
check(strtok((char*)NULL, ",") == NULL);
|
||||
equal(one + 6, "gh"); /* Stomped past end? */
|
||||
equal(one, "a"); /* Stomped old tokens? */
|
||||
equal(one + 2, "b");
|
||||
equal(one + 4, "c");
|
||||
|
||||
/* memcmp. */
|
||||
it = "memcmp";
|
||||
check(memcmp("a", "a", 1) == 0); /* Identity. */
|
||||
check(memcmp("abc", "abc", 3) == 0); /* Multicharacter. */
|
||||
check(memcmp("abcd", "abce", 4) < 0); /* Honestly unequal. */
|
||||
check(memcmp("abce", "abcd",4));
|
||||
check(memcmp("alph", "beta", 4) < 0);
|
||||
check(memcmp("abce", "abcd", 3) == 0); /* Count limited. */
|
||||
check(memcmp("abc", "def", 0) == 0); /* Zero count. */
|
||||
/* memcmp. */
|
||||
it = "memcmp";
|
||||
check(memcmp("a", "a", 1) == 0); /* Identity. */
|
||||
check(memcmp("abc", "abc", 3) == 0); /* Multicharacter. */
|
||||
check(memcmp("abcd", "abce", 4) < 0); /* Honestly unequal. */
|
||||
check(memcmp("abce", "abcd", 4));
|
||||
check(memcmp("alph", "beta", 4) < 0);
|
||||
check(memcmp("abce", "abcd", 3) == 0); /* Count limited. */
|
||||
check(memcmp("abc", "def", 0) == 0); /* Zero count. */
|
||||
|
||||
/* memcmp should test strings as unsigned */
|
||||
one[0] = 0xfe;
|
||||
two[0] = 0x03;
|
||||
check(memcmp(one, two,1) > 0);
|
||||
|
||||
|
||||
/* memchr. */
|
||||
it = "memchr";
|
||||
check(memchr("abcd", 'z', 4) == NULL); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(memchr(one, 'c', 4) == one+2); /* Basic test. */
|
||||
check(memchr(one, 'd', 4) == one+3); /* End of string. */
|
||||
check(memchr(one, 'a', 4) == one); /* Beginning. */
|
||||
check(memchr(one, '\0', 5) == one+4); /* Finding NUL. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(memchr(one, 'b', 5) == one+1); /* Finding first. */
|
||||
check(memchr(one, 'b', 0) == NULL); /* Zero count. */
|
||||
check(memchr(one, 'a', 1) == one); /* Singleton case. */
|
||||
(void) strcpy(one, "a\203b");
|
||||
check(memchr(one, 0203, 3) == one+1); /* Unsignedness. */
|
||||
/* memcmp should test strings as unsigned */
|
||||
one[0] = 0xfe;
|
||||
two[0] = 0x03;
|
||||
check(memcmp(one, two, 1) > 0);
|
||||
|
||||
/* memcpy - need not work for overlap. */
|
||||
it = "memcpy";
|
||||
check(memcpy(one, "abc", 4) == one); /* Returned value. */
|
||||
equal(one, "abc"); /* Did the copy go right? */
|
||||
/* memchr. */
|
||||
it = "memchr";
|
||||
check(memchr("abcd", 'z', 4) == NULL); /* Not found. */
|
||||
(void)strcpy(one, "abcd");
|
||||
check(memchr(one, 'c', 4) == one + 2); /* Basic test. */
|
||||
check(memchr(one, 'd', 4) == one + 3); /* End of string. */
|
||||
check(memchr(one, 'a', 4) == one); /* Beginning. */
|
||||
check(memchr(one, '\0', 5) == one + 4); /* Finding NUL. */
|
||||
(void)strcpy(one, "ababa");
|
||||
check(memchr(one, 'b', 5) == one + 1); /* Finding first. */
|
||||
check(memchr(one, 'b', 0) == NULL); /* Zero count. */
|
||||
check(memchr(one, 'a', 1) == one); /* Singleton case. */
|
||||
(void)strcpy(one, "a\203b");
|
||||
check(memchr(one, 0203, 3) == one + 1); /* Unsignedness. */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) memcpy(one+1, "xyz", 2);
|
||||
equal(one, "axydefgh"); /* Basic test. */
|
||||
/* memcpy - need not work for overlap. */
|
||||
it = "memcpy";
|
||||
check(memcpy(one, "abc", 4) == one); /* Returned value. */
|
||||
equal(one, "abc"); /* Did the copy go right? */
|
||||
|
||||
(void) strcpy(one, "abc");
|
||||
(void) memcpy(one, "xyz", 0);
|
||||
equal(one, "abc"); /* Zero-length copy. */
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
(void)memcpy(one + 1, "xyz", 2);
|
||||
equal(one, "axydefgh"); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "hi there");
|
||||
(void) strcpy(two, "foo");
|
||||
(void) memcpy(two, one, 9);
|
||||
equal(two, "hi there"); /* Just paranoia. */
|
||||
equal(one, "hi there"); /* Stomped on source? */
|
||||
(void)strcpy(one, "abc");
|
||||
(void)memcpy(one, "xyz", 0);
|
||||
equal(one, "abc"); /* Zero-length copy. */
|
||||
|
||||
(void)strcpy(one, "hi there");
|
||||
(void)strcpy(two, "foo");
|
||||
(void)memcpy(two, one, 9);
|
||||
equal(two, "hi there"); /* Just paranoia. */
|
||||
equal(one, "hi there"); /* Stomped on source? */
|
||||
#if 0
|
||||
/* memmove - must work on overlap. */
|
||||
it = "memmove";
|
||||
@@ -499,68 +485,69 @@ void libm_test_string()
|
||||
check(memccpy(two, one, 'x', 1) == two+1); /* Singleton. */
|
||||
equal(two, "xbcdlebee");
|
||||
#endif
|
||||
/* memset. */
|
||||
it = "memset";
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
check(memset(one+1, 'x', 3) == one+1); /* Return value. */
|
||||
equal(one, "axxxefgh"); /* Basic test. */
|
||||
/* memset. */
|
||||
it = "memset";
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
check(memset(one + 1, 'x', 3) == one + 1); /* Return value. */
|
||||
equal(one, "axxxefgh"); /* Basic test. */
|
||||
|
||||
(void) memset(one+2, 'y', 0);
|
||||
equal(one, "axxxefgh"); /* Zero-length set. */
|
||||
(void)memset(one + 2, 'y', 0);
|
||||
equal(one, "axxxefgh"); /* Zero-length set. */
|
||||
|
||||
(void) memset(one+5, 0, 1);
|
||||
equal(one, "axxxe"); /* Zero fill. */
|
||||
equal(one+6, "gh"); /* _AND the leftover. */
|
||||
(void)memset(one + 5, 0, 1);
|
||||
equal(one, "axxxe"); /* Zero fill. */
|
||||
equal(one + 6, "gh"); /* _AND the leftover. */
|
||||
|
||||
(void) memset(one+2, 010045, 1);
|
||||
equal(one, "ax\045xe"); /* Unsigned char convert. */
|
||||
(void)memset(one + 2, 010045, 1);
|
||||
equal(one, "ax\045xe"); /* Unsigned char convert. */
|
||||
|
||||
/* bcopy - much like memcpy.
|
||||
Berklix manual is silent about overlap, so don't test it. */
|
||||
it = "bcopy";
|
||||
(void) bcopy("abc", one, 4);
|
||||
equal(one, "abc"); /* Simple copy. */
|
||||
/* bcopy - much like memcpy.
|
||||
Berklix manual is silent about overlap, so don't test it. */
|
||||
it = "bcopy";
|
||||
(void)bcopy("abc", one, 4);
|
||||
equal(one, "abc"); /* Simple copy. */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) bcopy("xyz", one+1, 2);
|
||||
equal(one, "axydefgh"); /* Basic test. */
|
||||
(void)strcpy(one, "abcdefgh");
|
||||
(void)bcopy("xyz", one + 1, 2);
|
||||
equal(one, "axydefgh"); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "abc");
|
||||
(void) bcopy("xyz", one, 0);
|
||||
equal(one, "abc"); /* Zero-length copy. */
|
||||
(void)strcpy(one, "abc");
|
||||
(void)bcopy("xyz", one, 0);
|
||||
equal(one, "abc"); /* Zero-length copy. */
|
||||
|
||||
(void) strcpy(one, "hi there");
|
||||
(void) strcpy(two, "foo");
|
||||
(void) bcopy(one, two, 9);
|
||||
equal(two, "hi there"); /* Just paranoia. */
|
||||
equal(one, "hi there"); /* Stomped on source? */
|
||||
(void)strcpy(one, "hi there");
|
||||
(void)strcpy(two, "foo");
|
||||
(void)bcopy(one, two, 9);
|
||||
equal(two, "hi there"); /* Just paranoia. */
|
||||
equal(one, "hi there"); /* Stomped on source? */
|
||||
|
||||
/* bzero. */
|
||||
it = "bzero";
|
||||
(void) strcpy(one, "abcdef");
|
||||
bzero(one+2, 2);
|
||||
equal(one, "ab"); /* Basic test. */
|
||||
equal(one+3, "");
|
||||
equal(one+4, "ef");
|
||||
/* bzero. */
|
||||
it = "bzero";
|
||||
(void)strcpy(one, "abcdef");
|
||||
bzero(one + 2, 2);
|
||||
equal(one, "ab"); /* Basic test. */
|
||||
equal(one + 3, "");
|
||||
equal(one + 4, "ef");
|
||||
|
||||
(void) strcpy(one, "abcdef");
|
||||
bzero(one+2, 0);
|
||||
equal(one, "abcdef"); /* Zero-length copy. */
|
||||
(void)strcpy(one, "abcdef");
|
||||
bzero(one + 2, 0);
|
||||
equal(one, "abcdef"); /* Zero-length copy. */
|
||||
|
||||
/* bcmp - somewhat like memcmp. */
|
||||
it = "bcmp";
|
||||
check(bcmp("a", "a", 1) == 0); /* Identity. */
|
||||
check(bcmp("abc", "abc", 3) == 0); /* Multicharacter. */
|
||||
check(bcmp("abcd", "abce", 4) != 0); /* Honestly unequal. */
|
||||
check(bcmp("abce", "abcd",4));
|
||||
check(bcmp("alph", "beta", 4) != 0);
|
||||
check(bcmp("abce", "abcd", 3) == 0); /* Count limited. */
|
||||
check(bcmp("abc", "def", 0) == 0); /* Zero count. */
|
||||
/* bcmp - somewhat like memcmp. */
|
||||
it = "bcmp";
|
||||
check(bcmp("a", "a", 1) == 0); /* Identity. */
|
||||
check(bcmp("abc", "abc", 3) == 0); /* Multicharacter. */
|
||||
check(bcmp("abcd", "abce", 4) != 0); /* Honestly unequal. */
|
||||
check(bcmp("abce", "abcd", 4));
|
||||
check(bcmp("alph", "beta", 4) != 0);
|
||||
check(bcmp("abce", "abcd", 3) == 0); /* Count limited. */
|
||||
check(bcmp("abc", "def", 0) == 0); /* Zero count. */
|
||||
|
||||
if (errors) abort();
|
||||
printf("ok\n");
|
||||
if (errors)
|
||||
abort();
|
||||
printf("ok\n");
|
||||
|
||||
#if 0 /* strerror - VERY system-dependent. */
|
||||
#if 0 /* strerror - VERY system-dependent. */
|
||||
{
|
||||
extern CONST unsigned int _sys_nerr;
|
||||
extern CONST char *CONST _sys_errlist[];
|
||||
@@ -572,4 +559,3 @@ void libm_test_string()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#define memcmp memcmp_P
|
||||
#define memcpy memcpy_P
|
||||
#define memmem memmem_P
|
||||
@@ -69,106 +68,105 @@
|
||||
#define TOO_MANY_ERRORS 11
|
||||
static int errors = 0;
|
||||
|
||||
static void
|
||||
print_error (char const* msg, ...)
|
||||
{
|
||||
errors++;
|
||||
if (errors == TOO_MANY_ERRORS)
|
||||
static void print_error(char const* msg, ...)
|
||||
{
|
||||
errors++;
|
||||
if (errors == TOO_MANY_ERRORS)
|
||||
{
|
||||
fprintf (stderr, "Too many errors.\n");
|
||||
fprintf(stderr, "Too many errors.\n");
|
||||
}
|
||||
else if (errors < TOO_MANY_ERRORS)
|
||||
else if (errors < TOO_MANY_ERRORS)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, msg);
|
||||
vfprintf (stderr, msg, ap);
|
||||
va_end (ap);
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
/* Further errors omitted. */
|
||||
/* Further errors omitted. */
|
||||
}
|
||||
}
|
||||
|
||||
extern int rand_seed;
|
||||
void memcpy_main(void)
|
||||
void memcpy_main(void)
|
||||
{
|
||||
/* Allocate buffers to read and write from. */
|
||||
char src[BUFF_SIZE], dest[BUFF_SIZE], backup_src[BUFF_SIZE];
|
||||
/* Allocate buffers to read and write from. */
|
||||
char src[BUFF_SIZE], dest[BUFF_SIZE], backup_src[BUFF_SIZE];
|
||||
|
||||
/* Fill the source buffer with non-null values, reproducible random data. */
|
||||
srand (rand_seed);
|
||||
int i, j;
|
||||
unsigned sa;
|
||||
unsigned da;
|
||||
unsigned n;
|
||||
for (i = 0; i < BUFF_SIZE; i++)
|
||||
/* Fill the source buffer with non-null values, reproducible random data. */
|
||||
srand(rand_seed);
|
||||
int i, j;
|
||||
unsigned sa;
|
||||
unsigned da;
|
||||
unsigned n;
|
||||
for (i = 0; i < BUFF_SIZE; i++)
|
||||
{
|
||||
src[i] = (char)rand () | 1;
|
||||
backup_src[i] = src[i];
|
||||
src[i] = (char)rand() | 1;
|
||||
backup_src[i] = src[i];
|
||||
}
|
||||
|
||||
/* Make calls to memcpy with block sizes ranging between 1 and
|
||||
MAX_BLOCK_SIZE bytes, aligned and misaligned source and destination. */
|
||||
for (sa = 0; sa <= MAX_OFFSET; sa++)
|
||||
for (da = 0; da <= MAX_OFFSET; da++)
|
||||
for (n = 1; n <= MAX_BLOCK_SIZE; n++)
|
||||
{
|
||||
//printf (".");
|
||||
/* Zero dest so we can check it properly after the copying. */
|
||||
for (j = 0; j < BUFF_SIZE; j++)
|
||||
dest[j] = 0;
|
||||
|
||||
void *ret = memcpy (dest + START_COPY + da, src + sa, n);
|
||||
|
||||
/* Check return value. */
|
||||
if (ret != (dest + START_COPY + da))
|
||||
print_error ("\nFailed: wrong return value in memcpy of %u bytes "
|
||||
"with src_align %u and dst_align %u. "
|
||||
"Return value and dest should be the same"
|
||||
"(ret is %p, dest is %p)\n",
|
||||
n, sa, da, ret, dest + START_COPY + da);
|
||||
|
||||
/* Check that content of the destination buffer
|
||||
is the same as the source buffer, and
|
||||
memory outside destination buffer is not modified. */
|
||||
for (j = 0; j < BUFF_SIZE; j++)
|
||||
if ((unsigned)j < START_COPY + da)
|
||||
{
|
||||
if (dest[j] != 0)
|
||||
print_error ("\nFailed: after memcpy of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"byte %u before the start of dest is not 0.\n",
|
||||
n, sa, da, START_COPY - j);
|
||||
}
|
||||
else if ((unsigned)j < START_COPY + da + n)
|
||||
{
|
||||
i = j - START_COPY - da;
|
||||
if (dest[j] != (src + sa)[i])
|
||||
print_error ("\nFailed: after memcpy of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"byte %u in dest and src are not the same.\n",
|
||||
n, sa, da, i);
|
||||
}
|
||||
else if (dest[j] != 0)
|
||||
{
|
||||
print_error ("\nFailed: after memcpy of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"byte %u after the end of dest is not 0.\n",
|
||||
n, sa, da, j - START_COPY - da - n);
|
||||
}
|
||||
/* Make calls to memcpy with block sizes ranging between 1 and
|
||||
MAX_BLOCK_SIZE bytes, aligned and misaligned source and destination. */
|
||||
for (sa = 0; sa <= MAX_OFFSET; sa++)
|
||||
for (da = 0; da <= MAX_OFFSET; da++)
|
||||
for (n = 1; n <= MAX_BLOCK_SIZE; n++)
|
||||
{
|
||||
// printf (".");
|
||||
/* Zero dest so we can check it properly after the copying. */
|
||||
for (j = 0; j < BUFF_SIZE; j++)
|
||||
dest[j] = 0;
|
||||
|
||||
/* Check src is not modified. */
|
||||
for (j = 0; j < BUFF_SIZE; j++)
|
||||
if (src[i] != backup_src[i])
|
||||
print_error ("\nFailed: after memcpy of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"byte %u of src is modified.\n",
|
||||
n, sa, da, j);
|
||||
}
|
||||
void* ret = memcpy(dest + START_COPY + da, src + sa, n);
|
||||
|
||||
if (errors != 0)
|
||||
abort ();
|
||||
/* Check return value. */
|
||||
if (ret != (dest + START_COPY + da))
|
||||
print_error("\nFailed: wrong return value in memcpy of %u bytes "
|
||||
"with src_align %u and dst_align %u. "
|
||||
"Return value and dest should be the same"
|
||||
"(ret is %p, dest is %p)\n",
|
||||
n, sa, da, ret, dest + START_COPY + da);
|
||||
|
||||
printf("ok\n");
|
||||
/* Check that content of the destination buffer
|
||||
is the same as the source buffer, and
|
||||
memory outside destination buffer is not modified. */
|
||||
for (j = 0; j < BUFF_SIZE; j++)
|
||||
if ((unsigned)j < START_COPY + da)
|
||||
{
|
||||
if (dest[j] != 0)
|
||||
print_error("\nFailed: after memcpy of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"byte %u before the start of dest is not 0.\n",
|
||||
n, sa, da, START_COPY - j);
|
||||
}
|
||||
else if ((unsigned)j < START_COPY + da + n)
|
||||
{
|
||||
i = j - START_COPY - da;
|
||||
if (dest[j] != (src + sa)[i])
|
||||
print_error("\nFailed: after memcpy of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"byte %u in dest and src are not the same.\n",
|
||||
n, sa, da, i);
|
||||
}
|
||||
else if (dest[j] != 0)
|
||||
{
|
||||
print_error("\nFailed: after memcpy of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"byte %u after the end of dest is not 0.\n",
|
||||
n, sa, da, j - START_COPY - da - n);
|
||||
}
|
||||
|
||||
/* Check src is not modified. */
|
||||
for (j = 0; j < BUFF_SIZE; j++)
|
||||
if (src[i] != backup_src[i])
|
||||
print_error("\nFailed: after memcpy of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"byte %u of src is modified.\n",
|
||||
n, sa, da, j);
|
||||
}
|
||||
|
||||
if (errors != 0)
|
||||
abort();
|
||||
|
||||
printf("ok\n");
|
||||
}
|
||||
|
||||
@@ -55,140 +55,132 @@
|
||||
#define TOO_MANY_ERRORS 11
|
||||
int errors = 0;
|
||||
|
||||
#define DEBUGP \
|
||||
if (errors == TOO_MANY_ERRORS) \
|
||||
printf ("Further errors omitted\n"); \
|
||||
else if (errors < TOO_MANY_ERRORS) \
|
||||
printf
|
||||
#define DEBUGP \
|
||||
if (errors == TOO_MANY_ERRORS) \
|
||||
printf("Further errors omitted\n"); \
|
||||
else if (errors < TOO_MANY_ERRORS) \
|
||||
printf
|
||||
|
||||
/* A safe target-independent memmove. */
|
||||
|
||||
void
|
||||
mymemmove (unsigned char *dest, unsigned char *src, size_t n)
|
||||
void mymemmove(unsigned char* dest, unsigned char* src, size_t n)
|
||||
{
|
||||
if ((src <= dest && src + n <= dest)
|
||||
|| src >= dest)
|
||||
while (n-- > 0)
|
||||
*dest++ = *src++;
|
||||
else
|
||||
if ((src <= dest && src + n <= dest) || src >= dest)
|
||||
while (n-- > 0)
|
||||
*dest++ = *src++;
|
||||
else
|
||||
{
|
||||
dest += n;
|
||||
src += n;
|
||||
while (n-- > 0)
|
||||
*--dest = *--src;
|
||||
dest += n;
|
||||
src += n;
|
||||
while (n-- > 0)
|
||||
*--dest = *--src;
|
||||
}
|
||||
}
|
||||
|
||||
/* It's either the noinline attribute or forcing the test framework to
|
||||
pass -fno-builtin-memmove. */
|
||||
void
|
||||
xmemmove (unsigned char *dest, unsigned char *src, size_t n)
|
||||
__attribute__ ((__noinline__));
|
||||
void xmemmove(unsigned char* dest, unsigned char* src, size_t n) __attribute__((__noinline__));
|
||||
|
||||
void
|
||||
xmemmove (unsigned char *dest, unsigned char *src, size_t n)
|
||||
void xmemmove(unsigned char* dest, unsigned char* src, size_t n)
|
||||
{
|
||||
void *retp;
|
||||
retp = memmove (dest, src, n);
|
||||
void* retp;
|
||||
retp = memmove(dest, src, n);
|
||||
|
||||
if (retp != dest)
|
||||
if (retp != dest)
|
||||
{
|
||||
errors++;
|
||||
DEBUGP ("memmove of n bytes returned %p instead of dest=%p\n",
|
||||
retp, dest);
|
||||
errors++;
|
||||
DEBUGP("memmove of n bytes returned %p instead of dest=%p\n", retp, dest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Fill the array with something we can associate with a position, but
|
||||
not exactly the same as the position index. */
|
||||
|
||||
void
|
||||
fill (unsigned char dest[MAX*3])
|
||||
void fill(unsigned char dest[MAX * 3])
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < MAX*3; i++)
|
||||
dest[i] = (10 + i) % MAX;
|
||||
size_t i;
|
||||
for (i = 0; i < MAX * 3; i++)
|
||||
dest[i] = (10 + i) % MAX;
|
||||
}
|
||||
|
||||
void memmove_main(void)
|
||||
{
|
||||
size_t i;
|
||||
int errors = 0;
|
||||
size_t i;
|
||||
int errors = 0;
|
||||
|
||||
/* Leave some room before and after the area tested, so we can detect
|
||||
overwrites of up to N bytes, N being the amount tested. If you
|
||||
want to test using valgrind, make these malloced instead. */
|
||||
unsigned char from_test[MAX*3];
|
||||
unsigned char to_test[MAX*3];
|
||||
unsigned char from_known[MAX*3];
|
||||
unsigned char to_known[MAX*3];
|
||||
/* Leave some room before and after the area tested, so we can detect
|
||||
overwrites of up to N bytes, N being the amount tested. If you
|
||||
want to test using valgrind, make these malloced instead. */
|
||||
unsigned char from_test[MAX * 3];
|
||||
unsigned char to_test[MAX * 3];
|
||||
unsigned char from_known[MAX * 3];
|
||||
unsigned char to_known[MAX * 3];
|
||||
|
||||
/* Non-overlap. */
|
||||
for (i = 0; i < MAX; i++)
|
||||
/* Non-overlap. */
|
||||
for (i = 0; i < MAX; i++)
|
||||
{
|
||||
/* Do the memmove first before setting the known array, so we know
|
||||
it didn't change any of the known array. */
|
||||
fill (from_test);
|
||||
fill (to_test);
|
||||
xmemmove (to_test + MAX, 1 + from_test + MAX, i);
|
||||
/* Do the memmove first before setting the known array, so we know
|
||||
it didn't change any of the known array. */
|
||||
fill(from_test);
|
||||
fill(to_test);
|
||||
xmemmove(to_test + MAX, 1 + from_test + MAX, i);
|
||||
|
||||
fill (from_known);
|
||||
fill (to_known);
|
||||
mymemmove (to_known + MAX, 1 + from_known + MAX, i);
|
||||
fill(from_known);
|
||||
fill(to_known);
|
||||
mymemmove(to_known + MAX, 1 + from_known + MAX, i);
|
||||
|
||||
if (memcmp (to_known, to_test, sizeof (to_known)) != 0)
|
||||
{
|
||||
errors++;
|
||||
DEBUGP ("memmove failed non-overlap test for %d bytes\n", i);
|
||||
}
|
||||
if (memcmp(to_known, to_test, sizeof(to_known)) != 0)
|
||||
{
|
||||
errors++;
|
||||
DEBUGP("memmove failed non-overlap test for %d bytes\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Overlap-from-before. */
|
||||
for (i = 0; i < MAX; i++)
|
||||
/* Overlap-from-before. */
|
||||
for (i = 0; i < MAX; i++)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
fill (to_test);
|
||||
xmemmove (to_test + MAX * 2 - i, to_test + MAX * 2 - i - j, i);
|
||||
size_t j;
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
fill(to_test);
|
||||
xmemmove(to_test + MAX * 2 - i, to_test + MAX * 2 - i - j, i);
|
||||
|
||||
fill (to_known);
|
||||
mymemmove (to_known + MAX * 2 - i, to_known + MAX * 2 - i - j, i);
|
||||
fill(to_known);
|
||||
mymemmove(to_known + MAX * 2 - i, to_known + MAX * 2 - i - j, i);
|
||||
|
||||
if (memcmp (to_known, to_test, sizeof (to_known)) != 0)
|
||||
{
|
||||
errors++;
|
||||
DEBUGP ("memmove failed for %d bytes,"
|
||||
" with src %d bytes before dest\n",
|
||||
i, j);
|
||||
}
|
||||
}
|
||||
if (memcmp(to_known, to_test, sizeof(to_known)) != 0)
|
||||
{
|
||||
errors++;
|
||||
DEBUGP("memmove failed for %d bytes,"
|
||||
" with src %d bytes before dest\n",
|
||||
i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Overlap-from-after. */
|
||||
for (i = 0; i < MAX; i++)
|
||||
/* Overlap-from-after. */
|
||||
for (i = 0; i < MAX; i++)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
fill (to_test);
|
||||
xmemmove (to_test + MAX, to_test + MAX + j, i);
|
||||
size_t j;
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
fill(to_test);
|
||||
xmemmove(to_test + MAX, to_test + MAX + j, i);
|
||||
|
||||
fill (to_known);
|
||||
mymemmove (to_known + MAX, to_known + MAX + j, i);
|
||||
fill(to_known);
|
||||
mymemmove(to_known + MAX, to_known + MAX + j, i);
|
||||
|
||||
if (memcmp (to_known, to_test, sizeof (to_known)) != 0)
|
||||
{
|
||||
errors++;
|
||||
DEBUGP ("memmove failed when moving %d bytes,"
|
||||
" with src %d bytes after dest\n",
|
||||
i, j);
|
||||
}
|
||||
}
|
||||
if (memcmp(to_known, to_test, sizeof(to_known)) != 0)
|
||||
{
|
||||
errors++;
|
||||
DEBUGP("memmove failed when moving %d bytes,"
|
||||
" with src %d bytes after dest\n",
|
||||
i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errors != 0)
|
||||
abort ();
|
||||
printf("ok\n");
|
||||
if (errors != 0)
|
||||
abort();
|
||||
printf("ok\n");
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
|
||||
#define BUFF_SIZE 256
|
||||
|
||||
|
||||
/* The macro LONG_TEST controls whether a short or a more comprehensive test
|
||||
of strcmp should be performed. */
|
||||
#ifdef LONG_TEST
|
||||
@@ -106,186 +105,183 @@
|
||||
#error "Buffer overrun: MAX_OFFSET + MAX_BLOCK_SIZE + MAX_DIFF + MAX_LEN + MAX_ZEROS >= BUFF_SIZE."
|
||||
#endif
|
||||
|
||||
|
||||
#define TOO_MANY_ERRORS 11
|
||||
static int errors = 0;
|
||||
|
||||
const char *testname = "strcmp";
|
||||
const char* testname = "strcmp";
|
||||
|
||||
static void
|
||||
print_error (char const* msg, ...)
|
||||
static void print_error(char const* msg, ...)
|
||||
{
|
||||
errors++;
|
||||
if (errors == TOO_MANY_ERRORS)
|
||||
errors++;
|
||||
if (errors == TOO_MANY_ERRORS)
|
||||
{
|
||||
fprintf (stderr, "Too many errors.\n");
|
||||
fprintf(stderr, "Too many errors.\n");
|
||||
}
|
||||
else if (errors < TOO_MANY_ERRORS)
|
||||
else if (errors < TOO_MANY_ERRORS)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, msg);
|
||||
vfprintf (stderr, msg, ap);
|
||||
va_end (ap);
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
/* Further errors omitted. */
|
||||
/* Further errors omitted. */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern int rand_seed;
|
||||
void strcmp_main(void)
|
||||
void strcmp_main(void)
|
||||
{
|
||||
/* Allocate buffers to read and write from. */
|
||||
char src[BUFF_SIZE], dest[BUFF_SIZE];
|
||||
/* Allocate buffers to read and write from. */
|
||||
char src[BUFF_SIZE], dest[BUFF_SIZE];
|
||||
|
||||
/* Fill the source buffer with non-null values, reproducible random data. */
|
||||
srand (rand_seed);
|
||||
int i, j, zeros;
|
||||
unsigned sa;
|
||||
unsigned da;
|
||||
unsigned n, m, len;
|
||||
char *p;
|
||||
int ret;
|
||||
/* Fill the source buffer with non-null values, reproducible random data. */
|
||||
srand(rand_seed);
|
||||
int i, j, zeros;
|
||||
unsigned sa;
|
||||
unsigned da;
|
||||
unsigned n, m, len;
|
||||
char* p;
|
||||
int ret;
|
||||
|
||||
/* Make calls to strcmp with block sizes ranging between 1 and
|
||||
MAX_BLOCK_SIZE bytes, aligned and misaligned source and destination. */
|
||||
for (sa = 0; sa <= MAX_OFFSET; sa++)
|
||||
for (da = 0; da <= MAX_OFFSET; da++)
|
||||
for (n = 1; n <= MAX_BLOCK_SIZE; n++)
|
||||
{
|
||||
for (m = 1; m < n + MAX_DIFF; m++)
|
||||
for (len = 0; len < MAX_LEN; len++)
|
||||
for (zeros = 1; zeros < MAX_ZEROS; zeros++)
|
||||
{
|
||||
if (n - m > MAX_DIFF)
|
||||
continue;
|
||||
/* Make a copy of the source. */
|
||||
for (i = 0; i < BUFF_SIZE; i++)
|
||||
{
|
||||
src[i] = 'A' + (i % 26);
|
||||
dest[i] = src[i];
|
||||
}
|
||||
delay(0);
|
||||
memcpy (dest + da, src + sa, n);
|
||||
/* Make calls to strcmp with block sizes ranging between 1 and
|
||||
MAX_BLOCK_SIZE bytes, aligned and misaligned source and destination. */
|
||||
for (sa = 0; sa <= MAX_OFFSET; sa++)
|
||||
for (da = 0; da <= MAX_OFFSET; da++)
|
||||
for (n = 1; n <= MAX_BLOCK_SIZE; n++)
|
||||
{
|
||||
for (m = 1; m < n + MAX_DIFF; m++)
|
||||
for (len = 0; len < MAX_LEN; len++)
|
||||
for (zeros = 1; zeros < MAX_ZEROS; zeros++)
|
||||
{
|
||||
if (n - m > MAX_DIFF)
|
||||
continue;
|
||||
/* Make a copy of the source. */
|
||||
for (i = 0; i < BUFF_SIZE; i++)
|
||||
{
|
||||
src[i] = 'A' + (i % 26);
|
||||
dest[i] = src[i];
|
||||
}
|
||||
delay(0);
|
||||
memcpy(dest + da, src + sa, n);
|
||||
|
||||
/* Make src 0-terminated. */
|
||||
p = src + sa + n - 1;
|
||||
for (i = 0; i < zeros; i++)
|
||||
{
|
||||
*p++ = '\0';
|
||||
}
|
||||
/* Make src 0-terminated. */
|
||||
p = src + sa + n - 1;
|
||||
for (i = 0; i < zeros; i++)
|
||||
{
|
||||
*p++ = '\0';
|
||||
}
|
||||
|
||||
/* Modify dest. */
|
||||
p = dest + da + m - 1;
|
||||
for (j = 0; j < (int)len; j++)
|
||||
*p++ = 'x';
|
||||
/* Make dest 0-terminated. */
|
||||
*p = '\0';
|
||||
/* Modify dest. */
|
||||
p = dest + da + m - 1;
|
||||
for (j = 0; j < (int)len; j++)
|
||||
*p++ = 'x';
|
||||
/* Make dest 0-terminated. */
|
||||
*p = '\0';
|
||||
|
||||
ret = strcmp (src + sa, dest + da);
|
||||
ret = strcmp(src + sa, dest + da);
|
||||
|
||||
/* Check return value. */
|
||||
if (n == m)
|
||||
{
|
||||
if (len == 0)
|
||||
{
|
||||
if (ret != 0)
|
||||
{
|
||||
print_error ("\nFailed: after %s of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"dest after %d bytes is modified for %d bytes, "
|
||||
"return value is %d, expected 0.\n",
|
||||
testname, n, sa, da, m, len, ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ret >= 0)
|
||||
print_error ("\nFailed: after %s of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"dest after %d bytes is modified for %d bytes, "
|
||||
"return value is %d, expected negative.\n",
|
||||
testname, n, sa, da, m, len, ret);
|
||||
}
|
||||
}
|
||||
else if (m > n)
|
||||
{
|
||||
if (ret >= 0)
|
||||
{
|
||||
print_error ("\nFailed: after %s of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"dest after %d bytes is modified for %d bytes, "
|
||||
"return value is %d, expected negative.\n",
|
||||
testname, n, sa, da, m, len, ret);
|
||||
}
|
||||
}
|
||||
else /* m < n */
|
||||
{
|
||||
if (len == 0)
|
||||
{
|
||||
if (ret <= 0)
|
||||
print_error ("\nFailed: after %s of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"dest after %d bytes is modified for %d bytes, "
|
||||
"return value is %d, expected positive.\n",
|
||||
testname, n, sa, da, m, len, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ret >= 0)
|
||||
print_error ("\nFailed: after %s of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"dest after %d bytes is modified for %d bytes, "
|
||||
"return value is %d, expected negative.\n",
|
||||
testname, n, sa, da, m, len, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check return value. */
|
||||
if (n == m)
|
||||
{
|
||||
if (len == 0)
|
||||
{
|
||||
if (ret != 0)
|
||||
{
|
||||
print_error("\nFailed: after %s of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"dest after %d bytes is modified for %d bytes, "
|
||||
"return value is %d, expected 0.\n",
|
||||
testname, n, sa, da, m, len, ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ret >= 0)
|
||||
print_error("\nFailed: after %s of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"dest after %d bytes is modified for %d bytes, "
|
||||
"return value is %d, expected negative.\n",
|
||||
testname, n, sa, da, m, len, ret);
|
||||
}
|
||||
}
|
||||
else if (m > n)
|
||||
{
|
||||
if (ret >= 0)
|
||||
{
|
||||
print_error("\nFailed: after %s of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"dest after %d bytes is modified for %d bytes, "
|
||||
"return value is %d, expected negative.\n",
|
||||
testname, n, sa, da, m, len, ret);
|
||||
}
|
||||
}
|
||||
else /* m < n */
|
||||
{
|
||||
if (len == 0)
|
||||
{
|
||||
if (ret <= 0)
|
||||
print_error("\nFailed: after %s of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"dest after %d bytes is modified for %d bytes, "
|
||||
"return value is %d, expected positive.\n",
|
||||
testname, n, sa, da, m, len, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ret >= 0)
|
||||
print_error("\nFailed: after %s of %u bytes "
|
||||
"with src_align %u and dst_align %u, "
|
||||
"dest after %d bytes is modified for %d bytes, "
|
||||
"return value is %d, expected negative.\n",
|
||||
testname, n, sa, da, m, len, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check some corner cases. */
|
||||
src[1] = 'A';
|
||||
dest[1] = 'A';
|
||||
src[2] = 'B';
|
||||
dest[2] = 'B';
|
||||
src[3] = 'C';
|
||||
dest[3] = 'C';
|
||||
src[4] = '\0';
|
||||
dest[4] = '\0';
|
||||
/* Check some corner cases. */
|
||||
src[1] = 'A';
|
||||
dest[1] = 'A';
|
||||
src[2] = 'B';
|
||||
dest[2] = 'B';
|
||||
src[3] = 'C';
|
||||
dest[3] = 'C';
|
||||
src[4] = '\0';
|
||||
dest[4] = '\0';
|
||||
|
||||
src[0] = 0xc1;
|
||||
dest[0] = 0x41;
|
||||
ret = strcmp (src, dest);
|
||||
if (ret <= 0)
|
||||
print_error ("\nFailed: expected positive, return %d\n", ret);
|
||||
src[0] = 0xc1;
|
||||
dest[0] = 0x41;
|
||||
ret = strcmp(src, dest);
|
||||
if (ret <= 0)
|
||||
print_error("\nFailed: expected positive, return %d\n", ret);
|
||||
|
||||
src[0] = 0x01;
|
||||
dest[0] = 0x82;
|
||||
ret = strcmp (src, dest);
|
||||
if (ret >= 0)
|
||||
print_error ("\nFailed: expected negative, return %d\n", ret);
|
||||
src[0] = 0x01;
|
||||
dest[0] = 0x82;
|
||||
ret = strcmp(src, dest);
|
||||
if (ret >= 0)
|
||||
print_error("\nFailed: expected negative, return %d\n", ret);
|
||||
|
||||
dest[0] = src[0] = 'D';
|
||||
src[3] = 0xc1;
|
||||
dest[3] = 0x41;
|
||||
ret = strcmp (src, dest);
|
||||
if (ret <= 0)
|
||||
print_error ("\nFailed: expected positive, return %d\n", ret);
|
||||
dest[0] = src[0] = 'D';
|
||||
src[3] = 0xc1;
|
||||
dest[3] = 0x41;
|
||||
ret = strcmp(src, dest);
|
||||
if (ret <= 0)
|
||||
print_error("\nFailed: expected positive, return %d\n", ret);
|
||||
|
||||
src[3] = 0x01;
|
||||
dest[3] = 0x82;
|
||||
ret = strcmp (src, dest);
|
||||
if (ret >= 0)
|
||||
print_error ("\nFailed: expected negative, return %d\n", ret);
|
||||
src[3] = 0x01;
|
||||
dest[3] = 0x82;
|
||||
ret = strcmp(src, dest);
|
||||
if (ret >= 0)
|
||||
print_error("\nFailed: expected negative, return %d\n", ret);
|
||||
|
||||
//printf ("\n");
|
||||
if (errors != 0)
|
||||
// printf ("\n");
|
||||
if (errors != 0)
|
||||
{
|
||||
printf ("ERROR. FAILED.\n");
|
||||
abort ();
|
||||
printf("ERROR. FAILED.\n");
|
||||
abort();
|
||||
}
|
||||
//exit (0);
|
||||
printf("ok\n");
|
||||
// exit (0);
|
||||
printf("ok\n");
|
||||
}
|
||||
|
||||
@@ -26,336 +26,297 @@
|
||||
|
||||
#define MAX_2 (2 * MAX_1 + MAX_1 / 10)
|
||||
|
||||
void eprintf (int line, char *result, char *expected, int size)
|
||||
void eprintf(int line, char* result, char* expected, int size)
|
||||
{
|
||||
if (size != 0)
|
||||
printf ("Failure at line %d, result is <%.*s>, should be <%s> of size %d\n",
|
||||
line, size, result, expected, size);
|
||||
else
|
||||
printf ("Failure at line %d, result is <%s>, should be <%s>\n",
|
||||
line, result, expected);
|
||||
if (size != 0)
|
||||
printf("Failure at line %d, result is <%.*s>, should be <%s> of size %d\n", line, size,
|
||||
result, expected, size);
|
||||
else
|
||||
printf("Failure at line %d, result is <%s>, should be <%s>\n", line, result, expected);
|
||||
}
|
||||
|
||||
void mycopy (char *target, char *source, int size)
|
||||
void mycopy(char* target, char* source, int size)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; ++i)
|
||||
for (i = 0; i < size; ++i)
|
||||
{
|
||||
target[i] = source[i];
|
||||
target[i] = source[i];
|
||||
}
|
||||
}
|
||||
|
||||
void myset (char *target, char ch, int size)
|
||||
void myset(char* target, char ch, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; ++i)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; ++i)
|
||||
{
|
||||
target[i] = ch;
|
||||
target[i] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
void tstring_main(void)
|
||||
{
|
||||
char target[MAX_1] = "A";
|
||||
char first_char;
|
||||
char second_char;
|
||||
char array[] = "abcdefghijklmnopqrstuvwxz";
|
||||
char array2[] = "0123456789!@#$%^&*(";
|
||||
char buffer2[MAX_1];
|
||||
char buffer3[MAX_1];
|
||||
char buffer4[MAX_1];
|
||||
char buffer5[MAX_2];
|
||||
char buffer6[MAX_2];
|
||||
char buffer7[MAX_2];
|
||||
char expected[MAX_1];
|
||||
char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6, *tmp7;
|
||||
int i, j, k, x, z, align_test_iterations;
|
||||
z = 0;
|
||||
|
||||
int test_failed = 0;
|
||||
char target[MAX_1] = "A";
|
||||
char first_char;
|
||||
char second_char;
|
||||
char array[] = "abcdefghijklmnopqrstuvwxz";
|
||||
char array2[] = "0123456789!@#$%^&*(";
|
||||
char buffer2[MAX_1];
|
||||
char buffer3[MAX_1];
|
||||
char buffer4[MAX_1];
|
||||
char buffer5[MAX_2];
|
||||
char buffer6[MAX_2];
|
||||
char buffer7[MAX_2];
|
||||
char expected[MAX_1];
|
||||
char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6, *tmp7;
|
||||
int i, j, k, x, z, align_test_iterations;
|
||||
z = 0;
|
||||
|
||||
tmp1 = target;
|
||||
tmp2 = buffer2;
|
||||
tmp3 = buffer3;
|
||||
tmp4 = buffer4;
|
||||
tmp5 = buffer5;
|
||||
tmp6 = buffer6;
|
||||
tmp7 = buffer7;
|
||||
int test_failed = 0;
|
||||
|
||||
tmp2[0] = 'Z';
|
||||
tmp2[1] = '\0';
|
||||
tmp1 = target;
|
||||
tmp2 = buffer2;
|
||||
tmp3 = buffer3;
|
||||
tmp4 = buffer4;
|
||||
tmp5 = buffer5;
|
||||
tmp6 = buffer6;
|
||||
tmp7 = buffer7;
|
||||
|
||||
if (memset (target, 'X', 0) != target ||
|
||||
memcpy (target, "Y", 0) != target ||
|
||||
memmove (target, "K", 0) != target ||
|
||||
strncpy (tmp2, "4", 0) != tmp2 ||
|
||||
strncat (tmp2, "123", 0) != tmp2 ||
|
||||
strcat (target, "") != target)
|
||||
tmp2[0] = 'Z';
|
||||
tmp2[1] = '\0';
|
||||
|
||||
if (memset(target, 'X', 0) != target || memcpy(target, "Y", 0) != target
|
||||
|| memmove(target, "K", 0) != target || strncpy(tmp2, "4", 0) != tmp2
|
||||
|| strncat(tmp2, "123", 0) != tmp2 || strcat(target, "") != target)
|
||||
{
|
||||
eprintf (__LINE__, target, "A", 0);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "A", 0);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
if (strcmp (target, "A") || strlen(target) != 1 || memchr (target, 'A', 0) != NULL
|
||||
|| memcmp (target, "J", 0) || strncmp (target, "A", 1) || strncmp (target, "J", 0) ||
|
||||
tmp2[0] != 'Z' || tmp2[1] != '\0')
|
||||
if (strcmp(target, "A") || strlen(target) != 1 || memchr(target, 'A', 0) != NULL
|
||||
|| memcmp(target, "J", 0) || strncmp(target, "A", 1) || strncmp(target, "J", 0)
|
||||
|| tmp2[0] != 'Z' || tmp2[1] != '\0')
|
||||
{
|
||||
eprintf (__LINE__, target, "A", 0);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "A", 0);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
tmp2[2] = 'A';
|
||||
if (strcpy (target, "") != target ||
|
||||
strncpy (tmp2, "", 4) != tmp2 ||
|
||||
strcat (target, "") != target)
|
||||
tmp2[2] = 'A';
|
||||
if (strcpy(target, "") != target || strncpy(tmp2, "", 4) != tmp2
|
||||
|| strcat(target, "") != target)
|
||||
{
|
||||
eprintf (__LINE__, target, "", 0);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "", 0);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
if (target[0] != '\0' || strncmp (target, "", 1) ||
|
||||
memcmp (tmp2, "\0\0\0\0", 4))
|
||||
if (target[0] != '\0' || strncmp(target, "", 1) || memcmp(tmp2, "\0\0\0\0", 4))
|
||||
{
|
||||
eprintf (__LINE__, target, "", 0);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "", 0);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
tmp2[2] = 'A';
|
||||
if (strncat (tmp2, "1", 3) != tmp2 ||
|
||||
memcmp (tmp2, "1\0A", 3))
|
||||
tmp2[2] = 'A';
|
||||
if (strncat(tmp2, "1", 3) != tmp2 || memcmp(tmp2, "1\0A", 3))
|
||||
{
|
||||
eprintf (__LINE__, tmp2, "1\0A", 3);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, tmp2, "1\0A", 3);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
if (strcpy (tmp3, target) != tmp3 ||
|
||||
strcat (tmp3, "X") != tmp3 ||
|
||||
strncpy (tmp2, "X", 2) != tmp2 ||
|
||||
memset (target, tmp2[0], 1) != target)
|
||||
if (strcpy(tmp3, target) != tmp3 || strcat(tmp3, "X") != tmp3 || strncpy(tmp2, "X", 2) != tmp2
|
||||
|| memset(target, tmp2[0], 1) != target)
|
||||
{
|
||||
eprintf (__LINE__, target, "X", 0);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "X", 0);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
if (strcmp (target, "X") || strlen (target) != 1 ||
|
||||
memchr (target, 'X', 2) != target ||
|
||||
strchr (target, 'X') != target ||
|
||||
memchr (target, 'Y', 2) != NULL ||
|
||||
strchr (target, 'Y') != NULL ||
|
||||
strcmp (tmp3, target) ||
|
||||
strncmp (tmp3, target, 2) ||
|
||||
memcmp (target, "K", 0) ||
|
||||
strncmp (target, tmp3, 3))
|
||||
if (strcmp(target, "X") || strlen(target) != 1 || memchr(target, 'X', 2) != target
|
||||
|| strchr(target, 'X') != target || memchr(target, 'Y', 2) != NULL
|
||||
|| strchr(target, 'Y') != NULL || strcmp(tmp3, target) || strncmp(tmp3, target, 2)
|
||||
|| memcmp(target, "K", 0) || strncmp(target, tmp3, 3))
|
||||
{
|
||||
eprintf (__LINE__, target, "X", 0);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "X", 0);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
if (strcpy (tmp3, "Y") != tmp3 ||
|
||||
strcat (tmp3, "Y") != tmp3 ||
|
||||
memset (target, 'Y', 2) != target)
|
||||
if (strcpy(tmp3, "Y") != tmp3 || strcat(tmp3, "Y") != tmp3 || memset(target, 'Y', 2) != target)
|
||||
{
|
||||
eprintf (__LINE__, target, "Y", 0);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "Y", 0);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
target[2] = '\0';
|
||||
if (memcmp (target, "YY", 2) || strcmp (target, "YY") ||
|
||||
strlen (target) != 2 || memchr (target, 'Y', 2) != target ||
|
||||
strcmp (tmp3, target) ||
|
||||
strncmp (target, tmp3, 3) ||
|
||||
strncmp (target, tmp3, 4) ||
|
||||
strncmp (target, tmp3, 2) ||
|
||||
strchr (target, 'Y') != target)
|
||||
target[2] = '\0';
|
||||
if (memcmp(target, "YY", 2) || strcmp(target, "YY") || strlen(target) != 2
|
||||
|| memchr(target, 'Y', 2) != target || strcmp(tmp3, target) || strncmp(target, tmp3, 3)
|
||||
|| strncmp(target, tmp3, 4) || strncmp(target, tmp3, 2) || strchr(target, 'Y') != target)
|
||||
{
|
||||
eprintf (__LINE__, target, "YY", 2);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "YY", 2);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
strcpy (target, "WW");
|
||||
if (memcmp (target, "WW", 2) || strcmp (target, "WW") ||
|
||||
strlen (target) != 2 || memchr (target, 'W', 2) != target ||
|
||||
strchr (target, 'W') != target)
|
||||
strcpy(target, "WW");
|
||||
if (memcmp(target, "WW", 2) || strcmp(target, "WW") || strlen(target) != 2
|
||||
|| memchr(target, 'W', 2) != target || strchr(target, 'W') != target)
|
||||
{
|
||||
eprintf (__LINE__, target, "WW", 2);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "WW", 2);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
if (strncpy (target, "XX", 16) != target ||
|
||||
memcmp (target, "XX\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
|
||||
if (strncpy(target, "XX", 16) != target || memcmp(target, "XX\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16))
|
||||
{
|
||||
eprintf (__LINE__, target, "XX\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "XX\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
if (strcpy (tmp3, "ZZ") != tmp3 ||
|
||||
strcat (tmp3, "Z") != tmp3 ||
|
||||
memcpy (tmp4, "Z", 2) != tmp4 ||
|
||||
strcat (tmp4, "ZZ") != tmp4 ||
|
||||
memset (target, 'Z', 3) != target)
|
||||
if (strcpy(tmp3, "ZZ") != tmp3 || strcat(tmp3, "Z") != tmp3 || memcpy(tmp4, "Z", 2) != tmp4
|
||||
|| strcat(tmp4, "ZZ") != tmp4 || memset(target, 'Z', 3) != target)
|
||||
{
|
||||
eprintf (__LINE__, target, "ZZZ", 3);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "ZZZ", 3);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
target[3] = '\0';
|
||||
tmp5[0] = '\0';
|
||||
strncat (tmp5, "123", 2);
|
||||
if (memcmp (target, "ZZZ", 3) || strcmp (target, "ZZZ") ||
|
||||
strcmp (tmp3, target) || strcmp (tmp4, target) ||
|
||||
strncmp (target, "ZZZ", 4) || strncmp (target, "ZZY", 3) <= 0 ||
|
||||
strncmp ("ZZY", target, 4) >= 0 ||
|
||||
memcmp (tmp5, "12", 3) ||
|
||||
strlen (target) != 3)
|
||||
target[3] = '\0';
|
||||
tmp5[0] = '\0';
|
||||
strncat(tmp5, "123", 2);
|
||||
if (memcmp(target, "ZZZ", 3) || strcmp(target, "ZZZ") || strcmp(tmp3, target)
|
||||
|| strcmp(tmp4, target) || strncmp(target, "ZZZ", 4) || strncmp(target, "ZZY", 3) <= 0
|
||||
|| strncmp("ZZY", target, 4) >= 0 || memcmp(tmp5, "12", 3) || strlen(target) != 3)
|
||||
{
|
||||
eprintf (__LINE__, target, "ZZZ", 3);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "ZZZ", 3);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
target[2] = 'K';
|
||||
if (memcmp (target, "ZZZ", 2) || strcmp (target, "ZZZ") >= 0 ||
|
||||
memcmp (target, "ZZZ", 3) >= 0 || strlen (target) != 3 ||
|
||||
memchr (target, 'K', 3) != target + 2 ||
|
||||
strncmp (target, "ZZZ", 2) || strncmp (target, "ZZZ", 4) >= 0 ||
|
||||
strchr (target, 'K') != target + 2)
|
||||
target[2] = 'K';
|
||||
if (memcmp(target, "ZZZ", 2) || strcmp(target, "ZZZ") >= 0 || memcmp(target, "ZZZ", 3) >= 0
|
||||
|| strlen(target) != 3 || memchr(target, 'K', 3) != target + 2 || strncmp(target, "ZZZ", 2)
|
||||
|| strncmp(target, "ZZZ", 4) >= 0 || strchr(target, 'K') != target + 2)
|
||||
{
|
||||
eprintf (__LINE__, target, "ZZK", 3);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "ZZK", 3);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
strcpy (target, "AAA");
|
||||
if (memcmp (target, "AAA", 3) || strcmp (target, "AAA") ||
|
||||
strncmp (target, "AAA", 3) ||
|
||||
strlen (target) != 3)
|
||||
|
||||
strcpy(target, "AAA");
|
||||
if (memcmp(target, "AAA", 3) || strcmp(target, "AAA") || strncmp(target, "AAA", 3)
|
||||
|| strlen(target) != 3)
|
||||
{
|
||||
eprintf (__LINE__, target, "AAA", 3);
|
||||
test_failed = 1;
|
||||
eprintf(__LINE__, target, "AAA", 3);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
j = 5;
|
||||
while (j < MAX_1)
|
||||
|
||||
j = 5;
|
||||
while (j < MAX_1)
|
||||
{
|
||||
for (i = j-1; i <= j+1; ++i)
|
||||
for (i = j - 1; i <= j + 1; ++i)
|
||||
{
|
||||
/* don't bother checking unaligned data in the larger
|
||||
sizes since it will waste time without performing additional testing */
|
||||
if ((size_t)i <= 16 * sizeof(long))
|
||||
{
|
||||
align_test_iterations = 2*sizeof(long);
|
||||
if ((size_t)i <= 2 * sizeof(long) + 1)
|
||||
z = 2;
|
||||
else
|
||||
z = 2 * sizeof(long);
|
||||
}
|
||||
else
|
||||
/* don't bother checking unaligned data in the larger
|
||||
sizes since it will waste time without performing additional testing */
|
||||
if ((size_t)i <= 16 * sizeof(long))
|
||||
{
|
||||
align_test_iterations = 1;
|
||||
align_test_iterations = 2 * sizeof(long);
|
||||
if ((size_t)i <= 2 * sizeof(long) + 1)
|
||||
z = 2;
|
||||
else
|
||||
z = 2 * sizeof(long);
|
||||
}
|
||||
else
|
||||
{
|
||||
align_test_iterations = 1;
|
||||
}
|
||||
|
||||
for (x = 0; x < align_test_iterations; ++x)
|
||||
{
|
||||
tmp1 = target + x;
|
||||
tmp2 = buffer2 + x;
|
||||
tmp3 = buffer3 + x;
|
||||
tmp4 = buffer4 + x;
|
||||
tmp5 = buffer5 + x;
|
||||
tmp6 = buffer6 + x;
|
||||
for (x = 0; x < align_test_iterations; ++x)
|
||||
{
|
||||
tmp1 = target + x;
|
||||
tmp2 = buffer2 + x;
|
||||
tmp3 = buffer3 + x;
|
||||
tmp4 = buffer4 + x;
|
||||
tmp5 = buffer5 + x;
|
||||
tmp6 = buffer6 + x;
|
||||
|
||||
first_char = array[i % (sizeof(array) - 1)];
|
||||
second_char = array2[i % (sizeof(array2) - 1)];
|
||||
memset (tmp1, first_char, i);
|
||||
mycopy (tmp2, tmp1, i);
|
||||
myset (tmp2 + z, second_char, i - z - 1);
|
||||
if (memcpy (tmp1 + z, tmp2 + z, i - z - 1) != tmp1 + z)
|
||||
{
|
||||
printf ("error at line %d\n", __LINE__);
|
||||
test_failed = 1;
|
||||
}
|
||||
first_char = array[i % (sizeof(array) - 1)];
|
||||
second_char = array2[i % (sizeof(array2) - 1)];
|
||||
memset(tmp1, first_char, i);
|
||||
mycopy(tmp2, tmp1, i);
|
||||
myset(tmp2 + z, second_char, i - z - 1);
|
||||
if (memcpy(tmp1 + z, tmp2 + z, i - z - 1) != tmp1 + z)
|
||||
{
|
||||
printf("error at line %d\n", __LINE__);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
tmp1[i] = '\0';
|
||||
tmp2[i] = '\0';
|
||||
if (strcpy (expected, tmp2) != expected)
|
||||
{
|
||||
printf ("error at line %d\n", __LINE__);
|
||||
test_failed = 1;
|
||||
}
|
||||
tmp2[i-z] = first_char + 1;
|
||||
if (memmove (tmp2 + z + 1, tmp2 + z, i - z - 1) != tmp2 + z + 1 ||
|
||||
memset (tmp3, first_char, i) != tmp3)
|
||||
{
|
||||
printf ("error at line %d\n", __LINE__);
|
||||
test_failed = 1;
|
||||
}
|
||||
tmp1[i] = '\0';
|
||||
tmp2[i] = '\0';
|
||||
if (strcpy(expected, tmp2) != expected)
|
||||
{
|
||||
printf("error at line %d\n", __LINE__);
|
||||
test_failed = 1;
|
||||
}
|
||||
tmp2[i - z] = first_char + 1;
|
||||
if (memmove(tmp2 + z + 1, tmp2 + z, i - z - 1) != tmp2 + z + 1
|
||||
|| memset(tmp3, first_char, i) != tmp3)
|
||||
{
|
||||
printf("error at line %d\n", __LINE__);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
myset (tmp4, first_char, i);
|
||||
tmp5[0] = '\0';
|
||||
if (strncpy (tmp5, tmp1, i+1) != tmp5 ||
|
||||
strcat (tmp5, tmp1) != tmp5)
|
||||
{
|
||||
printf ("error at line %d\n", __LINE__);
|
||||
test_failed = 1;
|
||||
}
|
||||
mycopy (tmp6, tmp1, i);
|
||||
mycopy (tmp6 + i, tmp1, i + 1);
|
||||
myset(tmp4, first_char, i);
|
||||
tmp5[0] = '\0';
|
||||
if (strncpy(tmp5, tmp1, i + 1) != tmp5 || strcat(tmp5, tmp1) != tmp5)
|
||||
{
|
||||
printf("error at line %d\n", __LINE__);
|
||||
test_failed = 1;
|
||||
}
|
||||
mycopy(tmp6, tmp1, i);
|
||||
mycopy(tmp6 + i, tmp1, i + 1);
|
||||
|
||||
tmp7[2*i+z] = second_char;
|
||||
strcpy (tmp7, tmp1);
|
||||
|
||||
(void)strchr (tmp1, second_char);
|
||||
|
||||
if (memcmp (tmp1, expected, i) || strcmp (tmp1, expected) ||
|
||||
strncmp (tmp1, expected, i) ||
|
||||
strncmp (tmp1, expected, i+1) ||
|
||||
strcmp (tmp1, tmp2) >= 0 || memcmp (tmp1, tmp2, i) >= 0 ||
|
||||
strncmp (tmp1, tmp2, i+1) >= 0 ||
|
||||
(int)strlen (tmp1) != i || memchr (tmp1, first_char, i) != tmp1 ||
|
||||
strchr (tmp1, first_char) != tmp1 ||
|
||||
memchr (tmp1, second_char, i) != tmp1 + z ||
|
||||
strchr (tmp1, second_char) != tmp1 + z ||
|
||||
strcmp (tmp5, tmp6) ||
|
||||
strncat (tmp7, tmp1, i+2) != tmp7 ||
|
||||
strcmp (tmp7, tmp6) ||
|
||||
tmp7[2*i+z] != second_char)
|
||||
{
|
||||
eprintf (__LINE__, tmp1, expected, 0);
|
||||
printf ("x is %d\n",x);
|
||||
printf ("i is %d\n", i);
|
||||
printf ("tmp1 is <%p>\n", tmp1);
|
||||
printf ("tmp5 is <%p> <%s>\n", tmp5, tmp5);
|
||||
printf ("tmp6 is <%p> <%s>\n", tmp6, tmp6);
|
||||
test_failed = 1;
|
||||
}
|
||||
tmp7[2 * i + z] = second_char;
|
||||
strcpy(tmp7, tmp1);
|
||||
|
||||
for (k = 1; k <= align_test_iterations && k <= i; ++k)
|
||||
{
|
||||
if (memcmp (tmp3, tmp4, i - k + 1) != 0 ||
|
||||
strncmp (tmp3, tmp4, i - k + 1) != 0)
|
||||
{
|
||||
printf ("Failure at line %d, comparing %.*s with %.*s\n",
|
||||
__LINE__, i, tmp3, i, tmp4);
|
||||
test_failed = 1;
|
||||
}
|
||||
tmp4[i-k] = first_char + 1;
|
||||
if (memcmp (tmp3, tmp4, i) >= 0 ||
|
||||
strncmp (tmp3, tmp4, i) >= 0 ||
|
||||
memcmp (tmp4, tmp3, i) <= 0 ||
|
||||
strncmp (tmp4, tmp3, i) <= 0)
|
||||
{
|
||||
printf ("Failure at line %d, comparing %.*s with %.*s\n",
|
||||
__LINE__, i, tmp3, i, tmp4);
|
||||
test_failed = 1;
|
||||
}
|
||||
tmp4[i-k] = first_char;
|
||||
}
|
||||
}
|
||||
(void)strchr(tmp1, second_char);
|
||||
|
||||
if (memcmp(tmp1, expected, i) || strcmp(tmp1, expected)
|
||||
|| strncmp(tmp1, expected, i) || strncmp(tmp1, expected, i + 1)
|
||||
|| strcmp(tmp1, tmp2) >= 0 || memcmp(tmp1, tmp2, i) >= 0
|
||||
|| strncmp(tmp1, tmp2, i + 1) >= 0 || (int)strlen(tmp1) != i
|
||||
|| memchr(tmp1, first_char, i) != tmp1 || strchr(tmp1, first_char) != tmp1
|
||||
|| memchr(tmp1, second_char, i) != tmp1 + z
|
||||
|| strchr(tmp1, second_char) != tmp1 + z || strcmp(tmp5, tmp6)
|
||||
|| strncat(tmp7, tmp1, i + 2) != tmp7 || strcmp(tmp7, tmp6)
|
||||
|| tmp7[2 * i + z] != second_char)
|
||||
{
|
||||
eprintf(__LINE__, tmp1, expected, 0);
|
||||
printf("x is %d\n", x);
|
||||
printf("i is %d\n", i);
|
||||
printf("tmp1 is <%p>\n", tmp1);
|
||||
printf("tmp5 is <%p> <%s>\n", tmp5, tmp5);
|
||||
printf("tmp6 is <%p> <%s>\n", tmp6, tmp6);
|
||||
test_failed = 1;
|
||||
}
|
||||
|
||||
for (k = 1; k <= align_test_iterations && k <= i; ++k)
|
||||
{
|
||||
if (memcmp(tmp3, tmp4, i - k + 1) != 0 || strncmp(tmp3, tmp4, i - k + 1) != 0)
|
||||
{
|
||||
printf("Failure at line %d, comparing %.*s with %.*s\n", __LINE__, i, tmp3,
|
||||
i, tmp4);
|
||||
test_failed = 1;
|
||||
}
|
||||
tmp4[i - k] = first_char + 1;
|
||||
if (memcmp(tmp3, tmp4, i) >= 0 || strncmp(tmp3, tmp4, i) >= 0
|
||||
|| memcmp(tmp4, tmp3, i) <= 0 || strncmp(tmp4, tmp3, i) <= 0)
|
||||
{
|
||||
printf("Failure at line %d, comparing %.*s with %.*s\n", __LINE__, i, tmp3,
|
||||
i, tmp4);
|
||||
test_failed = 1;
|
||||
}
|
||||
tmp4[i - k] = first_char;
|
||||
}
|
||||
}
|
||||
}
|
||||
j = ((2 * j) >> 2) << 2;
|
||||
j = ((2 * j) >> 2) << 2;
|
||||
}
|
||||
|
||||
if (test_failed)
|
||||
abort();
|
||||
if (test_failed)
|
||||
abort();
|
||||
|
||||
printf("ok\n");
|
||||
printf("ok\n");
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
Arduino.cpp - Mocks for common Arduino APIs
|
||||
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.
|
||||
*/
|
||||
@@ -41,7 +41,6 @@ extern "C" unsigned long micros()
|
||||
return ((time.tv_sec - gtod0.tv_sec) * 1000000) + time.tv_usec - gtod0.tv_usec;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void yield()
|
||||
{
|
||||
run_scheduled_recurrent_functions();
|
||||
@@ -58,38 +57,35 @@ extern "C" bool can_yield()
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" void optimistic_yield (uint32_t interval_us)
|
||||
extern "C" void optimistic_yield(uint32_t interval_us)
|
||||
{
|
||||
(void)interval_us;
|
||||
}
|
||||
|
||||
extern "C" void esp_suspend()
|
||||
{
|
||||
}
|
||||
extern "C" void esp_suspend() { }
|
||||
|
||||
extern "C" void esp_schedule()
|
||||
{
|
||||
}
|
||||
extern "C" void esp_schedule() { }
|
||||
|
||||
extern "C" void esp_yield()
|
||||
{
|
||||
}
|
||||
extern "C" void esp_yield() { }
|
||||
|
||||
extern "C" void esp_delay (unsigned long ms)
|
||||
extern "C" void esp_delay(unsigned long ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
bool esp_try_delay(const uint32_t start_ms, const uint32_t timeout_ms, const uint32_t intvl_ms) {
|
||||
bool esp_try_delay(const uint32_t start_ms, const uint32_t timeout_ms, const uint32_t intvl_ms)
|
||||
{
|
||||
uint32_t expired = millis() - start_ms;
|
||||
if (expired >= timeout_ms) {
|
||||
if (expired >= timeout_ms)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
esp_delay(std::min((timeout_ms - expired), intvl_ms));
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" void __panic_func(const char* file, int line, const char* func) {
|
||||
extern "C" void __panic_func(const char* file, int line, const char* func)
|
||||
{
|
||||
(void)file;
|
||||
(void)line;
|
||||
(void)func;
|
||||
@@ -107,15 +103,14 @@ extern "C" void delayMicroseconds(unsigned int us)
|
||||
}
|
||||
|
||||
#include "cont.h"
|
||||
cont_t* g_pcont = NULL;
|
||||
extern "C" void cont_suspend(cont_t*)
|
||||
{
|
||||
}
|
||||
cont_t* g_pcont = NULL;
|
||||
extern "C" void cont_suspend(cont_t*) { }
|
||||
|
||||
extern "C" int __mockverbose (const char* fmt, ...)
|
||||
extern "C" int __mockverbose(const char* fmt, ...)
|
||||
{
|
||||
(void)fmt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mockverbose (const char* fmt, ...) __attribute__ ((weak, alias("__mockverbose"), format (printf, 1, 2)));
|
||||
int mockverbose(const char* fmt, ...)
|
||||
__attribute__((weak, alias("__mockverbose"), format(printf, 1, 2)));
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
Arduino.cpp - Mocks for common Arduino APIs
|
||||
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.
|
||||
*/
|
||||
@@ -17,4 +17,3 @@
|
||||
#include <catch.hpp>
|
||||
#include <sys/time.h>
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <user_interface.h> // wifi_get_ip_info()
|
||||
#include <user_interface.h> // wifi_get_ip_info()
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
@@ -41,280 +41,280 @@
|
||||
|
||||
#define MOCK_PORT_SHIFTER 9000
|
||||
|
||||
bool user_exit = false;
|
||||
bool run_once = false;
|
||||
const char* host_interface = nullptr;
|
||||
size_t spiffs_kb = 1024;
|
||||
size_t littlefs_kb = 1024;
|
||||
bool ignore_sigint = false;
|
||||
bool restore_tty = false;
|
||||
bool mockdebug = false;
|
||||
int mock_port_shifter = MOCK_PORT_SHIFTER;
|
||||
const char* fspath = nullptr;
|
||||
bool user_exit = false;
|
||||
bool run_once = false;
|
||||
const char* host_interface = nullptr;
|
||||
size_t spiffs_kb = 1024;
|
||||
size_t littlefs_kb = 1024;
|
||||
bool ignore_sigint = false;
|
||||
bool restore_tty = false;
|
||||
bool mockdebug = false;
|
||||
int mock_port_shifter = MOCK_PORT_SHIFTER;
|
||||
const char* fspath = nullptr;
|
||||
|
||||
#define STDIN STDIN_FILENO
|
||||
|
||||
static struct termios initial_settings;
|
||||
|
||||
int mockverbose (const char* fmt, ...)
|
||||
int mockverbose(const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
if (mockdebug)
|
||||
return fprintf(stderr, MOCK) + vfprintf(stderr, fmt, ap);
|
||||
return 0;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
if (mockdebug)
|
||||
return fprintf(stderr, MOCK) + vfprintf(stderr, fmt, ap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mock_start_uart(void)
|
||||
{
|
||||
struct termios settings;
|
||||
struct termios settings;
|
||||
|
||||
if (!isatty(STDIN))
|
||||
{
|
||||
perror("setting tty in raw mode: isatty(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
if (tcgetattr(STDIN, &initial_settings) < 0)
|
||||
{
|
||||
perror("setting tty in raw mode: tcgetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
settings = initial_settings;
|
||||
settings.c_lflag &= ~(ignore_sigint ? ISIG : 0);
|
||||
settings.c_lflag &= ~(ECHO | ICANON);
|
||||
settings.c_iflag &= ~(ICRNL | INLCR | ISTRIP | IXON);
|
||||
settings.c_oflag |= (ONLCR);
|
||||
settings.c_cc[VMIN] = 0;
|
||||
settings.c_cc[VTIME] = 0;
|
||||
if (tcsetattr(STDIN, TCSANOW, &settings) < 0)
|
||||
{
|
||||
perror("setting tty in raw mode: tcsetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
restore_tty = true;
|
||||
return 0;
|
||||
if (!isatty(STDIN))
|
||||
{
|
||||
perror("setting tty in raw mode: isatty(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
if (tcgetattr(STDIN, &initial_settings) < 0)
|
||||
{
|
||||
perror("setting tty in raw mode: tcgetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
settings = initial_settings;
|
||||
settings.c_lflag &= ~(ignore_sigint ? ISIG : 0);
|
||||
settings.c_lflag &= ~(ECHO | ICANON);
|
||||
settings.c_iflag &= ~(ICRNL | INLCR | ISTRIP | IXON);
|
||||
settings.c_oflag |= (ONLCR);
|
||||
settings.c_cc[VMIN] = 0;
|
||||
settings.c_cc[VTIME] = 0;
|
||||
if (tcsetattr(STDIN, TCSANOW, &settings) < 0)
|
||||
{
|
||||
perror("setting tty in raw mode: tcsetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
restore_tty = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mock_stop_uart(void)
|
||||
{
|
||||
if (!restore_tty) return 0;
|
||||
if (!isatty(STDIN)) {
|
||||
perror("restoring tty: isatty(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
if (tcsetattr(STDIN, TCSANOW, &initial_settings) < 0)
|
||||
{
|
||||
perror("restoring tty: tcsetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
printf("\e[?25h"); // show cursor
|
||||
return (0);
|
||||
if (!restore_tty)
|
||||
return 0;
|
||||
if (!isatty(STDIN))
|
||||
{
|
||||
perror("restoring tty: isatty(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
if (tcsetattr(STDIN, TCSANOW, &initial_settings) < 0)
|
||||
{
|
||||
perror("restoring tty: tcsetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
printf("\e[?25h"); // show cursor
|
||||
return (0);
|
||||
}
|
||||
|
||||
static uint8_t mock_read_uart(void)
|
||||
{
|
||||
uint8_t ch = 0;
|
||||
return (read(STDIN, &ch, 1) == 1) ? ch : 0;
|
||||
uint8_t ch = 0;
|
||||
return (read(STDIN, &ch, 1) == 1) ? ch : 0;
|
||||
}
|
||||
|
||||
void help (const char* argv0, int exitcode)
|
||||
void help(const char* argv0, int exitcode)
|
||||
{
|
||||
printf(
|
||||
"%s - compiled with esp8266/arduino emulator\n"
|
||||
"options:\n"
|
||||
"\t-h\n"
|
||||
"\tnetwork:\n"
|
||||
"\t-i <interface> - use this interface for IP address\n"
|
||||
"\t-l - bind tcp/udp servers to interface only (not 0.0.0.0)\n"
|
||||
"\t-s - port shifter (default: %d, when root: 0)\n"
|
||||
"\tterminal:\n"
|
||||
"\t-b - blocking tty/mocked-uart (default: not blocking tty)\n"
|
||||
"\t-T - show timestamp on output\n"
|
||||
"\tFS:\n"
|
||||
"\t-P - path for fs-persistent files (default: %s-)\n"
|
||||
"\t-S - spiffs size in KBytes (default: %zd)\n"
|
||||
"\t-L - littlefs size in KBytes (default: %zd)\n"
|
||||
"\t (spiffs, littlefs: negative value will force mismatched size)\n"
|
||||
"\tgeneral:\n"
|
||||
"\t-c - ignore CTRL-C (send it via Serial)\n"
|
||||
"\t-f - no throttle (possibly 100%%CPU)\n"
|
||||
"\t-1 - run loop once then exit (for host testing)\n"
|
||||
"\t-v - verbose\n"
|
||||
, argv0, MOCK_PORT_SHIFTER, argv0, spiffs_kb, littlefs_kb);
|
||||
exit(exitcode);
|
||||
printf("%s - compiled with esp8266/arduino emulator\n"
|
||||
"options:\n"
|
||||
"\t-h\n"
|
||||
"\tnetwork:\n"
|
||||
"\t-i <interface> - use this interface for IP address\n"
|
||||
"\t-l - bind tcp/udp servers to interface only (not 0.0.0.0)\n"
|
||||
"\t-s - port shifter (default: %d, when root: 0)\n"
|
||||
"\tterminal:\n"
|
||||
"\t-b - blocking tty/mocked-uart (default: not blocking tty)\n"
|
||||
"\t-T - show timestamp on output\n"
|
||||
"\tFS:\n"
|
||||
"\t-P - path for fs-persistent files (default: %s-)\n"
|
||||
"\t-S - spiffs size in KBytes (default: %zd)\n"
|
||||
"\t-L - littlefs size in KBytes (default: %zd)\n"
|
||||
"\t (spiffs, littlefs: negative value will force mismatched size)\n"
|
||||
"\tgeneral:\n"
|
||||
"\t-c - ignore CTRL-C (send it via Serial)\n"
|
||||
"\t-f - no throttle (possibly 100%%CPU)\n"
|
||||
"\t-1 - run loop once then exit (for host testing)\n"
|
||||
"\t-v - verbose\n",
|
||||
argv0, MOCK_PORT_SHIFTER, argv0, spiffs_kb, littlefs_kb);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
static struct option options[] =
|
||||
{
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "fast", no_argument, NULL, 'f' },
|
||||
{ "local", no_argument, NULL, 'l' },
|
||||
{ "sigint", no_argument, NULL, 'c' },
|
||||
{ "blockinguart", no_argument, NULL, 'b' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "timestamp", no_argument, NULL, 'T' },
|
||||
{ "interface", required_argument, NULL, 'i' },
|
||||
{ "fspath", required_argument, NULL, 'P' },
|
||||
{ "spiffskb", required_argument, NULL, 'S' },
|
||||
{ "littlefskb", required_argument, NULL, 'L' },
|
||||
{ "portshifter", required_argument, NULL, 's' },
|
||||
{ "once", no_argument, NULL, '1' },
|
||||
static struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "fast", no_argument, NULL, 'f' },
|
||||
{ "local", no_argument, NULL, 'l' },
|
||||
{ "sigint", no_argument, NULL, 'c' },
|
||||
{ "blockinguart", no_argument, NULL, 'b' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "timestamp", no_argument, NULL, 'T' },
|
||||
{ "interface", required_argument, NULL, 'i' },
|
||||
{ "fspath", required_argument, NULL, 'P' },
|
||||
{ "spiffskb", required_argument, NULL, 'S' },
|
||||
{ "littlefskb", required_argument, NULL, 'L' },
|
||||
{ "portshifter", required_argument, NULL, 's' },
|
||||
{ "once", no_argument, NULL, '1' },
|
||||
};
|
||||
|
||||
void cleanup ()
|
||||
void cleanup()
|
||||
{
|
||||
mock_stop_spiffs();
|
||||
mock_stop_littlefs();
|
||||
mock_stop_uart();
|
||||
mock_stop_spiffs();
|
||||
mock_stop_littlefs();
|
||||
mock_stop_uart();
|
||||
}
|
||||
|
||||
void make_fs_filename (String& name, const char* fspath, const char* argv0)
|
||||
void make_fs_filename(String& name, const char* fspath, const char* argv0)
|
||||
{
|
||||
name.clear();
|
||||
if (fspath)
|
||||
{
|
||||
int lastSlash = -1;
|
||||
for (int i = 0; argv0[i]; i++)
|
||||
if (argv0[i] == '/')
|
||||
lastSlash = i;
|
||||
name = fspath;
|
||||
name += '/';
|
||||
name += &argv0[lastSlash + 1];
|
||||
}
|
||||
else
|
||||
name = argv0;
|
||||
name.clear();
|
||||
if (fspath)
|
||||
{
|
||||
int lastSlash = -1;
|
||||
for (int i = 0; argv0[i]; i++)
|
||||
if (argv0[i] == '/')
|
||||
lastSlash = i;
|
||||
name = fspath;
|
||||
name += '/';
|
||||
name += &argv0[lastSlash + 1];
|
||||
}
|
||||
else
|
||||
name = argv0;
|
||||
}
|
||||
|
||||
void control_c (int sig)
|
||||
void control_c(int sig)
|
||||
{
|
||||
(void)sig;
|
||||
(void)sig;
|
||||
|
||||
if (user_exit)
|
||||
{
|
||||
fprintf(stderr, MOCK "stuck, killing\n");
|
||||
cleanup();
|
||||
exit(1);
|
||||
}
|
||||
user_exit = true;
|
||||
if (user_exit)
|
||||
{
|
||||
fprintf(stderr, MOCK "stuck, killing\n");
|
||||
cleanup();
|
||||
exit(1);
|
||||
}
|
||||
user_exit = true;
|
||||
}
|
||||
|
||||
int main (int argc, char* const argv [])
|
||||
int main(int argc, char* const argv[])
|
||||
{
|
||||
bool fast = false;
|
||||
blocking_uart = false; // global
|
||||
bool fast = false;
|
||||
blocking_uart = false; // global
|
||||
|
||||
signal(SIGINT, control_c);
|
||||
signal(SIGTERM, control_c);
|
||||
if (geteuid() == 0)
|
||||
mock_port_shifter = 0;
|
||||
else
|
||||
mock_port_shifter = MOCK_PORT_SHIFTER;
|
||||
signal(SIGINT, control_c);
|
||||
signal(SIGTERM, control_c);
|
||||
if (geteuid() == 0)
|
||||
mock_port_shifter = 0;
|
||||
else
|
||||
mock_port_shifter = MOCK_PORT_SHIFTER;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int n = getopt_long(argc, argv, "hlcfbvTi:S:s:L:P:1", options, NULL);
|
||||
if (n < 0)
|
||||
break;
|
||||
switch (n)
|
||||
{
|
||||
case 'h':
|
||||
help(argv[0], EXIT_SUCCESS);
|
||||
break;
|
||||
case 'i':
|
||||
host_interface = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
global_ipv4_netfmt = NO_GLOBAL_BINDING;
|
||||
break;
|
||||
case 's':
|
||||
mock_port_shifter = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
ignore_sigint = true;
|
||||
break;
|
||||
case 'f':
|
||||
fast = true;
|
||||
break;
|
||||
case 'S':
|
||||
spiffs_kb = atoi(optarg);
|
||||
break;
|
||||
case 'L':
|
||||
littlefs_kb = atoi(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
fspath = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
blocking_uart = true;
|
||||
break;
|
||||
case 'v':
|
||||
mockdebug = true;
|
||||
break;
|
||||
case 'T':
|
||||
serial_timestamp = true;
|
||||
break;
|
||||
case '1':
|
||||
run_once = true;
|
||||
break;
|
||||
default:
|
||||
help(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
int n = getopt_long(argc, argv, "hlcfbvTi:S:s:L:P:1", options, NULL);
|
||||
if (n < 0)
|
||||
break;
|
||||
switch (n)
|
||||
{
|
||||
case 'h':
|
||||
help(argv[0], EXIT_SUCCESS);
|
||||
break;
|
||||
case 'i':
|
||||
host_interface = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
global_ipv4_netfmt = NO_GLOBAL_BINDING;
|
||||
break;
|
||||
case 's':
|
||||
mock_port_shifter = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
ignore_sigint = true;
|
||||
break;
|
||||
case 'f':
|
||||
fast = true;
|
||||
break;
|
||||
case 'S':
|
||||
spiffs_kb = atoi(optarg);
|
||||
break;
|
||||
case 'L':
|
||||
littlefs_kb = atoi(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
fspath = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
blocking_uart = true;
|
||||
break;
|
||||
case 'v':
|
||||
mockdebug = true;
|
||||
break;
|
||||
case 'T':
|
||||
serial_timestamp = true;
|
||||
break;
|
||||
case '1':
|
||||
run_once = true;
|
||||
break;
|
||||
default:
|
||||
help(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
mockverbose("server port shifter: %d\n", mock_port_shifter);
|
||||
mockverbose("server port shifter: %d\n", mock_port_shifter);
|
||||
|
||||
if (spiffs_kb)
|
||||
{
|
||||
String name;
|
||||
make_fs_filename(name, fspath, argv[0]);
|
||||
name += "-spiffs";
|
||||
name += String(spiffs_kb > 0? spiffs_kb: -spiffs_kb, DEC);
|
||||
name += "KB";
|
||||
mock_start_spiffs(name, spiffs_kb);
|
||||
}
|
||||
if (spiffs_kb)
|
||||
{
|
||||
String name;
|
||||
make_fs_filename(name, fspath, argv[0]);
|
||||
name += "-spiffs";
|
||||
name += String(spiffs_kb > 0 ? spiffs_kb : -spiffs_kb, DEC);
|
||||
name += "KB";
|
||||
mock_start_spiffs(name, spiffs_kb);
|
||||
}
|
||||
|
||||
if (littlefs_kb)
|
||||
{
|
||||
String name;
|
||||
make_fs_filename(name, fspath, argv[0]);
|
||||
name += "-littlefs";
|
||||
name += String(littlefs_kb > 0? littlefs_kb: -littlefs_kb, DEC);
|
||||
name += "KB";
|
||||
mock_start_littlefs(name, littlefs_kb);
|
||||
}
|
||||
if (littlefs_kb)
|
||||
{
|
||||
String name;
|
||||
make_fs_filename(name, fspath, argv[0]);
|
||||
name += "-littlefs";
|
||||
name += String(littlefs_kb > 0 ? littlefs_kb : -littlefs_kb, DEC);
|
||||
name += "KB";
|
||||
mock_start_littlefs(name, littlefs_kb);
|
||||
}
|
||||
|
||||
// setup global global_ipv4_netfmt
|
||||
wifi_get_ip_info(0, nullptr);
|
||||
// setup global global_ipv4_netfmt
|
||||
wifi_get_ip_info(0, nullptr);
|
||||
|
||||
if (!blocking_uart)
|
||||
{
|
||||
// set stdin to non blocking mode
|
||||
mock_start_uart();
|
||||
}
|
||||
if (!blocking_uart)
|
||||
{
|
||||
// set stdin to non blocking mode
|
||||
mock_start_uart();
|
||||
}
|
||||
|
||||
// install exit handler in case Esp.restart() is called
|
||||
atexit(cleanup);
|
||||
// install exit handler in case Esp.restart() is called
|
||||
atexit(cleanup);
|
||||
|
||||
// first call to millis(): now is millis() and micros() beginning
|
||||
millis();
|
||||
// first call to millis(): now is millis() and micros() beginning
|
||||
millis();
|
||||
|
||||
setup();
|
||||
while (!user_exit)
|
||||
{
|
||||
uint8_t data = mock_read_uart();
|
||||
setup();
|
||||
while (!user_exit)
|
||||
{
|
||||
uint8_t data = mock_read_uart();
|
||||
|
||||
if (data)
|
||||
uart_new_data(UART0, data);
|
||||
if (!fast)
|
||||
usleep(1000); // not 100% cpu, ~1000 loops per second
|
||||
loop();
|
||||
loop_end();
|
||||
check_incoming_udp();
|
||||
if (data)
|
||||
uart_new_data(UART0, data);
|
||||
if (!fast)
|
||||
usleep(1000); // not 100% cpu, ~1000 loops per second
|
||||
loop();
|
||||
loop_end();
|
||||
check_incoming_udp();
|
||||
|
||||
if (run_once)
|
||||
user_exit = true;
|
||||
}
|
||||
cleanup();
|
||||
if (run_once)
|
||||
user_exit = true;
|
||||
}
|
||||
cleanup();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
|
||||
LittleFSMock* littlefs_mock = nullptr;
|
||||
|
||||
void mock_start_littlefs (const String& fname, size_t size_kb, size_t block_kb, size_t page_b)
|
||||
void mock_start_littlefs(const String& fname, size_t size_kb, size_t block_kb, size_t page_b)
|
||||
{
|
||||
littlefs_mock = new LittleFSMock(size_kb * 1024, block_kb * 1024, page_b, fname);
|
||||
littlefs_mock = new LittleFSMock(size_kb * 1024, block_kb * 1024, page_b, fname);
|
||||
}
|
||||
|
||||
void mock_stop_littlefs ()
|
||||
void mock_stop_littlefs()
|
||||
{
|
||||
if (littlefs_mock)
|
||||
delete littlefs_mock;
|
||||
littlefs_mock = nullptr;
|
||||
if (littlefs_mock)
|
||||
delete littlefs_mock;
|
||||
littlefs_mock = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
|
||||
SpiffsMock* spiffs_mock = nullptr;
|
||||
|
||||
void mock_start_spiffs (const String& fname, size_t size_kb, size_t block_kb, size_t page_b)
|
||||
void mock_start_spiffs(const String& fname, size_t size_kb, size_t block_kb, size_t page_b)
|
||||
{
|
||||
spiffs_mock = new SpiffsMock(size_kb * 1024, block_kb * 1024, page_b, fname);
|
||||
spiffs_mock = new SpiffsMock(size_kb * 1024, block_kb * 1024, page_b, fname);
|
||||
}
|
||||
|
||||
void mock_stop_spiffs ()
|
||||
void mock_stop_spiffs()
|
||||
{
|
||||
if (spiffs_mock)
|
||||
delete spiffs_mock;
|
||||
spiffs_mock = nullptr;
|
||||
if (spiffs_mock)
|
||||
delete spiffs_mock;
|
||||
spiffs_mock = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,28 +33,28 @@
|
||||
#include <poll.h>
|
||||
#include <map>
|
||||
|
||||
std::map<int,UdpContext*> udps;
|
||||
std::map<int, UdpContext*> udps;
|
||||
|
||||
void register_udp (int sock, UdpContext* udp)
|
||||
void register_udp(int sock, UdpContext* udp)
|
||||
{
|
||||
if (udp)
|
||||
udps[sock] = udp;
|
||||
else
|
||||
udps.erase(sock);
|
||||
if (udp)
|
||||
udps[sock] = udp;
|
||||
else
|
||||
udps.erase(sock);
|
||||
}
|
||||
|
||||
void check_incoming_udp ()
|
||||
void check_incoming_udp()
|
||||
{
|
||||
// check incoming udp
|
||||
for (auto& udp: udps)
|
||||
{
|
||||
pollfd p;
|
||||
p.fd = udp.first;
|
||||
p.events = POLLIN;
|
||||
if (poll(&p, 1, 0) && p.revents == POLLIN)
|
||||
{
|
||||
mockverbose("UDP poll(%d) -> cb\r", p.fd);
|
||||
udp.second->mock_cb();
|
||||
}
|
||||
}
|
||||
// check incoming udp
|
||||
for (auto& udp : udps)
|
||||
{
|
||||
pollfd p;
|
||||
p.fd = udp.first;
|
||||
p.events = POLLIN;
|
||||
if (poll(&p, 1, 0) && p.revents == POLLIN)
|
||||
{
|
||||
mockverbose("UDP poll(%d) -> cb\r", p.fd);
|
||||
udp.second->mock_cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,168 +39,173 @@
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
int mockSockSetup (int sock)
|
||||
int mockSockSetup(int sock)
|
||||
{
|
||||
if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
|
||||
{
|
||||
perror("socket fcntl(O_NONBLOCK)");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
|
||||
{
|
||||
perror("socket fcntl(O_NONBLOCK)");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
int i = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof i) == -1)
|
||||
{
|
||||
perror("sockopt(SO_NOSIGPIPE)(macOS)");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
int i = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof i) == -1)
|
||||
{
|
||||
perror("sockopt(SO_NOSIGPIPE)(macOS)");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return sock;
|
||||
return sock;
|
||||
}
|
||||
|
||||
int mockConnect (uint32_t ipv4, int& sock, int port)
|
||||
int mockConnect(uint32_t ipv4, int& sock, int port)
|
||||
{
|
||||
struct sockaddr_in server;
|
||||
if ((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
perror(MOCK "ClientContext:connect: ::socket()");
|
||||
return 0;
|
||||
}
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
memcpy(&server.sin_addr, &ipv4, 4);
|
||||
if (::connect(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
|
||||
{
|
||||
perror(MOCK "ClientContext::connect: ::connect()");
|
||||
return 0;
|
||||
}
|
||||
struct sockaddr_in server;
|
||||
if ((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
perror(MOCK "ClientContext:connect: ::socket()");
|
||||
return 0;
|
||||
}
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
memcpy(&server.sin_addr, &ipv4, 4);
|
||||
if (::connect(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
|
||||
{
|
||||
perror(MOCK "ClientContext::connect: ::connect()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mockSockSetup(sock) == -1? 0: 1;
|
||||
return mockSockSetup(sock) == -1 ? 0 : 1;
|
||||
}
|
||||
|
||||
ssize_t mockFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize)
|
||||
ssize_t mockFillInBuf(int sock, char* ccinbuf, size_t& ccinbufsize)
|
||||
{
|
||||
size_t maxread = CCBUFSIZE - ccinbufsize;
|
||||
ssize_t ret = ::read(sock, ccinbuf + ccinbufsize, maxread);
|
||||
size_t maxread = CCBUFSIZE - ccinbufsize;
|
||||
ssize_t ret = ::read(sock, ccinbuf + ccinbufsize, maxread);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
// connection closed
|
||||
// nothing is read
|
||||
return 0;
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
// connection closed
|
||||
// nothing is read
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
fprintf(stderr, MOCK "ClientContext::(read/peek fd=%i): filling buffer for %zd bytes: %s\n", sock, maxread, strerror(errno));
|
||||
if (ret == -1)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
fprintf(stderr,
|
||||
MOCK "ClientContext::(read/peek fd=%i): filling buffer for %zd bytes: %s\n",
|
||||
sock, maxread, strerror(errno));
|
||||
// error
|
||||
return -1;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
ccinbufsize += ret;
|
||||
return ret;
|
||||
ccinbufsize += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t mockPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf, size_t& ccinbufsize)
|
||||
ssize_t mockPeekBytes(int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize)
|
||||
{
|
||||
// usersize==0: peekAvailable()
|
||||
|
||||
if (usersize > CCBUFSIZE)
|
||||
mockverbose("CCBUFSIZE(%d) should be increased by %zd bytes (-> %zd)\n", CCBUFSIZE, usersize - CCBUFSIZE, usersize);
|
||||
if (usersize > CCBUFSIZE)
|
||||
mockverbose("CCBUFSIZE(%d) should be increased by %zd bytes (-> %zd)\n", CCBUFSIZE,
|
||||
usersize - CCBUFSIZE, usersize);
|
||||
|
||||
struct pollfd p;
|
||||
size_t retsize = 0;
|
||||
do
|
||||
{
|
||||
if (usersize && usersize <= ccinbufsize)
|
||||
{
|
||||
// data already buffered
|
||||
retsize = usersize;
|
||||
break;
|
||||
}
|
||||
|
||||
// check incoming data data
|
||||
if (mockFillInBuf(sock, ccinbuf, ccinbufsize) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
struct pollfd p;
|
||||
size_t retsize = 0;
|
||||
do
|
||||
{
|
||||
if (usersize && usersize <= ccinbufsize)
|
||||
{
|
||||
// data already buffered
|
||||
retsize = usersize;
|
||||
break;
|
||||
}
|
||||
|
||||
// check incoming data data
|
||||
if (mockFillInBuf(sock, ccinbuf, ccinbufsize) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (usersize == 0 && ccinbufsize)
|
||||
// peekAvailable
|
||||
return ccinbufsize;
|
||||
|
||||
if (usersize <= ccinbufsize)
|
||||
{
|
||||
// data just received
|
||||
retsize = usersize;
|
||||
break;
|
||||
}
|
||||
|
||||
// wait for more data until timeout
|
||||
p.fd = sock;
|
||||
p.events = POLLIN;
|
||||
} while (poll(&p, 1, timeout_ms) == 1);
|
||||
|
||||
if (usersize <= ccinbufsize)
|
||||
{
|
||||
// data just received
|
||||
retsize = usersize;
|
||||
break;
|
||||
}
|
||||
|
||||
// wait for more data until timeout
|
||||
p.fd = sock;
|
||||
p.events = POLLIN;
|
||||
} while (poll(&p, 1, timeout_ms) == 1);
|
||||
|
||||
if (dst)
|
||||
{
|
||||
memcpy(dst, ccinbuf, retsize);
|
||||
}
|
||||
|
||||
return retsize;
|
||||
return retsize;
|
||||
}
|
||||
|
||||
ssize_t mockRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize)
|
||||
ssize_t mockRead(int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize)
|
||||
{
|
||||
ssize_t copied = mockPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize);
|
||||
if (copied < 0)
|
||||
return -1;
|
||||
// swallow (XXX use a circular buffer)
|
||||
memmove(ccinbuf, ccinbuf + copied, ccinbufsize - copied);
|
||||
ccinbufsize -= copied;
|
||||
return copied;
|
||||
ssize_t copied = mockPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize);
|
||||
if (copied < 0)
|
||||
return -1;
|
||||
// swallow (XXX use a circular buffer)
|
||||
memmove(ccinbuf, ccinbuf + copied, ccinbufsize - copied);
|
||||
ccinbufsize -= copied;
|
||||
return copied;
|
||||
}
|
||||
|
||||
ssize_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms)
|
||||
{
|
||||
size_t sent = 0;
|
||||
while (sent < size)
|
||||
{
|
||||
|
||||
struct pollfd p;
|
||||
p.fd = sock;
|
||||
p.events = POLLOUT;
|
||||
int ret = poll(&p, 1, timeout_ms);
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "ClientContext::write(%d): %s\n", sock, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
ssize_t mockWrite(int sock, const uint8_t* data, size_t size, int timeout_ms)
|
||||
{
|
||||
size_t sent = 0;
|
||||
while (sent < size)
|
||||
{
|
||||
struct pollfd p;
|
||||
p.fd = sock;
|
||||
p.events = POLLOUT;
|
||||
int ret = poll(&p, 1, timeout_ms);
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "ClientContext::write(%d): %s\n", sock, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
#ifndef MSG_NOSIGNAL
|
||||
ret = ::write(sock, data + sent, size - sent);
|
||||
ret = ::write(sock, data + sent, size - sent);
|
||||
#else
|
||||
ret = ::send(sock, data + sent, size - sent, MSG_NOSIGNAL);
|
||||
ret = ::send(sock, data + sent, size - sent, MSG_NOSIGNAL);
|
||||
#endif
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "ClientContext::write/send(%d): %s\n", sock, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
sent += ret;
|
||||
if (sent < size)
|
||||
fprintf(stderr, MOCK "ClientContext::write: sent %d bytes (%zd / %zd)\n", ret, sent, size);
|
||||
}
|
||||
}
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "ClientContext::write/send(%d): %s\n", sock, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
sent += ret;
|
||||
if (sent < size)
|
||||
fprintf(stderr, MOCK "ClientContext::write: sent %d bytes (%zd / %zd)\n", ret, sent,
|
||||
size);
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_ESP_WIFI
|
||||
mockverbose(MOCK "ClientContext::write: total sent %zd bytes\n", sent);
|
||||
#endif
|
||||
return sent;
|
||||
return sent;
|
||||
}
|
||||
|
||||
@@ -35,23 +35,24 @@
|
||||
#include <WiFiClient.h>
|
||||
#include <include/ClientContext.h>
|
||||
|
||||
#include <netdb.h> // gethostbyname
|
||||
#include <netdb.h> // gethostbyname
|
||||
|
||||
err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg)
|
||||
err_t dns_gethostbyname(const char* hostname, ip_addr_t* addr, dns_found_callback found,
|
||||
void* callback_arg)
|
||||
{
|
||||
(void)callback_arg;
|
||||
(void)found;
|
||||
struct hostent* hbn = gethostbyname(hostname);
|
||||
if (!hbn)
|
||||
return ERR_TIMEOUT;
|
||||
addr->addr = *(uint32_t*)hbn->h_addr_list[0];
|
||||
return ERR_OK;
|
||||
(void)callback_arg;
|
||||
(void)found;
|
||||
struct hostent* hbn = gethostbyname(hostname);
|
||||
if (!hbn)
|
||||
return ERR_TIMEOUT;
|
||||
addr->addr = *(uint32_t*)hbn->h_addr_list[0];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static struct tcp_pcb mock_tcp_pcb;
|
||||
tcp_pcb* tcp_new (void)
|
||||
tcp_pcb* tcp_new(void)
|
||||
{
|
||||
// this is useless
|
||||
// ClientContext is setting the source port and we don't care here
|
||||
return &mock_tcp_pcb;
|
||||
// this is useless
|
||||
// ClientContext is setting the source port and we don't care here
|
||||
return &mock_tcp_pcb;
|
||||
}
|
||||
|
||||
@@ -32,46 +32,53 @@
|
||||
#ifndef EEPROM_MOCK
|
||||
#define EEPROM_MOCK
|
||||
|
||||
class EEPROMClass {
|
||||
class EEPROMClass
|
||||
{
|
||||
public:
|
||||
EEPROMClass(uint32_t sector);
|
||||
EEPROMClass(void);
|
||||
~EEPROMClass();
|
||||
EEPROMClass(uint32_t sector);
|
||||
EEPROMClass(void);
|
||||
~EEPROMClass();
|
||||
|
||||
void begin(size_t size);
|
||||
uint8_t read(int address);
|
||||
void write(int address, uint8_t val);
|
||||
bool commit();
|
||||
void end();
|
||||
void begin(size_t size);
|
||||
uint8_t read(int address);
|
||||
void write(int address, uint8_t val);
|
||||
bool commit();
|
||||
void end();
|
||||
|
||||
template<typename T>
|
||||
T& get(int const address, T& t)
|
||||
{
|
||||
if (address < 0 || address + sizeof(T) > _size)
|
||||
return t;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
((uint8_t*)&t)[i] = read(i);
|
||||
return t;
|
||||
}
|
||||
template<typename T>
|
||||
T& get(int const address, T& t)
|
||||
{
|
||||
if (address < 0 || address + sizeof(T) > _size)
|
||||
return t;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
((uint8_t*)&t)[i] = read(i);
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T& put(int const address, const T& t)
|
||||
{
|
||||
if (address < 0 || address + sizeof(T) > _size)
|
||||
return t;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
write(i, ((uint8_t*)&t)[i]);
|
||||
return t;
|
||||
}
|
||||
template<typename T>
|
||||
const T& put(int const address, const T& t)
|
||||
{
|
||||
if (address < 0 || address + sizeof(T) > _size)
|
||||
return t;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
write(i, ((uint8_t*)&t)[i]);
|
||||
return t;
|
||||
}
|
||||
|
||||
size_t length() { return _size; }
|
||||
size_t length()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
//uint8_t& operator[](int const address) { return read(address); }
|
||||
uint8_t operator[] (int address) { return read(address); }
|
||||
// uint8_t& operator[](int const address) { return read(address); }
|
||||
uint8_t operator[](int address)
|
||||
{
|
||||
return read(address);
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t _size = 0;
|
||||
int _fd = -1;
|
||||
size_t _size = 0;
|
||||
int _fd = -1;
|
||||
};
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_EEPROM)
|
||||
|
||||
@@ -42,60 +42,82 @@
|
||||
static uint8_t _mode[GPIONUM];
|
||||
static uint8_t _gpio[GPIONUM];
|
||||
|
||||
void pinMode (uint8_t pin, uint8_t mode)
|
||||
void pinMode(uint8_t pin, uint8_t mode)
|
||||
{
|
||||
#define xxx(mode) case mode: m=STRHELPER(mode); break
|
||||
const char* m;
|
||||
switch (mode)
|
||||
{
|
||||
case INPUT: m="INPUT"; break;
|
||||
case OUTPUT: m="OUTPUT"; break;
|
||||
case INPUT_PULLUP: m="INPUT_PULLUP"; break;
|
||||
case OUTPUT_OPEN_DRAIN: m="OUTPUT_OPEN_DRAIN"; break;
|
||||
case INPUT_PULLDOWN_16: m="INPUT_PULLDOWN_16"; break;
|
||||
case WAKEUP_PULLUP: m="WAKEUP_PULLUP"; break;
|
||||
case WAKEUP_PULLDOWN: m="WAKEUP_PULLDOWN"; break;
|
||||
default: m="(special)";
|
||||
}
|
||||
VERBOSE("gpio%d: mode='%s'\n", pin, m);
|
||||
#define xxx(mode) \
|
||||
case mode: \
|
||||
m = STRHELPER(mode); \
|
||||
break
|
||||
const char* m;
|
||||
switch (mode)
|
||||
{
|
||||
case INPUT:
|
||||
m = "INPUT";
|
||||
break;
|
||||
case OUTPUT:
|
||||
m = "OUTPUT";
|
||||
break;
|
||||
case INPUT_PULLUP:
|
||||
m = "INPUT_PULLUP";
|
||||
break;
|
||||
case OUTPUT_OPEN_DRAIN:
|
||||
m = "OUTPUT_OPEN_DRAIN";
|
||||
break;
|
||||
case INPUT_PULLDOWN_16:
|
||||
m = "INPUT_PULLDOWN_16";
|
||||
break;
|
||||
case WAKEUP_PULLUP:
|
||||
m = "WAKEUP_PULLUP";
|
||||
break;
|
||||
case WAKEUP_PULLDOWN:
|
||||
m = "WAKEUP_PULLDOWN";
|
||||
break;
|
||||
default:
|
||||
m = "(special)";
|
||||
}
|
||||
VERBOSE("gpio%d: mode='%s'\n", pin, m);
|
||||
|
||||
if (pin < GPIONUM)
|
||||
{
|
||||
_mode[pin] = mode;
|
||||
_mode[pin] = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void digitalWrite(uint8_t pin, uint8_t val)
|
||||
{
|
||||
VERBOSE("digitalWrite(pin=%d val=%d)\n", pin, val);
|
||||
if (pin < GPIONUM) {
|
||||
VERBOSE("digitalWrite(pin=%d val=%d)\n", pin, val);
|
||||
if (pin < GPIONUM)
|
||||
{
|
||||
_gpio[pin] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void analogWrite(uint8_t pin, int val)
|
||||
{
|
||||
VERBOSE("analogWrite(pin=%d, val=%d\n", pin, val);
|
||||
VERBOSE("analogWrite(pin=%d, val=%d\n", pin, val);
|
||||
}
|
||||
|
||||
int analogRead(uint8_t pin)
|
||||
{
|
||||
(void)pin;
|
||||
return 512;
|
||||
(void)pin;
|
||||
return 512;
|
||||
}
|
||||
|
||||
void analogWriteRange(uint32_t range)
|
||||
{
|
||||
VERBOSE("analogWriteRange(range=%d)\n", range);
|
||||
VERBOSE("analogWriteRange(range=%d)\n", range);
|
||||
}
|
||||
|
||||
int digitalRead(uint8_t pin)
|
||||
{
|
||||
VERBOSE("digitalRead(%d)\n", pin);
|
||||
VERBOSE("digitalRead(%d)\n", pin);
|
||||
|
||||
if (pin < GPIONUM) {
|
||||
return _gpio[pin] != 0;
|
||||
} else {
|
||||
return 0;
|
||||
if (pin < GPIONUM)
|
||||
{
|
||||
return _gpio[pin] != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,52 +42,52 @@
|
||||
|
||||
#define EEPROM_FILE_NAME "eeprom"
|
||||
|
||||
EEPROMClass::EEPROMClass ()
|
||||
{
|
||||
}
|
||||
EEPROMClass::EEPROMClass() { }
|
||||
|
||||
EEPROMClass::~EEPROMClass ()
|
||||
EEPROMClass::~EEPROMClass()
|
||||
{
|
||||
if (_fd >= 0)
|
||||
close(_fd);
|
||||
if (_fd >= 0)
|
||||
close(_fd);
|
||||
}
|
||||
|
||||
void EEPROMClass::begin(size_t size)
|
||||
{
|
||||
_size = size;
|
||||
if ( (_fd = open(EEPROM_FILE_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1
|
||||
|| ftruncate(_fd, size) == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "EEPROM: cannot open/create '%s' for r/w: %s\n\r", EEPROM_FILE_NAME, strerror(errno));
|
||||
_fd = -1;
|
||||
}
|
||||
_size = size;
|
||||
if ((_fd = open(EEPROM_FILE_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))
|
||||
== -1
|
||||
|| ftruncate(_fd, size) == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "EEPROM: cannot open/create '%s' for r/w: %s\n\r", EEPROM_FILE_NAME,
|
||||
strerror(errno));
|
||||
_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void EEPROMClass::end()
|
||||
{
|
||||
if (_fd != -1)
|
||||
close(_fd);
|
||||
if (_fd != -1)
|
||||
close(_fd);
|
||||
}
|
||||
|
||||
bool EEPROMClass::commit()
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t EEPROMClass::read (int x)
|
||||
uint8_t EEPROMClass::read(int x)
|
||||
{
|
||||
char c = 0;
|
||||
if (pread(_fd, &c, 1, x) != 1)
|
||||
fprintf(stderr, MOCK "eeprom: %s\n\r", strerror(errno));
|
||||
return c;
|
||||
char c = 0;
|
||||
if (pread(_fd, &c, 1, x) != 1)
|
||||
fprintf(stderr, MOCK "eeprom: %s\n\r", strerror(errno));
|
||||
return c;
|
||||
}
|
||||
|
||||
void EEPROMClass::write (int x, uint8_t c)
|
||||
void EEPROMClass::write(int x, uint8_t c)
|
||||
{
|
||||
if (x > (int)_size)
|
||||
fprintf(stderr, MOCK "### eeprom beyond\r\n");
|
||||
else if (pwrite(_fd, &c, 1, x) != 1)
|
||||
fprintf(stderr, MOCK "eeprom: %s\n\r", strerror(errno));
|
||||
if (x > (int)_size)
|
||||
fprintf(stderr, MOCK "### eeprom beyond\r\n");
|
||||
else if (pwrite(_fd, &c, 1, x) != 1)
|
||||
fprintf(stderr, MOCK "eeprom: %s\n\r", strerror(errno));
|
||||
}
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_EEPROM)
|
||||
|
||||
@@ -36,204 +36,223 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned long long operator"" _kHz(unsigned long long x) {
|
||||
unsigned long long operator"" _kHz(unsigned long long x)
|
||||
{
|
||||
return x * 1000;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _MHz(unsigned long long x) {
|
||||
unsigned long long operator"" _MHz(unsigned long long x)
|
||||
{
|
||||
return x * 1000 * 1000;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _GHz(unsigned long long x) {
|
||||
unsigned long long operator"" _GHz(unsigned long long x)
|
||||
{
|
||||
return x * 1000 * 1000 * 1000;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _kBit(unsigned long long x) {
|
||||
unsigned long long operator"" _kBit(unsigned long long x)
|
||||
{
|
||||
return x * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _MBit(unsigned long long x) {
|
||||
unsigned long long operator"" _MBit(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _GBit(unsigned long long x) {
|
||||
unsigned long long operator"" _GBit(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024 * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _kB(unsigned long long x) {
|
||||
unsigned long long operator"" _kB(unsigned long long x)
|
||||
{
|
||||
return x * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _MB(unsigned long long x) {
|
||||
unsigned long long operator"" _MB(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _GB(unsigned long long x) {
|
||||
unsigned long long operator"" _GB(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024 * 1024;
|
||||
}
|
||||
|
||||
uint32_t _SPIFFS_start;
|
||||
|
||||
void eboot_command_write (struct eboot_command* cmd)
|
||||
void eboot_command_write(struct eboot_command* cmd)
|
||||
{
|
||||
(void)cmd;
|
||||
(void)cmd;
|
||||
}
|
||||
|
||||
EspClass ESP;
|
||||
|
||||
void EspClass::restart ()
|
||||
void EspClass::restart()
|
||||
{
|
||||
mockverbose("Esp.restart(): exiting\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
mockverbose("Esp.restart(): exiting\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
uint32_t EspClass::getChipId()
|
||||
{
|
||||
return 0xee1337;
|
||||
return 0xee1337;
|
||||
}
|
||||
|
||||
bool EspClass::checkFlashConfig(bool needsEquals)
|
||||
{
|
||||
(void) needsEquals;
|
||||
return true;
|
||||
(void)needsEquals;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getSketchSize()
|
||||
{
|
||||
return 400000;
|
||||
return 400000;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFreeHeap()
|
||||
{
|
||||
return 30000;
|
||||
return 30000;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getMaxFreeBlockSize()
|
||||
{
|
||||
return 20000;
|
||||
return 20000;
|
||||
}
|
||||
|
||||
String EspClass::getResetReason()
|
||||
{
|
||||
return "Power on";
|
||||
return "Power on";
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFreeSketchSpace()
|
||||
{
|
||||
return 4 * 1024 * 1024;
|
||||
return 4 * 1024 * 1024;
|
||||
}
|
||||
|
||||
const char *EspClass::getSdkVersion()
|
||||
const char* EspClass::getSdkVersion()
|
||||
{
|
||||
return "2.5.0";
|
||||
return "2.5.0";
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFlashChipSpeed()
|
||||
{
|
||||
return 40;
|
||||
return 40;
|
||||
}
|
||||
|
||||
void EspClass::getHeapStats(uint32_t* hfree, uint16_t* hmax, uint8_t* hfrag) {
|
||||
uint32_t hf = 10 * 1024;
|
||||
float hm = 1 * 1024;
|
||||
void EspClass::getHeapStats(uint32_t* hfree, uint16_t* hmax, uint8_t* hfrag)
|
||||
{
|
||||
uint32_t hf = 10 * 1024;
|
||||
float hm = 1 * 1024;
|
||||
|
||||
if (hfree) *hfree = hf;
|
||||
if (hmax) *hmax = hm;
|
||||
if (hfrag) *hfrag = 100 - (sqrt(hm) * 100) / hf;
|
||||
if (hfree)
|
||||
*hfree = hf;
|
||||
if (hmax)
|
||||
*hmax = hm;
|
||||
if (hfrag)
|
||||
*hfrag = 100 - (sqrt(hm) * 100) / hf;
|
||||
}
|
||||
|
||||
void EspClass::getHeapStats(uint32_t* hfree, uint32_t* hmax, uint8_t* hfrag) {
|
||||
uint32_t hf = 10 * 1024;
|
||||
float hm = 1 * 1024;
|
||||
void EspClass::getHeapStats(uint32_t* hfree, uint32_t* hmax, uint8_t* hfrag)
|
||||
{
|
||||
uint32_t hf = 10 * 1024;
|
||||
float hm = 1 * 1024;
|
||||
|
||||
if (hfree) *hfree = hf;
|
||||
if (hmax) *hmax = hm;
|
||||
if (hfrag) *hfrag = 100 - (sqrt(hm) * 100) / hf;
|
||||
if (hfree)
|
||||
*hfree = hf;
|
||||
if (hmax)
|
||||
*hmax = hm;
|
||||
if (hfrag)
|
||||
*hfrag = 100 - (sqrt(hm) * 100) / hf;
|
||||
}
|
||||
|
||||
bool EspClass::flashEraseSector(uint32_t sector)
|
||||
{
|
||||
(void) sector;
|
||||
return true;
|
||||
(void)sector;
|
||||
return true;
|
||||
}
|
||||
|
||||
FlashMode_t EspClass::getFlashChipMode()
|
||||
{
|
||||
return FM_DOUT;
|
||||
return FM_DOUT;
|
||||
}
|
||||
|
||||
FlashMode_t EspClass::magicFlashChipMode(uint8_t byte)
|
||||
{
|
||||
(void) byte;
|
||||
return FM_DOUT;
|
||||
(void)byte;
|
||||
return FM_DOUT;
|
||||
}
|
||||
|
||||
bool EspClass::flashWrite(uint32_t offset, const uint32_t *data, size_t size)
|
||||
bool EspClass::flashWrite(uint32_t offset, const uint32_t* data, size_t size)
|
||||
{
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EspClass::flashWrite(uint32_t offset, const uint8_t *data, size_t size)
|
||||
bool EspClass::flashWrite(uint32_t offset, const uint8_t* data, size_t size)
|
||||
{
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size)
|
||||
bool EspClass::flashRead(uint32_t offset, uint32_t* data, size_t size)
|
||||
{
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EspClass::flashRead(uint32_t offset, uint8_t *data, size_t size)
|
||||
bool EspClass::flashRead(uint32_t offset, uint8_t* data, size_t size)
|
||||
{
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t EspClass::magicFlashChipSize(uint8_t byte) {
|
||||
switch(byte & 0x0F) {
|
||||
case 0x0: // 4 Mbit (512KB)
|
||||
return (512_kB);
|
||||
case 0x1: // 2 MBit (256KB)
|
||||
return (256_kB);
|
||||
case 0x2: // 8 MBit (1MB)
|
||||
return (1_MB);
|
||||
case 0x3: // 16 MBit (2MB)
|
||||
return (2_MB);
|
||||
case 0x4: // 32 MBit (4MB)
|
||||
return (4_MB);
|
||||
case 0x8: // 64 MBit (8MB)
|
||||
return (8_MB);
|
||||
case 0x9: // 128 MBit (16MB)
|
||||
return (16_MB);
|
||||
default: // fail?
|
||||
return 0;
|
||||
uint32_t EspClass::magicFlashChipSize(uint8_t byte)
|
||||
{
|
||||
switch (byte & 0x0F)
|
||||
{
|
||||
case 0x0: // 4 Mbit (512KB)
|
||||
return (512_kB);
|
||||
case 0x1: // 2 MBit (256KB)
|
||||
return (256_kB);
|
||||
case 0x2: // 8 MBit (1MB)
|
||||
return (1_MB);
|
||||
case 0x3: // 16 MBit (2MB)
|
||||
return (2_MB);
|
||||
case 0x4: // 32 MBit (4MB)
|
||||
return (4_MB);
|
||||
case 0x8: // 64 MBit (8MB)
|
||||
return (8_MB);
|
||||
case 0x9: // 128 MBit (16MB)
|
||||
return (16_MB);
|
||||
default: // fail?
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFlashChipRealSize(void)
|
||||
{
|
||||
return magicFlashChipSize(4);
|
||||
return magicFlashChipSize(4);
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFlashChipSize(void)
|
||||
{
|
||||
return magicFlashChipSize(4);
|
||||
return magicFlashChipSize(4);
|
||||
}
|
||||
|
||||
String EspClass::getFullVersion ()
|
||||
String EspClass::getFullVersion()
|
||||
{
|
||||
return "emulation-on-host";
|
||||
return "emulation-on-host";
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFreeContStack()
|
||||
@@ -241,9 +260,7 @@ uint32_t EspClass::getFreeContStack()
|
||||
return 4000;
|
||||
}
|
||||
|
||||
void EspClass::resetFreeContStack()
|
||||
{
|
||||
}
|
||||
void EspClass::resetFreeContStack() { }
|
||||
|
||||
uint32_t EspClass::getCycleCount()
|
||||
{
|
||||
@@ -257,23 +274,15 @@ uint32_t esp_get_cycle_count()
|
||||
return (((uint64_t)t.tv_sec) * 1000000 + t.tv_usec) * (F_CPU / 1000000);
|
||||
}
|
||||
|
||||
void EspClass::setDramHeap()
|
||||
{
|
||||
}
|
||||
void EspClass::setDramHeap() { }
|
||||
|
||||
void EspClass::setIramHeap()
|
||||
{
|
||||
}
|
||||
void EspClass::setIramHeap() { }
|
||||
|
||||
void EspClass::setExternalHeap()
|
||||
{
|
||||
}
|
||||
void EspClass::setExternalHeap() { }
|
||||
|
||||
void EspClass::resetHeap()
|
||||
{
|
||||
}
|
||||
void EspClass::resetHeap() { }
|
||||
|
||||
void EspClass::reset ()
|
||||
void EspClass::reset()
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -35,29 +35,23 @@
|
||||
SPIClass SPI;
|
||||
#endif
|
||||
|
||||
SPIClass::SPIClass ()
|
||||
{
|
||||
}
|
||||
SPIClass::SPIClass() { }
|
||||
|
||||
uint8_t SPIClass::transfer(uint8_t data)
|
||||
{
|
||||
return data;
|
||||
return data;
|
||||
}
|
||||
|
||||
void SPIClass::begin()
|
||||
{
|
||||
}
|
||||
void SPIClass::begin() { }
|
||||
|
||||
void SPIClass::end()
|
||||
{
|
||||
}
|
||||
void SPIClass::end() { }
|
||||
|
||||
void SPIClass::setFrequency(uint32_t freq)
|
||||
{
|
||||
(void)freq;
|
||||
(void)freq;
|
||||
}
|
||||
|
||||
void SPIClass::setHwCs(bool use)
|
||||
{
|
||||
(void)use;
|
||||
(void)use;
|
||||
}
|
||||
|
||||
@@ -34,56 +34,91 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
uint32_t lwip_htonl(uint32_t hostlong)
|
||||
{
|
||||
return htonl(hostlong);
|
||||
}
|
||||
uint16_t lwip_htons(uint16_t hostshort)
|
||||
{
|
||||
return htons(hostshort);
|
||||
}
|
||||
uint32_t lwip_ntohl(uint32_t netlong)
|
||||
{
|
||||
return ntohl(netlong);
|
||||
}
|
||||
uint16_t lwip_ntohs(uint16_t netshort)
|
||||
{
|
||||
return ntohs(netshort);
|
||||
}
|
||||
|
||||
uint32_t lwip_htonl (uint32_t hostlong) { return htonl(hostlong); }
|
||||
uint16_t lwip_htons (uint16_t hostshort) { return htons(hostshort); }
|
||||
uint32_t lwip_ntohl (uint32_t netlong) { return ntohl(netlong); }
|
||||
uint16_t lwip_ntohs (uint16_t netshort) { return ntohs(netshort); }
|
||||
char* ets_strcpy(char* d, const char* s)
|
||||
{
|
||||
return strcpy(d, s);
|
||||
}
|
||||
char* ets_strncpy(char* d, const char* s, size_t n)
|
||||
{
|
||||
return strncpy(d, s, n);
|
||||
}
|
||||
size_t ets_strlen(const char* s)
|
||||
{
|
||||
return strlen(s);
|
||||
}
|
||||
|
||||
char* ets_strcpy (char* d, const char* s) { return strcpy(d, s); }
|
||||
char* ets_strncpy (char* d, const char* s, size_t n) { return strncpy(d, s, n); }
|
||||
size_t ets_strlen (const char* s) { return strlen(s); }
|
||||
|
||||
int ets_printf (const char* fmt, ...)
|
||||
{
|
||||
int ets_printf(const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int len = vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
return len;
|
||||
}
|
||||
int len = vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
return len;
|
||||
}
|
||||
|
||||
void stack_thunk_add_ref() { }
|
||||
void stack_thunk_del_ref() { }
|
||||
void stack_thunk_repaint() { }
|
||||
void stack_thunk_add_ref() { }
|
||||
void stack_thunk_del_ref() { }
|
||||
void stack_thunk_repaint() { }
|
||||
|
||||
uint32_t stack_thunk_get_refcnt() { return 0; }
|
||||
uint32_t stack_thunk_get_stack_top() { return 0; }
|
||||
uint32_t stack_thunk_get_stack_bot() { return 0; }
|
||||
uint32_t stack_thunk_get_cont_sp() { return 0; }
|
||||
uint32_t stack_thunk_get_max_usage() { return 0; }
|
||||
void stack_thunk_dump_stack() { }
|
||||
uint32_t stack_thunk_get_refcnt()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint32_t stack_thunk_get_stack_top()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint32_t stack_thunk_get_stack_bot()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint32_t stack_thunk_get_cont_sp()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint32_t stack_thunk_get_max_usage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void stack_thunk_dump_stack() { }
|
||||
|
||||
// Thunking macro
|
||||
#define make_stack_thunk(fcnToThunk)
|
||||
|
||||
};
|
||||
|
||||
void configTime(int timezone, int daylightOffset_sec,
|
||||
const char* server1, const char* server2, const char* server3)
|
||||
void configTime(int timezone, int daylightOffset_sec, const char* server1, const char* server2,
|
||||
const char* server3)
|
||||
{
|
||||
(void)server1;
|
||||
(void)server2;
|
||||
(void)server3;
|
||||
(void)server1;
|
||||
(void)server2;
|
||||
(void)server3;
|
||||
|
||||
mockverbose("configTime: TODO (tz=%dH offset=%dS) (time will be host's)\n", timezone, daylightOffset_sec);
|
||||
mockverbose("configTime: TODO (tz=%dH offset=%dS) (time will be host's)\n", timezone,
|
||||
daylightOffset_sec);
|
||||
}
|
||||
|
||||
void configTime(const char* tz, const char* server1, const char* server2, const char* server3)
|
||||
{
|
||||
(void)server1;
|
||||
(void)server2;
|
||||
(void)server3;
|
||||
(void)server1;
|
||||
(void)server2;
|
||||
(void)server3;
|
||||
|
||||
mockverbose("configTime: TODO (tz='%s') (time will be host's)\n", tz);
|
||||
mockverbose("configTime: TODO (tz='%s') (time will be host's)\n", tz);
|
||||
}
|
||||
|
||||
@@ -28,475 +28,455 @@
|
||||
is responsible for feeding the RX FIFO new data by calling uart_new_data().
|
||||
*/
|
||||
|
||||
#include <unistd.h> // write
|
||||
#include <sys/time.h> // gettimeofday
|
||||
#include <time.h> // localtime
|
||||
#include <unistd.h> // write
|
||||
#include <sys/time.h> // gettimeofday
|
||||
#include <time.h> // localtime
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "uart.h"
|
||||
|
||||
//#define UART_DISCARD_NEWEST
|
||||
|
||||
extern "C" {
|
||||
|
||||
bool blocking_uart = true; // system default
|
||||
|
||||
static int s_uart_debug_nr = UART1;
|
||||
|
||||
static uart_t *UART[2] = { NULL, NULL };
|
||||
|
||||
struct uart_rx_buffer_
|
||||
extern "C"
|
||||
{
|
||||
size_t size;
|
||||
size_t rpos;
|
||||
size_t wpos;
|
||||
uint8_t * buffer;
|
||||
};
|
||||
bool blocking_uart = true; // system default
|
||||
|
||||
struct uart_
|
||||
{
|
||||
int uart_nr;
|
||||
int baud_rate;
|
||||
bool rx_enabled;
|
||||
bool tx_enabled;
|
||||
bool rx_overrun;
|
||||
struct uart_rx_buffer_ * rx_buffer;
|
||||
};
|
||||
static int s_uart_debug_nr = UART1;
|
||||
|
||||
bool serial_timestamp = false;
|
||||
static uart_t* UART[2] = { NULL, NULL };
|
||||
|
||||
// write one byte to the emulated UART
|
||||
static void
|
||||
uart_do_write_char(const int uart_nr, char c)
|
||||
{
|
||||
static bool w = false;
|
||||
struct uart_rx_buffer_
|
||||
{
|
||||
size_t size;
|
||||
size_t rpos;
|
||||
size_t wpos;
|
||||
uint8_t* buffer;
|
||||
};
|
||||
|
||||
if (uart_nr >= UART0 && uart_nr <= UART1)
|
||||
{
|
||||
if (serial_timestamp && (c == '\n' || c == '\r'))
|
||||
{
|
||||
if (w)
|
||||
{
|
||||
FILE* out = uart_nr == UART0? stdout: stderr;
|
||||
timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
const tm* tm = localtime(&tv.tv_sec);
|
||||
fprintf(out, "\r\n%d:%02d:%02d.%06d: ", tm->tm_hour, tm->tm_min, tm->tm_sec, (int)tv.tv_usec);
|
||||
fflush(out);
|
||||
w = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct uart_
|
||||
{
|
||||
int uart_nr;
|
||||
int baud_rate;
|
||||
bool rx_enabled;
|
||||
bool tx_enabled;
|
||||
bool rx_overrun;
|
||||
struct uart_rx_buffer_* rx_buffer;
|
||||
};
|
||||
|
||||
bool serial_timestamp = false;
|
||||
|
||||
// write one byte to the emulated UART
|
||||
static void uart_do_write_char(const int uart_nr, char c)
|
||||
{
|
||||
static bool w = false;
|
||||
|
||||
if (uart_nr >= UART0 && uart_nr <= UART1)
|
||||
{
|
||||
if (serial_timestamp && (c == '\n' || c == '\r'))
|
||||
{
|
||||
if (w)
|
||||
{
|
||||
FILE* out = uart_nr == UART0 ? stdout : stderr;
|
||||
timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
const tm* tm = localtime(&tv.tv_sec);
|
||||
fprintf(out, "\r\n%d:%02d:%02d.%06d: ", tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||
(int)tv.tv_usec);
|
||||
fflush(out);
|
||||
w = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
||||
write(uart_nr + 1, &c, 1);
|
||||
write(uart_nr + 1, &c, 1);
|
||||
#pragma GCC diagnostic pop
|
||||
w = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write a new byte into the RX FIFO buffer
|
||||
static void
|
||||
uart_handle_data(uart_t* uart, uint8_t data)
|
||||
{
|
||||
struct uart_rx_buffer_ *rx_buffer = uart->rx_buffer;
|
||||
|
||||
size_t nextPos = (rx_buffer->wpos + 1) % rx_buffer->size;
|
||||
if(nextPos == rx_buffer->rpos)
|
||||
{
|
||||
uart->rx_overrun = true;
|
||||
#ifdef UART_DISCARD_NEWEST
|
||||
return;
|
||||
#else
|
||||
if (++rx_buffer->rpos == rx_buffer->size)
|
||||
rx_buffer->rpos = 0;
|
||||
#endif
|
||||
}
|
||||
rx_buffer->buffer[rx_buffer->wpos] = data;
|
||||
rx_buffer->wpos = nextPos;
|
||||
}
|
||||
|
||||
// insert a new byte into the RX FIFO nuffer
|
||||
void
|
||||
uart_new_data(const int uart_nr, uint8_t data)
|
||||
{
|
||||
uart_t* uart = UART[uart_nr];
|
||||
|
||||
if(uart == NULL || !uart->rx_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
uart_handle_data(uart, data);
|
||||
}
|
||||
|
||||
static size_t
|
||||
uart_rx_available_unsafe(const struct uart_rx_buffer_ * rx_buffer)
|
||||
{
|
||||
size_t ret = rx_buffer->wpos - rx_buffer->rpos;
|
||||
|
||||
if(rx_buffer->wpos < rx_buffer->rpos)
|
||||
ret = (rx_buffer->wpos + rx_buffer->size) - rx_buffer->rpos;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// taking data straight from fifo, only needed in uart_resize_rx_buffer()
|
||||
static int
|
||||
uart_read_char_unsafe(uart_t* uart)
|
||||
{
|
||||
if (uart_rx_available_unsafe(uart->rx_buffer))
|
||||
{
|
||||
// take oldest sw data
|
||||
int ret = uart->rx_buffer->buffer[uart->rx_buffer->rpos];
|
||||
uart->rx_buffer->rpos = (uart->rx_buffer->rpos + 1) % uart->rx_buffer->size;
|
||||
return ret;
|
||||
}
|
||||
// unavailable
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
/************ UART API FUNCTIONS **************************/
|
||||
/**********************************************************/
|
||||
|
||||
size_t
|
||||
uart_rx_available(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
|
||||
return uart_rx_available_unsafe(uart->rx_buffer);
|
||||
}
|
||||
|
||||
int
|
||||
uart_peek_char(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || !uart->rx_enabled)
|
||||
return -1;
|
||||
|
||||
if (!uart_rx_available_unsafe(uart->rx_buffer))
|
||||
return -1;
|
||||
|
||||
return uart->rx_buffer->buffer[uart->rx_buffer->rpos];
|
||||
}
|
||||
|
||||
int
|
||||
uart_read_char(uart_t* uart)
|
||||
{
|
||||
uint8_t ret;
|
||||
return uart_read(uart, (char*)&ret, 1) ? ret : -1;
|
||||
}
|
||||
|
||||
size_t
|
||||
uart_read(uart_t* uart, char* userbuffer, size_t usersize)
|
||||
{
|
||||
if(uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
|
||||
if (!blocking_uart)
|
||||
{
|
||||
char c;
|
||||
if (read(0, &c, 1) == 1)
|
||||
uart_new_data(0, c);
|
||||
w = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t ret = 0;
|
||||
while (ret < usersize && uart_rx_available_unsafe(uart->rx_buffer))
|
||||
{
|
||||
// pour sw buffer to user's buffer
|
||||
// get largest linear length from sw buffer
|
||||
size_t chunk = uart->rx_buffer->rpos < uart->rx_buffer->wpos ?
|
||||
uart->rx_buffer->wpos - uart->rx_buffer->rpos :
|
||||
uart->rx_buffer->size - uart->rx_buffer->rpos;
|
||||
if (ret + chunk > usersize)
|
||||
chunk = usersize - ret;
|
||||
memcpy(userbuffer + ret, uart->rx_buffer->buffer + uart->rx_buffer->rpos, chunk);
|
||||
uart->rx_buffer->rpos = (uart->rx_buffer->rpos + chunk) % uart->rx_buffer->size;
|
||||
ret += chunk;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// write a new byte into the RX FIFO buffer
|
||||
static void uart_handle_data(uart_t* uart, uint8_t data)
|
||||
{
|
||||
struct uart_rx_buffer_* rx_buffer = uart->rx_buffer;
|
||||
|
||||
size_t
|
||||
uart_resize_rx_buffer(uart_t* uart, size_t new_size)
|
||||
{
|
||||
if(uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
size_t nextPos = (rx_buffer->wpos + 1) % rx_buffer->size;
|
||||
if (nextPos == rx_buffer->rpos)
|
||||
{
|
||||
uart->rx_overrun = true;
|
||||
#ifdef UART_DISCARD_NEWEST
|
||||
return;
|
||||
#else
|
||||
if (++rx_buffer->rpos == rx_buffer->size)
|
||||
rx_buffer->rpos = 0;
|
||||
#endif
|
||||
}
|
||||
rx_buffer->buffer[rx_buffer->wpos] = data;
|
||||
rx_buffer->wpos = nextPos;
|
||||
}
|
||||
|
||||
if(uart->rx_buffer->size == new_size)
|
||||
return uart->rx_buffer->size;
|
||||
// insert a new byte into the RX FIFO nuffer
|
||||
void uart_new_data(const int uart_nr, uint8_t data)
|
||||
{
|
||||
uart_t* uart = UART[uart_nr];
|
||||
|
||||
uint8_t * new_buf = (uint8_t*)malloc(new_size);
|
||||
if(!new_buf)
|
||||
return uart->rx_buffer->size;
|
||||
if (uart == NULL || !uart->rx_enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
size_t new_wpos = 0;
|
||||
// if uart_rx_available_unsafe() returns non-0, uart_read_char_unsafe() can't return -1
|
||||
while(uart_rx_available_unsafe(uart->rx_buffer) && new_wpos < new_size)
|
||||
new_buf[new_wpos++] = uart_read_char_unsafe(uart);
|
||||
if (new_wpos == new_size)
|
||||
new_wpos = 0;
|
||||
uart_handle_data(uart, data);
|
||||
}
|
||||
|
||||
uint8_t * old_buf = uart->rx_buffer->buffer;
|
||||
uart->rx_buffer->rpos = 0;
|
||||
uart->rx_buffer->wpos = new_wpos;
|
||||
uart->rx_buffer->size = new_size;
|
||||
uart->rx_buffer->buffer = new_buf;
|
||||
free(old_buf);
|
||||
return uart->rx_buffer->size;
|
||||
}
|
||||
static size_t uart_rx_available_unsafe(const struct uart_rx_buffer_* rx_buffer)
|
||||
{
|
||||
size_t ret = rx_buffer->wpos - rx_buffer->rpos;
|
||||
|
||||
size_t
|
||||
uart_get_rx_buffer_size(uart_t* uart)
|
||||
{
|
||||
return uart && uart->rx_enabled ? uart->rx_buffer->size : 0;
|
||||
}
|
||||
if (rx_buffer->wpos < rx_buffer->rpos)
|
||||
ret = (rx_buffer->wpos + rx_buffer->size) - rx_buffer->rpos;
|
||||
|
||||
size_t
|
||||
uart_write_char(uart_t* uart, char c)
|
||||
{
|
||||
if(uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uart_do_write_char(uart->uart_nr, c);
|
||||
// taking data straight from fifo, only needed in uart_resize_rx_buffer()
|
||||
static int uart_read_char_unsafe(uart_t* uart)
|
||||
{
|
||||
if (uart_rx_available_unsafe(uart->rx_buffer))
|
||||
{
|
||||
// take oldest sw data
|
||||
int ret = uart->rx_buffer->buffer[uart->rx_buffer->rpos];
|
||||
uart->rx_buffer->rpos = (uart->rx_buffer->rpos + 1) % uart->rx_buffer->size;
|
||||
return ret;
|
||||
}
|
||||
// unavailable
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/**********************************************************/
|
||||
/************ UART API FUNCTIONS **************************/
|
||||
/**********************************************************/
|
||||
|
||||
size_t
|
||||
uart_write(uart_t* uart, const char* buf, size_t size)
|
||||
{
|
||||
if(uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
size_t uart_rx_available(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
|
||||
size_t ret = size;
|
||||
const int uart_nr = uart->uart_nr;
|
||||
while (size--)
|
||||
uart_do_write_char(uart_nr, *buf++);
|
||||
return uart_rx_available_unsafe(uart->rx_buffer);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
int uart_peek_char(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL || !uart->rx_enabled)
|
||||
return -1;
|
||||
|
||||
size_t
|
||||
uart_tx_free(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
if (!uart_rx_available_unsafe(uart->rx_buffer))
|
||||
return -1;
|
||||
|
||||
return UART_TX_FIFO_SIZE;
|
||||
}
|
||||
return uart->rx_buffer->buffer[uart->rx_buffer->rpos];
|
||||
}
|
||||
|
||||
void
|
||||
uart_wait_tx_empty(uart_t* uart)
|
||||
{
|
||||
(void) uart;
|
||||
}
|
||||
int uart_read_char(uart_t* uart)
|
||||
{
|
||||
uint8_t ret;
|
||||
return uart_read(uart, (char*)&ret, 1) ? ret : -1;
|
||||
}
|
||||
|
||||
void
|
||||
uart_flush(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return;
|
||||
size_t uart_read(uart_t* uart, char* userbuffer, size_t usersize)
|
||||
{
|
||||
if (uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
|
||||
if(uart->rx_enabled)
|
||||
{
|
||||
uart->rx_buffer->rpos = 0;
|
||||
uart->rx_buffer->wpos = 0;
|
||||
}
|
||||
}
|
||||
if (!blocking_uart)
|
||||
{
|
||||
char c;
|
||||
if (read(0, &c, 1) == 1)
|
||||
uart_new_data(0, c);
|
||||
}
|
||||
|
||||
void
|
||||
uart_set_baudrate(uart_t* uart, int baud_rate)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return;
|
||||
size_t ret = 0;
|
||||
while (ret < usersize && uart_rx_available_unsafe(uart->rx_buffer))
|
||||
{
|
||||
// pour sw buffer to user's buffer
|
||||
// get largest linear length from sw buffer
|
||||
size_t chunk = uart->rx_buffer->rpos < uart->rx_buffer->wpos
|
||||
? uart->rx_buffer->wpos - uart->rx_buffer->rpos
|
||||
: uart->rx_buffer->size - uart->rx_buffer->rpos;
|
||||
if (ret + chunk > usersize)
|
||||
chunk = usersize - ret;
|
||||
memcpy(userbuffer + ret, uart->rx_buffer->buffer + uart->rx_buffer->rpos, chunk);
|
||||
uart->rx_buffer->rpos = (uart->rx_buffer->rpos + chunk) % uart->rx_buffer->size;
|
||||
ret += chunk;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uart->baud_rate = baud_rate;
|
||||
}
|
||||
size_t uart_resize_rx_buffer(uart_t* uart, size_t new_size)
|
||||
{
|
||||
if (uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
|
||||
int
|
||||
uart_get_baudrate(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return 0;
|
||||
if (uart->rx_buffer->size == new_size)
|
||||
return uart->rx_buffer->size;
|
||||
|
||||
return uart->baud_rate;
|
||||
}
|
||||
uint8_t* new_buf = (uint8_t*)malloc(new_size);
|
||||
if (!new_buf)
|
||||
return uart->rx_buffer->size;
|
||||
|
||||
uint8_t
|
||||
uart_get_bit_length(const int uart_nr)
|
||||
{
|
||||
uint8_t width = ((uart_nr % 16) >> 2) + 5;
|
||||
uint8_t parity = (uart_nr >> 5) + 1;
|
||||
uint8_t stop = uart_nr % 4;
|
||||
return (width + parity + stop + 1);
|
||||
}
|
||||
size_t new_wpos = 0;
|
||||
// if uart_rx_available_unsafe() returns non-0, uart_read_char_unsafe() can't return -1
|
||||
while (uart_rx_available_unsafe(uart->rx_buffer) && new_wpos < new_size)
|
||||
new_buf[new_wpos++] = uart_read_char_unsafe(uart);
|
||||
if (new_wpos == new_size)
|
||||
new_wpos = 0;
|
||||
|
||||
uart_t*
|
||||
uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin, size_t rx_size, bool invert)
|
||||
{
|
||||
(void) config;
|
||||
(void) tx_pin;
|
||||
(void) invert;
|
||||
uart_t* uart = (uart_t*) malloc(sizeof(uart_t));
|
||||
if(uart == NULL)
|
||||
return NULL;
|
||||
uint8_t* old_buf = uart->rx_buffer->buffer;
|
||||
uart->rx_buffer->rpos = 0;
|
||||
uart->rx_buffer->wpos = new_wpos;
|
||||
uart->rx_buffer->size = new_size;
|
||||
uart->rx_buffer->buffer = new_buf;
|
||||
free(old_buf);
|
||||
return uart->rx_buffer->size;
|
||||
}
|
||||
|
||||
uart->uart_nr = uart_nr;
|
||||
uart->rx_overrun = false;
|
||||
size_t uart_get_rx_buffer_size(uart_t* uart)
|
||||
{
|
||||
return uart && uart->rx_enabled ? uart->rx_buffer->size : 0;
|
||||
}
|
||||
|
||||
switch(uart->uart_nr)
|
||||
{
|
||||
case UART0:
|
||||
uart->rx_enabled = (mode != UART_TX_ONLY);
|
||||
uart->tx_enabled = (mode != UART_RX_ONLY);
|
||||
if(uart->rx_enabled)
|
||||
{
|
||||
struct uart_rx_buffer_ * rx_buffer = (struct uart_rx_buffer_ *)malloc(sizeof(struct uart_rx_buffer_));
|
||||
if(rx_buffer == NULL)
|
||||
{
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
rx_buffer->size = rx_size;//var this
|
||||
rx_buffer->rpos = 0;
|
||||
rx_buffer->wpos = 0;
|
||||
rx_buffer->buffer = (uint8_t *)malloc(rx_buffer->size);
|
||||
if(rx_buffer->buffer == NULL)
|
||||
{
|
||||
free(rx_buffer);
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
uart->rx_buffer = rx_buffer;
|
||||
}
|
||||
break;
|
||||
size_t uart_write_char(uart_t* uart, char c)
|
||||
{
|
||||
if (uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
|
||||
case UART1:
|
||||
// Note: uart_interrupt_handler does not support RX on UART 1.
|
||||
uart->rx_enabled = false;
|
||||
uart->tx_enabled = (mode != UART_RX_ONLY);
|
||||
break;
|
||||
uart_do_write_char(uart->uart_nr, c);
|
||||
|
||||
case UART_NO:
|
||||
default:
|
||||
// big fail!
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uart_set_baudrate(uart, baudrate);
|
||||
size_t uart_write(uart_t* uart, const char* buf, size_t size)
|
||||
{
|
||||
if (uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
|
||||
UART[uart_nr] = uart;
|
||||
size_t ret = size;
|
||||
const int uart_nr = uart->uart_nr;
|
||||
while (size--)
|
||||
uart_do_write_char(uart_nr, *buf++);
|
||||
|
||||
return uart;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
uart_uninit(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return;
|
||||
size_t uart_tx_free(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
|
||||
if(uart->rx_enabled) {
|
||||
free(uart->rx_buffer->buffer);
|
||||
free(uart->rx_buffer);
|
||||
}
|
||||
free(uart);
|
||||
}
|
||||
return UART_TX_FIFO_SIZE;
|
||||
}
|
||||
|
||||
bool
|
||||
uart_swap(uart_t* uart, int tx_pin)
|
||||
{
|
||||
(void) uart;
|
||||
(void) tx_pin;
|
||||
return true;
|
||||
}
|
||||
void uart_wait_tx_empty(uart_t* uart)
|
||||
{
|
||||
(void)uart;
|
||||
}
|
||||
|
||||
bool
|
||||
uart_set_tx(uart_t* uart, int tx_pin)
|
||||
{
|
||||
(void) uart;
|
||||
(void) tx_pin;
|
||||
return true;
|
||||
}
|
||||
void uart_flush(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return;
|
||||
|
||||
bool
|
||||
uart_set_pins(uart_t* uart, int tx, int rx)
|
||||
{
|
||||
(void) uart;
|
||||
(void) tx;
|
||||
(void) rx;
|
||||
return true;
|
||||
}
|
||||
if (uart->rx_enabled)
|
||||
{
|
||||
uart->rx_buffer->rpos = 0;
|
||||
uart->rx_buffer->wpos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
uart_tx_enabled(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return false;
|
||||
void uart_set_baudrate(uart_t* uart, int baud_rate)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return;
|
||||
|
||||
return uart->tx_enabled;
|
||||
}
|
||||
uart->baud_rate = baud_rate;
|
||||
}
|
||||
|
||||
bool
|
||||
uart_rx_enabled(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return false;
|
||||
int uart_get_baudrate(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return 0;
|
||||
|
||||
return uart->rx_enabled;
|
||||
}
|
||||
return uart->baud_rate;
|
||||
}
|
||||
|
||||
bool
|
||||
uart_has_overrun(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || !uart->rx_overrun)
|
||||
return false;
|
||||
uint8_t uart_get_bit_length(const int uart_nr)
|
||||
{
|
||||
uint8_t width = ((uart_nr % 16) >> 2) + 5;
|
||||
uint8_t parity = (uart_nr >> 5) + 1;
|
||||
uint8_t stop = uart_nr % 4;
|
||||
return (width + parity + stop + 1);
|
||||
}
|
||||
|
||||
// clear flag
|
||||
uart->rx_overrun = false;
|
||||
return true;
|
||||
}
|
||||
uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin, size_t rx_size,
|
||||
bool invert)
|
||||
{
|
||||
(void)config;
|
||||
(void)tx_pin;
|
||||
(void)invert;
|
||||
uart_t* uart = (uart_t*)malloc(sizeof(uart_t));
|
||||
if (uart == NULL)
|
||||
return NULL;
|
||||
|
||||
bool
|
||||
uart_has_rx_error(uart_t* uart)
|
||||
{
|
||||
(void) uart;
|
||||
return false;
|
||||
}
|
||||
uart->uart_nr = uart_nr;
|
||||
uart->rx_overrun = false;
|
||||
|
||||
void
|
||||
uart_set_debug(int uart_nr)
|
||||
{
|
||||
(void)uart_nr;
|
||||
}
|
||||
switch (uart->uart_nr)
|
||||
{
|
||||
case UART0:
|
||||
uart->rx_enabled = (mode != UART_TX_ONLY);
|
||||
uart->tx_enabled = (mode != UART_RX_ONLY);
|
||||
if (uart->rx_enabled)
|
||||
{
|
||||
struct uart_rx_buffer_* rx_buffer
|
||||
= (struct uart_rx_buffer_*)malloc(sizeof(struct uart_rx_buffer_));
|
||||
if (rx_buffer == NULL)
|
||||
{
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
rx_buffer->size = rx_size; // var this
|
||||
rx_buffer->rpos = 0;
|
||||
rx_buffer->wpos = 0;
|
||||
rx_buffer->buffer = (uint8_t*)malloc(rx_buffer->size);
|
||||
if (rx_buffer->buffer == NULL)
|
||||
{
|
||||
free(rx_buffer);
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
uart->rx_buffer = rx_buffer;
|
||||
}
|
||||
break;
|
||||
|
||||
int
|
||||
uart_get_debug()
|
||||
{
|
||||
return s_uart_debug_nr;
|
||||
}
|
||||
case UART1:
|
||||
// Note: uart_interrupt_handler does not support RX on UART 1.
|
||||
uart->rx_enabled = false;
|
||||
uart->tx_enabled = (mode != UART_RX_ONLY);
|
||||
break;
|
||||
|
||||
void
|
||||
uart_start_detect_baudrate(int uart_nr)
|
||||
{
|
||||
(void) uart_nr;
|
||||
}
|
||||
case UART_NO:
|
||||
default:
|
||||
// big fail!
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
uart_detect_baudrate(int uart_nr)
|
||||
{
|
||||
(void) uart_nr;
|
||||
return 115200;
|
||||
}
|
||||
uart_set_baudrate(uart, baudrate);
|
||||
|
||||
UART[uart_nr] = uart;
|
||||
|
||||
return uart;
|
||||
}
|
||||
|
||||
void uart_uninit(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return;
|
||||
|
||||
if (uart->rx_enabled)
|
||||
{
|
||||
free(uart->rx_buffer->buffer);
|
||||
free(uart->rx_buffer);
|
||||
}
|
||||
free(uart);
|
||||
}
|
||||
|
||||
bool uart_swap(uart_t* uart, int tx_pin)
|
||||
{
|
||||
(void)uart;
|
||||
(void)tx_pin;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uart_set_tx(uart_t* uart, int tx_pin)
|
||||
{
|
||||
(void)uart;
|
||||
(void)tx_pin;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uart_set_pins(uart_t* uart, int tx, int rx)
|
||||
{
|
||||
(void)uart;
|
||||
(void)tx;
|
||||
(void)rx;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uart_tx_enabled(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return false;
|
||||
|
||||
return uart->tx_enabled;
|
||||
}
|
||||
|
||||
bool uart_rx_enabled(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return false;
|
||||
|
||||
return uart->rx_enabled;
|
||||
}
|
||||
|
||||
bool uart_has_overrun(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL || !uart->rx_overrun)
|
||||
return false;
|
||||
|
||||
// clear flag
|
||||
uart->rx_overrun = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uart_has_rx_error(uart_t* uart)
|
||||
{
|
||||
(void)uart;
|
||||
return false;
|
||||
}
|
||||
|
||||
void uart_set_debug(int uart_nr)
|
||||
{
|
||||
(void)uart_nr;
|
||||
}
|
||||
|
||||
int uart_get_debug()
|
||||
{
|
||||
return s_uart_debug_nr;
|
||||
}
|
||||
|
||||
void uart_start_detect_baudrate(int uart_nr)
|
||||
{
|
||||
(void)uart_nr;
|
||||
}
|
||||
|
||||
int uart_detect_baudrate(int uart_nr)
|
||||
{
|
||||
(void)uart_nr;
|
||||
return 115200;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
size_t uart_peek_available (uart_t* uart) { return 0; }
|
||||
const char* uart_peek_buffer (uart_t* uart) { return nullptr; }
|
||||
void uart_peek_consume (uart_t* uart, size_t consume) { (void)uart; (void)consume; }
|
||||
|
||||
size_t uart_peek_available(uart_t* uart)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const char* uart_peek_buffer(uart_t* uart)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
void uart_peek_consume(uart_t* uart, size_t consume)
|
||||
{
|
||||
(void)uart;
|
||||
(void)consume;
|
||||
}
|
||||
|
||||
@@ -44,32 +44,31 @@ extern "C" const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY);
|
||||
|
||||
// lwIP API side of WiFiServer
|
||||
|
||||
WiFiServer::WiFiServer (const IPAddress& addr, uint16_t port)
|
||||
WiFiServer::WiFiServer(const IPAddress& addr, uint16_t port)
|
||||
{
|
||||
(void)addr;
|
||||
_port = port;
|
||||
(void)addr;
|
||||
_port = port;
|
||||
}
|
||||
|
||||
WiFiServer::WiFiServer (uint16_t port)
|
||||
WiFiServer::WiFiServer(uint16_t port)
|
||||
{
|
||||
_port = port;
|
||||
_port = port;
|
||||
}
|
||||
|
||||
WiFiClient WiFiServer::available (uint8_t* status)
|
||||
WiFiClient WiFiServer::available(uint8_t* status)
|
||||
{
|
||||
(void)status;
|
||||
return accept();
|
||||
(void)status;
|
||||
return accept();
|
||||
}
|
||||
|
||||
WiFiClient WiFiServer::accept ()
|
||||
WiFiClient WiFiServer::accept()
|
||||
{
|
||||
if (hasClient())
|
||||
return WiFiClient(new ClientContext(serverAccept(pcb2int(_listen_pcb))));
|
||||
return WiFiClient();
|
||||
if (hasClient())
|
||||
return WiFiClient(new ClientContext(serverAccept(pcb2int(_listen_pcb))));
|
||||
return WiFiClient();
|
||||
}
|
||||
|
||||
// static declaration
|
||||
|
||||
#include <include/UdpContext.h>
|
||||
uint32_t UdpContext::staticMCastAddr = 0;
|
||||
|
||||
|
||||
@@ -44,26 +44,26 @@
|
||||
|
||||
// host socket internal side of WiFiServer
|
||||
|
||||
int serverAccept (int srvsock)
|
||||
int serverAccept(int srvsock)
|
||||
{
|
||||
int clisock;
|
||||
socklen_t n;
|
||||
struct sockaddr_in client;
|
||||
n = sizeof(client);
|
||||
if ((clisock = accept(srvsock, (struct sockaddr*)&client, &n)) == -1)
|
||||
{
|
||||
perror(MOCK "accept()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return mockSockSetup(clisock);
|
||||
int clisock;
|
||||
socklen_t n;
|
||||
struct sockaddr_in client;
|
||||
n = sizeof(client);
|
||||
if ((clisock = accept(srvsock, (struct sockaddr*)&client, &n)) == -1)
|
||||
{
|
||||
perror(MOCK "accept()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return mockSockSetup(clisock);
|
||||
}
|
||||
|
||||
void WiFiServer::begin (uint16_t port)
|
||||
void WiFiServer::begin(uint16_t port)
|
||||
{
|
||||
return begin(port, !0);
|
||||
}
|
||||
|
||||
void WiFiServer::begin (uint16_t port, uint8_t backlog)
|
||||
void WiFiServer::begin(uint16_t port, uint8_t backlog)
|
||||
{
|
||||
if (!backlog)
|
||||
return;
|
||||
@@ -71,85 +71,86 @@ void WiFiServer::begin (uint16_t port, uint8_t backlog)
|
||||
return begin();
|
||||
}
|
||||
|
||||
void WiFiServer::begin ()
|
||||
void WiFiServer::begin()
|
||||
{
|
||||
int sock;
|
||||
int mockport;
|
||||
struct sockaddr_in server;
|
||||
int sock;
|
||||
int mockport;
|
||||
struct sockaddr_in server;
|
||||
|
||||
mockport = _port;
|
||||
if (mockport < 1024 && mock_port_shifter)
|
||||
{
|
||||
mockport += mock_port_shifter;
|
||||
fprintf(stderr, MOCK "=====> WiFiServer port: %d shifted to %d (use option -s) <=====\n", _port, mockport);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, MOCK "=====> WiFiServer port: %d <=====\n", mockport);
|
||||
mockport = _port;
|
||||
if (mockport < 1024 && mock_port_shifter)
|
||||
{
|
||||
mockport += mock_port_shifter;
|
||||
fprintf(stderr, MOCK "=====> WiFiServer port: %d shifted to %d (use option -s) <=====\n",
|
||||
_port, mockport);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, MOCK "=====> WiFiServer port: %d <=====\n", mockport);
|
||||
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
perror(MOCK "socket()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
perror(MOCK "socket()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) == -1)
|
||||
{
|
||||
perror(MOCK "reuseport");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) == -1)
|
||||
{
|
||||
perror(MOCK "reuseport");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(mockport);
|
||||
server.sin_addr.s_addr = htonl(global_source_address);
|
||||
if (bind(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
|
||||
{
|
||||
perror(MOCK "bind()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(mockport);
|
||||
server.sin_addr.s_addr = htonl(global_source_address);
|
||||
if (bind(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
|
||||
{
|
||||
perror(MOCK "bind()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (listen(sock, 1) == -1)
|
||||
{
|
||||
perror(MOCK "listen()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (listen(sock, 1) == -1)
|
||||
{
|
||||
perror(MOCK "listen()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
// store int into pointer
|
||||
_listen_pcb = int2pcb(sock);
|
||||
// store int into pointer
|
||||
_listen_pcb = int2pcb(sock);
|
||||
}
|
||||
|
||||
bool WiFiServer::hasClient ()
|
||||
bool WiFiServer::hasClient()
|
||||
{
|
||||
struct pollfd p;
|
||||
p.fd = pcb2int(_listen_pcb);
|
||||
p.events = POLLIN;
|
||||
return poll(&p, 1, 0) && p.revents == POLLIN;
|
||||
struct pollfd p;
|
||||
p.fd = pcb2int(_listen_pcb);
|
||||
p.events = POLLIN;
|
||||
return poll(&p, 1, 0) && p.revents == POLLIN;
|
||||
}
|
||||
|
||||
void WiFiServer::close ()
|
||||
void WiFiServer::close()
|
||||
{
|
||||
if (pcb2int(_listen_pcb) >= 0)
|
||||
::close(pcb2int(_listen_pcb));
|
||||
_listen_pcb = int2pcb(-1);
|
||||
if (pcb2int(_listen_pcb) >= 0)
|
||||
::close(pcb2int(_listen_pcb));
|
||||
_listen_pcb = int2pcb(-1);
|
||||
}
|
||||
|
||||
void WiFiServer::stop ()
|
||||
void WiFiServer::stop()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
size_t WiFiServer::hasClientData ()
|
||||
size_t WiFiServer::hasClientData()
|
||||
{
|
||||
// Trivial Mocking:
|
||||
// There is no waiting list of clients in this trivial mocking code,
|
||||
// so the code has to act as if the tcp backlog list is full,
|
||||
// and nothing is known about potential further clients.
|
||||
// It could be implemented by accepting new clients and store their data until the current one is closed.
|
||||
// It could be implemented by accepting new clients and store their data until the current one
|
||||
// is closed.
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool WiFiServer::hasMaxPendingClients ()
|
||||
bool WiFiServer::hasMaxPendingClients()
|
||||
{
|
||||
// Mocking code does not consider the waiting client list,
|
||||
// so it will return ::hasClient() here meaning:
|
||||
|
||||
@@ -7,58 +7,54 @@ esp8266::AddressListImplementation::AddressList addrList;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern netif netif0;
|
||||
|
||||
extern netif netif0;
|
||||
netif* netif_list = &netif0;
|
||||
|
||||
netif* netif_list = &netif0;
|
||||
err_t dhcp_renew(struct netif* netif)
|
||||
{
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t dhcp_renew(struct netif *netif)
|
||||
{
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
void sntp_setserver(u8_t, const ip_addr_t) { }
|
||||
|
||||
void sntp_setserver(u8_t, const ip_addr_t)
|
||||
{
|
||||
}
|
||||
const ip_addr_t* sntp_getserver(u8_t)
|
||||
{
|
||||
return IP_ADDR_ANY;
|
||||
}
|
||||
|
||||
const ip_addr_t* sntp_getserver(u8_t)
|
||||
{
|
||||
return IP_ADDR_ANY;
|
||||
}
|
||||
err_t etharp_request(struct netif* netif, const ip4_addr_t* ipaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)ipaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t etharp_request(struct netif *netif, const ip4_addr_t *ipaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)ipaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
err_t igmp_start(struct netif* netif)
|
||||
{
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t igmp_start(struct netif* netif)
|
||||
{
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
err_t igmp_joingroup_netif(struct netif* netif, const ip4_addr_t* groupaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)groupaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)groupaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
err_t igmp_leavegroup_netif(struct netif* netif, const ip4_addr_t* groupaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)groupaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)groupaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
struct netif* netif_get_by_index(u8_t idx)
|
||||
{
|
||||
(void)idx;
|
||||
return &netif0;
|
||||
}
|
||||
|
||||
struct netif* netif_get_by_index(u8_t idx)
|
||||
{
|
||||
(void)idx;
|
||||
return &netif0;
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#include <user_interface.h>
|
||||
#include <lwip/netif.h>
|
||||
|
||||
extern netif netif0;
|
||||
extern netif netif0;
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
|
||||
#endif // __MOCKLWIP_H
|
||||
#endif // __MOCKLWIP_H
|
||||
|
||||
@@ -39,176 +39,189 @@
|
||||
#include <assert.h>
|
||||
#include <net/if.h>
|
||||
|
||||
int mockUDPSocket ()
|
||||
int mockUDPSocket()
|
||||
{
|
||||
int s;
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1 || fcntl(s, F_SETFL, O_NONBLOCK) == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDP socket: %s", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return s;
|
||||
int s;
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1 || fcntl(s, F_SETFL, O_NONBLOCK) == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDP socket: %s", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
bool mockUDPListen (int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast)
|
||||
bool mockUDPListen(int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast)
|
||||
{
|
||||
int optval;
|
||||
int mockport;
|
||||
int optval;
|
||||
int mockport;
|
||||
|
||||
mockport = port;
|
||||
if (mockport < 1024 && mock_port_shifter)
|
||||
{
|
||||
mockport += mock_port_shifter;
|
||||
fprintf(stderr, MOCK "=====> UdpServer port: %d shifted to %d (use option -s) <=====\n", port, mockport);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, MOCK "=====> UdpServer port: %d <=====\n", mockport);
|
||||
mockport = port;
|
||||
if (mockport < 1024 && mock_port_shifter)
|
||||
{
|
||||
mockport += mock_port_shifter;
|
||||
fprintf(stderr, MOCK "=====> UdpServer port: %d shifted to %d (use option -s) <=====\n",
|
||||
port, mockport);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, MOCK "=====> UdpServer port: %d <=====\n", mockport);
|
||||
|
||||
optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) == -1)
|
||||
fprintf(stderr, MOCK "SO_REUSEPORT failed\n");
|
||||
optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1)
|
||||
fprintf(stderr, MOCK "SO_REUSEADDR failed\n");
|
||||
optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) == -1)
|
||||
fprintf(stderr, MOCK "SO_REUSEPORT failed\n");
|
||||
optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1)
|
||||
fprintf(stderr, MOCK "SO_REUSEADDR failed\n");
|
||||
|
||||
struct sockaddr_in servaddr;
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
struct sockaddr_in servaddr;
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
|
||||
// Filling server information
|
||||
servaddr.sin_family = AF_INET;
|
||||
(void) dstaddr;
|
||||
//servaddr.sin_addr.s_addr = htonl(global_source_address);
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_port = htons(mockport);
|
||||
// Filling server information
|
||||
servaddr.sin_family = AF_INET;
|
||||
(void)dstaddr;
|
||||
// servaddr.sin_addr.s_addr = htonl(global_source_address);
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_port = htons(mockport);
|
||||
|
||||
// Bind the socket with the server address
|
||||
if (bind(sock, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDP bind on port %d failed: %s\n", mockport, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
mockverbose("UDP server on port %d (sock=%d)\n", mockport, sock);
|
||||
// Bind the socket with the server address
|
||||
if (bind(sock, (const struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDP bind on port %d failed: %s\n", mockport, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
mockverbose("UDP server on port %d (sock=%d)\n", mockport, sock);
|
||||
|
||||
if (!mcast)
|
||||
mcast = inet_addr("224.0.0.1"); // all hosts group
|
||||
if (mcast)
|
||||
{
|
||||
// https://web.cs.wpi.edu/~claypool/courses/4514-B99/samples/multicast.c
|
||||
// https://stackoverflow.com/questions/12681097/c-choose-interface-for-udp-multicast-socket
|
||||
if (!mcast)
|
||||
mcast = inet_addr("224.0.0.1"); // all hosts group
|
||||
if (mcast)
|
||||
{
|
||||
// https://web.cs.wpi.edu/~claypool/courses/4514-B99/samples/multicast.c
|
||||
// https://stackoverflow.com/questions/12681097/c-choose-interface-for-udp-multicast-socket
|
||||
|
||||
struct ip_mreq mreq;
|
||||
mreq.imr_multiaddr.s_addr = mcast;
|
||||
//mreq.imr_interface.s_addr = htonl(global_source_address);
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
struct ip_mreq mreq;
|
||||
mreq.imr_multiaddr.s_addr = mcast;
|
||||
// mreq.imr_interface.s_addr = htonl(global_source_address);
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (host_interface)
|
||||
{
|
||||
if (host_interface)
|
||||
{
|
||||
#if __APPLE__
|
||||
int idx = if_nametoindex(host_interface);
|
||||
if (setsockopt(sock, IPPROTO_TCP, IP_BOUND_IF, &idx, sizeof(idx)) == -1)
|
||||
int idx = if_nametoindex(host_interface);
|
||||
if (setsockopt(sock, IPPROTO_TCP, IP_BOUND_IF, &idx, sizeof(idx)) == -1)
|
||||
#else
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, host_interface, strlen(host_interface)) == -1)
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, host_interface,
|
||||
strlen(host_interface))
|
||||
== -1)
|
||||
#endif
|
||||
fprintf(stderr, MOCK "UDP multicast: can't setup bind/output on interface %s: %s\n", host_interface, strerror(errno));
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &mreq.imr_interface, sizeof(struct in_addr)) == -1)
|
||||
fprintf(stderr, MOCK "UDP multicast: can't setup bind/input on interface %s: %s\n", host_interface, strerror(errno));
|
||||
}
|
||||
fprintf(stderr, MOCK "UDP multicast: can't setup bind/output on interface %s: %s\n",
|
||||
host_interface, strerror(errno));
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &mreq.imr_interface,
|
||||
sizeof(struct in_addr))
|
||||
== -1)
|
||||
fprintf(stderr, MOCK "UDP multicast: can't setup bind/input on interface %s: %s\n",
|
||||
host_interface, strerror(errno));
|
||||
}
|
||||
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||
{
|
||||
fprintf(stderr, MOCK "can't join multicast group addr %08x\n", (int)mcast);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
mockverbose("joined multicast group addr %08lx\n", (long)ntohl(mcast));
|
||||
}
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||
{
|
||||
fprintf(stderr, MOCK "can't join multicast group addr %08x\n", (int)mcast);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
mockverbose("joined multicast group addr %08lx\n", (long)ntohl(mcast));
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
size_t mockUDPFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize, uint8_t& addrsize, uint8_t addr[16], uint16_t& port)
|
||||
size_t mockUDPFillInBuf(int sock, char* ccinbuf, size_t& ccinbufsize, uint8_t& addrsize,
|
||||
uint8_t addr[16], uint16_t& port)
|
||||
{
|
||||
struct sockaddr_storage addrbuf;
|
||||
socklen_t addrbufsize = std::min((socklen_t)sizeof(addrbuf), (socklen_t)16);
|
||||
struct sockaddr_storage addrbuf;
|
||||
socklen_t addrbufsize = std::min((socklen_t)sizeof(addrbuf), (socklen_t)16);
|
||||
|
||||
size_t maxread = CCBUFSIZE - ccinbufsize;
|
||||
ssize_t ret = ::recvfrom(sock, ccinbuf + ccinbufsize, maxread, 0/*flags*/, (sockaddr*)&addrbuf, &addrbufsize);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
fprintf(stderr, MOCK "UDPContext::(read/peek): filling buffer for %zd bytes: %s\n", maxread, strerror(errno));
|
||||
ret = 0;
|
||||
}
|
||||
size_t maxread = CCBUFSIZE - ccinbufsize;
|
||||
ssize_t ret = ::recvfrom(sock, ccinbuf + ccinbufsize, maxread, 0 /*flags*/, (sockaddr*)&addrbuf,
|
||||
&addrbufsize);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
fprintf(stderr, MOCK "UDPContext::(read/peek): filling buffer for %zd bytes: %s\n",
|
||||
maxread, strerror(errno));
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
port = ntohs(((sockaddr_in*)&addrbuf)->sin_port);
|
||||
if (addrbuf.ss_family == AF_INET)
|
||||
memcpy(&addr[0], &(((sockaddr_in*)&addrbuf)->sin_addr.s_addr), addrsize = 4);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, MOCK "TODO UDP+IPv6\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (ret > 0)
|
||||
{
|
||||
port = ntohs(((sockaddr_in*)&addrbuf)->sin_port);
|
||||
if (addrbuf.ss_family == AF_INET)
|
||||
memcpy(&addr[0], &(((sockaddr_in*)&addrbuf)->sin_addr.s_addr), addrsize = 4);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, MOCK "TODO UDP+IPv6\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
return ccinbufsize += ret;
|
||||
return ccinbufsize += ret;
|
||||
}
|
||||
|
||||
size_t mockUDPPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf, size_t& ccinbufsize)
|
||||
size_t mockUDPPeekBytes(int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize)
|
||||
{
|
||||
(void) sock;
|
||||
(void) timeout_ms;
|
||||
if (usersize > CCBUFSIZE)
|
||||
fprintf(stderr, MOCK "CCBUFSIZE(%d) should be increased by %zd bytes (-> %zd)\n", CCBUFSIZE, usersize - CCBUFSIZE, usersize);
|
||||
(void)sock;
|
||||
(void)timeout_ms;
|
||||
if (usersize > CCBUFSIZE)
|
||||
fprintf(stderr, MOCK "CCBUFSIZE(%d) should be increased by %zd bytes (-> %zd)\n", CCBUFSIZE,
|
||||
usersize - CCBUFSIZE, usersize);
|
||||
|
||||
size_t retsize = 0;
|
||||
if (ccinbufsize)
|
||||
{
|
||||
// data already buffered
|
||||
retsize = usersize;
|
||||
if (retsize > ccinbufsize)
|
||||
retsize = ccinbufsize;
|
||||
}
|
||||
memcpy(dst, ccinbuf, retsize);
|
||||
return retsize;
|
||||
size_t retsize = 0;
|
||||
if (ccinbufsize)
|
||||
{
|
||||
// data already buffered
|
||||
retsize = usersize;
|
||||
if (retsize > ccinbufsize)
|
||||
retsize = ccinbufsize;
|
||||
}
|
||||
memcpy(dst, ccinbuf, retsize);
|
||||
return retsize;
|
||||
}
|
||||
|
||||
void mockUDPSwallow (size_t copied, char* ccinbuf, size_t& ccinbufsize)
|
||||
void mockUDPSwallow(size_t copied, char* ccinbuf, size_t& ccinbufsize)
|
||||
{
|
||||
// poor man buffer
|
||||
memmove(ccinbuf, ccinbuf + copied, ccinbufsize - copied);
|
||||
ccinbufsize -= copied;
|
||||
// poor man buffer
|
||||
memmove(ccinbuf, ccinbuf + copied, ccinbufsize - copied);
|
||||
ccinbufsize -= copied;
|
||||
}
|
||||
|
||||
size_t mockUDPRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize)
|
||||
size_t mockUDPRead(int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize)
|
||||
{
|
||||
size_t copied = mockUDPPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize);
|
||||
mockUDPSwallow(copied, ccinbuf, ccinbufsize);
|
||||
return copied;
|
||||
size_t copied = mockUDPPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize);
|
||||
mockUDPSwallow(copied, ccinbuf, ccinbufsize);
|
||||
return copied;
|
||||
}
|
||||
|
||||
size_t mockUDPWrite (int sock, const uint8_t* data, size_t size, int timeout_ms, uint32_t ipv4, uint16_t port)
|
||||
size_t mockUDPWrite(int sock, const uint8_t* data, size_t size, int timeout_ms, uint32_t ipv4,
|
||||
uint16_t port)
|
||||
{
|
||||
(void) timeout_ms;
|
||||
// Filling server information
|
||||
struct sockaddr_in peer;
|
||||
peer.sin_family = AF_INET;
|
||||
peer.sin_addr.s_addr = ipv4; //XXFIXME should use lwip_htonl?
|
||||
peer.sin_port = htons(port);
|
||||
int ret = ::sendto(sock, data, size, 0/*flags*/, (const sockaddr*)&peer, sizeof(peer));
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDPContext::write: write(%d): %s\n", sock, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (ret != (int)size)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDPContext::write: short write (%d < %zd) (TODO)\n", ret, size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
(void)timeout_ms;
|
||||
// Filling server information
|
||||
struct sockaddr_in peer;
|
||||
peer.sin_family = AF_INET;
|
||||
peer.sin_addr.s_addr = ipv4; // XXFIXME should use lwip_htonl?
|
||||
peer.sin_port = htons(port);
|
||||
int ret = ::sendto(sock, data, size, 0 /*flags*/, (const sockaddr*)&peer, sizeof(peer));
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDPContext::write: write(%d): %s\n", sock, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (ret != (int)size)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDPContext::write: short write (%d < %zd) (TODO)\n", ret, size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -4,59 +4,69 @@
|
||||
Part of the Wiring project - http://wiring.org.co
|
||||
Copyright (c) 2004-06 Hernando Barragan
|
||||
Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/
|
||||
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
}
|
||||
|
||||
void randomSeed(unsigned long seed) {
|
||||
if(seed != 0) {
|
||||
void randomSeed(unsigned long seed)
|
||||
{
|
||||
if (seed != 0)
|
||||
{
|
||||
srand(seed);
|
||||
}
|
||||
}
|
||||
|
||||
long random(long howbig) {
|
||||
if(howbig == 0) {
|
||||
long random(long howbig)
|
||||
{
|
||||
if (howbig == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (rand()) % howbig;
|
||||
}
|
||||
|
||||
long random(long howsmall, long howbig) {
|
||||
if(howsmall >= howbig) {
|
||||
long random(long howsmall, long howbig)
|
||||
{
|
||||
if (howsmall >= howbig)
|
||||
{
|
||||
return howsmall;
|
||||
}
|
||||
long diff = howbig - howsmall;
|
||||
return random(diff) + howsmall;
|
||||
}
|
||||
|
||||
long map(long x, long in_min, long in_max, long out_min, long out_max) {
|
||||
long map(long x, long in_min, long in_max, long out_min, long out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
uint16_t makeWord(unsigned int w) {
|
||||
uint16_t makeWord(unsigned int w)
|
||||
{
|
||||
return w;
|
||||
}
|
||||
|
||||
uint16_t makeWord(unsigned char h, unsigned char l) {
|
||||
uint16_t makeWord(unsigned char h, unsigned char l)
|
||||
{
|
||||
return (h << 8) | l;
|
||||
}
|
||||
|
||||
@@ -36,45 +36,46 @@
|
||||
#include <stdarg.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
typedef signed char sint8_t;
|
||||
typedef signed short sint16_t;
|
||||
typedef signed long sint32_t;
|
||||
typedef signed long long sint64_t;
|
||||
typedef signed char sint8_t;
|
||||
typedef signed short sint16_t;
|
||||
typedef signed long sint32_t;
|
||||
typedef signed long long sint64_t;
|
||||
// CONFLICT typedef unsigned long long u_int64_t;
|
||||
typedef float real32_t;
|
||||
typedef double real64_t;
|
||||
typedef float real32_t;
|
||||
typedef double real64_t;
|
||||
|
||||
// CONFLICT typedef unsigned char uint8;
|
||||
typedef unsigned char u8;
|
||||
typedef signed char sint8;
|
||||
typedef signed char int8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short sint16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned char u8;
|
||||
typedef signed char sint8;
|
||||
typedef signed char int8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short sint16;
|
||||
typedef signed short s16;
|
||||
// CONFLICT typedef unsigned int uint32;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int sint32;
|
||||
typedef signed int s32;
|
||||
typedef int int32;
|
||||
typedef signed long long sint64;
|
||||
typedef unsigned long long uint64;
|
||||
typedef unsigned long long u64;
|
||||
typedef float real32;
|
||||
typedef double real64;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int sint32;
|
||||
typedef signed int s32;
|
||||
typedef int int32;
|
||||
typedef signed long long sint64;
|
||||
typedef unsigned long long uint64;
|
||||
typedef unsigned long long u64;
|
||||
typedef float real32;
|
||||
typedef double real64;
|
||||
|
||||
#define __le16 u16
|
||||
#define __le16 u16
|
||||
|
||||
#define LOCAL static
|
||||
#define LOCAL static
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL (void *)0
|
||||
#define NULL (void*)0
|
||||
#endif /* NULL */
|
||||
|
||||
/* probably should not put STATUS here */
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
OK = 0,
|
||||
FAIL,
|
||||
PENDING,
|
||||
@@ -82,10 +83,10 @@ typedef enum {
|
||||
CANCEL,
|
||||
} STATUS;
|
||||
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
|
||||
#define REG_SET_BIT(_r, _b) (*(volatile uint32_t*)(_r) |= (_b))
|
||||
#define REG_CLR_BIT(_r, _b) (*(volatile uint32_t*)(_r) &= ~(_b))
|
||||
#define REG_SET_BIT(_r, _b) (*(volatile uint32_t*)(_r) |= (_b))
|
||||
#define REG_CLR_BIT(_r, _b) (*(volatile uint32_t*)(_r) &= ~(_b))
|
||||
|
||||
#define DMEM_ATTR __attribute__((section(".bss")))
|
||||
#define SHMEM_ATTR
|
||||
@@ -93,9 +94,15 @@ typedef enum {
|
||||
#ifdef ICACHE_FLASH
|
||||
#define __ICACHE_STRINGIZE_NX(A) #A
|
||||
#define __ICACHE_STRINGIZE(A) __ICACHE_STRINGIZE_NX(A)
|
||||
#define ICACHE_FLASH_ATTR __attribute__((section("\".irom0.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#define IRAM_ATTR __attribute__((section("\".iram.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#define ICACHE_RODATA_ATTR __attribute__((section("\".irom.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#define ICACHE_FLASH_ATTR \
|
||||
__attribute__((section("\".irom0.text." __FILE__ "." __ICACHE_STRINGIZE( \
|
||||
__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#define IRAM_ATTR \
|
||||
__attribute__((section("\".iram.text." __FILE__ "." __ICACHE_STRINGIZE( \
|
||||
__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#define ICACHE_RODATA_ATTR \
|
||||
__attribute__((section("\".irom.text." __FILE__ "." __ICACHE_STRINGIZE( \
|
||||
__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#else
|
||||
#define ICACHE_FLASH_ATTR
|
||||
#define IRAM_ATTR
|
||||
@@ -108,10 +115,9 @@ typedef enum {
|
||||
#define STORE_ATTR __attribute__((aligned(4)))
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define BOOL bool
|
||||
#define TRUE true
|
||||
#define FALSE false
|
||||
|
||||
#define BOOL bool
|
||||
#define TRUE true
|
||||
#define FALSE false
|
||||
|
||||
#endif /* !__cplusplus */
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#ifndef FAKE_ESP8266_PERI_H
|
||||
#define FAKE_ESP8266_PERI_H
|
||||
|
||||
const int GPI = 0;
|
||||
const int GPO = 0;
|
||||
const int GPI = 0;
|
||||
const int GPO = 0;
|
||||
const int GP16I = 0;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,17 +11,15 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern uint32_t s_phys_addr;
|
||||
extern uint32_t s_phys_size;
|
||||
extern uint32_t s_phys_page;
|
||||
extern uint32_t s_phys_block;
|
||||
extern uint8_t* s_phys_data;
|
||||
|
||||
extern uint32_t s_phys_addr;
|
||||
extern uint32_t s_phys_size;
|
||||
extern uint32_t s_phys_page;
|
||||
extern uint32_t s_phys_block;
|
||||
extern uint8_t* s_phys_data;
|
||||
|
||||
extern int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t *dst);
|
||||
extern int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t *src);
|
||||
extern int32_t flash_hal_erase(uint32_t addr, uint32_t size);
|
||||
|
||||
extern int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t* dst);
|
||||
extern int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t* src);
|
||||
extern int32_t flash_hal_erase(uint32_t addr, uint32_t size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,31 +7,35 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
uint32_t s_phys_addr = 0;
|
||||
uint32_t s_phys_size = 0;
|
||||
uint32_t s_phys_page = 0;
|
||||
uint32_t s_phys_addr = 0;
|
||||
uint32_t s_phys_size = 0;
|
||||
uint32_t s_phys_page = 0;
|
||||
uint32_t s_phys_block = 0;
|
||||
uint8_t* s_phys_data = nullptr;
|
||||
uint8_t* s_phys_data = nullptr;
|
||||
}
|
||||
|
||||
int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
|
||||
int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t* dst)
|
||||
{
|
||||
memcpy(dst, s_phys_data + addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t *src) {
|
||||
int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t* src)
|
||||
{
|
||||
memcpy(s_phys_data + addr, src, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t flash_hal_erase(uint32_t addr, uint32_t size) {
|
||||
if ((size & (FLASH_SECTOR_SIZE - 1)) != 0 ||
|
||||
(addr & (FLASH_SECTOR_SIZE - 1)) != 0) {
|
||||
int32_t flash_hal_erase(uint32_t addr, uint32_t size)
|
||||
{
|
||||
if ((size & (FLASH_SECTOR_SIZE - 1)) != 0 || (addr & (FLASH_SECTOR_SIZE - 1)) != 0)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
const uint32_t sector = addr / FLASH_SECTOR_SIZE;
|
||||
const uint32_t sector = addr / FLASH_SECTOR_SIZE;
|
||||
const uint32_t sectorCount = size / FLASH_SECTOR_SIZE;
|
||||
for (uint32_t i = 0; i < sectorCount; ++i) {
|
||||
for (uint32_t i = 0; i < sectorCount; ++i)
|
||||
{
|
||||
memset(s_phys_data + (sector + i) * FLASH_SECTOR_SIZE, 0xff, FLASH_SECTOR_SIZE);
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -26,7 +26,7 @@ class WiFiClient;
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
bool getDefaultPrivateGlobalSyncValue ();
|
||||
bool getDefaultPrivateGlobalSyncValue();
|
||||
|
||||
typedef void (*discard_cb_t)(void*, ClientContext*);
|
||||
|
||||
@@ -39,19 +39,19 @@ public:
|
||||
{
|
||||
(void)pcb;
|
||||
}
|
||||
|
||||
ClientContext (int sock) :
|
||||
|
||||
ClientContext(int sock) :
|
||||
_discard_cb(nullptr), _discard_cb_arg(nullptr), _refcnt(0), _next(nullptr),
|
||||
_sync(::getDefaultPrivateGlobalSyncValue()), _sock(sock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
err_t abort()
|
||||
{
|
||||
if (_sock >= 0)
|
||||
{
|
||||
::close(_sock);
|
||||
mockverbose("socket %d closed\n", _sock);
|
||||
mockverbose("socket %d closed\n", _sock);
|
||||
}
|
||||
_sock = -1;
|
||||
return ERR_ABRT;
|
||||
@@ -88,11 +88,12 @@ public:
|
||||
void unref()
|
||||
{
|
||||
DEBUGV(":ur %d\r\n", _refcnt);
|
||||
if(--_refcnt == 0) {
|
||||
if (--_refcnt == 0)
|
||||
{
|
||||
discard_received();
|
||||
close();
|
||||
if (_discard_cb)
|
||||
_discard_cb(_discard_cb_arg, this);
|
||||
_discard_cb(_discard_cb_arg, this);
|
||||
DEBUGV(":del\r\n");
|
||||
delete this;
|
||||
}
|
||||
@@ -172,10 +173,10 @@ public:
|
||||
int read()
|
||||
{
|
||||
char c;
|
||||
return read(&c, 1)? (unsigned char)c: -1;
|
||||
return read(&c, 1) ? (unsigned char)c : -1;
|
||||
}
|
||||
|
||||
size_t read (char* dst, size_t size)
|
||||
size_t read(char* dst, size_t size)
|
||||
{
|
||||
ssize_t ret = mockRead(_sock, dst, size, 0, _inbuf, _inbufsize);
|
||||
if (ret < 0)
|
||||
@@ -189,10 +190,10 @@ public:
|
||||
int peek()
|
||||
{
|
||||
char c;
|
||||
return peekBytes(&c, 1)? c: -1;
|
||||
return peekBytes(&c, 1) ? c : -1;
|
||||
}
|
||||
|
||||
size_t peekBytes(char *dst, size_t size)
|
||||
size_t peekBytes(char* dst, size_t size)
|
||||
{
|
||||
ssize_t ret = mockPeekBytes(_sock, dst, size, _timeout_ms, _inbuf, _inbufsize);
|
||||
if (ret < 0)
|
||||
@@ -216,60 +217,62 @@ public:
|
||||
|
||||
uint8_t state()
|
||||
{
|
||||
(void)getSize(); // read on socket to force detect closed peer
|
||||
return _sock >= 0? ESTABLISHED: CLOSED;
|
||||
(void)getSize(); // read on socket to force detect closed peer
|
||||
return _sock >= 0 ? ESTABLISHED : CLOSED;
|
||||
}
|
||||
|
||||
size_t write(const char* data, size_t size)
|
||||
{
|
||||
ssize_t ret = mockWrite(_sock, (const uint8_t*)data, size, _timeout_ms);
|
||||
if (ret < 0)
|
||||
{
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
ssize_t ret = mockWrite(_sock, (const uint8_t*)data, size, _timeout_ms);
|
||||
if (ret < 0)
|
||||
{
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT)
|
||||
void keepAlive(uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC,
|
||||
uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC,
|
||||
uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT)
|
||||
{
|
||||
(void) idle_sec;
|
||||
(void) intv_sec;
|
||||
(void) count;
|
||||
(void)idle_sec;
|
||||
(void)intv_sec;
|
||||
(void)count;
|
||||
mockverbose("TODO ClientContext::keepAlive()\n");
|
||||
}
|
||||
|
||||
bool isKeepAliveEnabled () const
|
||||
bool isKeepAliveEnabled() const
|
||||
{
|
||||
mockverbose("TODO ClientContext::isKeepAliveEnabled()\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t getKeepAliveIdle () const
|
||||
uint16_t getKeepAliveIdle() const
|
||||
{
|
||||
mockverbose("TODO ClientContext::getKeepAliveIdle()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t getKeepAliveInterval () const
|
||||
uint16_t getKeepAliveInterval() const
|
||||
{
|
||||
mockverbose("TODO ClientContext::getKeepAliveInternal()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t getKeepAliveCount () const
|
||||
uint8_t getKeepAliveCount() const
|
||||
{
|
||||
mockverbose("TODO ClientContext::getKeepAliveCount()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool getSync () const
|
||||
bool getSync() const
|
||||
{
|
||||
mockverbose("TODO ClientContext::getSync()\n");
|
||||
return _sync;
|
||||
}
|
||||
|
||||
void setSync (bool sync)
|
||||
void setSync(bool sync)
|
||||
{
|
||||
mockverbose("TODO ClientContext::setSync()\n");
|
||||
_sync = sync;
|
||||
@@ -277,13 +280,13 @@ public:
|
||||
|
||||
// return a pointer to available data buffer (size = peekAvailable())
|
||||
// semantic forbids any kind of read() before calling peekConsume()
|
||||
const char* peekBuffer ()
|
||||
const char* peekBuffer()
|
||||
{
|
||||
return _inbuf;
|
||||
}
|
||||
|
||||
// return number of byte accessible by peekBuffer()
|
||||
size_t peekAvailable ()
|
||||
size_t peekAvailable()
|
||||
{
|
||||
ssize_t ret = mockPeekBytes(_sock, nullptr, 0, 0, _inbuf, _inbufsize);
|
||||
if (ret < 0)
|
||||
@@ -295,7 +298,7 @@ public:
|
||||
}
|
||||
|
||||
// consume bytes after use (see peekBuffer)
|
||||
void peekConsume (size_t consume)
|
||||
void peekConsume(size_t consume)
|
||||
{
|
||||
assert(consume <= _inbufsize);
|
||||
memmove(_inbuf, _inbuf + consume, _inbufsize - consume);
|
||||
@@ -303,22 +306,21 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
discard_cb_t _discard_cb = nullptr;
|
||||
void* _discard_cb_arg = nullptr;
|
||||
|
||||
discard_cb_t _discard_cb = nullptr;
|
||||
void* _discard_cb_arg = nullptr;
|
||||
|
||||
int8_t _refcnt;
|
||||
int8_t _refcnt;
|
||||
ClientContext* _next;
|
||||
|
||||
|
||||
bool _sync;
|
||||
|
||||
|
||||
// MOCK
|
||||
|
||||
int _sock = -1;
|
||||
|
||||
int _sock = -1;
|
||||
int _timeout_ms = 5000;
|
||||
|
||||
char _inbuf [CCBUFSIZE];
|
||||
char _inbuf[CCBUFSIZE];
|
||||
size_t _inbufsize = 0;
|
||||
};
|
||||
|
||||
#endif //CLIENTCONTEXT_H
|
||||
#endif // CLIENTCONTEXT_H
|
||||
|
||||
@@ -37,17 +37,14 @@ extern netif netif0;
|
||||
class UdpContext
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::function<void(void)> rxhandler_t;
|
||||
|
||||
UdpContext(): _on_rx(nullptr), _refcnt(0)
|
||||
UdpContext() : _on_rx(nullptr), _refcnt(0)
|
||||
{
|
||||
_sock = mockUDPSocket();
|
||||
}
|
||||
|
||||
~UdpContext()
|
||||
{
|
||||
}
|
||||
~UdpContext() { }
|
||||
|
||||
void ref()
|
||||
{
|
||||
@@ -64,7 +61,7 @@ public:
|
||||
|
||||
bool connect(const ip_addr_t* addr, uint16_t port)
|
||||
{
|
||||
_dst = *addr;
|
||||
_dst = *addr;
|
||||
_dstport = port;
|
||||
return true;
|
||||
}
|
||||
@@ -103,7 +100,7 @@ public:
|
||||
void setMulticastTTL(int ttl)
|
||||
{
|
||||
(void)ttl;
|
||||
//mockverbose("TODO: UdpContext::setMulticastTTL\n");
|
||||
// mockverbose("TODO: UdpContext::setMulticastTTL\n");
|
||||
}
|
||||
|
||||
netif* getInputNetif() const
|
||||
@@ -156,13 +153,13 @@ public:
|
||||
IPAddress getDestAddress()
|
||||
{
|
||||
mockverbose("TODO: implement UDP getDestAddress\n");
|
||||
return 0; //ip_hdr* iphdr = GET_IP_HDR(_rx_buf);
|
||||
return 0; // ip_hdr* iphdr = GET_IP_HDR(_rx_buf);
|
||||
}
|
||||
|
||||
uint16_t getLocalPort()
|
||||
{
|
||||
mockverbose("TODO: implement UDP getLocalPort\n");
|
||||
return 0; //
|
||||
return 0; //
|
||||
}
|
||||
|
||||
bool next()
|
||||
@@ -191,14 +188,14 @@ public:
|
||||
int peek()
|
||||
{
|
||||
char c;
|
||||
return mockUDPPeekBytes(_sock, &c, 1, _timeout_ms, _inbuf, _inbufsize) ? : -1;
|
||||
return mockUDPPeekBytes(_sock, &c, 1, _timeout_ms, _inbuf, _inbufsize) ?: -1;
|
||||
}
|
||||
|
||||
void flush()
|
||||
{
|
||||
//mockverbose("UdpContext::flush() does not follow arduino's flush concept\n");
|
||||
//exit(EXIT_FAILURE);
|
||||
// would be:
|
||||
// mockverbose("UdpContext::flush() does not follow arduino's flush concept\n");
|
||||
// exit(EXIT_FAILURE);
|
||||
// would be:
|
||||
_inbufsize = 0;
|
||||
}
|
||||
|
||||
@@ -206,7 +203,8 @@ public:
|
||||
{
|
||||
if (size + _outbufsize > sizeof _outbuf)
|
||||
{
|
||||
mockverbose("UdpContext::append: increase CCBUFSIZE (%d -> %zd)\n", CCBUFSIZE, (size + _outbufsize));
|
||||
mockverbose("UdpContext::append: increase CCBUFSIZE (%d -> %zd)\n", CCBUFSIZE,
|
||||
(size + _outbufsize));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -217,9 +215,10 @@ public:
|
||||
|
||||
err_t trySend(ip_addr_t* addr = 0, uint16_t port = 0, bool keepBuffer = true)
|
||||
{
|
||||
uint32_t dst = addr ? addr->addr : _dst.addr;
|
||||
uint16_t dstport = port ? : _dstport;
|
||||
size_t wrt = mockUDPWrite(_sock, (const uint8_t*)_outbuf, _outbufsize, _timeout_ms, dst, dstport);
|
||||
uint32_t dst = addr ? addr->addr : _dst.addr;
|
||||
uint16_t dstport = port ?: _dstport;
|
||||
size_t wrt
|
||||
= mockUDPWrite(_sock, (const uint8_t*)_outbuf, _outbufsize, _timeout_ms, dst, dstport);
|
||||
err_t ret = _outbufsize ? ERR_OK : ERR_ABRT;
|
||||
if (!keepBuffer || wrt == _outbufsize)
|
||||
cancelBuffer();
|
||||
@@ -239,7 +238,7 @@ public:
|
||||
bool sendTimeout(ip_addr_t* addr, uint16_t port,
|
||||
esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
|
||||
{
|
||||
err_t err;
|
||||
err_t err;
|
||||
esp8266::polledTimeout::oneShotFastMs timeout(timeoutMs);
|
||||
while (((err = trySend(addr, port)) != ERR_OK) && !timeout)
|
||||
delay(0);
|
||||
@@ -250,15 +249,14 @@ public:
|
||||
|
||||
void mock_cb(void)
|
||||
{
|
||||
if (_on_rx) _on_rx();
|
||||
if (_on_rx)
|
||||
_on_rx();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static uint32_t staticMCastAddr;
|
||||
|
||||
private:
|
||||
|
||||
void translate_addr()
|
||||
{
|
||||
if (addrsize == 4)
|
||||
@@ -267,22 +265,22 @@ private:
|
||||
memcpy(&ipv4, addr, 4);
|
||||
ip4_addr_set_u32(&ip_2_ip4(_dst), ipv4);
|
||||
// ^ this is a workaround for "type-punned pointer" with "*(uint32*)addr"
|
||||
//ip4_addr_set_u32(&ip_2_ip4(_dst), *(uint32_t*)addr);
|
||||
// ip4_addr_set_u32(&ip_2_ip4(_dst), *(uint32_t*)addr);
|
||||
}
|
||||
else
|
||||
mockverbose("TODO unhandled udp address of size %d\n", (int)addrsize);
|
||||
}
|
||||
|
||||
int _sock = -1;
|
||||
int _sock = -1;
|
||||
rxhandler_t _on_rx;
|
||||
int _refcnt = 0;
|
||||
int _refcnt = 0;
|
||||
|
||||
ip_addr_t _dst;
|
||||
uint16_t _dstport;
|
||||
uint16_t _dstport;
|
||||
|
||||
char _inbuf [CCBUFSIZE];
|
||||
char _inbuf[CCBUFSIZE];
|
||||
size_t _inbufsize = 0;
|
||||
char _outbuf [CCBUFSIZE];
|
||||
char _outbuf[CCBUFSIZE];
|
||||
size_t _outbufsize = 0;
|
||||
|
||||
int _timeout_ms = 0;
|
||||
@@ -291,11 +289,11 @@ private:
|
||||
uint8_t addr[16];
|
||||
};
|
||||
|
||||
extern "C" inline err_t igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
|
||||
extern "C" inline err_t igmp_joingroup(const ip4_addr_t* ifaddr, const ip4_addr_t* groupaddr)
|
||||
{
|
||||
(void)ifaddr;
|
||||
UdpContext::staticMCastAddr = groupaddr->addr;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
#endif//UDPCONTEXT_H
|
||||
#endif // UDPCONTEXT_H
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
#include "littlefs_mock.h"
|
||||
#include "spiffs_mock.h"
|
||||
#include "spiffs/spiffs.h"
|
||||
@@ -56,7 +55,8 @@ LittleFSMock::LittleFSMock(ssize_t fs_size, size_t fs_block, size_t fs_page, con
|
||||
|
||||
void LittleFSMock::reset()
|
||||
{
|
||||
LittleFS = FS(FSImplPtr(new littlefs_impl::LittleFSImpl(0, s_phys_size, s_phys_page, s_phys_block, 5)));
|
||||
LittleFS = FS(
|
||||
FSImplPtr(new littlefs_impl::LittleFSImpl(0, s_phys_size, s_phys_page, s_phys_block, 5)));
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -72,47 +72,52 @@ LittleFSMock::~LittleFSMock()
|
||||
LittleFS = FS(FSImplPtr(nullptr));
|
||||
}
|
||||
|
||||
void LittleFSMock::load ()
|
||||
void LittleFSMock::load()
|
||||
{
|
||||
if (!m_fs.size() || !m_storage.length())
|
||||
return;
|
||||
|
||||
|
||||
int fs = ::open(m_storage.c_str(), O_RDONLY);
|
||||
if (fs == -1)
|
||||
{
|
||||
fprintf(stderr, "LittleFS: loading '%s': %s\n", m_storage.c_str(), strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
off_t flen = lseek(fs, 0, SEEK_END);
|
||||
if (flen == (off_t)-1)
|
||||
{
|
||||
fprintf(stderr, "LittleFS: checking size of '%s': %s\n", m_storage.c_str(), strerror(errno));
|
||||
fprintf(stderr, "LittleFS: checking size of '%s': %s\n", m_storage.c_str(),
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
lseek(fs, 0, SEEK_SET);
|
||||
|
||||
|
||||
if (flen != (off_t)m_fs.size())
|
||||
{
|
||||
fprintf(stderr, "LittleFS: size of '%s': %d does not match requested size %zd\n", m_storage.c_str(), (int)flen, m_fs.size());
|
||||
fprintf(stderr, "LittleFS: size of '%s': %d does not match requested size %zd\n",
|
||||
m_storage.c_str(), (int)flen, m_fs.size());
|
||||
if (!m_overwrite && flen > 0)
|
||||
{
|
||||
fprintf(stderr, "LittleFS: aborting at user request\n");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "LittleFS: continuing without loading at user request, '%s' will be overwritten\n", m_storage.c_str());
|
||||
fprintf(stderr,
|
||||
"LittleFS: continuing without loading at user request, '%s' will be overwritten\n",
|
||||
m_storage.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "LittleFS: loading %zi bytes from '%s'\n", m_fs.size(), m_storage.c_str());
|
||||
ssize_t r = ::read(fs, m_fs.data(), m_fs.size());
|
||||
if (r != (ssize_t)m_fs.size())
|
||||
fprintf(stderr, "LittleFS: reading %zi bytes: returned %zd: %s\n", m_fs.size(), r, strerror(errno));
|
||||
fprintf(stderr, "LittleFS: reading %zi bytes: returned %zd: %s\n", m_fs.size(), r,
|
||||
strerror(errno));
|
||||
}
|
||||
::close(fs);
|
||||
}
|
||||
|
||||
void LittleFSMock::save ()
|
||||
void LittleFSMock::save()
|
||||
{
|
||||
if (!m_fs.size() || !m_storage.length())
|
||||
return;
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
|
||||
Based on spiffs_mock:
|
||||
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.
|
||||
*/
|
||||
@@ -27,22 +27,25 @@
|
||||
|
||||
#define DEFAULT_LITTLEFS_FILE_NAME "littlefs.bin"
|
||||
|
||||
class LittleFSMock {
|
||||
class LittleFSMock
|
||||
{
|
||||
public:
|
||||
LittleFSMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const String& storage = emptyString);
|
||||
LittleFSMock(ssize_t fs_size, size_t fs_block, size_t fs_page,
|
||||
const String& storage = emptyString);
|
||||
void reset();
|
||||
~LittleFSMock();
|
||||
|
||||
|
||||
protected:
|
||||
void load ();
|
||||
void save ();
|
||||
void load();
|
||||
void save();
|
||||
|
||||
std::vector<uint8_t> m_fs;
|
||||
String m_storage;
|
||||
bool m_overwrite;
|
||||
String m_storage;
|
||||
bool m_overwrite;
|
||||
};
|
||||
|
||||
#define LITTLEFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) LittleFSMock littlefs_mock(size_kb * 1024, block_kb * 1024, page_b, storage)
|
||||
#define LITTLEFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) \
|
||||
LittleFSMock littlefs_mock(size_kb * 1024, block_kb * 1024, page_b, storage)
|
||||
#define LITTLEFS_MOCK_RESET() littlefs_mock.reset()
|
||||
|
||||
#endif /* littlefs_mock_hpp */
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
@@ -39,16 +39,15 @@
|
||||
#define EXP_FUNC extern
|
||||
#define STDCALL
|
||||
|
||||
#define MD5_SIZE 16
|
||||
#define MD5_SIZE 16
|
||||
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint32_t state[4]; /* state (ABCD) */
|
||||
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
uint8_t buffer[64]; /* input buffer */
|
||||
uint32_t state[4]; /* state (ABCD) */
|
||||
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
uint8_t buffer[64]; /* input buffer */
|
||||
} MD5_CTX;
|
||||
|
||||
|
||||
/* Constants for MD5Transform routine.
|
||||
*/
|
||||
#define S11 7
|
||||
@@ -70,15 +69,13 @@ typedef struct
|
||||
|
||||
/* ----- static functions ----- */
|
||||
static void MD5Transform(uint32_t state[4], const uint8_t block[64]);
|
||||
static void Encode(uint8_t *output, uint32_t *input, uint32_t len);
|
||||
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len);
|
||||
static void Encode(uint8_t* output, uint32_t* input, uint32_t len);
|
||||
static void Decode(uint32_t* output, const uint8_t* input, uint32_t len);
|
||||
|
||||
static const uint8_t PADDING[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const uint8_t PADDING[64]
|
||||
= { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
/* F, G, H and I are basic MD5 functions.
|
||||
*/
|
||||
@@ -88,35 +85,39 @@ static const uint8_t PADDING[64] =
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits. */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
Rotation is separate from addition to prevent recomputation. */
|
||||
#define FF(a, b, c, d, x, s, ac) { \
|
||||
(a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) { \
|
||||
(a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define FF(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += F((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += G((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += H((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += I((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5 initialization - begins an MD5 operation, writing a new ctx.
|
||||
*/
|
||||
EXP_FUNC void STDCALL MD5Init(MD5_CTX *ctx)
|
||||
EXP_FUNC void STDCALL MD5Init(MD5_CTX* ctx)
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
|
||||
@@ -131,10 +132,10 @@ EXP_FUNC void STDCALL MD5Init(MD5_CTX *ctx)
|
||||
/**
|
||||
* Accepts an array of octets as the next portion of the message.
|
||||
*/
|
||||
EXP_FUNC void STDCALL MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
|
||||
EXP_FUNC void STDCALL MD5Update(MD5_CTX* ctx, const uint8_t* msg, int len)
|
||||
{
|
||||
uint32_t x;
|
||||
int i, partLen;
|
||||
int i, partLen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
x = (uint32_t)((ctx->count[0] >> 3) & 0x3F);
|
||||
@@ -147,7 +148,7 @@ EXP_FUNC void STDCALL MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
|
||||
partLen = 64 - x;
|
||||
|
||||
/* Transform as many times as possible. */
|
||||
if (len >= partLen)
|
||||
if (len >= partLen)
|
||||
{
|
||||
memcpy(&ctx->buffer[x], msg, partLen);
|
||||
MD5Transform(ctx->state, ctx->buffer);
|
||||
@@ -161,15 +162,15 @@ EXP_FUNC void STDCALL MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
|
||||
i = 0;
|
||||
|
||||
/* Buffer remaining input */
|
||||
memcpy(&ctx->buffer[x], &msg[i], len-i);
|
||||
memcpy(&ctx->buffer[x], &msg[i], len - i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 128-bit message digest into the user's array
|
||||
*/
|
||||
EXP_FUNC void STDCALL MD5Final(uint8_t *digest, MD5_CTX *ctx)
|
||||
EXP_FUNC void STDCALL MD5Final(uint8_t* digest, MD5_CTX* ctx)
|
||||
{
|
||||
uint8_t bits[8];
|
||||
uint8_t bits[8];
|
||||
uint32_t x, padLen;
|
||||
|
||||
/* Save number of bits */
|
||||
@@ -177,7 +178,7 @@ EXP_FUNC void STDCALL MD5Final(uint8_t *digest, MD5_CTX *ctx)
|
||||
|
||||
/* Pad out to 56 mod 64.
|
||||
*/
|
||||
x = (uint32_t)((ctx->count[0] >> 3) & 0x3f);
|
||||
x = (uint32_t)((ctx->count[0] >> 3) & 0x3f);
|
||||
padLen = (x < 56) ? (56 - x) : (120 - x);
|
||||
MD5Update(ctx, PADDING, padLen);
|
||||
|
||||
@@ -193,82 +194,81 @@ EXP_FUNC void STDCALL MD5Final(uint8_t *digest, MD5_CTX *ctx)
|
||||
*/
|
||||
static void MD5Transform(uint32_t state[4], const uint8_t block[64])
|
||||
{
|
||||
uint32_t a = state[0], b = state[1], c = state[2],
|
||||
d = state[3], x[MD5_SIZE];
|
||||
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[MD5_SIZE];
|
||||
|
||||
Decode(x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
|
||||
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
|
||||
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
|
||||
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
|
||||
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
|
||||
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
|
||||
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
|
||||
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
|
||||
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
|
||||
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
|
||||
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
|
||||
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
|
||||
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
|
||||
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
|
||||
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
|
||||
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
|
||||
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
|
||||
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
|
||||
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
|
||||
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
|
||||
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
|
||||
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
|
||||
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
|
||||
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
|
||||
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
|
||||
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
|
||||
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
|
||||
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
|
||||
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
|
||||
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
|
||||
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
|
||||
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
|
||||
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
@@ -280,16 +280,16 @@ static void MD5Transform(uint32_t state[4], const uint8_t block[64])
|
||||
* Encodes input (uint32_t) into output (uint8_t). Assumes len is
|
||||
* a multiple of 4.
|
||||
*/
|
||||
static void Encode(uint8_t *output, uint32_t *input, uint32_t len)
|
||||
static void Encode(uint8_t* output, uint32_t* input, uint32_t len)
|
||||
{
|
||||
uint32_t i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
{
|
||||
output[j] = (uint8_t)(input[i] & 0xff);
|
||||
output[j+1] = (uint8_t)((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (uint8_t)((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (uint8_t)((input[i] >> 24) & 0xff);
|
||||
output[j] = (uint8_t)(input[i] & 0xff);
|
||||
output[j + 1] = (uint8_t)((input[i] >> 8) & 0xff);
|
||||
output[j + 2] = (uint8_t)((input[i] >> 16) & 0xff);
|
||||
output[j + 3] = (uint8_t)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,11 +297,11 @@ static void Encode(uint8_t *output, uint32_t *input, uint32_t len)
|
||||
* Decodes input (uint8_t) into output (uint32_t). Assumes len is
|
||||
* a multiple of 4.
|
||||
*/
|
||||
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len)
|
||||
static void Decode(uint32_t* output, const uint8_t* input, uint32_t len)
|
||||
{
|
||||
uint32_t i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
|
||||
(((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
|
||||
output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j + 1]) << 8)
|
||||
| (((uint32_t)input[j + 2]) << 16) | (((uint32_t)input[j + 3]) << 24);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
*/
|
||||
|
||||
#define CORE_MOCK 1
|
||||
#define MOCK "(mock) " // TODO: provide common logging API instead of adding this string everywhere?
|
||||
#define MOCK \
|
||||
"(mock) " // TODO: provide common logging API instead of adding this string everywhere?
|
||||
|
||||
//
|
||||
|
||||
@@ -57,15 +58,15 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
// TODO: #include <stdlib_noniso.h> ?
|
||||
char* itoa (int val, char *s, int radix);
|
||||
char* ltoa (long val, char *s, int radix);
|
||||
// TODO: #include <stdlib_noniso.h> ?
|
||||
char* itoa(int val, char* s, int radix);
|
||||
char* ltoa(long val, char* s, int radix);
|
||||
|
||||
|
||||
size_t strlcat(char *dst, const char *src, size_t size);
|
||||
size_t strlcpy(char *dst, const char *src, size_t size);
|
||||
size_t strlcat(char* dst, const char* src, size_t size);
|
||||
size_t strlcpy(char* dst, const char* src, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -74,7 +75,7 @@ size_t strlcpy(char *dst, const char *src, size_t size);
|
||||
// exotic typedefs used in the sdk
|
||||
|
||||
#include <stdint.h>
|
||||
typedef uint8_t uint8;
|
||||
typedef uint8_t uint8;
|
||||
typedef uint32_t uint32;
|
||||
|
||||
//
|
||||
@@ -97,26 +98,30 @@ uint32_t esp_get_cycle_count();
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include <osapi.h>
|
||||
int ets_printf (const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
int ets_printf(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
#define os_printf_plus printf
|
||||
#define ets_vsnprintf vsnprintf
|
||||
inline void ets_putc (char c) { putchar(c); }
|
||||
inline void ets_putc(char c)
|
||||
{
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
int mockverbose (const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
int mockverbose(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
extern const char* host_interface; // cmdline parameter
|
||||
extern bool serial_timestamp;
|
||||
extern int mock_port_shifter;
|
||||
extern bool blocking_uart;
|
||||
extern uint32_t global_source_address; // 0 = INADDR_ANY by default
|
||||
extern const char* host_interface; // cmdline parameter
|
||||
extern bool serial_timestamp;
|
||||
extern int mock_port_shifter;
|
||||
extern bool blocking_uart;
|
||||
extern uint32_t global_source_address; // 0 = INADDR_ANY by default
|
||||
|
||||
#define NO_GLOBAL_BINDING 0xffffffff
|
||||
extern uint32_t global_ipv4_netfmt; // selected interface addresse to bind to
|
||||
extern uint32_t global_ipv4_netfmt; // selected interface addresse to bind to
|
||||
|
||||
void loop_end();
|
||||
void loop_end();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -132,41 +137,48 @@ void loop_end();
|
||||
|
||||
// uart
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
void uart_new_data(const int uart_nr, uint8_t data);
|
||||
void uart_new_data(const int uart_nr, uint8_t data);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// tcp
|
||||
int mockSockSetup (int sock);
|
||||
int mockConnect (uint32_t addr, int& sock, int port);
|
||||
ssize_t mockFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize);
|
||||
ssize_t mockPeekBytes (int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize);
|
||||
ssize_t mockRead (int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize);
|
||||
ssize_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms);
|
||||
int serverAccept (int sock);
|
||||
int mockSockSetup(int sock);
|
||||
int mockConnect(uint32_t addr, int& sock, int port);
|
||||
ssize_t mockFillInBuf(int sock, char* ccinbuf, size_t& ccinbufsize);
|
||||
ssize_t mockPeekBytes(int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize);
|
||||
ssize_t mockRead(int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize);
|
||||
ssize_t mockWrite(int sock, const uint8_t* data, size_t size, int timeout_ms);
|
||||
int serverAccept(int sock);
|
||||
|
||||
// udp
|
||||
void check_incoming_udp ();
|
||||
int mockUDPSocket ();
|
||||
bool mockUDPListen (int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast = 0);
|
||||
size_t mockUDPFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize, uint8_t& addrsize, uint8_t addr[16], uint16_t& port);
|
||||
size_t mockUDPPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf, size_t& ccinbufsize);
|
||||
size_t mockUDPRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize);
|
||||
size_t mockUDPWrite (int sock, const uint8_t* data, size_t size, int timeout_ms, uint32_t ipv4, uint16_t port);
|
||||
void mockUDPSwallow (size_t copied, char* ccinbuf, size_t& ccinbufsize);
|
||||
void check_incoming_udp();
|
||||
int mockUDPSocket();
|
||||
bool mockUDPListen(int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast = 0);
|
||||
size_t mockUDPFillInBuf(int sock, char* ccinbuf, size_t& ccinbufsize, uint8_t& addrsize,
|
||||
uint8_t addr[16], uint16_t& port);
|
||||
size_t mockUDPPeekBytes(int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize);
|
||||
size_t mockUDPRead(int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize);
|
||||
size_t mockUDPWrite(int sock, const uint8_t* data, size_t size, int timeout_ms, uint32_t ipv4,
|
||||
uint16_t port);
|
||||
void mockUDPSwallow(size_t copied, char* ccinbuf, size_t& ccinbufsize);
|
||||
|
||||
class UdpContext;
|
||||
void register_udp (int sock, UdpContext* udp = nullptr);
|
||||
void register_udp(int sock, UdpContext* udp = nullptr);
|
||||
|
||||
//
|
||||
|
||||
void mock_start_spiffs (const String& fname, size_t size_kb, size_t block_kb = 8, size_t page_b = 512);
|
||||
void mock_stop_spiffs ();
|
||||
void mock_start_littlefs (const String& fname, size_t size_kb, size_t block_kb = 8, size_t page_b = 512);
|
||||
void mock_stop_littlefs ();
|
||||
void mock_start_spiffs(const String& fname, size_t size_kb, size_t block_kb = 8,
|
||||
size_t page_b = 512);
|
||||
void mock_stop_spiffs();
|
||||
void mock_start_littlefs(const String& fname, size_t size_kb, size_t block_kb = 8,
|
||||
size_t page_b = 512);
|
||||
void mock_stop_littlefs();
|
||||
|
||||
//
|
||||
|
||||
@@ -174,4 +186,4 @@ void mock_stop_littlefs ();
|
||||
|
||||
//
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __cplusplus
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
noniso.cpp - replacements for non-ISO functions used by Arduino core
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
@@ -21,61 +20,69 @@
|
||||
#include <math.h>
|
||||
#include "stdlib_noniso.h"
|
||||
|
||||
|
||||
void reverse(char* begin, char* end) {
|
||||
char *is = begin;
|
||||
char *ie = end - 1;
|
||||
while(is < ie) {
|
||||
void reverse(char* begin, char* end)
|
||||
{
|
||||
char* is = begin;
|
||||
char* ie = end - 1;
|
||||
while (is < ie)
|
||||
{
|
||||
char tmp = *ie;
|
||||
*ie = *is;
|
||||
*is = tmp;
|
||||
*ie = *is;
|
||||
*is = tmp;
|
||||
++is;
|
||||
--ie;
|
||||
}
|
||||
}
|
||||
|
||||
char* utoa(unsigned value, char* result, int base) {
|
||||
if(base < 2 || base > 16) {
|
||||
char* utoa(unsigned value, char* result, int base)
|
||||
{
|
||||
if (base < 2 || base > 16)
|
||||
{
|
||||
*result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
char* out = result;
|
||||
char* out = result;
|
||||
unsigned quotient = value;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
const unsigned tmp = quotient / base;
|
||||
*out = "0123456789abcdef"[quotient - (tmp * base)];
|
||||
*out = "0123456789abcdef"[quotient - (tmp * base)];
|
||||
++out;
|
||||
quotient = tmp;
|
||||
} while(quotient);
|
||||
} while (quotient);
|
||||
|
||||
reverse(result, out);
|
||||
*out = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
char* itoa(int value, char* result, int base) {
|
||||
if(base < 2 || base > 16) {
|
||||
char* itoa(int value, char* result, int base)
|
||||
{
|
||||
if (base < 2 || base > 16)
|
||||
{
|
||||
*result = 0;
|
||||
return result;
|
||||
}
|
||||
if (base != 10) {
|
||||
return utoa((unsigned)value, result, base);
|
||||
}
|
||||
if (base != 10)
|
||||
{
|
||||
return utoa((unsigned)value, result, base);
|
||||
}
|
||||
|
||||
char* out = result;
|
||||
int quotient = abs(value);
|
||||
char* out = result;
|
||||
int quotient = abs(value);
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
const int tmp = quotient / base;
|
||||
*out = "0123456789abcdef"[quotient - (tmp * base)];
|
||||
*out = "0123456789abcdef"[quotient - (tmp * base)];
|
||||
++out;
|
||||
quotient = tmp;
|
||||
} while(quotient);
|
||||
} while (quotient);
|
||||
|
||||
// Apply negative sign
|
||||
if(value < 0)
|
||||
if (value < 0)
|
||||
*out++ = '-';
|
||||
|
||||
reverse(result, out);
|
||||
@@ -83,17 +90,19 @@ char* itoa(int value, char* result, int base) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int atoi(const char* s) {
|
||||
return (int) atol(s);
|
||||
int atoi(const char* s)
|
||||
{
|
||||
return (int)atol(s);
|
||||
}
|
||||
|
||||
long atol(const char* s) {
|
||||
char * tmp;
|
||||
long atol(const char* s)
|
||||
{
|
||||
char* tmp;
|
||||
return strtol(s, &tmp, 10);
|
||||
}
|
||||
|
||||
double atof(const char* s) {
|
||||
char * tmp;
|
||||
double atof(const char* s)
|
||||
{
|
||||
char* tmp;
|
||||
return strtod(s, &tmp);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
pins_arduino.h
|
||||
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 pins_arduino_h
|
||||
#define pins_arduino_h
|
||||
|
||||
|
||||
#endif /* pins_arduino_h */
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
*/
|
||||
|
||||
#ifndef _SYS_QUEUE_H_
|
||||
#define _SYS_QUEUE_H_
|
||||
#define _SYS_QUEUE_H_
|
||||
|
||||
#include <machine/ansi.h> /* for __offsetof */
|
||||
#include <machine/ansi.h> /* for __offsetof */
|
||||
|
||||
/*
|
||||
* This file defines four types of data structures: singly-linked lists,
|
||||
@@ -106,322 +106,373 @@
|
||||
/*
|
||||
* Singly-linked List declarations.
|
||||
*/
|
||||
#define SLIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *slh_first; /* first element */ \
|
||||
}
|
||||
#define SLIST_HEAD(name, type) \
|
||||
struct name \
|
||||
{ \
|
||||
struct type* slh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL \
|
||||
}
|
||||
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* sle_next; /* next element */ \
|
||||
}
|
||||
|
||||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sle_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked List functions.
|
||||
*/
|
||||
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||
|
||||
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||
|
||||
#define SLIST_FOREACH(var, head, field) \
|
||||
for ((var) = SLIST_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = SLIST_NEXT((var), field))
|
||||
#define SLIST_FOREACH(var, head, field) \
|
||||
for ((var) = SLIST_FIRST((head)); (var); (var) = SLIST_NEXT((var), field))
|
||||
|
||||
#define SLIST_INIT(head) do { \
|
||||
SLIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
#define SLIST_INIT(head) \
|
||||
do \
|
||||
{ \
|
||||
SLIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
||||
SLIST_NEXT((slistelm), field) = (elm); \
|
||||
} while (0)
|
||||
#define SLIST_INSERT_AFTER(slistelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
||||
SLIST_NEXT((slistelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
||||
SLIST_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
#define SLIST_INSERT_HEAD(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
||||
SLIST_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
|
||||
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||
if (SLIST_FIRST((head)) == (elm)) { \
|
||||
SLIST_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = SLIST_FIRST((head)); \
|
||||
while (SLIST_NEXT(curelm, field) != (elm)) \
|
||||
curelm = SLIST_NEXT(curelm, field); \
|
||||
SLIST_NEXT(curelm, field) = \
|
||||
SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SLIST_REMOVE(head, elm, type, field) \
|
||||
do \
|
||||
{ \
|
||||
if (SLIST_FIRST((head)) == (elm)) \
|
||||
{ \
|
||||
SLIST_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
struct type* curelm = SLIST_FIRST((head)); \
|
||||
while (SLIST_NEXT(curelm, field) != (elm)) \
|
||||
curelm = SLIST_NEXT(curelm, field); \
|
||||
SLIST_NEXT(curelm, field) = SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
||||
} while (0)
|
||||
#define SLIST_REMOVE_HEAD(head, field) \
|
||||
do \
|
||||
{ \
|
||||
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue declarations.
|
||||
*/
|
||||
#define STAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *stqh_first;/* first element */ \
|
||||
struct type **stqh_last;/* addr of last next element */ \
|
||||
}
|
||||
#define STAILQ_HEAD(name, type) \
|
||||
struct name \
|
||||
{ \
|
||||
struct type* stqh_first; /* first element */ \
|
||||
struct type** stqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).stqh_first }
|
||||
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL, &(head).stqh_first \
|
||||
}
|
||||
|
||||
#define STAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *stqe_next; /* next element */ \
|
||||
}
|
||||
#define STAILQ_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* stqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue functions.
|
||||
*/
|
||||
#define STAILQ_CONCAT(head1, head2) do { \
|
||||
if (!STAILQ_EMPTY((head2))) { \
|
||||
*(head1)->stqh_last = (head2)->stqh_first; \
|
||||
(head1)->stqh_last = (head2)->stqh_last; \
|
||||
STAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (0)
|
||||
#define STAILQ_CONCAT(head1, head2) \
|
||||
do \
|
||||
{ \
|
||||
if (!STAILQ_EMPTY((head2))) \
|
||||
{ \
|
||||
*(head1)->stqh_last = (head2)->stqh_first; \
|
||||
(head1)->stqh_last = (head2)->stqh_last; \
|
||||
STAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
||||
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
||||
|
||||
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||
|
||||
#define STAILQ_FOREACH(var, head, field) \
|
||||
for((var) = STAILQ_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = STAILQ_NEXT((var), field))
|
||||
#define STAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = STAILQ_FIRST((head)); (var); (var) = STAILQ_NEXT((var), field))
|
||||
|
||||
#define STAILQ_INIT(head) do { \
|
||||
STAILQ_FIRST((head)) = NULL; \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
#define STAILQ_INIT(head) \
|
||||
do \
|
||||
{ \
|
||||
STAILQ_FIRST((head)) = NULL; \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_NEXT((tqelm), field) = (elm); \
|
||||
} while (0)
|
||||
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_NEXT((tqelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
#define STAILQ_INSERT_HEAD(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
STAILQ_NEXT((elm), field) = NULL; \
|
||||
*(head)->stqh_last = (elm); \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define STAILQ_INSERT_TAIL(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
STAILQ_NEXT((elm), field) = NULL; \
|
||||
*(head)->stqh_last = (elm); \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_LAST(head, type, field) \
|
||||
(STAILQ_EMPTY((head)) ? \
|
||||
NULL : \
|
||||
((struct type *) \
|
||||
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
|
||||
#define STAILQ_LAST(head, type, field) \
|
||||
(STAILQ_EMPTY((head)) \
|
||||
? NULL \
|
||||
: ((struct type*)((char*)((head)->stqh_last) - __offsetof(struct type, field))))
|
||||
|
||||
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||
|
||||
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
||||
if (STAILQ_FIRST((head)) == (elm)) { \
|
||||
STAILQ_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = STAILQ_FIRST((head)); \
|
||||
while (STAILQ_NEXT(curelm, field) != (elm)) \
|
||||
curelm = STAILQ_NEXT(curelm, field); \
|
||||
if ((STAILQ_NEXT(curelm, field) = \
|
||||
STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
|
||||
(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
|
||||
} \
|
||||
} while (0)
|
||||
#define STAILQ_REMOVE(head, elm, type, field) \
|
||||
do \
|
||||
{ \
|
||||
if (STAILQ_FIRST((head)) == (elm)) \
|
||||
{ \
|
||||
STAILQ_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
struct type* curelm = STAILQ_FIRST((head)); \
|
||||
while (STAILQ_NEXT(curelm, field) != (elm)) \
|
||||
curelm = STAILQ_NEXT(curelm, field); \
|
||||
if ((STAILQ_NEXT(curelm, field) = STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) \
|
||||
== NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((curelm), field); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
||||
if ((STAILQ_FIRST((head)) = \
|
||||
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
#define STAILQ_REMOVE_HEAD(head, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((STAILQ_FIRST((head)) = STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
|
||||
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* List declarations.
|
||||
*/
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *lh_first; /* first element */ \
|
||||
}
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name \
|
||||
{ \
|
||||
struct type* lh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL \
|
||||
}
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *le_next; /* next element */ \
|
||||
struct type **le_prev; /* address of previous next element */ \
|
||||
}
|
||||
#define LIST_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* le_next; /* next element */ \
|
||||
struct type** le_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* List functions.
|
||||
*/
|
||||
|
||||
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
|
||||
#define LIST_FIRST(head) ((head)->lh_first)
|
||||
#define LIST_FIRST(head) ((head)->lh_first)
|
||||
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = LIST_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = LIST_NEXT((var), field))
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = LIST_FIRST((head)); (var); (var) = LIST_NEXT((var), field))
|
||||
|
||||
#define LIST_INIT(head) do { \
|
||||
LIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
#define LIST_INIT(head) \
|
||||
do \
|
||||
{ \
|
||||
LIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
|
||||
LIST_NEXT((listelm), field)->field.le_prev = \
|
||||
&LIST_NEXT((elm), field); \
|
||||
LIST_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
#define LIST_INSERT_AFTER(listelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) \
|
||||
LIST_NEXT((listelm), field)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
LIST_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||
LIST_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.le_prev = (elm); \
|
||||
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define LIST_INSERT_BEFORE(listelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||
LIST_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.le_prev = (elm); \
|
||||
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
||||
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
|
||||
LIST_FIRST((head)) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
||||
} while (0)
|
||||
#define LIST_INSERT_HEAD(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
||||
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
LIST_FIRST((head)) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
|
||||
#define LIST_REMOVE(elm, field) do { \
|
||||
if (LIST_NEXT((elm), field) != NULL) \
|
||||
LIST_NEXT((elm), field)->field.le_prev = \
|
||||
(elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define LIST_REMOVE(elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if (LIST_NEXT((elm), field) != NULL) \
|
||||
LIST_NEXT((elm), field)->field.le_prev = (elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Tail queue declarations.
|
||||
*/
|
||||
#define TAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *tqh_first; /* first element */ \
|
||||
struct type **tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
#define TAILQ_HEAD(name, type) \
|
||||
struct name \
|
||||
{ \
|
||||
struct type* tqh_first; /* first element */ \
|
||||
struct type** tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).tqh_first }
|
||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL, &(head).tqh_first \
|
||||
}
|
||||
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *tqe_next; /* next element */ \
|
||||
struct type **tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* tqe_next; /* next element */ \
|
||||
struct type** tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#define TAILQ_CONCAT(head1, head2, field) do { \
|
||||
if (!TAILQ_EMPTY(head2)) { \
|
||||
*(head1)->tqh_last = (head2)->tqh_first; \
|
||||
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
|
||||
(head1)->tqh_last = (head2)->tqh_last; \
|
||||
TAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (0)
|
||||
#define TAILQ_CONCAT(head1, head2, field) \
|
||||
do \
|
||||
{ \
|
||||
if (!TAILQ_EMPTY(head2)) \
|
||||
{ \
|
||||
*(head1)->tqh_last = (head2)->tqh_first; \
|
||||
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
|
||||
(head1)->tqh_last = (head2)->tqh_last; \
|
||||
TAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = TAILQ_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = TAILQ_NEXT((var), field))
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = TAILQ_FIRST((head)); (var); (var) = TAILQ_NEXT((var), field))
|
||||
|
||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = TAILQ_LAST((head), headname); \
|
||||
(var); \
|
||||
(var) = TAILQ_PREV((var), headname, field))
|
||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = TAILQ_LAST((head), headname); (var); (var) = TAILQ_PREV((var), headname, field))
|
||||
|
||||
#define TAILQ_INIT(head) do { \
|
||||
TAILQ_FIRST((head)) = NULL; \
|
||||
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
#define TAILQ_INIT(head) \
|
||||
do \
|
||||
{ \
|
||||
TAILQ_FIRST((head)) = NULL; \
|
||||
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||
&TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL) \
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
TAILQ_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
TAILQ_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
||||
TAILQ_FIRST((head))->field.tqe_prev = \
|
||||
&TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_FIRST((head)) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
||||
TAILQ_FIRST((head))->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_FIRST((head)) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
TAILQ_NEXT((elm), field) = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
TAILQ_NEXT((elm), field) = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
#define TAILQ_LAST(head, headname) (*(((struct headname*)((head)->tqh_last))->tqh_last))
|
||||
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#define TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define TAILQ_PREV(elm, headname, field) (*(((struct headname*)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = (elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
@@ -430,39 +481,37 @@ struct { \
|
||||
* They bogusly assumes that all queue heads look alike.
|
||||
*/
|
||||
|
||||
struct quehead {
|
||||
struct quehead *qh_link;
|
||||
struct quehead *qh_rlink;
|
||||
struct quehead
|
||||
{
|
||||
struct quehead* qh_link;
|
||||
struct quehead* qh_rlink;
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef __GNUC__
|
||||
|
||||
static __inline void
|
||||
insque(void *a, void *b)
|
||||
static __inline void insque(void* a, void* b)
|
||||
{
|
||||
struct quehead *element = (struct quehead *)a,
|
||||
*head = (struct quehead *)b;
|
||||
struct quehead *element = (struct quehead*)a, *head = (struct quehead*)b;
|
||||
|
||||
element->qh_link = head->qh_link;
|
||||
element->qh_rlink = head;
|
||||
head->qh_link = element;
|
||||
element->qh_link->qh_rlink = element;
|
||||
element->qh_link = head->qh_link;
|
||||
element->qh_rlink = head;
|
||||
head->qh_link = element;
|
||||
element->qh_link->qh_rlink = element;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
remque(void *a)
|
||||
static __inline void remque(void* a)
|
||||
{
|
||||
struct quehead *element = (struct quehead *)a;
|
||||
struct quehead* element = (struct quehead*)a;
|
||||
|
||||
element->qh_link->qh_rlink = element->qh_rlink;
|
||||
element->qh_rlink->qh_link = element->qh_link;
|
||||
element->qh_rlink = 0;
|
||||
element->qh_link->qh_rlink = element->qh_rlink;
|
||||
element->qh_rlink->qh_link = element->qh_link;
|
||||
element->qh_rlink = 0;
|
||||
}
|
||||
|
||||
#else /* !__GNUC__ */
|
||||
|
||||
void insque(void *a, void *b);
|
||||
void remque(void *a);
|
||||
void insque(void* a, void* b);
|
||||
void remque(void* a);
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
|
||||
#define SDSIZE 16LL
|
||||
uint64_t _sdCardSizeB = 0;
|
||||
uint8_t *_sdCard = nullptr;
|
||||
uint8_t* _sdCard = nullptr;
|
||||
|
||||
@@ -21,22 +21,32 @@
|
||||
#include <vector>
|
||||
#include <FS.h>
|
||||
|
||||
class SDFSMock {
|
||||
class SDFSMock
|
||||
{
|
||||
public:
|
||||
SDFSMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const String& storage = emptyString) { (void)fs_size; (void)fs_block; (void)fs_page; (void)storage; }
|
||||
SDFSMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const String& storage = emptyString)
|
||||
{
|
||||
(void)fs_size;
|
||||
(void)fs_block;
|
||||
(void)fs_page;
|
||||
(void)storage;
|
||||
}
|
||||
void reset() { }
|
||||
~SDFSMock() { }
|
||||
};
|
||||
|
||||
extern uint64_t _sdCardSizeB;
|
||||
extern uint8_t *_sdCard;
|
||||
extern uint8_t* _sdCard;
|
||||
|
||||
#define SDFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) \
|
||||
SDFS.end(); \
|
||||
SDFSMock sdfs_mock(size_kb * 1024, block_kb * 1024, page_b, storage); free(_sdCard); \
|
||||
_sdCardSizeB = size_kb ? 16 * 1024 * 1024 : 0; \
|
||||
if (_sdCardSizeB) _sdCard = (uint8_t*)calloc(_sdCardSizeB, 1); \
|
||||
else _sdCard = nullptr; \
|
||||
#define SDFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) \
|
||||
SDFS.end(); \
|
||||
SDFSMock sdfs_mock(size_kb * 1024, block_kb * 1024, page_b, storage); \
|
||||
free(_sdCard); \
|
||||
_sdCardSizeB = size_kb ? 16 * 1024 * 1024 : 0; \
|
||||
if (_sdCardSizeB) \
|
||||
_sdCard = (uint8_t*)calloc(_sdCardSizeB, 1); \
|
||||
else \
|
||||
_sdCard = nullptr; \
|
||||
SDFS.setConfig(SDFSConfig().setAutoFormat(true));
|
||||
#define SDFS_MOCK_RESET() sdfs_mock.reset()
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
#include "spiffs_mock.h"
|
||||
#include "spiffs/spiffs.h"
|
||||
#include "debug.h"
|
||||
@@ -54,7 +53,8 @@ SpiffsMock::SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const S
|
||||
|
||||
void SpiffsMock::reset()
|
||||
{
|
||||
SPIFFS = FS(FSImplPtr(new spiffs_impl::SPIFFSImpl(0, s_phys_size, s_phys_page, s_phys_block, 5)));
|
||||
SPIFFS
|
||||
= FS(FSImplPtr(new spiffs_impl::SPIFFSImpl(0, s_phys_size, s_phys_page, s_phys_block, 5)));
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -70,18 +70,18 @@ SpiffsMock::~SpiffsMock()
|
||||
SPIFFS = FS(FSImplPtr(nullptr));
|
||||
}
|
||||
|
||||
void SpiffsMock::load ()
|
||||
void SpiffsMock::load()
|
||||
{
|
||||
if (!m_fs.size() || !m_storage.length())
|
||||
return;
|
||||
|
||||
|
||||
int fs = ::open(m_storage.c_str(), O_RDONLY);
|
||||
if (fs == -1)
|
||||
{
|
||||
fprintf(stderr, "SPIFFS: loading '%s': %s\n", m_storage.c_str(), strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
off_t flen = lseek(fs, 0, SEEK_END);
|
||||
if (flen == (off_t)-1)
|
||||
{
|
||||
@@ -89,28 +89,32 @@ void SpiffsMock::load ()
|
||||
return;
|
||||
}
|
||||
lseek(fs, 0, SEEK_SET);
|
||||
|
||||
|
||||
if (flen != (off_t)m_fs.size())
|
||||
{
|
||||
fprintf(stderr, "SPIFFS: size of '%s': %d does not match requested size %zd\n", m_storage.c_str(), (int)flen, m_fs.size());
|
||||
fprintf(stderr, "SPIFFS: size of '%s': %d does not match requested size %zd\n",
|
||||
m_storage.c_str(), (int)flen, m_fs.size());
|
||||
if (!m_overwrite && flen > 0)
|
||||
{
|
||||
fprintf(stderr, "SPIFFS: aborting at user request\n");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "SPIFFS: continuing without loading at user request, '%s' will be overwritten\n", m_storage.c_str());
|
||||
fprintf(stderr,
|
||||
"SPIFFS: continuing without loading at user request, '%s' will be overwritten\n",
|
||||
m_storage.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "SPIFFS: loading %zi bytes from '%s'\n", m_fs.size(), m_storage.c_str());
|
||||
ssize_t r = ::read(fs, m_fs.data(), m_fs.size());
|
||||
if (r != (ssize_t)m_fs.size())
|
||||
fprintf(stderr, "SPIFFS: reading %zi bytes: returned %zd: %s\n", m_fs.size(), r, strerror(errno));
|
||||
fprintf(stderr, "SPIFFS: reading %zi bytes: returned %zd: %s\n", m_fs.size(), r,
|
||||
strerror(errno));
|
||||
}
|
||||
::close(fs);
|
||||
}
|
||||
|
||||
void SpiffsMock::save ()
|
||||
void SpiffsMock::save()
|
||||
{
|
||||
if (!m_fs.size() || !m_storage.length())
|
||||
return;
|
||||
@@ -130,4 +134,3 @@ void SpiffsMock::save ()
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
spiffs_mock.h - SPIFFS HAL mock for host side testing
|
||||
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.
|
||||
*/
|
||||
@@ -24,22 +24,25 @@
|
||||
|
||||
#define DEFAULT_SPIFFS_FILE_NAME "spiffs.bin"
|
||||
|
||||
class SpiffsMock {
|
||||
class SpiffsMock
|
||||
{
|
||||
public:
|
||||
SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const String& storage = emptyString);
|
||||
SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page,
|
||||
const String& storage = emptyString);
|
||||
void reset();
|
||||
~SpiffsMock();
|
||||
|
||||
|
||||
protected:
|
||||
void load ();
|
||||
void save ();
|
||||
void load();
|
||||
void save();
|
||||
|
||||
std::vector<uint8_t> m_fs;
|
||||
String m_storage;
|
||||
bool m_overwrite;
|
||||
String m_storage;
|
||||
bool m_overwrite;
|
||||
};
|
||||
|
||||
#define SPIFFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) SpiffsMock spiffs_mock(size_kb * 1024, block_kb * 1024, page_b, storage)
|
||||
#define SPIFFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) \
|
||||
SpiffsMock spiffs_mock(size_kb * 1024, block_kb * 1024, page_b, storage)
|
||||
#define SPIFFS_MOCK_RESET() spiffs_mock.reset()
|
||||
|
||||
#endif /* spiffs_mock_hpp */
|
||||
|
||||
@@ -5,25 +5,24 @@
|
||||
'_cups_strlcat()' - Safely concatenate two strings.
|
||||
*/
|
||||
|
||||
size_t /* O - Length of string */
|
||||
strlcat(char *dst, /* O - Destination string */
|
||||
const char *src, /* I - Source string */
|
||||
size_t size) /* I - Size of destination string buffer */
|
||||
size_t /* O - Length of string */
|
||||
strlcat(char* dst, /* O - Destination string */
|
||||
const char* src, /* I - Source string */
|
||||
size_t size) /* I - Size of destination string buffer */
|
||||
{
|
||||
size_t srclen; /* Length of source string */
|
||||
size_t dstlen; /* Length of destination string */
|
||||
|
||||
size_t srclen; /* Length of source string */
|
||||
size_t dstlen; /* Length of destination string */
|
||||
|
||||
/*
|
||||
Figure out how much room is left...
|
||||
*/
|
||||
|
||||
dstlen = strlen(dst);
|
||||
size -= dstlen + 1;
|
||||
size -= dstlen + 1;
|
||||
|
||||
if (!size)
|
||||
{
|
||||
return (dstlen); /* No room, return immediately... */
|
||||
return (dstlen); /* No room, return immediately... */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -53,19 +52,18 @@ strlcat(char *dst, /* O - Destination string */
|
||||
'_cups_strlcpy()' - Safely copy two strings.
|
||||
*/
|
||||
|
||||
size_t /* O - Length of string */
|
||||
strlcpy(char *dst, /* O - Destination string */
|
||||
const char *src, /* I - Source string */
|
||||
size_t /* O - Length of string */
|
||||
strlcpy(char* dst, /* O - Destination string */
|
||||
const char* src, /* I - Source string */
|
||||
size_t size) /* I - Size of destination string buffer */
|
||||
{
|
||||
size_t srclen; /* Length of source string */
|
||||
|
||||
size_t srclen; /* Length of source string */
|
||||
|
||||
/*
|
||||
Figure out how much room is needed...
|
||||
*/
|
||||
|
||||
size --;
|
||||
size--;
|
||||
|
||||
srclen = strlen(src);
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
#include <LwipDhcpServer.h>
|
||||
|
||||
bool DhcpServer::set_dhcps_lease(struct dhcps_lease *please)
|
||||
bool DhcpServer::set_dhcps_lease(struct dhcps_lease* please)
|
||||
{
|
||||
(void)please;
|
||||
return false;
|
||||
@@ -62,22 +62,20 @@ bool DhcpServer::set_dhcps_offer_option(uint8 level, void* optarg)
|
||||
return false;
|
||||
}
|
||||
|
||||
void DhcpServer::end ()
|
||||
{
|
||||
}
|
||||
void DhcpServer::end() { }
|
||||
|
||||
bool DhcpServer::begin (struct ip_info *info)
|
||||
bool DhcpServer::begin(struct ip_info* info)
|
||||
{
|
||||
(void)info;
|
||||
return false;
|
||||
}
|
||||
|
||||
DhcpServer::DhcpServer (netif* netif)
|
||||
DhcpServer::DhcpServer(netif* netif)
|
||||
{
|
||||
(void)netif;
|
||||
}
|
||||
|
||||
DhcpServer::~DhcpServer ()
|
||||
DhcpServer::~DhcpServer()
|
||||
{
|
||||
end();
|
||||
}
|
||||
@@ -86,7 +84,6 @@ DhcpServer dhcpSoftAP(nullptr);
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#include <user_interface.h>
|
||||
#include <lwip/netif.h>
|
||||
|
||||
@@ -120,14 +117,14 @@ extern "C"
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool wifi_station_get_config(struct station_config *config)
|
||||
bool wifi_station_get_config(struct station_config* config)
|
||||
{
|
||||
strcpy((char*)config->ssid, "emulated-ssid");
|
||||
strcpy((char*)config->password, "emulated-ssid-password");
|
||||
config->bssid_set = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
config->bssid[i] = i;
|
||||
config->threshold.rssi = 1;
|
||||
config->threshold.rssi = 1;
|
||||
config->threshold.authmode = AUTH_WPA_PSK;
|
||||
#ifdef NONOSDK3V0
|
||||
config->open_and_wep_mode_disable = true;
|
||||
@@ -135,9 +132,7 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
void wifi_fpm_close(void)
|
||||
{
|
||||
}
|
||||
void wifi_fpm_close(void) { }
|
||||
|
||||
sint8 wifi_fpm_do_sleep(uint32 sleep_time_in_us)
|
||||
{
|
||||
@@ -145,34 +140,30 @@ extern "C"
|
||||
return 1;
|
||||
}
|
||||
|
||||
void wifi_fpm_do_wakeup(void)
|
||||
{
|
||||
}
|
||||
void wifi_fpm_do_wakeup(void) { }
|
||||
|
||||
void wifi_fpm_open(void)
|
||||
{
|
||||
}
|
||||
void wifi_fpm_open(void) { }
|
||||
|
||||
void wifi_fpm_set_sleep_type(sleep_type_t type)
|
||||
{
|
||||
(void)type;
|
||||
}
|
||||
|
||||
uint32_t global_ipv4_netfmt = 0; // global binding
|
||||
uint32_t global_ipv4_netfmt = 0; // global binding
|
||||
|
||||
netif netif0;
|
||||
netif netif0;
|
||||
uint32_t global_source_address = INADDR_ANY;
|
||||
|
||||
bool wifi_get_ip_info(uint8 if_index, struct ip_info *info)
|
||||
bool wifi_get_ip_info(uint8 if_index, struct ip_info* info)
|
||||
{
|
||||
// emulate wifi_get_ip_info()
|
||||
// ignore if_index
|
||||
// use global option -i (host_interface) to select bound interface/address
|
||||
|
||||
struct ifaddrs * ifAddrStruct = NULL, * ifa = NULL;
|
||||
uint32_t ipv4 = lwip_htonl(0x7f000001);
|
||||
uint32_t mask = lwip_htonl(0xff000000);
|
||||
global_source_address = INADDR_ANY; // =0
|
||||
struct ifaddrs *ifAddrStruct = NULL, *ifa = NULL;
|
||||
uint32_t ipv4 = lwip_htonl(0x7f000001);
|
||||
uint32_t mask = lwip_htonl(0xff000000);
|
||||
global_source_address = INADDR_ANY; // =0
|
||||
|
||||
if (getifaddrs(&ifAddrStruct) != 0)
|
||||
{
|
||||
@@ -186,22 +177,24 @@ extern "C"
|
||||
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
|
||||
{
|
||||
mockverbose("host: interface: %s", ifa->ifa_name);
|
||||
if (ifa->ifa_addr
|
||||
&& ifa->ifa_addr->sa_family == AF_INET // ip_info is IPv4 only
|
||||
)
|
||||
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET // ip_info is IPv4 only
|
||||
)
|
||||
{
|
||||
auto test_ipv4 = lwip_ntohl(*(uint32_t*) & ((struct sockaddr_in*)ifa->ifa_addr)->sin_addr);
|
||||
auto test_ipv4
|
||||
= lwip_ntohl(*(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr);
|
||||
mockverbose(" IPV4 (0x%08lx)", test_ipv4);
|
||||
if ((test_ipv4 & 0xff000000) == 0x7f000000)
|
||||
// 127./8
|
||||
mockverbose(" (local, ignored)");
|
||||
else
|
||||
{
|
||||
if (!host_interface || (host_interface && strcmp(ifa->ifa_name, host_interface) == 0))
|
||||
if (!host_interface
|
||||
|| (host_interface && strcmp(ifa->ifa_name, host_interface) == 0))
|
||||
{
|
||||
// use the first non-local interface, or, if specified, the one selected by user on cmdline
|
||||
ipv4 = *(uint32_t*) & ((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
|
||||
mask = *(uint32_t*) & ((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
|
||||
// use the first non-local interface, or, if specified, the one selected by
|
||||
// user on cmdline
|
||||
ipv4 = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
|
||||
mask = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
|
||||
mockverbose(" (selected)\n");
|
||||
if (host_interface)
|
||||
global_source_address = ntohl(ipv4);
|
||||
@@ -216,7 +209,7 @@ extern "C"
|
||||
freeifaddrs(ifAddrStruct);
|
||||
|
||||
(void)if_index;
|
||||
//if (if_index != STATION_IF)
|
||||
// if (if_index != STATION_IF)
|
||||
// fprintf(stderr, "we are not AP");
|
||||
|
||||
if (global_ipv4_netfmt == NO_GLOBAL_BINDING)
|
||||
@@ -224,15 +217,15 @@ extern "C"
|
||||
|
||||
if (info)
|
||||
{
|
||||
info->ip.addr = ipv4;
|
||||
info->ip.addr = ipv4;
|
||||
info->netmask.addr = mask;
|
||||
info->gw.addr = ipv4;
|
||||
info->gw.addr = ipv4;
|
||||
|
||||
netif0.ip_addr.addr = ipv4;
|
||||
netif0.netmask.addr = mask;
|
||||
netif0.gw.addr = ipv4;
|
||||
netif0.flags = NETIF_FLAG_IGMP | NETIF_FLAG_UP | NETIF_FLAG_LINK_UP;
|
||||
netif0.next = nullptr;
|
||||
netif0.gw.addr = ipv4;
|
||||
netif0.flags = NETIF_FLAG_IGMP | NETIF_FLAG_UP | NETIF_FLAG_LINK_UP;
|
||||
netif0.next = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -243,7 +236,7 @@ extern "C"
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool wifi_get_macaddr(uint8 if_index, uint8 *macaddr)
|
||||
bool wifi_get_macaddr(uint8 if_index, uint8* macaddr)
|
||||
{
|
||||
(void)if_index;
|
||||
macaddr[0] = 0xde;
|
||||
@@ -267,7 +260,7 @@ extern "C"
|
||||
return MIN_SLEEP_T;
|
||||
}
|
||||
|
||||
#endif // nonos-sdk-pre-3
|
||||
#endif // nonos-sdk-pre-3
|
||||
|
||||
sleep_type_t wifi_get_sleep_type(void)
|
||||
{
|
||||
@@ -281,13 +274,13 @@ extern "C"
|
||||
}
|
||||
|
||||
wifi_event_handler_cb_t wifi_event_handler_cb_emu = nullptr;
|
||||
void wifi_set_event_handler_cb(wifi_event_handler_cb_t cb)
|
||||
void wifi_set_event_handler_cb(wifi_event_handler_cb_t cb)
|
||||
{
|
||||
wifi_event_handler_cb_emu = cb;
|
||||
mockverbose("TODO: wifi_set_event_handler_cb set\n");
|
||||
}
|
||||
|
||||
bool wifi_set_ip_info(uint8 if_index, struct ip_info *info)
|
||||
bool wifi_set_ip_info(uint8 if_index, struct ip_info* info)
|
||||
{
|
||||
(void)if_index;
|
||||
(void)info;
|
||||
@@ -352,12 +345,12 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_station_get_config_default(struct station_config *config)
|
||||
bool wifi_station_get_config_default(struct station_config* config)
|
||||
{
|
||||
return wifi_station_get_config(config);
|
||||
}
|
||||
|
||||
char wifi_station_get_hostname_str [128];
|
||||
char wifi_station_get_hostname_str[128];
|
||||
const char* wifi_station_get_hostname(void)
|
||||
{
|
||||
return strcpy(wifi_station_get_hostname_str, "esposix");
|
||||
@@ -378,19 +371,19 @@ extern "C"
|
||||
return set != 0;
|
||||
}
|
||||
|
||||
bool wifi_station_set_config(struct station_config *config)
|
||||
bool wifi_station_set_config(struct station_config* config)
|
||||
{
|
||||
(void)config;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_station_set_config_current(struct station_config *config)
|
||||
bool wifi_station_set_config_current(struct station_config* config)
|
||||
{
|
||||
(void)config;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_station_set_hostname(const char *name)
|
||||
bool wifi_station_set_hostname(const char* name)
|
||||
{
|
||||
(void)name;
|
||||
return true;
|
||||
@@ -422,20 +415,20 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_softap_get_config(struct softap_config *config)
|
||||
bool wifi_softap_get_config(struct softap_config* config)
|
||||
{
|
||||
strcpy((char*)config->ssid, "apssid");
|
||||
strcpy((char*)config->password, "appasswd");
|
||||
config->ssid_len = strlen("appasswd");
|
||||
config->channel = 1;
|
||||
config->authmode = AUTH_WPA2_PSK;
|
||||
config->ssid_hidden = 0;
|
||||
config->max_connection = 4;
|
||||
config->ssid_len = strlen("appasswd");
|
||||
config->channel = 1;
|
||||
config->authmode = AUTH_WPA2_PSK;
|
||||
config->ssid_hidden = 0;
|
||||
config->max_connection = 4;
|
||||
config->beacon_interval = 100;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_softap_get_config_default(struct softap_config *config)
|
||||
bool wifi_softap_get_config_default(struct softap_config* config)
|
||||
{
|
||||
return wifi_softap_get_config(config);
|
||||
}
|
||||
@@ -445,19 +438,19 @@ extern "C"
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool wifi_softap_set_config(struct softap_config *config)
|
||||
bool wifi_softap_set_config(struct softap_config* config)
|
||||
{
|
||||
(void)config;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_softap_set_config_current(struct softap_config *config)
|
||||
bool wifi_softap_set_config_current(struct softap_config* config)
|
||||
{
|
||||
(void)config;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please)
|
||||
bool wifi_softap_set_dhcps_lease(struct dhcps_lease* please)
|
||||
{
|
||||
(void)please;
|
||||
return true;
|
||||
@@ -476,7 +469,7 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_station_scan(struct scan_config *config, scan_done_cb_t cb)
|
||||
bool wifi_station_scan(struct scan_config* config, scan_done_cb_t cb)
|
||||
{
|
||||
(void)config;
|
||||
cb(nullptr, FAIL);
|
||||
@@ -498,7 +491,7 @@ extern "C"
|
||||
(void)intr;
|
||||
}
|
||||
|
||||
void dns_setserver(u8_t numdns, ip_addr_t *dnsserver)
|
||||
void dns_setserver(u8_t numdns, ip_addr_t* dnsserver)
|
||||
{
|
||||
(void)numdns;
|
||||
(void)dnsserver;
|
||||
@@ -511,11 +504,10 @@ extern "C"
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
#include <smartconfig.h>
|
||||
bool smartconfig_start(sc_callback_t cb, ...)
|
||||
{
|
||||
//XXXFIXME ... -> ptr
|
||||
// XXXFIXME ... -> ptr
|
||||
cb(SC_STATUS_LINK, NULL);
|
||||
return true;
|
||||
}
|
||||
@@ -530,4 +522,4 @@ extern "C"
|
||||
return NONE_SLEEP_T;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
|
||||
@@ -2,245 +2,239 @@
|
||||
#include "PolledTimeout.h"
|
||||
|
||||
#define mockverbose printf
|
||||
#include "common/MockEsp.cpp" // getCycleCount
|
||||
#include "common/MockEsp.cpp" // getCycleCount
|
||||
|
||||
//This won't work for
|
||||
// This won't work for
|
||||
template<typename argT>
|
||||
inline bool
|
||||
fuzzycomp(argT a, argT b)
|
||||
inline bool fuzzycomp(argT a, argT b)
|
||||
{
|
||||
const argT epsilon = 10;
|
||||
return (std::max(a,b) - std::min(a,b) <= epsilon);
|
||||
const argT epsilon = 10;
|
||||
return (std::max(a, b) - std::min(a, b) <= epsilon);
|
||||
}
|
||||
|
||||
TEST_CASE("OneShot Timeout 500000000ns (0.5s)", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::oneShotFastNs;
|
||||
using timeType = oneShotFastNs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::oneShotFastNs;
|
||||
using timeType = oneShotFastNs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("OneShot Timeout 500000000ns (0.5s)");
|
||||
Serial.println("OneShot Timeout 500000000ns (0.5s)");
|
||||
|
||||
oneShotFastNs timeout(500000000);
|
||||
before = micros();
|
||||
while(!timeout.expired())
|
||||
yield();
|
||||
after = micros();
|
||||
oneShotFastNs timeout(500000000);
|
||||
before = micros();
|
||||
while (!timeout.expired())
|
||||
yield();
|
||||
after = micros();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta/1000, (timeType)500));
|
||||
REQUIRE(fuzzycomp(delta / 1000, (timeType)500));
|
||||
|
||||
Serial.print("reset\n");
|
||||
|
||||
Serial.print("reset\n");
|
||||
timeout.reset();
|
||||
before = micros();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = micros();
|
||||
|
||||
timeout.reset();
|
||||
before = micros();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = micros();
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta/1000, (timeType)500));
|
||||
REQUIRE(fuzzycomp(delta / 1000, (timeType)500));
|
||||
}
|
||||
|
||||
TEST_CASE("OneShot Timeout 3000000us", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::oneShotFastUs;
|
||||
using timeType = oneShotFastUs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::oneShotFastUs;
|
||||
using timeType = oneShotFastUs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("OneShot Timeout 3000000us");
|
||||
Serial.println("OneShot Timeout 3000000us");
|
||||
|
||||
oneShotFastUs timeout(3000000);
|
||||
before = micros();
|
||||
while(!timeout.expired())
|
||||
yield();
|
||||
after = micros();
|
||||
oneShotFastUs timeout(3000000);
|
||||
before = micros();
|
||||
while (!timeout.expired())
|
||||
yield();
|
||||
after = micros();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta/1000, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta / 1000, (timeType)3000));
|
||||
|
||||
Serial.print("reset\n");
|
||||
|
||||
Serial.print("reset\n");
|
||||
timeout.reset();
|
||||
before = micros();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = micros();
|
||||
|
||||
timeout.reset();
|
||||
before = micros();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = micros();
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %u\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta/1000, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta / 1000, (timeType)3000));
|
||||
}
|
||||
|
||||
TEST_CASE("OneShot Timeout 3000ms", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::oneShotMs;
|
||||
using timeType = oneShotMs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::oneShotMs;
|
||||
using timeType = oneShotMs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
|
||||
oneShotMs timeout(3000);
|
||||
before = millis();
|
||||
while(!timeout.expired())
|
||||
yield();
|
||||
after = millis();
|
||||
oneShotMs timeout(3000);
|
||||
before = millis();
|
||||
while (!timeout.expired())
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
|
||||
Serial.print("reset\n");
|
||||
|
||||
Serial.print("reset\n");
|
||||
timeout.reset();
|
||||
before = millis();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
timeout.reset();
|
||||
before = millis();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
}
|
||||
|
||||
TEST_CASE("OneShot Timeout 3000ms reset to 1000ms", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::oneShotMs;
|
||||
using timeType = oneShotMs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::oneShotMs;
|
||||
using timeType = oneShotMs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
|
||||
oneShotMs timeout(3000);
|
||||
before = millis();
|
||||
while(!timeout.expired())
|
||||
yield();
|
||||
after = millis();
|
||||
oneShotMs timeout(3000);
|
||||
before = millis();
|
||||
while (!timeout.expired())
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
|
||||
Serial.print("reset\n");
|
||||
|
||||
Serial.print("reset\n");
|
||||
timeout.reset(1000);
|
||||
before = millis();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
timeout.reset(1000);
|
||||
before = millis();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)1000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)1000));
|
||||
}
|
||||
|
||||
TEST_CASE("Periodic Timeout 1T 3000ms", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::periodicMs;
|
||||
using timeType = periodicMs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::periodicMs;
|
||||
using timeType = periodicMs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("Periodic Timeout 1T 3000ms");
|
||||
Serial.println("Periodic Timeout 1T 3000ms");
|
||||
|
||||
periodicMs timeout(3000);
|
||||
before = millis();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
periodicMs timeout(3000);
|
||||
before = millis();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
|
||||
Serial.print("no reset needed\n");
|
||||
Serial.print("no reset needed\n");
|
||||
|
||||
before = millis();
|
||||
while(!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
before = millis();
|
||||
while (!timeout)
|
||||
yield();
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
}
|
||||
|
||||
TEST_CASE("Periodic Timeout 10T 1000ms", "[polledTimeout]")
|
||||
{
|
||||
using esp8266::polledTimeout::periodicMs;
|
||||
using timeType = periodicMs::timeType;
|
||||
timeType before, after, delta;
|
||||
using esp8266::polledTimeout::periodicMs;
|
||||
using timeType = periodicMs::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("Periodic 10T Timeout 1000ms");
|
||||
Serial.println("Periodic 10T Timeout 1000ms");
|
||||
|
||||
int counter = 10;
|
||||
int counter = 10;
|
||||
|
||||
periodicMs timeout(1000);
|
||||
before = millis();
|
||||
while(1)
|
||||
{
|
||||
if(timeout)
|
||||
periodicMs timeout(1000);
|
||||
before = millis();
|
||||
while (1)
|
||||
{
|
||||
Serial.print("*");
|
||||
if(!--counter)
|
||||
break;
|
||||
yield();
|
||||
if (timeout)
|
||||
{
|
||||
Serial.print("*");
|
||||
if (!--counter)
|
||||
break;
|
||||
yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
after = millis();
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("\ndelta = %lu\n", delta);
|
||||
REQUIRE(fuzzycomp(delta, (timeType)10000));
|
||||
delta = after - before;
|
||||
Serial.printf("\ndelta = %lu\n", delta);
|
||||
REQUIRE(fuzzycomp(delta, (timeType)10000));
|
||||
}
|
||||
|
||||
TEST_CASE("OneShot Timeout 3000ms reset to 1000ms custom yield", "[polledTimeout]")
|
||||
{
|
||||
using YieldOrSkipPolicy = esp8266::polledTimeout::YieldPolicy::YieldOrSkip;
|
||||
using oneShotMsYield = esp8266::polledTimeout::timeoutTemplate<false, YieldOrSkipPolicy>;
|
||||
using timeType = oneShotMsYield::timeType;
|
||||
timeType before, after, delta;
|
||||
using YieldOrSkipPolicy = esp8266::polledTimeout::YieldPolicy::YieldOrSkip;
|
||||
using oneShotMsYield = esp8266::polledTimeout::timeoutTemplate<false, YieldOrSkipPolicy>;
|
||||
using timeType = oneShotMsYield::timeType;
|
||||
timeType before, after, delta;
|
||||
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
Serial.println("OneShot Timeout 3000ms");
|
||||
|
||||
oneShotMsYield timeout(3000);
|
||||
before = millis();
|
||||
while (!timeout.expired())
|
||||
;
|
||||
after = millis();
|
||||
|
||||
oneShotMsYield timeout(3000);
|
||||
before = millis();
|
||||
while(!timeout.expired());
|
||||
after = millis();
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)3000));
|
||||
Serial.print("reset\n");
|
||||
|
||||
timeout.reset(1000);
|
||||
before = millis();
|
||||
while (!timeout)
|
||||
;
|
||||
after = millis();
|
||||
|
||||
Serial.print("reset\n");
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
timeout.reset(1000);
|
||||
before = millis();
|
||||
while(!timeout);
|
||||
after = millis();
|
||||
|
||||
delta = after - before;
|
||||
Serial.printf("delta = %lu\n", delta);
|
||||
|
||||
REQUIRE(fuzzycomp(delta, (timeType)1000));
|
||||
REQUIRE(fuzzycomp(delta, (timeType)1000));
|
||||
}
|
||||
|
||||
|
||||
@@ -27,19 +27,19 @@ TEST_CASE("Print::write overrides all compile properly", "[core][Print]")
|
||||
REQUIRE(LittleFS.begin());
|
||||
auto p = LittleFS.open("test.bin", "w");
|
||||
REQUIRE(p);
|
||||
uint8_t uint8 = 1;
|
||||
uint16_t uint16 = 2;
|
||||
uint32_t uint32 = 3;
|
||||
size_t size = 4;
|
||||
int8_t int8 = 1;
|
||||
int16_t int16 = 2;
|
||||
int32_t int32 = 3;
|
||||
char c = 'h';
|
||||
int i = 10;
|
||||
long l = 11;
|
||||
unsigned char uc = 20;
|
||||
unsigned int ui = 21;
|
||||
unsigned long ul = 22;
|
||||
uint8_t uint8 = 1;
|
||||
uint16_t uint16 = 2;
|
||||
uint32_t uint32 = 3;
|
||||
size_t size = 4;
|
||||
int8_t int8 = 1;
|
||||
int16_t int16 = 2;
|
||||
int32_t int32 = 3;
|
||||
char c = 'h';
|
||||
int i = 10;
|
||||
long l = 11;
|
||||
unsigned char uc = 20;
|
||||
unsigned int ui = 21;
|
||||
unsigned long ul = 22;
|
||||
p.write(uint8);
|
||||
p.write(uint16);
|
||||
p.write(uint32);
|
||||
@@ -60,7 +60,7 @@ TEST_CASE("Print::write overrides all compile properly", "[core][Print]")
|
||||
p = LittleFS.open("test.bin", "r");
|
||||
REQUIRE(p);
|
||||
uint8_t buff[16];
|
||||
int len = p.read(buff, 16);
|
||||
int len = p.read(buff, 16);
|
||||
p.close();
|
||||
REQUIRE(len == 15);
|
||||
REQUIRE(buff[0] == 1);
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
#include <catch.hpp>
|
||||
#include <Updater.h>
|
||||
|
||||
|
||||
// Use a SPIFFS file because we can't instantiate a virtual class like Print
|
||||
TEST_CASE("Updater fails when writes overflow requested size", "[core][Updater]")
|
||||
{
|
||||
UpdaterClass *u;
|
||||
uint8_t buff[6000];
|
||||
UpdaterClass* u;
|
||||
uint8_t buff[6000];
|
||||
memset(buff, 0, sizeof(buff));
|
||||
u = new UpdaterClass();
|
||||
REQUIRE(u->begin(6000));
|
||||
|
||||
@@ -32,30 +32,35 @@ TEST_CASE("MD5Builder::add works as expected", "[core][MD5Builder]")
|
||||
REQUIRE(builder.toString() == "9edb67f2b22c604fab13e2fd1d6056d7");
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("MD5Builder::addHexString works as expected", "[core][MD5Builder]")
|
||||
{
|
||||
WHEN("A char array is parsed"){
|
||||
MD5Builder builder;
|
||||
builder.begin();
|
||||
const char * myPayload = "1234567890abcdeffedcba98765432106469676974616c7369676e61747572656170706c69636174696F6e73";
|
||||
builder.addHexString(myPayload);
|
||||
builder.calculate();
|
||||
REQUIRE(builder.toString() == "47b937a6f9f12a4c389fa5854e023efb");
|
||||
WHEN("A char array is parsed")
|
||||
{
|
||||
MD5Builder builder;
|
||||
builder.begin();
|
||||
const char* myPayload = "1234567890abcdeffedcba98765432106469676974616c7369676e617475726561"
|
||||
"70706c69636174696F6e73";
|
||||
builder.addHexString(myPayload);
|
||||
builder.calculate();
|
||||
REQUIRE(builder.toString() == "47b937a6f9f12a4c389fa5854e023efb");
|
||||
}
|
||||
|
||||
WHEN("A Arduino String is parsed"){
|
||||
MD5Builder builder;
|
||||
builder.begin();
|
||||
builder.addHexString(String("1234567890abcdeffedcba98765432106469676974616c7369676e61747572656170706c69636174696f6e73"));
|
||||
builder.calculate();
|
||||
REQUIRE(builder.toString() == "47b937a6f9f12a4c389fa5854e023efb");
|
||||
WHEN("A Arduino String is parsed")
|
||||
{
|
||||
MD5Builder builder;
|
||||
builder.begin();
|
||||
builder.addHexString(String("1234567890abcdeffedcba98765432106469676974616c7369676e61747572"
|
||||
"656170706c69636174696f6e73"));
|
||||
builder.calculate();
|
||||
REQUIRE(builder.toString() == "47b937a6f9f12a4c389fa5854e023efb");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MD5Builder::addStream works", "[core][MD5Builder]"){
|
||||
MD5Builder builder;
|
||||
const char* str = "MD5Builder::addStream_works_longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong";
|
||||
TEST_CASE("MD5Builder::addStream works", "[core][MD5Builder]")
|
||||
{
|
||||
MD5Builder builder;
|
||||
const char* str = "MD5Builder::addStream_works_"
|
||||
"longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong";
|
||||
{
|
||||
StreamString stream;
|
||||
stream.print(str);
|
||||
|
||||
@@ -19,15 +19,16 @@
|
||||
|
||||
TEST_CASE("strstr_P works as strstr", "[core][pgmspace]")
|
||||
{
|
||||
auto t = [](const char* h, const char* n) {
|
||||
auto t = [](const char* h, const char* n)
|
||||
{
|
||||
const char* strstr_P_result = strstr_P(h, n);
|
||||
const char* strstr_result = strstr(h, n);
|
||||
const char* strstr_result = strstr(h, n);
|
||||
REQUIRE(strstr_P_result == strstr_result);
|
||||
};
|
||||
|
||||
// Test case data is from avr-libc, original copyright (c) 2007 Dmitry Xmelkov
|
||||
// See avr-libc/tests/simulate/pmstring/strstr_P.c
|
||||
t ("", "");
|
||||
t("", "");
|
||||
t("12345", "");
|
||||
t("ababac", "abac");
|
||||
t("", "a");
|
||||
|
||||
@@ -43,8 +43,8 @@ TEST_CASE("String::trim", "[core][String]")
|
||||
TEST_CASE("String::replace", "[core][String]")
|
||||
{
|
||||
String str;
|
||||
str = "The quick brown fox jumped over the lazy dog.";
|
||||
String find = "fox";
|
||||
str = "The quick brown fox jumped over the lazy dog.";
|
||||
String find = "fox";
|
||||
String replace = "vulpes vulpes";
|
||||
str.replace(find, replace);
|
||||
REQUIRE(str == "The quick brown vulpes vulpes jumped over the lazy dog.");
|
||||
@@ -52,10 +52,10 @@ TEST_CASE("String::replace", "[core][String]")
|
||||
|
||||
TEST_CASE("String(value, base)", "[core][String]")
|
||||
{
|
||||
String strbase2(9999,2);
|
||||
String strbase8(9999,8);
|
||||
String strbase10(9999,10);
|
||||
String strbase16(9999,16);
|
||||
String strbase2(9999, 2);
|
||||
String strbase8(9999, 8);
|
||||
String strbase10(9999, 10);
|
||||
String strbase16(9999, 16);
|
||||
REQUIRE(strbase2 == "10011100001111");
|
||||
REQUIRE(strbase8 == "23417");
|
||||
REQUIRE(strbase10 == "9999");
|
||||
@@ -64,7 +64,7 @@ TEST_CASE("String(value, base)", "[core][String]")
|
||||
String strnegf(-2.123, 3);
|
||||
REQUIRE(strnegi == "-9999");
|
||||
REQUIRE(strnegf == "-2.123");
|
||||
String strbase16l((long)999999,16);
|
||||
String strbase16l((long)999999, 16);
|
||||
REQUIRE(strbase16l == "f423f");
|
||||
}
|
||||
|
||||
@@ -83,8 +83,8 @@ TEST_CASE("String constructors", "[core][String]")
|
||||
String s1("abcd");
|
||||
String s2(s1);
|
||||
REQUIRE(s1 == s2);
|
||||
String *s3 = new String("manos");
|
||||
s2 = *s3;
|
||||
String* s3 = new String("manos");
|
||||
s2 = *s3;
|
||||
delete s3;
|
||||
REQUIRE(s2 == "manos");
|
||||
s3 = new String("thisismuchlongerthantheother");
|
||||
@@ -97,8 +97,8 @@ TEST_CASE("String constructors", "[core][String]")
|
||||
REQUIRE(ssh == "3.14159_abcd");
|
||||
String flash = (F("hello from flash"));
|
||||
REQUIRE(flash == "hello from flash");
|
||||
const char textarray[6] = {'h', 'e', 'l', 'l', 'o', 0};
|
||||
String hello(textarray);
|
||||
const char textarray[6] = { 'h', 'e', 'l', 'l', 'o', 0 };
|
||||
String hello(textarray);
|
||||
REQUIRE(hello == "hello");
|
||||
String hello2;
|
||||
hello2 = textarray;
|
||||
@@ -135,13 +135,21 @@ TEST_CASE("String concantenation", "[core][String]")
|
||||
str += LLONG_MIN;
|
||||
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808");
|
||||
str += String(LLONG_MIN, 10);
|
||||
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808");
|
||||
REQUIRE(str
|
||||
== "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-"
|
||||
"9223372036854775808");
|
||||
str += LLONG_MAX;
|
||||
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-92233720368547758089223372036854775807");
|
||||
REQUIRE(str
|
||||
== "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-"
|
||||
"92233720368547758089223372036854775807");
|
||||
str += ULLONG_MAX;
|
||||
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808922337203685477580718446744073709551615");
|
||||
REQUIRE(str
|
||||
== "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-"
|
||||
"9223372036854775808922337203685477580718446744073709551615");
|
||||
str += String(ULLONG_MAX, 16);
|
||||
REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808922337203685477580718446744073709551615ffffffffffffffff");
|
||||
REQUIRE(str
|
||||
== "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-"
|
||||
"9223372036854775808922337203685477580718446744073709551615ffffffffffffffff");
|
||||
str = "clean";
|
||||
REQUIRE(str.concat(str) == true);
|
||||
REQUIRE(str == "cleanclean");
|
||||
@@ -156,19 +164,19 @@ TEST_CASE("String concantenation", "[core][String]")
|
||||
REQUIRE(str == "-100");
|
||||
// Non-zero-terminated array concatenation
|
||||
const char buff[] = "abcdefg";
|
||||
String n;
|
||||
n = "1234567890"; // Make it a SSO string, fill with non-0 data
|
||||
n = "1"; // Overwrite [1] with 0, but leave old junk in SSO space still
|
||||
String n;
|
||||
n = "1234567890"; // Make it a SSO string, fill with non-0 data
|
||||
n = "1"; // Overwrite [1] with 0, but leave old junk in SSO space still
|
||||
n.concat(buff, 3);
|
||||
REQUIRE(n == "1abc"); // Ensure the trailing 0 is always present even w/this funky concat
|
||||
for (int i=0; i<20; i++)
|
||||
n.concat(buff, 1); // Add 20 'a's to go from SSO to normal string
|
||||
REQUIRE(n == "1abc"); // Ensure the trailing 0 is always present even w/this funky concat
|
||||
for (int i = 0; i < 20; i++)
|
||||
n.concat(buff, 1); // Add 20 'a's to go from SSO to normal string
|
||||
REQUIRE(n == "1abcaaaaaaaaaaaaaaaaaaaa");
|
||||
n = "";
|
||||
for (int i=0; i<=5; i++)
|
||||
for (int i = 0; i <= 5; i++)
|
||||
n.concat(buff, i);
|
||||
REQUIRE(n == "aababcabcdabcde");
|
||||
n.concat(buff, 0); // And check no add'n
|
||||
n.concat(buff, 0); // And check no add'n
|
||||
REQUIRE(n == "aababcabcdabcde");
|
||||
}
|
||||
|
||||
@@ -211,7 +219,7 @@ TEST_CASE("String byte access", "[core][String]")
|
||||
TEST_CASE("String conversion", "[core][String]")
|
||||
{
|
||||
String s = "12345";
|
||||
long l = s.toInt();
|
||||
long l = s.toInt();
|
||||
REQUIRE(l == 12345);
|
||||
s = "2147483647";
|
||||
l = s.toInt();
|
||||
@@ -222,9 +230,9 @@ TEST_CASE("String conversion", "[core][String]")
|
||||
s = "-2147483648";
|
||||
l = s.toInt();
|
||||
REQUIRE(l == INT_MIN);
|
||||
s = "3.14159";
|
||||
s = "3.14159";
|
||||
float f = s.toFloat();
|
||||
REQUIRE( fabs(f - 3.14159) < 0.0001 );
|
||||
REQUIRE(fabs(f - 3.14159) < 0.0001);
|
||||
}
|
||||
|
||||
TEST_CASE("String case", "[core][String]")
|
||||
@@ -246,7 +254,7 @@ TEST_CASE("String nulls", "[core][String]")
|
||||
s.trim();
|
||||
s.toUpperCase();
|
||||
s.toLowerCase();
|
||||
s.remove(1,1);
|
||||
s.remove(1, 1);
|
||||
s.remove(10);
|
||||
s.replace("taco", "burrito");
|
||||
s.replace('a', 'b');
|
||||
@@ -268,7 +276,7 @@ TEST_CASE("String nulls", "[core][String]")
|
||||
REQUIRE(s == "");
|
||||
REQUIRE(s.length() == 0);
|
||||
s.setCharAt(1, 't');
|
||||
REQUIRE(s.startsWith("abc",0) == false);
|
||||
REQUIRE(s.startsWith("abc", 0) == false);
|
||||
REQUIRE(s.startsWith("def") == false);
|
||||
REQUIRE(s.equalsConstantTime("def") == false);
|
||||
REQUIRE(s.equalsConstantTime("") == true);
|
||||
@@ -299,125 +307,128 @@ TEST_CASE("String sizes near 8b", "[core][String]")
|
||||
String s15("12345678901234");
|
||||
String s16("123456789012345");
|
||||
String s17("1234567890123456");
|
||||
REQUIRE(!strcmp(s7.c_str(),"123456"));
|
||||
REQUIRE(!strcmp(s8.c_str(),"1234567"));
|
||||
REQUIRE(!strcmp(s9.c_str(),"12345678"));
|
||||
REQUIRE(!strcmp(s15.c_str(),"12345678901234"));
|
||||
REQUIRE(!strcmp(s16.c_str(),"123456789012345"));
|
||||
REQUIRE(!strcmp(s17.c_str(),"1234567890123456"));
|
||||
REQUIRE(!strcmp(s7.c_str(), "123456"));
|
||||
REQUIRE(!strcmp(s8.c_str(), "1234567"));
|
||||
REQUIRE(!strcmp(s9.c_str(), "12345678"));
|
||||
REQUIRE(!strcmp(s15.c_str(), "12345678901234"));
|
||||
REQUIRE(!strcmp(s16.c_str(), "123456789012345"));
|
||||
REQUIRE(!strcmp(s17.c_str(), "1234567890123456"));
|
||||
s7 += '_';
|
||||
s8 += '_';
|
||||
s9 += '_';
|
||||
s15 += '_';
|
||||
s16 += '_';
|
||||
s17 += '_';
|
||||
REQUIRE(!strcmp(s7.c_str(),"123456_"));
|
||||
REQUIRE(!strcmp(s8.c_str(),"1234567_"));
|
||||
REQUIRE(!strcmp(s9.c_str(),"12345678_"));
|
||||
REQUIRE(!strcmp(s15.c_str(),"12345678901234_"));
|
||||
REQUIRE(!strcmp(s16.c_str(),"123456789012345_"));
|
||||
REQUIRE(!strcmp(s17.c_str(),"1234567890123456_"));
|
||||
REQUIRE(!strcmp(s7.c_str(), "123456_"));
|
||||
REQUIRE(!strcmp(s8.c_str(), "1234567_"));
|
||||
REQUIRE(!strcmp(s9.c_str(), "12345678_"));
|
||||
REQUIRE(!strcmp(s15.c_str(), "12345678901234_"));
|
||||
REQUIRE(!strcmp(s16.c_str(), "123456789012345_"));
|
||||
REQUIRE(!strcmp(s17.c_str(), "1234567890123456_"));
|
||||
}
|
||||
|
||||
TEST_CASE("String SSO works", "[core][String]")
|
||||
{
|
||||
// This test assumes that SSO_SIZE==8, if that changes the test must as well
|
||||
String s;
|
||||
s += "0";
|
||||
REQUIRE(s == "0");
|
||||
REQUIRE(s.length() == 1);
|
||||
const char *savesso = s.c_str();
|
||||
s += 1;
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01");
|
||||
REQUIRE(s.length() == 2);
|
||||
s += "2";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012");
|
||||
REQUIRE(s.length() == 3);
|
||||
s += 3;
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123");
|
||||
REQUIRE(s.length() == 4);
|
||||
s += "4";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01234");
|
||||
REQUIRE(s.length() == 5);
|
||||
s += "5";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012345");
|
||||
REQUIRE(s.length() == 6);
|
||||
s += "6";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456");
|
||||
REQUIRE(s.length() == 7);
|
||||
s += "7";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01234567");
|
||||
REQUIRE(s.length() == 8);
|
||||
s += "8";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012345678");
|
||||
REQUIRE(s.length() == 9);
|
||||
s += "9";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789");
|
||||
REQUIRE(s.length() == 10);
|
||||
if (sizeof(savesso) == 4) {
|
||||
s += "a";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789a");
|
||||
REQUIRE(s.length() == 11);
|
||||
s += "b";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789ab");
|
||||
REQUIRE(s.length() == 12);
|
||||
s += "c";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abc");
|
||||
REQUIRE(s.length() == 13);
|
||||
} else {
|
||||
s += "a";
|
||||
// This test assumes that SSO_SIZE==8, if that changes the test must as well
|
||||
String s;
|
||||
s += "0";
|
||||
REQUIRE(s == "0");
|
||||
REQUIRE(s.length() == 1);
|
||||
const char* savesso = s.c_str();
|
||||
s += 1;
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789a");
|
||||
REQUIRE(s.length() == 11);
|
||||
s += "bcde";
|
||||
REQUIRE(s == "01");
|
||||
REQUIRE(s.length() == 2);
|
||||
s += "2";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789abcde");
|
||||
REQUIRE(s.length() == 15);
|
||||
s += "fghi";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghi");
|
||||
REQUIRE(s.length() == 19);
|
||||
s += "j";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghij");
|
||||
REQUIRE(s.length() == 20);
|
||||
s += "k";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijk");
|
||||
REQUIRE(s.length() == 21);
|
||||
s += "l";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijkl");
|
||||
REQUIRE(s.length() == 22);
|
||||
s += "m";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklm");
|
||||
REQUIRE(s.length() == 23);
|
||||
s += "nopq";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklmnopq");
|
||||
REQUIRE(s.length() == 27);
|
||||
s += "rstu";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklmnopqrstu");
|
||||
REQUIRE(s.length() == 31);
|
||||
}
|
||||
s = "0123456789abcde";
|
||||
s = s.substring(s.indexOf('a'));
|
||||
REQUIRE(s == "abcde");
|
||||
REQUIRE(s.length() == 5);
|
||||
REQUIRE(s == "012");
|
||||
REQUIRE(s.length() == 3);
|
||||
s += 3;
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123");
|
||||
REQUIRE(s.length() == 4);
|
||||
s += "4";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01234");
|
||||
REQUIRE(s.length() == 5);
|
||||
s += "5";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012345");
|
||||
REQUIRE(s.length() == 6);
|
||||
s += "6";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456");
|
||||
REQUIRE(s.length() == 7);
|
||||
s += "7";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "01234567");
|
||||
REQUIRE(s.length() == 8);
|
||||
s += "8";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "012345678");
|
||||
REQUIRE(s.length() == 9);
|
||||
s += "9";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789");
|
||||
REQUIRE(s.length() == 10);
|
||||
if (sizeof(savesso) == 4)
|
||||
{
|
||||
s += "a";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789a");
|
||||
REQUIRE(s.length() == 11);
|
||||
s += "b";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789ab");
|
||||
REQUIRE(s.length() == 12);
|
||||
s += "c";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abc");
|
||||
REQUIRE(s.length() == 13);
|
||||
}
|
||||
else
|
||||
{
|
||||
s += "a";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789a");
|
||||
REQUIRE(s.length() == 11);
|
||||
s += "bcde";
|
||||
REQUIRE(s.c_str() == savesso);
|
||||
REQUIRE(s == "0123456789abcde");
|
||||
REQUIRE(s.length() == 15);
|
||||
s += "fghi";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghi");
|
||||
REQUIRE(s.length() == 19);
|
||||
s += "j";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghij");
|
||||
REQUIRE(s.length() == 20);
|
||||
s += "k";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijk");
|
||||
REQUIRE(s.length() == 21);
|
||||
s += "l";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijkl");
|
||||
REQUIRE(s.length() == 22);
|
||||
s += "m";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklm");
|
||||
REQUIRE(s.length() == 23);
|
||||
s += "nopq";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklmnopq");
|
||||
REQUIRE(s.length() == 27);
|
||||
s += "rstu";
|
||||
REQUIRE(s.c_str() != savesso);
|
||||
REQUIRE(s == "0123456789abcdefghijklmnopqrstu");
|
||||
REQUIRE(s.length() == 31);
|
||||
}
|
||||
s = "0123456789abcde";
|
||||
s = s.substring(s.indexOf('a'));
|
||||
REQUIRE(s == "abcde");
|
||||
REQUIRE(s.length() == 5);
|
||||
}
|
||||
|
||||
#include <new>
|
||||
@@ -426,70 +437,67 @@ void repl(const String& key, const String& val, String& s, boolean useURLencode)
|
||||
s.replace(key, val);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("String SSO handles junk in memory", "[core][String]")
|
||||
{
|
||||
// We fill the SSO space with garbage then construct an object in it and check consistency
|
||||
// This is NOT how you want to use Strings outside of this testing!
|
||||
unsigned char space[64];
|
||||
String *s = (String*)space;
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String;
|
||||
REQUIRE(*s == "");
|
||||
s->~String();
|
||||
// We fill the SSO space with garbage then construct an object in it and check consistency
|
||||
// This is NOT how you want to use Strings outside of this testing!
|
||||
unsigned char space[64];
|
||||
String* s = (String*)space;
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String;
|
||||
REQUIRE(*s == "");
|
||||
s->~String();
|
||||
|
||||
// Tests from #5883
|
||||
bool useURLencode = false;
|
||||
const char euro[4] = {(char)0xe2, (char)0x82, (char)0xac, 0}; // Unicode euro symbol
|
||||
const char yen[3] = {(char)0xc2, (char)0xa5, 0}; // Unicode yen symbol
|
||||
// Tests from #5883
|
||||
bool useURLencode = false;
|
||||
const char euro[4] = { (char)0xe2, (char)0x82, (char)0xac, 0 }; // Unicode euro symbol
|
||||
const char yen[3] = { (char)0xc2, (char)0xa5, 0 }; // Unicode yen symbol
|
||||
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("%ssid%");
|
||||
repl(("%ssid%"), "MikroTik", *s, useURLencode);
|
||||
REQUIRE(*s == "MikroTik");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("%ssid%");
|
||||
repl(("%ssid%"), "MikroTik", *s, useURLencode);
|
||||
REQUIRE(*s == "MikroTik");
|
||||
s->~String();
|
||||
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("{E}");
|
||||
repl(("{E}"), euro, *s, useURLencode);
|
||||
REQUIRE(*s == "€");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("€");
|
||||
repl(("€"), euro, *s, useURLencode);
|
||||
REQUIRE(*s == "€");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("{Y}");
|
||||
repl(("{Y}"), yen, *s, useURLencode);
|
||||
REQUIRE(*s == "¥");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("¥");
|
||||
repl(("¥"), yen, *s, useURLencode);
|
||||
REQUIRE(*s == "¥");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("{E}");
|
||||
repl(("{E}"), euro, *s, useURLencode);
|
||||
REQUIRE(*s == "€");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("€");
|
||||
repl(("€"), euro, *s, useURLencode);
|
||||
REQUIRE(*s == "€");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("{Y}");
|
||||
repl(("{Y}"), yen, *s, useURLencode);
|
||||
REQUIRE(*s == "¥");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("¥");
|
||||
repl(("¥"), yen, *s, useURLencode);
|
||||
REQUIRE(*s == "¥");
|
||||
s->~String();
|
||||
|
||||
memset(space, 0xff, 64);
|
||||
new(s) String("%sysname%");
|
||||
repl(("%sysname%"), "CO2_defect", *s, useURLencode);
|
||||
REQUIRE(*s == "CO2_defect");
|
||||
s->~String();
|
||||
memset(space, 0xff, 64);
|
||||
new (s) String("%sysname%");
|
||||
repl(("%sysname%"), "CO2_defect", *s, useURLencode);
|
||||
REQUIRE(*s == "CO2_defect");
|
||||
s->~String();
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Issue #5949 - Overlapping src/dest in replace", "[core][String]")
|
||||
{
|
||||
String blah = "blah";
|
||||
blah.replace("xx", "y");
|
||||
REQUIRE(blah == "blah");
|
||||
blah.replace("x", "yy");
|
||||
REQUIRE(blah == "blah");
|
||||
blah.replace(blah, blah);
|
||||
REQUIRE(blah == "blah");
|
||||
String blah = "blah";
|
||||
blah.replace("xx", "y");
|
||||
REQUIRE(blah == "blah");
|
||||
blah.replace("x", "yy");
|
||||
REQUIRE(blah == "blah");
|
||||
blah.replace(blah, blah);
|
||||
REQUIRE(blah == "blah");
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Issue #2736 - StreamString SSO fix", "[core][StreamString]")
|
||||
{
|
||||
StreamString s;
|
||||
@@ -502,102 +510,101 @@ TEST_CASE("Issue #2736 - StreamString SSO fix", "[core][StreamString]")
|
||||
|
||||
TEST_CASE("Strings with NULs", "[core][String]")
|
||||
{
|
||||
// The following should never be done in a real app! This is only to inject 0s in the middle of a string.
|
||||
// Fits in SSO...
|
||||
String str("01234567");
|
||||
REQUIRE(str.length() == 8);
|
||||
char *ptr = (char *)str.c_str();
|
||||
ptr[3] = 0;
|
||||
String str2;
|
||||
str2 = str;
|
||||
REQUIRE(str2.length() == 8);
|
||||
// Needs a buffer pointer
|
||||
str = "0123456789012345678901234567890123456789";
|
||||
ptr = (char *)str.c_str();
|
||||
ptr[3] = 0;
|
||||
str2 = str;
|
||||
REQUIRE(str2.length() == 40);
|
||||
String str3("a");
|
||||
ptr = (char *)str3.c_str();
|
||||
*ptr = 0;
|
||||
REQUIRE(str3.length() == 1);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 2);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 4);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 8);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 16);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 32);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 64);
|
||||
static char zeros[64] = {0};
|
||||
const char *p = str3.c_str();
|
||||
REQUIRE(!memcmp(p, zeros, 64));
|
||||
// The following should never be done in a real app! This is only to inject 0s in the middle of
|
||||
// a string. Fits in SSO...
|
||||
String str("01234567");
|
||||
REQUIRE(str.length() == 8);
|
||||
char* ptr = (char*)str.c_str();
|
||||
ptr[3] = 0;
|
||||
String str2;
|
||||
str2 = str;
|
||||
REQUIRE(str2.length() == 8);
|
||||
// Needs a buffer pointer
|
||||
str = "0123456789012345678901234567890123456789";
|
||||
ptr = (char*)str.c_str();
|
||||
ptr[3] = 0;
|
||||
str2 = str;
|
||||
REQUIRE(str2.length() == 40);
|
||||
String str3("a");
|
||||
ptr = (char*)str3.c_str();
|
||||
*ptr = 0;
|
||||
REQUIRE(str3.length() == 1);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 2);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 4);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 8);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 16);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 32);
|
||||
str3 += str3;
|
||||
REQUIRE(str3.length() == 64);
|
||||
static char zeros[64] = { 0 };
|
||||
const char* p = str3.c_str();
|
||||
REQUIRE(!memcmp(p, zeros, 64));
|
||||
}
|
||||
|
||||
TEST_CASE("Replace and string expansion", "[core][String]")
|
||||
{
|
||||
String s, l;
|
||||
// Make these large enough to span SSO and non SSO
|
||||
String whole = "#123456789012345678901234567890";
|
||||
const char *res = "abcde123456789012345678901234567890";
|
||||
for (size_t i=1; i < whole.length(); i++) {
|
||||
s = whole.substring(0, i);
|
||||
l = s;
|
||||
l.replace("#", "abcde");
|
||||
char buff[64];
|
||||
strcpy(buff, res);
|
||||
buff[5 + i-1] = 0;
|
||||
REQUIRE(!strcmp(l.c_str(), buff));
|
||||
REQUIRE(l.length() == strlen(buff));
|
||||
}
|
||||
String s, l;
|
||||
// Make these large enough to span SSO and non SSO
|
||||
String whole = "#123456789012345678901234567890";
|
||||
const char* res = "abcde123456789012345678901234567890";
|
||||
for (size_t i = 1; i < whole.length(); i++)
|
||||
{
|
||||
s = whole.substring(0, i);
|
||||
l = s;
|
||||
l.replace("#", "abcde");
|
||||
char buff[64];
|
||||
strcpy(buff, res);
|
||||
buff[5 + i - 1] = 0;
|
||||
REQUIRE(!strcmp(l.c_str(), buff));
|
||||
REQUIRE(l.length() == strlen(buff));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("String chaining", "[core][String]")
|
||||
{
|
||||
const char* chunks[] {
|
||||
"~12345",
|
||||
"67890",
|
||||
"qwertyuiopasdfghjkl",
|
||||
"zxcvbnm"
|
||||
};
|
||||
const char* chunks[] { "~12345", "67890", "qwertyuiopasdfghjkl", "zxcvbnm" };
|
||||
|
||||
String all;
|
||||
for (auto* chunk : chunks) {
|
||||
all += chunk;
|
||||
}
|
||||
String all;
|
||||
for (auto* chunk : chunks)
|
||||
{
|
||||
all += chunk;
|
||||
}
|
||||
|
||||
// make sure we can chain a combination of things to form a String
|
||||
REQUIRE((String(chunks[0]) + String(chunks[1]) + String(chunks[2]) + String(chunks[3])) == all);
|
||||
REQUIRE((chunks[0] + String(chunks[1]) + F(chunks[2]) + chunks[3]) == all);
|
||||
REQUIRE((String(chunks[0]) + F(chunks[1]) + F(chunks[2]) + String(chunks[3])) == all);
|
||||
REQUIRE(('~' + String(&chunks[0][0] + 1) + chunks[1] + String(chunks[2]) + F(chunks[3])) == all);
|
||||
REQUIRE((String(chunks[0]) + '6' + (&chunks[1][0] + 1) + String(chunks[2]) + F(chunks[3])) == all);
|
||||
// make sure we can chain a combination of things to form a String
|
||||
REQUIRE((String(chunks[0]) + String(chunks[1]) + String(chunks[2]) + String(chunks[3])) == all);
|
||||
REQUIRE((chunks[0] + String(chunks[1]) + F(chunks[2]) + chunks[3]) == all);
|
||||
REQUIRE((String(chunks[0]) + F(chunks[1]) + F(chunks[2]) + String(chunks[3])) == all);
|
||||
REQUIRE(('~' + String(&chunks[0][0] + 1) + chunks[1] + String(chunks[2]) + F(chunks[3]))
|
||||
== all);
|
||||
REQUIRE((String(chunks[0]) + '6' + (&chunks[1][0] + 1) + String(chunks[2]) + F(chunks[3]))
|
||||
== all);
|
||||
|
||||
// these are still invalid (and also cannot compile at all):
|
||||
// - `F(...)` + `F(...)`
|
||||
// - `F(...)` + `const char*`
|
||||
// - `const char*` + `F(...)`
|
||||
// we need `String()` as either rhs or lhs
|
||||
// these are still invalid (and also cannot compile at all):
|
||||
// - `F(...)` + `F(...)`
|
||||
// - `F(...)` + `const char*`
|
||||
// - `const char*` + `F(...)`
|
||||
// we need `String()` as either rhs or lhs
|
||||
|
||||
// ensure chaining reuses the buffer
|
||||
// (internal details...)
|
||||
{
|
||||
String tmp(chunks[3]);
|
||||
tmp.reserve(2 * all.length());
|
||||
auto* ptr = tmp.c_str();
|
||||
String result("~1" + String(&chunks[0][0] + 2) + F(chunks[1]) + chunks[2] + std::move(tmp));
|
||||
REQUIRE(result == all);
|
||||
REQUIRE(static_cast<const void*>(result.c_str()) == static_cast<const void*>(ptr));
|
||||
}
|
||||
// ensure chaining reuses the buffer
|
||||
// (internal details...)
|
||||
{
|
||||
String tmp(chunks[3]);
|
||||
tmp.reserve(2 * all.length());
|
||||
auto* ptr = tmp.c_str();
|
||||
String result("~1" + String(&chunks[0][0] + 2) + F(chunks[1]) + chunks[2] + std::move(tmp));
|
||||
REQUIRE(result == all);
|
||||
REQUIRE(static_cast<const void*>(result.c_str()) == static_cast<const void*>(ptr));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("String concat OOB #8198", "[core][String]")
|
||||
{
|
||||
char *p = (char*)malloc(16);
|
||||
char* p = (char*)malloc(16);
|
||||
memset(p, 'x', 16);
|
||||
String s = "abcd";
|
||||
s.concat(p, 16);
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#include "../../../libraries/SDFS/src/SDFS.h"
|
||||
#include "../../../libraries/SD/src/SD.h"
|
||||
|
||||
|
||||
namespace spiffs_test {
|
||||
namespace spiffs_test
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
@@ -47,9 +47,9 @@ namespace spiffs_test {
|
||||
TEST_CASE("SPIFFS checks the config object passed in", "[fs]")
|
||||
{
|
||||
SPIFFS_MOCK_DECLARE(64, 8, 512, "");
|
||||
FSConfig f;
|
||||
SPIFFSConfig s;
|
||||
SDFSConfig d;
|
||||
FSConfig f;
|
||||
SPIFFSConfig s;
|
||||
SDFSConfig d;
|
||||
LittleFSConfig l;
|
||||
|
||||
REQUIRE_FALSE(SPIFFS.setConfig(f));
|
||||
@@ -59,14 +59,15 @@ TEST_CASE("SPIFFS checks the config object passed in", "[fs]")
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
};
|
||||
}; // namespace spiffs_test
|
||||
|
||||
|
||||
namespace littlefs_test {
|
||||
namespace littlefs_test
|
||||
{
|
||||
#define FSTYPE LittleFS
|
||||
#define TESTPRE "LittleFS - "
|
||||
#define TESTPAT "[lfs]"
|
||||
// LittleFS routines strip leading slashes before doing anything, so up to 31 char names are allowable
|
||||
// LittleFS routines strip leading slashes before doing anything, so up to 31 char names are
|
||||
// allowable
|
||||
#define TOOLONGFILENAME "/12345678901234567890123456789012"
|
||||
#define FS_MOCK_DECLARE LITTLEFS_MOCK_DECLARE
|
||||
#define FS_MOCK_RESET LITTLEFS_MOCK_RESET
|
||||
@@ -82,9 +83,9 @@ namespace littlefs_test {
|
||||
TEST_CASE("LittleFS checks the config object passed in", "[fs]")
|
||||
{
|
||||
LITTLEFS_MOCK_DECLARE(64, 8, 512, "");
|
||||
FSConfig f;
|
||||
SPIFFSConfig s;
|
||||
SDFSConfig d;
|
||||
FSConfig f;
|
||||
SPIFFSConfig s;
|
||||
SDFSConfig d;
|
||||
LittleFSConfig l;
|
||||
|
||||
REQUIRE_FALSE(LittleFS.setConfig(f));
|
||||
@@ -93,17 +94,21 @@ TEST_CASE("LittleFS checks the config object passed in", "[fs]")
|
||||
REQUIRE(LittleFS.setConfig(l));
|
||||
}
|
||||
|
||||
};
|
||||
}; // namespace littlefs_test
|
||||
|
||||
namespace sdfs_test {
|
||||
namespace sdfs_test
|
||||
{
|
||||
#define FSTYPE SDFS
|
||||
#define TESTPRE "SDFS - "
|
||||
#define TESTPAT "[sdfs]"
|
||||
// SDFS supports long paths (MAXPATH)
|
||||
#define TOOLONGFILENAME "/" \
|
||||
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" \
|
||||
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" \
|
||||
"12345678901234567890123456789012345678901234567890123456"
|
||||
#define TOOLONGFILENAME \
|
||||
"/" \
|
||||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012" \
|
||||
"34567890" \
|
||||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012" \
|
||||
"34567890" \
|
||||
"12345678901234567890123456789012345678901234567890123456"
|
||||
#define FS_MOCK_DECLARE SDFS_MOCK_DECLARE
|
||||
#define FS_MOCK_RESET SDFS_MOCK_RESET
|
||||
#define FS_HAS_DIRS
|
||||
@@ -118,9 +123,9 @@ namespace sdfs_test {
|
||||
TEST_CASE("SDFS checks the config object passed in", "[fs]")
|
||||
{
|
||||
SDFS_MOCK_DECLARE(64, 8, 512, "");
|
||||
FSConfig f;
|
||||
SPIFFSConfig s;
|
||||
SDFSConfig d;
|
||||
FSConfig f;
|
||||
SPIFFSConfig s;
|
||||
SDFSConfig d;
|
||||
LittleFSConfig l;
|
||||
|
||||
REQUIRE_FALSE(SDFS.setConfig(f));
|
||||
@@ -142,7 +147,7 @@ TEST_CASE("SD.h FILE_WRITE macro is append", "[fs]")
|
||||
f.write(65);
|
||||
f.write("bbcc");
|
||||
f.write("theend", 6);
|
||||
char block[3]={'x','y','z'};
|
||||
char block[3] = { 'x', 'y', 'z' };
|
||||
f.write(block, 3);
|
||||
uint32_t bigone = 0x40404040;
|
||||
f.write((const uint8_t*)&bigone, 4);
|
||||
@@ -155,11 +160,11 @@ TEST_CASE("SD.h FILE_WRITE macro is append", "[fs]")
|
||||
File g = SD.open("/file2.txt", FILE_WRITE);
|
||||
g.write(0);
|
||||
g.close();
|
||||
g = SD.open("/file2.txt", FILE_READ);
|
||||
g = SD.open("/file2.txt", FILE_READ);
|
||||
uint8_t u = 0x66;
|
||||
g.read(&u, 1);
|
||||
g.close();
|
||||
REQUIRE(u == 0);
|
||||
}
|
||||
|
||||
};
|
||||
}; // namespace sdfs_test
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef PGM_P
|
||||
#define PGM_P const char *
|
||||
#define PGM_P const char*
|
||||
#endif
|
||||
|
||||
#ifndef PGM_VOID_P
|
||||
#define PGM_VOID_P const void *
|
||||
#define PGM_VOID_P const void*
|
||||
#endif
|
||||
|
||||
#ifndef PSTR
|
||||
@@ -27,37 +27,49 @@
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#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_dword(addr) (*reinterpret_cast<const uint32_t*>(addr))
|
||||
#define pgm_read_float(addr) (*reinterpret_cast<const float*>(addr))
|
||||
#define pgm_read_ptr(addr) (*reinterpret_cast<const void* const *>(addr))
|
||||
#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_dword(addr) (*reinterpret_cast<const uint32_t*>(addr))
|
||||
#define pgm_read_float(addr) (*reinterpret_cast<const float*>(addr))
|
||||
#define pgm_read_ptr(addr) (*reinterpret_cast<const void* const*>(addr))
|
||||
#else
|
||||
#define pgm_read_byte(addr) (*(const uint8_t*)(addr))
|
||||
#define pgm_read_word(addr) (*(const uint16_t*)(addr))
|
||||
#define pgm_read_dword(addr) (*(const uint32_t*)(addr))
|
||||
#define pgm_read_float(addr) (*(const float)(addr))
|
||||
#define pgm_read_ptr(addr) (*(const void* const *)(addr))
|
||||
#define pgm_read_byte(addr) (*(const uint8_t*)(addr))
|
||||
#define pgm_read_word(addr) (*(const uint16_t*)(addr))
|
||||
#define pgm_read_dword(addr) (*(const uint32_t*)(addr))
|
||||
#define pgm_read_float(addr) (*(const float)(addr))
|
||||
#define pgm_read_ptr(addr) (*(const void* const*)(addr))
|
||||
#endif
|
||||
|
||||
#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_ptr_near(addr) pgm_read_ptr(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)
|
||||
#define pgm_read_ptr_far(addr) pgm_read_ptr(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_ptr_near(addr) pgm_read_ptr(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)
|
||||
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
|
||||
|
||||
// Wrapper inlines for _P functions
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
inline const char *strstr_P(const char *haystack, const char *needle) { return strstr(haystack, needle); }
|
||||
inline char *strcpy_P(char *dest, const char *src) { return strcpy(dest, src); }
|
||||
inline size_t strlen_P(const char *s) { return strlen(s); }
|
||||
inline int vsnprintf_P(char *str, size_t size, const char *format, va_list ap) { return vsnprintf(str, size, format, ap); }
|
||||
inline const char* strstr_P(const char* haystack, const char* needle)
|
||||
{
|
||||
return strstr(haystack, needle);
|
||||
}
|
||||
inline char* strcpy_P(char* dest, const char* src)
|
||||
{
|
||||
return strcpy(dest, src);
|
||||
}
|
||||
inline size_t strlen_P(const char* s)
|
||||
{
|
||||
return strlen(s);
|
||||
}
|
||||
inline int vsnprintf_P(char* str, size_t size, const char* format, va_list ap)
|
||||
{
|
||||
return vsnprintf(str, size, format, ap);
|
||||
}
|
||||
|
||||
#define memcpy_P memcpy
|
||||
#define memmove_P memmove
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
org=$(cd ${0%/*}; pwd)
|
||||
cd ${org}/..
|
||||
pwd
|
||||
test -d cores/esp8266
|
||||
test -d libraries
|
||||
|
||||
# in a near future, restyle-all.sh will be renamed to restyle.sh
|
||||
# and will be checked against CI
|
||||
|
||||
for d in libraries; do
|
||||
find $d -name "*.ino" -exec \
|
||||
astyle \
|
||||
--suffix=none \
|
||||
--options=${org}/astyle_examples.conf {} \;
|
||||
done
|
||||
@@ -1,50 +1,64 @@
|
||||
#!/bin/sh
|
||||
# requires clang-format, git, python3 with pyyaml
|
||||
|
||||
set -e
|
||||
set -e -x
|
||||
|
||||
org=$(cd ${0%/*}; pwd)
|
||||
cd ${org}/..
|
||||
pwd
|
||||
test -d cores/esp8266
|
||||
test -d libraries
|
||||
root=$(git rev-parse --show-toplevel)
|
||||
test -d ${root}/cores/esp8266
|
||||
test -d ${root}/libraries
|
||||
|
||||
# should be: all="cores/esp8266 libraries"
|
||||
# allow `env CLANG_FORMAT=clang-format-13`, or some other version
|
||||
# default to v13, latest stable version from https://apt.llvm.org
|
||||
CLANG_FORMAT=${CLANG_FORMAT:-clang-format-13}
|
||||
|
||||
all="
|
||||
# TODO: waiting for llvm-14 to allow --style=file:<path-to-file>
|
||||
makeClangFormatStyle() {
|
||||
python3 -c 'import sys,yaml; sys.stdout.write(yaml.dump(yaml.safe_load(open(sys.argv[1], "r")), default_flow_style=True)); sys.stdout.flush();' $1
|
||||
}
|
||||
|
||||
#########################################
|
||||
# 'all' variable should be "cores/esp8266 libraries"
|
||||
|
||||
all=${1:-"
|
||||
cores/esp8266/Lwip*
|
||||
libraries/ESP8266mDNS
|
||||
libraries/Wire
|
||||
libraries/lwIP*
|
||||
cores/esp8266/Lwip*
|
||||
cores/esp8266/debug*
|
||||
cores/esp8266/core_esp8266_si2c.cpp
|
||||
cores/esp8266/StreamString.*
|
||||
cores/esp8266/StreamSend.*
|
||||
libraries/Netdump
|
||||
"
|
||||
tests
|
||||
"}
|
||||
|
||||
# core
|
||||
#########################################
|
||||
# restyling core & libraries
|
||||
|
||||
for d in $all; do
|
||||
if [ -d "$d" ]; then
|
||||
echo "-------- directory $d:"
|
||||
for e in c cpp h; do
|
||||
find $d -name "*.$e" -exec \
|
||||
astyle \
|
||||
--suffix=none \
|
||||
--options=${org}/astyle_core.conf {} \;
|
||||
done
|
||||
cd $root
|
||||
|
||||
style=$(makeClangFormatStyle ${root}/tests/clang-format-core.yaml)
|
||||
for target in $all; do
|
||||
if [ -d "$target" ]; then
|
||||
find $target \
|
||||
'(' -name "*.cpp" -o -name "*.c" -o -name "*.h" ')' \
|
||||
-exec $CLANG_FORMAT --verbose --style="$style" -i {} \;
|
||||
else
|
||||
echo "-------- file $d:"
|
||||
astyle --suffix=none --options=${org}/astyle_core.conf "$d"
|
||||
$CLANG_FORMAT --verbose --style="$style" -i $target
|
||||
fi
|
||||
done
|
||||
|
||||
# examples
|
||||
#########################################
|
||||
# restyling arduino examples
|
||||
|
||||
for d in libraries; do
|
||||
echo "-------- examples in $d:"
|
||||
find $d -name "*.ino" -exec \
|
||||
astyle \
|
||||
--suffix=none \
|
||||
--options=${org}/astyle_examples.conf {} \;
|
||||
done
|
||||
# TODO should not be matched, these are formatted externally
|
||||
# exclude=$(git submodule --quiet foreach git rev-parse --show-toplevel | grep libraries)
|
||||
|
||||
style=$(makeClangFormatStyle ${root}/tests/clang-format-arduino.yaml)
|
||||
find libraries \
|
||||
-path libraries/ESP8266SdFat -prune -o \
|
||||
-path libraries/Ethernet -prune -o \
|
||||
-path libraries/SoftwareSerial -prune -o \
|
||||
-name '*.ino' -exec $CLANG_FORMAT --verbose --style="$style" -i {} \;
|
||||
|
||||
#########################################
|
||||
|
||||
@@ -115,7 +115,8 @@ elif [ "$BUILD_TYPE" = host ]; then
|
||||
tests/ci/host_test.sh
|
||||
|
||||
elif [ "$BUILD_TYPE" = style ]; then
|
||||
tests/ci/install_astyle.sh
|
||||
tests/ci/check_restyle.sh
|
||||
tests/restyle.sh
|
||||
|
||||
else
|
||||
echo "BUILD_TYPE not set or invalid"
|
||||
|
||||
Reference in New Issue
Block a user