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 // Like PW_TOKENIZE_TO_GLOBAL_HANDLER, encodes a tokenized string and arguments 23 // to a buffer on the stack. The macro adds a payload argument, which is passed 24 // through to the global handler function 25 // pw_tokenizer_HandleEncodedMessageWithPayload, which must be defined by the 26 // user of pw_tokenizer. The payload is a uintptr_t. 27 // 28 // For example, the following tokenizes a log string and passes the log level as 29 // the payload. 30 /* 31 #define LOG_ERROR(...) \ 32 PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD(kLogLevelError, __VA_ARGS__) 33 34 void pw_tokenizer_HandleEncodedMessageWithPayload( 35 pw_tokenizer_Payload log_level, 36 const uint8_t encoded_message[], 37 size_t size_bytes) { 38 if (log_level >= kLogLevelWarning) { 39 MyProject_EnqueueMessageForUart(buffer, size_bytes); 40 } 41 } 42 */ 43 #define PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD(payload, format, ...) \ 44 PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD_DOMAIN( \ 45 PW_TOKENIZER_DEFAULT_DOMAIN, payload, format, __VA_ARGS__) 46 47 // Same as PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD, but tokenizes to the 48 // specified domain. 49 #define PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD_DOMAIN( \ 50 domain, payload, format, ...) \ 51 PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD_MASK( \ 52 domain, UINT32_MAX, payload, format, __VA_ARGS__) 53 54 // Same as PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD_DOMAIN, but applies a mask 55 // to the token. 56 #define PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD_MASK( \ 57 domain, mask, payload, format, ...) \ 58 do { \ 59 PW_TOKENIZE_FORMAT_STRING(domain, mask, format, __VA_ARGS__); \ 60 _pw_tokenizer_ToGlobalHandlerWithPayload( \ 61 payload, \ 62 _pw_tokenizer_token, \ 63 PW_TOKENIZER_ARG_TYPES(__VA_ARGS__) PW_COMMA_ARGS(__VA_ARGS__)); \ 64 } while (0) 65 66 PW_EXTERN_C_START 67 68 typedef uintptr_t pw_tokenizer_Payload; 69 70 // This function must be defined pw_tokenizer:global_handler_with_payload 71 // backend. This function is called with the encoded message by 72 // pw_tokenizer_ToGlobalHandler and a caller-provided payload argument. 73 void pw_tokenizer_HandleEncodedMessageWithPayload( 74 pw_tokenizer_Payload payload, 75 const uint8_t encoded_message[], 76 size_t size_bytes); 77 78 // This function encodes the tokenized strings. Do not call it directly; 79 // instead, use the PW_TOKENIZE_TO_GLOBAL_HANDLER_WITH_PAYLOAD macro. 80 void _pw_tokenizer_ToGlobalHandlerWithPayload(pw_tokenizer_Payload payload, 81 pw_tokenizer_Token token, 82 pw_tokenizer_ArgTypes types, 83 ...); 84 85 PW_EXTERN_C_END 86