BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsla_format.h
Go to the documentation of this file.
1
/// @file bsla_format.h
2
///
3
/// The content of this file has been pre-processed for Doxygen.
4
///
5
6
7
// bsla_format.h -*-C++-*-
8
#ifndef INCLUDED_BSLA_FORMAT
9
#define INCLUDED_BSLA_FORMAT
10
11
#include <
bsls_ident.h
>
12
BSLS_IDENT
(
"$Id: $"
)
13
14
/// @defgroup bsla_format bsla_format
15
/// @brief Provide a macro to indicate that a return value is a format string.
16
/// @addtogroup bsl
17
/// @{
18
/// @addtogroup bsla
19
/// @{
20
/// @addtogroup bsla_format
21
/// @{
22
///
23
/// <h1> Outline </h1>
24
/// * <a href="#bsla_format-purpose"> Purpose</a>
25
/// * <a href="#bsla_format-macros"> Macros </a>
26
/// * <a href="#bsla_format-description"> Description </a>
27
/// * <a href="#bsla_format-macro-reference"> Macro Reference </a>
28
/// * <a href="#bsla_format-usage"> Usage </a>
29
/// * <a href="#bsla_format-example-1-a-language-translator-function"> Example 1: A Language Translator Function </a>
30
///
31
/// # Purpose {#bsla_format-purpose}
32
/// Provide a macro to indicate that a return value is a format string.
33
///
34
/// # Macros {#bsla_format-macros}
35
///
36
/// - BSLA_FORMAT(FMT_IDX): validate `printf`-style format spec. in `n`th arg.
37
/// - BSLA_FORMAT_IS_ACTIVE: defined if `BSLA_FORMAT` is active
38
///
39
/// @see bsla_annotations
40
///
41
/// # Description {#bsla_format-description}
42
/// This component provides a preprocessor macro to indicate that
43
/// an indexed argument of a function is a `printf`-style format specification,
44
/// and that the function will return a `printf`-style format string with an
45
/// equivalent specification.
46
///
47
/// ## Macro Reference {#bsla_format-macro-reference}
48
///
49
///
50
/// `BSLA_FORMAT(FMT_IDX)`:
51
/// This annotation specifies that the so-annotated function takes an
52
/// argument that is a valid format string for a `printf`-style function
53
/// and returns a format string that is consistent with that format. This
54
/// allows format strings manipulated by translation functions to be
55
/// checked against arguments. Without this annotation, attempting to
56
/// manipulate the format string via this kind of function might generate
57
/// warnings about non-literal formats, or fail to generate warnings about
58
/// mismatched arguments.
59
///
60
/// `BSLA_FORMAT_IS_ACTIVE`:
61
/// The macro `BSLA_FORMAT_IS_ACTIVE` is defined if `BSLA_FORMAT` expands
62
/// to something with the desired effect; otherwise `BSLA_FORMAT_IS_ACTIVE`
63
/// is not defined and `BSLA_FORMAT` expands to nothing.
64
///
65
/// ## Usage {#bsla_format-usage}
66
///
67
///
68
/// This section illustrates intended use of this component.
69
///
70
/// ### Example 1: A Language Translator Function {#bsla_format-example-1-a-language-translator-function}
71
///
72
///
73
/// First, we define an `enum`, `Language`, to indicate the choice of languages:
74
/// @code
75
/// enum Language {
76
/// e_ENGLISH,
77
/// e_SPANISH,
78
/// e_DUTCH,
79
/// e_FRENCH };
80
/// @endcode
81
/// Then, we define a function, `prefixName`, which will take a format string
82
/// and prefix it with the word `name` in the selected language. The
83
/// `BSLA_FORMAT` annotation indicates that the result will be a pointer to a
84
/// `printf`-style format string equivalent to the format string passed to the
85
/// third argument:
86
/// @code
87
/// const char *prefixName(char *buf, Language lang, const char *format)
88
/// BSLA_FORMAT(3);
89
/// const char *prefixName(char *buf, Language lang, const char *format)
90
/// // Create a buffer beginning with the word 'name' translated to the
91
/// // specified 'lang', followed by the specified format string 'format',
92
/// // using the specified 'buf' for memory.
93
/// {
94
/// const char *name = "";
95
/// switch (lang) {
96
/// case e_ENGLISH: name = "Name"; break;
97
/// case e_SPANISH: name = "Nombre"; break;
98
/// case e_DUTCH: name = "Naam"; break;
99
/// case e_FRENCH: name = "Nom"; break;
100
/// }
101
/// ::strcpy(buf, name);
102
/// ::strcat(buf, ": ");
103
/// ::strcat(buf, format);
104
///
105
/// return buf;
106
/// }
107
/// @endcode
108
/// Next, in `main`, we call `printf` and `sscanf` using the return value of
109
/// `prefixName`. No warnings occur when correct arguments are passed:
110
/// @code
111
/// char buffer[1000];
112
/// ::printf(prefixName(buffer, e_SPANISH, "%s\n"), "Michael Bloomberg");
113
///
114
/// char name[100];
115
/// ::sscanf("Emmanuel Macron", prefixName(buffer, e_FRENCH, "%s"), name);
116
/// @endcode
117
/// Now, we call `printf` and `sscanf` passing arguments that won't match the
118
/// resulting format string:
119
/// @code
120
/// ::printf(prefixName(buffer, e_ENGLISH, "%s\n"), 2.7);
121
/// int x;
122
/// ::sscanf("Sharon den Adel", prefixName(buffer, e_DUTCH, "%s"), &x);
123
/// @endcode
124
/// Finally, we observe the following warning messages with g++:
125
/// @code
126
/// .../bsla/bsla_format.t.cpp:306:56: warning: format '%s' expects argument
127
/// of type 'char*', but argument 2 has type 'double' [-Wformat=]
128
/// ::printf(prefixName(buffer, e_ENGLISH, "%s\n"), 2.7);
129
/// ^
130
/// .../bsla_format.t.cpp:308:70: warning: format '%s' expects argument of
131
/// type 'char*', but argument 3 has type 'int*' [-Wformat=]
132
/// ::sscanf("Sharon den Adel", prefixName(buffer, e_DUTCH, "%s"), &x);
133
/// ~~^
134
/// @endcode
135
/// @}
136
/** @} */
137
/** @} */
138
139
/** @addtogroup bsl
140
* @{
141
*/
142
/** @addtogroup bsla
143
* @{
144
*/
145
/** @addtogroup bsla_format
146
* @{
147
*/
148
149
#include <bsls_platform.h>
150
151
// =============================
152
// Checks for Pre-Defined macros
153
// =============================
154
155
#if defined(BSLA_FORMAT)
156
#error BSLA_FORMAT is already defined!
157
#endif
158
159
#if defined(BSLA_FORMAT_IS_ACTIVE)
160
#error BSLA_FORMAT_IS_ACTIVE is already defined!
161
#endif
162
163
// =========================
164
// Set macros as appropriate
165
// =========================
166
167
#if defined(BSLS_PLATFORM_CMP_GNU) || \
168
defined(BSLS_PLATFORM_CMP_CLANG) || \
169
defined(BSLS_PLATFORM_CMP_IBM)
170
#define BSLA_FORMAT(FMT_IDX) __attribute__((format_arg(FMT_IDX)))
171
172
#define BSLA_FORMAT_IS_ACTIVE 1
173
#else
174
#define BSLA_FORMAT(FMT_IDX)
175
#endif
176
177
#endif
178
179
// ----------------------------------------------------------------------------
180
// Copyright 2019 Bloomberg Finance L.P.
181
//
182
// Licensed under the Apache License, Version 2.0 (the "License");
183
// you may not use this file except in compliance with the License.
184
// You may obtain a copy of the License at
185
//
186
// http://www.apache.org/licenses/LICENSE-2.0
187
//
188
// Unless required by applicable law or agreed to in writing, software
189
// distributed under the License is distributed on an "AS IS" BASIS,
190
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
191
// See the License for the specific language governing permissions and
192
// limitations under the License.
193
// ----------------------------- END-OF-FILE ----------------------------------
194
195
/** @} */
196
/** @} */
197
/** @} */
bsls_ident.h
BSLS_IDENT
#define BSLS_IDENT(str)
Definition
bsls_ident.h:195
doxygen_input
bde
groups
bsl
bsla
bsla_format.h
Generated by
1.9.8