1    /*!
     2     *  ======== Registry ========
     3     *  Register modules that are not statically configured
     4     *
     5     *  This module provides a mechanism by which legacy C code can have its own
     6     *  module logging support, including having a name and its own diags mask.
     7     *
     8     *  Without the Registry, all logging done by legacy C code is handled by the 
     9     *  xdc.runtime.Main module. This means that all log events will be marked as
    10     *  coming from "xdc.runtime.Main", and there is only a single diags mask for
    11     *  controlling logging across all legacy C code. The Registry module addresses
    12     *  this and allows legacy C code to have the same granular control over 
    13     *  logging as statically defined RTSC modules.
    14     *
    15     *  To use the Registry, legacy code must define the symbol `Registry_CURDESC`
    16     *  to be the name of an externally declared `Registery_Desc` structure.
    17     *  This symbol must be defined before the inclusion of any xdc/runtime header
    18     *  files. If any xdc/runtime header files are included before the definition
    19     *  of this symbol, the Registry may not function properly. 
    20     *  
    21     *  Note: by defining this symbol on the compile line, rather than in the
    22     *  file, one can easily compile code to be used in one of two environments:
    23     *    1. a fixed configuration environment where moudles are registered
    24     *       via Registry_addModule(), or
    25     *
    26     *    2. a "normal" configurable environment in which this code is
    27     *       assumed to be part of the xdc.runtime.Main module.
    28     *
    29     *  The `Registry_Desc` structure must then register by calling the
    30     *  '{@link #addModule}' API. The structure is typically registered and 
    31     *  initialized within `main()`.
    32     *
    33     *  For example:
    34     *
    35     *  @p(code)
    36     *  //Define the required symbol, Registry_CURDESC, to this file's 
    37     *  //Registry_Desc object
    38     *  #define Registry_CURDESC    main_desc
    39     *  #include <xdc/runtime/Registry.h>
    40     *
    41     *  //Declare the Registry_Desc object, the name is unimportant
    42     *  Registry_Desc main_desc;
    43     *
    44     *  Int main(Int argc, String argv[]) {  
    45     *    
    46     *  //Register this file as a module "main"
    47     *  Registry_addModule(&main_desc, "main");
    48     *  @p     
    49     *
    50     *  Once registered, the legacy code may call log APIs without any other change
    51     *  and the formatted log events will show as coming from the registered 
    52     *  modules. Also, the logging by the legacy code is now filtered by its own 
    53     *  diags mask. The bits of this mask can be set using the Diags_setMask API.
    54     *
    55     *  Continuing the previous example:
    56     *  @p(code)
    57     *  //Initialize the legacy code's diags mask to enable USER1.
    58     *  Diags_setMask("main=1");
    59     *  @p
    60     *
    61     *  All events logged registered modules will be sent to the logger configured
    62     *  for the Registry module. For example, to configure the logger for use by
    63     *  all modules in the Registry:
    64     *  @p(code)
    65     *  Registry.common$.logger = LoggerBuf.create();
    66     *  @p
    67     *  
    68     *  There is no way to statically configure the diags masks for individual
    69     *  registered modules, since the registered modules are not known until
    70     *  runtime. However, it is possible to configure diags categories to be
    71     *  permanently off or on for ALL registered modules. This is done by 
    72     *  configuring the diags mask for the xdc.runtime.Registry module. Diags 
    73     *  categories set to ALWAYS_OFF will be permanently off for all Registry 
    74     *  modules. Categories set to ALWAYS_ON will be permanently on for all 
    75     *  Registry modules. 
    76     *
    77     *  In order to enable runtime configuration of individual Registry module
    78     *  masks, all relevant diags categories must be set to RUNTIME_OFF or 
    79     *  RUNTIME_ON in the Registry module's mask. 
    80     */
    81    @CustomHeader
    82    module Registry
    83    {
    84        /*!
    85         *  ======== Result ========
    86         *  Status code returned from {@link addModule}.
    87         *
    88         *  SUCCESS - The module was added successfully.
    89         *  ALLOC_FAILED - Unused.
    90         *  ALREADY_ADDED - The module has already been added or another module
    91         *                  with the same name is present. The Registry will not
    92         *                  be modified.
    93         *  ALL_IDS_USED - There are no more module ids available for new modules.
    94         *                 There are a total of 16,384 - 1 module ids available for
    95         *                 use by the Registry.
    96         */
    97        enum Result {
    98            SUCCESS,
    99            ALLOC_FAILED,
   100            ALREADY_ADDED,
   101            ALL_IDS_USED
   102        };
   103        
   104        /*! Registry module descriptor */
   105        typedef Types.RegDesc Desc;    
   106        
   107        /*!
   108         *  ======== addModule ========
   109         *  Add a runtime module to the registry with the specified name.
   110         *
   111         *  The 'desc' parameter and the 'modName' string provided must both be 
   112         *  permanent since the Registry will maintain references to both of these.
   113         *
   114         *  Returns a status code indicating success or the cause of failure. See
   115         *  {@link Result} for details.
   116         */
   117        Result addModule(Desc *desc, String modName);
   118        
   119        /*!
   120         *  ======== findByName ========
   121         *  Find the registered module with the given name.
   122         */
   123        Desc *findByName(String name);
   124        
   125        /*!
   126         *  ======== findByNamePattern ========
   127         *  @_nodoc
   128         *  Find all registered modules matching the specified pattern.
   129         *
   130         *  This API is intended for use by Diags_setMask.
   131         *
   132         *  The name pattern can be an exact module name or it can contain '%'
   133         *  as a wildcard. The 'len' parameter is the string length of the pattern.
   134         *
   135         *  This function returns one module at a time, but can be called
   136         *  repeatedly to find all modules matching the pattern. On the first
   137         *  call, pass NULL as the 'prev' parameter. In all following calls,
   138         *  pass the last returned descriptor. This function returns NULL when
   139         *  it can't find any more modules matching the name pattern.
   140         */
   141        Desc *findByNamePattern(String namePat, Int len, Desc *prev);
   142    
   143        /*!
   144         *  ======== findById ========
   145         *  Find registered module's descriptor from it's module ID.
   146         */
   147        Desc *findById(Types.ModuleId mid);
   148    
   149        /*!
   150         *  ======== getMask ========
   151         *  Get the named registered module's diagnostic mask.
   152         */
   153        Bool getMask(String name, Types.DiagsMask *mask);
   154    
   155        /*!
   156         *  ======== isMember ========
   157         *  Determines if the specified module ID belongs to a registered module.
   158         *
   159         *  This function returns TRUE if and only if the specified module id
   160         *  is a valid Registry module id. It does not search the Registry for the
   161         *  module id, but simply checks if the id is within the range of valid
   162         *  Registry module ids.
   163         */
   164        Bool isMember(Types.ModuleId mid);
   165        
   166        /*!
   167         *  ======== getNextModule ========
   168         *  API for walking the list of modules in the Registry.
   169         *
   170         *  This API retrieves the next module in the Registry's module list. To
   171         *  get the head of the list, pass NULL. This API returns NULL when there
   172         *  are no more module's in the list.
   173         */
   174        Desc *getNextModule(Desc *desc);
   175        
   176        /*!
   177         *  ======== getModuleName ========
   178         *  Get the module name associated with this module descriptor.
   179         */
   180        Char *getModuleName(Desc *desc);
   181        
   182        /*!
   183         *  ======== getModuleId ========
   184         *  Get the module id associated with this module descriptor.
   185         */
   186        Types.ModuleId getModuleId(Desc *desc);
   187        
   188    internal:
   189        
   190        Desc *findByNameInList(String name, Desc *listHead);
   191        Void newModule(Desc *desc, String modName);
   192        Bool matchPattern(String pattern, Int len, String modName);
   193        
   194        /*
   195         *  ======== Module_State ========
   196         */
   197        struct Module_State {
   198            Desc *listHead;
   199            Types.ModuleId curId;
   200        }
   201    }
   202    /*
   203     *  @(#) xdc.runtime; 2, 1, 0,289; 8-20-2010 17:21:08; /db/ztree/library/trees/xdc/xdc-v48x/src/packages/
   204     */
   205