1 /*
2 * Copyright (c) 2008 Texas Instruments. All rights reserved.
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 * ======== System.xdc ========
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 metaonlystruct 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 metaonlyconfig 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; /* width in format specifier */
444 Bool lFlag; /* length modifier flag */
445 Bool lJust; /* left justify flag */
446 Int precis; /* precision in format specifier */
447 Int len; /* length of formatted number */
448 Int zpad; /* leading zero pad flag */
449 Char *end; /* pointer to end of local buf to hold num */
450 Bool aFlag; /* deal with vars on stack as IArgs */
451 Char *ptr; /* ptr to local buf after filling in num */
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 readonlyconfig ExtendFxn extendFxn = '&xdc_runtime_System_printfExtend__I';
459
460 /*
461 * ======== printfExtend ========
462 * System_printfExtend is generated based on extendedFormats string
463 *
464 * This generated function is accessed through an internal config so
465 * that it is an indirect call in the ROM case, but optimized to a direct
466 * call in the RAM case.
467 *
468 * @_nodoc
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 metaonlyconfig 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[]; /* array of atexit handlers */
521 Int numAtexitHandlers; /* Current num of atexit handlers */
522 Int exitStatus; /* status for exit handlers */
523 };
524 }
525 /*
526 * @(#) xdc.runtime; 2, 0, 0, 0,207; 6-9-2009 20:10:19; /db/ztree/library/trees/xdc-t50x/src/packages/
527 */
528