1 2 3 4 5 6 7 8 9 10 11 12
13 14 15
16
17 package xdc.runtime;
18
19 /*!
20 * ======== System ========
21 * Basic system services
22 *
23 * This module provides basic low-level "system" services; e.g.,
24 * character output, `printf`-like output, and exit handling.
25 *
26 * This module is gated and other modules use its gate via the
27 * `{@link Gate#enterSystem}` and `{@link Gate#leaveSystem}`. The `System`
28 * gate must be enterable by any thread in a multi-threaded environments. For
29 * example, in many real-time multi-threaded environments some types of
30 * threads, such as Interrupt Service Routines (ISRs), are not allowed to call
31 * operations that block the caller. In such an environment, either the
32 * `System` gate must disable all interrupts or ISRs must never call a function
33 * in the `xdc.runtime` package.
34 */
35
36 @Template("./System.xdt")
37 @Gated
38 @ModuleStartup
39 @DirectCall
40 module System {
41
42 /*!
43 * ======== AtexitHandler ========
44 * `System`'s atexit function prototype.
45 *
46 * Functions 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 /*!
67 * ======== AbortFxn ========
68 * System abort function prototype.
69 *
70 * Functions of this type can be plugged into `System`'s abort function
71 * that will be executed during abnormal application termination.
72 *
73 * @see #abort
74 */
75 typedef Void (*AbortFxn)();
76
77 /*!
78 * ======== ExitFxn ========
79 * System exit function prototype.
80 *
81 * Functions of this type can be plugged into `System`'s exit function that
82 * will be executed during normal application termination.
83 *
84 * @see #exit
85 */
86 typedef Void (*ExitFxn)(Int);
87
88 /*! @_nodoc */
89 @XmlDtd
90 metaonly struct Module_View {
91 String atexitHandlers[];
92 Int numAtexitHandlers;
93 };
94
95 /*! @_nodoc */
96 metaonly struct PathEntryView {
97 String entry;
98 }
99
100 /*!
101 * ======== rovViewInfo ========
102 * @_nodoc
103 */
104 @Facet
105 metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
106 xdc.rov.ViewInfo.create({
107 viewMap: [
108 ['XDCROOT',
109 {
110 type: xdc.rov.ViewInfo.MODULE_DATA,
111 viewInitFxn: 'viewInitXdcRoot',
112 structName: 'PathEntryView'
113 }
114 ],
115 ['XDCPATH',
116 {
117 type: xdc.rov.ViewInfo.MODULE_DATA,
118 viewInitFxn: 'viewInitXdcPath',
119 structName: 'PathEntryView'
120 }
121 ],
122 ]
123 });
124
125 /*!
126 * ======== A_cannotFitIntoArg ========
127 * Assert that the target's `Float` type fits in an `IArg`
128 *
129 * This assertion is triggered when the `%f` format specifier is used,
130 * the argument treated as an `IArg`, but for the current target
131 * `sizeof(Float)` > `sizeof(IArg)`.
132 */
133 config Assert.Id A_cannotFitIntoArg = {
134 msg: "A_cannotFitIntoArg: sizeof(Float) > sizeof(Arg)"
135 };
136
137 /*!
138 * ======== extendedFormats ========
139 * Optional conversions supported by `{@link #printf System_printf}`
140 *
141 * This string specifies the set of optional argument conversion
142 * specifiers required by the application. By reducing the number of
143 * optional conversions understood by the `System {@link #printf}`
144 * methods, it is possible to significantly reduce the code size
145 * footprint of the `System` module. This configuration parameter
146 * enables one to balance `printf` functionality against code size
147 * footprint.
148 *
149 * The format of this string is simply a concatenated list of the desired
150 * conversion specifiers (with the leading `%` character). For example,
151 * to support both `%f` and `%$L` set `extendedFormats` to `"%$L%f"`.
152 *
153 * To disable all optional converstions, set `extendedFormats` to `null`
154 * or the empty string ("").
155 *
156 * For a complete list of supported extensions, see the
157 * `{@link #printf System_printf}` "Extended_Format_Specifiers" section.
158 *
159 * @a(Note)
160 * If an optional conversion is used by some part of the application and
161 * it is not specified in `extendedFormats`, the conversion character(s)
162 * and leading `%` are treated as ordinary characters to be output. As
163 * a result, all subsequent arguments will almost certainly be converted
164 * using the wrong conversion specifier!
165 *
166 * @see #printf
167 */
168
169 metaonly config String extendedFormats = "%$L%$S%$F";
170
171 /*!
172 * ======== SupportProxy ========
173 * The implementation module of the low-level system functions.
174 *
175 * This configuration parameter allows one to "bind" a different
176 * implementation of the low-level services required to implement
177 * `System`.
178 * @p(code)
179 * var System = xdc.useModule("xdc.runtime.System");
180 * var SysStd = xdc.useModule("xdc.runtime.SysStd");
181 * System.SupportProxy = SysStd;
182 * @p
183 *
184 * If this parameter is not set, it defaults to `{@link SysMin}`.
185 */
186
187 proxy SupportProxy inherits ISystemSupport;
188
189 /*!
190 * ======== maxAtexitHandlers ========
191 * Maximum number of dynamic atexit handlers allowed in the system.
192 *
193 * Maximum number of `System` `atexit` handlers set during runtime via
194 * the `{@link System#atexit}` function.
195 *
196 */
197
198 config Int maxAtexitHandlers = 8;
199
200 /*!
201 * ======== abortFxn ========
202 * Abort handler function
203 *
204 * This configuration parameter allows user to plug in their own abort
205 * function. By default `{@link #abortStd}` which calls ANSI C Standard
206 * `abort()` is plugged in. Alternatively `{@link #abortSpin}` can be
207 * plugged which loops infinitely.
208 *
209 */
210
211 config AbortFxn abortFxn = System.abortStd;
212
213 /*!
214 * ======== exitFxn ========
215 * Exit handler function
216 *
217 * This configuration parameter allows user to plug in their own exit
218 * function. By default `{@link #exitStd}` which calls ANSI C Standard
219 * `exit()` is plugged in. Alternatively `{@link #exitSpin}` can be
220 * plugged which loops infinitely.
221 *
222 */
223
224 config ExitFxn exitFxn = System.exitStd;
225
226 /*!
227 * ======== abort ========
228 * Print a message and abort currently running executable.
229 *
230 * This is called when an executable abnormally terminates.
231 * The `System` gate is entered, the
232 * `{@link #SupportProxy}`'s `abort` function is called
233 * and then `{@link #abortFxn}` is called.
234 * No exit functions bound via `System_atexit()` or the ANSI C Standard
235 * Library `atexit()` functions are executed.
236 *
237 * @param(str) abort message (not a format string)
238 */
239
240 Void abort(CString str);
241
242 /*!
243 * ======== abortStd ========
244 * ANSI C Standard implementation of abortFxn function
245 *
246 * This function calls ANSI C Standard `abort()` to terminate currently
247 * running executable. This function is used by default in
248 * `{@link #abortFxn}`.
249 *
250 */
251
252 Void abortStd();
253
254 /*!
255 * ======== abortSpin ========
256 * Lightweight implementation of abortFxn function
257 *
258 * This functions loops indefinitely. This can used as an alternative
259 * `{@link #abortFxn}` when a lightweight implementation is
260 * required instead of the ANSI C Standard `abort()`.
261 */
262
263 Void abortSpin();
264
265 /*!
266 * ======== atexit ========
267 * Add an exit handler
268 *
269 * `System_atexit` pushes `handler` onto an internal stack of functions
270 * to be executed when system is exiting (e.g. `System_exit` is called).
271 * Up to `{@link #maxAtexitHandlers}` functions can be specified in this
272 * manner. During the exit processing, the functions are popped off the
273 * internal stack and called until the stack is empty.
274 *
275 * The `System` gate is entered before the `System_atexit` functions
276 * are called.
277 *
278 * The `SupportProxy`'s `{@link ISystemSupport#exit}` function is called
279 * after all the atexit functions are called.
280 *
281 * @param(handler) the `AtexitHandler` to invoke during system
282 * exit processing.
283 *
284 * @a(returns)
285 * If `FALSE` is returned, the exit handler was not added and it will
286 * not be called during an exit.
287 */
288
289 Bool atexit(AtexitHandler handler);
290
291 /*!
292 * ======== atexitMeta ========
293 * Add an exit handler during configuration
294 *
295 * This is the static counterpart to `System_atexit()`. This method can
296 * be used to add `atexit` handlers at configuration time. These
297 * handlers do not count against the `maxAtexitHandlers`.
298 *
299 * @param(handler) the `AtexitHandler` to invoke during system
300 * exit processing.
301 */
302
303 metaonly Void atexitMeta(AtexitHandler handler);
304
305 /*!
306 * ======== exit ========
307 * Exit currently running executable.
308 *
309 * This function is called when an executable needs to terminate
310 * normally. This function processes all functions bound via
311 * `System_atexit` and then calls `{@link #exitFxn}`. The
312 * `{@link #SupportProxy}`'s `exit` function is called during this time.
313 *
314 * @param(stat) exit status to return to calling environment.
315 */
316
317 Void exit(Int stat);
318
319 /*!
320 * ======== exitStd ========
321 * Implements an `exitFxn` function
322 *
323 * This function calls ANSI C Standard `exit()` to terminate currently
324 * running executable normally. This function is used by default in
325 * `{@link #exitFxn}`.
326 *
327 * @param(stat) exit status to return to calling environment.
328 */
329
330 Void exitStd(Int stat);
331
332 /*!
333 * ======== exitSpin ========
334 * Implements an `exitFxn` function
335 *
336 * This functions loops indefinitely. This can used as an alternative
337 * `{@link #exitFxn}` when a light weight implementation is
338 * required instead of the ANSI C Standard `exit()`.
339 *
340 * @param(stat) exit status to return to calling environment.
341 */
342
343 Void exitSpin(Int stat);
344
345 /*!
346 * ======== processAtExit ========
347 * Processes all functions bound via `System_atexit`
348 *
349 * This function is called by `System_exit` to process all functions
350 * bound via `System_atexit`. User can add this to ANSI C standard
351 * `atexit` function so that all functions bound via `System_atexit` are
352 * processed when ANSI C standard `exit` function is called.
353 *
354 * @param(stat) exit status which will be passed to all functions
355 * processed.
356 */
357
358 Void processAtExit(Int stat);
359
360 /*!
361 * ======== putch ========
362 * Output a single character
363 *
364 * The `{@link #SupportProxy}`'s `putch` function is called
365 * by this function.
366 *
367 * @param(ch) character to be output.
368 */
369
370 Void putch(Char ch);
371
372 /*!
373 * ======== flush ========
374 * Flush standard System I/O
375 *
376 * This function causes any buffered output characters are "written"
377 * to the output device.
378 *
379 * The `{@link #SupportProxy}`'s `flush` function is called
380 * by this function.
381 */
382
383 Void flush();
384
385 /*!
386 * ======== printf ========
387 * A smaller faster printf
388 *
389 * This function behaves much like the ANSI C Standard `printf`
390 * but does not support the full range of format strings specified by
391 * the C Standard. In addition, several non-standard format specifiers
392 * are recognized.
393 *
394 * @a(Format Strings)
395 * The format string is a character string composed of zero or
396 * more directives: ordinary characters (not %), which are copied
397 * unchanged to the output stream; and conversion specifications, each of
398 * which results in fetching zero or more subsequent arguments. Each
399 * conversion specification is introduced by the character %, and ends
400 * with a conversion specifier. In between there may be (in this order)
401 * zero or more flags, an optional minimum field width, an optional
402 * precision and an optional length modifier.
403 *
404 * @a(Flags)
405 * The following flags are supported:
406 * @p(dlist)
407 * - `-`
408 * The converted value is to be left adjusted on the field
409 * boundary (the default is right justification.)
410 * - `0`
411 * The value should be zero padded. For d, i, o, u, and x
412 * conversions, the converted value is padded on the left
413 * with zeros rather than blanks.
414 * @p
415 *
416 * @a(Field Width)
417 * The optional field width specifier is a decimal digit string (with
418 * nonzero first digit) specifying a minimum field width. If the
419 * converted value has fewer characters than the field width, it will
420 * be padded with spaces on the left (or right, if the left-adjustment
421 * flag has been given). Instead of a decimal digit string one may
422 * write `*` to specify that the field width is given in the next
423 * argument. A negative field width is taken as a '-' flag followed
424 * by a positive field width.
425 *
426 * @a(Precision)
427 * The optional precision specifier is a period ('.') followed by an
428 * optional decimal digit string. Instead of a decimal digit string
429 * one may write `*` to specify that the precision is given in the
430 * next argument which must be of type int.
431 *
432 * If the precision is given as just '.', or the precision is
433 * negative, the precision is taken to be zero. This gives the
434 * minimum number of digits to appear for d, i, o, u, and x
435 * conversions, or the maximum number of characters to be printed from
436 * a string for s conversions.
437 *
438 * @a(Length Modifiers)
439 * The optional length modifier is a single character from the following
440 * list.
441 * @p(dlist)
442 * - `l`
443 * A following integer conversion corresponds to a long int
444 * or unsigned long int argument
445 *
446 * @p
447 *
448 * @a(Conversion Specifiers)
449 * The following conversion specifiers are supported.
450 * @p(dlist)
451 * - `d`, `i`
452 * signed integer
453 * - `u`
454 * unsigned decimal
455 * - `x`
456 * unsigned hex
457 * - `o`
458 * unsigned octal
459 * - `p`
460 * pointer (@ + hex num)
461 * - `c`
462 * character
463 * - `s`
464 * string
465 * @p
466 * @a(Extended Conversion Specifiers)
467 * The following conversion specifiers are optionally supported. See
468 * the `{@link #extendedFormats}` configuration parameter for more
469 * information about how to enable these conversion specifiers.
470 *
471 * @p(dlist)
472 * - `f`
473 * decimal floating point.
474 * - `$`
475 * non-ANSI conversion prefix. This prefix indicates that the
476 * next character identifies a non-ANSI standard conversion. See
477 * the next section for details.
478 * @p
479 *
480 * @a(Non ANSI Conversion Specifiers)
481 * Among the extended conversion specifiers are unique specifiers which
482 * are not part of ANSI printf. These are specified using a $, for
483 * example %$L.
484 *
485 * These unique specifiers do not support the minimum field width
486 * attribute. Certain specifiers have additional restrictions; see below.
487 *
488 * @p(dlist)
489 * - '$L'
490 * The argument is treated as a pointer to a `{@link Types#Label}`
491 * and is converted to an appropriate string.
492 * - '$F'
493 * Displays a file and line number; used for displaying the call
494 * site. This specifier consumes two arguments, the file and line
495 * number, in that order. See an example below.
496 * - '$S'
497 * The argument is treated as a format string, and is recursively
498 * formatted using any following arguments. This specifier does
499 * not support the use of the "precision" field for specifying
500 * maximum string length.
501 * @p
502 *
503 * The following are example uses of the %$F and %$S format specifiers.
504 *
505 * In this call using %$F, the compiler recognizes these symbols and
506 * fills in the file and line number.
507 * @p(code)
508 * System_printf("%$F", __FILE__, __LINE__);
509 * @p
510 * This call outputs, for example,
511 * @p(code)
512 * "MyCode.c", line 35:
513 * @p
514 * Here is an example using %$S, passing a recursive format string.
515 * @p(code)
516 * System_printf("Msg: %$S", "My msg, code: %d", 5);
517 * @p
518 * This outputs:
519 * @p(code)
520 * Msg: My msg, code: 5
521 * @p
522 *
523 * @param(fmt) a 'printf-style' format string
524 *
525 * @a(returns)
526 * `printf` returns the number of characters printed.
527 */
528
529 Int printf(CString fmt, ...);
530
531 /*!
532 * ======== aprintf ========
533 * `{@link #printf}` where all optional arguments are `IArg`s
534 *
535 * This function will treat each argument as though it was widened to be
536 * of type `IArg` prior to being passed to the `{@link #printf}` function
537 *
538 * @see #printf
539 */
540
541 Int aprintf(CString fmt, ...);
542
543 /*!
544 * ======== sprintf ========
545 * Write formated output to a character buffer
546 *
547 * This function is identical to `{@link #printf}` except that the
548 * output is copied to the specified character buffer `buf` followed
549 * by a terminating '\0' character.
550 *
551 * @param(buf) a character output buffer
552 * @param(fmt) a 'printf-style' format string
553 *
554 * @a(returns)
555 * `sprintf` returns the number of characters output not including the
556 * '\0' termination character.
557 */
558
559 Int sprintf(Char buf[], CString fmt, ...);
560
561 /*!
562 * ======== asprintf ========
563 * `{@link #sprintf}` where all optional arguments are `IArg`s
564 *
565 * This function will treat each argument as though it was widened to be
566 * of type `IArg` prior to being passed to the `{@link #sprintf}`
567 * function.
568 *
569 * @see #sprintf
570 */
571
572 Int asprintf(Char buf[], CString fmt, ...);
573
574 /*!
575 * ======== vprintf ========
576 * A VaList printf
577 *
578 * This function is identical to `{@link #printf}` except that its
579 * arguments are passed via a VaList (a "varargs list").
580 *
581 * @param(fmt) a standard 'printf-style' format string.
582 * @param(va) an args list that points to the arguments referenced
583 * by the fmt string
584 *
585 * @a(returns)
586 * `vprintf` returns the number of characters output.
587 */
588
589 Int vprintf(CString fmt, VaList va);
590
591 /*!
592 * ======== avprintf ========
593 * `{@link #vprintf}` where all optional arguments are `IArg`s
594 *
595 * This function will treat each argument as though it was widened to be
596 * of type `IArg` prior to being passed to the `{@link #vprintf}`
597 * function.
598 *
599 * @see #vprintf
600 */
601
602 Int avprintf(CString fmt, VaList va);
603
604 /*!
605 * ======== vsprintf ========
606 * A `VaList` sprintf
607 *
608 * This function is identical to `{@link #sprintf}` except that
609 * its arguments are passed via a `VaList` (a "varargs list").
610 *
611 * @param(buf) a character output buffer
612 * @param(fmt) a standard '`printf`-style' format string.
613 * @param(va) an arguments list that points to the arguments referenced
614 * by the `fmt` string
615 *
616 * @a(returns)
617 * `vsprintf` returns the number of characters output.
618 */
619
620 Int vsprintf(Char buf[], CString fmt, VaList va);
621
622 /*!
623 * ======== avsprintf ========
624 * `{@link #vsprintf}` where all optional arguments are `IArg`s
625 *
626 * This function is identical to `{@link #sprintf}` except that
627 * its arguments are passed via a `VaList` (a "varargs list").
628 *
629 * This function will treat each argument as though it was widened to be
630 * of type `IArg` prior to being passed to the `vsprintf` function
631 *
632 * @see #vsprintf
633 */
634
635 Int avsprintf(Char buf[], CString fmt, VaList va);
636
637 /*!
638 * ======== snprintf ========
639 * Write formated output to a character buffer
640 *
641 * This function is identical to `{@link #sprintf}` except that at most
642 * `n` characters are copied to the specified character buffer `buf`.
643 * If n is zero, nothing is written to character buffer. Otherwise,
644 * output characters beyond the `n` - 1 are discarded rather than
645 * being written to the character buf, and a null character is written
646 * at the end of the characters written into the buffer.
647 *
648 * @param(buf) a character output buffer
649 * @param(n) the maximum number of characters, including '\0', written to
650 * the output buffer `buf`
651 * @param(fmt) a 'printf-style' format string
652 *
653 * @a(returns)
654 * `snprintf` returns the number of characters that would have been
655 * written had `n` been sufficiently large, not counting the terminating
656 * '\0' character. However, if extended conversion specifiers are used
657 * (@see #printf), the return value may be lower than the number of
658 * characters that would be written had `n` been sufficiently large.
659 */
660
661 Int snprintf(Char buf[], SizeT n, CString fmt, ...);
662
663 /*!
664 * ======== vsnprintf ========
665 * A `VaList` snprintf
666 *
667 * This function is identical to `{@link #snprintf}` except that
668 * its arguments are passed via a `VaList` (a "varargs list").
669 *
670 * @param(buf) a character output buffer
671 * @param(n) at most number of characters including '\0' written to
672 * output buffer
673 * @param(fmt) a standard '`printf`-style' format string.
674 * @param(va) an arguments list that points to the arguments referenced
675 * by the `fmt` string
676 *
677 * @a(returns)
678 * `vsnprintf` returns the number of characters that would have been
679 * written had `n` been sufficiently large, not counting the terminating
680 * '\0' character. However, if extended conversion specifiers are used
681 * (@see #printf), the return value may be lower than the number of
682 * characters that would be written had `n` been sufficiently large.
683 */
684
685 Int vsnprintf(Char buf[], SizeT n, CString fmt, VaList va);
686
687 internal:
688
689 /*! struct used to keep track of state during doPrint */
690 struct ParseData {
691 Int width;
692 Bool lFlag;
693 Bool lJust;
694 Int precis;
695 UInt len;
696 Int zpad;
697 Char *end;
698 Bool aFlag;
699 Char *ptr;
700 };
701
702 /*! typedef for generated functions to process extended formats */
703 typedef Int (*ExtendFxn)(Char **, CString *, VaList *, ParseData *);
704
705 /*! config parameter used to call generated function */
706 readonly config ExtendFxn extendFxn = '&xdc_runtime_System_printfExtend__I';
707
708 709 710 711 712 713 714 715 716 717
718 Int printfExtend (Char **bufp, CString *fmt, VaList *va, ParseData *parse);
719
720 /*!
721 * ======== exitFxns ========
722 * @_nodoc
723 * List of functions statically plugged to be called at exit
724 *
725 */
726 metaonly config AtexitHandler exitFxns[];
727
728 /*!
729 * ======== mprintf ========
730 * @_nodoc
731 */
732 function mprintf(fmt, args);
733
734 /*!
735 * ======== doPrint ========
736 * @_nodoc
737 */
738 Int doPrint(Char buf[], SizeT n, CString fmt, VaList *pva, Bool aFlag);
739
740 /*!
741 * ======== lastFxn ========
742 * @_nodoc
743 *
744 * Calls atexit() after all other modules have been initialized
745 * This used to be done in System_Module_startup() but this caused
746 * problems since atexit() uses a heap which isn't necessarily
747 * initialized.
748 */
749 Void lastFxn();
750
751 /*!
752 * ======== putchar ========
753 * @_nodoc
754 *
755 * Write character ch to the buffer and, if the buffer pointer is
756 * non-`NULL`, update the buffer pointer.
757 *
758 * Keeps track of the number of characters written into the buffer by
759 * modifying bufsize `n`. Atmost, `n` - 1 characters are written.
760 */
761 Void putchar(Char **bufp, Char ch, SizeT *n);
762
763 /*!
764 * ======== rtsExit ========
765 * @_nodoc
766 */
767 Void rtsExit();
768
769 /*!
770 * ======== atexitDone ========
771 * @_nodoc
772 */
773 Bool atexitDone();
774
775 /*!
776 * ======== Module_State ========
777 * @_nodoc
778 */
779 struct Module_State {
780 AtexitHandler atexitHandlers[];
781 Int numAtexitHandlers;
782 };
783 }
784 785 786
787