Skip to content

Commit 3512caf

Browse files
committed
Made changes for issue #20 - Modify how 'override' argument is implemented
* Implemented getOutputFileModifiedDate() function to get the modified date of an embedded file. * Modified logic in main.cpp to follow issue #20 suggested behavior.
1 parent cc6bcc9 commit 3512caf

File tree

4 files changed

+155
-23
lines changed

4 files changed

+155
-23
lines changed

src/BaseGenerator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ namespace bin2cpp
4848
std::string BaseGenerator::getFileHeading(const char * iInputFilename)
4949
{
5050
std::string filename = getFilename(iInputFilename);
51-
uint64_t fileDateModified = getFileModifiedDate(iInputFilename);
51+
uint64_t lastModifiedDate = getFileModifiedDate(iInputFilename);
5252

5353
std::string header;
5454
header <<
5555
header << "/**\n";
5656
header << " * This file was generated by bin2cpp v" << getVersionString() << "\n";
5757
header << " * Copyright (C) 2013-" << bin2cpp::getCopyrightYear() << " end2endzone.com. All rights reserved.\n";
58-
header << " * Source code for file '" << filename << "', last modified " << fileDateModified << ".\n";
58+
header << " * Source code for file '" << filename << "', last modified " << lastModifiedDate << ".\n";
5959
header << " * Do not modify this file.\n";
6060
header << " */\n";
6161
return header;

src/common.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,33 @@
2020

2121
namespace bin2cpp
2222
{
23+
template <class T>
24+
inline bool parseValueT (const std::string& str, T & t)
25+
{
26+
static const T ZERO = (T)0;
27+
static const T MULTIPLIER = (T)10;
28+
static const T SIGN_MULTIPLIER = (T)-1;
29+
bool parseOK = false;
30+
t = ZERO;
31+
for(size_t i=0; i<str.size(); i++)
32+
{
33+
char c = str[i];
34+
if (c >= '0' && c <= '9')
35+
{
36+
t *= MULTIPLIER;
37+
c -= '0'; //convert character to numeric value
38+
t += (T)c;
39+
parseOK = true;
40+
}
41+
else if (c == '-')
42+
{
43+
t *= SIGN_MULTIPLIER;
44+
parseOK = true;
45+
}
46+
}
47+
return parseOK;
48+
}
49+
2350
//Note: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2
2451
template <class T>
2552
inline std::string toStringT (const T & t)
@@ -448,6 +475,43 @@ namespace bin2cpp
448475
return mod_time;
449476
}
450477

478+
uint64_t getOutputFileModifiedDate(const std::string & iPath)
479+
{
480+
uint64_t mod_time = 0;
481+
482+
FILE * f = fopen(iPath.c_str(), "r");
483+
if (!f)
484+
return mod_time;
485+
486+
//create buffer for each chunks from input buffer
487+
static const size_t BUFFER_SIZE = 10240;
488+
char buffer[BUFFER_SIZE];
489+
while(/*!feof(f)*/ fgets(buffer, BUFFER_SIZE, f) != NULL )
490+
{
491+
//read a text line of the file
492+
std::string text = buffer;
493+
494+
static const char * lastModifiedTag = "last modified";
495+
size_t lastModifiedIndex = text.find(lastModifiedTag);
496+
if (lastModifiedIndex != std::string::npos)
497+
{
498+
std::string date = text.substr(lastModifiedIndex);
499+
strReplace(date, lastModifiedTag, "");
500+
strReplace(date, " ", "");
501+
strReplace(date, ".", "");
502+
503+
//parse date into mod_time
504+
bool parseOK = parseValue(date, mod_time);
505+
if (parseOK)
506+
fclose(f); //force existing while loop
507+
}
508+
}
509+
510+
fclose(f);
511+
512+
return mod_time;
513+
}
514+
451515
std::string toString(const uint64_t & value)
452516
{
453517
return toStringT(value);
@@ -483,4 +547,9 @@ namespace bin2cpp
483547
return str;
484548
}
485549

550+
bool parseValue(const std::string& str, uint64_t & oValue)
551+
{
552+
return parseValueT(str, oValue);
553+
}
554+
486555
}; //bin2cpp

src/common.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,13 @@ namespace bin2cpp
160160
///<return>Returns the modified date of the given file.<return>
161161
uint64_t getFileModifiedDate(const std::string & iPath);
162162

163+
///<summary>
164+
///Returns the modified date from an embedded file's c++ header/source file.
165+
///</summary>
166+
///<param name="iPath">The valid path to a c++ header/source file.</param>
167+
///<return>Returns the modified date from an embedded file's c++ header/source file.<return>
168+
uint64_t getOutputFileModifiedDate(const std::string & iPath);
169+
163170
///<summary>
164171
///Converts the given value to string.
165172
///</summary>
@@ -195,4 +202,12 @@ namespace bin2cpp
195202
///<return>Returns the given string.<return>
196203
std::string& operator<<(std::string& str, const uint64_t & value);
197204

205+
///<summary>
206+
///Parse the given string into the given numeric variable.
207+
///</summary>
208+
///<param name="str">The input string which contains a numeric value.</param>
209+
///<param name="value">The output numeric value.</param>
210+
///<return>Returns true when the parsing is successful.<return>
211+
bool parseValue(const std::string& str, uint64_t & oValue);
212+
198213
}; //bin2cpp

src/main.cpp

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -209,25 +209,90 @@ int main(int argc, char* argv[])
209209
info << "...";
210210
bin2cpp::log(bin2cpp::LOG_INFO, info.c_str());
211211

212-
//generate header
212+
//prepare output files path
213213
std::string outputHeaderPath = outputFolder + "\\" + headerFilename;
214-
bin2cpp::log(bin2cpp::LOG_INFO, "Writing file \"%s\"...", outputHeaderPath.c_str());
214+
std::string outputCppPath = outputFolder + "\\" + headerFilename; bin2cpp::strReplace(outputCppPath, ".h", ".cpp");
215+
std::string cppFilename = headerFilename; bin2cpp::strReplace(cppFilename, ".h", ".cpp");
216+
uint64_t lastModifiedDate = getFileModifiedDate(inputFile);
217+
215218
bin2cpp::ErrorCodes headerResult = bin2cpp::ErrorCodes::Success;
219+
bin2cpp::ErrorCodes cppResult = bin2cpp::ErrorCodes::Success;
216220

217221
//check if header file already exists
218222
if (bin2cpp::fileExists(outputHeaderPath.c_str()))
219223
{
220-
if (!overrideExisting)
224+
uint64_t outputModifiedDate = getOutputFileModifiedDate(outputHeaderPath);
225+
bool outputFileOutdated = (outputModifiedDate == 0 || lastModifiedDate > outputModifiedDate);
226+
if (outputFileOutdated)
227+
{
228+
//should we force override flag ?
229+
if (overrideExisting)
230+
{
231+
//no problem, user has already choosen to update the output files.
232+
}
233+
else
234+
{
235+
//force overriding output files.
236+
std::string message;
237+
message << "Output file \'" << headerFilename << "\' is out of date. Forcing override flag";
238+
bin2cpp::log(bin2cpp::LOG_INFO, message.c_str());
239+
overrideExisting = true;
240+
}
241+
}
242+
else if (lastModifiedDate == outputModifiedDate)
243+
{
244+
//output file already up to date.
245+
headerResult = bin2cpp::ErrorCodes::OutputFilesSkipped;
246+
}
247+
else if (!overrideExisting)
248+
{
249+
//fail if not overriding output file
250+
bin2cpp::ErrorCodes error = bin2cpp::ErrorCodes::OutputFileAlreadyExist;
251+
bin2cpp::log(bin2cpp::LOG_ERROR, "%s (%s)", getErrorCodeDescription(error), outputHeaderPath.c_str());
252+
return error;
253+
}
254+
}
255+
256+
//check if cpp file already exists
257+
if (bin2cpp::fileExists(outputCppPath.c_str()))
258+
{
259+
uint64_t outputModifiedDate = getOutputFileModifiedDate(outputCppPath);
260+
bool outputFileOutdated = (outputModifiedDate == 0 || lastModifiedDate > outputModifiedDate);
261+
if (outputFileOutdated)
221262
{
263+
//should we force override flag ?
264+
if (overrideExisting)
265+
{
266+
//no problem, user has already choosen to update the output files.
267+
}
268+
else
269+
{
270+
//force overriding output files.
271+
std::string message;
272+
message << "Output file \'" << cppFilename << "\' is out of date. Forcing override flag";
273+
bin2cpp::log(bin2cpp::LOG_INFO, message.c_str());
274+
overrideExisting = true;
275+
}
276+
}
277+
else if (lastModifiedDate == outputModifiedDate)
278+
{
279+
//output file already up to date.
280+
cppResult = bin2cpp::ErrorCodes::OutputFilesSkipped;
281+
}
282+
else if (!overrideExisting)
283+
{
284+
//fail if not overriding output file
222285
bin2cpp::ErrorCodes error = bin2cpp::ErrorCodes::OutputFileAlreadyExist;
223286
bin2cpp::log(bin2cpp::LOG_ERROR, "%s (%s)", getErrorCodeDescription(error), outputHeaderPath.c_str());
224287
return error;
225288
}
226289
}
227290

291+
//generate header
228292
if (headerResult == bin2cpp::ErrorCodes::Success)
229293
{
230294
//generate file or override existing
295+
bin2cpp::log(bin2cpp::LOG_INFO, "Writing file \"%s\"...", outputHeaderPath.c_str());
231296
headerResult = generator->createHeaderEmbededFile(inputFile.c_str(), outputHeaderPath.c_str(), functionIdentifier.c_str());
232297
}
233298
if (headerResult == bin2cpp::ErrorCodes::Success)
@@ -246,27 +311,10 @@ int main(int argc, char* argv[])
246311
}
247312

248313
//generate cpp
249-
std::string outputCppPath = outputFolder + "\\" + headerFilename;
250-
bin2cpp::strReplace(outputCppPath, ".h", ".cpp");
251-
bin2cpp::log(bin2cpp::LOG_INFO, "Writing file \"%s\"...", outputCppPath.c_str());
252-
bin2cpp::ErrorCodes cppResult = bin2cpp::ErrorCodes::Success;
253-
254-
//check if cpp file already exists
255-
std::string cppFilename = headerFilename;
256-
bin2cpp::strReplace(cppFilename, ".h", ".cpp");
257-
if (bin2cpp::fileExists(outputCppPath.c_str()))
258-
{
259-
if (!overrideExisting)
260-
{
261-
bin2cpp::ErrorCodes error = bin2cpp::ErrorCodes::OutputFileAlreadyExist;
262-
bin2cpp::log(bin2cpp::LOG_ERROR, "%s (%s)", getErrorCodeDescription(error), outputCppPath.c_str());
263-
return error;
264-
}
265-
}
266-
267314
if (cppResult == bin2cpp::ErrorCodes::Success)
268315
{
269316
//generate file or override existing
317+
bin2cpp::log(bin2cpp::LOG_INFO, "Writing file \"%s\"...", outputCppPath.c_str());
270318
cppResult = generator->createCppEmbeddedFile(inputFile.c_str(), outputCppPath.c_str(), functionIdentifier.c_str(), chunkSize);
271319
}
272320
if (cppResult == bin2cpp::ErrorCodes::Success)

0 commit comments

Comments
 (0)