3

I have a text file with some C-like plain text. I would like to, at compile time (and ideally using cmake), take the text in this file and use it to generate a simple C++ header file - one that has a couple of includes, namespace declaration, and an std::string whose value is the contents of my text file, new lines and everything included.

What's the best way to do this?

7
  • A simple shell script should be able to do it. Read the file and then write it into the initialization of std::string varname = "...";. The main thing to remember is to escape any double quotes and backslashes. Commented May 27, 2016 at 16:09
  • @Barmar: Probably easier to use a raw string literal (at least in most cases). Commented May 27, 2016 at 16:14
  • I'm pretty sure this is a duplicate. The easiest way is to use some nested #include statement inside a raw string literal definition. Commented May 27, 2016 at 16:14
  • If the main goal is to get the file contents into a string literal, you might appreciate the work going on for a file string literals proposal. Commented May 27, 2016 at 16:16
  • Raw string literals looks very much what I would love to use if I wasn't stuck on C++ 98... =\ Commented May 27, 2016 at 16:33

1 Answer 1

1

Okay, so I went with a solution different from the ones suggested here. Here's what I did.

Inside my source code, I define a handler class where I will make use of the string literal I need. Two things are important here:

  • The header file is actually an .hpp.in while under version control. The implementation file is a normal .cpp
  • Inside this header file, I choose a variable and #define it so: #define MY_STRING @MY_STRING@

Now, inside the CMakeLists.txt responsible for these two files, I do this:

  • Read the raw text file into a cmake variable
  • Remove all // comments, save the result in a temporary variable
  • Replace all \n characters with the string "newline", save the result into a new temporary variable
  • Define the same variable I used in my header above above (i.e. MY_STRING), and assign it from that latest temporary variable
  • Copy the header from the its location under ${CMAKE_SOURCE_DIR} into the appropriate location under ${CMAKE_BINARY_DIR} (and renaming it to a .hpp) by specifying @ONLY. This ensures that cmake will copy the header file, but will also update the #define MY_STRING @MY_STRING@ with the value of MY_STRING I set a little earlier.

Finally, inside the implementation file for my handler I define the following macros:

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

so that I can call TOSTRING(MY_STRING) and assign the output to an std::string my_string. Once this is done, all I need to do is replace the "newline" placeholder strings with "\n" - and I am done! my_string now has a value equivalent to the the one in the raw text file (sans the comments there).

I wish I had more time to play with this, and fewer other tasks to distract me, but the way things are, this will have to do for now.

Thank you all for you help!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.