Subversion Repositories Kolibri OS

Rev

Rev 6536 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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 
16
 
6068 serge 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;
6074 serge 27
    int    __subsystem__;
6068 serge 28
};
4349 Serge 29
 
6664 serge 30
extern void init_global_reent();
6536 serge 31
extern void init_stdio();
32
extern void __init_conio();
33
extern void __fini_conio();
6074 serge 34
 
6536 serge 35
extern void tls_init(void);
6068 serge 36
extern int main (int, char **, char **);
4349 Serge 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
 
6068 serge 44
char* __appenv;
45
int   __appenv_size;
4349 Serge 46
 
6068 serge 47
char * __libc_getenv(const char *name)
48
{
49
    return NULL;
50
}
4349 Serge 51
 
6068 serge 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
    };
4349 Serge 60
 
6068 serge 61
    enum quote_state state;
62
    unsigned int argc;
63
    char *p = cmdline;
64
    char *new_arg, *start;
4349 Serge 65
 
6068 serge 66
    argc = 0;
4349 Serge 67
 
6068 serge 68
    for(;;)
69
    {
70
        /* skip over spaces and tabs */
71
        if ( *p )
72
        {
73
            while (*p == ' ' || *p == '\t')
74
                ++p;
75
        }
4349 Serge 76
 
6068 serge 77
        if (*p == '\0')
78
            break;
4349 Serge 79
 
6068 serge 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
            }
4349 Serge 102
 
6068 serge 103
            if( *p == ' ' || *p == '\t' )
104
            {
105
                if( state == QUOTE_NONE )
106
                {
107
                    break;
108
                }
109
            }
4349 Serge 110
 
6068 serge 111
            if( *p == '\0' )
112
                break;
4349 Serge 113
 
6068 serge 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
        }
4349 Serge 161
    }
162
 
6068 serge 163
    return argc;
164
};
165
 
4349 Serge 166
void  __attribute__((noreturn))
6536 serge 167
__libc_init (void)
4349 Serge 168
{
6068 serge 169
    struct   app_hdr *header = NULL;
170
    int retval = 0;
4349 Serge 171
 
6068 serge 172
    char **argv;
173
    int    argc;
4349 Serge 174
 
6536 serge 175
    tls_init();
6664 serge 176
    init_global_reent();
6068 serge 177
    init_stdio();
4349 Serge 178
 
6074 serge 179
    if(header->__subsystem__ == 3)
180
        __init_conio();
4349 Serge 181
 
6068 serge 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;
4349 Serge 187
 
6068 serge 188
        split_cmdline(header->cmdline, argv + 1);
189
    }
190
    else
4349 Serge 191
    {
6068 serge 192
        argc = 1;
193
        argv = alloca((argc+1)*sizeof(char*));
194
        argv[0] = header->path;
195
    }
196
    argv[argc] = NULL;
4349 Serge 197
 
6068 serge 198
    retval = main(argc, argv, NULL);
199
done:
6074 serge 200
    if(header->__subsystem__ == 3)
201
        __fini_conio();
202
 
6068 serge 203
    exit (retval);
4349 Serge 204
}
205