2017-03-03 6 views
2

Gibt es eine eingebaute in Funktion zu konvertieren wörtliche einen String in einen C-String zu konvertieren. Zum Beispiel:CMake Funktion String C Stringliteral

set(foo [[Hello\ World"!\]]) 
convert_to_cstring_literal(bar "${foo}") 
message("${foo}") # Should print (including quotes): "Hello\\ World\"!\\" 

Ich meine ich dies mit regulären Ausdrücken mit erheblichen Aufwand zu tun, aber wenn es eine eingebaute Funktion ist wäre es viel schöner.

+0

Sie können * * fast verwenden das ' ESCAPE_QUOTES '-Option auf' string (CONFIGURE', aber es [entgeht Backslashes nicht] (https://github.com/Kitware/CMake/blob/3c0de6db2d9e0580f23cc95c4a1e00a8f66108c9/Source/cmSystemTools.cxx#L208). – Timmmm

+0

Do w Sprechen wir über Pre-Prozessor-Definitionen? Sie werden automatisch maskiert (siehe [Richtlinie CMP0005] (https://cmake.org/cmake/help/latest/policy/CMP0005.html)). Andernfalls würde etwas aus ['CPack.cmake'] (https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/CPack.cmake#L351) genügen:' string (REGEX REPLACE "([\ \\ $ \ "])" "\\\\\\ 1" entkommen "$ {value}") '? – Florian

+0

es * ist * eine Präprozessordefinition, aber leider muss ich es zu einem Header schreiben und verwenden' configure_file() ', weil [Sie nicht zuverlässig sie auf der Kommandozeile übergeben können] (https://cmake.org/cmake/help/v3.8/prop_dir/COMPILE_DEFINITIONS.html#prop_dir:COMPILE_DEFINITIONS). auch meine Definition enthält mehr .??? C-Strings, es ist ein Array initialiser Liste wie folgt aus: '{ "foo", "bar"}' – Timmmm

Antwort

0

Drehen meines Kommentars in einer Antwort

Slightly die CMake die Funktion _cpack_escape_for_cmake von CPack.cmake Modifizierung ich in der Lage war erfolgreich folgendes zu testen:

cmake_minimum_required(VERSION 2.8) 

project(CStringLiteral) 

function(convert_to_cstring_literal var value) 
    string(REGEX REPLACE "([\\\$\"])" "\\\\\\1" escaped "${value}") 
    set("${var}" "\"${escaped}\"" PARENT_SCOPE) 
endfunction() 

set(foo [[Hello\ World"!\]]) 

convert_to_cstring_literal(bar "${foo}") 
message("${bar}") # prints "Hello\\ World\"!\\" 
0

Also, ich habe tatsächlich eine verwendete einen anderen Trick auf diesem nach oben: C++ rohen Stringliterale. Es ist natürlich nicht 100% garantiert, also benutze es nicht bei nicht vertrauenswürdiger Eingabe (nicht sicher warum du in CMake haben willst). Aber für die meisten Zwecke sollte es in Ordnung sein.

set(foo "R\"#?#:#?#(${foo})#?#:#?#\"") 
+0

Warum haben Sie '# # # #' als Trennzeichen für die C++ rohen String einfach nur neugierig, aber sieht irgendwie verwirrend aus .. – SebNag

+0

Es kann alles Mögliche sein.Ich habe '?' verwendet, da es nicht in Windows-Pfaden erscheinen kann, und die Zeichenfolge, die ich benutze, ist ein Pfad.Vorüber hinaus ist es nur eine verrückte Zufallsfolge, die ich hoffe niemandem bringt tatsächlich "foo" Sie werden Dinge brechen (daher warum ich sagte "es ist nicht 100%"). – Timmmm