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