2011-08-24 8 views
12

Qual è il modo migliore per unire una lista in CMake in una stringa?Il modo migliore/più breve per unire un elenco in CMake

Unendomi intendo convertire SET (somelist "a" "b" "c \; c") a "a: b: c; c" dove è possibile selezionare la stringa di colla (":"). Il seguente codice funziona ma è VERAMENTE lungo, c'è un modo migliore?

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" 

Purtroppo utilizzando STRING (REPLACE ...) non funziona:

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" 

risposta

10

Di solito questo compito viene risolto con un semplice comando string REPLACE . È possibile trovare un numero di tali sostituzioni negli script in arrivo con cmake. Ma se si ha realmente bisogno di preoccuparsi e virgola all'interno voi i valori, quindi è possibile utilizzare il seguente codice:

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

È possibile utilizzare la funzione string REPLACE:

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

Oh sì, grazie, questo funziona. Ma questo significa che non posso avere una lista in cui un elemento contiene un punto e virgola? – Geli

+1

Ho aggiornato la domanda per includere un elenco con elementi che contengono il punto e virgola. – Geli

+0

La funzione originale JOIN non gestisce nemmeno il punto e virgola. Emette "a: b: cc" sotto Windows con cmake 2.8.5. – sakra

5

Le risposte di cui sopra sono ok, quando non si utilizza il punto e virgola o quando si può (e vuole) di fuga loro. preferisco non di fuggire e virgola, così ho scritto la seguente funzione:

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() 

Il vantaggio è che la lista può essere vuoto e non deve essere in una variabile (ma può essere scritto nel posto di invocazione).

L'utilizzo è:

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' 
Problemi correlati