28#include "pw_polyfill/static_assert.h"
29#include "pw_preprocessor/arguments.h"
30#include "pw_preprocessor/compiler.h"
31#include "pw_preprocessor/concat.h"
32#include "pw_preprocessor/util.h"
33#include "pw_tokenizer/internal/argument_types.h"
34#include "pw_tokenizer/internal/tokenize_string.h"
38typedef uint32_t pw_tokenizer_Token;
46#define PW_TOKENIZER_DEFAULT_DOMAIN ""
51#define PW_TOKENIZE_STRING_OPTIONAL_DOMAIN(...) \
52 PW_DELEGATE_BY_ARG_COUNT(_PW_TOKENIZE_STRING_OPTIONAL_DOMAIN_, __VA_ARGS__)
54#define _PW_TOKENIZE_STRING_OPTIONAL_DOMAIN_1(string_literal) \
55 PW_TOKENIZE_STRING(string_literal)
57#define _PW_TOKENIZE_STRING_OPTIONAL_DOMAIN_2(domain, string_literal) \
58 PW_TOKENIZE_STRING_DOMAIN(domain, string_literal)
72#define PW_TOKENIZE_STRING(string_literal) \
73 PW_TOKENIZE_STRING_DOMAIN(PW_TOKENIZER_DEFAULT_DOMAIN, string_literal)
83#define PW_TOKENIZE_STRING_EXPR(string_literal) \
85 constexpr uint32_t lambda_ret_token = PW_TOKENIZE_STRING(string_literal); \
86 return lambda_ret_token; \
91#define PW_TOKENIZE_STRING_DOMAIN(domain, string_literal) \
92 PW_TOKENIZE_STRING_MASK(domain, UINT32_MAX, string_literal)
96#define PW_TOKENIZE_STRING_DOMAIN_EXPR(domain, string_literal) \
98 constexpr uint32_t lambda_ret_token = \
99 PW_TOKENIZE_STRING_DOMAIN(domain, string_literal); \
100 return lambda_ret_token; \
106#define PW_TOKENIZE_STRING_MASK(domain, mask, string_literal) \
107 _PW_TOKENIZER_MASK_TOKEN(mask, string_literal); \
109 static_assert(0 < (mask) && (mask) <= UINT32_MAX, \
110 "Tokenizer masks must be non-zero uint32_t values."); \
112 PW_TOKENIZER_DEFINE_TOKEN( \
113 _PW_TOKENIZER_MASK_TOKEN(mask, string_literal), domain, string_literal)
118#define PW_TOKENIZE_STRING_MASK_EXPR(domain, mask, string_literal) \
120 constexpr uint32_t lambda_ret_token = \
121 PW_TOKENIZE_STRING_MASK(domain, mask, string_literal); \
122 return lambda_ret_token; \
125#define _PW_TOKENIZER_MASK_TOKEN(mask, string_literal) \
126 ((pw_tokenizer_Token)(mask) & PW_TOKENIZER_STRING_TOKEN(string_literal))
158#define PW_TOKENIZE_TO_BUFFER(buffer, buffer_size_pointer, format, ...) \
159 PW_TOKENIZE_TO_BUFFER_DOMAIN(PW_TOKENIZER_DEFAULT_DOMAIN, \
161 buffer_size_pointer, \
167#define PW_TOKENIZE_TO_BUFFER_DOMAIN( \
168 domain, buffer, buffer_size_pointer, format, ...) \
169 PW_TOKENIZE_TO_BUFFER_MASK( \
170 domain, UINT32_MAX, buffer, buffer_size_pointer, format, __VA_ARGS__)
174#define PW_TOKENIZE_TO_BUFFER_MASK( \
175 domain, mask, buffer, buffer_size_pointer, format, ...) \
177 PW_TOKENIZE_FORMAT_STRING(domain, mask, format, __VA_ARGS__); \
178 _pw_tokenizer_ToBuffer(buffer, \
179 buffer_size_pointer, \
180 PW_TOKENIZER_REPLACE_FORMAT_STRING(__VA_ARGS__)); \
205#define PW_TOKENIZER_REPLACE_FORMAT_STRING(...) \
206 _PW_TOKENIZER_REPLACE_FORMAT_STRING(PW_EMPTY_ARGS(__VA_ARGS__), __VA_ARGS__)
208#define _PW_TOKENIZER_REPLACE_FORMAT_STRING(empty_args, ...) \
209 _PW_CONCAT_2(_PW_TOKENIZER_REPLACE_FORMAT_STRING_, empty_args)(__VA_ARGS__)
211#define _PW_TOKENIZER_REPLACE_FORMAT_STRING_1() _pw_tokenizer_token, 0u
212#define _PW_TOKENIZER_REPLACE_FORMAT_STRING_0(...) \
213 _pw_tokenizer_token, PW_TOKENIZER_ARG_TYPES(__VA_ARGS__), __VA_ARGS__
224#define PW_TOKENIZER_ARG_TYPES(...) \
225 PW_DELEGATE_BY_ARG_COUNT(_PW_TOKENIZER_TYPES_, __VA_ARGS__)
231void _pw_tokenizer_ToBuffer(
void* buffer,
232 size_t* buffer_size_bytes,
233 pw_tokenizer_Token token,
234 pw_tokenizer_ArgTypes types,
238static inline void pw_tokenizer_CheckFormatString(
const char* format, ...)
241static inline
void pw_tokenizer_CheckFormatString(const
char* format, ...) {
260#define PW_TOKENIZE_FORMAT_STRING(domain, mask, format, ...) \
262 PW_FUNCTION_ARG_COUNT(__VA_ARGS__) <= PW_TOKENIZER_MAX_SUPPORTED_ARGS, \
263 "Tokenized strings cannot have more than " \
264 PW_STRINGIFY(PW_TOKENIZER_MAX_SUPPORTED_ARGS) " arguments; " \
265 PW_STRINGIFY(PW_FUNCTION_ARG_COUNT(__VA_ARGS__)) \
266 " arguments were used for " #format " (" #__VA_ARGS__ ")"); \
267 PW_TOKENIZE_FORMAT_STRING_ANY_ARG_COUNT(domain, mask, format, __VA_ARGS__)
282#define PW_TOKENIZE_FORMAT_STRING_ANY_ARG_COUNT(domain, mask, format, ...) \
284 pw_tokenizer_CheckFormatString(format PW_COMMA_ARGS(__VA_ARGS__)); \
288 static _PW_TOKENIZER_CONST pw_tokenizer_Token _pw_tokenizer_token = \
289 _PW_TOKENIZER_MASK_TOKEN(mask, format); \
291 PW_TOKENIZER_DEFINE_TOKEN(_pw_tokenizer_token, domain, format)
294#define _PW_TOKENIZER_UNIQUE(prefix) PW_CONCAT(prefix, __LINE__, _, __COUNTER__)
298#define _PW_TOKENIZER_CONST constexpr
306#define PW_TOKENIZER_DEFINE_TOKEN(token, domain, string) \
307 static_assert(::pw::tokenizer::internal::ValidDomain(domain), \
308 "pw_tokenizer domains may only contain alphanumeric " \
309 "characters, underscore, or colon, and cannot start with a " \
310 "number; space characters are ignored"); \
311 alignas(1) static constexpr auto _PW_TOKENIZER_SECTION _PW_TOKENIZER_UNIQUE( \
312 _pw_tokenizer_string_entry_) = \
313 ::pw::tokenizer::internal::MakeEntry(token, domain, string)
315namespace pw::tokenizer {
317using Token = ::pw_tokenizer_Token;
318inline constexpr const char* kDefaultDomain = PW_TOKENIZER_DEFAULT_DOMAIN;
324#define _PW_TOKENIZER_CONST const
325#define _PW_ALIGNAS(alignment) __attribute__((aligned(alignment)))
327#define PW_TOKENIZER_DEFINE_TOKEN(token, domain, string) \
328 _PW_ALIGNAS(1) static const _PW_TOKENIZER_STRING_ENTRY(token, domain, string)
373#define _PW_TOKENIZER_SECTION \
374 PW_KEEP_IN_SECTION(PW_STRINGIFY(_PW_TOKENIZER_UNIQUE(.pw.)))
376#define _PW_TOKENIZER_SECTION \
377 PW_KEEP_IN_SECTION(PW_STRINGIFY(_PW_TOKENIZER_UNIQUE(.pw_tokenizer.entries.)))
#define PW_PRINTF_FORMAT(format_index, parameter_index)
Definition: compiler.h:86