os/ossrv/genericopenlibs/cstdlib/UCRT/UCRT0.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// Common code useful to all crt0 variants. This is kept in the DLL to allow us to
sl@0
    15
// change it in future releases.
sl@0
    16
// 
sl@0
    17
//
sl@0
    18
sl@0
    19
#include <e32std.h>
sl@0
    20
#include <e32base.h>
sl@0
    21
#include <estlib.h>
sl@0
    22
sl@0
    23
#include <unistd.h>	// for chdir
sl@0
    24
#include <stdlib.h>	// for calloc
sl@0
    25
#include <string.h>	// for strdup
sl@0
    26
sl@0
    27
const TInt KMaxArgC=25;
sl@0
    28
sl@0
    29
static char* wcstombs_alloc (const wchar_t* aString)
sl@0
    30
	{
sl@0
    31
	if (aString==NULL)
sl@0
    32
		return NULL;
sl@0
    33
sl@0
    34
	size_t size = wcstombs(0, aString, 0);
sl@0
    35
	char* buf = (char*)malloc(size * sizeof(char));
sl@0
    36
sl@0
    37
	size = wcstombs(buf, aString, size);
sl@0
    38
	if (size == (size_t) -1)
sl@0
    39
		{
sl@0
    40
		free(buf);
sl@0
    41
		return NULL;
sl@0
    42
		}
sl@0
    43
	buf = (char*)realloc(buf, (size+1) * sizeof(char));
sl@0
    44
	return buf;
sl@0
    45
	}
sl@0
    46
sl@0
    47
#ifdef EKA2
sl@0
    48
sl@0
    49
static wchar_t* allocCommandLine(const TDesC& aPath)
sl@0
    50
	{
sl@0
    51
    TInt cmdLength = User::CommandLineLength()+1;	// for zero termination
sl@0
    52
	TText16* cmdbuf = (TText16*)malloc(cmdLength*sizeof(TText16));
sl@0
    53
	if (cmdbuf==0)
sl@0
    54
		return (wchar_t*)cmdbuf;		// we are just doomed, so give up now
sl@0
    55
sl@0
    56
	TPtr16 cmdline(cmdbuf, cmdLength);
sl@0
    57
    User::CommandLine(cmdline);	
sl@0
    58
sl@0
    59
	// The .EXE recogniser supplies a command line which is the name of the file,
sl@0
    60
	// followed by a space. This is usually not what's wanted, so remove the
sl@0
    61
	// filename if it is an exact match for the start of the command line.
sl@0
    62
sl@0
    63
	if (cmdline.Find(aPath)==0)
sl@0
    64
		{
sl@0
    65
		cmdline.Delete(0, aPath.Length());
sl@0
    66
		}
sl@0
    67
	cmdline.ZeroTerminate();
sl@0
    68
	return (wchar_t*)cmdbuf;
sl@0
    69
	}
sl@0
    70
sl@0
    71
#else//EKA2
sl@0
    72
sl@0
    73
static wchar_t* allocCommandLine(const TDesC& aPath)
sl@0
    74
	{
sl@0
    75
	RProcess me;
sl@0
    76
	TInt cmdLength = me.CommandLineLength()+1;	// for zero termination
sl@0
    77
	TText16* cmdbuf = (TText16*)malloc(cmdLength*sizeof(TText16));
sl@0
    78
	if (cmdbuf==0)
sl@0
    79
		return (wchar_t*)cmdbuf;		// we are just doomed, so give up now
sl@0
    80
sl@0
    81
	TPtr16 cmdline(cmdbuf, cmdLength);
sl@0
    82
	me.CommandLine(cmdline);	
sl@0
    83
sl@0
    84
	// The .EXE recogniser supplies a command line which is the name of the file,
sl@0
    85
	// followed by a space. This is usually not what's wanted, so remove the
sl@0
    86
	// filename if it is an exact match for the start of the command line.
sl@0
    87
sl@0
    88
	if (cmdline.Find(aPath)==0)
sl@0
    89
		{
sl@0
    90
		cmdline.Delete(0, aPath.Length());
sl@0
    91
		}
sl@0
    92
	cmdline.ZeroTerminate();
sl@0
    93
	return (wchar_t*)cmdbuf;
sl@0
    94
	}
sl@0
    95
sl@0
    96
#endif//EKA2
sl@0
    97
sl@0
    98
EXPORT_C void __crt0(int& argc, char**& argv, char**& envp)
sl@0
    99
	{     
sl@0
   100
	// Find out the filename for argv[0]
sl@0
   101
sl@0
   102
	TBuf16<KMaxFileName+1> exepath(RProcess().FileName());
sl@0
   103
sl@0
   104
	// Sort out argc/argv, creating an array of pointers into a copy of
sl@0
   105
	// the commandline.
sl@0
   106
sl@0
   107
	wchar_t* cmdbuf = allocCommandLine(exepath);
sl@0
   108
	char* cmd = wcstombs_alloc(cmdbuf);
sl@0
   109
	free(cmdbuf);
sl@0
   110
	char* filename = wcstombs_alloc((const wchar_t *)exepath.PtrZ());
sl@0
   111
sl@0
   112
	argv = (char**)calloc(KMaxArgC, sizeof(char*));
sl@0
   113
		
sl@0
   114
	// Check for memory allocation failures.
sl@0
   115
	if (argv==0 || cmd==0 || filename== 0)
sl@0
   116
		{
sl@0
   117
		// Free any memory that could have been allocated before returning.
sl@0
   118
		free(cmd);
sl@0
   119
		free(filename);
sl@0
   120
		return;		// it's basically doomed at this point anyway	
sl@0
   121
		}
sl@0
   122
sl@0
   123
	// Split the command line into the separate arguments
sl@0
   124
	// Follow the stdarg.c rules in the Win32 runtime, namely
sl@0
   125
	// 1. space and tab are whitespace separators, except inside "..." pairs
sl@0
   126
	// 2. strings of \ are literal unless followed by " (see below)
sl@0
   127
	// 3. a pair of "" in a quoted string is a literal "
sl@0
   128
sl@0
   129
	const char KSpace= ' ';
sl@0
   130
	const char KTab  = '\t';
sl@0
   131
	const char KQuote= '"';
sl@0
   132
	const char KSlash= '\\';
sl@0
   133
sl@0
   134
	argv[0]=filename;
sl@0
   135
	argc = 1;
sl@0
   136
	char *q = cmd;
sl@0
   137
	const char* p = cmd;
sl@0
   138
	FOREVER
sl@0
   139
		{
sl@0
   140
		char c;
sl@0
   141
		TInt quoted=0;
sl@0
   142
sl@0
   143
		// skip leading whitespace
sl@0
   144
		do	
sl@0
   145
			c=*p++;
sl@0
   146
		while (c && (c==KSpace || c==KTab));
sl@0
   147
sl@0
   148
		// update the argv,argc
sl@0
   149
		if (c=='\0' || argc>=KMaxArgC)
sl@0
   150
			break;
sl@0
   151
sl@0
   152
		argv[argc] = q;
sl@0
   153
		argc++;
sl@0
   154
sl@0
   155
		// copy the argument from p to q
sl@0
   156
		for (;c!='\0';c=*p++)
sl@0
   157
			{
sl@0
   158
sl@0
   159
			// The UNC filenames format used, e.g. \\host\dir\file
sl@0
   160
			// Hence the rather odd rules: for N>=0
sl@0
   161
			// 2N+1 slash + " => N slash + literal "
sl@0
   162
			// 2N   slash + " => N slash, start/end quoted substring
sl@0
   163
			// N    slash + ? => N slash + ?
sl@0
   164
sl@0
   165
			int slashcount=0;
sl@0
   166
			while (c==KSlash)
sl@0
   167
				{
sl@0
   168
				*q++=c;		// copy the slashes (might be too many)
sl@0
   169
				slashcount++;
sl@0
   170
				c=*p++;
sl@0
   171
				}
sl@0
   172
			if (c=='\0')
sl@0
   173
				break;
sl@0
   174
			if (c==KQuote)
sl@0
   175
				{
sl@0
   176
				q-=(slashcount-(slashcount/2));	// slashes followed by quote - adjust
sl@0
   177
				if (slashcount&1)
sl@0
   178
					{
sl@0
   179
					*q++=c;		// literal quote
sl@0
   180
					continue;
sl@0
   181
					}
sl@0
   182
				if (quoted && *p==KQuote)
sl@0
   183
					{
sl@0
   184
					p++;
sl@0
   185
					*q++=c;		// "" inside quoted section = literal quote
sl@0
   186
					continue;
sl@0
   187
					}
sl@0
   188
				quoted=!quoted;
sl@0
   189
				continue;
sl@0
   190
				}
sl@0
   191
			if (!quoted && (c==KSpace || c==KTab))
sl@0
   192
				break;
sl@0
   193
			*q++=c;
sl@0
   194
			}
sl@0
   195
		*q++='\0';	// terminate the copy
sl@0
   196
sl@0
   197
		if (c=='\0')
sl@0
   198
			break;	// end of command line
sl@0
   199
		}
sl@0
   200
sl@0
   201
	// sort out the environment
sl@0
   202
sl@0
   203
	envp=0;
sl@0
   204
	}
sl@0
   205
sl@0
   206
EXPORT_C void __crt0(int& argc, wchar_t**& wargv, wchar_t**& wenvp)
sl@0
   207
	{     
sl@0
   208
	// Find out the filename for argv[0]
sl@0
   209
sl@0
   210
	TBuf16<KMaxFileName+1> exepath(RProcess().FileName());
sl@0
   211
sl@0
   212
	// Sort out argc/argv, creating an array of pointers into a copy of
sl@0
   213
	// the commandline.
sl@0
   214
sl@0
   215
	wchar_t* cmd = allocCommandLine(exepath);
sl@0
   216
	wchar_t* filename = wcsdup((const wchar_t *)exepath.PtrZ());
sl@0
   217
	wargv = (wchar_t**)calloc(KMaxArgC, sizeof(wchar_t*));
sl@0
   218
	
sl@0
   219
	// Check for memory allocation failures.
sl@0
   220
	if (wargv==0 || cmd==0 || filename== 0)
sl@0
   221
		{
sl@0
   222
		// Free any memory that could have been allocated before returning.
sl@0
   223
		free(cmd);
sl@0
   224
		free(filename);
sl@0
   225
		return;		// it's basically doomed at this point anyway	
sl@0
   226
		}
sl@0
   227
sl@0
   228
	// Split the command line into the separate arguments
sl@0
   229
	// Follow the stdarg.c rules in the Win32 runtime, namely
sl@0
   230
	// 1. space and tab are whitespace separators, except inside "..." pairs
sl@0
   231
	// 2. strings of \ are literal unless followed by " (see below)
sl@0
   232
	// 3. a pair of "" in a quoted string is a literal "
sl@0
   233
sl@0
   234
	const wchar_t KSpace= L' ';
sl@0
   235
	const wchar_t KTab  = L'\t';
sl@0
   236
	const wchar_t KQuote= L'"';
sl@0
   237
	const wchar_t KSlash= L'\\';
sl@0
   238
sl@0
   239
	wargv[0]=filename;
sl@0
   240
	argc = 1;
sl@0
   241
	wchar_t *q = cmd;
sl@0
   242
	wchar_t *p = cmd;
sl@0
   243
	FOREVER
sl@0
   244
		{
sl@0
   245
		wchar_t c;
sl@0
   246
		TInt quoted=0;
sl@0
   247
sl@0
   248
		// skip leading whitespace
sl@0
   249
		do	
sl@0
   250
			c=*p++;
sl@0
   251
		while (c && (c==KSpace || c==KTab));
sl@0
   252
sl@0
   253
		// update the argv,argc
sl@0
   254
		if (c=='\0' || argc>=KMaxArgC)
sl@0
   255
			break;
sl@0
   256
sl@0
   257
		wargv[argc] = q;
sl@0
   258
		argc++;
sl@0
   259
sl@0
   260
		// copy the argument from p to q
sl@0
   261
		for (;c!=L'\0';c=*p++)
sl@0
   262
			{
sl@0
   263
sl@0
   264
			// The UNC filenames format used, e.g. \\host\dir\file
sl@0
   265
			// Hence the rather odd rules: for N>=0
sl@0
   266
			// 2N+1 slash + " => N slash + literal "
sl@0
   267
			// 2N   slash + " => N slash, start/end quoted substring
sl@0
   268
			// N    slash + ? => N slash + ?
sl@0
   269
sl@0
   270
			int slashcount=0;
sl@0
   271
			while (c==KSlash)
sl@0
   272
				{
sl@0
   273
				*q++=c;		// copy the slashes (might be too many)
sl@0
   274
				slashcount++;
sl@0
   275
				c=*p++;
sl@0
   276
				}
sl@0
   277
			if (c==L'\0')
sl@0
   278
				break;
sl@0
   279
			if (c==KQuote)
sl@0
   280
				{
sl@0
   281
				q-=(slashcount-(slashcount/2));	// slashes followed by quote - adjust
sl@0
   282
				if (slashcount&1)
sl@0
   283
					{
sl@0
   284
					*q++=c;		// literal quote
sl@0
   285
					continue;
sl@0
   286
					}
sl@0
   287
				if (quoted && *p==KQuote)
sl@0
   288
					{
sl@0
   289
					p++;
sl@0
   290
					*q++=c;		// "" inside quoted section = literal quote
sl@0
   291
					continue;
sl@0
   292
					}
sl@0
   293
				quoted=!quoted;
sl@0
   294
				continue;
sl@0
   295
				}
sl@0
   296
			if (!quoted && (c==KSpace || c==KTab))
sl@0
   297
				break;
sl@0
   298
			*q++=c;
sl@0
   299
			}
sl@0
   300
		*q++=L'\0';	// terminate the copy
sl@0
   301
sl@0
   302
		if (c==L'\0')
sl@0
   303
			break;	// end of command line
sl@0
   304
		}
sl@0
   305
sl@0
   306
	// sort out the environment
sl@0
   307
sl@0
   308
	wenvp=0;
sl@0
   309
	}