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