\doxysection{src/core/utils.c File Reference} \label{utils_8c}\index{src/core/utils.c@{src/core/utils.c}} {\ttfamily \#include $<$stdbool.\+h$>$}\newline {\ttfamily \#include $<$string.\+h$>$}\newline {\ttfamily \#include $<$stdint.\+h$>$}\newline {\ttfamily \#include $<$errno.\+h$>$}\newline {\ttfamily \#include $<$stdio.\+h$>$}\newline {\ttfamily \#include $<$inttypes.\+h$>$}\newline {\ttfamily \#include $<$limits.\+h$>$}\newline {\ttfamily \#include $<$osmocom/core/utils.\+h$>$}\newline {\ttfamily \#include $<$osmocom/core/bit64gen.\+h$>$}\newline {\ttfamily \#include \char`\"{}config.\+h\char`\"{}}\newline \doxysubsection*{Macros} \begin{DoxyCompactItemize} \item \#define \textbf{ BACKSLASH\+\_\+\+CASE}(\textbf{ c}, repr) \end{DoxyCompactItemize} \doxysubsection*{Functions} \begin{DoxyCompactItemize} \item const char $\ast$ \textbf{ get\+\_\+value\+\_\+string} (const struct \textbf{ value\+\_\+string} $\ast$vs, uint32\+\_\+t val) \begin{DoxyCompactList}\small\item\em get human-\/readable string for given value \end{DoxyCompactList}\item const char $\ast$ \textbf{ get\+\_\+value\+\_\+string\+\_\+or\+\_\+null} (const struct \textbf{ value\+\_\+string} $\ast$vs, uint32\+\_\+t val) \begin{DoxyCompactList}\small\item\em get human-\/readable string or NULL for given value \end{DoxyCompactList}\item int \textbf{ get\+\_\+string\+\_\+value} (const struct \textbf{ value\+\_\+string} $\ast$vs, const char $\ast$str) \begin{DoxyCompactList}\small\item\em get numeric value for given human-\/readable string \end{DoxyCompactList}\item char \textbf{ osmo\+\_\+bcd2char} (uint8\+\_\+t bcd) \begin{DoxyCompactList}\small\item\em Convert BCD-\/encoded digit into printable character. \end{DoxyCompactList}\item uint8\+\_\+t \textbf{ osmo\+\_\+char2bcd} (char \textbf{ c}) \begin{DoxyCompactList}\small\item\em Convert number in ASCII to BCD value. \end{DoxyCompactList}\item int \textbf{ osmo\+\_\+bcd2str} (char $\ast$dst, size\+\_\+t dst\+\_\+size, const uint8\+\_\+t $\ast$bcd, int start\+\_\+nibble, int end\+\_\+nibble, bool allow\+\_\+hex) \begin{DoxyCompactList}\small\item\em Convert BCD to string. \end{DoxyCompactList}\item int \textbf{ osmo\+\_\+str2bcd} (uint8\+\_\+t $\ast$dst, size\+\_\+t dst\+\_\+size, const char $\ast$\textbf{ digits}, int start\+\_\+nibble, int end\+\_\+nibble, bool allow\+\_\+hex) \begin{DoxyCompactList}\small\item\em Convert string to BCD. \end{DoxyCompactList}\item int \textbf{ osmo\+\_\+hexparse} (const char $\ast$str, uint8\+\_\+t $\ast$b, unsigned int max\+\_\+len) \begin{DoxyCompactList}\small\item\em Parse a string containing hexadecimal digits. \end{DoxyCompactList}\item const char $\ast$ \textbf{ osmo\+\_\+hexdump\+\_\+buf} (char $\ast$out\+\_\+buf, size\+\_\+t out\+\_\+buf\+\_\+size, const unsigned char $\ast$buf, int \textbf{ len}, const char $\ast$delim, bool delim\+\_\+after\+\_\+last) \begin{DoxyCompactList}\small\item\em Convert binary sequence to hexadecimal ASCII string. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+ubit\+\_\+dump\+\_\+buf} (char $\ast$buf, size\+\_\+t buf\+\_\+len, const uint8\+\_\+t $\ast$bits, unsigned int \textbf{ len}) \begin{DoxyCompactList}\small\item\em Convert a sequence of unpacked bits to ASCII string, in user-\/supplied buffer. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+ubit\+\_\+dump} (const uint8\+\_\+t $\ast$bits, unsigned int \textbf{ len}) \begin{DoxyCompactList}\small\item\em Convert a sequence of unpacked bits to ASCII string, in static buffer. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+hexdump} (const unsigned char $\ast$buf, int \textbf{ len}) \begin{DoxyCompactList}\small\item\em Convert binary sequence to hexadecimal ASCII string. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+hexdump\+\_\+c} (const void $\ast$ctx, const unsigned char $\ast$buf, int \textbf{ len}) \begin{DoxyCompactList}\small\item\em Convert binary sequence to hexadecimal ASCII string. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+hexdump\+\_\+nospc} (const unsigned char $\ast$buf, int \textbf{ len}) \begin{DoxyCompactList}\small\item\em Convert binary sequence to hexadecimal ASCII string. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+hexdump\+\_\+nospc\+\_\+c} (const void $\ast$ctx, const unsigned char $\ast$buf, int \textbf{ len}) \begin{DoxyCompactList}\small\item\em Convert binary sequence to hexadecimal ASCII string. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+osmo\+\_\+hexdump\+\_\+nospc} (const unsigned char $\ast$buf, int \textbf{ len}) \textbf{ \+\_\+\+\_\+attribute\+\_\+\+\_\+}((\+\_\+\+\_\+deprecated\+\_\+\+\_\+)) \item char \textbf{ alias} (\char`\"{}osmo\+\_\+hexdump\+\_\+nospc\char`\"{}))) \item int \textbf{ osmo\+\_\+constant\+\_\+time\+\_\+cmp} (const uint8\+\_\+t $\ast$exp, const uint8\+\_\+t $\ast$rel, const int count) \begin{DoxyCompactList}\small\item\em Wishful thinking to generate a constant time compare. \end{DoxyCompactList}\item uint64\+\_\+t \textbf{ osmo\+\_\+decode\+\_\+big\+\_\+endian} (const uint8\+\_\+t $\ast$\textbf{ data}, size\+\_\+t data\+\_\+len) \begin{DoxyCompactList}\small\item\em Generic retrieval of 1..8 bytes as big-\/endian uint64\+\_\+t. \end{DoxyCompactList}\item uint8\+\_\+t $\ast$ \textbf{ osmo\+\_\+encode\+\_\+big\+\_\+endian} (uint64\+\_\+t value, size\+\_\+t data\+\_\+len) \begin{DoxyCompactList}\small\item\em Generic big-\/endian encoding of big endian number up to 64bit. \end{DoxyCompactList}\item size\+\_\+t \textbf{ osmo\+\_\+strlcpy} (char $\ast$dst, const char $\ast$src, size\+\_\+t siz) \begin{DoxyCompactList}\small\item\em Copy a C-\/string into a sized buffer. \end{DoxyCompactList}\item const char $\ast$ \textbf{ osmo\+\_\+strnchr} (const char $\ast$str, size\+\_\+t str\+\_\+size, char \textbf{ c}) \begin{DoxyCompactList}\small\item\em Find first occurence of a char in a size limited string. \end{DoxyCompactList}\item bool \textbf{ osmo\+\_\+is\+\_\+hexstr} (const char $\ast$str, int min\+\_\+digits, int max\+\_\+digits, bool require\+\_\+even) \begin{DoxyCompactList}\small\item\em Validate that a given string is a hex string within given size limits. \end{DoxyCompactList}\item bool \textbf{ osmo\+\_\+separated\+\_\+identifiers\+\_\+valid} (const char $\ast$str, const char $\ast$sep\+\_\+chars) \begin{DoxyCompactList}\small\item\em Determine if a given identifier is valid, i.\+e. \end{DoxyCompactList}\item bool \textbf{ osmo\+\_\+identifier\+\_\+valid} (const char $\ast$str) \begin{DoxyCompactList}\small\item\em Determine if a given identifier is valid, i.\+e. \end{DoxyCompactList}\item void \textbf{ osmo\+\_\+identifier\+\_\+sanitize\+\_\+buf} (char $\ast$str, const char $\ast$sep\+\_\+chars, char replace\+\_\+with) \begin{DoxyCompactList}\small\item\em Replace characters in the given string buffer so that it is guaranteed to pass \doxyref{osmo\+\_\+separated\+\_\+identifiers\+\_\+valid()}{p.}{group__utils_gabac697c1ef493cb5691eb5f11c4af984}. \end{DoxyCompactList}\item const char $\ast$ \textbf{ osmo\+\_\+escape\+\_\+str\+\_\+buf} (const char $\ast$str, int in\+\_\+len, char $\ast$buf, size\+\_\+t bufsize) \begin{DoxyCompactList}\small\item\em Like osmo\+\_\+escape\+\_\+str\+\_\+buf2, but with unusual ordering of arguments, and may sometimes return string constants instead of writing to buf for error cases or empty input. \end{DoxyCompactList}\item int \textbf{ osmo\+\_\+print\+\_\+n} (char $\ast$buf, size\+\_\+t bufsize, const char $\ast$str, size\+\_\+t \textbf{ n}) \begin{DoxyCompactList}\small\item\em Copy N characters to a buffer with a function signature useful for \doxyref{OSMO\+\_\+\+STRBUF\+\_\+\+APPEND()}{p.}{group__utils_gafff80b7c628a7b9138d0d663f6554de2}. \end{DoxyCompactList}\item static int \textbf{ \+\_\+osmo\+\_\+escape\+\_\+str\+\_\+buf} (char $\ast$buf, size\+\_\+t bufsize, const char $\ast$str, int in\+\_\+len, bool legacy\+\_\+format) \begin{DoxyCompactList}\small\item\em Return the string with all non-\/printable characters escaped. \end{DoxyCompactList}\item int \textbf{ osmo\+\_\+escape\+\_\+str\+\_\+buf3} (char $\ast$buf, size\+\_\+t bufsize, const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Return the string with all non-\/printable characters escaped. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+escape\+\_\+str\+\_\+buf2} (char $\ast$buf, size\+\_\+t bufsize, const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Return the string with all non-\/printable characters escaped. \end{DoxyCompactList}\item const char $\ast$ \textbf{ osmo\+\_\+escape\+\_\+str} (const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Return the string with all non-\/printable characters escaped. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+escape\+\_\+str\+\_\+c} (const void $\ast$ctx, const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Return the string with all non-\/printable characters escaped, in dynamically-\/allocated buffer. \end{DoxyCompactList}\item static size\+\_\+t \textbf{ \+\_\+osmo\+\_\+quote\+\_\+str\+\_\+buf} (char $\ast$buf, size\+\_\+t bufsize, const char $\ast$str, int in\+\_\+len, bool legacy\+\_\+format) \begin{DoxyCompactList}\small\item\em Return a quoted and escaped representation of the string. \end{DoxyCompactList}\item int \textbf{ osmo\+\_\+quote\+\_\+str\+\_\+buf3} (char $\ast$buf, size\+\_\+t bufsize, const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Like \doxyref{osmo\+\_\+escape\+\_\+str\+\_\+buf3()}{p.}{group__utils_ga6b4866958eb385b561fc1fa91db242e7}, but returns double-\/quotes around a string, or \char`\"{}\+NULL\char`\"{} for a NULL string. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+quote\+\_\+str\+\_\+buf2} (char $\ast$buf, size\+\_\+t bufsize, const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Like \doxyref{osmo\+\_\+escape\+\_\+str\+\_\+buf2()}{p.}{group__utils_gab6d6c37d5cc2807eb63b41498f38fb9d}, but returns double-\/quotes around a string, or \char`\"{}\+NULL\char`\"{} for a NULL string. \end{DoxyCompactList}\item const char $\ast$ \textbf{ osmo\+\_\+quote\+\_\+str\+\_\+buf} (const char $\ast$str, int in\+\_\+len, char $\ast$buf, size\+\_\+t bufsize) \begin{DoxyCompactList}\small\item\em Like osmo\+\_\+quote\+\_\+str\+\_\+buf2, but with unusual ordering of arguments, and may sometimes return string constants instead of writing to buf for error cases or empty input. \end{DoxyCompactList}\item const char $\ast$ \textbf{ osmo\+\_\+quote\+\_\+str} (const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Like \doxyref{osmo\+\_\+quote\+\_\+str\+\_\+buf()}{p.}{group__utils_gad5c8e9dbe2d66556fde2a49418d2db89} but returns the result in a static buffer. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+quote\+\_\+str\+\_\+c} (const void $\ast$ctx, const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Like \doxyref{osmo\+\_\+quote\+\_\+str\+\_\+buf()}{p.}{group__utils_gad5c8e9dbe2d66556fde2a49418d2db89} but returns the result in a dynamically-\/allocated buffer. \end{DoxyCompactList}\item size\+\_\+t \textbf{ osmo\+\_\+escape\+\_\+cstr\+\_\+buf} (char $\ast$buf, size\+\_\+t bufsize, const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Return the string with all non-\/printable characters escaped. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+escape\+\_\+cstr\+\_\+c} (void $\ast$ctx, const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Return the string with all non-\/printable characters escaped, in dynamically-\/allocated buffer. \end{DoxyCompactList}\item size\+\_\+t \textbf{ osmo\+\_\+quote\+\_\+cstr\+\_\+buf} (char $\ast$buf, size\+\_\+t bufsize, const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Like \doxyref{osmo\+\_\+escape\+\_\+str\+\_\+buf2()}{p.}{group__utils_gab6d6c37d5cc2807eb63b41498f38fb9d}, but returns double-\/quotes around a string, or \char`\"{}\+NULL\char`\"{} for a NULL string. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+quote\+\_\+cstr\+\_\+c} (void $\ast$ctx, const char $\ast$str, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Return the string quoted and with all non-\/printable characters escaped, in dynamically-\/allocated buffer. \end{DoxyCompactList}\item uint32\+\_\+t \textbf{ osmo\+\_\+isqrt32} (uint32\+\_\+t x) \begin{DoxyCompactList}\small\item\em perform an integer square root operation on unsigned 32bit integer. \end{DoxyCompactList}\item size\+\_\+t \textbf{ osmo\+\_\+str\+\_\+tolower\+\_\+buf} (char $\ast$dest, size\+\_\+t dest\+\_\+len, const char $\ast$src) \begin{DoxyCompactList}\small\item\em Convert a string to lowercase, while checking buffer size boundaries. \end{DoxyCompactList}\item const char $\ast$ \textbf{ osmo\+\_\+str\+\_\+tolower} (const char $\ast$src) \begin{DoxyCompactList}\small\item\em Convert a string to lowercase, using a static buffer. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+str\+\_\+tolower\+\_\+c} (const void $\ast$ctx, const char $\ast$src) \begin{DoxyCompactList}\small\item\em Convert a string to lowercase, dynamically allocating the output from given talloc context See also \doxyref{osmo\+\_\+str\+\_\+tolower\+\_\+buf()}{p.}{group__utils_ga8912910863d88f52b9d62220ee66feed}. \end{DoxyCompactList}\item size\+\_\+t \textbf{ osmo\+\_\+str\+\_\+toupper\+\_\+buf} (char $\ast$dest, size\+\_\+t dest\+\_\+len, const char $\ast$src) \begin{DoxyCompactList}\small\item\em Convert a string to uppercase, while checking buffer size boundaries. \end{DoxyCompactList}\item const char $\ast$ \textbf{ osmo\+\_\+str\+\_\+toupper} (const char $\ast$src) \begin{DoxyCompactList}\small\item\em Convert a string to uppercase, using a static buffer. \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+str\+\_\+toupper\+\_\+c} (const void $\ast$ctx, const char $\ast$src) \begin{DoxyCompactList}\small\item\em Convert a string to uppercase, dynamically allocating the output from given talloc context See also \doxyref{osmo\+\_\+str\+\_\+tolower\+\_\+buf()}{p.}{group__utils_ga8912910863d88f52b9d62220ee66feed}. \end{DoxyCompactList}\item char \textbf{ osmo\+\_\+luhn} (const char $\ast$in, int in\+\_\+len) \begin{DoxyCompactList}\small\item\em Calculate the Luhn checksum (as used for IMEIs). \end{DoxyCompactList}\item bool \textbf{ osmo\+\_\+str\+\_\+startswith} (const char $\ast$str, const char $\ast$startswith\+\_\+str) \begin{DoxyCompactList}\small\item\em Compare start of a string. \end{DoxyCompactList}\item int \textbf{ osmo\+\_\+float\+\_\+str\+\_\+to\+\_\+int} (int64\+\_\+t $\ast$val, const char $\ast$str, unsigned int precision) \begin{DoxyCompactList}\small\item\em Convert a string of a floating point number to a signed int, with a decimal factor (fixed-\/point precision). \end{DoxyCompactList}\item int \textbf{ osmo\+\_\+int\+\_\+to\+\_\+float\+\_\+str\+\_\+buf} (char $\ast$buf, size\+\_\+t buflen, int64\+\_\+t val, unsigned int precision) \begin{DoxyCompactList}\small\item\em Convert an integer to a floating point string using a decimal quotient (fixed-\/point precision). \end{DoxyCompactList}\item char $\ast$ \textbf{ osmo\+\_\+int\+\_\+to\+\_\+float\+\_\+str\+\_\+c} (void $\ast$ctx, int64\+\_\+t val, unsigned int precision) \begin{DoxyCompactList}\small\item\em Convert an integer with a factor of a million to a floating point string. \end{DoxyCompactList}\item int \textbf{ osmo\+\_\+str\+\_\+to\+\_\+int64} (int64\+\_\+t $\ast$result, const char $\ast$str, int base, int64\+\_\+t min\+\_\+val, int64\+\_\+t max\+\_\+val) \begin{DoxyCompactList}\small\item\em Convert a string of a number to int64\+\_\+t, including all common strtoll() validity checks. \end{DoxyCompactList}\item int \textbf{ osmo\+\_\+str\+\_\+to\+\_\+int} (int $\ast$result, const char $\ast$str, int base, int min\+\_\+val, int max\+\_\+val) \begin{DoxyCompactList}\small\item\em Convert a string of a number to int, including all common strtoll() validity checks. \end{DoxyCompactList}\item void \textbf{ osmo\+\_\+talloc\+\_\+replace\+\_\+string\+\_\+fmt} (void $\ast$ctx, char $\ast$$\ast$dst, const char $\ast$fmt,...) \begin{DoxyCompactList}\small\item\em Replace a string using talloc and release its prior content (if any). \end{DoxyCompactList}\end{DoxyCompactItemize} \doxysubsection*{Variables} \begin{DoxyCompactItemize} \item static \+\_\+\+\_\+thread char \textbf{ namebuf} [255] \item static \+\_\+\+\_\+thread char \textbf{ capsbuf} [128] \item static \+\_\+\+\_\+thread char \textbf{ hexd\+\_\+buff} [4096] \item static const char \textbf{ hex\+\_\+chars} [$\,$] = \char`\"{}0123456789abcdef\char`\"{} \item static const char \textbf{ osmo\+\_\+identifier\+\_\+illegal\+\_\+chars} [$\,$] = \char`\"{}., \{\}[$\,$]()$<$$>$$\vert$$\sim$\textbackslash{}\textbackslash{}$^\wedge$\`{}\textquotesingle{}\textbackslash{}\char`\"{}?=;/+$\ast$\&\%\$\#!\char`\"{} \end{DoxyCompactItemize} \doxysubsection{Macro Definition Documentation} \mbox{\label{utils_8c_ae812fca8f8365243de0b72bb7885b4be}} \index{utils.c@{utils.c}!BACKSLASH\_CASE@{BACKSLASH\_CASE}} \index{BACKSLASH\_CASE@{BACKSLASH\_CASE}!utils.c@{utils.c}} \doxysubsubsection{BACKSLASH\_CASE} {\footnotesize\ttfamily \#define BACKSLASH\+\_\+\+CASE(\begin{DoxyParamCaption}\item[{}]{\textbf{ c}, }\item[{}]{repr }\end{DoxyParamCaption})} {\bfseries Value\+:} \begin{DoxyCode}{0} \DoxyCodeLine{ \textcolor{keywordflow}{case} c: \(\backslash\)} \DoxyCodeLine{ OSMO\_STRBUF\_PRINTF(sb, \textcolor{stringliteral}{"{}\(\backslash\)\(\backslash\)\%c"{}}, repr); \(\backslash\)} \DoxyCodeLine{ break} \end{DoxyCode}