2011-08-24 8 views
12

Jaki jest najlepszy sposób dołączenia do listy w CMake w ciągu znaków?Najlepszy/Najkrótszy sposób na dołączenie do listy w CMake

Przystępując mam na myśli przekonwertować SET (somelist "a" "b" "c \; c") na "a: b: c; c", gdzie ciąg klej (":") jest do wybrania. Poniższy kod działa, ale jest NAPRAWDĘ długi, czy istnieje lepszy sposób?

FUNCTION(JOIN LISTNAME GLUE OUTPUT) 
SET(_TMP_STR "") 
    FOREACH(VAL ${${LISTNAME}}) 
    SET(_TMP_STR "${_TMP_STR}${GLUE}${VAL}") 
    ENDFOREACH(VAL ${${LISTNAME}}) 
    STRING(LENGTH "${GLUE}" GLUE_LEN) 
    STRING(LENGTH "${_TMP_STR}" OUT_LEN) 
    MATH(EXPR OUT_LEN ${OUT_LEN}-${GLUE_LEN}) 
    STRING(SUBSTRING "${_TMP_STR}" ${GLUE_LEN} ${OUT_LEN} _TMP_STR) 
    SET(${OUTPUT} "${_TMP_STR}" PARENT_SCOPE) 
ENDFUNCTION() 

#USAGE: 
SET(somelist "a" "b" "c\;c") 
JOIN(somelist ":" output) 
MESSAGE("${output}") # will output "a:b:c;c" 

Niestety używając String (REPLACE ...) nie działa:

function(JOINSTRREPLACE VALUES GLUE OUTPUT) 
    string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}") 
    set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE) 
endfunction() 
JOINSTRREPLACE("${somelist}" ":" output) 
MESSAGE(${output}) # will output "a:b:c\:c" 

Odpowiedz

10

Zazwyczaj jest to zadanie jest rozwiązane z prostego polecenia string REPLACE . Możesz znaleźć wiele takich zamienników w skryptach przychodzących z cmake. Ale jeśli naprawdę trzeba dbać o średnikami wewnątrz ciebie wartości, a następnie można użyć następującego kodu:

function(JOIN VALUES GLUE OUTPUT) 
    string (REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}") 
    string (REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping 
    set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE) 
endfunction() 

SET(letters "" "\;a" b c "d\;d") 
JOIN("${letters}" ":" output) 
MESSAGE("${output}") # :;a:b:c:d;d 
6

Można użyć string REPLACE funkcję:

function(JOIN VALUES GLUE OUTPUT) 
    string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}") 
    set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE) 
endfunction() 

#USAGE: 
SET(somelist a b c) 
JOIN("${somelist}" ":" output) 
MESSAGE("${output}") # will output "a:b:c" 
+0

Aha dzięki, to działa. Ale czy to oznacza, że ​​nie mogę mieć listy, w której element zawiera średnik? – Geli

+1

Zaktualizowałem pytanie, dodając listę zawierającą elementy, które zawierają średniki. – Geli

+0

Twoja oryginalna funkcja JOIN również nie radzi sobie ze średnikami. Wyprowadza "a: b: cc" pod Windows z cmake 2.8.5. – sakra

5

Odpowiedzi powyżej są OK, jeśli nie używać średników lub gdy można (i chce) ucieczkę im. wolę nie uciec średników, więc napisałem następującą funkcję:

function(JOIN OUTPUT GLUE) 
    set(_TMP_RESULT "") 
    set(_GLUE "") # effective glue is empty at the beginning 
    foreach(arg ${ARGN}) 
     set(_TMP_RESULT "${_TMP_RESULT}${_GLUE}${arg}") 
     set(_GLUE "${GLUE}") 
    endforeach() 
    set(${OUTPUT} "${_TMP_RESULT}" PARENT_SCOPE) 
endfunction() 

Zaletą jest to, że lista może być pusta i nie muszą być w zmiennej (ale może być napisany w miejscu inwokacji).

Użycie jest:

set(SOME_LIST a b c d) 
join(RESULT "/" ${SOME_LIST}) 
message(STATUS "RESULT='${RESULT}'") # outputs RESULT='a/b/c/d' 
# or 
join(RESULT " " e f g h) 
message(STATUS "RESULT='${RESULT}'") # outputs RESULT='e f g h'