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