summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/CMakeCCompilerId.c9
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake78
-rw-r--r--Modules/CMakeLists.txt2
-rw-r--r--Source/cmBootstrapCommands.cxx3
-rw-r--r--Source/cmFileCommand.cxx10
-rw-r--r--Source/cmFileCommand.h7
-rw-r--r--Source/cmHexFileConverter.cxx266
-rw-r--r--Source/cmHexFileConverter.h33
-rw-r--r--Tests/StringFileTest/CMakeLists.txt22
-rw-r--r--Tests/StringFileTest/main.ihx21
-rw-r--r--Tests/StringFileTest/main.srec21
11 files changed, 419 insertions, 53 deletions
diff --git a/Modules/CMakeCCompilerId.c b/Modules/CMakeCCompilerId.c
index a29c6a0..8a8753a 100644
--- a/Modules/CMakeCCompilerId.c
+++ b/Modules/CMakeCCompilerId.c
@@ -41,14 +41,9 @@
/* sdcc, the small devices C compiler for embedded systems,
http://sdcc.sourceforge.net
- Beside this id not supported yet by CMake
- Unfortunately this doesn't work because SDCC (and other embedded compilers
- too) produce not binary files, but e.g. Intel hex files by default.
- This also means it has a different suffix (.ihx) so the file isn't even
- found. */
-/*
+ Beside this id not supported yet by CMake. */
#elif defined(SDCC)
-# define COMPILER_ID "SDCC" */
+# define COMPILER_ID "SDCC"
#elif defined(_COMPILER_VERSION)
# define COMPILER_ID "MIPSpro"
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index a0c0164..f0fce8f 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -66,56 +66,52 @@ MACRO(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
"${CMAKE_${lang}_COMPILER_ID_SRC}\" succeeded with the following output:\n"
"${CMAKE_${lang}_COMPILER_ID_OUTPUT}\n\n")
- # Find the executable produced by the compiler.
- SET(CMAKE_${lang}_COMPILER_ID_EXE)
- GET_FILENAME_COMPONENT(CMAKE_${lang}_COMPILER_ID_SRC_BASE ${CMAKE_${lang}_COMPILER_ID_SRC} NAME_WE)
- FOREACH(name a.out a.exe ${CMAKE_${lang}_COMPILER_ID_SRC_BASE}.exe)
- IF(EXISTS ${CMAKE_${lang}_COMPILER_ID_DIR}/${name})
- SET(CMAKE_${lang}_COMPILER_ID_EXE ${CMAKE_${lang}_COMPILER_ID_DIR}/${name})
- ENDIF(EXISTS ${CMAKE_${lang}_COMPILER_ID_DIR}/${name})
- ENDFOREACH(name)
-
- # Check if the executable was found.
- IF(CMAKE_${lang}_COMPILER_ID_EXE)
- # The executable was found.
+ # Find the executable produced by the compiler, try all files in the binary dir
+ SET(CMAKE_${lang}_COMPILER_ID)
+ FILE(GLOB COMPILER_${lang}_PRODUCED_FILES ${CMAKE_${lang}_COMPILER_ID_DIR}/*)
+ FOREACH(CMAKE_${lang}_COMPILER_ID_EXE ${COMPILER_${lang}_PRODUCED_FILES})
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Compilation of the ${lang} compiler identification source \""
"${CMAKE_${lang}_COMPILER_ID_SRC}\" produced \""
"${CMAKE_${lang}_COMPILER_ID_EXE}\"\n\n")
+ # only check if we don't have it yet
+ IF(NOT CMAKE_${lang}_COMPILER_ID)
+ # Read the compiler identification string from the executable file.
+ FILE(STRINGS ${CMAKE_${lang}_COMPILER_ID_EXE}
+ CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 2 REGEX "INFO:")
+ FOREACH(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
+ IF("${info}" MATCHES ".*INFO:compiler\\[([^]]*)\\].*")
+ STRING(REGEX REPLACE ".*INFO:compiler\\[([^]]*)\\].*" "\\1"
+ CMAKE_${lang}_COMPILER_ID "${info}")
+ ENDIF("${info}" MATCHES ".*INFO:compiler\\[([^]]*)\\].*")
+ IF("${info}" MATCHES ".*INFO:platform\\[([^]]*)\\].*")
+ STRING(REGEX REPLACE ".*INFO:platform\\[([^]]*)\\].*" "\\1"
+ CMAKE_${lang}_PLATFORM_ID "${info}")
+ ENDIF("${info}" MATCHES ".*INFO:platform\\[([^]]*)\\].*")
+ ENDFOREACH(info)
- # Read the compiler identification string from the executable file.
- FILE(STRINGS ${CMAKE_${lang}_COMPILER_ID_EXE}
- CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 2 REGEX "INFO:")
- FOREACH(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
- IF("${info}" MATCHES ".*INFO:compiler\\[([^]]*)\\].*")
- STRING(REGEX REPLACE ".*INFO:compiler\\[([^]]*)\\].*" "\\1"
- CMAKE_${lang}_COMPILER_ID "${info}")
- ENDIF("${info}" MATCHES ".*INFO:compiler\\[([^]]*)\\].*")
- IF("${info}" MATCHES ".*INFO:platform\\[([^]]*)\\].*")
- STRING(REGEX REPLACE ".*INFO:platform\\[([^]]*)\\].*" "\\1"
- CMAKE_${lang}_PLATFORM_ID "${info}")
- ENDIF("${info}" MATCHES ".*INFO:platform\\[([^]]*)\\].*")
- ENDFOREACH(info)
+ # Check the compiler identification string.
+ IF(CMAKE_${lang}_COMPILER_ID)
+ # The compiler identification was found.
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "The ${lang} compiler identification is ${CMAKE_${lang}_COMPILER_ID}, found in \""
+ "${CMAKE_${lang}_COMPILER_ID_EXE}\"\n\n")
+ ELSE(CMAKE_${lang}_COMPILER_ID)
+ # The compiler identification could not be found.
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "The ${lang} compiler identification could not be found in \""
+ "${CMAKE_${lang}_COMPILER_ID_EXE}\"\n\n")
+ ENDIF(CMAKE_${lang}_COMPILER_ID)
+ ENDIF(NOT CMAKE_${lang}_COMPILER_ID)
+ ENDFOREACH(CMAKE_${lang}_COMPILER_ID_EXE)
- # Check the compiler identification string.
- IF(CMAKE_${lang}_COMPILER_ID)
- # The compiler identification was found.
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "The ${lang} compiler identification is ${CMAKE_${lang}_COMPILER_ID}\n\n")
- ELSE(CMAKE_${lang}_COMPILER_ID)
- # The compiler identification could not be found.
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "The ${lang} compiler identification could not be found in \""
- "${CMAKE_${lang}_COMPILER_ID_EXE}\"\n\n")
- ENDIF(CMAKE_${lang}_COMPILER_ID)
- ELSE(CMAKE_${lang}_COMPILER_ID_EXE)
- # The executable was not found.
+ IF(NOT COMPILER_${lang}_PRODUCED_FILES)
+ # No executable was found.
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Compilation of the ${lang} compiler identification source \""
"${CMAKE_${lang}_COMPILER_ID_SRC}\" did not produce an executable in "
- "${CMAKE_${lang}_COMPILER_ID_DIR} "
- "with a name known to CMake.\n\n")
- ENDIF(CMAKE_${lang}_COMPILER_ID_EXE)
+ "${CMAKE_${lang}_COMPILER_ID_DIR} .\n\n")
+ ENDIF(NOT COMPILER_${lang}_PRODUCED_FILES)
IF(CMAKE_${lang}_COMPILER_ID)
MESSAGE(STATUS "The ${lang} compiler identification is "
diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt
index c575043..01e2595 100644
--- a/Modules/CMakeLists.txt
+++ b/Modules/CMakeLists.txt
@@ -1,5 +1,5 @@
# just install the modules
-# new file added, force rerunning cmake #
+# new file added, force rerunning cmake
SUBDIRS(Platform)
INSTALL_FILES(${CMAKE_DATA_DIR}/Modules .*\\.cmake$)
diff --git a/Source/cmBootstrapCommands.cxx b/Source/cmBootstrapCommands.cxx
index 19be6df..f129eb0 100644
--- a/Source/cmBootstrapCommands.cxx
+++ b/Source/cmBootstrapCommands.cxx
@@ -30,6 +30,7 @@
#include "cmBuildCommand.cxx"
#include "cmCMakeMinimumRequired.cxx"
#include "cmConfigureFileCommand.cxx"
+#include "cmCoreTryCompile.cxx"
#include "cmCreateTestSourceList.cxx"
#include "cmElseCommand.cxx"
#include "cmEnableTestingCommand.cxx"
@@ -47,6 +48,7 @@
#include "cmGetCMakePropertyCommand.cxx"
#include "cmGetFilenameComponentCommand.cxx"
#include "cmGetSourceFilePropertyCommand.cxx"
+#include "cmHexFileConverter.cxx"
#include "cmIfCommand.cxx"
#include "cmIncludeCommand.cxx"
#include "cmIncludeDirectoryCommand.cxx"
@@ -66,7 +68,6 @@
#include "cmStringCommand.cxx"
#include "cmSubdirCommand.cxx"
#include "cmTargetLinkLibrariesCommand.cxx"
-#include "cmCoreTryCompile.cxx"
#include "cmTryCompileCommand.cxx"
#include "cmTryRunCommand.cxx"
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index ed3ac2c..5b3390d 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -15,6 +15,8 @@
=========================================================================*/
#include "cmFileCommand.h"
+#include "cmake.h"
+#include "cmHexFileConverter.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -414,6 +416,14 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
return false;
}
}
+
+ std::string binaryFileName = this->Makefile->GetCurrentOutputDirectory();
+ binaryFileName += cmake::GetCMakeFilesDirectory();
+ binaryFileName += "/FileCommandStringsBinaryFile";
+ if (cmHexFileConverter::TryConvert(fileName.c_str(), binaryFileName.c_str()))
+ {
+ fileName = binaryFileName;
+ }
// Open the specified file.
#if defined(_WIN32) || defined(__CYGWIN__)
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index f758151..5868725 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -93,9 +93,10 @@ public:
"want to generate input files to CMake.\n"
"READ will read the content of a file and store it into the "
"variable.\n"
- "STRINGS will parse a list of ASCII strings from a file and store it "
- "in a variable. Binary data in the file are ignored. Carriage return "
- "(CR) characters are ignored. "
+ "STRINGS will parse a list of ASCII strings from a binary file and "
+ "store it in a variable. Binary data in the file are ignored. Carriage "
+ "return (CR) characters are ignored. It works also for Intel Hex and "
+ "Motorola S-record files.\n "
"LIMIT_COUNT sets the maximum number of strings to return. "
"LIMIT_INPUT sets the maximum number of bytes to read from "
"the input file. "
diff --git a/Source/cmHexFileConverter.cxx b/Source/cmHexFileConverter.cxx
new file mode 100644
index 0000000..f8d369f
--- /dev/null
+++ b/Source/cmHexFileConverter.cxx
@@ -0,0 +1,266 @@
+/*=========================================================================
+
+ Program: CMake - Cross-Platform Makefile Generator
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
+ See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+#include "cmHexFileConverter.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#define INTEL_HEX_MIN_LINE_LENGTH (1+8 +2)
+#define INTEL_HEX_MAX_LINE_LENGTH (1+8+(256*2)+2)
+#define MOTOROLA_SREC_MIN_LINE_LENGTH (2+2+4 +2)
+#define MOTOROLA_SREC_MAX_LINE_LENGTH (2+2+8+(256*2)+2)
+
+// might go to SystemTools ?
+static bool cm_IsHexChar(char c)
+{
+ return (((c >= '0') && (c <= '9'))
+ || ((c >= 'a') && (c <= 'f'))
+ || ((c >= 'A') && (c <= 'F')));
+}
+
+static unsigned int ChompStrlen(const char* line)
+{
+ if (line == 0)
+ {
+ return 0;
+ }
+ unsigned int length = strlen(line);
+ if ((line[length-1] == '\n') || (line[length-1] == '\r'))
+ {
+ length--;
+ }
+ if ((line[length-1] == '\n') || (line[length-1] == '\r'))
+ {
+ length--;
+ }
+ return length;
+}
+
+static bool OutputBin(FILE* file, const char * buf,
+ unsigned int startIndex, unsigned int stopIndex)
+{
+ bool success = true;
+ char hexNumber[3];
+ hexNumber[2] = '\0';
+ char outBuf[256];
+ int outBufCount = 0;
+ for (unsigned int i = startIndex; i < stopIndex; i += 2)
+ {
+ hexNumber[0] = buf[i];
+ hexNumber[1] = buf[i+1];
+ unsigned int convertedByte = 0;
+ if (sscanf(hexNumber, "%x", &convertedByte) != 1)
+ {
+ success = false;
+ break;
+ }
+ outBuf[outBufCount] = convertedByte & 0xff;
+ outBufCount++;
+ }
+ if (success)
+ {
+ success = (fwrite(outBuf, 1, outBufCount, file)==outBufCount);
+ }
+ return success;
+}
+
+// see http://www.die.net/doc/linux/man/man5/srec.5.html
+static bool ConvertMotorolaSrecLine(const char* buf, FILE* outFile)
+{
+ unsigned int slen = ChompStrlen(buf);
+ if ((slen < MOTOROLA_SREC_MIN_LINE_LENGTH)
+ || (slen > MOTOROLA_SREC_MAX_LINE_LENGTH))
+ {
+ return false;
+ }
+
+ // line length must be even
+ if (slen % 2 == 1)
+ {
+ return false;
+ }
+
+ if (buf[0] != 'S')
+ {
+ return false;
+ }
+
+ unsigned int dataStart = 0;
+ // ignore extra address records
+ if ((buf[1] == '5') || (buf[1] == '7') || (buf[1] == '8') || (buf[1] == '9'))
+ {
+ return true;
+ }
+ else if (buf[1] == '1')
+ {
+ dataStart = 8;
+ }
+ else if (buf[1] == '2')
+ {
+ dataStart = 10;
+ }
+ else if (buf[1] == '3')
+ {
+ dataStart = 12;
+ }
+ else // unknown record type
+ {
+ return false;
+ }
+
+ // ignore the last two bytes (checksum)
+ return OutputBin(outFile, buf, dataStart, slen - 2);
+}
+
+// see http://en.wikipedia.org/wiki/Intel_hex
+static bool ConvertIntelHexLine(const char* buf, FILE* outFile)
+{
+ unsigned int slen = ChompStrlen(buf);
+ if ((slen < INTEL_HEX_MIN_LINE_LENGTH)
+ || (slen > INTEL_HEX_MAX_LINE_LENGTH))
+ {
+ return false;
+ }
+
+ // line length must be odd
+ if (slen % 2 == 0)
+ {
+ return false;
+ }
+
+ if ((buf[0] != ':') || (buf[7] != '0'))
+ {
+ return false;
+ }
+
+ unsigned int dataStart = 0;
+ if ((buf[8] == '0') || (buf[8] == '1'))
+ {
+ dataStart = 9;
+ }
+ // ignore extra address records
+ else if ((buf[8] == '2') || (buf[8] == '3') || (buf[8] == '4') || (buf[8] == '5'))
+ {
+ return true;
+ }
+ else // unknown record type
+ {
+ return false;
+ }
+
+// ignore the last two bytes (checksum)
+ return OutputBin(outFile, buf, dataStart, slen - 2);
+}
+
+cmHexFileConverter::FileType cmHexFileConverter::DetermineFileType(
+ const char* inFileName)
+{
+ char buf[1024];
+ FILE* inFile = fopen(inFileName, "rb");
+ if (inFile == 0)
+ {
+ return Binary;
+ }
+
+ fgets(buf, 1024, inFile);
+ fclose(inFile);
+ FileType type = Binary;
+ unsigned int minLineLength = 0;
+ unsigned int maxLineLength = 0;
+ if (buf[0] == ':') // might be an intel hex file
+ {
+ type = IntelHex;
+ minLineLength = INTEL_HEX_MIN_LINE_LENGTH;
+ maxLineLength = INTEL_HEX_MAX_LINE_LENGTH;
+ }
+ else if (buf[0] == 'S') // might be a motorola srec file
+ {
+ type = MotorolaSrec;
+ minLineLength = MOTOROLA_SREC_MIN_LINE_LENGTH;
+ maxLineLength = MOTOROLA_SREC_MAX_LINE_LENGTH;
+ }
+ else
+ {
+ return Binary;
+ }
+
+ int slen = ChompStrlen(buf);
+ if ((slen < minLineLength) || (slen > maxLineLength))
+ {
+ return Binary;
+ }
+
+ for (unsigned int i = 1; i < slen; i++)
+ {
+ if (!cm_IsHexChar(buf[i]))
+ {
+ return Binary;
+ }
+ }
+ return type;
+}
+
+bool cmHexFileConverter::TryConvert(const char* inFileName,
+ const char* outFileName)
+{
+ FileType type = DetermineFileType(inFileName);
+ if (type == Binary)
+ {
+ return false;
+ }
+
+ // try to open the file
+ FILE* inFile = fopen(inFileName, "rb");
+ FILE* outFile = fopen(outFileName, "wb");
+ if ((inFile == 0) || (outFile == 0))
+ {
+ if (inFile != 0)
+ {
+ fclose(inFile);
+ }
+ if (outFile != 0)
+ {
+ fclose(outFile);
+ }
+ return false;
+ }
+
+ // convert them line by line
+ bool success = false;
+ char buf[1024];
+ while (fgets(buf, 1024, inFile) != 0)
+ {
+ if (type == MotorolaSrec)
+ {
+ success = ConvertMotorolaSrecLine(buf, outFile);
+ }
+ else if (type == IntelHex)
+ {
+ success = ConvertIntelHexLine(buf, outFile);
+ }
+ if (success == false)
+ {
+ break;
+ }
+ }
+
+ // close them again
+ fclose(inFile);
+ fclose(outFile);
+ return success;
+}
+
diff --git a/Source/cmHexFileConverter.h b/Source/cmHexFileConverter.h
new file mode 100644
index 0000000..8b6dc72
--- /dev/null
+++ b/Source/cmHexFileConverter.h
@@ -0,0 +1,33 @@
+/*=========================================================================
+
+ Program: CMake - Cross-Platform Makefile Generator
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
+ See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef cmHexFileConverter_h
+#define cmHexFileConverter_h
+
+/** \class cmHexFileConverter
+ * \brief Can detects Intel Hex and Motorola S-record files and convert them
+ * to binary files.
+ *
+ */
+class cmHexFileConverter
+{
+public:
+ enum FileType {Binary, IntelHex, MotorolaSrec};
+ static FileType DetermineFileType(const char* inFileName);
+ static bool TryConvert(const char* inFileName, const char* outFileName);
+};
+
+#endif
diff --git a/Tests/StringFileTest/CMakeLists.txt b/Tests/StringFileTest/CMakeLists.txt
index c2bb53f..36d15ce 100644
--- a/Tests/StringFileTest/CMakeLists.txt
+++ b/Tests/StringFileTest/CMakeLists.txt
@@ -16,6 +16,28 @@ ELSE("${infile_strings}" STREQUAL "${infile_strings_goal}")
"FILE(STRINGS) incorrectly read [${infile_strings}]")
ENDIF("${infile_strings}" STREQUAL "${infile_strings_goal}")
+
+# test that FILE(STRINGS) also work with Intel hex and Motorola S-record files
+# this file has been created with "sdcc main.c"
+FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/main.ihx" infile_strings REGEX INFO)
+SET(infile_strings_goal "INFO:compiler\\[SDCC-HEX\\]")
+IF("${infile_strings}" MATCHES "${infile_strings_goal}")
+ MESSAGE("FILE(STRINGS) correctly read from hex file [${infile_strings}]")
+ELSE("${infile_strings}" MATCHES "${infile_strings_goal}")
+ MESSAGE(SEND_ERROR
+ "FILE(STRINGS) incorrectly read from hex file [${infile_strings}]")
+ENDIF("${infile_strings}" MATCHES "${infile_strings_goal}")
+
+# this file has been created with "sdcc main.c --out-fmt-s19"
+FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/main.srec" infile_strings REGEX INFO)
+SET(infile_strings_goal "INFO:compiler\\[SDCC-SREC\\]")
+IF("${infile_strings}" MATCHES "${infile_strings_goal}")
+ MESSAGE("FILE(STRINGS) correctly read from srec file [${infile_strings}]")
+ELSE("${infile_strings}" MATCHES "${infile_strings_goal}")
+ MESSAGE(SEND_ERROR
+ "FILE(STRINGS) incorrectly read from srec file [${infile_strings}]")
+ENDIF("${infile_strings}" MATCHES "${infile_strings_goal}")
+
# String test
STRING(REGEX MATCH "[cC][mM][aA][kK][eE]" rmvar "CMake is great")
STRING(REGEX MATCHALL "[cC][mM][aA][kK][eE]" rmallvar "CMake is better than cmake or CMake")
diff --git a/Tests/StringFileTest/main.ihx b/Tests/StringFileTest/main.ihx
new file mode 100644
index 0000000..c1d1dd2
--- /dev/null
+++ b/Tests/StringFileTest/main.ihx
@@ -0,0 +1,21 @@
+:03000000020003F8
+:03005C0002005F40
+:05005F0012006480FEA8
+:010064002279
+:0E006900494E464F3A636F6D70696C65725B6D
+:0A007700534443432D4845585D00F3
+:06003200E478FFF6D8FDA2
+:080010007900E94400601B7A4D
+:0500180000900081785A
+:03001D000075A0CB
+:0A00200000E493F2A308B800020503
+:08002A00A0D9F4DAF275A0FF81
+:080038007800E84400600A7939
+:030040000075A0A8
+:0600430000E4F309D8FC03
+:080049007800E84400600C7926
+:0B00510000900000E4F0A3D8FCD9FAF6
+:03000300758107FD
+:0A000600120065E582600302005F4E
+:04006500758200227E
+:00000001FF
diff --git a/Tests/StringFileTest/main.srec b/Tests/StringFileTest/main.srec
new file mode 100644
index 0000000..bd47c29
--- /dev/null
+++ b/Tests/StringFileTest/main.srec
@@ -0,0 +1,21 @@
+S1060000020003F4
+S106005C02005F3C
+S108005F12006480FEA4
+S10400642275
+S1110069494E464F3A636F6D70696C65725B69
+S10E0077534443432D535245435D00A6
+S1090032E478FFF6D8FD9E
+S10B00107900E94400601B7A49
+S1080018009000827855
+S106001D0075A0C7
+S10D002000E493F2A308B8000205FF
+S10B002AA0D9F4DAF275A0FF7D
+S10B00387800E84400600A7935
+S10600400075A0A4
+S109004300E4F309D8FCFF
+S10B00497800E84400600C7922
+S10E005100900000E4F0A3D8FCD9FAF2
+S1060003758107F9
+S10D0006120065E582600302005F4A
+S1070065758200227A
+S9030000FC