Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert from decimal to hexadecimal in cmake

Tags:

cmake

The Y: Is it possible to take a variable A with 16 decimal and convert it to 10 hexadecimal, and vice versa, in a CMake?

Google searching only led me to the following:

http://public.kitware.com/pipermail/cmake/2008-September/024092.html

Which doesn't do the conversion.

The X: I'm trying to use "Configure File", reading the configured value as a decimal and outputting it as a hexadecimal in the configured header file.

like image 320
IdeaHat Avatar asked Sep 29 '22 17:09

IdeaHat


2 Answers

I rolled my own, but this feels like it should be a built-in

    cmake_minimum_required (VERSION 2.6.4)

    macro(HEXCHAR2DEC VAR VAL)
        if (${VAL} MATCHES "[0-9]")
            SET(${VAR} ${VAL})
        elseif(${VAL} MATCHES "[aA]")
            SET(${VAR} 10)
        elseif(${VAL} MATCHES "[bB]")
            SET(${VAR} 11)
        elseif(${VAL} MATCHES "[cC]")
            SET(${VAR} 12)
        elseif(${VAL} MATCHES "[dD]")
            SET(${VAR} 13)
        elseif(${VAL} MATCHES "[eE]")
            SET(${VAR} 14)
        elseif(${VAL} MATCHES "[fF]")
            SET(${VAR} 15)
        else()
            MESSAGE(FATAL_ERROR "Invalid format for hexidecimal character")
        endif()

    endmacro(HEXCHAR2DEC)

    macro(HEX2DEC VAR VAL)

        IF (${VAL} EQUAL 0)
            SET(${VAR} 0)
        ELSE()

            SET(CURINDEX 0)
            STRING(LENGTH "${VAL}" CURLENGTH)

            SET(${VAR} 0)

            while (CURINDEX LESS  CURLENGTH)

                STRING(SUBSTRING "${VAL}" ${CURINDEX} 1 CHAR)

                HEXCHAR2DEC(CHAR ${CHAR})

                MATH(EXPR POWAH "(1<<((${CURLENGTH}-${CURINDEX}-1)*4))")
                MATH(EXPR CHAR "(${CHAR}*${POWAH})")
                MATH(EXPR ${VAR} "${${VAR}}+${CHAR}")
                MATH(EXPR CURINDEX "${CURINDEX}+1")
            endwhile()
        ENDIF()

    endmacro(HEX2DEC)

    macro(DECCHAR2HEX VAR VAL)

        if (${VAL} LESS 10)
            SET(${VAR} ${VAL})
        elseif(${VAL} EQUAL 10)
            SET(${VAR} "A")
        elseif(${VAL} EQUAL 11)
            SET(${VAR} "B")
        elseif(${VAL} EQUAL 12)
            SET(${VAR} "C")
        elseif(${VAL} EQUAL 13)
            SET(${VAR} "D")
        elseif(${VAL} EQUAL 14)
            SET(${VAR} "E")
        elseif(${VAL} EQUAL 15)
            SET(${VAR} "F")
        else()
            MESSAGE(FATAL_ERROR "Invalid format for hexidecimal character")
        endif()
    endmacro(DECCHAR2HEX)

    macro(DEC2HEX VAR VAL)
        if (${VAL} EQUAL 0)
            SET(${VAR} 0)
        ELSE()
            SET(VAL2 ${VAL})
            SET(${VAR} "")

            WHILE (${VAL2} GREATER 0)
                MATH(EXPR VALCHAR "(${VAL2}&15)")
                DECCHAR2HEX(VALCHAR ${VALCHAR})
                SET(${VAR} "${VALCHAR}${${VAR}}")
                MATH(EXPR VAL2 "${VAL2} >> 4")
            ENDWHILE()
        ENDIF()
    endmacro(DEC2HEX)
like image 183
IdeaHat Avatar answered Oct 05 '22 08:10

IdeaHat


Using some tricks you can do this fairly simply. CMake's expressions use int internally, so it only works up to 231-1 bits. Something like this (you might want to alter it for big endian or whatever).

function (NumberToHex number output)
    set (chars "0123456789abcdef")
    set (hex "")

    foreach (i RANGE 7)
        math (EXPR nibble "${number} & 15")
        string (SUBSTRING "${chars}" "${nibble}" 1 nibble_hex)
        string (APPEND hex "${nibble_hex}")

        math (EXPR number "${number} >> 4")
    endforeach ()

    string (REGEX REPLACE "(.)(.)" "\\2\\1" hex "${hex}")
    set ("${output}" "${hex}" PARENT_SCOPE)
endfunction ()
like image 35
Timmmm Avatar answered Oct 05 '22 07:10

Timmmm