mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-04 13:19:51 -05:00
ENH: make the compiler id detection work, even if the output file name of
the compiler is completely unknown and even if it produces intel hex or motorola s-record files, with test Alex
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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. "
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user