\doxysection{utils.\+h}
\label{utils_8h_source}\index{include/osmocom/core/utils.h@{include/osmocom/core/utils.h}}
\textbf{ Go to the documentation of this file.}
\begin{DoxyCode}{0}
\DoxyCodeLine{1 \textcolor{preprocessor}{\#pragma once}}
\DoxyCodeLine{2 }
\DoxyCodeLine{3 \textcolor{preprocessor}{\#include <stdbool.h>}}
\DoxyCodeLine{4 \textcolor{preprocessor}{\#include <stdint.h>}}
\DoxyCodeLine{5 \textcolor{preprocessor}{\#include <stdio.h>}}
\DoxyCodeLine{6 \textcolor{preprocessor}{\#include <string.h>}}
\DoxyCodeLine{7 }
\DoxyCodeLine{8 \textcolor{preprocessor}{\#include <osmocom/core/backtrace.h>}}
\DoxyCodeLine{9 \textcolor{preprocessor}{\#include <osmocom/core/talloc.h>}}
\DoxyCodeLine{10 \textcolor{preprocessor}{\#include <osmocom/core/panic.h>}}
\DoxyCodeLine{11 \textcolor{preprocessor}{\#include <osmocom/core/defs.h>}}
\DoxyCodeLine{12 }
\DoxyCodeLine{18 \textcolor{preprocessor}{\#ifndef ARRAY\_SIZE}}
\DoxyCodeLine{19 \textcolor{preprocessor}{\#define ARRAY\_SIZE(x) (sizeof(x) / sizeof((x)[0]))}}
\DoxyCodeLine{20 \textcolor{preprocessor}{\#endif}}
\DoxyCodeLine{22 \textcolor{preprocessor}{\#define OSMO\_MAX(a, b) ((a) >= (b) ? (a) : (b))}}
\DoxyCodeLine{24 \textcolor{preprocessor}{\#define OSMO\_MIN(a, b) ((a) >= (b) ? (b) : (a))}}
\DoxyCodeLine{26 \textcolor{preprocessor}{\#define OSMO\_CMP(a, b) ((a) < (b)? -\/1 : ((a) > (b)? 1 : 0))}}
\DoxyCodeLine{30 \textcolor{preprocessor}{\#define OSMO\_STRINGIFY(x) \#x}}
\DoxyCodeLine{32 \textcolor{preprocessor}{\#define OSMO\_STRINGIFY\_VAL(x) OSMO\_STRINGIFY(x)}}
\DoxyCodeLine{34 \textcolor{preprocessor}{\#define OSMO\_VALUE\_STRING(x) \{ x, \#x \}}}
\DoxyCodeLine{36 \textcolor{preprocessor}{\#define OSMO\_BYTES\_FOR\_BITS(BITS) (((BITS) + 7) / 8)}}
\DoxyCodeLine{37 }
\DoxyCodeLine{39 \textcolor{preprocessor}{\#define OSMO\_STRLCPY\_ARRAY(array, src) osmo\_strlcpy(array, src, sizeof(array))}}
\DoxyCodeLine{40 }
\DoxyCodeLine{42 \textcolor{preprocessor}{\#if defined(\_\_GNUC\_\_)}}
\DoxyCodeLine{43 \textcolor{preprocessor}{\#define OSMO\_LIKELY(exp) \_\_builtin\_expect(!!(exp), 1)}}
\DoxyCodeLine{44 \textcolor{preprocessor}{\#define OSMO\_UNLIKELY(exp) \_\_builtin\_expect(!!(exp), 0)}}
\DoxyCodeLine{45 \textcolor{preprocessor}{\#else}}
\DoxyCodeLine{46 \textcolor{preprocessor}{\#define OSMO\_LIKELY(exp) exp}}
\DoxyCodeLine{47 \textcolor{preprocessor}{\#define OSMO\_UNLIKELY(exp) exp}}
\DoxyCodeLine{48 \textcolor{preprocessor}{\#endif}}
\DoxyCodeLine{49 }
\DoxyCodeLine{51 \textcolor{keyword}{struct }value\_string \{}
\DoxyCodeLine{52         uint32\_t value;            }
\DoxyCodeLine{53         \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str;     }
\DoxyCodeLine{54 \};}
\DoxyCodeLine{55 }
\DoxyCodeLine{56 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *get\_value\_string(\textcolor{keyword}{const} \textcolor{keyword}{struct} value\_string *vs, uint32\_t val);}
\DoxyCodeLine{57 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *get\_value\_string\_or\_null(\textcolor{keyword}{const} \textcolor{keyword}{struct} value\_string *vs,}
\DoxyCodeLine{58                                      uint32\_t val);}
\DoxyCodeLine{59 }
\DoxyCodeLine{60 \textcolor{keywordtype}{int} get\_string\_value(\textcolor{keyword}{const} \textcolor{keyword}{struct} value\_string *vs, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str);}
\DoxyCodeLine{61 }
\DoxyCodeLine{62 \textcolor{keywordtype}{char} osmo\_bcd2char(uint8\_t bcd);}
\DoxyCodeLine{63 \textcolor{comment}{/* only works for numbers in ASCII */}}
\DoxyCodeLine{64 uint8\_t osmo\_char2bcd(\textcolor{keywordtype}{char} c);}
\DoxyCodeLine{65 }
\DoxyCodeLine{66 \textcolor{keywordtype}{int} osmo\_bcd2str(\textcolor{keywordtype}{char} *dst, \textcolor{keywordtype}{size\_t} dst\_size, \textcolor{keyword}{const} uint8\_t *bcd, \textcolor{keywordtype}{int} start\_nibble, \textcolor{keywordtype}{int} end\_nibble, \textcolor{keywordtype}{bool} allow\_hex);}
\DoxyCodeLine{67 \textcolor{keywordtype}{int} osmo\_str2bcd(uint8\_t *dst, \textcolor{keywordtype}{size\_t} dst\_size, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *digits, \textcolor{keywordtype}{int} start\_nibble, \textcolor{keywordtype}{int} end\_nibble, \textcolor{keywordtype}{bool} allow\_hex);}
\DoxyCodeLine{68 }
\DoxyCodeLine{69 \textcolor{keywordtype}{int} osmo\_hexparse(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, uint8\_t *b, \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} max\_len);}
\DoxyCodeLine{70 }
\DoxyCodeLine{71 \textcolor{keywordtype}{char} *osmo\_ubit\_dump\_buf(\textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} buf\_len, \textcolor{keyword}{const} uint8\_t *bits, \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} len);}
\DoxyCodeLine{72 \textcolor{keywordtype}{char} *osmo\_ubit\_dump(\textcolor{keyword}{const} uint8\_t *bits, \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} len);}
\DoxyCodeLine{73 \textcolor{keywordtype}{char} *osmo\_hexdump(\textcolor{keyword}{const} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{int} len);}
\DoxyCodeLine{74 \textcolor{keywordtype}{char} *osmo\_hexdump\_c(\textcolor{keyword}{const} \textcolor{keywordtype}{void} *ctx, \textcolor{keyword}{const} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{int} len);}
\DoxyCodeLine{75 \textcolor{keywordtype}{char} *osmo\_hexdump\_nospc(\textcolor{keyword}{const} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{int} len);}
\DoxyCodeLine{76 \textcolor{keywordtype}{char} *osmo\_hexdump\_nospc\_c(\textcolor{keyword}{const} \textcolor{keywordtype}{void} *ctx, \textcolor{keyword}{const} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{int} len);}
\DoxyCodeLine{77 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *osmo\_hexdump\_buf(\textcolor{keywordtype}{char} *out\_buf, \textcolor{keywordtype}{size\_t} out\_buf\_size, \textcolor{keyword}{const} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{int} len, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *delim,}
\DoxyCodeLine{78                              \textcolor{keywordtype}{bool} delim\_after\_last);}
\DoxyCodeLine{79 }
\DoxyCodeLine{80 \textcolor{keywordtype}{char} *osmo\_osmo\_hexdump\_nospc(\textcolor{keyword}{const} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{int} len) \_\_attribute\_\_((\_\_deprecated\_\_));}
\DoxyCodeLine{81 }
\DoxyCodeLine{82 \textcolor{preprocessor}{\#define osmo\_static\_assert(exp, name) typedef int dummy\#\#name [(exp) ? 1 : -\/1] \_\_attribute\_\_((\_\_unused\_\_));}}
\DoxyCodeLine{83 }
\DoxyCodeLine{84 \textcolor{keywordtype}{void} osmo\_str2lower(\textcolor{keywordtype}{char} *out, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *in)}
\DoxyCodeLine{85         OSMO\_DEPRECATED(\textcolor{stringliteral}{"{}Use osmo\_str\_tolower() or osmo\_str\_tolower\_buf() instead,"{}}}
\DoxyCodeLine{86                         \textcolor{stringliteral}{"{} to properly check target memory bounds"{}});}
\DoxyCodeLine{87 \textcolor{keywordtype}{void} osmo\_str2upper(\textcolor{keywordtype}{char} *out, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *in)}
\DoxyCodeLine{88         OSMO\_DEPRECATED(\textcolor{stringliteral}{"{}Use osmo\_str\_toupper() or osmo\_str\_toupper\_buf() instead,"{}}}
\DoxyCodeLine{89                         \textcolor{stringliteral}{"{} to properly check target memory bounds"{}});}
\DoxyCodeLine{90 }
\DoxyCodeLine{91 \textcolor{keywordtype}{size\_t} osmo\_str\_tolower\_buf(\textcolor{keywordtype}{char} *dest, \textcolor{keywordtype}{size\_t} dest\_len, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *src);}
\DoxyCodeLine{92 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *osmo\_str\_tolower(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *src);}
\DoxyCodeLine{93 \textcolor{keywordtype}{char} *osmo\_str\_tolower\_c(\textcolor{keyword}{const} \textcolor{keywordtype}{void} *ctx, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *src);}
\DoxyCodeLine{94 }
\DoxyCodeLine{95 \textcolor{keywordtype}{size\_t} osmo\_str\_toupper\_buf(\textcolor{keywordtype}{char} *dest, \textcolor{keywordtype}{size\_t} dest\_len, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *src);}
\DoxyCodeLine{96 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *osmo\_str\_toupper(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *src);}
\DoxyCodeLine{97 \textcolor{keywordtype}{char} *osmo\_str\_toupper\_c(\textcolor{keyword}{const} \textcolor{keywordtype}{void} *ctx, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *src);}
\DoxyCodeLine{98 }
\DoxyCodeLine{99 \textcolor{preprocessor}{\#define OSMO\_SNPRINTF\_RET(ret, rem, offset, len)                \(\backslash\)}}
\DoxyCodeLine{100 \textcolor{preprocessor}{do \{                                                            \(\backslash\)}}
\DoxyCodeLine{101 \textcolor{preprocessor}{        len += ret;                                             \(\backslash\)}}
\DoxyCodeLine{102 \textcolor{preprocessor}{        if (ret > rem)                                          \(\backslash\)}}
\DoxyCodeLine{103 \textcolor{preprocessor}{                ret = rem;                                      \(\backslash\)}}
\DoxyCodeLine{104 \textcolor{preprocessor}{        offset += ret;                                          \(\backslash\)}}
\DoxyCodeLine{105 \textcolor{preprocessor}{        rem -\/= ret;                                             \(\backslash\)}}
\DoxyCodeLine{106 \textcolor{preprocessor}{\} while (0)}}
\DoxyCodeLine{107 }
\DoxyCodeLine{113 \textcolor{preprocessor}{\#define OSMO\_ASSERT(exp)    \(\backslash\)}}
\DoxyCodeLine{114 \textcolor{preprocessor}{do \{ \(\backslash\)}}
\DoxyCodeLine{115 \textcolor{preprocessor}{        if (OSMO\_UNLIKELY(!(exp))) \{ \(\backslash\)}}
\DoxyCodeLine{116 \textcolor{preprocessor}{                osmo\_panic("{}Assert failed \%s \%s:\%d\(\backslash\)n"{}}, \#exp, \_\_FILE\_\_, \_\_LINE\_\_); \(\backslash\)}
\DoxyCodeLine{117         \} \(\backslash\)}
\DoxyCodeLine{118 \} while (0); \textcolor{comment}{/* some code invokes OSMO\_ASSERT() without the semicolon */}\textcolor{preprocessor}{}}
\DoxyCodeLine{119 }
\DoxyCodeLine{124 \textcolor{keyword}{static} \textcolor{keyword}{inline} \textcolor{keywordtype}{void} osmo\_talloc\_replace\_string(\textcolor{keywordtype}{void} *ctx, \textcolor{keywordtype}{char} **dst, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *newstr)}
\DoxyCodeLine{125 \{}
\DoxyCodeLine{126         \textcolor{keywordflow}{if} (*dst)}
\DoxyCodeLine{127                 talloc\_free(*dst);}
\DoxyCodeLine{128         *dst = talloc\_strdup(ctx, newstr);}
\DoxyCodeLine{129 \}}
\DoxyCodeLine{130 }
\DoxyCodeLine{131 \textcolor{keywordtype}{void} osmo\_talloc\_replace\_string\_fmt(\textcolor{keywordtype}{void} *ctx, \textcolor{keywordtype}{char} **dst, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *fmt, ...);}
\DoxyCodeLine{132 }
\DoxyCodeLine{143 \textcolor{preprocessor}{\#define osmo\_talloc\_asprintf(ctx, dest, fmt, args ...) \(\backslash\)}}
\DoxyCodeLine{144 \textcolor{preprocessor}{        do \{ \(\backslash\)}}
\DoxyCodeLine{145 \textcolor{preprocessor}{                if (!dest) \(\backslash\)}}
\DoxyCodeLine{146 \textcolor{preprocessor}{                        dest = talloc\_asprintf(ctx, fmt, \#\# args); \(\backslash\)}}
\DoxyCodeLine{147 \textcolor{preprocessor}{                else \(\backslash\)}}
\DoxyCodeLine{148 \textcolor{preprocessor}{                        dest = talloc\_asprintf\_append((char*)dest, fmt, \#\# args); \(\backslash\)}}
\DoxyCodeLine{149 \textcolor{preprocessor}{        \} while (0)}}
\DoxyCodeLine{150 }
\DoxyCodeLine{151 \textcolor{keywordtype}{int} osmo\_constant\_time\_cmp(\textcolor{keyword}{const} uint8\_t *exp, \textcolor{keyword}{const} uint8\_t *rel, \textcolor{keyword}{const} \textcolor{keywordtype}{int} count);}
\DoxyCodeLine{152 uint64\_t osmo\_decode\_big\_endian(\textcolor{keyword}{const} uint8\_t *data, \textcolor{keywordtype}{size\_t} data\_len);}
\DoxyCodeLine{153 uint8\_t *osmo\_encode\_big\_endian(uint64\_t value, \textcolor{keywordtype}{size\_t} data\_len);}
\DoxyCodeLine{154 }
\DoxyCodeLine{155 \textcolor{keywordtype}{size\_t} osmo\_strlcpy(\textcolor{keywordtype}{char} *dst, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *src, \textcolor{keywordtype}{size\_t} siz);}
\DoxyCodeLine{156 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *osmo\_strnchr(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{size\_t} str\_size, \textcolor{keywordtype}{char} c);}
\DoxyCodeLine{157 }
\DoxyCodeLine{158 \textcolor{keywordtype}{bool} osmo\_is\_hexstr(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} min\_digits, \textcolor{keywordtype}{int} max\_digits,}
\DoxyCodeLine{159                     \textcolor{keywordtype}{bool} require\_even);}
\DoxyCodeLine{160 }
\DoxyCodeLine{161 \textcolor{keywordtype}{bool} osmo\_identifier\_valid(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str);}
\DoxyCodeLine{162 \textcolor{keywordtype}{bool} osmo\_separated\_identifiers\_valid(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *sep\_chars);}
\DoxyCodeLine{163 \textcolor{keywordtype}{void} osmo\_identifier\_sanitize\_buf(\textcolor{keywordtype}{char} *str, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *sep\_chars, \textcolor{keywordtype}{char} replace\_with);}
\DoxyCodeLine{164 }
\DoxyCodeLine{165 \textcolor{keywordtype}{size\_t} osmo\_escape\_cstr\_buf(\textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} bufsize, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{166 \textcolor{keywordtype}{char} *osmo\_escape\_cstr\_c(\textcolor{keywordtype}{void} *ctx, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{167 \textcolor{keywordtype}{size\_t} osmo\_quote\_cstr\_buf(\textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} bufsize, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{168 \textcolor{keywordtype}{char} *osmo\_quote\_cstr\_c(\textcolor{keywordtype}{void} *ctx, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{169 }
\DoxyCodeLine{170 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *osmo\_escape\_str(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} len);}
\DoxyCodeLine{171 \textcolor{keywordtype}{int} osmo\_escape\_str\_buf3(\textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} bufsize, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{172 \textcolor{keywordtype}{char} *osmo\_escape\_str\_buf2(\textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} bufsize, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{173 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *osmo\_escape\_str\_buf(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len, \textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} bufsize);}
\DoxyCodeLine{174 \textcolor{keywordtype}{char} *osmo\_escape\_str\_c(\textcolor{keyword}{const} \textcolor{keywordtype}{void} *ctx, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{175 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *osmo\_quote\_str(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{176 \textcolor{keywordtype}{int} osmo\_quote\_str\_buf3(\textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} bufsize, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{177 \textcolor{keywordtype}{char} *osmo\_quote\_str\_buf2(\textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} bufsize, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{178 \textcolor{keyword}{const} \textcolor{keywordtype}{char} *osmo\_quote\_str\_buf(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len, \textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} bufsize);}
\DoxyCodeLine{179 \textcolor{keywordtype}{char} *osmo\_quote\_str\_c(\textcolor{keyword}{const} \textcolor{keywordtype}{void} *ctx, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{180 }
\DoxyCodeLine{181 \textcolor{keywordtype}{int} osmo\_print\_n(\textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} bufsize, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{size\_t} n);}
\DoxyCodeLine{182 }
\DoxyCodeLine{183 uint32\_t osmo\_isqrt32(uint32\_t x);}
\DoxyCodeLine{184 }
\DoxyCodeLine{189 \textcolor{preprocessor}{\#define OSMO\_MOD\_FLR(x, y) (((x) > 0 \&\& (y) < 0) || ((x) < 0 \&\& (y) > 0) ? (x) \% (y) + (y) : (x) \% (y))}}
\DoxyCodeLine{190 }
\DoxyCodeLine{195 \textcolor{preprocessor}{\#define OSMO\_MOD\_EUC(x, y) ((x) \% (y) < 0 ? (y) > 0 ? (x) \% (y) + (y) : (x) \% (y) -\/ (y) : (x) \% (y))}}
\DoxyCodeLine{196 }
\DoxyCodeLine{197 \textcolor{keywordtype}{char} osmo\_luhn(\textcolor{keyword}{const} \textcolor{keywordtype}{char}* in, \textcolor{keywordtype}{int} in\_len);}
\DoxyCodeLine{198 }
\DoxyCodeLine{200 \textcolor{keyword}{struct }osmo\_strbuf \{}
\DoxyCodeLine{202         \textcolor{keywordtype}{char} *buf;}
\DoxyCodeLine{204         \textcolor{keywordtype}{size\_t} len;}
\DoxyCodeLine{206         \textcolor{keywordtype}{char} *pos;}
\DoxyCodeLine{210         \textcolor{keywordtype}{size\_t} chars\_needed;}
\DoxyCodeLine{211 \};}
\DoxyCodeLine{212 }
\DoxyCodeLine{249 \textcolor{preprocessor}{\#define OSMO\_STRBUF\_APPEND(STRBUF, func, args...) do \{ \(\backslash\)}}
\DoxyCodeLine{250 \textcolor{preprocessor}{                if (!(STRBUF).pos) \(\backslash\)}}
\DoxyCodeLine{251 \textcolor{preprocessor}{                        (STRBUF).pos = (STRBUF).buf; \(\backslash\)}}
\DoxyCodeLine{252 \textcolor{preprocessor}{                size\_t \_sb\_remain = OSMO\_STRBUF\_REMAIN(STRBUF); \(\backslash\)}}
\DoxyCodeLine{253 \textcolor{preprocessor}{                int \_sb\_l = func((STRBUF).pos, \_sb\_remain, \#\#args); \(\backslash\)}}
\DoxyCodeLine{254 \textcolor{preprocessor}{                if (\_sb\_l < 0 || (size\_t)\_sb\_l > \_sb\_remain) \(\backslash\)}}
\DoxyCodeLine{255 \textcolor{preprocessor}{                        (STRBUF).pos = (STRBUF).buf + (STRBUF).len; \(\backslash\)}}
\DoxyCodeLine{256 \textcolor{preprocessor}{                else if ((STRBUF).pos) \(\backslash\)}}
\DoxyCodeLine{257 \textcolor{preprocessor}{                        (STRBUF).pos += \_sb\_l; \(\backslash\)}}
\DoxyCodeLine{258 \textcolor{preprocessor}{                if (\_sb\_l > 0) \(\backslash\)}}
\DoxyCodeLine{259 \textcolor{preprocessor}{                        (STRBUF).chars\_needed += \_sb\_l; \(\backslash\)}}
\DoxyCodeLine{260 \textcolor{preprocessor}{        \} while(0)}}
\DoxyCodeLine{261 }
\DoxyCodeLine{281 \textcolor{preprocessor}{\#define OSMO\_STRBUF\_PRINTF(STRBUF, fmt, args...) \(\backslash\)}}
\DoxyCodeLine{282 \textcolor{preprocessor}{        OSMO\_STRBUF\_APPEND(STRBUF, snprintf, fmt, \#\#args)}}
\DoxyCodeLine{283 }
\DoxyCodeLine{287 \textcolor{keyword}{static} \textcolor{keyword}{inline} \textcolor{keywordtype}{size\_t} \_osmo\_strbuf\_remain(\textcolor{keyword}{const} \textcolor{keyword}{struct} osmo\_strbuf *sb)}
\DoxyCodeLine{288 \{}
\DoxyCodeLine{289         \textcolor{keywordflow}{if} (OSMO\_UNLIKELY(sb == NULL || sb-\/>buf == NULL))}
\DoxyCodeLine{290                 \textcolor{keywordflow}{return} 0;}
\DoxyCodeLine{291         \textcolor{keywordflow}{if} (sb-\/>pos == NULL)}
\DoxyCodeLine{292                 \textcolor{keywordflow}{return} sb-\/>len;}
\DoxyCodeLine{293         \textcolor{keywordflow}{return} sb-\/>len -\/ (sb-\/>pos -\/ sb-\/>buf);}
\DoxyCodeLine{294 \}}
\DoxyCodeLine{295 }
\DoxyCodeLine{297 \textcolor{preprocessor}{\#define OSMO\_STRBUF\_REMAIN(STRBUF) \(\backslash\)}}
\DoxyCodeLine{298 \textcolor{preprocessor}{        \_osmo\_strbuf\_remain(\&(STRBUF))}}
\DoxyCodeLine{299 }
\DoxyCodeLine{303 \textcolor{keyword}{static} \textcolor{keyword}{inline} \textcolor{keywordtype}{size\_t} \_osmo\_strbuf\_char\_count(\textcolor{keyword}{const} \textcolor{keyword}{struct} osmo\_strbuf *sb)}
\DoxyCodeLine{304 \{}
\DoxyCodeLine{305         \textcolor{keywordflow}{if} (OSMO\_UNLIKELY(sb == NULL || sb-\/>buf == NULL))}
\DoxyCodeLine{306                 \textcolor{keywordflow}{return} 0;}
\DoxyCodeLine{307         \textcolor{keywordflow}{if} (sb-\/>pos == NULL || sb-\/>pos <= sb-\/>buf)}
\DoxyCodeLine{308                 \textcolor{keywordflow}{return} 0;}
\DoxyCodeLine{309         \textcolor{keywordflow}{return} OSMO\_MIN((\textcolor{keywordtype}{size\_t})(sb-\/>pos -\/ sb-\/>buf), sb-\/>len -\/ 1);}
\DoxyCodeLine{310 \}}
\DoxyCodeLine{311 }
\DoxyCodeLine{313 \textcolor{preprocessor}{\#define OSMO\_STRBUF\_CHAR\_COUNT(STRBUF) \(\backslash\)}}
\DoxyCodeLine{314 \textcolor{preprocessor}{        \_osmo\_strbuf\_char\_count(\&(STRBUF))}}
\DoxyCodeLine{315 }
\DoxyCodeLine{324 \textcolor{preprocessor}{\#define OSMO\_STRBUF\_APPEND\_NOLEN(STRBUF, func, args...) do \{ \(\backslash\)}}
\DoxyCodeLine{325 \textcolor{preprocessor}{                if (!(STRBUF).pos) \(\backslash\)}}
\DoxyCodeLine{326 \textcolor{preprocessor}{                        (STRBUF).pos = (STRBUF).buf; \(\backslash\)}}
\DoxyCodeLine{327 \textcolor{preprocessor}{                size\_t \_sb\_remain = OSMO\_STRBUF\_REMAIN(STRBUF); \(\backslash\)}}
\DoxyCodeLine{328 \textcolor{preprocessor}{                if (\_sb\_remain) \{ \(\backslash\)}}
\DoxyCodeLine{329 \textcolor{preprocessor}{                        func((STRBUF).pos, \_sb\_remain, \#\#args); \(\backslash\)}}
\DoxyCodeLine{330 \textcolor{preprocessor}{                \} \(\backslash\)}}
\DoxyCodeLine{331 \textcolor{preprocessor}{                size\_t \_sb\_l = (STRBUF).pos ? strnlen((STRBUF).pos, \_sb\_remain) : 0; \(\backslash\)}}
\DoxyCodeLine{332 \textcolor{preprocessor}{                if (\_sb\_l > \_sb\_remain) \(\backslash\)}}
\DoxyCodeLine{333 \textcolor{preprocessor}{                        (STRBUF).pos = (STRBUF).buf + (STRBUF).len; \(\backslash\)}}
\DoxyCodeLine{334 \textcolor{preprocessor}{                else if ((STRBUF).pos) \(\backslash\)}}
\DoxyCodeLine{335 \textcolor{preprocessor}{                        (STRBUF).pos += \_sb\_l; \(\backslash\)}}
\DoxyCodeLine{336 \textcolor{preprocessor}{                (STRBUF).chars\_needed += \_sb\_l; \(\backslash\)}}
\DoxyCodeLine{337 \textcolor{preprocessor}{        \} while(0)}}
\DoxyCodeLine{338 }
\DoxyCodeLine{339 \textcolor{keywordtype}{void} osmo\_strbuf\_drop\_tail(\textcolor{keyword}{struct} osmo\_strbuf *sb, \textcolor{keywordtype}{size\_t} n\_chars);}
\DoxyCodeLine{340 \textcolor{comment}{/* Convenience macro. struct osmo\_strbuf are typically static to a function scope. Avoid having to type '\&', same as}}
\DoxyCodeLine{341 \textcolor{comment}{ * with all the other OSMO\_STRBUF\_* API. */}}
\DoxyCodeLine{342 \textcolor{preprocessor}{\#define OSMO\_STRBUF\_DROP\_TAIL(STRBUF, N\_CHARS) osmo\_strbuf\_drop\_tail(\&(STRBUF), N\_CHARS)}}
\DoxyCodeLine{343 }
\DoxyCodeLine{344 \textcolor{keywordtype}{void} osmo\_strbuf\_added\_tail(\textcolor{keyword}{struct} osmo\_strbuf *sb, \textcolor{keywordtype}{size\_t} n\_chars);}
\DoxyCodeLine{345 \textcolor{comment}{/* Convenience macro. struct osmo\_strbuf are typically static to a function scope. Avoid having to type '\&', same as}}
\DoxyCodeLine{346 \textcolor{comment}{ * with all the other OSMO\_STRBUF\_* API. */}}
\DoxyCodeLine{347 \textcolor{preprocessor}{\#define OSMO\_STRBUF\_ADDED\_TAIL(STRBUF, N\_CHARS) osmo\_strbuf\_added\_tail(\&(STRBUF), N\_CHARS)}}
\DoxyCodeLine{348 }
\DoxyCodeLine{349 \textcolor{keywordtype}{bool} osmo\_str\_startswith(\textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *startswith\_str);}
\DoxyCodeLine{350 }
\DoxyCodeLine{351 \textcolor{keywordtype}{int} osmo\_float\_str\_to\_int(int64\_t *val, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} precision);}
\DoxyCodeLine{352 \textcolor{keywordtype}{int} osmo\_int\_to\_float\_str\_buf(\textcolor{keywordtype}{char} *buf, \textcolor{keywordtype}{size\_t} buflen, int64\_t val, \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} precision);}
\DoxyCodeLine{353 \textcolor{keywordtype}{char} *osmo\_int\_to\_float\_str\_c(\textcolor{keywordtype}{void} *ctx, int64\_t val, \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} precision);}
\DoxyCodeLine{354 }
\DoxyCodeLine{355 \textcolor{keywordtype}{int} osmo\_str\_to\_int64(int64\_t *result, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} base, int64\_t min\_val, int64\_t max\_val);}
\DoxyCodeLine{356 \textcolor{keywordtype}{int} osmo\_str\_to\_int(\textcolor{keywordtype}{int} *result, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *str, \textcolor{keywordtype}{int} base, \textcolor{keywordtype}{int} min\_val, \textcolor{keywordtype}{int} max\_val);}
\DoxyCodeLine{357 }
\DoxyCodeLine{382 \textcolor{preprocessor}{\#define OSMO\_NAME\_C\_IMPL(CTX, INITIAL\_BUFSIZE, ON\_ERROR, FUNC\_BUF, FUNC\_BUF\_ARGS...) \(\backslash\)}}
\DoxyCodeLine{383 \textcolor{preprocessor}{        size\_t \_len = INITIAL\_BUFSIZE; \(\backslash\)}}
\DoxyCodeLine{384 \textcolor{preprocessor}{        int \_needed; \(\backslash\)}}
\DoxyCodeLine{385 \textcolor{preprocessor}{        char *\_str = NULL; \(\backslash\)}}
\DoxyCodeLine{386 \textcolor{preprocessor}{        if ((INITIAL\_BUFSIZE) > 0) \{ \(\backslash\)}}
\DoxyCodeLine{387 \textcolor{preprocessor}{                \_str = (char*)talloc\_named\_const(CTX, \_len, \_\_func\_\_); \(\backslash\)}}
\DoxyCodeLine{388 \textcolor{preprocessor}{                OSMO\_ASSERT(\_str); \(\backslash\)}}
\DoxyCodeLine{389 \textcolor{preprocessor}{        \} \(\backslash\)}}
\DoxyCodeLine{390 \textcolor{preprocessor}{        \_needed = FUNC\_BUF(\_str, \_len, \#\# FUNC\_BUF\_ARGS); \(\backslash\)}}
\DoxyCodeLine{391 \textcolor{preprocessor}{        if (\_needed < 0) \(\backslash\)}}
\DoxyCodeLine{392 \textcolor{preprocessor}{                goto OSMO\_NAME\_C\_on\_error; \(\backslash\)}}
\DoxyCodeLine{393 \textcolor{preprocessor}{        if ((unsigned int) \_needed < \_len) \(\backslash\)}}
\DoxyCodeLine{394 \textcolor{preprocessor}{                return \_str; \(\backslash\)}}
\DoxyCodeLine{395 \textcolor{preprocessor}{        \_len = \_needed + 1; \(\backslash\)}}
\DoxyCodeLine{396 \textcolor{preprocessor}{        if (\_str) \(\backslash\)}}
\DoxyCodeLine{397 \textcolor{preprocessor}{                talloc\_free(\_str); \(\backslash\)}}
\DoxyCodeLine{398 \textcolor{preprocessor}{        \_str = (char*)talloc\_named\_const(CTX, \_len, \_\_func\_\_); \(\backslash\)}}
\DoxyCodeLine{399 \textcolor{preprocessor}{        OSMO\_ASSERT(\_str); \(\backslash\)}}
\DoxyCodeLine{400 \textcolor{preprocessor}{        \_needed = FUNC\_BUF(\_str, \_len, \#\# FUNC\_BUF\_ARGS); \(\backslash\)}}
\DoxyCodeLine{401 \textcolor{preprocessor}{        if (\_needed < 0) \(\backslash\)}}
\DoxyCodeLine{402 \textcolor{preprocessor}{                goto OSMO\_NAME\_C\_on\_error; \(\backslash\)}}
\DoxyCodeLine{403 \textcolor{preprocessor}{        return \_str; \(\backslash\)}}
\DoxyCodeLine{404 \textcolor{preprocessor}{OSMO\_NAME\_C\_on\_error: \(\backslash\)}}
\DoxyCodeLine{405 \textcolor{preprocessor}{        }\textcolor{comment}{/* Re-\/using and re-\/sizing above allocated buf ends up in very complex code. Just free and strdup. */}\textcolor{preprocessor}{ \(\backslash\)}}
\DoxyCodeLine{406 \textcolor{preprocessor}{        if (\_str) \(\backslash\)}}
\DoxyCodeLine{407 \textcolor{preprocessor}{                talloc\_free(\_str); \(\backslash\)}}
\DoxyCodeLine{408 \textcolor{preprocessor}{        if (!(ON\_ERROR)) \(\backslash\)}}
\DoxyCodeLine{409 \textcolor{preprocessor}{                return NULL; \(\backslash\)}}
\DoxyCodeLine{410 \textcolor{preprocessor}{        \_str = talloc\_strdup(CTX, ON\_ERROR); \(\backslash\)}}
\DoxyCodeLine{411 \textcolor{preprocessor}{        OSMO\_ASSERT(\_str); \(\backslash\)}}
\DoxyCodeLine{412 \textcolor{preprocessor}{        talloc\_set\_name\_const(\_str, \_\_func\_\_); \(\backslash\)}}
\DoxyCodeLine{413 \textcolor{preprocessor}{        return \_str;}}
\DoxyCodeLine{414 }

\end{DoxyCode}
