Subversion Repositories Kolibri OS

Rev

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 <stdlib.h>
  16.  
  17. struct app_hdr
  18. {
  19.     char  banner[8];
  20.     int   version;
  21.     int   start;
  22.     int   iend;
  23.     int   memsize;
  24.     int   stacktop;
  25.     char  *cmdline;
  26.     char  *path;
  27.     int    __subsystem__;
  28. };
  29.  
  30. extern void init_reent();
  31. extern void init_stdio();
  32. extern void __init_conio();
  33. extern void __fini_conio();
  34.  
  35. extern void tls_init(void);
  36. extern int main (int, char **, char **);
  37.  
  38. /* NOTE: The code for initializing the _argv, _argc, and environ variables
  39.  *       has been moved to a separate .c file which is included in both
  40.  *       crt1.c and dllcrt1.c. This means changes in the code don't have to
  41.  *       be manually synchronized, but it does lead to this not-generally-
  42.  *       a-good-idea use of include. */
  43.  
  44. char* __appenv;
  45. int   __appenv_size;
  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. __libc_init (void)
  168. {
  169.     struct   app_hdr *header = NULL;
  170.     int retval = 0;
  171.  
  172.     char **argv;
  173.     int    argc;
  174.  
  175.     tls_init();
  176.     init_reent();
  177.     init_stdio();
  178.  
  179.     if(header->__subsystem__ == 3)
  180.         __init_conio();
  181.  
  182.     if( header->cmdline[0] != 0)
  183.     {
  184.         argc = split_cmdline(header->cmdline, NULL) + 1;
  185.         argv = alloca((argc+1)*sizeof(char*));
  186.         argv[0] = header->path;
  187.  
  188.         split_cmdline(header->cmdline, argv + 1);
  189.     }
  190.     else
  191.     {
  192.         argc = 1;
  193.         argv = alloca((argc+1)*sizeof(char*));
  194.         argv[0] = header->path;
  195.     }
  196.     argv[argc] = NULL;
  197.  
  198.     retval = main(argc, argv, NULL);
  199. done:
  200.     if(header->__subsystem__ == 3)
  201.         __fini_conio();
  202.  
  203.     exit (retval);
  204. }
  205.  
  206.