1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #pragma once
15 
16 #include <stddef.h>
17 #include <stdint.h>
18 
19 #include "pw_preprocessor/util.h"
20 #include "pw_tokenizer/tokenize.h"
21 
22 // Encodes a tokenized string and arguments to a buffer on the stack. The buffer
23 // is passed to the user-defined pw_tokenizer_HandleEncodedMessage function. The
24 // size of the stack-allocated argument encoding buffer is set with the
25 // PW_TOKENIZER_CFG_ENCODING_BUFFER_SIZE_BYTES option.
26 //
27 // The macro's arguments are equivalent to the following function signature:
28 //
29 //   TokenizeToGlobalHandler(const char* format,
30 //                           ...);  /* printf-style arguments */
31 //
32 // For example, the following encodes a tokenized string with a value returned
33 // from a function call. The encoded message is passed to the caller-defined
34 // pw_tokenizer_HandleEncodedMessage function.
35 //
36 //   void OutputLastReadSize() {
37 //     PW_TOKENIZE_TO_GLOBAL_HANDLER("Read %u bytes", ReadSizeBytes());
38 //   }
39 //
40 //   void pw_tokenizer_HandleEncodedMessage(const uint8_t encoded_message[],
41 //                                         size_t size_bytes) {
42 //     MyProject_EnqueueMessageForUart(buffer, size_bytes);
43 //   }
44 //
45 #define PW_TOKENIZE_TO_GLOBAL_HANDLER(format, ...) \
46   PW_TOKENIZE_TO_GLOBAL_HANDLER_DOMAIN(            \
47       PW_TOKENIZER_DEFAULT_DOMAIN, format, __VA_ARGS__)
48 
49 // Same as PW_TOKENIZE_TO_GLOBAL_HANDLER, but tokenizes to the specified domain.
50 #define PW_TOKENIZE_TO_GLOBAL_HANDLER_DOMAIN(domain, format, ...) \
51   PW_TOKENIZE_TO_GLOBAL_HANDLER_MASK(domain, UINT32_MAX, format, __VA_ARGS__)
52 
53 // Same as PW_TOKENIZE_TO_GLOBAL_HANDLER_DOMAIN, but applies a mask to the
54 // token.
55 #define PW_TOKENIZE_TO_GLOBAL_HANDLER_MASK(domain, mask, format, ...) \
56   do {                                                                \
57     PW_TOKENIZE_FORMAT_STRING(domain, mask, format, __VA_ARGS__);     \
58     _pw_tokenizer_ToGlobalHandler(_pw_tokenizer_token,                \
59                                   PW_TOKENIZER_ARG_TYPES(__VA_ARGS__) \
60                                       PW_COMMA_ARGS(__VA_ARGS__));    \
61   } while (0)
62 
63 PW_EXTERN_C_START
64 
65 // This function must be defined by the pw_tokenizer:global_handler backend.
66 // This function is called with the encoded message by
67 // _pw_tokenizer_ToGlobalHandler.
68 void pw_tokenizer_HandleEncodedMessage(const uint8_t encoded_message[],
69                                        size_t size_bytes);
70 
71 // This function encodes the tokenized strings. Do not call it directly;
72 // instead, use the PW_TOKENIZE_TO_GLOBAL_HANDLER macro.
73 void _pw_tokenizer_ToGlobalHandler(pw_tokenizer_Token token,
74                                    pw_tokenizer_ArgTypes types,
75                                    ...);
76 
77 PW_EXTERN_C_END
78