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