\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 $<$sys/types.\+h$>$}\newline
{\ttfamily \#include $<$inttypes.\+h$>$}\newline
{\ttfamily \#include $<$limits.\+h$>$}\newline
{\ttfamily \#include \char`\"{}config.\+h\char`\"{}}\newline
{\ttfamily \#include $<$osmocom/core/utils.\+h$>$}\newline
{\ttfamily \#include $<$osmocom/core/bit64gen.\+h$>$}\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 \textbf{ 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 
void \textbf{ osmo\+\_\+strbuf\+\_\+drop\+\_\+tail} (struct \textbf{ osmo\+\_\+strbuf} $\ast$sb, size\+\_\+t n\+\_\+chars)
\begin{DoxyCompactList}\small\item\em Remove up to N chars from the end of an \doxyref{osmo\+\_\+strbuf}{p.}{structosmo__strbuf}. \end{DoxyCompactList}\item 
void \textbf{ osmo\+\_\+strbuf\+\_\+added\+\_\+tail} (struct \textbf{ osmo\+\_\+strbuf} $\ast$sb, size\+\_\+t n\+\_\+chars)
\begin{DoxyCompactList}\small\item\em Let \doxyref{osmo\+\_\+strbuf}{p.}{structosmo__strbuf} know that n\+\_\+chars characters (excluding nul) were written to the end of the buffer. \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}
