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    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         *  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        /*!
    67         *  ======== AbortFxn ========
    68         *  System abort function prototype.
    69         *
    70         *  Fuctions of this type can be plugged in to `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         *  Fuctions of this type can be plugged in to `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        metaonly config String extendedFormats = "%$L%$S%$F";
   169    
   170        /*!
   171         *  ======== SupportProxy ========
   172         *  The implementation module of the low-level system functions.
   173         *
   174         *  This configuration parameter allows one to "bind" a different
   175         *  implementation of the low-level services required to implement
   176         *  `System`.
   177         *  @p(code)
   178         *      var System = xdc.useModule("xdc.runtime.System");
   179         *      var SysStd = xdc.useModule("xdc.runtime.SysStd");
   180         *      System.SupportProxy = SysStd;
   181         *  @p
   182         *
   183         *  If this parameter is not set, it defaults to `{@link SysMin}`.
   184         */
   185        proxy SupportProxy inherits ISystemSupport;
   186    
   187        /*!
   188         *  ======== maxAtexitHandlers ========
   189         *  Maximum number of dynamic atexit handlers allowed in the system.
   190         *
   191         *  Maximum number of `System` `atexit` handlers set during runtime via
   192         *  the `{@link System#atexit}` function.
   193         *
   194         */
   195        config Int maxAtexitHandlers = 8;
   196    
   197        /*!
   198         *  ======== abortFxn ========
   199         *  Abort handler function
   200         *
   201         *  This configuration parameter allows user to plug in their own abort
   202         *  function. By default `{@link #abortStd}` which calls ANSI C Standard 
   203         *  `abort()` is plugged in. Alternatively `{@link #abortSpin}` can be 
   204         *  plugged which loops infinitely.
   205         *
   206         */
   207        config AbortFxn abortFxn = System.abortStd;
   208    
   209        /*!
   210         *  ======== exitFxn ========
   211         *  Exit handler function
   212         *
   213         *  This configuration parameter allows user to plug in their own exit
   214         *  function. By default `{@link #exitStd}` which calls ANSI C Standard 
   215         *  `exit()` is plugged in. Alternatively `{@link #exitSpin}` can be 
   216         *  plugged which loops infinitely.
   217         *
   218         */
   219        config ExitFxn exitFxn = System.exitStd;
   220    
   221        /*!
   222         *  ======== abort ========
   223         *  Print a message and abort currently running executable.
   224         *
   225         *  This is called when an executable abnormally terminates.  
   226         *  The `System` gate is entered, the 
   227         *  `{@link #SupportProxy}`'s `abort` function is called
   228         *  and then `{@link #abortFxn}` is called.
   229         *  No exit functions bound via `System_atexit()` or the ANSI C Standard
   230         *  Library `atexit()` functions are executed. 
   231         *
   232         *  @param(str) abort message (not a format string)
   233         */
   234        Void abort(CString str);
   235    
   236        /*!
   237         *  ======== abortStd ========
   238         *  ANSI C Standard implementation of abortFxn function
   239         *
   240         *  This function calls ANSI C Standard `abort()` to terminate currently 
   241         *  running executable. This function is used by default in 
   242         *  `{@link #abortFxn}`. 
   243         *
   244         */
   245        Void abortStd();
   246    
   247        /*!
   248         *  ======== abortSpin ========
   249         *  LIghtweight implementation of abortFxn function
   250         *
   251         *  This functions loops indefinitely. This can used as an alternative
   252         *  `{@link #abortFxn}` when a lightweight implementation is 
   253         *  required instead of the ANSI C Standard `abort()`.
   254         *
   255         */
   256        Void abortSpin();
   257    
   258        /*!
   259         *  ======== atexit ========
   260         *  Add an exit handler
   261         *
   262         *  `System_atexit` pushes `handler` onto an internal stack of functions 
   263         *  to be executed when system is exiting (e.g. `System_exit` is called).
   264         *  Up to `{@link #maxAtexitHandlers}` functions can be specified in this
   265         *  manner.  During the exit processing, the functions are popped off the
   266         *  internal stack and called until the stack is empty.
   267         *
   268         *  The `System` gate is entered before the `System_atexit` functions 
   269         *  are called.
   270         *
   271         *  The `SupportProxy`'s `{@link ISystemSupport#exit}` function is called
   272         *  after all the atexit functions are called.
   273         *
   274         *  @param(handler) the `AtexitHandler` to invoke during system
   275         *                  exit processing.
   276         *
   277         *  @a(returns)
   278         *  If `FALSE` is returned, the exit handler was not added and it will
   279         *  not be called during an exit.
   280         */
   281        Bool atexit(AtexitHandler handler);
   282    
   283        /*!
   284         *  ======== atexitMeta ========     
   285         *  Add an exit handler during configuration
   286         *
   287         *  This is the static counterpart to `System_atexit()`. This method can
   288         *  be used to add `atexit` handlers at configuration time.  These
   289         *  handlers do not count against the `maxAtexitHandlers`.
   290         *
   291         *  @param(handler) the `AtexitHandler` to invoke during system
   292         *                  exit processing.
   293         */
   294        metaonly Void atexitMeta(AtexitHandler handler);
   295    
   296        /*!
   297         *  ======== exit ========
   298         *  Exit currently running executable.
   299         *
   300         *  This function is called when an executable needs to terminate
   301         *  normally.  This function processes all functions bound via 
   302         *  `System_atexit` and then calls `{@link #exitFxn}`. The 
   303         *  `{@link #SupportProxy}`'s `exit` function is called during this time.
   304         *
   305         *  @param(stat)    exit status to return to calling environment.
   306         */
   307        Void exit(Int stat);
   308    
   309        /*!
   310         *  ======== exitStd ========
   311         *  Implements an `exitFxn` function
   312         *
   313         *  This function calls ANSI C Standard `exit()` to terminate currently 
   314         *  running executable normally. This function is used by default in 
   315         *  `{@link #exitFxn}`. 
   316         *
   317         *  @param(stat)    exit status to return to calling environment.
   318         */
   319        Void exitStd(Int stat);
   320    
   321        /*!
   322         *  ======== exitSpin ========
   323         *  Implements an `exitFxn` function
   324         *
   325         *  This functions loops indefinitely. This can used as an alternative
   326         *  `{@link #exitFxn}` when a light weight implementation is 
   327         *  required instead of the ANSI C Standard `exit()`.
   328         *
   329         *  @param(stat)    exit status to return to calling environment.
   330         */
   331        Void exitSpin(Int stat);
   332    
   333        /*!
   334         *  ======== processAtExit ========
   335         *  Processes all functions bound via `System_atexit`
   336         *
   337         *  This function is called by `System_exit` to process all functions
   338         *  bound via `System_atexit`. User can add this to ANSI C standard
   339         *  `atexit` function so that all functions bound via `System_atexit` are
   340         *  processed when ANSI C standard `exit` function is called.
   341         *
   342         *  @param(stat)    exit status which will passed to all functions 
   343         *                  processed.
   344         */
   345        Void processAtExit(Int stat);
   346    
   347        /*!
   348         *  ======== putch ========
   349         *  Output a single character
   350         *
   351         *  The `{@link #SupportProxy}`'s `putch` function is called
   352         *  by this function.
   353         *
   354         *  @param(ch) character to be output.
   355         */
   356        Void putch(Char ch);
   357    
   358        /*!
   359         *  ======== flush ========
   360         *  Flush standard System I/O     
   361         *
   362         *  This function causes any buffered output characters are "written"
   363         *  to the output device.
   364         *
   365         *  The `{@link #SupportProxy}`'s `flush` function is called
   366         *  by this function.
   367         */
   368        Void flush();
   369    
   370        /*!
   371         *  ======== printf ========
   372         *  A smaller faster printf
   373         *
   374         *  This function behaves much like the ANSI C Standard `printf`
   375         *  but does not support the full range of format strings specified by
   376         *  the C Standard.  In addition, several non-standard format specifiers
   377         *  are recognized.
   378         *
   379         *  @a(Format Strings)
   380         *  The format string is a character string composed of zero or
   381         *  more directives: ordinary characters (not %), which are copied
   382         *  unchanged to the output stream; and conversion specifications, each of
   383         *  which results in fetching zero or more subsequent arguments.  Each
   384         *  conversion specification is introduced by the character %, and ends
   385         *  with a conversion specifier.  In between there may be (in this order)
   386         *  zero or more flags, an optional minimum field width, an optional
   387         *  precision and an optional length modifier.
   388         *
   389         *  @a(Flags)
   390         *  The following flags are supported:
   391         *  @p(dlist)
   392         *      - `-`
   393         *          The converted value is to be left adjusted on the field
   394         *          boundary (the default is right justification.)
   395         *      - `0`
   396         *          The value should be zero padded. For d, i, o, u, and x
   397         *          conversions, the converted value is padded on the left
   398         *          with zeros rather than blanks.
   399         *  @p
   400         *
   401         *  @a(Field Width)
   402         *  The optional field width specifier is a decimal digit string (with
   403         *  nonzero first digit) specifying a minimum field width. If the
   404         *  converted value has fewer characters than the field width, it will
   405         *  be padded with spaces on the left (or right, if the left-adjustment
   406         *  flag has been given).  Instead of a decimal digit string one may
   407         *  write `*` to specify that the field width is given in the next
   408         *  argument.  A negative field width is taken as a '-' flag followed
   409         *  by a positive field width.
   410         *
   411         *  @a(Precision)
   412         *  The optional precision specifier is a period ('.') followed by an
   413         *  optional decimal digit string.  Instead of a decimal digit string
   414         *  one may write `*` to specify that the precision is given in the 
   415         *  next argument which must be of type int.
   416         *
   417         *  If the precision is given as just '.', or the precision is
   418         *  negative, the precision is taken to be zero.  This gives the
   419         *  minimum number of digits to appear for d, i, o, u, and x
   420         *  conversions, or the maximum number of characters to be printed from
   421         *  a string for s conversions.
   422         *
   423         *  @a(Length Modifiers)
   424         *  The optional length modifier is a single character from the following
   425         *  list.
   426         *  @p(dlist)
   427         *      - `l`
   428         *          A  following integer conversion corresponds to a long int
   429         *          or unsigned long int argument
   430         *
   431         *  @p
   432         *
   433         *  @a(Conversion Specifiers)
   434         *  The following conversion specifiers are supported.
   435         *  @p(dlist)
   436         *      - `d`, `i`
   437         *          signed integer
   438         *      - `u`
   439         *          unsigned decimal
   440         *      - `x`
   441         *          unsigned hex
   442         *      - `o`
   443         *          unsigned octal
   444         *      - `p`
   445         *          pointer (@ + hex num)
   446         *      - `c`
   447         *          character
   448         *      - `s`
   449         *          string
   450         *  @p
   451         *  @a(Extended Conversion Specifiers)
   452         *  The following conversion specifiers are optionally supported.  See
   453         *  the `{@link #extendedFormats}` configuration parameter for more
   454         *  information about how to enable these conversion specifiers.
   455         *
   456         *  @p(dlist)
   457         *      - `f`
   458         *          decimal floating point.
   459         *      - `$`
   460         *          non-ANSI conversion prefix.  This prefix indicates that the
   461         *          next character identifies a non-ANSI standard conversion. See
   462         *          the next section for details.
   463         *  @p
   464         *
   465         *  @a(Non ANSI Conversion Specifiers)
   466         *  Among the extended conversion specifiers are unique specifiers which
   467         *  are not part of ANSI printf. These are specified using a $, for 
   468         *  example %$L.
   469         *
   470         *  These unique specifiers do not support the minimum field width
   471         *  attribute. Certain specifiers have additional restrictions; see below.
   472         *  
   473         *  @p(dlist)
   474         *      - '$L'
   475         *          The argument is treated as a pointer to a `{@link Types#Label}`
   476         *          and is converted to an appropriate string.
   477         *      - '$F'
   478         *          Displays a file and line number; used for displaying the call 
   479         *          site. This specifier consumes two arguments, the file and line 
   480         *          number, in that order. See an example below.
   481         *      - '$S'
   482         *          The argument is treated as a format string, and is recursively
   483         *          formatted using any following arguments. This specifier does 
   484         *          not support the use of the "precision" field for specifying 
   485         *          maximum string length.
   486         *  @p
   487         * 
   488         *  The following are example uses of the %$F and %$S format specifiers.
   489         *  
   490         *  In this call using %$F, the compiler recognizes these symbols and
   491         *  fills in the file and line number.
   492         *  @p(code)
   493         *  System_printf("%$F", __FILE__, __LINE__);
   494         *  @p
   495         *  This call outputs, for example,
   496         *  @p(code)
   497         *  "MyCode.c", line 35: 
   498         *  @p
   499         *  Here is an example using %$S, passing a recursive format string.
   500         *  @p(code)
   501         *  System_printf("Msg: %$S", "My msg, code: %d", 5);
   502         *  @p
   503         *  This outputs:
   504         *  @p(code)
   505         *  Msg: My msg, code: 5
   506         *  @p
   507         *
   508         *  @param(fmt) a 'printf-style' format string
   509         *
   510         *  @a(returns)
   511         *  `printf` returns the number of characters printed.
   512         */
   513        Int printf(CString fmt, ...);
   514    
   515        /*!
   516         *  ======== aprintf ========
   517         *  `{@link #printf}` where all optional arguments are `IArg`s
   518         *
   519         *  This function will treat each argument as though it was widened to be 
   520         *  of type `IArg` prior to being passed to the `{@link #printf}` function
   521         *
   522         *  @see #printf
   523         */
   524        Int aprintf(CString fmt, ...);
   525    
   526        /*!
   527         *  ======== sprintf ========
   528         *  Write formated output to a character buffer
   529         *
   530         *  This function is identical to `{@link #printf}` except that the
   531         *  output is copied to the specified character buffer `buf` followed
   532         *  by a terminating '\0' character.
   533         *
   534         *  @param(buf) a character output buffer
   535         *  @param(fmt) a 'printf-style' format string
   536         *
   537         *  @a(returns)
   538         *  `sprintf` returns the number of characters output not including the
   539         *  '\0' termination character.
   540         */
   541        Int sprintf(Char buf[], CString fmt, ...);
   542    
   543        /*!
   544         *  ======== asprintf ========
   545         *  `{@link #sprintf}` where all optional arguments are `IArg`s
   546         *
   547         *  This function will treat each argument as though it was widened to be 
   548         *  of type `IArg` prior to being passed to the `{@link #sprintf}`
   549         *  function.
   550         *
   551         *  @see #sprintf
   552         */
   553        Int asprintf(Char buf[], CString fmt, ...);
   554    
   555        /*!
   556         *  ======== vprintf ========
   557         *  A VaList printf
   558         *
   559         *  This function is identical to `{@link #printf}` except that its
   560         *  arguments are passed via a VaList (a "varargs list").
   561         *
   562         *  @param(fmt) a standard 'printf-style' format string.
   563         *  @param(va)  an args list that points to the arguments referenced
   564         *              by the fmt string
   565         *
   566         *  @a(returns)
   567         *  `vprintf` returns the number of characters output.
   568         */
   569        Int vprintf(CString fmt, VaList va);
   570    
   571        /*!
   572         *  ======== avprintf ========
   573         *  `{@link #vprintf}` where all optional arguments are `IArg`s
   574         *
   575         *  This function will treat each argument as though it was widened to be 
   576         *  of type `IArg` prior to being passed to the `{@link #vprintf}`
   577         *  function.
   578         *
   579         *  @see #vprintf
   580         */
   581        Int avprintf(CString fmt, VaList va);
   582    
   583        /*!
   584         *  ======== vsprintf ========
   585         *  A `VaList` sprintf
   586         *
   587         *  This function is identical to `{@link #sprintf}` except that 
   588         *  its arguments are passed via a `VaList` (a "varargs list").
   589         *
   590         *  @param(buf) a character output buffer
   591         *  @param(fmt) a standard '`printf`-style' format string.
   592         *  @param(va)  an arguments list that points to the arguments referenced
   593         *              by the `fmt` string
   594         *
   595         *  @a(returns)
   596         *  `vsprintf` returns the number of characters output.
   597         */
   598        Int vsprintf(Char buf[], CString fmt, VaList va);
   599    
   600        /*!
   601         *  ======== avsprintf ========
   602         *  `{@link #vsprintf}` where all optional arguments are `IArg`s
   603         *
   604         *  This function is identical to `{@link #sprintf}` except that 
   605         *  its arguments are passed via a `VaList` (a "varargs list").
   606         *
   607         *  This function will treat each argument as though it was widened to be 
   608         *  of type `IArg` prior to being passed to the `vsprintf` function
   609         *
   610         *  @see #vsprintf
   611         */
   612        Int avsprintf(Char buf[], CString fmt, VaList va);
   613        
   614        /*!
   615         *  ======== snprintf ========
   616         *  Write formated output to a character buffer
   617         *
   618         *  This function is identical to `{@link #sprintf}` except that atmost
   619         *  `n` characters is copied to the specified character buffer `buf` 
   620         *  If n is zero, nothing is written to character buffer. Otherwise,
   621         *  output characters beyond the `n` - 1 are discarded rather than
   622         *  being written to the character buf, and a null character is written 
   623         *  at the end of the characters actually written into the buffer.
   624         *
   625         *  @param(buf) a character output buffer
   626         *  @param(n)   the maximum number of characters, including '\0', written to
   627         *              the output buffer `buf`
   628         *  @param(fmt) a 'printf-style' format string
   629         *
   630         *  @a(returns)
   631         *  `snprintf` returns the number of characters returns the number of 
   632         *  characters that would have been written had `n` been sufficiently 
   633         *  large, not counting the terminating '\0' character.
   634         */
   635        Int snprintf(Char buf[], SizeT n, CString fmt, ...);
   636        
   637        /*!
   638         *  ======== vsnprintf ========
   639         *  A `VaList` snprintf
   640         *
   641         *  This function is identical to `{@link #snprintf}` except that 
   642         *  its arguments are passed via a `VaList` (a "varargs list").
   643         *
   644         *  @param(buf) a character output buffer
   645         *  @param(n)   at most number of characters including '\0' written to
   646         *              output buffer
   647         *  @param(fmt) a standard '`printf`-style' format string.
   648         *  @param(va)  an arguments list that points to the arguments referenced
   649         *              by the `fmt` string
   650         *
   651         *  @a(returns)
   652         *  `vsnprintf` returns the number of characters that would have been
   653         *  written had `n` been sufficiently large, not counting the terminating
   654         *  '\0' character.
   655         */
   656        Int vsnprintf(Char buf[], SizeT n, CString fmt, VaList va);
   657            
   658    internal:
   659    
   660        /*! struct used to keep track of state during doPrint */
   661        struct ParseData {
   662            Int     width;      /* width in format specifier */
   663            Bool    lFlag;      /* length modifier flag */
   664            Bool    lJust;      /* left justify flag */
   665            Int     precis;     /* precision in format specifier */
   666            Int     len;        /* length of formatted number */
   667            Int     zpad;       /* leading zero pad flag */
   668            Char    *end;       /* pointer to end of local buf to hold num */
   669            Bool    aFlag;      /* deal with vars on stack as IArgs */
   670            Char    *ptr;       /* ptr to local buf after filling in num */
   671        };
   672    
   673        /*! typedef for generated functions to process extended formats */
   674        typedef Int (*ExtendFxn)(Char **, CString *, VaList *, ParseData *);
   675    
   676        /*! config parameter used to call generated function  */
   677        readonly config ExtendFxn extendFxn = '&xdc_runtime_System_printfExtend__I';
   678        
   679        /*
   680         * ======== printfExtend ======== 
   681         *  System_printfExtend is generated based on extendedFormats string
   682         *
   683         *  This generated function is accessed through an internal config so
   684         *  that it is an indirect call in the ROM case, but optimized to a direct
   685         *  call in the RAM case.
   686         *
   687         * @_nodoc
   688         */
   689        Int printfExtend (Char **bufp, CString *fmt, VaList *va, ParseData *parse);
   690    
   691        /*!
   692         *  ======== exitFxns ========
   693         *  @_nodoc
   694         *  List of functions statically plugged to be called at exit
   695         *
   696         */
   697        metaonly config AtexitHandler exitFxns[];
   698        
   699        /*!
   700         *  ======== mprintf ========     
   701         *  @_nodoc
   702         */
   703        function mprintf(fmt, args);
   704        
   705        /*!
   706         *  ======== doPrint ========
   707         *  @_nodoc
   708         */
   709        Int doPrint(Char buf[], SizeT n, CString fmt, VaList *pva, Bool aFlag);
   710        
   711        /*!
   712         *  ======== formatNum ========
   713         *  @_nodoc
   714         *
   715         */
   716        Char *formatNum(Char *ptr, UInt32 n, Int zpad, Int base);
   717    
   718        /*!
   719         *  ======== lastFxn ========
   720         *  @_nodoc
   721         *
   722         *  Calls atexit() after all other modules have been initialized
   723         *  This used to be done in System_Module_startup() but this caused
   724         *  problems since atexit() uses a heap which isn't necessarily
   725         *  initialized.
   726         */
   727        Void lastFxn();
   728        
   729        /*!
   730         *  ======== putchar ========
   731         *  @_nodoc
   732         *
   733         *  Write character ch to the buffer and, if the buffer pointer is
   734         *  non-`NULL`, update the buffer pointer.
   735         *
   736         *  Keeps track of the number of characters written into the buffer by
   737         *  modifying bufsize `n`. Atmost, `n` - 1 characters are written.  
   738         */
   739        Void putchar(Char **bufp, Char ch, SizeT *n);
   740        
   741        /*!
   742         *  ======== rtsExit ========
   743         *  @_nodoc
   744         */
   745        Void rtsExit();
   746    
   747        /*!
   748         *  ======== atexitDone ========
   749         *  @_nodoc
   750         */
   751        Bool atexitDone();
   752    
   753        /*!
   754         *  ======== Module_State ========
   755         *  @_nodoc
   756         */
   757        struct Module_State {
   758            AtexitHandler  atexitHandlers[];   /* array of atexit handlers       */
   759            Int            numAtexitHandlers;  /* Current num of atexit handlers */
   760        };
   761    }
   762    /*
   763     *  @(#) xdc.runtime; 2, 1, 0,471; 3-20-2014 17:05:47; /db/ztree/library/trees/xdc/xdc-A32x/src/packages/
   764     */
   765