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        /* REQ_TAG(SYSBIOS-886) */
   143        CString ropeText(RopeId rope);
   144    
   145        /*!
   146         *  ======== matchRope ========
   147         *  Compare pattern string `pat` to String identified by `rope`.
   148         *  @_nodoc
   149         *
   150         *  This function is invoked from `{@link Diags#setMask()}`, see the
   151         *  documentation for that function to find out how the patterns are
   152         *  created.
   153         *
   154         *  @a(pre-conditions)
   155         *  @p(blist)
   156         *      - lenp must be less than or equal to the length of pat
   157         *      - wildcard '%' is at src[(*lenp) - 1], if it's in the the pattern
   158         *  @p
   159    
   160         *  @a(post-conditions)
   161         *  @p(blist)
   162         *      - lenp is decreased by the length of any matching prefix
   163         *  @p
   164         *
   165         *  Returns:
   166         *  @p(blist)
   167         *      - -1  `pat` does not match string
   168         *      - 0   string is a prefix of pattern
   169         *      - 1   wildcard match
   170         *  @p
   171         */
   172        /* REQ_TAG(SYSBIOS-893) */
   173        Int matchRope(RopeId rope, CString pat, UShort *lenp);
   174    
   175        /*!
   176         *  ======== putLab ========
   177         *  Convert label to an ASCII character sequence
   178         *
   179         *  This function converts a `{@link Types#Label}` to a sequence of
   180         *  ASCII characters, writes the characters to the supplied buffer,
   181         *  updates the buffer pointer to point to the location after the last
   182         *  output character, and returns the number of characters output.
   183         *
   184         *  No more than `len` characters will be output.  If the label would
   185         *  otherwise be longer, the output is truncated at the point where a
   186         *  potential overflow is detected. The return value always reflects the
   187         *  number of characters output, but it may be less than `len`.
   188         *
   189         *  Label structures can be initialized from any module's instance handle
   190         *  using the module's `Mod_Handle_label()` method.  See
   191         *  `{@link Types#Label}` for more information.
   192         *
   193         *  @param(lab)    address of the label to interpret
   194         *  @param(bufp)   address of the output buffer pointer or `NULL`
   195         *
   196         *                 If `bufp` is `NULL`, the label's characters are
   197         *                 output via `{@link System#putch()}`.
   198         *
   199         *  @param(len)    maximum number of characters to generate
   200         *
   201         *                 If `len` is negative, the number of characters to be
   202         *                 generated is not limited.
   203         *
   204         *  @a(returns)
   205         *  The return value always reflects the number of characters output,
   206         *  but it may be less than `len`.
   207         *
   208         *  @see Types#Label
   209         */
   210        /* REQ_TAG(SYSBIOS-895), REQ_TAG(SYSBIOS-897), REQ_TAG(SYSBIOS-898) */
   211        Int putLab(Types.Label *lab, Char **bufp, Int len);
   212    
   213        /*!
   214         *  ======== putMod ========
   215         *  Convert module ID to its ASCII name
   216         *
   217         *  This function converts a `{@link Types#ModuleId}` to a sequence of
   218         *  ASCII characters, writes the characters to the supplied buffer,
   219         *  updates the buffer pointer to point to the location after the last
   220         *  output character, and returns the number of characters output.
   221         *
   222         *  No more than `len` characters will be output.  If the module name would
   223         *  otherwise be longer, the output is truncated at the point where a
   224         *  potential overflow is detected. The return value always reflects the
   225         *  number of characters output, but it may be less than `len`.
   226         *
   227         *  @param(mid)    ID of the module
   228         *  @param(bufp)   address of the output buffer pointer or `NULL`
   229         *
   230         *                 If `bufp` is `NULL`, the module's name characters are
   231         *                 output via `{@link System#putch()}`.
   232         *
   233         *  @param(len)    maximum number of characters to generate
   234         *
   235         *                 If `len` is negative, the number of characters to be
   236         *                 generated is not limited.
   237         *
   238         *  @a(returns)
   239         *  The return value always reflects the number of characters output,
   240         *  but it may be less than `len`.
   241         */
   242        /* REQ_TAG(SYSBIOS-894), REQ_TAG(SYSBIOS-897), REQ_TAG(SYSBIOS-898) */
   243        Int putMod(Types.ModuleId mid, Char **bufp, Int len);
   244    
   245        /*!
   246         *  ======== putSite ========
   247         *  Convert call site structure to an ASCII character sequence
   248         *
   249         *  This function converts a `{@link Types#Site}` to a sequence of
   250         *  ASCII characters, writes the characters to the supplied buffer,
   251         *  updates the buffer pointer to point to the location after the last
   252         *  output character, and returns the number of characters output.
   253         *
   254         *  No more than `len` characters will be output.  If the sequence would
   255         *  otherwise be longer, the output is truncated at the point where a
   256         *  potential overflow is detected.
   257         *
   258         *  @param(site)   address of the call site structure to interpret
   259         *  @param(bufp)   address of the output buffer pointer or `NULL`
   260         *
   261         *                 If `bufp` is `NULL`, the site's name characters are
   262         *                 output via `{@link System#putch()}`.
   263         *
   264         *  @param(len)    maximum number of characters to generate
   265         *
   266         *                 If `len` is negative, the number of characters to be
   267         *                 generated is not limited.
   268         *
   269         *  @a(returns)
   270         *  The return value always reflects the number of characters output,
   271         *  but it may be less than `len`.
   272         */
   273        /* REQ_TAG(SYSBIOS-896), REQ_TAG(SYSBIOS-897), REQ_TAG(SYSBIOS-898) */
   274        Int putSite(Types.Site *site, Char **bufp, Int len);
   275    
   276    internal:
   277    
   278        struct Node {
   279            Types.RopeId left;
   280            Types.RopeId right;
   281        };
   282    
   283        typedef Bool (*RopeVisitor)(Ptr, CString);
   284    
   285        struct MatchVisState {
   286            CString pat;
   287            UShort  *lenp;
   288            Int     res;
   289        };
   290    
   291        struct PrintVisState {
   292            Char   **bufp;
   293            UShort len;
   294            Int    res;
   295        };
   296    
   297        /* charTab[] and nodeTab[] are the "compressed" representation of
   298         * target strings used to name instances, modules, packages, ...
   299         *
   300         * The predefined node id 0 represents the empty string.
   301         */
   302        config Char charTab[] = [0];
   303        config Node nodeTab[] = [{left: 0, right: 0}];
   304    
   305        /* REQ_TAG(SYSBIOS-887) */
   306        config Int16 charCnt = 1;
   307        config Int16 nodeCnt = 1;
   308    
   309        /*
   310         * The module ids are allocated as follows:
   311         * 0x1 - 0x4000     unnamed modules
   312         * 0x4001 - 0x7FFF  registry modules
   313         * 0x8000 - 0xFFFF  named modules
   314         *
   315         * See 'genModNames' in Text.xs
   316         *
   317         * TODO - We may be able to set unnamedModsLastId based on the config
   318         *        to give the Registry more room, but then the Registry id range
   319         *        would not be a constant.
   320         */
   321        config UInt16 unnamedModsLastId = 0x4000;
   322        config UInt16 registryModsLastId = 0x7FFF;
   323    
   324    /* unnamedModCnt can be used to define a constant that allows external
   325     * modules to define their own module IDs that don't conflict with the
   326     * statically configured modules; e.g., the dlog example could use this
   327     */
   328    //    config Int16 unnamedModCnt = 0;
   329    
   330        /*!
   331         *  ======== defineRopeCord ========
   332         *  Put text in charTab[] and return its offset within charTab
   333         */
   334        function defineRopeCord(text);
   335    
   336        /*!
   337         *  ======== defineRopeNode ========
   338         *  Create a new Node structure, add it to nodeTabe, and return nodeId,
   339         *  which is an offset within nodeTab with the leftmost bit set.
   340         */
   341        function defineRopeNode(left, right);
   342    
   343        function fetchAddr(raddr);
   344        function fetchCord(cid);
   345        function fetchId(rid);
   346        function fetchNode(nid);
   347    
   348        function genModNames();
   349        function genPkgName();
   350    
   351        Bool matchVisFxn(Ptr p, CString s);
   352        Bool printVisFxn(Ptr p, CString s);
   353    
   354        Void visitRope(RopeId rope, RopeVisitor visFxn, Ptr visState);
   355        Void visitRope2(RopeId rope, RopeVisitor visFxn, Ptr visState,
   356                        CString stack[]);
   357    
   358        typedef Void (*VisitRopeFxn)(RopeId, RopeVisitor, Ptr);
   359        typedef Void (*VisitRopeFxn2)(RopeId, RopeVisitor, Ptr, CString[]);
   360    
   361        config VisitRopeFxn visitRopeFxn = visitRope;
   362    
   363        config VisitRopeFxn2 visitRopeFxn2 = visitRope2;
   364    
   365        /*!
   366         *  ======== xprintf ========
   367         *  @param(bufp)   address of the output buffer pointer or `NULL`
   368         *
   369         *                 If `bufp` is `NULL`, the site's name characters are
   370         *                 output via `{@link System#putch()}`.
   371         *
   372         *  @param(len)    maximum number of characters to generate
   373         *
   374         *                 If `len` is negative, the number of characters to be
   375         *                 generated is not limited.
   376         *
   377         *  @a(returns)
   378         *  The return value always reflects the number of characters output,
   379         *  but it may be less than `len`.
   380         */
   381        Int xprintf(Char **bufp, SizeT len, CString fmt, ...);
   382    
   383        struct Module_State {
   384            CPtr charBase;
   385            CPtr nodeBase;
   386        };
   387    }
   388    /*
   389     *  @(#) xdc.runtime; 2, 1, 0,0; 10-3-2020 15:24:56; /db/ztree/library/trees/xdc/xdc-K04/src/packages/
   390     */
   391