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