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