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 `{@link Log}` events will
    10     *  be marked as coming from "`xdc.runtime.Main`", and there is only a single
    11     *  diagnostics mask for the runtime control of logging across all legacy C
    12     *  code. The `Registry` module allows legacy C code to have the same granular
    13     *  control over logging as statically defined RTSC modules.
    14     *
    15     *  To use the `Registry` module, legacy code must define the symbol
    16     *  `Registry_CURDESC` to be the name of an externally declared
    17     *  `Registery_Desc` structure.  This symbol must be defined before the
    18     *  inclusion of any `xdc/runtime` header files. If any `xdc/runtime` header
    19     *  files are included before the definition of this symbol, the `Registry`
    20     *  module may not function properly. 
    21     *  
    22     *  Note: by defining this symbol on the compile line, rather than in the
    23     *  file, one can easily compile code to be used in one of two environments:
    24     *  @p(nlist)
    25     *    - a fixed configuration environment where modules are registered
    26     *      via `{@link #addModule Registry_addModule()}`, or
    27     *
    28     *    - a "normal" configurable environment in which this code is
    29     *      assumed to be part of the `{@link Main}` module.
    30     *  @p
    31     *  The `Registry_Desc` structure must then be registered by calling
    32     *  `{@link #addModule Registry_addModule()}`. The structure is typically
    33     *  registered and initialized within `main()`.
    34     *
    35     *  For example:
    36     *
    37     *  @p(code)
    38     *  //Define the required symbol, Registry_CURDESC, to this file's 
    39     *  //Registry_Desc object
    40     *  #define Registry_CURDESC    mainDesc
    41     *  #include <xdc/runtime/Registry.h>
    42     *
    43     *  //Declare the Registry_Desc object, the name is unimportant
    44     *  Registry_Desc mainDesc;
    45     *
    46     *  Int main(Int argc, String argv[]) {  
    47     *    
    48     *  //Register this file as a module "main"
    49     *  Registry_addModule(&mainDesc, "main");
    50     *  @p     
    51     *
    52     *  Once registered, the legacy code may call `{@link Log}` APIs without any
    53     *  other change and the formatted `Log` events will show as coming from the
    54     *  registered modules. Also, the logging by the legacy code is now filtered
    55     *  by its own diagnostic mask. The bits of this mask can be set using 
    56     *  `{@link Diags#setMask Diags_setMask}`.
    57     *
    58     *  Continuing the previous example:
    59     *  @p(code)
    60     *  //Initialize the legacy code's diags mask to enable USER1.
    61     *  Diags_setMask("main=1");
    62     *  @p
    63     *
    64     *  All events logged registered modules will be sent to the logger configured
    65     *  for the `Registry` module. For example, to configure the logger for use by
    66     *  all modules managed by `Registry`:
    67     *  @p(code)
    68     *  Registry.common$.logger = LoggerBuf.create();
    69     *  @p
    70     *  
    71     *  Since the registered modules are not known until runtime, it is not
    72     *  possible to statically configure the diagnostics masks for individual
    73     *  registered modules. However, it is possible to configure diagnostics
    74     *  categories to be permanently off or on for ALL registered modules. This
    75     *  is done by configuring the diagnostic mask for the `Registry` module.
    76     *  Diagnostic categories set to `{@link Diags#ALWAYS_OFF Diags.ALWAYS_OFF}`
    77     *  will be permanently off for all `Registry` modules. Categories set to
    78     *  `{@link Diags#ALWAYS_ON Diags.ALWAYS_ON}` will be
    79     *  permanently on for all modules managed by `Registry`. 
    80     *
    81     *  In order to enable runtime configuration of individual `Registry` module
    82     *  masks, all relevant diagnostic categories must be set to
    83     *  `{@link Diags#RUNTIME_OFF Diags.RUNTIME_OFF}` or
    84     *  `{@link Diags#RUNTIME_ON Diags.RUNTIME_ON}` in the `Registry` module's
    85     *  mask. 
    86     */
    87    @CustomHeader
    88    module Registry
    89    {
    90        /*!
    91         *  ======== RegisteredModuleView ========
    92         *  @_nodoc
    93         *  View element for the 'Registered Modules' ROV view.
    94         */
    95        metaonly struct RegisteredModuleView {
    96            String modName;
    97            Int id;
    98            String mask;
    99            Ptr descAddr;
   100        }
   101    
   102        /*!
   103         *  ======== rovViewInfo ========
   104         *  @_nodoc
   105         */
   106        @Facet
   107        metaonly config xdc.rov.ViewInfo.Instance rovViewInfo = 
   108            xdc.rov.ViewInfo.create({
   109                viewMap: [
   110                    ['Registered Modules',
   111                        {
   112                            type: xdc.rov.ViewInfo.MODULE_DATA,
   113                            viewInitFxn: 'viewInitRegisteredModules',
   114                            structName: 'RegisteredModuleView'
   115                        }
   116                    ]
   117                ]
   118            });
   119    
   120        /*!
   121         *  ======== Result ========
   122         *  Status codes
   123         */
   124        enum Result {
   125            SUCCESS,        /*! The module was added successfully */
   126            ALLOC_FAILED,   /*! reserved */
   127            ALREADY_ADDED,  /*! The module has already been added  or another
   128                             *  module with the same name is present
   129                             */
   130            ALL_IDS_USED    /*! No more module ids available for new modules */
   131        };
   132        
   133        /*!
   134         *  ======== RegDesc ========
   135         *  Registry module descriptor
   136         */
   137        typedef Types.RegDesc Desc;
   138        
   139        /*!
   140         *  ======== addModule ========
   141         *  Add a runtime module to the registry with the specified name
   142         *
   143         *  The `desc` parameter and the `modName` string provided must both be 
   144         *  permanent since the `Registry` will maintain references to both of
   145         *  these.
   146         *
   147         *  @param(desc)    non-`NULL` pointer to a `{#Desc Registry_Desc}`
   148         *                  structure.
   149         *  @param(modName) non-`NULL` string name of the module being registered.
   150         *
   151         *  @a(returns)
   152         *  `Registry_addModule` returns one of the following
   153         *  `{@link #Result Result}` status values indicating success or the
   154         *  cause of failure:
   155         *  @p(blist)
   156         *  - `{@link #SUCCESS SUCCESS}`
   157         *  - `{@link #ALREADY_ADDED ALREADY_ADDED}`
   158         *  - `{@link #ALL_IDS_USED ALL_IDS_USED}`  There are a total of 16,384 - 1
   159         *    module ids available for use by `Registry`.
   160         *  @p
   161         */
   162        Result addModule(Desc *desc, String modName);
   163        
   164        /*!
   165         *  ======== findByName ========
   166         *  Find the registered module with the given name
   167         *
   168         *  @param(modName) non-`NULL` string name of a registered module
   169         *
   170         *  @a(returns)
   171         *  If the name `modName` is registered via
   172         *  `{@link #addModule Registry_addModule()}`, this function
   173         *  returns the pointer to the registered `Registry_Desc` structure;
   174         *  otherwise it returns `NULL`.
   175         */
   176        Desc *findByName(String modName);
   177        
   178        /*!
   179         *  ======== findByNamePattern ========
   180         *  @_nodoc
   181         *  Find all registered modules matching the specified pattern.
   182         *
   183         *  This API is intended for use by Diags_setMask.
   184         *
   185         *  The name pattern can be an exact module name or it can contain '%'
   186         *  as a wildcard. The `len` parameter is the string length of the pattern.
   187         *
   188         *  This function returns one module at a time, but can be called
   189         *  repeatedly to find all modules matching the pattern. On the first
   190         *  call, pass `NULL` as the `prev` parameter. In all following calls,
   191         *  pass the last returned descriptor. This function returns `NULL` when
   192         *  it can't find any more modules matching the name pattern.
   193         */
   194        Desc *findByNamePattern(String namePat, Int len, Desc *prev);
   195    
   196        /*!
   197         *  ======== findById ========
   198         *  Find registered module's descriptor from it's module ID
   199         *
   200         *  @param(mid) any module id
   201         *
   202         *  @a(returns)
   203         *  If the ID `mid` is registered via
   204         *  `{@link #addModule Registry_addModule()}`, this function
   205         *  returns the pointer to the registered `Registry_Desc` structure;
   206         *  otherwise it returns `NULL`.
   207         */
   208        Desc *findById(Types.ModuleId mid);
   209    
   210        /*!
   211         *  ======== getMask ========
   212         *  Get the specified module's diagnostic mask
   213         *
   214         *  @param(modName) non-`NULL` string name of a registered module
   215         *  @param(mask)    non-`NULL` pointer to a mask to be initialized
   216         *                  to the the current state of the diagnostics mask
   217         *                  associated with `modName`
   218         *
   219         *  @a(returns)
   220         *  The function returns `TRUE` if `name` identifies a registered module;
   221         *  otherwise, it return `FALSE`.
   222         */
   223        Bool getMask(String name, Types.DiagsMask *mask);
   224    
   225        /*!
   226         *  ======== isMember ========
   227         *  Determines if the specified module ID belongs to a registered module
   228         *
   229         *  @param(mid) any module id
   230         *
   231         *  @a(returns)
   232         *  This function returns `TRUE` if and only if the specified module id
   233         *  is a valid `Registry` module id. It does not search registered
   234         *  module ids, but simply checks if the id is within the range of valid
   235         *  `Registry` module ids.
   236         */
   237        Bool isMember(Types.ModuleId mid);
   238        
   239        /*!
   240         *  ======== getNextModule ========
   241         *  Scan the current list of registered modules
   242         *
   243         *  This function used to scan the list of all `Registry_Desc` structures
   244         *  currently being managed by the `Registry` module.
   245         *
   246         *  @param(desc)    optionally `NULL` pointer to a `Registry_Desc`
   247         *                  structure.  If `desc` is `NULL`, a pointer to the
   248         *                  first structure is returned.  If `desc` is non-`NULL`
   249         *                  and equal to a previous return value of this function,
   250         *                  a pointer to the "next" `Registry_Desc` structure
   251         *                  is returned.
   252         *
   253         *  @a(returns)
   254         *  This function returns a non-`NULL` pointer to one of the
   255         *  `Registry_Desc` structures added via `Registry_Desc` structures or
   256         *  `NULL` in the case that
   257         *  @p(blist)
   258         *      - there are no more module's in the list after `desc`, or
   259         *      - there are no modules registered
   260         *  @p
   261         */
   262        Desc *getNextModule(Desc *desc);
   263        
   264        /*!
   265         *  ======== getModuleName ========
   266         *  Get the module name associated with a specified module descriptor
   267         *
   268         *  @param(desc)    non-`NULL` pointer to a `{#Desc Registry_Desc}`
   269         *                  structure.
   270         *
   271         *  @a(returns)
   272         *  If the specified module descriptor has been initialized via a
   273         *  successful call to `{@link #addModule Registry_addModule()}`, this
   274         *  function returns the module name passed `Registry_addModule()`;
   275         *  otherwise, its return value is indeterminate.
   276         */
   277        String getModuleName(Desc *desc);
   278        
   279        /*!
   280         *  ======== getModuleId ========
   281         *  Get the module id associated with a specified module descriptor
   282         *
   283         *  @param(desc)    non-`NULL` pointer to a `{#Desc Registry_Desc}`
   284         *                  structure.
   285         *
   286         *  @a(returns)
   287         *  If the specified module descriptor has been initialized via a
   288         *  successful call to `{@link #addModule Registry_addModule()}`, this
   289         *  function returns the module id assigned by `Registry_addModule()`;
   290         *  otherwise, its return value is indeterminate.
   291         */
   292        Types.ModuleId getModuleId(Desc *desc);
   293        
   294    internal:
   295        
   296        Desc *findByNameInList(String name, Desc *listHead);
   297        Void newModule(Desc *desc, String modName);
   298        Bool matchPattern(String pattern, Int len, String modName);
   299        
   300        /* Functions for accessing the Registry at ROV-time. */
   301        function isMemberRov(modId);
   302        function lookupModIdRov(modId);
   303        
   304        /*
   305         *  ======== Module_State ========
   306         */
   307        struct Module_State {
   308            Desc            *listHead;
   309            Types.ModuleId  curId;
   310        }
   311    }
   312    /*
   313     *  @(#) xdc.runtime; 2, 1, 0,371; 2-10-2012 10:18:55; /db/ztree/library/trees/xdc/xdc-y21x/src/packages/
   314     */
   315