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