Subversion Repositories Kolibri OS

Rev

Rev 5198 | Rev 6074 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.  * crt1.c
  3.  * This file has no copyright assigned and is placed in the Public Domain.
  4.  * This file is a part of the mingw-runtime package.
  5.  * No warranty is given; refer to the file DISCLAIMER within the package.
  6.  *
  7.  * Source code for the startup proceedures used by all programs. This code
  8.  * is compiled to make crt1.o, which should be located in the library path.
  9.  *
  10.  */
  11.  
  12. /* Hide the declaration of _fmode with dllimport attribute in stdlib.h to
  13.    avoid problems with older GCC. */
  14.  
  15. #include <newlib.h>
  16. #include <stdint.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <stdio.h>
  20. #include <sys/kos_io.h>
  21.  
  22. struct app_hdr
  23. {
  24.     char  banner[8];
  25.     int   version;
  26.     int   start;
  27.     int   iend;
  28.     int   memsize;
  29.     int   stacktop;
  30.     char  *cmdline;
  31.     char  *path;
  32. };
  33.  
  34. extern int main (int, char **, char **);
  35.  
  36. /* NOTE: The code for initializing the _argv, _argc, and environ variables
  37.  *       has been moved to a separate .c file which is included in both
  38.  *       crt1.c and dllcrt1.c. This means changes in the code don't have to
  39.  *       be manually synchronized, but it does lead to this not-generally-
  40.  *       a-good-idea use of include. */
  41.  
  42. char* __appenv;
  43. int   __appenv_size;
  44.  
  45. extern char _tls_map[128];
  46.  
  47. char * __libc_getenv(const char *name)
  48. {
  49.     return NULL;
  50. }
  51.  
  52. static int split_cmdline(char *cmdline, char **argv)
  53. {
  54.     enum quote_state
  55.     {
  56.         QUOTE_NONE,         /* no " active in current parm       */
  57.         QUOTE_DELIMITER,    /* " was first char and must be last */
  58.         QUOTE_STARTED       /* " was seen, look for a match      */
  59.     };
  60.  
  61.     enum quote_state state;
  62.     unsigned int argc;
  63.     char *p = cmdline;
  64.     char *new_arg, *start;
  65.  
  66.     argc = 0;
  67.  
  68.     for(;;)
  69.     {
  70.         /* skip over spaces and tabs */
  71.         if ( *p )
  72.         {
  73.             while (*p == ' ' || *p == '\t')
  74.                 ++p;
  75.         }
  76.  
  77.         if (*p == '\0')
  78.             break;
  79.  
  80.         state = QUOTE_NONE;
  81.         if( *p == '\"' )
  82.         {
  83.             p++;
  84.             state = QUOTE_DELIMITER;
  85.         }
  86.         new_arg = start = p;
  87.         for (;;)
  88.         {
  89.             if( *p == '\"' )
  90.             {
  91.                 p++;
  92.                 if( state == QUOTE_NONE )
  93.                 {
  94.                     state = QUOTE_STARTED;
  95.                 }
  96.                 else
  97.                 {
  98.                     state = QUOTE_NONE;
  99.                 }
  100.                 continue;
  101.             }
  102.  
  103.             if( *p == ' ' || *p == '\t' )
  104.             {
  105.                 if( state == QUOTE_NONE )
  106.                 {
  107.                     break;
  108.                 }
  109.             }
  110.  
  111.             if( *p == '\0' )
  112.                 break;
  113.  
  114.             if( *p == '\\' )
  115.             {
  116.                 if( p[1] == '\"' )
  117.                 {
  118.                     ++p;
  119.                     if( p[-2] == '\\' )
  120.                     {
  121.                         continue;
  122.                     }
  123.                 }
  124.             }
  125.             if( argv )
  126.             {
  127.                 *(new_arg++) = *p;
  128.             }
  129.             ++p;
  130.         };
  131.  
  132.         if( argv )
  133.         {
  134.             argv[ argc ] = start;
  135.             ++argc;
  136.  
  137.             /*
  138.               The *new = '\0' is req'd in case there was a \" to "
  139.               translation. It must be after the *p check against
  140.               '\0' because new and p could point to the same char
  141.               in which case the scan would be terminated too soon.
  142.             */
  143.  
  144.             if( *p == '\0' )
  145.             {
  146.                 *new_arg = '\0';
  147.                 break;
  148.             }
  149.             *new_arg = '\0';
  150.             ++p;
  151.         }
  152.         else
  153.         {
  154.             ++argc;
  155.             if( *p == '\0' )
  156.             {
  157.                 break;
  158.             }
  159.             ++p;
  160.         }
  161.     }
  162.  
  163.     return argc;
  164. };
  165.  
  166. void  __attribute__((noreturn))
  167. __crt_startup (void)
  168. {
  169.     struct   app_hdr *header = NULL;
  170.     int retval = 0;
  171.  
  172.     char **argv;
  173.     int    argc;
  174.  
  175.     memset(_tls_map, 0xFF, 32*4);
  176.     _tls_map[0] = 0xE0;
  177.     init_reent();
  178.     init_stdio();
  179.  
  180.  
  181.     if( header->cmdline[0] != 0)
  182.     {
  183.         argc = split_cmdline(header->cmdline, NULL) + 1;
  184.         argv = alloca((argc+1)*sizeof(char*));
  185.         argv[0] = header->path;
  186.  
  187.         split_cmdline(header->cmdline, argv + 1);
  188.     }
  189.     else
  190.     {
  191.         argc = 1;
  192.         argv = alloca((argc+1)*sizeof(char*));
  193.         argv[0] = header->path;
  194.     }
  195.     argv[argc] = NULL;
  196.  
  197.     retval = main(argc, argv, NULL);
  198. done:
  199.     exit (retval);
  200. }
  201.  
  202.