1    /* --COPYRIGHT--,ESD
     2     *  Copyright (c) 2008 Texas Instruments. All rights reserved. 
     3     *  This program and the accompanying materials are made available under the 
     4     *  terms of the Eclipse Public License v1.0 and Eclipse Distribution License
     5     *  v. 1.0 which accompanies this distribution. The Eclipse Public License is
     6     *  available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
     7     *  Distribution License is available at 
     8     *  http://www.eclipse.org/org/documents/edl-v10.php.
     9     *
    10     *  Contributors:
    11     *      Texas Instruments - initial implementation
    12     * --/COPYRIGHT--*/
    13    /*
    14     *  ======== Log.xdc ========
    15     *
    16     *! Revision History
    17     *! ================
    18     *! 06-May-2009 cmcc    Fixed ROV bug SDOCM00057314
    19     *! 06-Feb-2008 nitya   Fixed SDSCM00020676
    20     *! 17-Dec-2007 sasha   implemented code review changes
    21     */
    22    
    23    /*!
    24     *  ======== Log ========
    25     *  Event logging manager
    26     *
    27     *  RTSC modules and the application code generate `{@link #Event Log_Event}`
    28     *  events by calling the `Log` module's functions. The `Log` module then
    29     *  passes those events to an `{@link ILogger}` instance assigned to the event
    30     *  originating module, specified by that module's configuration parameter
    31     *  `common$.logger`. `ILogger` instances handle events, usually converting
    32     *  events to `{@link #EventRec Log_EventRec}` records prior to recording,
    33     *  transmitting, or displaying them.
    34     *
    35     *  All events generated by a target module are stored and displayed by an
    36     *  `ILogger`, for example, an instance of
    37     *  `{@link LoggerBuf xdc.runtime.LoggerBuf}` or
    38     *  `{@link LoggerSys xdc.runtime.LoggerSys}`. However at runtime, modules
    39     *  generate events through this module, rather than invoking directly their
    40     *  `ILogger`s. By doing so,  modules can be configured to use different
    41     *  `ILogger` implementations without any changes to their source code.
    42     *  
    43     *  A logger instance can accept `Log` events from any module, but a module
    44     *  can put `Log` events to only one logger instance. There can be one or
    45     *  more logger instances in a system. All `Log` calls that are not in a
    46     *  module are controlled by the module `{@link Main xdc.runtime.Main}`.
    47     *  For example, top-level application code or any existing sources that
    48     *  simply call the `Log` or `Assert` methods implicitly use the logger
    49     *  associated with the `Main` module.
    50     *
    51     *  The generation of a `Log` event is controlled by a module's diagnostics
    52     *  mask, which is described in details in `{@link Diags}`. Each `Log` event
    53     *  is associated with a mask. `Log` events are generated only when a
    54     *  particular bit is set in both the `Log` event mask
    55     *  and the module's diagnostics mask. For example, a `Log` event mask with
    56     *  the `{@link Diags#USER1 USER1}` bit set is generated only when the `USER1`
    57     *  bit is also set in the module's diagnostics mask.
    58     *
    59     *  There are two ways to generate `Log` events:
    60     *
    61     *  @p(blist)
    62     *  - `{@link #write8 LOG_write()}`, which is tailored for module writers
    63     *  and takes full advantage of the XDC configuration model. For example,
    64     *  the message string associated with the `Log` event need not be a part of
    65     *  the final application, significantly reducing the "footprint overhead"
    66     *  of embedding diagnostics in deployed systems. The `Log_write[0-8]()`
    67     *  functions allow up to 8 values to be passed to the logger. They expect
    68     *  the logger to handle any formatting. A `Log` event type allows you to
    69     *  specify the type of event.
    70     *  - `{@link #print6 LOG_print()}`, which is designed for arbitrary C code.
    71     *  The `Log_print[0-6]()` functions allow up to 6 values to be passed along
    72     *  with a printf-like format string to the logger. They handle printf-style
    73     *  formatting.
    74     *  @p
    75     *
    76     *  Both functions are controlled by the module's diagnostics mask. Their
    77     *  storage or output is defined by the logger that is assigned to the
    78     *  module that calls the `Log` methods or to the 
    79     *  `{@link Main xdc.runtime.Main}` module if the caller is not part of a
    80     *  module.
    81     *
    82     *  The `Log` function call sites are implemented in such a way that an
    83     *  optimizer can completely eliminate `Log` code from the program if the
    84     *  `Log` functions have been permanently disabled at configuration time. If
    85     *  the `Log` functions are permanently turned on at configuration time,
    86     *  then the optimizer can eliminate all runtime conditional checking and
    87     *  simply invoke the `Log` functions directly. Runtime checking is performed
    88     *  only when the `Log` functions are configured to be runtime modifiable.
    89     *
    90     *  @a(Examples)
    91     *  Example 1: The following example defines a `Log` event, uses that `Log`
    92     *  event in a module, and configures the program to generate the `Log`
    93     *  event. In this example, both `USER1` and `USER2` bits are set in the
    94     *  event mask. This means that if either bit is set in the module's
    95     *  diagnostics mask, then the `Log` event will be generated.
    96     *
    97     *  This is a part of the XDC specification file for the `Mod` module
    98     *  (Mod.xdc):
    99     *
   100     *  @p(code)
   101     *  import xdc.runtime.Diags;
   102     *  import xdc.runtime.Log;
   103     *
   104     *  config Log.Event L_someEvent = {
   105     *      mask: Diags.USER1 | Diags.USER2,
   106     *      msg: "my log event message, arg1: 0x%x, arg2: 0x%x"
   107     *  };
   108     *  @p
   109     *
   110     *  This is a part of the C code implementation of the Mod module:
   111     *
   112     *  @p(code)
   113     *  #include <xdc/runtime/Log.h>
   114     *  UInt x, y;
   115     *
   116     *  Log_write2(Mod_L_someEvent, (IArg)x, (IArg)y);
   117     *  @p
   118     *
   119     *  The following configuration script demonstrates how the application might
   120     *  control the `Log` statements embedded in the `Mod` module at configuration
   121     *  time. In this case, the configuration script arranges for the `Log`
   122     *  statements within the `Mod` module (shown above) to always generate events.
   123     *  Without these configuration statements, no `Log` events would be generated
   124     *  by this module.
   125     *
   126     *  This is part of the XDC configuration file for the application:
   127     *
   128     *  @p(code)
   129     *  var Diags = xdc.useModule('xdc.runtime.Diags');
   130     *  var Mod = xdc.useModule('my.pkg.Mod');
   131     *  Mod.common$.diags_USER1 = Diags.ALWAYS_ON;
   132     *  @p
   133     *
   134     *  @p(html)
   135     *  <hr />
   136     *  @p
   137     *
   138     *  Example 2: The following XDC configuration statements turn on enter
   139     *  and exit logging at configuration time for a module. Without any other
   140     *  changes in the runtime code, every time a module `Mod`'s function is 
   141     *  being called or exits, an event will be logged.
   142     *
   143     *  @p(code)
   144     *  var Diags = xdc.useModule('xdc.runtime.Diags');
   145     *  var Mod = xdc.useModule('my.pkg.Mod');
   146     *
   147     *  Mod.common$.diags_ENTER = Diags.ALWAYS_ON;
   148     *  Mod.common$.diags_EXIT = Diags.ALWAYS_ON;
   149     *  @p
   150     *
   151     *  @p(html)
   152     *  <hr />
   153     *  @p
   154     *
   155     *  Example 3: The following example configures a module to support enter and
   156     *  exit logging, but defers the actual activation and deactivation of the
   157     *  logging until runtime. See the `{@link Diags#setMask Diags_setMask()}`
   158     *  function for details on specifying the control string.
   159     *
   160     *  This is a part of the XDC configuration file for the application:
   161     *
   162     *  @p(code)
   163     *  var Diags = xdc.useModule('xdc.runtime.Diags');
   164     *  var Mod = xdc.useModule('my.pkg.Mod');
   165     *
   166     *  Mod.common$.diags_ENTER = Diags.RUNTIME_OFF;
   167     *  Mod.common$.diags_EXIT = Diags.RUNTIME_OFF;
   168     *  @p
   169     *
   170     *  This is a part of the C code for the application:
   171     *
   172     *  @p(code)
   173     *  // turn on enter and exit logging in the module
   174     *  Diags_setMask("my.pkg.Mod+EX");
   175     *
   176     *  // turn off enter and exit logging in the module
   177     *  Diags_setMask("my.pkg.Mod-EX");
   178     *  @p
   179     */
   180    
   181    @CustomHeader
   182    
   183    module Log {
   184    
   185        /*!
   186         *  ======== NUMARGS ========
   187         *  Maximum number of arguments supported in `Log` events.
   188         */
   189        const Int NUMARGS = 8;
   190    
   191        /*!
   192         *  ======== PRINTFID ========
   193         *  The `EventId` for `Log_print()` events
   194         */
   195        const EventId PRINTFID = 0;
   196        
   197        /*! 
   198         *  ======== EventDesc ========
   199         *  `Log` event descriptor
   200         *
   201         *  Each `Log` event is defined by a `Log` event descriptor.
   202         *
   203         *  The `mask` defines which bits in the module's diagnostics mask
   204         *  enable this `Log` event.  Events "posted" via `Log_write` are only
   205         *  written to the underlying logger if one of the mask's bits matches 
   206         *  the caller's module diagnostics settings (see
   207         *  `{@link xdc.runtime.Types#common$}`).
   208         *
   209         *  The `msg` defines a printf style format string that defines how to
   210         *  render the arguments passed along the event in a `Log_write` call.
   211         *  For a description of the allowable format strings see
   212         *  `{@link #print6}`.
   213         *
   214         *  @see #write8
   215         *  @see #print6
   216         */
   217        metaonly struct EventDesc {
   218            Diags.Mask  mask;   /*! event enable mask */
   219            String      msg;    /*! event "printf" message format string */
   220        };
   221    
   222        /*!
   223         *  ======== EventInfo ========
   224         *  @_nodoc
   225         */
   226        metaonly struct EventInfo {
   227            String text;
   228            String modName;
   229            String eventName;
   230            Int eventId;
   231            IArg arg[NUMARGS];
   232        };
   233    
   234        /*!
   235         *  ======== EventRec ========
   236         *  The target representation of a recorded event
   237         *
   238         *  This structure defines how events are recorded on the target.
   239         */
   240        struct EventRec {
   241            Types.Timestamp64 tstamp;   /*! time event was written */
   242            Bits32 serial;              /*! serial number of event */
   243            Types.Event evt;            /*! target encoding of an Event */
   244            IArg arg[NUMARGS];          /*! arguments passed via Log_write/print */
   245        }
   246    
   247        /*! 
   248         *  ======== Event ========
   249         *  `Log` event type
   250         *
   251         *  An `Event` is represented on the target as a 32-bit value that can
   252         *  be decoded offline to recover the `Event` information defined in
   253         *  a corresponding metaonly `EventDesc`.  In addition, `Event`s may be
   254         *  decoded at runtime via methods provided in this module; see
   255         *  `{@link #getMask}` and `{@link #getEventId}`.
   256         *
   257         *  When an event is "raised" a `{@link Types#Event Types_Event}` is
   258         *  created which has the same event ID as the `Log_Event` but also
   259         *  encodes the module ID of the caller.  This new event is passed to
   260         *  the underlying `{@link ILogger}` module along with any arguments
   261         *  associated with the event.
   262         *
   263         *  @see #getMask
   264         *  @see #getEventId
   265         */
   266        @Encoded typedef EventDesc Event;
   267    
   268        /*!
   269         *  ======== EventId ========
   270         *  Unique ID embedded in each `{@link #Event}`
   271         *
   272         *  This ID must be used to compare two `Event`s for equality.  Event
   273         *  ids are not guaranteed to remain constant between different
   274         *  configurations of an application.  For example, adding a module
   275         *  may cause the event ids of another module to change.
   276         *
   277         *  However, event ids declared by a module are guaranteed to be
   278         *  consecutive values starting from the first declared
   279         *  `{@link #Event Log_Event}` and increasing to the last declared
   280         *  event.  As a result, clients of a module can efficiently test ranges
   281         *  of events and modules can add new events, such as internal trace
   282         *  events, without breaking clients; simply be careful to add new events
   283         *  after any existing events in you module's `.xdc` specification.
   284         *
   285         *  @see #getEventId
   286         *  @see #Event
   287         */
   288        typedef Types.RopeId EventId;
   289        
   290        /*! 
   291         *  ======== L_construct ========
   292         *  Lifecycle event posted when an instance is constructed
   293         */
   294        config Log.Event L_construct = {
   295            mask: Diags.LIFECYCLE, msg: "<-- construct: %p('%s')"
   296        };
   297    
   298        /*!
   299         *  ======== L_create ========
   300         *  Lifecycle event posted when an instance is created
   301         */
   302        config Log.Event L_create = {
   303            mask: Diags.LIFECYCLE, msg: "<-- create: %p('%s')"
   304        };
   305    
   306        /*!
   307         *  ======== L_destruct ========
   308         *  Lifecycle event posted when an instance is destructed
   309         */
   310        config Log.Event L_destruct = {
   311            mask: Diags.LIFECYCLE, msg: "--> destruct: (%p)"
   312        };
   313    
   314        /*!
   315         *  ======== L_delete ========
   316         *  Lifecycle event posted when an instance is deleted
   317         */
   318        config Log.Event L_delete = {
   319            mask: Diags.LIFECYCLE, msg: "--> delete: (%p)"
   320        };
   321    
   322        /*!
   323         *  ======== getMask ========
   324         *  Get the `Diags` mask for the specified (encoded) event
   325         *
   326         *  @param(evt)     the `Log` event encoding a mask and event ID
   327         *
   328         *  @a(returns)     `Diags` mask for the specified event
   329         */
   330        @Macro Diags.Mask getMask(Event evt);
   331    
   332        /*!
   333         *  ======== getRope ========
   334         *  Get RopeId of the Event.msg for the specified (encoded) event
   335         *  @_nodoc
   336         */
   337        @Macro Text.RopeId getRope(Event evt);
   338    
   339        /*!
   340         *  ======== getEventId ========
   341         *  Get event ID of the specified (encoded) event
   342         *
   343         *  This method is used to compare "known" `Log` events with
   344         *  "raised" `{@link Types#Event Types_Event}`.
   345         *
   346         *  @param(evt)     the `Log` event encoding a mask and event ID
   347         *
   348         *  @a(returns)     event ID of the specified event
   349         *
   350         *  @see Types#getEventId
   351         */
   352        @Macro EventId getEventId(Event evt);
   353    
   354        /*!
   355         *  ======== print0 ========
   356         *  Generate a `Log` "print event" with 0 arguments
   357         *
   358         *  @see #print6
   359         */
   360        @Macro Void print0(Diags.Mask mask, String fmt);
   361    
   362        /*!
   363         *  ======== print1 ========
   364         *  Generate a `Log` "print event" with 1 argument
   365         *
   366         *  @see #print6
   367         */
   368        @Macro Void print1(Diags.Mask mask, String fmt, IArg a1);
   369    
   370        /*!
   371         *  ======== print2 ========
   372         *  Generate a `Log` "print event" with 2 arguments
   373         *
   374         *  @see #print6
   375         */
   376        @Macro Void print2(Diags.Mask mask, String fmt, IArg a1, IArg a2);
   377    
   378        /*!
   379         *  ======== print3 ========
   380         *  Generate a `Log` "print event" with 3 arguments
   381         *
   382         *  @see #print6
   383         */
   384        @Macro Void print3(Diags.Mask mask, String fmt, IArg a1, IArg a2, IArg a3);
   385    
   386        /*!
   387         *  ======== print4 ========
   388         *  Generate a `Log` "print event" with 4 arguments
   389         *
   390         *  @see #print6
   391         */
   392        @Macro Void print4(Diags.Mask mask, String fmt, IArg a1, IArg a2, IArg a3,
   393            IArg a4);
   394    
   395        /*!
   396         *  ======== print5 ========
   397         *  Generate a `Log` "print event" with 5 arguments
   398         *
   399         *  @see #print6
   400         */
   401        @Macro Void print5(Diags.Mask mask, String fmt, IArg a1, IArg a2, IArg a3,
   402            IArg a4, IArg a5);
   403    
   404        /*!
   405         *  ======== print6 ========
   406         *  Generate a `Log` "print event" with 6 arguments
   407         *
   408         *  As a convenience to C (as well as assembly language) programmers,
   409         *  the `Log` module provides a variation of the ever-popular `printf`
   410         *  function.
   411         *  The `print[0-6]` functions generate a `Log` "print event" and route
   412         *  it to the current module's logger.
   413         *
   414         *  The arguments passed to `print[0-6]` may be characters, integers,
   415         *  strings, or pointers.  However, because the declared type of the
   416         *  arguments is `{@link xdc IArg}`, all pointer arguments must be cast
   417         *  to an `IArg` type.  `IArg` is an integral type large enough to hold
   418         *  any pointer or an `int`.  So, casting a pointer to an `IArg` does
   419         *  not cause any loss of information and C's normal integer conversions
   420         *  make the cast unnecessary for integral arguments.
   421         *
   422         *  The format string can use the following conversion characters.
   423         *  However, it is important to recall that all arguments referenced by
   424         *  these conversion characters have been converted to an `IArg`
   425         *  prior to conversion; so, the use of "length modifiers" should be
   426         *  avoided.
   427         *
   428         *  @p(code)
   429         *  Conversion Character    Description
   430         *  ------------------------------------------------
   431         *  %c                      Character
   432         *  %d                      Signed integer
   433         *  %u                      Unsigned integer
   434         *  %x                      Unsigned hexadecimal integer
   435         *  %o                      Unsigned octal integer
   436         *  %s                      Character string
   437         *  %p                      Pointer
   438         *  %f                      Single precision floating point (float)
   439         *  @p
   440         *
   441         *  Format strings, while very convenient, are a well known source of
   442         *  portability problems: each format specification must precisely match
   443         *  the types of the arguments passed. Underlying "printf" functions use
   444         *  the format string to determine how far to advance through their
   445         *  argument list. For targets where pointer types and integers are the
   446         *  same size there are no problems.  However, suppose a target's pointer
   447         *  type is larger than its integer type. In this case, because integer
   448         *  arguments are widened to be of type `IArg`, a format specification of
   449         *  "%d" causes an underlying `printf()` implementation to read the
   450         *  extended part of the integer argument as part of the next argument(!).
   451         *
   452         *  To get around this problem and still allow the use of "natural" 
   453         *  format specifications (e.g., `%d` and `%x` with optional width
   454         *  specifications), `{@link System#aprintf()}` is used which assumes
   455         *  that all arguments have been widened to be of type `IArg`.
   456         *
   457         *  See `{@link System#printf}` for complete details.
   458         *
   459         *  The `%f` format specifier is used to print a single precision float
   460         *  value. Note that `%f` assumes that sizeof(Float) <= sizeof(IArg).
   461         *  Most clients that interpret float values except that they are
   462         *  represented in IEEE 754 floating point format. Therefore, it is
   463         *  recommended that the float values are converted into that format prior
   464         *  to supplying the values to `Log` functions in cases where targets do
   465         *  not generate the float values in IEEE 754 floating point format by
   466         *  default.
   467         *
   468         *  @param(mask)    enable bits for this `Log` event
   469         *  @param(fmt)     a `printf` style format string
   470         *  @param(a1)      value for first format conversion character
   471         *  @param(a2)      value for second format conversion character
   472         *  @param(a3)      value for third format conversion character
   473         *  @param(a4)      value for fourth format conversion character
   474         *  @param(a5)      value for fifth format conversion character
   475         *  @param(a6)      value for sixth format conversion character
   476         *
   477         *  @a(Examples)
   478         *  The following example demonstrates a typical usage.
   479         *  @p(code)
   480         *  String  list[];
   481         *  UInt    i;
   482         *
   483         *  Log_print2(Diags_USER2, "list[%u] = %s\n", i, (IArg)list[i]);
   484         *  @p
   485         *  Note that the `IArg` cast above is only necessary for pointer
   486         *  arguments; C's normal parameter conversions implicitly convert
   487         *  integral arguments.
   488         */
   489        @Macro Void print6(Diags.Mask mask, String fmt, IArg a1, IArg a2, IArg a3,
   490            IArg a4, IArg a5, IArg a6);
   491    
   492        /*!
   493         *  ======== put4 ========
   494         *  Unconditionally put the specified `Types` event
   495         *
   496         *  This method unconditionally puts the specified `{@link Types#Event}`
   497         *  `evt` into the log.  This type of event is created either implicitly
   498         *  (and passed to an `{@link ILogger}` implementation) or explicitly
   499         *  via `{@link Types#makeEvent()}`.
   500         *
   501         *  @param(evt)     the `Types` event to put into the log
   502         *  @param(a1)      value for first format conversion character
   503         *  @param(a2)      value for second format conversion character
   504         *  @param(a3)      value for third format conversion character
   505         *  @param(a4)      value for fourth format conversion character
   506         *
   507         *  @see #put8
   508         */
   509        @Macro Void put4(Types.Event evt, IArg a1, IArg a2, IArg a3, IArg a4);
   510    
   511        /*!
   512         *  ======== put8 ========
   513         *  Unconditionally put the specified `Types` event
   514         *
   515         *  This method is identical to `{@link #put4}` except that it allows
   516         *  up to eight arguments to be passed.
   517         *  
   518         *  @see #put4
   519         */
   520        @Macro Void put8(Types.Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
   521                            IArg a5, IArg a6, IArg a7, IArg a8);
   522    
   523        /*! 
   524         *  ======== write0 ========
   525         *  Generate a `Log` event with 0 arguments
   526         *
   527         *  @see #write8
   528         */
   529        @Macro Void write0(Event evt);
   530    
   531        /*! 
   532         *  ======== write1 ========
   533         *  Generate a `Log` event with 1 argument
   534         *
   535         *  @see #write8
   536         */
   537        @Macro Void write1(Event evt, IArg a1);
   538    
   539        /*!
   540         *  ======== write2 ========
   541         *  Generate a `Log` event with 2 arguments
   542         *
   543         *  @see #write8
   544         */
   545        @Macro Void write2(Event evt, IArg a1, IArg a2);
   546    
   547        /*!
   548         *  ======== write3 ========
   549         *  Generate a `Log` event with 3 arguments
   550         *
   551         *  @see #write8
   552         */
   553        @Macro Void write3(Event evt, IArg a1, IArg a2, IArg a3);
   554    
   555        /*!
   556         *  ======== write4 ========
   557         *  Generate a `Log` event with 4 arguments
   558         *
   559         *  @see #write8
   560         */
   561        @Macro Void write4(Event evt, IArg a1, IArg a2, IArg a3, IArg a4);
   562    
   563        /*!
   564         *  ======== write5 ========
   565         *  Generate a `Log` event with 5 arguments
   566         *
   567         *  @see #write8
   568         */
   569        @Macro Void write5(Event evt, IArg a1, IArg a2, IArg a3, IArg a4, IArg a5);
   570    
   571        /*!
   572         *  ======== write6 ========
   573         *  Generate a `Log` event with 6 arguments
   574         *
   575         *  @see #write8
   576         */
   577        @Macro Void write6(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
   578                            IArg a5, IArg a6);
   579    
   580        /*!
   581         *  ======== write7 ========
   582         *  Generate a `Log` event with 7 arguments
   583         *
   584         *  @see #write8
   585         */
   586        @Macro Void write7(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
   587                            IArg a5, IArg a6, IArg a7);
   588    
   589        /*!
   590         *  ======== write8 ========
   591         *  Generate a `Log` event with 8 arguments
   592         *
   593         *  If the mask in the specified `Log` event has any bit set which is
   594         *  also set in the current module's diagnostics mask, then this call to
   595         *  write will "raise" the given `Log` event.
   596         *
   597         *  @param(evt)     the `Log` event to write
   598         *  @param(a1)      value for first format conversion character
   599         *  @param(a2)      value for second format conversion character
   600         *  @param(a3)      value for third format conversion character
   601         *  @param(a4)      value for fourth format conversion character
   602         *  @param(a5)      value for fifth format conversion character
   603         *  @param(a6)      value for sixth format conversion character
   604         *  @param(a7)      value for seventh format conversion character
   605         *  @param(a8)      value for eighth format conversion character
   606         */
   607        @Macro Void write8(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
   608                            IArg a5, IArg a6, IArg a7, IArg a8);
   609    
   610        /*!
   611         *  ======== doPrint ========
   612         *  Render an event as text via `{@link System#printf System_printf}`
   613         *
   614         *  This method is not gated and may make more than one call to
   615         *  `System_printf`.  This utility method is typically used within the
   616         *  implementation of a logger which initializes
   617         *  `{@link #EventRec Log_EventRec}` structures based on `Log` events
   618         *  produced by the application.
   619         *
   620         *  @param(evRec)   a non`NULL` pointer to an initialized `Log_EventRec`
   621         *                  structure to be formated via
   622         *                  `{@link System#printf System_printf}`.
   623         */
   624        Void doPrint(EventRec *evRec);
   625    
   626        /*!
   627         *  @_nodoc
   628         *  ======== decode ========
   629         *  In ROV, decode the specified Event evt into info structure
   630         */
   631        function decode(info, evt, args);
   632        
   633        /*!
   634         *  @_nodoc
   635         *  ======== evtIdToName ========
   636         *  In ROV, lookup an event's name given its id.
   637         */
   638        function evtIdToName(eventId);
   639        
   640        /*!
   641         *  @_nodoc
   642         *  ======== getEventMsg ========
   643         *  In ROV, look up the record's message based on its event Id, then 
   644         *  format it with the given arguments.
   645         */
   646        function getEventMsg(eventId, args);
   647    
   648    internal:
   649    
   650        /*
   651         *  ======== idToInfo ========
   652         *  Map event ID strings into a string of the form <eventName>::<eventMsg>
   653         */
   654        metaonly config String idToInfo[string] = [];
   655        
   656    }
   657    /*
   658     *  @(#) xdc.runtime; 2, 0, 0, 0,214; 7-29-2009 14:53:44; /db/ztree/library/trees/xdc-t56x/src/packages/
   659     */
   660