/src/logging-log4cxx/src/main/include/log4cxx/patternlayout.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
3 | | * contributor license agreements. See the NOTICE file distributed with |
4 | | * this work for additional information regarding copyright ownership. |
5 | | * The ASF licenses this file to You under the Apache License, Version 2.0 |
6 | | * (the "License"); you may not use this file except in compliance with |
7 | | * the License. You may obtain a copy of the License at |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | */ |
17 | | |
18 | | #ifndef _LOG4CXX_PATTERN_LAYOUT_H |
19 | | #define _LOG4CXX_PATTERN_LAYOUT_H |
20 | | |
21 | | #include <log4cxx/layout.h> |
22 | | #include <log4cxx/pattern/loggingeventpatternconverter.h> |
23 | | #include <log4cxx/pattern/formattinginfo.h> |
24 | | #include <log4cxx/pattern/patternparser.h> |
25 | | |
26 | | namespace LOG4CXX_NS |
27 | | { |
28 | | LOG4CXX_LIST_DEF(LoggingEventPatternConverterList, LOG4CXX_NS::pattern::LoggingEventPatternConverterPtr); |
29 | | LOG4CXX_LIST_DEF(FormattingInfoList, LOG4CXX_NS::pattern::FormattingInfoPtr); |
30 | | |
31 | | /** |
32 | | * A flexible layout configurable with pattern string. |
33 | | * |
34 | | * <p> |
35 | | * The goal of this class is to format a {@link spi::LoggingEvent LoggingEvent} and |
36 | | * return the results as a string. The results depend on the <em>conversion pattern</em>. |
37 | | * </p> |
38 | | * |
39 | | * <p> |
40 | | * The conversion pattern is closely related to the conversion pattern of the printf |
41 | | * function in C. A conversion pattern is composed of literal text and format control |
42 | | * expressions called <em>conversion specifiers</em>. |
43 | | * </p> |
44 | | * |
45 | | * <p> |
46 | | * <i>You are free to insert any literal text within the conversion pattern.</i> |
47 | | * </p> |
48 | | * |
49 | | * <p> |
50 | | * Each conversion specifier starts with a percent sign (%) and is followed by optional |
51 | | * <em>format modifiers</em> and a <em>conversion character</em>. The conversion character |
52 | | * specifies the type of data, e.g. logger, level, date, thread name. The format modifiers |
53 | | * control such things as field width, padding, left and right justification. The |
54 | | * following is a simple example. |
55 | | * </p> |
56 | | * |
57 | | * <p> |
58 | | * Let the conversion pattern be <strong>"%-5p [%t]: %m%n"</strong> and assume that the log4cxx |
59 | | * environment was set to use a PatternLayout. Then the statements |
60 | | * |
61 | | * ~~~{.cpp} |
62 | | * auto root = Logger::getRootLogger(); |
63 | | * root->debug("Message 1"); |
64 | | * root->warn("Message 2"); |
65 | | * ~~~ |
66 | | * |
67 | | * would yield the output |
68 | | * <pre> |
69 | | * DEBUG [main]: Message 1 |
70 | | * WARN [main]: Message 2</pre> |
71 | | * </p> |
72 | | * |
73 | | * <p> |
74 | | * Note that there is no explicit separator between text and conversion specifiers. The |
75 | | * pattern parser knows when it has reached the end of a conversion specifier when it |
76 | | * reads a conversion character. In the example above the conversion specifier <strong>%-5p</strong> |
77 | | * means the level of the logging event should be left justified to a width of five |
78 | | * characters. |
79 | | * </p> |
80 | | * |
81 | | * <p>The recognized conversion characters are:</p> |
82 | | * |
83 | | * <table border="1" cellpadding="8"> |
84 | | * <tr> |
85 | | * <th align="center"><strong>Conversion Character</strong></th> |
86 | | * <th align="center"><strong>Effect</strong></th> |
87 | | * </tr> |
88 | | * <tr> |
89 | | * <td align="center"><strong>c</strong></td> |
90 | | * <td> |
91 | | * Used to output the name of the logger generating the logging event. The <strong>c</strong> conversion specifier |
92 | | * can be optionally followed by <em>precision specifier</em>, that is a decimal |
93 | | * constant in brackets. |
94 | | * <p> |
95 | | * If a precision specifier is given, then only the corresponding number of |
96 | | * right most components of the logger name will be printed. By default the |
97 | | * logger name is printed in full. |
98 | | * </p> |
99 | | * <p> |
100 | | * For example, for the logger name "a.b.c" the pattern <strong>%c{2}</strong> will |
101 | | * output "b.c". |
102 | | * </p> |
103 | | * </td> |
104 | | * </tr> |
105 | | * <tr> |
106 | | * <td align="center"> |
107 | | * <p><strong>C</strong></p> |
108 | | * <p><strong>class</strong></p> |
109 | | * </td> |
110 | | * <td> |
111 | | * Used to output the class of the issuer of the logging event if the compiler |
112 | | * used supports a macro to retrieve the method of the currently compiled line and |
113 | | * if the LOG4CXX_TRACE-like macros are used to issue a logging request. In this |
114 | | * case the macro LOG4CXX_* is expanded at compile time to generate location info |
115 | | * of the logging event and adds the method name, besides file and line, if |
116 | | * available. In most cases the provided method contains the classname and can |
117 | | * therefore be retrieved form the location info as needed. |
118 | | * <p> |
119 | | * Currently supported compilers are those from Microsoft, GNU-C and Borland. |
120 | | * </p> |
121 | | * </td> |
122 | | * </tr> |
123 | | * <tr> |
124 | | * <td align="center"><strong>d</strong></td> |
125 | | * <td> |
126 | | * Used to output the date of the logging event. The date conversion specifier may |
127 | | * be followed by a set of braces containing a date and time pattern string |
128 | | * compatible with java.text.SimpleDateFormat, <em>ABSOLUTE</em>, <em>DATE</em> or |
129 | | * <em>ISO8601</em>. For example, <strong>%d{HH:mm:ss,SSS}</strong>, |
130 | | * <strong>%d{dd MMM yyyy HH:mm:ss,SSS}</strong> or <strong>%d{DATE}</strong>. If no |
131 | | * date format specifier is given then ISO8601 format is assumed. |
132 | | * </td> |
133 | | * </tr> |
134 | | * <tr> |
135 | | * <td align="center"><strong>f</strong></td> |
136 | | * <td> |
137 | | * Used to output the short file name where the logging request was issued. |
138 | | * </td> |
139 | | * </tr> |
140 | | * <tr> |
141 | | * <td align="center"><strong>F</strong></td> |
142 | | * <td> |
143 | | * Used to output the file name where the logging request was issued. |
144 | | * </td> |
145 | | * </tr> |
146 | | * <tr> |
147 | | * <td align="center"><strong>l</strong></td> |
148 | | * <td> |
149 | | * Used to output location information of the caller which generated the logging |
150 | | * event. |
151 | | * </td> |
152 | | * </tr> |
153 | | * <tr> |
154 | | * <td align="center"><strong>L</strong></td> |
155 | | * <td> |
156 | | * Used to output the line number from where the logging request was issued. |
157 | | * </td> |
158 | | * </tr> |
159 | | * <tr> |
160 | | * <td align="center"><strong>m</strong></td> |
161 | | * <td> |
162 | | * Used to output the application supplied message associated with the logging event. |
163 | | * To output in a quoted context, add set of braces containing the quote character. |
164 | | * Any quote character in the message is augmented with a second quote character. |
165 | | * For example, use %m{'} in an SQL insert statement. |
166 | | * </td> |
167 | | * </tr> |
168 | | * <tr> |
169 | | * <td align="center"> |
170 | | * <strong>M</strong> |
171 | | * <p><strong>method</strong></p> |
172 | | * </td> |
173 | | * <td> |
174 | | * Used to output the method of the issuer of the logging event if the compiler |
175 | | * used supports a macro to retrieve the method of the currently compiled line |
176 | | * and if the LOG4CXX_TRACE-like macros are used to issue a logging request. In |
177 | | * this case the macro LOG4CXX_* is expanded at compile time to generate location |
178 | | * info of the logging event and adds the method name, besides file and line, if |
179 | | * available. In most cases the provided method contains the classname which is |
180 | | * ignored in every attempt to retrieve the method from the location info. |
181 | | * <p> |
182 | | * Currently supported compilers are those from Microsoft, GNU-C and Borland. |
183 | | * </p> |
184 | | * </td> |
185 | | * </tr> |
186 | | * <tr> |
187 | | * <td align="center"><strong>n</strong></td> |
188 | | * <td> |
189 | | * Outputs the platform dependent line separator character or characters. |
190 | | * <p> |
191 | | * This conversion character offers practically the same performance as using |
192 | | * non-portable line separator strings such as "\n", or "\r\n". Thus, it is the |
193 | | * preferred way of specifying a line separator. |
194 | | * </p> |
195 | | * </td> |
196 | | * </tr> |
197 | | * <tr> |
198 | | * <td align="center"><strong>p</strong></td> |
199 | | * <td>Used to output the level of the logging event.</td> |
200 | | * </tr> |
201 | | * <tr> |
202 | | * <td align="center"><strong>r</strong></td> |
203 | | * <td> |
204 | | * Used to output the number of milliseconds elapsed since the start of the |
205 | | * application until the creation of the logging event. |
206 | | * </td> |
207 | | * </tr> |
208 | | * <tr> |
209 | | * <td align="center"><strong>t</strong><p><strong>thread</strong></p></td> |
210 | | * <td>Used to output the ID of the thread that generated the logging event.</td> |
211 | | * </tr> |
212 | | * <tr> |
213 | | * <td align="center"><strong>T</strong><p><strong>threadname</strong></p></td> |
214 | | * <td>Used to output the name of the thread that generated the logging event. May not be available on all platforms.</td> |
215 | | * </tr> |
216 | | * <tr> |
217 | | * <td align="center"><strong>x</strong></td> |
218 | | * <td> |
219 | | * Used to output the NDC (nested diagnostic context) associated with the thread that |
220 | | * generated the logging event. |
221 | | * </td> |
222 | | * </tr> |
223 | | * <tr> |
224 | | * <td align="center"><strong>X</strong></td> |
225 | | * <td> |
226 | | * Used to output the MDC (mapped diagnostic context) associated with the thread that |
227 | | * generated the logging event. All key/value pairs are output, each inside <strong>{}</strong> unless |
228 | | * the <strong>X</strong> is followed by a key placed between braces, as in <strong>%X{clientNumber}</strong> |
229 | | * where <code>clientNumber</code> is the key. In this case the value in the MDC corresponding to |
230 | | * the key will be output. |
231 | | * <p>See MDC class for more details.</p> |
232 | | * </td> |
233 | | * </tr> |
234 | | * <tr> |
235 | | * <td align="center"><strong>J</strong></td> |
236 | | * <td> |
237 | | * Used to output JSON key/value pairs of all MDC (mapped diagnostic context) |
238 | | * entries associated with the thread that generated the logging event. |
239 | | * To output in a quoted context, add set of braces containing the quote character. |
240 | | * Any quote character in the message is augmented with a second quote character. |
241 | | * For example, use %J{'} in an SQL insert statement. |
242 | | * <p>See MDC class for more details.</p> |
243 | | * </td> |
244 | | * </tr> |
245 | | * <tr> |
246 | | * <td align="center"><strong>y</strong></td> |
247 | | * <td> |
248 | | * Used to wrap log with color. The <strong>y</strong> is the end of a color block.<br> |
249 | | * </td> |
250 | | * </tr> |
251 | | * <tr> |
252 | | * <td align="center"><strong>Y</strong></td> |
253 | | * <td> |
254 | | * Used to wrap log with color. The <strong>Y</strong> is the start of a color block. |
255 | | * Color will be taken from the log level. The default colors are: |
256 | | * - `TRACE` - blue |
257 | | * - `DEBUG` - cyan |
258 | | * - `INFO` - green |
259 | | * - `WARN` - yellow |
260 | | * - `ERROR` - red |
261 | | * - `FATAL` - magenta |
262 | | * |
263 | | * These colors are all customizable. |
264 | | * </td> |
265 | | * </tr> |
266 | | * <tr> |
267 | | * <td align="center"><strong>%</strong></td> |
268 | | * <td>The sequence %% outputs a single percent sign.</td> |
269 | | * </tr> |
270 | | * </table> |
271 | | * |
272 | | * <p> |
273 | | * By default the relevant information is output as is. However, with the aid of format |
274 | | * modifiers it is possible to change the minimum field width, the maximum field width |
275 | | * and justification. |
276 | | * </p> |
277 | | * |
278 | | * <p> |
279 | | * The optional format modifier is placed between the percent sign and the conversion |
280 | | * character. |
281 | | * </p> |
282 | | * |
283 | | * <p> |
284 | | * The first optional format modifier is the <em>left justification flag</em> which is |
285 | | * just the minus (-) character. Then comes the optional <em>minimum field width</em> |
286 | | * modifier. This is a 1 to 3 decimal digit constant that represents the minimum number of characters |
287 | | * to output. If the data item requires fewer characters, it is padded on either the left |
288 | | * or the right until the minimum width is reached. The default is to pad on the left |
289 | | * (right justify) but you can specify right padding with the left justification flag. The |
290 | | * padding character is space. If the data item is larger than the minimum field width, |
291 | | * the field is expanded to accommodate the data. The value is never truncated. |
292 | | * </p> |
293 | | * |
294 | | * <p> |
295 | | * This behavior can be changed using the <em>maximum field width</em> modifier which is |
296 | | * designated by a period followed by a 1 to 3 decimal digit constant. If the data item is longer than |
297 | | * the maximum field, then the extra characters are removed from the <em>beginning</em> of |
298 | | * the data item and not from the end. For example, it the maximum field width is eight |
299 | | * and the data item is ten characters long, then the first two characters of the data |
300 | | * item are dropped. This behavior deviates from the printf function in C where truncation |
301 | | * is done from the end. |
302 | | * </p> |
303 | | * |
304 | | * <p>Below are various format modifier examples for the logger conversion specifier.</p> |
305 | | * |
306 | | * <table border="1" cellpadding="8"> |
307 | | * <tr> |
308 | | * <th align="center"><strong>Format modifier</strong></th> |
309 | | * <th align="center"><strong>left justify</strong></th> |
310 | | * <th align="center"><strong>minimum width</strong></th> |
311 | | * <th align="center"><strong>maximum width</strong></th> |
312 | | * <th align="center"><strong>comment</strong></th> |
313 | | * </tr> |
314 | | * <tr> |
315 | | * <td align="center">%20c</td> |
316 | | * <td align="center">false</td> |
317 | | * <td align="center">20</td> |
318 | | * <td align="center">none</td> |
319 | | * <td>Left pad with spaces if the logger name is less than 20 characters long.</td> |
320 | | * </tr> |
321 | | * <tr> |
322 | | * <td align="center">%-20c</td> |
323 | | * <td align="center">true</td> |
324 | | * <td align="center">20</td> |
325 | | * <td align="center">none</td> |
326 | | * <td>Right pad with spaces if the logger name is less than 20 characters long.</td> |
327 | | * </tr> |
328 | | * <tr> |
329 | | * <td align="center">%.30c</td> |
330 | | * <td align="center">NA</td> |
331 | | * <td align="center">none</td> |
332 | | * <td align="center">30</td> |
333 | | * <td>Truncate from the beginning if the logger name is longer than 30 characters.</td> |
334 | | * </tr> |
335 | | * <tr> |
336 | | * <td align="center">%20.30c</td> |
337 | | * <td align="center">false</td> |
338 | | * <td align="center">20</td> |
339 | | * <td align="center">30</td> |
340 | | * <td> |
341 | | * Left pad with spaces if the logger name is shorter than 20 characters. However, if |
342 | | * logger name is longer than 30 characters, then truncate from the beginning. |
343 | | * </td> |
344 | | * </tr> |
345 | | * <tr> |
346 | | * <td align="center">%-20.30c</td> |
347 | | * <td align="center">true</td> |
348 | | * <td align="center">20</td> |
349 | | * <td align="center">30</td> |
350 | | * <td> |
351 | | * Right pad with spaces if the logger name is shorter than 20 characters. However, if |
352 | | * logger name is longer than 30 characters, then truncate from the beginning. |
353 | | * </td> |
354 | | * </tr> |
355 | | * </table> |
356 | | * |
357 | | * <p>Below are some examples of conversion patterns.</p> |
358 | | * |
359 | | * <p><strong>%%r [%%t] %-5p %%c %%x - %%m\n</strong></p> |
360 | | * <p>This is essentially the TTCC layout.</p> |
361 | | * |
362 | | * <p><strong>%-6r [%15.15t] %-5p %30.30c %%x - %%m\n</strong></p> |
363 | | * |
364 | | * <p> |
365 | | * Similar to the TTCC layout except that the relative time is right padded if less than 6 |
366 | | * digits, thread name is right padded if less than 15 characters and truncated if longer |
367 | | * and the logger name is left padded if shorter than 30 characters and truncated if |
368 | | * longer. |
369 | | * </p> |
370 | | * |
371 | | * <p> |
372 | | * The above text is largely inspired from Peter A. Darnell and Philip E. Margolis' highly |
373 | | * recommended book "C -- a Software Engineering Approach", ISBN 0-387-97389-3. |
374 | | * </p> |
375 | | * |
376 | | * <h2>Colorizing log output</h2> |
377 | | * |
378 | | * In order to customize the colors for the %Y specifier, options have been added to the |
379 | | * PatternLayout in order to let users define their own colors. Foreground/background colors |
380 | | * can be set, as well as other text effects. A user can also set the ANSI escape pattern |
381 | | * directly if they want. |
382 | | * |
383 | | * Each level can be set individually. The configuration options for the levels are as follows: |
384 | | * <ul> |
385 | | * <li>FatalColor</li> |
386 | | * <li>ErrorColor</li> |
387 | | * <li>WarnColor</li> |
388 | | * <li>InfoColor</li> |
389 | | * <li>DebugColor</li> |
390 | | * <li>ErrorColor</li> |
391 | | * </ul> |
392 | | * |
393 | | * Foreground colors may be set by using fg(), background colors may be set by using bg(), and |
394 | | * other options(such as bold) may be set as well. |
395 | | * |
396 | | * Available colors: |
397 | | * <ul> |
398 | | * <li>Black</li> |
399 | | * <li>Red</li> |
400 | | * <li>Green</li> |
401 | | * <li>Yellow</li> |
402 | | * <li>Blue</li> |
403 | | * <li>Magenta</li> |
404 | | * <li>Cyan</li> |
405 | | * <li>White</li> |
406 | | * </ul> |
407 | | * |
408 | | * Available graphics modes: |
409 | | * <ul> |
410 | | * <li>Bold</li> |
411 | | * <li>Dim</li> |
412 | | * <li>Italic</li> |
413 | | * <li>Underline</li> |
414 | | * <li>Blinking</li> |
415 | | * <li>Inverse</li> |
416 | | * <li>Strikethrough</li> |
417 | | * </ul> |
418 | | * |
419 | | * Combining these together, we can configure our colors as we want, shown here in XML: |
420 | | * |
421 | | * Set the background color to red, make text blinking and bold: |
422 | | * <pre> |
423 | | * <param name="FatalColor" value="bg(red)|blinking|bold"/> |
424 | | * </pre> |
425 | | * |
426 | | * Set the foreground color to blue: |
427 | | * <pre> |
428 | | * <param name="FatalColor" value="fg(blue)"/> |
429 | | * </pre> |
430 | | * |
431 | | * Set the foreground color to white and the background color to black: |
432 | | * <pre> |
433 | | * <param name="FatalColor" value="fg(white)|bg(black)"/> |
434 | | * </pre> |
435 | | * |
436 | | * Clear the formatting for the specified level(no formatting will be applied): |
437 | | * <pre> |
438 | | * <param name="FatalColor" value="none"/> |
439 | | * </pre> |
440 | | * |
441 | | * Set a color based off on an ANSI escape sequence(equivalent to setting fg(red)): |
442 | | * <pre> |
443 | | * <param name="FatalColor" value="\x1b[31m"/> |
444 | | * </pre> |
445 | | */ |
446 | | class LOG4CXX_EXPORT PatternLayout : public Layout |
447 | | { |
448 | | LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(PatternLayoutPrivate, m_priv) |
449 | | |
450 | | public: |
451 | | DECLARE_LOG4CXX_OBJECT(PatternLayout) |
452 | 0 | BEGIN_LOG4CXX_CAST_MAP() |
453 | 0 | LOG4CXX_CAST_ENTRY(PatternLayout) |
454 | 0 | LOG4CXX_CAST_ENTRY_CHAIN(Layout) |
455 | 0 | END_LOG4CXX_CAST_MAP() |
456 | | |
457 | | /** |
458 | | * Does nothing |
459 | | */ |
460 | | PatternLayout(); |
461 | | |
462 | | /** |
463 | | * Constructs a PatternLayout using the supplied conversion pattern. |
464 | | */ |
465 | | PatternLayout(const LogString& pattern); |
466 | | |
467 | | ~PatternLayout(); |
468 | | |
469 | | /** |
470 | | * Use \c conversionPattern as to control formatting. |
471 | | * |
472 | | * The pattern can be a mix of literal content and |
473 | | * conversion specifiers. |
474 | | */ |
475 | | void setConversionPattern(const LogString& conversionPattern); |
476 | | |
477 | | /** |
478 | | * Returns the value of the <strong>ConversionPattern</strong> option. |
479 | | */ |
480 | | LogString getConversionPattern() const; |
481 | | |
482 | | /** |
483 | | \copybrief spi::OptionHandler::activateOptions() |
484 | | |
485 | | Calls createPatternParser |
486 | | */ |
487 | | void activateOptions(helpers::Pool& p) override; |
488 | | |
489 | | /** |
490 | | \copybrief spi::OptionHandler::setOption() |
491 | | |
492 | | Supported options | Supported values | Default value |
493 | | -------------- | ---------------- | --------------- |
494 | | ConversionPattern | {any} | \%m\%n |
495 | | FatalColor | (\ref validColors "1") | magenta |
496 | | ErrorColor | (\ref validColors "1") | red |
497 | | WarnColor | (\ref validColors "1") | yellow |
498 | | InfoColor | (\ref validColors "1") | green |
499 | | DebugColor | (\ref validColors "1") | cyan |
500 | | TraceColor | (\ref validColors "1") | blue |
501 | | |
502 | | \anchor validColors (1) The word <code>None</code> or |
503 | | <a href="https://en.wikipedia.org/wiki/ANSI_escape_code">valid ANSI escape sequence</a>. |
504 | | A prefix of <code>\\x1b</code> will be replaced with the <code>ESC</code> character. |
505 | | The character prefix <code>ESC</code> and suffix <code>m</code> will be added |
506 | | to the value if it does not begin with <code>\\x1b</code>. |
507 | | Color names can be combined with graphic modes using a <code>|</code> separator. |
508 | | Enclose the color name in <code>bg()</code> to set the background. |
509 | | Enclose the color name in <code>fg()</code> to set the foreground. |
510 | | |
511 | | \sa setConversionPattern |
512 | | */ |
513 | | void setOption(const LogString& option, const LogString& value) override; |
514 | | |
515 | | /** |
516 | | * The PatternLayout does not handle the throwable contained within |
517 | | * {@link spi::LoggingEvent LoggingEvents}. Thus, it returns |
518 | | * <code>true</code>. |
519 | | */ |
520 | | bool ignoresThrowable() const override |
521 | 0 | { |
522 | 0 | return true; |
523 | 0 | } |
524 | | |
525 | | /** |
526 | | * Produces a formatted string as specified by the conversion pattern. |
527 | | */ |
528 | | void format( LogString& output, |
529 | | const spi::LoggingEventPtr& event, |
530 | | helpers::Pool& pool) const override; |
531 | | |
532 | | protected: |
533 | | virtual LOG4CXX_NS::pattern::PatternMap getFormatSpecifiers(); |
534 | | |
535 | | private: |
536 | | pattern::PatternConverterPtr createColorStartPatternConverter(const std::vector<LogString>& options); |
537 | | }; |
538 | | |
539 | | LOG4CXX_PTR_DEF(PatternLayout); |
540 | | } // namespace log4cxx |
541 | | |
542 | | #endif //_LOG4CXX_PATTERN_LAYOUT_H |