1 2 3 4 5 6 7 8 9 10 11 12
13 14 15 16
17
18 package xdc.runtime;
19
20 /*!
21 * ======== System ========
22 * Basic system services
23 *
24 * This module provides basic low-level "system" services; e.g.,
25 * character output, `printf`-like output, and exit handling.
26 *
27 * This module is gated and other modules use its gate via the
28 * `{@link Gate#enterSystem}` and `{@link Gate#leaveSystem}`. The
29 * `System` gate must be enterable by any thread in a multi-threaded
30 * environments. For example, in many real-time multi-threaded environments
31 * some types of threads, such as Interrupt Service Routines (ISRs), are not
32 * allowed to call operations that block the caller. In such an environment,
33 * either the `System` gate must disable all interrupts or ISRs must never
34 * call a function in the `xdc.runtime` package.
35 */
36
37 @Template("./System.xdt")
38 @Gated
39 @ModuleStartup
40 module System {
41
42 /*!
43 * ======== AtexitHandler ========
44 * `System`'s atexit function prototype.
45 *
46 * Fuctions of this type can be added to the list of functions that
47 * are executed during application termination.
48 *
49 * @see #atexit
50 */
51 typedef Void (*AtexitHandler)(Int);
52
53 /*!
54 * ======== STATUS_UNKNOWN ========
55 * Unknown exit status value
56 *
57 * When the program exits by calling {@link #exit System_exit()} the
58 * `System`'s `atexit` functions are passed the status value passed to
59 * `System_exit()`. However, if the program exits using
60 * the ANSI C Standard Library `exit()` function, the `System`'s `atexit`
61 * functions are passed `System_STATUS_UNKNOWN`; ANSI C `atexit`
62 * functions are not passed the exit status.
63 */
64 const Int STATUS_UNKNOWN = 0xCAFE;
65
66 /*! @_nodoc */
67 @XmlDtd
68 metaonly struct Module_View {
69 String atexitHandlers[];
70 Int numAtexitHandlers;
71 };
72
73 /*!
74 * ======== A_cannotFitIntoArg ========
75 * Assert that the target's `Float` type fits in an `IArg`
76 *
77 * This assertion is triggered when the `%f` format specifier is used,
78 * the argument treated as an `IArg`, but for the current target
79 * `sizeof(Float)` > `sizeof(IArg)`.
80 */
81 config Assert.Id A_cannotFitIntoArg = {
82 msg: "A_cannotFitIntoArg: sizeof(Float) > sizeof(Arg)"
83 };
84
85 /*!
86 * ======== extendedFormats ========
87 * Optional conversions supported by `{@link #printf System_printf}`
88 *
89 * This string specifies the set of optional argument conversion
90 * specifiers required by the application. By reducing the number of
91 * optional conversions understood by the `System {@link #printf}`
92 * methods, it is possible to significantly reduce the code size
93 * footprint of the `System` module. This configuration parameter
94 * enables one to balance `printf` functionality against code size
95 * footprint.
96 *
97 * The format of this string is simply a concatenated list of the desired
98 * conversion specifiers (with the leading `%` character). For example,
99 * to support both `%f` and `%$L` set `extendedFormats` to `"%$L%f"`.
100 *
101 * To disable all optional converstions, set `extendedFormats` to `null`
102 * or the empty string ("").
103 *
104 * For a complete list of supported extensions, see the
105 * {@link #printf System_printf} "Extended_Format_Specifiers" section.
106 *
107 * @(Note)
108 * If an optional conversion is used by some part of the application and
109 * it is not specified in `extendedFormats`, the conversion character(s)
110 * and leading `%` are treated as ordinary characters to be output. As
111 * a result, all subsequent arguments will almost certainly be converted
112 * using the wrong conversion specifier!
113 *
114 * @see #printf
115 */
116 metaonly config String extendedFormats = "%$L";
117
118 /*!
119 * ======== SupportProxy ========
120 * The implementation module of the low-level system functions.
121 *
122 * This configuration parameter allows one to "bind" a different
123 * implementation of the low-level services required to implement
124 * `System`.
125 * @p(code)
126 * var System = xdc.useModule("xdc.runtime.System");
127 * var SysStd = xdc.useModule("xdc.runtime.SysStd");
128 * System.SupportProxy = SysStd;
129 * @p
130 *
131 * If this parameter is not set, it defaults to `{@link SysMin}`.
132 */
133 proxy SupportProxy inherits ISystemSupport;
134
135 /*!
136 * ======== maxAtexitHandlers ========
137 * Maximum number of dynamic atexit handlers allowed in the system.
138 *
139 * Maximum number of `System` `atexit` handlers set during runtime via
140 * the `{@link System#atexit}` function.
141 *
142 */
143 config Int maxAtexitHandlers = 8;
144
145 /*!
146 * ======== abort ========
147 * Print a message and abort currently running executable.
148 *
149 * This is called when an executable abnormally terminates.
150 * The `System` gate is entered, the
151 * `{@link #SupportProxy}`'s `abort` function is called
152 * and `abort` is called.
153 * No exit functions bound via `System_atexit()` or the ANSI C Standard
154 * Library `atexit()` functions are executed.
155 *
156 * @param(str) abort message (not a format string)
157 */
158 Void abort(String str);
159
160 /*!
161 * ======== atexit ========
162 * Add an exit handler
163 *
164 * `System_atexit` pushes `handler` onto an internal stack of functions
165 * to be executed when system is exiting (e.g. `System_exit` or `exit` is
166 * called). Up to `{@link #maxAtexitHandlers}` functions can be specified
167 * in this manner. During the exit processing, the functions are popped
168 * off the internal stack and called until the stack is empty.
169 *
170 * The `System` gate is entered before the `System_atexit` functions
171 * are called.
172 *
173 * The `SupportProxy`'s `{@link ISystemSupport#exit}` function is called
174 * after all the atexit functions are called.
175 *
176 * @param(handler) the `AtexitHandler` to invoke during system
177 * exit processing.
178 *
179 * @a(returns)
180 * If `FALSE` is returned, the exit handler was not added and it will
181 * not be called during an exit.
182 */
183 Bool atexit(AtexitHandler handler);
184
185 /*!
186 * ======== atexitMeta ========
187 * Add an exit handler during configuration
188 *
189 * This is the static counterpart to `System_atexit()`. This method can
190 * be used to add `atexit` handlers at configuration time. These
191 * handlers do not count against the `maxAtexitHandlers`.
192 *
193 * @param(handler) the `AtexitHandler` to invoke during system
194 * exit processing.
195 */
196 metaonly Void atexitMeta(AtexitHandler handler);
197
198 /*!
199 * ======== exit ========
200 * Exit currently running executable.
201 *
202 * This function is called when an executable needs to terminate
203 * normally. This function sets the exit code and simply calls `exit`.
204 * All functions bound via `System_atexit` or the ANSI C Standar Library
205 * `atexit` function are then executed. The `{@link #SupportProxy}`'s
206 * `exit` function is called during this time.
207 *
208 * @param(stat) exit status to return to calling environment.
209 */
210 Void exit(Int stat);
211
212 /*!
213 * ======== putch ========
214 * Output a single character
215 *
216 * The `{@link #SupportProxy}`'s `putch` function is called
217 * by this function.
218 *
219 * @param(ch) character to be output.
220 */
221 Void putch(Char ch);
222
223 /*!
224 * ======== flush ========
225 * Flush standard System I/O
226 *
227 * This function causes any buffered output characters are "written"
228 * to the output device.
229 *
230 * The `{@link #SupportProxy}`'s `flush` function is called
231 * by this function.
232 */
233 Void flush();
234
235 /*!
236 * ======== printf ========
237 * A smaller faster printf
238 *
239 * This function behaves much like the ANSI C Standard `printf`
240 * but does not support the full range of format strings specified by
241 * the C Standard. In addition, several non-standard format specifiers
242 * are recognized.
243 *
244 * @a(Format Strings)
245 * The format string is a character string composed of zero or
246 * more directives: ordinary characters (not %), which are copied
247 * unchanged to the output stream; and conversion specifications, each of
248 * which results in fetching zero or more subsequent arguments. Each
249 * conversion specification is introduced by the character %, and ends
250 * with a conversion specifier. In between there may be (in this order)
251 * zero or more flags, an optional minimum field width, an optional
252 * precision and an optional length modifier.
253 *
254 * @a(Flags)
255 * The following flags are supported:
256 * @p(dlist)
257 * - `-`
258 * The converted value is to be left adjusted on the field
259 * boundary (the default is right justification.)
260 * - `0`
261 * The value should be zero padded. For d, i, o, u, and x
262 * conversions, the converted value is padded on the left
263 * with zeros rather than blanks.
264 * @p
265 *
266 * @a(Field Width)
267 * The optional field width specifier is a decimal digit string (with
268 * nonzero first digit) specifying a minimum field width. If the
269 * converted value has fewer characters than the field width, it will
270 * be padded with spaces on the left (or right, if the left-adjustment
271 * flag has been given). Instead of a decimal digit string one may
272 * write `*` to specify that the field width is given in the next
273 * argument. A negative field width is taken as a '-' flag followed
274 * by a positive field width.
275 *
276 * @a(Precision)
277 * The optional precision specifier is a period ('.') followed by an
278 * optional decimal digit string. Instead of a decimal digit string
279 * one may write `*` to specify that the precision is given in the
280 * next argument which must be of type int.
281 *
282 * If the precision is given as just '.', or the precision is
283 * negative, the precision is taken to be zero. This gives the
284 * minimum number of digits to appear for d, i, o, u, and x
285 * conversions, or the maximum number of characters to be printed from
286 * a string for s conversions.
287 *
288 * @a(Length Modifiers)
289 * The optional length modifier is a single character from the following
290 * list.
291 * @p(dlist)
292 * - `l`
293 * A following integer conversion corresponds to a long int
294 * or unsigned long int argument
295 *
296 * @p
297 *
298 * @a(Conversion Specifiers)
299 * The following conversion specifiers are supported.
300 * @p(dlist)
301 * - `d`, `i`
302 * signed integer
303 * - `u`
304 * unsigned decimal
305 * - `x`
306 * unsigned hex
307 * - `o`
308 * unsigned octal
309 * - `p`
310 * pointer (@ + hex num)
311 * - `c`
312 * character
313 * - `s`
314 * string
315 * @p
316 * @a(Extended Conversion Specifiers)
317 * The following conversion specifiers are optionally supported. See
318 * the `{@link #extendedFormats}` configuration parameter for more
319 * information about how to enable these conversion specifiers.
320 *
321 * @p(dlist)
322 * - `f`
323 * decimal floating point.
324 * - `$`
325 * non-ANSI conversion prefix. This prefix indicates that the
326 * next character identifies a non-ANSI standard conversion.
327 *
328 * If the next character is `L` then the argument is treated as
329 * a pointer to a `{@link Types#Label}` and is converted to an
330 * appropriate string.
331 * @p
332 *
333 * @param(fmt) a 'printf-style' format string
334 *
335 * @a(returns)
336 * `printf` returns the number of characters printed.
337 */
338 Int printf(String fmt, ...);
339
340 /*!
341 * ======== aprintf ========
342 * `{@link #printf}` where all optional arguments are `IArg`s
343 *
344 * This function will treat each argument as though it was widened to be
345 * of type `IArg` prior to being passed to the `{@link #printf}` function
346 *
347 * @see #printf
348 */
349 Int aprintf(String fmt, ...);
350
351 /*!
352 * ======== sprintf ========
353 * Write formated output to a character buffer
354 *
355 * This function is identical to `{@link #printf}` except that the
356 * output is copied to the specified character buffer `buf` followed
357 * by a terminating '\0' character.
358 *
359 * @param(buf) a character output buffer
360 * @param(fmt) a 'printf-style' format string
361 *
362 * @a(returns)
363 * `sprintf` returns the number of characters output not including the
364 * '\0' termination character.
365 */
366 Int sprintf(Char buf[], String fmt, ...);
367
368 /*!
369 * ======== asprintf ========
370 * `{@link #sprintf}` where all optional arguments are `IArg`s
371 *
372 * This function will treat each argument as though it was widened to be
373 * of type `IArg` prior to being passed to the `{@link #sprintf}`
374 * function.
375 *
376 * @see #sprintf
377 */
378 Int asprintf(Char buf[], String fmt, ...);
379
380 /*!
381 * ======== vprintf ========
382 * A VaList printf
383 *
384 * This function is identical to `{@link #printf}` except that its
385 * arguments are passed via a VaList (a "varargs list").
386 *
387 * @param(fmt) a standard 'printf-style' format string.
388 * @param(va) an args list that points to the arguments referenced
389 * by the fmt string
390 *
391 * @a(returns)
392 * `vprintf` returns the number of characters output.
393 */
394 Int vprintf(String fmt, VaList va);
395
396 /*!
397 * ======== avprintf ========
398 * `{@link #vprintf}` where all optional arguments are `IArg`s
399 *
400 * This function will treat each argument as though it was widened to be
401 * of type `IArg` prior to being passed to the `{@link #vprintf}`
402 * function.
403 *
404 * @see #vprintf
405 */
406 Int avprintf(String fmt, VaList va);
407
408 /*!
409 * ======== vsprintf ========
410 * A `VaList` sprintf
411 *
412 * This function is identical to `{@link #sprintf}` except that
413 * its arguments are passed via a `VaList` (a "varargs list").
414 *
415 * @param(buf) a character output buffer
416 * @param(fmt) a standard '`printf`-style' format string.
417 * @param(va) an arguments list that points to the arguments referenced
418 * by the `fmt` string
419 *
420 * @a(returns)
421 * `vsprintf` returns the number of characters output.
422 */
423 Int vsprintf(Char buf[], String fmt, VaList va);
424
425 /*!
426 * ======== avsprintf ========
427 * `{@link #vsprintf}` where all optional arguments are `IArg`s
428 *
429 * This function is identical to `{@link #sprintf}` except that
430 * its arguments are passed via a `VaList` (a "varargs list").
431 *
432 * This function will treat each argument as though it was widened to be
433 * of type `IArg` prior to being passed to the `vsprintf` function
434 *
435 * @see #vsprintf
436 */
437 Int avsprintf(Char buf[], String fmt, VaList va);
438
439 internal:
440
441 /*! struct used to keep track of state during doPrint */
442 struct ParseData {
443 Int width;
444 Bool lFlag;
445 Bool lJust;
446 Int precis;
447 Int len;
448 Int zpad;
449 Char *end;
450 Bool aFlag;
451 Char *ptr;
452 };
453
454 /*! typedef for generated functions to process extended formats */
455 typedef Int (*ExtendFxn)(Char **, Char **, VaList, ParseData *);
456
457 /*! config parameter used to call generated function */
458 readonly config ExtendFxn extendFxn = '&xdc_runtime_System_printfExtend__I';
459
460 461 462 463 464 465 466 467 468 469
470 Int printfExtend (Char **bufp, Char **fmt, VaList va, ParseData *parse);
471
472 /*!
473 * ======== exitFxns ========
474 * @_nodoc
475 * List of functions statically plugged to be called at exit
476 *
477 */
478 metaonly config AtexitHandler exitFxns[];
479
480 /*!
481 * ======== mprintf ========
482 * @_nodoc
483 */
484 function mprintf(fmt, args);
485
486 /*!
487 * ======== doPrint ========
488 * @_nodoc
489 *
490 */
491 Int doPrint(Char buf[], String fmt, VaList va, Bool aFlag);
492
493 /*!
494 * ======== formatNum ========
495 * @_nodoc
496 *
497 */
498 Char *formatNum(Char *ptr, UInt32 n, Int zpad, Int base);
499
500 /*!
501 * ======== putchar ========
502 * @_nodoc
503 *
504 * Write character ch to the buffer and, if the buffer pointer is
505 * non-`NULL`, update the buffer pointer.
506 */
507 Void putchar(Char **bufp, Char ch);
508
509 /*!
510 * ======== rtsExit ========
511 * @_nodoc
512 */
513 Void rtsExit();
514
515 /*!
516 * ======== Module_State ========
517 * @_nodoc
518 */
519 struct Module_State {
520 AtexitHandler atexitHandlers[];
521 Int numAtexitHandlers;
522 Int exitStatus;
523 };
524 }
525 526 527
528