From 7b54af713dd9ab72335dabb161afba8cd2cc4cc8 Mon Sep 17 00:00:00 2001 From: Alexander Neundorf Date: Wed, 2 Jan 2008 16:46:38 -0500 Subject: [PATCH] ENH: add the keywords OFFSET and HEX to the FILE() command, using OFFSET an offset can be specified where the reading starts, and using HEX the data can be converted into a hex string, so binary data can be compared with text functions -add docs for LIMIT, OFFSET and HEX Alex --- Source/cmFileCommand.cxx | 97 ++++++++++++++++++++++++++++++---------- Source/cmFileCommand.h | 6 ++- 2 files changed, 78 insertions(+), 25 deletions(-) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 092dfb183..1a12ddfca 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -205,15 +205,38 @@ bool cmFileCommand::HandleReadCommand(std::vector const& args) return false; } - std::string fileName = args[1]; - if ( !cmsys::SystemTools::FileIsFullPath(args[1].c_str()) ) + cmCommandArgumentsHelper argHelper; + cmCommandArgumentGroup group; + + cmCAString readArg (&argHelper, "READ"); + cmCAString fileNameArg (&argHelper, 0); + cmCAString resultArg (&argHelper, 0); + + cmCAString offsetArg (&argHelper, "OFFSET", &group); + cmCAString limitArg (&argHelper, "LIMIT", &group); + cmCAEnabler hexOutputArg (&argHelper, "HEX", &group); + readArg.Follows(0); + fileNameArg.Follows(&readArg); + resultArg.Follows(&fileNameArg); + group.Follows(&resultArg); + argHelper.Parse(&args, 0); + + std::string fileName = fileNameArg.GetString(); + if ( !cmsys::SystemTools::FileIsFullPath(fileName.c_str()) ) { fileName = this->Makefile->GetCurrentDirectory(); - fileName += "/" + args[1]; + fileName += "/" + fileNameArg.GetString(); } - std::string variable = args[2]; + std::string variable = resultArg.GetString(); + + // Open the specified file. +#if defined(_WIN32) || defined(__CYGWIN__) + std::ifstream file(fileName.c_str(), std::ios::in | (hexOutputArg.IsEnabled()?std::ios::binary:0)); +#else std::ifstream file(fileName.c_str(), std::ios::in); +#endif + if ( !file ) { std::string error = "Internal CMake error when trying to open file: "; @@ -223,36 +246,64 @@ bool cmFileCommand::HandleReadCommand(std::vector const& args) return false; } - // if there a limit? + // is there a limit? long sizeLimit = -1; - if (args.size() >= 5 && args[3] == "LIMIT") + if (limitArg.GetString().size() > 0) { - sizeLimit = atoi(args[4].c_str()); + sizeLimit = atoi(limitArg.GetCString()); } - std::string output; - std::string line; - bool has_newline = false; - while (sizeLimit != 0 && - cmSystemTools::GetLineFromStream(file, line, &has_newline, - sizeLimit) ) + // is there an offset? + long offset = 0; + if (offsetArg.GetString().size() > 0) { - if (sizeLimit > 0) + offset = atoi(offsetArg.GetCString()); + } + + file.seekg(offset); + + std::string output; + + if (hexOutputArg.IsEnabled()) + { + // Convert part of the file into hex code + int c; + while((sizeLimit != 0) && (c = file.get(), file)) { - sizeLimit = sizeLimit - static_cast(line.size()); - if (has_newline) + char hex[4]; + sprintf(hex, "%x", c&0xff); + output += hex; + if (sizeLimit > 0) { sizeLimit--; } - if (sizeLimit < 0) - { - sizeLimit = 0; - } } - output += line; - if ( has_newline ) + } + else + { + std::string line; + bool has_newline = false; + while (sizeLimit != 0 && + cmSystemTools::GetLineFromStream(file, line, &has_newline, + sizeLimit) ) { - output += "\n"; + if (sizeLimit > 0) + { + sizeLimit = sizeLimit - static_cast(line.size()); + if (has_newline) + { + sizeLimit--; + } + if (sizeLimit < 0) + { + sizeLimit = 0; + } + } + output += line; + if ( has_newline ) + { + output += "\n"; + } } } this->Makefile->AddDefinition(variable.c_str(), output.c_str()); diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index b629df0a4..2fed8afa6 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -68,7 +68,7 @@ public: return " file(WRITE filename \"message to write\"... )\n" " file(APPEND filename \"message to write\"... )\n" - " file(READ filename variable [LIMIT numBytes])\n" + " file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX])\n" " file(STRINGS filename variable [LIMIT_COUNT num]\n" " [LIMIT_INPUT numBytes] [LIMIT_OUTPUT numBytes]\n" " [LENGTH_MINIMUM numBytes] [LENGTH_MAXIMUM numBytes]\n" @@ -93,7 +93,9 @@ public: "because it will lead to an infinite loop. Use configure_file if you " "want to generate input files to CMake.\n" "READ will read the content of a file and store it into the " - "variable.\n" + "variable. It will start at the given offset and read up to numBytes. " + "If the argument HEX is given, the binary data will be converted to " + "hexadecimal representation and this will be stored in 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. It works also for Intel Hex and "