1 2 3 4 5 6 7 8 9 10 11 12
13 14 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
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
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
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
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
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
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
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
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
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
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 298 299 300 301
302 config Char charTab[] = [0];
303 config Node nodeTab[] = [{left: 0, right: 0}];
304
305
306 config Int16 charCnt = 1;
307 config Int16 nodeCnt = 1;
308
309 310 311 312 313 314 315 316 317 318 319 320
321 config UInt16 unnamedModsLastId = 0x4000;
322 config UInt16 registryModsLastId = 0x7FFF;
323
324 325 326 327
328
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 390
391