Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4972 → Rev 4973

/programs/develop/libraries/menuetlibc/src/libc/crt0/crt0.c
0,0 → 1,401
#include<menuet/os.h>
#include<unistd.h>
 
void _exit(int code)
{
__asm__ __volatile__("int $0x40"::"a"(-1));
for(;;);
}
 
#include <libc/stubs.h>
#include <io.h>
#include <unistd.h>
#include <stdlib.h>
#include <crt0.h>
#include <libc/farptrgs.h>
#include <ctype.h>
#include <string.h>
#include <fcntl.h>
 
#define ds _my_ds()
 
 
extern char __menuet__app_param_area[];
extern char __menuet__app_path_area[];
 
static void * c1xmalloc(size_t s)
{
void *q = malloc(s);
if (q == 0)
{
#define err(x)
err("No memory to gather arguments\r\n");
_exit(1);
}
return q;
}
 
static int atohex(char *s)
{
int rv = 0;
while (*s)
{
int v = *s - '0';
if (v > 9)
v -= 7;
v &= 15; /* in case it's lower case */
rv = rv*16 + v;
s++;
}
return rv;
}
 
typedef struct Arg {
char *arg;
char **arg_globbed;
struct ArgList *arg_file;
struct Arg *next;
int was_quoted;
} Arg;
 
typedef struct ArgList {
int argc;
Arg **argv;
} ArgList;
 
static Arg *new_arg(void)
{
Arg *a = (Arg *)c1xmalloc(sizeof(Arg));
memset(a, 0, sizeof(Arg));
return a;
}
 
static void delete_arglist(ArgList *al);
 
static void delete_arg(Arg *a)
{
if (a->arg) free(a->arg);
if (a->arg_globbed)
{
int i;
for (i=0; a->arg_globbed[i]; i++)
free(a->arg_globbed[i]);
free(a->arg_globbed);
}
if (a->arg_file)
delete_arglist(a->arg_file);
free(a);
}
 
static ArgList * new_arglist(int count)
{
ArgList *al = (ArgList *)c1xmalloc(sizeof(ArgList));
al->argc = count;
al->argv = (Arg **)c1xmalloc((count+1)*sizeof(Arg *));
memset(al->argv, 0, (count+1)*sizeof(Arg *));
return al;
}
 
static void delete_arglist(ArgList *al)
{
int i;
for (i=0; i<al->argc; i++)
delete_arg(al->argv[i]);
free(al->argv);
free(al);
}
 
static char * parse_arg(char *bp, char *last, int unquote, size_t *len, int *was_quoted)
{
char *ep = bp, *epp = bp;
int quote=0;
 
while ((quote || !isspace(*(unsigned char *)ep)) && ep < last)
{
if (quote && *ep == quote)
{
quote = 0;
if (!unquote)
*epp++ = *ep;
ep++;
}
else if (!quote && (*ep == '\'' || *ep == '"'))
{
quote = *ep++;
if (!unquote)
*epp++ = quote;
}
else if (*ep == '\\' && strchr("'\"", ep[1]) && ep < last-1)
{
if (!unquote)
*epp++ = *ep;
ep++;
*epp++ = *ep++;
/* *was_quoted = 1; - This makes no sense. */
}
else
{
if ((quote && (strchr("[?*", *ep) || strncmp(ep, "...", 3) == 0))
&& unquote)
*was_quoted = 1;
*epp++ = *ep++;
}
}
 
*len = epp - bp;
return ep;
}
 
static ArgList * parse_bytes(char *bytes, int length, int unquote)
{
int largc, i;
Arg *a, **anext, *afirst;
ArgList *al;
char *bp=bytes, *ep, *last=bytes+length;
 
anext = &afirst;
largc = 0;
while (bp<last)
{
size_t arg_len;
while (isspace(*(unsigned char *)bp) && bp < last)
bp++;
if (bp == last)
break;
*anext = a = new_arg();
ep = parse_arg(bp, last, unquote, &arg_len, &(a->was_quoted));
anext = &(a->next);
largc++;
a->arg = (char *)c1xmalloc(arg_len+1);
memcpy(a->arg, bp, arg_len);
a->arg[arg_len] = 0;
bp = ep+1;
}
al = new_arglist(largc);
for (i=0, a=afirst; i<largc; i++, a=a->next)
al->argv[i] = a;
return al;
}
 
static ArgList * parse_print0(char *bytes, int length)
{
int largc, i;
Arg *a, **anext, *afirst;
ArgList *al;
char *bp=bytes, *ep, *last=bytes+length;
 
anext = &afirst;
largc = 0;
while (bp<last)
{
size_t arg_len = strlen(bp);
ep = bp;
bp += arg_len + 1;
*anext = a = new_arg();
a->was_quoted = 1;
anext = &(a->next);
largc++;
a->arg = (char *)c1xmalloc(arg_len+1);
memcpy(a->arg, ep, arg_len);
a->arg[arg_len] = 0;
}
al = new_arglist(largc);
for (i=0, a=afirst; i<largc; i++, a=a->next)
al->argv[i] = a;
return al;
}
 
static int count_args(ArgList *al)
{
int i, r=0;
for (i=0; i<al->argc; i++)
{
int j;
if (al->argv[i]->arg_globbed)
{
for (j=0; al->argv[i]->arg_globbed[j]; j++);
r += j;
}
else if (al->argv[i]->arg_file)
{
r += count_args(al->argv[i]->arg_file);
}
else
{
r++;
}
}
return r;
}
 
static char ** fill_args(char **largv, ArgList *al)
{
int i;
for (i=0; i<al->argc; i++)
{
int j;
if (al->argv[i]->arg_globbed)
{
for (j=0; al->argv[i]->arg_globbed[j]; j++)
{
*largv++ = al->argv[i]->arg_globbed[j];
al->argv[i]->arg_globbed[j] = 0;
}
}
else if (al->argv[i]->arg_file)
{
largv = fill_args(largv, al->argv[i]->arg_file);
}
else
{
*largv++ = al->argv[i]->arg;
al->argv[i]->arg = 0;
}
}
return largv;
}
 
static void expand_response_files(ArgList *al)
{
int i, f;
for (i=0; i<al->argc; i++)
{
if (! al->argv[i]->was_quoted && al->argv[i]->arg[0] == '@')
if ((f = _open(al->argv[i]->arg+1, O_RDONLY)) >= 0)
{
char *bytes;
int len, st_size;
st_size = lseek(f, 0L, SEEK_END);
lseek(f, 0L, SEEK_SET);
if (st_size < 0)
st_size = 0;
bytes = (char *)c1xmalloc(st_size+1);
len = _read(f, bytes, st_size);
if (len < 0)
len = 0;
_close(f);
/* if the last character is ^Z, remove it */
if (len > 0 && bytes[len-1] == 0x1a)
len--;
/* assume 'find -print0' if the last char is a '\0' */
if (len > 0 && bytes[len-1] == '\0')
al->argv[i]->arg_file = parse_print0(bytes, len);
else
al->argv[i]->arg_file = parse_bytes(bytes, len, (_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0);
expand_response_files(al->argv[i]->arg_file);
free(bytes);
}
}
}
 
static void expand_wildcards(ArgList *al)
{
int i;
for (i=0; i<al->argc; i++)
{
if (al->argv[i]->arg_file)
expand_wildcards(al->argv[i]->arg_file);
else if (!(al->argv[i]->was_quoted))
{
al->argv[i]->arg_globbed = __crt0_glob_function(al->argv[i]->arg);
}
}
}
 
static void add_arg(const char* arg, const char* end)
{
char* res;
__crt0_argv = realloc(__crt0_argv, 4*(++__crt0_argc));
res = malloc(end-arg+1);
if (!__crt0_argv || !res) _exit(1);
__crt0_argv[__crt0_argc-1] = res;
while (arg < end)
{
if (arg[0] == '"' && arg[1] == '"') ++arg;
*res++ = *arg++;
}
*res = 0;
}
 
void __crt0_setup_arguments(void)
{
#if 0
// ­¥ ¡ã¤¥¬ áâà ¤ âì 䨣­ñ©...
ArgList *arglist;
char *argv0;
int prepend_argv0 = 1;
int should_expand_wildcards = 1;
char *proxy_v = 0;
argv0="menuet.app";
/*
** Next, scan dos's command line.
*/
{
char doscmd[128];
memcpy(doscmd+1,__menuet__app_param_area,128);
arglist = parse_bytes(doscmd+1, doscmd[0] & 0x7f,
(_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0);
}
 
/*
** Now, expand response files
*/
if (!(_crt0_startup_flags & _CRT0_FLAG_DISALLOW_RESPONSE_FILES))
expand_response_files(arglist);
 
/*
** Now, expand wildcards
*/
 
if (should_expand_wildcards)
expand_wildcards(arglist);
 
__crt0_argc = prepend_argv0 + count_args(arglist);
__crt0_argv = (char **)c1xmalloc((__crt0_argc+1) * sizeof(char *));
if (prepend_argv0)
__crt0_argv[0] = argv0;
*fill_args(__crt0_argv+prepend_argv0, arglist) = 0;
#else
// ...  ¯à®áâ® à §¡¥àñ¬ ª®¬ ­¤­ãî áâபã. - diamond
char* ptr;
char* cur_arg=NULL;
int bInQuote=0;
add_arg(__menuet__app_path_area,
__menuet__app_path_area + strlen(__menuet__app_path_area));
for (ptr=__menuet__app_param_area;*ptr && ptr<__menuet__app_param_area+256;ptr++)
{
if (*ptr == ' ' || *ptr == '\t')
{
if (cur_arg && !bInQuote)
{
add_arg(cur_arg,ptr);
cur_arg = NULL;
}
continue;
}
if (*ptr == '"')
{
if (ptr[1] == '"')
{if (!cur_arg) cur_arg=ptr;ptr++;}
else
{
if (cur_arg)
{
add_arg(cur_arg,ptr);
if (bInQuote)
{
bInQuote = 0;
cur_arg = NULL;
continue;
}
}
bInQuote = 1;
cur_arg = ptr+1;
}
continue;
}
if (!cur_arg) cur_arg = ptr;
}
if (cur_arg) add_arg(cur_arg,ptr);
#endif
}