1    /* 
     2     *  Copyright (c) 2008-2019 Texas Instruments Incorporated
     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     * */
    13    /*
    14     *  ========= Text.xdc ========
    15     */
    16    
    17    package xdc.runtime;
    18    
    19    /*!
    20     *  ======== Text ========
    21     *  Runtime text handling services
    22     *
    23     *  This module efficiently manages a collection of strings that have common
    24     *  substrings.  Collections with a high degree of commonality are stored in
    25     *  much less space than as an ordinary table of independent C strings.
    26     *
    27     *  To further save space, the "compressed" representation need not even
    28     *  be loaded in the target's memory; see `{@link #isLoaded}`.
    29     *
    30     *  The total space available for the compressed representation of text strings
    31     *  is limited to 32K characters; the lowest 15 bits of a 16-bit "rope id" are
    32     *  an index of a storage array.
    33     */
    34    @Template("./Text.xdt")
    35    @DirectCall
    36    module Text {
    37    
    38        /*!
    39         *  ======== CordAddr ========
    40         *  @_nodoc
    41         */
    42        typedef Types.CordAddr CordAddr;
    43    
    44        /*!
    45         *  ======== Label ========
    46         */
    47        typedef Types.Label Label;
    48    
    49        /*!
    50         *  ======== RopeId ========
    51         *  @_nodoc
    52         *
    53         *  A rope id is a 16-bit value whose most-significant bit indicates
    54         *  whether the lower 15-bits are an offset into the string table
    55         *  `charTab` or an offset into the "node" table `nodeTab`.
    56         *
    57         *  The node id 0 represents the empty string "".
    58         */
    59        /* REQ_TAG(SYSBIOS-892) */
    60        typedef Types.RopeId RopeId;
    61    
    62        /*!
    63         *  ======== Module_View ========
    64         *  @_nodoc
    65         */
    66        @XmlDtd
    67        metaonly struct Module_View {
    68            Ptr charBase;
    69            Ptr nodeBase;
    70        };
    71    
    72        /*!
    73         *  ======== nameUnknown ========
    74         *  Default unknowable instance name
    75         *
    76         *  The name of an instance if the module's instances are configured to
    77         *  not have names.
    78         */
    79        /* REQ_TAG(SYSBIOS-889) */
    80        config String nameUnknown = "{unknown-instance-name}";
    81    
    82        /*!
    83         *  ======== nameEmpty ========
    84         *  Default `NULL` instance name
    85         *
    86         *  The name used if the instance's name has been set to `NULL`.
    87         */
    88        /* REQ_TAG(SYSBIOS-890) */
    89        config String nameEmpty = "{empty-instance-name}";
    90    
    91        /*!
    92         *  ======== nameStatic ========
    93         *  Default static instance name
    94         *
    95         *  The name of an instance if the name exists but it's not loaded
    96         *  on the target.
    97         */
    98        /* REQ_TAG(SYSBIOS-891) */
    99        config String nameStatic = "{static-instance-name}";
   100    
   101        /*!
   102         *  ======== isLoaded ========
   103         *  Ensure character-strings are loaded in target memory
   104         *
   105         *  Character strings managed by this module are allocated together
   106         *  with other character strings, and loaded to the target, when this
   107         *  parameter is set to its default value `true`. If this parameter is
   108         *  set to `false`, the character strings managed by Text are kept in the
   109         *  application object file, but they are not loaded to the target.
   110         *
   111         *  A consequence of setting this parameter to `false` is that all names
   112         *  assigned to static instances are set to NULL, and cannot be displayed by
   113         *  the code loaded to the target. Also, the Log Events that automatically
   114         *  print instance names will print NULL for any static instance.
   115         *
   116         *  ROV is not affected by this parameter and it will also correctly display
   117         *  names of static instances in their modules' views. ROV detects these
   118         *  names from the saved configuration files.
   119         *
   120         *  Module and event IDs are still unique and Log.Events within one module
   121         *  have consecutive IDs.
   122         */
   123        /* REQ_TAG(SYSBIOS-888) */
   124        config Bool isLoaded = true;
   125    
   126        /*!
   127         *  ======== cordText ========
   128         *  Return `NULL` if cord is in `charTab` and `isLoaded` is `FALSE`
   129         *  @_nodoc
   130         */
   131        String cordText(CordAddr cord);
   132    
   133        /*!
   134         *  ======== ropeText ========
   135         *  Convert rope to an ordinary C string
   136         *
   137         *  Convert rope to an ordinary C string or to NULL if rope refers
   138         *  to a node in nodeTab
   139         *
   140         *  @_nodoc
   141         */
   142        CString ropeText(RopeId rope);
   143    
   144        /*!
   145         *  ======== matchRope ========
   146         *  Compare pattern string `pat` to String identified by `rope`.
   147         *  @_nodoc
   148         *
   149         *  This function is invoked from `{@link Diags#setMask()}`, see the
   150         *  documentation for that function to find out how the patterns are
   151         *  created.
   152         *
   153         *  @a(pre-conditions)
   154         *  @p(blist)
   155         *      - lenp must be less than or equal to the length of pat
   156         *      - wildcard '%' is at src[(*lenp) - 1], if it's in the the pattern
   157         *  @p
   158    
   159         *  @a(post-conditions)
   160         *  @p(blist)
   161         *      - lenp is decreased by the length of any matching prefix
   162         *  @p
   163         *
   164         *  Returns:
   165         *  @p(blist)
   166         *      - -1  `pat` does not match string
   167         *      - 0   string is a prefix of pattern
   168         *      - 1   wildcard match
   169         *  @p
   170         */
   171        /* REQ_TAG(SYSBIOS-893) */
   172        Int matchRope(RopeId rope, CString pat, UShort *lenp);
   173    
   174        /*!
   175         *  ======== putLab ========
   176         *  Convert label to an ASCII character sequence
   177         *
   178         *  This function converts a `{@link Types#Label}` to a sequence of
   179         *  ASCII characters, writes the characters to the supplied buffer,
   180         *  updates the buffer pointer to point to the location after the last
   181         *  output character, and returns the number of characters output.
   182         *
   183         *  No more than `len` characters will be output.  If the label would
   184         *  otherwise be longer, the output is truncated at the point where a
   185         *  potential overflow is detected. The return value always reflects the
   186         *  number of characters output, but it may be less than `len`.
   187         *
   188         *  Label structures can be initialized from any module's instance handle
   189         *  using the module's `Mod_Handle_label()` method.  See
   190         *  `{@link Types#Label}` for more information.
   191         *
   192         *  @param(lab)    address of the label to interpret
   193         *  @param(bufp)   address of the output buffer pointer or `NULL`
   194         *
   195         *                 If `bufp` is `NULL`, the label's characters are
   196         *                 output via `{@link System#putch()}`.
   197         *
   198         *  @param(len)    maximum number of characters to generate
   199         *
   200         *                 If `len` is negative, the number of characters to be
   201         *                 generated is not limited.
   202         *
   203         *  @a(returns)
   204         *  The return value always reflects the number of characters output,
   205         *  but it may be less than `len`.
   206         *
   207         *  @see Types#Label
   208         */
   209        /* REQ_TAG(SYSBIOS-895), REQ_TAG(SYSBIOS-897), REQ_TAG(SYSBIOS-898) */
   210        Int putLab(Types.Label *lab, Char **bufp, Int len);
   211    
   212        /*!
   213         *  ======== putMod ========
   214         *  Convert module ID to its ASCII name
   215         *
   216         *  This function converts a `{@link Types#ModuleId}` to a sequence of
   217         *  ASCII characters, writes the characters to the supplied buffer,
   218         *  updates the buffer pointer to point to the location after the last
   219         *  output character, and returns the number of characters output.
   220         *
   221         *  No more than `len` characters will be output.  If the module name would
   222         *  otherwise be longer, the output is truncated at the point where a
   223         *  potential overflow is detected. The return value always reflects the
   224         *  number of characters output, but it may be less than `len`.
   225         *
   226         *  @param(mid)    ID of the module
   227         *  @param(bufp)   address of the output buffer pointer or `NULL`
   228         *
   229         *                 If `bufp` is `NULL`, the module's name characters are
   230         *                 output via `{@link System#putch()}`.
   231         *
   232         *  @param(len)    maximum number of characters to generate
   233         *
   234         *                 If `len` is negative, the number of characters to be
   235         *                 generated is not limited.
   236         *
   237         *  @a(returns)
   238         *  The return value always reflects the number of characters output,
   239         *  but it may be less than `len`.
   240         */
   241        /* REQ_TAG(SYSBIOS-894), REQ_TAG(SYSBIOS-897), REQ_TAG(SYSBIOS-898) */
   242        Int putMod(Types.ModuleId mid, Char **bufp, Int len);
   243    
   244        /*!
   245         *  ======== putSite ========
   246         *  Convert call site structure to an ASCII character sequence
   247         *
   248         *  This function converts a `{@link Types#Site}` to a sequence of
   249         *  ASCII characters, writes the characters to the supplied buffer,
   250         *  updates the buffer pointer to point to the location after the last
   251         *  output character, and returns the number of characters output.
   252         *
   253         *  No more than `len` characters will be output.  If the sequence would
   254         *  otherwise be longer, the output is truncated at the point where a
   255         *  potential overflow is detected.
   256         *
   257         *  @param(site)   address of the call site structure to interpret
   258         *  @param(bufp)   address of the output buffer pointer or `NULL`
   259         *
   260         *                 If `bufp` is `NULL`, the site's name characters are
   261         *                 output via `{@link System#putch()}`.
   262         *
   263         *  @param(len)    maximum number of characters to generate
   264         *
   265         *                 If `len` is negative, the number of characters to be
   266         *                 generated is not limited.
   267         *
   268         *  @a(returns)
   269         *  The return value always reflects the number of characters output,
   270         *  but it may be less than `len`.
   271         */
   272        /* REQ_TAG(SYSBIOS-896), REQ_TAG(SYSBIOS-897), REQ_TAG(SYSBIOS-898) */
   273        Int putSite(Types.Site *site, Char **bufp, Int len);
   274    
   275    internal:
   276    
   277        struct Node {
   278            Types.RopeId left;
   279            Types.RopeId right;
   280        };
   281    
   282        typedef Bool (*RopeVisitor)(Ptr, CString);
   283    
   284        struct MatchVisState {
   285            CString pat;
   286            UShort  *lenp;
   287            Int     res;
   288        };
   289    
   290        struct PrintVisState {
   291            Char   **bufp;
   292            UShort len;
   293            Int    res;
   294        };
   295    
   296        /* charTab[] and nodeTab[] are the "compressed" representation of
   297         * target strings used to name instances, modules, packages, ...
   298         *
   299         * The predefined node id 0 represents the empty string.
   300         */
   301        config Char charTab[] = [0];
   302        config Node nodeTab[] = [{left: 0, right: 0}];
   303    
   304        config Int16 charCnt = 1;
   305        config Int16 nodeCnt = 1;
   306    
   307        /*
   308         * The module ids are allocated as follows:
   309         * 0x1 - 0x4000     unnamed modules
   310         * 0x4001 - 0x7FFF  registry modules
   311         * 0x8000 - 0xFFFF  named modules
   312         *
   313         * See 'genModNames' in Text.xs
   314         *
   315         * TODO - We may be able to set unnamedModsLastId based on the config
   316         *        to give the Registry more room, but then the Registry id range
   317         *        would not be a constant.
   318         */
   319        config UInt16 unnamedModsLastId = 0x4000;
   320        config UInt16 registryModsLastId = 0x7FFF;
   321    
   322    /* unnamedModCnt can be used to define a constant that allows external
   323     * modules to define their own module IDs that don't conflict with the
   324     * statically configured modules; e.g., the dlog example could use this
   325     */
   326    //    config Int16 unnamedModCnt = 0;
   327    
   328        /*!
   329         *  ======== defineRopeCord ========
   330         *  Put text in charTab[] and return its offset within charTab
   331         */
   332        function defineRopeCord(text);
   333    
   334        /*!
   335         *  ======== defineRopeNode ========
   336         *  Create a new Node structure, add it to nodeTabe, and return nodeId,
   337         *  which is an offset within nodeTab with the leftmost bit set.
   338         */
   339        function defineRopeNode(left, right);
   340    
   341        function fetchAddr(raddr);
   342        function fetchCord(cid);
   343        function fetchId(rid);
   344        function fetchNode(nid);
   345    
   346        function genModNames();
   347        function genPkgName();
   348    
   349        Bool matchVisFxn(Ptr p, CString s);
   350        Bool printVisFxn(Ptr p, CString s);
   351    
   352        Void visitRope(RopeId rope, RopeVisitor visFxn, Ptr visState);
   353        Void visitRope2(RopeId rope, RopeVisitor visFxn, Ptr visState,
   354                        CString stack[]);
   355    
   356        typedef Void (*VisitRopeFxn)(RopeId, RopeVisitor, Ptr);
   357        typedef Void (*VisitRopeFxn2)(RopeId, RopeVisitor, Ptr, CString[]);
   358    
   359        config VisitRopeFxn visitRopeFxn = visitRope;
   360    
   361        config VisitRopeFxn2 visitRopeFxn2 = visitRope2;
   362    
   363        /*!
   364         *  ======== xprintf ========
   365         *  @param(bufp)   address of the output buffer pointer or `NULL`
   366         *
   367         *                 If `bufp` is `NULL`, the site's name characters are
   368         *                 output via `{@link System#putch()}`.
   369         *
   370         *  @param(len)    maximum number of characters to generate
   371         *
   372         *                 If `len` is negative, the number of characters to be
   373         *                 generated is not limited.
   374         *
   375         *  @a(returns)
   376         *  The return value always reflects the number of characters output,
   377         *  but it may be less than `len`.
   378         */
   379        Int xprintf(Char **bufp, SizeT len, CString fmt, ...);
   380    
   381        struct Module_State {
   382            CPtr charBase;
   383            CPtr nodeBase;
   384        };
   385    }
   386    /*
   387     *  @(#) xdc.runtime; 2, 1, 0,0; 8-21-2019 13:22:47; /db/ztree/library/trees/xdc/xdc-H25/src/packages/
   388     */
   389