blob: a2defee7019f96e66b64dc953782931da75db6e1 [file] [log] [blame]
/* --COPYRIGHT--,ESD
* Copyright (c) 2008 Texas Instruments. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License
* v. 1.0 which accompanies this distribution. The Eclipse Public License is
* available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
* Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Texas Instruments - initial implementation
* --/COPYRIGHT--*/
/*
* ======== Log.xdc ========
*/
/*!
* ======== Log ========
* Event logging manager
*
* RTSC modules and the application code generate `{@link #Event Log_Event}`
* events by calling the `Log` module's functions. The `Log` module then
* passes those events to an `{@link ILogger}` instance assigned to the event
* originating module, specified by that module's configuration parameter
* `common$.logger`. `ILogger` instances handle events, usually converting
* events to `{@link #EventRec Log_EventRec}` records prior to recording,
* transmitting, or displaying them.
*
* All events generated by a target module are stored and displayed by an
* `ILogger`, examples of which are instances of
* `{@link LoggerBuf xdc.runtime.LoggerBuf}` or
* `{@link LoggerSys xdc.runtime.LoggerSys}`. At runtime, modules
* generate events through this module, rather than invoking directly their
* `ILogger`s. By doing so, modules can be configured to use different
* `ILogger` implementations without any changes to their source code.
*
* A logger instance can accept `Log` events from any module, but a module
* can put `Log` events to only one logger instance. There can be one or
* more logger instances in a system. All `Log` calls that are not in a
* module are controlled by the module `{@link Main xdc.runtime.Main}`.
* For example, top-level application code or any existing sources that
* simply call the `Log` or `Assert` methods implicitly use the logger
* associated with the `Main` module.
*
* The generation of a `Log` event is controlled by a module's diagnostics
* mask, which is described in details in `{@link Diags}`. Each `Log` event
* is associated with a mask. `Log` events are generated only when a
* particular bit is set in both the `Log` event mask and the module's
* diagnostics mask. For example, a `Log` event mask with the
* `{@link Diags#USER1 USER1}` bit set is generated only when the `USER1`
* bit is also set in the module's diagnostics mask.
*
* There are two ways to generate `Log` events:
*
* @p(blist)
* - `{@link #write8 Log_write()}`, which is tailored for module writers
* and takes full advantage of the XDC configuration model. For example,
* the message string associated with the `Log` event need not be a part of
* the final application, significantly reducing the "footprint overhead"
* of embedding diagnostics in deployed systems. The `Log_write[0-8]()`
* functions allow up to 8 values to be passed to the logger. They expect
* the logger to handle any formatting. A `Log` event type allows you to
* specify the type of event.
* - `{@link #print6 Log_print()}`, which is designed for arbitrary C code.
* The `Log_print[0-6]()` functions allow up to 6 values to be passed along
* with a printf-like format string to the logger. They handle printf-style
* formatting.
* @p
*
* Both functions are controlled by the module's diagnostics mask. Their
* storage or output is defined by the logger that is assigned to the
* module that calls the `Log` methods or to the
* `{@link Main xdc.runtime.Main}` module if the caller is not part of a
* module.
*
* The `Log` function call sites are implemented in such a way that an
* optimizer can completely eliminate `Log` code from the program if the
* `Log` functions have been permanently disabled at configuration time. If
* the `Log` functions are permanently turned on at configuration time,
* then the optimizer can eliminate all runtime conditional checking and
* simply invoke the `Log` functions directly. Runtime checking is performed
* only when the `Log` functions are configured to be runtime modifiable.
*
* The Log calls can also be completely removed by defining the symbol
* `xdc_runtime_Log_DISABLE_ALL`. This can be done on the compile line, e.g.
* `-Dxdc_runtime_Log_DISABLE_ALL`. This will completely remove the `Log`
* statements from any code compiled with this flag, regardless of the
* application's logging configuration or your compiler's optimization
* settings.
*
* It is also possible to remove all logging except for
* `{@link #error Log_error}`, `{@link #warning Log_warning}`, or
* `{@link #info Log_info}` statements. This is done by first defining
* `xdc_runtime_Log_DISABLE_ALL`, followed by defining one or more of the
* symbols below to leave that type of logging enabled:
* @p(blist)
* - `xdc_runtime_Log_ENABLE_ERROR`
* - `xdc_runtime_Log_ENABLE_WARNING`
* - `xdc_runtime_Log_ENABLE_INFO`
* @p
* For example, to disable all `Log` statements except for `Log_error`, add
* the following to the compile line:
* @p(code)
* -Dxdc_runtime_Log_DISABLE_ALL -Dxdc_runtime_Log_ENABLE_ERROR
* @p
*
* @a(Examples)
* Example 1: The following example defines a `Log` event, uses that `Log`
* event in a module, and configures the program to generate the `Log`
* event. In this example, both `USER1` and `USER2` bits are set in the
* event mask. This means that if either bit is set in the module's
* diagnostics mask, then the `Log` event will be generated.
*
* This is a part of the XDC specification file for the `Mod` module
* (Mod.xdc):
*
* @p(code)
* import xdc.runtime.Diags;
* import xdc.runtime.Log;
*
* config Log.Event L_someEvent = {
* mask: Diags.USER1 | Diags.USER2,
* level: Diags.LEVEL1,
* msg: "my log event message, arg1: 0x%x, arg2: 0x%x"
* };
* @p
*
* This is a part of the C code implementation of the Mod module:
*
* @p(code)
* #include <xdc/runtime/Log.h>
* UInt x, y;
*
* Log_write2(Mod_L_someEvent, (IArg)x, (IArg)y);
* @p
*
* The following configuration script demonstrates how the application might
* control the `Log` statements embedded in the `Mod` module at configuration
* time. In this case, the configuration script arranges for the `Log`
* statements within the `Mod` module (shown above) to always generate events.
* Without these configuration statements, no `Log` events would be generated
* by this module.
*
* This is part of the XDC configuration file for the application:
*
* @p(code)
* var Diags = xdc.useModule('xdc.runtime.Diags');
* var LoggerSys = xdc.useModule('xdc.runtime.LoggerSys');
* var Mod = xdc.useModule('my.pkg.Mod');
* Mod.common$.diags_USER1 = Diags.ALWAYS_ON;
* Mod.common$.logger = LoggerSys.create();
* @p
*
* @p(html)
* <hr />
* @p
*
* Example 2: The following XDC configuration statements turn on enter
* and exit logging at configuration time for a module. Without any other
* changes in the runtime code, every time a module `Mod`'s function is
* being called or exits, an event will be logged.
*
* @p(code)
* var Diags = xdc.useModule('xdc.runtime.Diags');
* var Mod = xdc.useModule('my.pkg.Mod');
*
* Mod.common$.diags_ENTER = Diags.ALWAYS_ON;
* Mod.common$.diags_EXIT = Diags.ALWAYS_ON;
* @p
*
* @p(html)
* <hr />
* @p
*
* Example 3: The following example configures a module to support enter and
* exit logging, but defers the actual activation and deactivation of the
* logging until runtime. See the `{@link Diags#setMask Diags_setMask()}`
* function for details on specifying the control string.
*
* This is a part of the XDC configuration file for the application:
*
* @p(code)
* var Diags = xdc.useModule('xdc.runtime.Diags');
* var Mod = xdc.useModule('my.pkg.Mod');
*
* Mod.common$.diags_ENTER = Diags.RUNTIME_OFF;
* Mod.common$.diags_EXIT = Diags.RUNTIME_OFF;
* @p
*
* This is a part of the C code for the application:
*
* @p(code)
* // turn on enter and exit logging in the module
* Diags_setMask("my.pkg.Mod+EX");
*
* // turn off enter and exit logging in the module
* Diags_setMask("my.pkg.Mod-EX");
* @p
*/
@CustomHeader
@DirectCall
module Log {
/*!
* ======== NUMARGS ========
* Maximum number of arguments supported in `Log` events.
*/
const Int NUMARGS = 8;
/*!
* ======== PRINTFID ========
* The `EventId` for `Log_print()` events
*/
const EventId PRINTFID = 0;
/*!
* ======== EventDesc ========
* `Log` event descriptor
*
* Each `Log` event is defined by a `Log` event descriptor.
*
* The `mask` defines which bits in the module's diagnostics mask
* enable this `Log` event. Events "posted" via `Log_write` are only
* written to the underlying logger if one of the mask's bits matches
* the caller's module diagnostics settings (see
* `{@link xdc.runtime.Types#common$}`).
*
* The 'level' defines the event level of the event. While the diags
* bits selected in the 'mask' signify the "category" of the event (e.g.
* Entry/Exit, Analysis, Info), the 'level' field allows you to assign
* a "priority" or "detail level" to the event relative to other events in
* that category. There are four event levels defined by
* '{@link xdc.runtime.Diags#EventLevel}'.
*
* Filtering of events by level is handled by the ILogger implementation.
* ILogger implementations which also implement the {@link IFilterLogger}
* interface support filtering of events based on priority level.
*
* Specifying an event level is optional. Events that don't specify a
* level will receive Diags.LEVEL1 by default, making them the highest
* priority and ensuring that they will not inadvertently be filtered out
* by level-based filtering.
*
* The `msg` defines a printf style format string that defines how to
* render the arguments passed along the event in a `Log_write` call.
* For a description of the allowable format strings see
* `{@link #print6}`.
*
* @see #write8
* @see #print6
*/
metaonly struct EventDesc {
Diags.Mask mask; /*! event enable mask */
Diags.EventLevel level; /*! event level relative to other events */
String msg; /*! event "printf" message format string */
};
/*!
* ======== EventRec ========
* The target representation of a recorded event
*
* This structure defines how events are recorded on the target.
*/
struct EventRec {
Types.Timestamp64 tstamp; /*! time event was written */
Bits32 serial; /*! serial number of event */
Types.Event evt; /*! target encoding of an Event */
IArg arg[NUMARGS]; /*! arguments passed via Log_write/print */
}
/*!
* ======== Event ========
* `Log` event type
*
* An `Event` is represented on the target as a 32-bit value that can
* be decoded offline to recover the `Event` information defined in
* a corresponding metaonly `EventDesc`. In addition, `Event`s may be
* decoded at runtime via methods provided in this module; see
* `{@link #getMask}` and `{@link #getEventId}`.
*
* When an event is "raised" a `{@link Types#Event Types_Event}` is
* created which has the same event ID as the `Log_Event` but also
* encodes the module ID of the caller. This new event is passed to
* the underlying `{@link ILogger}` module along with any arguments
* associated with the event.
*
* @see #getMask
* @see #getEventId
*/
@Encoded typedef EventDesc Event;
/*!
* ======== EventId ========
* Unique ID embedded in each `{@link #Event}`
*
* This ID must be used to compare two `Event`s for equality. Event
* ids are not guaranteed to remain constant between different
* configurations of an application. For example, adding a module
* may cause the event ids of another module to change.
*
* However, event ids declared by a module are guaranteed to be
* consecutive values starting from the first declared
* `{@link #Event Log_Event}` and increasing to the last declared
* event. As a result, clients of a module can efficiently test ranges
* of events and modules can add new events, such as internal trace
* events, without breaking clients; simply be careful to add new events
* after any existing events in you module's `.xdc` specification.
*
* @see #getEventId
* @see #Event
*/
typedef Types.RopeId EventId;
/*!
* ======== L_construct ========
* Lifecycle event posted when an instance is constructed
*/
config Log.Event L_construct = {
mask: Diags.LIFECYCLE,
msg: "<-- construct: %p('%s')"
};
/*!
* ======== L_create ========
* Lifecycle event posted when an instance is created
*/
config Log.Event L_create = {
mask: Diags.LIFECYCLE,
msg: "<-- create: %p('%s')"
};
/*!
* ======== L_destruct ========
* Lifecycle event posted when an instance is destructed
*/
config Log.Event L_destruct = {
mask: Diags.LIFECYCLE,
msg: "--> destruct: (%p)"
};
/*!
* ======== L_delete ========
* Lifecycle event posted when an instance is deleted
*/
config Log.Event L_delete = {
mask: Diags.LIFECYCLE,
msg: "--> delete: (%p)"
};
/*!
* ======== L_error ========
* Error event posted by Log_errorX API
*
* This event is marked as a STATUS event and given the priority level
* of ERROR.
*
* This event prints the Log call site (%$F) and a format string (%$S)
* which is recursively formatted with any additional arguments.
*/
config Log.Event L_error = {
mask: Diags.STATUS,
level: Diags.ERROR,
msg: "ERROR: %$F%$S"
};
/*!
* ======== L_warning ========
* Warning event posted by Log_warningX API
*
* This event is marked as a STATUS event and given the priority level of
* WARNING.
*
* This event prints the Log call site (%$F) and a format string (%$S)
* which is recursively formatted with any addition arguments.
*/
config xdc.runtime.Log.Event L_warning = {
mask: Diags.STATUS,
level: Diags.WARNING,
msg: "WARNING: %$F%$S"
};
/*!
* ======== L_info ========
* Info event posted by Log_infoX API
*
* This event is marked as an INFO event. The event priority is not
* specified in the event definition. Rather, it is specified as an
* argument to the Log_infoX APIs.
*
* This event prints the Log call site (%$F) and a format string (%$S)
* which is recursively formatted with any addition arguments.
*/
config xdc.runtime.Log.Event L_info = {
mask: Diags.INFO,
msg: "%$F%$S"
};
/*!
* ======== L_start ========
* Benchmark event used to log the start of an operation
* @_nodoc
*
* @a(Example)
* The following C code shows how to log a simple
* benchmark 'start' event along with a user-specified
* format string describing the event.
*
* @p(code)
* #include <xdc/runtime/Log.h>
* ...
* Log_write2(Log_L_start, (IArg)"My benchmark event", (IArg)myUniqueId);
* Log_write2(Log_L_stop, (IArg)"My benchmark event", (IArg)myUniqueId);
* @p
*
* @param(fmt) a constant string that provides format specifiers for
* up to 6 additional parameters
* @param(id) a unique ID used to match benchmark start and stop
* events
*/
config xdc.runtime.Log.Event L_start = {
mask: Diags.ANALYSIS,
msg: "Start: %$S"};
/*!
* ======== L_stop ========
* Benchmark event used to log the end of an operation
* @_nodoc
*
* @a(Example)
* The following C code shows how to log a simple
* benchmark 'stop' event along with a user-specified
* format string describing the event.
*
* @p(code)
* #include <xdc/runtime/Log.h>
* ...
* Log_write2(Log_L_start, (IArg)"My benchmark event", (IArg)myUniqueId);
* Log_write2(Log_L_stop, (IArg)"My benchmark event", (IArg)myUniqueId);
* @p
*
* @param(fmt) a constant string that provides format specifiers for
* up to 6 additional parameters
* @param(id) a unique ID used to match benchmark start and stop
* events
*/
config xdc.runtime.Log.Event L_stop = {
mask: Diags.ANALYSIS,
msg: "Stop: %$S"};
/*!
* ======== L_startInstance ========
* Benchmark event used to log the start of an operation instance
* @_nodoc
*
* Event parameter provides instance data to differentiate
* between multiple instances that can run in parallel.
*
* @a(Example)
* The following C code shows how to log a benchmark
* 'startInstance' event along with a user-specified
* instance identifier and a format string describing the event.
*
* @p(code)
* #include <xdc/runtime/Log.h>
* ...
* Log_write3(Log_L_startInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
* ...
* Log_write3(Log_L_stopInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
* @p
*
* @param(fmt) a constant string that provides format specifiers for
* up to 6 additional parameters
* @param(id) a unique ID used to match benchmark start and stop
* events
* @param(instId) a unique instance ID that can be used to match
* instance events
*/
config xdc.runtime.Log.Event L_startInstance = {
mask: Diags.ANALYSIS,
msg: "StartInstance: %$S"
};
/*!
* ======== L_stopInstance ========
* Benchmark event used to log the end of an operation instance
* @_nodoc
*
* Event parameter provides instance data to differentiate
* between multiple instances that can run in parallel.
*
* @a(Example)
* The following C code shows how to log a benchmark
* 'stopInstance' event along with a user-specified
* instance identifier and a format string describing the event.
*
* @p(code)
* #include <xdc/runtime/Log.h>
* ...
* Log_write3(Log_L_startInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
* ...
* Log_write3(Log_L_stopInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
* @p
*
* @param(fmt) a constant string that provides format specifiers for
* up to 6 additional parameters
* @param(id) a unique ID used to match benchmark start and stop
* events
* @param(instId) a unique instance ID that can be used to match
* instance events
*/
config xdc.runtime.Log.Event L_stopInstance = {
mask: Diags.ANALYSIS,
msg: "StopInstance: %$S"
};
/*!
* ======== getMask ========
* Get the `Diags` mask for the specified (encoded) event
*
* @param(evt) the `Log` event encoding a mask and event ID
*
* @a(returns) `Diags` mask for the specified event
*/
@Macro Diags.Mask getMask(Event evt);
/*!
* ======== getRope ========
* Get RopeId of the Event.msg for the specified (encoded) event
* @_nodoc
*/
@Macro Text.RopeId getRope(Event evt);
/*!
* ======== getEventId ========
* Get event ID of the specified (encoded) event
*
* This method is used to compare "known" `Log` events with
* "raised" `{@link Types#Event Types_Event}`.
*
* @param(evt) the `Log` event encoding a mask and event ID
*
* @a(returns) event ID of the specified event
*
* @see Types#getEventId
*/
@Macro EventId getEventId(Event evt);
/*!
* ======== print0 ========
* Generate a `Log` "print event" with 0 arguments
*
* @see #print6
*/
@Macro Void print0(Diags.Mask mask, CString fmt);
/*!
* ======== print1 ========
* Generate a `Log` "print event" with 1 argument
*
* @see #print6
*/
@Macro Void print1(Diags.Mask mask, CString fmt, IArg a1);
/*!
* ======== print2 ========
* Generate a `Log` "print event" with 2 arguments
*
* @see #print6
*/
@Macro Void print2(Diags.Mask mask, CString fmt, IArg a1, IArg a2);
/*!
* ======== print3 ========
* Generate a `Log` "print event" with 3 arguments
*
* @see #print6
*/
@Macro Void print3(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
IArg a3);
/*!
* ======== print4 ========
* Generate a `Log` "print event" with 4 arguments
*
* @see #print6
*/
@Macro Void print4(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
IArg a3, IArg a4);
/*!
* ======== print5 ========
* Generate a `Log` "print event" with 5 arguments
*
* @see #print6
*/
@Macro Void print5(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
IArg a3, IArg a4, IArg a5);
/*!
* ======== print6 ========
* Generate a `Log` "print event" with 6 arguments
*
* As a convenience to C (as well as assembly language) programmers,
* the `Log` module provides a variation of the ever-popular `printf`
* function.
* The `print[0-6]` functions generate a `Log` "print event" and route
* it to the current module's logger.
*
* The arguments passed to `print[0-6]` may be characters, integers,
* strings, or pointers. However, because the declared type of the
* arguments is `{@link xdc IArg}`, all pointer arguments must be cast
* to an `IArg` type. `IArg` is an integral type large enough to hold
* any pointer or an `int`. So, casting a pointer to an `IArg` does
* not cause any loss of information and C's normal integer conversions
* make the cast unnecessary for integral arguments.
*
* The format string can use the following conversion characters.
* However, it is important to recall that all arguments referenced by
* these conversion characters have been converted to an `IArg`
* prior to conversion; so, the use of "length modifiers" should be
* avoided.
*
* @p(code)
* Conversion Character Description
* ------------------------------------------------
* %c Character
* %d Signed integer
* %u Unsigned integer
* %x Unsigned hexadecimal integer
* %o Unsigned octal integer
* %s Character string
* %p Pointer
* %f Single precision floating point (float)
* @p
*
* Format strings, while very convenient, are a well known source of
* portability problems: each format specification must precisely match
* the types of the arguments passed. Underlying "printf" functions use
* the format string to determine how far to advance through their
* argument list. For targets where pointer types and integers are the
* same size there are no problems. However, suppose a target's pointer
* type is larger than its integer type. In this case, because integer
* arguments are widened to be of type `IArg`, a format specification of
* "%d" causes an underlying `printf()` implementation to read the
* extended part of the integer argument as part of the next argument(!).
*
* To get around this problem and still allow the use of "natural"
* format specifications (e.g., `%d` and `%x` with optional width
* specifications), `{@link System#aprintf()}` is used which assumes
* that all arguments have been widened to be of type `IArg`.
*
* See `{@link System#printf}` for complete details.
*
* The `%f` format specifier is used to print a single precision float
* value. Note that `%f` assumes that sizeof(Float) <= sizeof(IArg).
* Most clients that interpret float values expect that they are
* represented in IEEE 754 floating point format. Therefore, it is
* recommended that the float values be converted into that format prior
* to supplying the values to `Log` functions in cases where targets do
* not generate the float values in IEEE 754 floating point format by
* default.
*
* The first argument to a `Log_print` call is the diags category to be
* associated with the event.
*
* It is also possible to associate an event level with the event to
* enable filtering of events based on event level. Conceptually, it is
* best to regard the event level as completely separate from the event's
* diags category; however, the priority value actually occupies a part
* of the diags mask. For this reason, it is possible to specify an event
* level by OR'ing the level with the diags mask. For example, to print
* an `Diags_INFO` event of `Diags_LEVEL2`, you'd simply write:
* (Diags_INFO | Diags_LEVEL2)
*
* Specifying an event level is optional. `Log_print` calls which do not
* specify a level will receive the highest priority by default.
*
* @param(mask) enable bits and optional detail level for this event
* @param(fmt) a `printf` style format string
* @param(a1) value for first format conversion character
* @param(a2) value for second format conversion character
* @param(a3) value for third format conversion character
* @param(a4) value for fourth format conversion character
* @param(a5) value for fifth format conversion character
* @param(a6) value for sixth format conversion character
*
* @a(Examples)
* The following example demonstrates a typical usage.
* @p(code)
* String list[];
* UInt i;
*
* Log_print2(Diags_USER2, "list[%u] = %s\n", i, (IArg)list[i]);
* @p
* Note that the `IArg` cast above is only necessary for pointer
* arguments; C's normal parameter conversions implicitly convert
* integral arguments.
*
* To simplify the conversion from `float` arguments to `IArg`,
* the standard header `xdc/std.h` provides a macro, named floatToArg(),
* to do this conversion in a type safe manner. So, the following
* statement will print "`float = 2.3456`":
* @p(code)
* Log_print1(Diags_USER1, "float = %f", floatToArg(2.34567));
* @p
*
* Note that, if you are formatting events on the target, you must
* also add support for floating point to ASCII conversion to
* `{@link System#printf}`; for more information, see the
* `{@link System#extendedFormats}` reference documenation. For example:
* @p(code)
* var System = xdc.useModule('xdc.runtime.System');
* System.extendedFormats = "%f";
* @p
*/
@Macro Void print6(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
IArg a3, IArg a4, IArg a5, IArg a6);
/*!
* ======== error0 ========
* Generate a `Log` "error event" with 0 arguments
*
* @see #error5
*/
@Macro Void error0(CString fmt);
/*!
* ======== error1 ========
* Generate a `Log` "error event" with 1 argument
*
* @see #error5
*/
@Macro Void error1(CString fmt, IArg a1);
/*!
* ======== error2 ========
* Generate a `Log` "error event" with 2 arguments
*
* @see #error5
*/
@Macro Void error2(CString fmt, IArg a1, IArg a2);
/*!
* ======== error3 ========
* Generate a `Log` "error event" with 3 arguments
*
* @see #error5
*/
@Macro Void error3(CString fmt, IArg a1, IArg a2, IArg a3);
/*!
* ======== error4 ========
* Generate a `Log` "error event" with 4 arguments
*
* @see #error5
*/
@Macro Void error4(CString fmt, IArg a1, IArg a2, IArg a3,
IArg a4);
/*!
* ======== error5 ========
* Generate a `Log` "error event" with 5 arguments
*
* The Log_error APIs are intended to allow users to easily log error
* events in their code. Similar to the Log_print APIs, Log_error does not
* require that you define an event. You simply pass an informative error
* string which can optionally be formatted with additional arguments. The
* error is logged with the predefined event {@link #L_error}.
*
* Log_error prepends a string to the message which identifies it as an
* ERROR and specifies the filename and line number of the Log_error call
* site. A simple example:
*
* @p(code)
* Log_error0("Invalid argument");
* @p
* This event will be formatted as (assuming that the above call was line
* 35 of "MyCode.c")
* @p(code)
* ERROR at "MyCode.c", line 35: Invalid argument
* @p
*
* Users may provide additional information in the error event, such as
* a predefined error code or details of the error. These additional
* values will be used to format the string passed to Log_error.
* @see #print6 for information about format strings.
*
* Log_error does not use a variable length argument list--you must call
* the appropriate Log_errorX API based on the number of arguments.
*
* @param(fmt) a reference to a constant error string / fmt string
* @param(a1) value for an additional parameter (e.g. an error code)
* @param(a2) value for an additional parameter
* @param(a3) value for an additional parameter
* @param(a4) value for an additional parameter
* @param(a5) value for an additional parameter
*
* @a(Examples)
* The following example demonstrates a typical usage.
* @p(code)
* Int myArg;
*
* Log_error1("Invalid argument: %d", myArg);
* @p
* The above event is formatted as, for example:
* @p(code)
* ERROR: "MyCode.c", line 35: Invalid argument: -1
* @p
*/
@Macro Void error5(CString fmt, IArg a1, IArg a2, IArg a3,
IArg a4, IArg a5);
/*!
* ======== warning0 ========
* Generate a `Log` "warning event" with 0 arguments
*
* @see #warning5
*/
@Macro Void warning0(CString fmt);
/*!
* ======== warning1 ========
* Generate a `Log` "warning event" with 1 argument
*
* @see #warning5
*/
@Macro Void warning1(CString fmt, IArg a1);
/*!
* ======== warning2 ========
* Generate a `Log` "warning event" with 2 arguments
*
* @see #warning5
*/
@Macro Void warning2(CString fmt, IArg a1, IArg a2);
/*!
* ======== warning3 ========
* Generate a `Log` "warning event" with 3 arguments
*
* @see #warning5
*/
@Macro Void warning3(CString fmt, IArg a1, IArg a2, IArg a3);
/*!
* ======== warning4 ========
* Generate a `Log` "warning event" with 4 arguments
*
* @see #warning5
*/
@Macro Void warning4(CString fmt, IArg a1, IArg a2, IArg a3,
IArg a4);
/*!
* ======== warning5 ========
* Generate a `Log` "warning event" with 5 arguments
*
* The Log_warning APIs provide the same features as the Log_error APIs,
* but are used to specifically log "warning" events.
* @see #error5
*
* The Log_warning APIs are equivalent to the Log_error APIs except that
* they use the predefined {@link #L_warning} event. Log_warning prepends
* a string to the message which identifies it as a WARNING and specifies
* the filename and line number of the Log_warning call site.
*
* @param(fmt) reference to a constant warning string / fmt string
* @param(a1) value for an additional parameter (e.g. a warning code)
* @param(a2) value for an additional parameter
* @param(a3) value for an additional parameter
* @param(a4) value for an additional parameter
* @param(a5) value for an additional parameter
*
* @a(Examples)
* The following example demonstrates a typical usage.
* @p(code)
* Int myArg;
*
* Log_warning1("Value may be too high: %d", myArg);
* @p
* The above event is formatted as:
* @p(code)
* WARNING: "MyCode.c", line 50: Value may be too high: 4096
* @p
*/
@Macro Void warning5(CString fmt, IArg a1, IArg a2, IArg a3,
IArg a4, IArg a5);
/*!
* ======== info0 ========
* Generate a `Log` "info event" with 0 arguments
*
* @see #info5
*/
@Macro Void info0(CString fmt);
/*!
* ======== info1 ========
* Generate a `Log` "info event" with 1 argument
*
* @see #info5
*/
@Macro Void info1(CString fmt, IArg a1);
/*!
* ======== info2 ========
* Generate a `Log` "info event" with 2 arguments
*
* @see #info5
*/
@Macro Void info2(CString fmt, IArg a1, IArg a2);
/*!
* ======== info3 ========
* Generate a `Log` "info event" with 3 arguments
*
* @see #info5
*/
@Macro Void info3(CString fmt, IArg a1, IArg a2, IArg a3);
/*!
* ======== info4 ========
* Generate a `Log` "info event" with 4 arguments
*
* @see #info5
*/
@Macro Void info4(CString fmt, IArg a1, IArg a2, IArg a3, IArg a4);
/*!
* ======== info5 ========
* Generate a `Log` "info event" with 5 arguments
*
* The Log_info APIs are provided for easily logging generic
* "informational" events with call site information. They are similar to
* the Log_print APIs in that they do not require you to define an event--
* you simply pass an informative printf-style string which can optionally
* be formatted with additional arguments. The info record is logged with
* the predefined event '{@link #L_info}'.
*
* The Log_info APIs log the {@link #L_info} event which uses the 'INFO'
* diags category. They do not allow you to specify an event priority.
*
* Log_info prepends the filename and line number of the call site to the
* message.
*
* @param(fmt) reference to a constant event string / fmt string
* @param(a1) value for an additional parameter (e.g. an event code)
* @param(a2) value for an additional parameter
* @param(a3) value for an additional parameter
* @param(a4) value for an additional parameter
* @param(a5) value for an additional parameter
*
* @a(Examples)
* The following example demonstrates a typical usage.
* @p(code)
* Int load;
*
* Log_info1("Current load: %d", load);
* @p
* The above event is formatted as, for example:
* @p(code)
* "MyCode.c", line 15: Current load: 25
* @p
*/
@Macro Void info5(CString fmt, IArg a1, IArg a2, IArg a3, IArg a4,
IArg a5);
/*!
* ======== put0 ========
* Unconditionally put the specified Log event with 0 arguments
*
* @see #put8
*/
@Macro Void put0(Log.Event evt, Types.ModuleId mid);
/*!
* ======== put1 ========
* Unconditionally put the specified Log event and 1 argument
*
* @see #put8
*/
@Macro Void put1(Log.Event evt, Types.ModuleId mid, IArg a1);
/*!
* ======== put2 ========
* Unconditionally put the specified Log event and 2 arguments
*
* @see #put8
*/
@Macro Void put2(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2);
/*!
* ======== put4 ========
* Unconditionally put the specified Log event and 4 arguments
*
* @see #put8
*/
@Macro Void put4(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2,
IArg a3, IArg a4);
/*!
* ======== put8 ========
* Unconditionally put the specified Log event and 8 arguments
*
* This method unconditionally puts the specified `{@link Event}`
* `evt` into the log. The `{@link Types#ModuleId}` `mid` should be the
* module ID of the module which is putting the event.
*
* @param(evt) the Log event to put into the log
* @param(mid) module ID of the module putting the event
* @param(a1) value for first format conversion character
* @param(a2) value for second format conversion character
* @param(a3) value for third format conversion character
* @param(a4) value for fourth format conversion character
* @param(a5) value for fifth format conversion character
* @param(a6) value for sixth format conversion character
* @param(a7) value for seventh format conversion character
* @param(a8) value for eighth format conversion character
*/
@Macro Void put8(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2,
IArg a3, IArg a4, IArg a5, IArg a6, IArg a7, IArg a8);
/*!
* ======== write0 ========
* Generate a `Log` event with 0 arguments
*
* @see #write8
*/
@Macro Void write0(Event evt);
/*!
* ======== write1 ========
* Generate a `Log` event with 1 argument
*
* @see #write8
*/
@Macro Void write1(Event evt, IArg a1);
/*!
* ======== write2 ========
* Generate a `Log` event with 2 arguments
*
* @see #write8
*/
@Macro Void write2(Event evt, IArg a1, IArg a2);
/*!
* ======== write3 ========
* Generate a `Log` event with 3 arguments
*
* @see #write8
*/
@Macro Void write3(Event evt, IArg a1, IArg a2, IArg a3);
/*!
* ======== write4 ========
* Generate a `Log` event with 4 arguments
*
* @see #write8
*/
@Macro Void write4(Event evt, IArg a1, IArg a2, IArg a3, IArg a4);
/*!
* ======== write5 ========
* Generate a `Log` event with 5 arguments
*
* @see #write8
*/
@Macro Void write5(Event evt, IArg a1, IArg a2, IArg a3, IArg a4, IArg a5);
/*!
* ======== write6 ========
* Generate a `Log` event with 6 arguments
*
* @see #write8
*/
@Macro Void write6(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
IArg a5, IArg a6);
/*!
* ======== write7 ========
* Generate a `Log` event with 7 arguments
*
* @see #write8
*/
@Macro Void write7(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
IArg a5, IArg a6, IArg a7);
/*!
* ======== write8 ========
* Generate a `Log` event with 8 arguments
*
* If the mask in the specified `Log` event has any bit set which is
* also set in the current module's diagnostics mask, then this call to
* write will "raise" the given `Log` event.
*
* @param(evt) the `Log` event to write
* @param(a1) value for first format conversion character
* @param(a2) value for second format conversion character
* @param(a3) value for third format conversion character
* @param(a4) value for fourth format conversion character
* @param(a5) value for fifth format conversion character
* @param(a6) value for sixth format conversion character
* @param(a7) value for seventh format conversion character
* @param(a8) value for eighth format conversion character
*/
@Macro Void write8(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
IArg a5, IArg a6, IArg a7, IArg a8);
/*!
* ======== doPrint ========
* Render an event as text via `{@link System#printf System_printf}`
*
* This method is not gated and may make more than one call to
* `System_printf`. This utility method is typically used within the
* implementation of a logger which initializes
* `{@link #EventRec Log_EventRec}` structures based on `Log` events
* produced by the application.
*
* @param(evRec) a non`NULL` pointer to an initialized `Log_EventRec`
* structure to be formated via
* `{@link System#printf System_printf}`.
*/
Void doPrint(EventRec *evRec);
/*!
* @_nodoc
* ======== lookupEventMessage ========
* Returns the format string for the event with the given id.
*/
function lookupEventMessage(eventId);
/*!
* @_nodoc
* ======== getTargetArgSize ========
* Returns the target size of a record argument in bytes (not MAUs).
*/
function getTargetArgSize();
/*!
* @_nodoc
* ======== lookupEventName ========
*/
function lookupEventName(eventId);
/*!
* @_nodoc
* ======== lookupModuleName ========
*/
function lookupModuleName(modId);
/*!
* @_nodoc
* ======== getTargetEventRecSize ========
* Returns the record size in bytes (not MAUs).
*/
function getTargetEventRecSize();
internal:
/*
* ======== idToInfo ========
* Map event ID strings into a string of the form <eventName>::<eventMsg>
*/
metaonly config String idToInfo[string] = [];
}