Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4973 right-hear 1
#include
2
#include
3
 
4
void _exit(int code)
5
{
6
 __asm__ __volatile__("int $0x40"::"a"(-1));
7
 for(;;);
8
}
9
 
10
#include 
11
#include 
12
#include 
13
#include 
14
#include 
15
#include 
16
#include 
17
#include 
18
#include 
19
 
20
#define ds _my_ds()
21
 
22
 
23
extern char __menuet__app_param_area[];
24
extern char __menuet__app_path_area[];
25
 
26
static void * c1xmalloc(size_t s)
27
{
28
 void *q = malloc(s);
29
 if (q == 0)
30
 {
31
#define err(x)
32
  err("No memory to gather arguments\r\n");
33
  _exit(1);
34
 }
35
 return q;
36
}
37
 
38
static int atohex(char *s)
39
{
40
  int rv = 0;
41
  while (*s)
42
  {
43
    int v = *s - '0';
44
    if (v > 9)
45
      v -= 7;
46
    v &= 15; /* in case it's lower case */
47
    rv = rv*16 + v;
48
    s++;
49
  }
50
  return rv;
51
}
52
 
53
typedef struct Arg {
54
  char *arg;
55
  char **arg_globbed;
56
  struct ArgList *arg_file;
57
  struct Arg *next;
58
  int was_quoted;
59
} Arg;
60
 
61
typedef struct ArgList {
62
  int argc;
63
  Arg **argv;
64
} ArgList;
65
 
66
static Arg *new_arg(void)
67
{
68
  Arg *a = (Arg *)c1xmalloc(sizeof(Arg));
69
  memset(a, 0, sizeof(Arg));
70
  return a;
71
}
72
 
73
static void delete_arglist(ArgList *al);
74
 
75
static void delete_arg(Arg *a)
76
{
77
  if (a->arg) free(a->arg);
78
  if (a->arg_globbed)
79
  {
80
    int i;
81
    for (i=0; a->arg_globbed[i]; i++)
82
      free(a->arg_globbed[i]);
83
    free(a->arg_globbed);
84
  }
85
  if (a->arg_file)
86
    delete_arglist(a->arg_file);
87
  free(a);
88
}
89
 
90
static ArgList * new_arglist(int count)
91
{
92
  ArgList *al = (ArgList *)c1xmalloc(sizeof(ArgList));
93
  al->argc = count;
94
  al->argv = (Arg **)c1xmalloc((count+1)*sizeof(Arg *));
95
  memset(al->argv, 0, (count+1)*sizeof(Arg *));
96
  return al;
97
}
98
 
99
static void delete_arglist(ArgList *al)
100
{
101
  int i;
102
  for (i=0; iargc; i++)
103
    delete_arg(al->argv[i]);
104
  free(al->argv);
105
  free(al);
106
}
107
 
108
static char * parse_arg(char *bp, char *last, int unquote, size_t *len, int *was_quoted)
109
{
110
  char *ep = bp, *epp = bp;
111
  int quote=0;
112
 
113
  while ((quote || !isspace(*(unsigned char *)ep)) && ep < last)
114
  {
115
    if (quote && *ep == quote)
116
    {
117
      quote = 0;
118
      if (!unquote)
119
	*epp++ = *ep;
120
      ep++;
121
    }
122
    else if (!quote && (*ep == '\'' || *ep == '"'))
123
    {
124
      quote = *ep++;
125
      if (!unquote)
126
	*epp++ = quote;
127
    }
128
    else if (*ep == '\\' && strchr("'\"", ep[1]) && ep < last-1)
129
    {
130
      if (!unquote)
131
	*epp++ = *ep;
132
      ep++;
133
      *epp++ = *ep++;
134
      /* *was_quoted = 1;  - This makes no sense. */
135
    }
136
    else
137
    {
138
      if ((quote && (strchr("[?*", *ep) || strncmp(ep, "...", 3) == 0))
139
	  && unquote)
140
	*was_quoted = 1;
141
      *epp++ = *ep++;
142
    }
143
  }
144
 
145
  *len = epp - bp;
146
  return ep;
147
}
148
 
149
static ArgList * parse_bytes(char *bytes, int length, int unquote)
150
{
151
  int largc, i;
152
  Arg *a, **anext, *afirst;
153
  ArgList *al;
154
  char *bp=bytes, *ep, *last=bytes+length;
155
 
156
  anext = &afirst;
157
  largc = 0;
158
  while (bp
159
  {
160
    size_t arg_len;
161
    while (isspace(*(unsigned char *)bp) && bp < last)
162
      bp++;
163
    if (bp == last)
164
      break;
165
    *anext = a = new_arg();
166
    ep = parse_arg(bp, last, unquote, &arg_len, &(a->was_quoted));
167
    anext = &(a->next);
168
    largc++;
169
    a->arg = (char *)c1xmalloc(arg_len+1);
170
    memcpy(a->arg, bp, arg_len);
171
    a->arg[arg_len] = 0;
172
    bp = ep+1;
173
  }
174
  al = new_arglist(largc);
175
  for (i=0, a=afirst; inext)
176
    al->argv[i] = a;
177
  return al;
178
}
179
 
180
static ArgList * parse_print0(char *bytes, int length)
181
{
182
  int largc, i;
183
  Arg *a, **anext, *afirst;
184
  ArgList *al;
185
  char *bp=bytes, *ep, *last=bytes+length;
186
 
187
  anext = &afirst;
188
  largc = 0;
189
  while (bp
190
  {
191
    size_t arg_len = strlen(bp);
192
    ep = bp;
193
    bp += arg_len + 1;
194
    *anext = a = new_arg();
195
    a->was_quoted = 1;
196
    anext = &(a->next);
197
    largc++;
198
    a->arg = (char *)c1xmalloc(arg_len+1);
199
    memcpy(a->arg, ep, arg_len);
200
    a->arg[arg_len] = 0;
201
  }
202
  al = new_arglist(largc);
203
  for (i=0, a=afirst; inext)
204
    al->argv[i] = a;
205
  return al;
206
}
207
 
208
static int count_args(ArgList *al)
209
{
210
  int i, r=0;
211
  for (i=0; iargc; i++)
212
  {
213
    int j;
214
    if (al->argv[i]->arg_globbed)
215
    {
216
      for (j=0; al->argv[i]->arg_globbed[j]; j++);
217
      r += j;
218
    }
219
    else if (al->argv[i]->arg_file)
220
    {
221
      r += count_args(al->argv[i]->arg_file);
222
    }
223
    else
224
    {
225
      r++;
226
    }
227
  }
228
  return r;
229
}
230
 
231
static char ** fill_args(char **largv, ArgList *al)
232
{
233
  int i;
234
  for (i=0; iargc; i++)
235
  {
236
    int j;
237
    if (al->argv[i]->arg_globbed)
238
    {
239
      for (j=0; al->argv[i]->arg_globbed[j]; j++)
240
      {
241
        *largv++ = al->argv[i]->arg_globbed[j];
242
        al->argv[i]->arg_globbed[j] = 0;
243
      }
244
    }
245
    else if (al->argv[i]->arg_file)
246
    {
247
      largv = fill_args(largv, al->argv[i]->arg_file);
248
    }
249
    else
250
    {
251
      *largv++ = al->argv[i]->arg;
252
      al->argv[i]->arg = 0;
253
    }
254
  }
255
  return largv;
256
}
257
 
258
static void expand_response_files(ArgList *al)
259
{
260
  int i, f;
261
  for (i=0; iargc; i++)
262
  {
263
    if (! al->argv[i]->was_quoted && al->argv[i]->arg[0] == '@')
264
      if ((f = _open(al->argv[i]->arg+1, O_RDONLY)) >= 0)
265
      {
266
	char *bytes;
267
	int len, st_size;
268
	st_size = lseek(f, 0L, SEEK_END);
269
	lseek(f, 0L, SEEK_SET);
270
        if (st_size < 0)
271
	  st_size = 0;
272
        bytes = (char *)c1xmalloc(st_size+1);
273
        len = _read(f, bytes, st_size);
274
        if (len < 0)
275
	  len = 0;
276
        _close(f);
277
        /* if the last character is ^Z, remove it */
278
        if (len > 0 && bytes[len-1] == 0x1a)
279
          len--;
280
	/* assume 'find -print0' if the last char is a '\0' */
281
	if (len > 0 && bytes[len-1] == '\0')
282
          al->argv[i]->arg_file = parse_print0(bytes, len);
283
	else
284
          al->argv[i]->arg_file = parse_bytes(bytes, len, (_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0);
285
        expand_response_files(al->argv[i]->arg_file);
286
	free(bytes);
287
      }
288
  }
289
}
290
 
291
static void expand_wildcards(ArgList *al)
292
{
293
  int i;
294
  for (i=0; iargc; i++)
295
  {
296
    if (al->argv[i]->arg_file)
297
      expand_wildcards(al->argv[i]->arg_file);
298
    else if (!(al->argv[i]->was_quoted))
299
    {
300
      al->argv[i]->arg_globbed = __crt0_glob_function(al->argv[i]->arg);
301
    }
302
  }
303
}
304
 
305
static void add_arg(const char* arg, const char* end)
306
{
307
	char* res;
308
	__crt0_argv = realloc(__crt0_argv, 4*(++__crt0_argc));
309
	res = malloc(end-arg+1);
310
	if (!__crt0_argv || !res) _exit(1);
311
	__crt0_argv[__crt0_argc-1] = res;
312
	while (arg < end)
313
	{
314
		if (arg[0] == '"' && arg[1] == '"') ++arg;
315
		*res++ = *arg++;
316
	}
317
	*res = 0;
318
}
319
 
320
void __crt0_setup_arguments(void)
321
{
322
#if 0
323
// не будем страдать фигнёй...
324
  ArgList *arglist;
325
  char *argv0;
326
  int prepend_argv0 = 1;
327
  int should_expand_wildcards = 1;
328
  char *proxy_v = 0;
329
  argv0="menuet.app";
330
  /*
331
  ** Next, scan dos's command line.
332
  */
333
  {
334
    char doscmd[128];
335
    memcpy(doscmd+1,__menuet__app_param_area,128);
336
    arglist = parse_bytes(doscmd+1, doscmd[0] & 0x7f,
337
			  (_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0);
338
  }
339
 
340
  /*
341
  **  Now, expand response files
342
  */
343
  if (!(_crt0_startup_flags & _CRT0_FLAG_DISALLOW_RESPONSE_FILES))
344
    expand_response_files(arglist);
345
 
346
  /*
347
  **  Now, expand wildcards
348
  */
349
 
350
  if (should_expand_wildcards)
351
    expand_wildcards(arglist);
352
 
353
  __crt0_argc = prepend_argv0 + count_args(arglist);
354
  __crt0_argv = (char **)c1xmalloc((__crt0_argc+1) * sizeof(char *));
355
  if (prepend_argv0)
356
    __crt0_argv[0] = argv0;
357
  *fill_args(__crt0_argv+prepend_argv0, arglist) = 0;
358
#else
359
// ...а просто разберём командную строку. - diamond
360
	char* ptr;
361
	char* cur_arg=NULL;
362
	int bInQuote=0;
363
	add_arg(__menuet__app_path_area,
364
		__menuet__app_path_area + strlen(__menuet__app_path_area));
365
	for (ptr=__menuet__app_param_area;*ptr && ptr<__menuet__app_param_area+256;ptr++)
366
	{
367
		if (*ptr == ' ' || *ptr == '\t')
368
		{
369
			if (cur_arg && !bInQuote)
370
			{
371
				add_arg(cur_arg,ptr);
372
				cur_arg = NULL;
373
			}
374
			continue;
375
		}
376
		if (*ptr == '"')
377
		{
378
			if (ptr[1] == '"')
379
			{if (!cur_arg) cur_arg=ptr;ptr++;}
380
			else
381
			{
382
				if (cur_arg)
383
				{
384
					add_arg(cur_arg,ptr);
385
					if (bInQuote)
386
					{
387
						bInQuote = 0;
388
						cur_arg = NULL;
389
						continue;
390
					}
391
				}
392
				bInQuote = 1;
393
				cur_arg = ptr+1;
394
			}
395
			continue;
396
		}
397
		if (!cur_arg) cur_arg = ptr;
398
	}
399
	if (cur_arg) add_arg(cur_arg,ptr);
400
#endif
401
}