diff -r 000000000000 -r e4d67989cc36 genericopenlibs/cstdlib/UCRT/UCRT0.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericopenlibs/cstdlib/UCRT/UCRT0.CPP Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,309 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Common code useful to all crt0 variants. This is kept in the DLL to allow us to +// change it in future releases. +// +// + +#include +#include +#include + +#include // for chdir +#include // for calloc +#include // for strdup + +const TInt KMaxArgC=25; + +static char* wcstombs_alloc (const wchar_t* aString) + { + if (aString==NULL) + return NULL; + + size_t size = wcstombs(0, aString, 0); + char* buf = (char*)malloc(size * sizeof(char)); + + size = wcstombs(buf, aString, size); + if (size == (size_t) -1) + { + free(buf); + return NULL; + } + buf = (char*)realloc(buf, (size+1) * sizeof(char)); + return buf; + } + +#ifdef EKA2 + +static wchar_t* allocCommandLine(const TDesC& aPath) + { + TInt cmdLength = User::CommandLineLength()+1; // for zero termination + TText16* cmdbuf = (TText16*)malloc(cmdLength*sizeof(TText16)); + if (cmdbuf==0) + return (wchar_t*)cmdbuf; // we are just doomed, so give up now + + TPtr16 cmdline(cmdbuf, cmdLength); + User::CommandLine(cmdline); + + // The .EXE recogniser supplies a command line which is the name of the file, + // followed by a space. This is usually not what's wanted, so remove the + // filename if it is an exact match for the start of the command line. + + if (cmdline.Find(aPath)==0) + { + cmdline.Delete(0, aPath.Length()); + } + cmdline.ZeroTerminate(); + return (wchar_t*)cmdbuf; + } + +#else//EKA2 + +static wchar_t* allocCommandLine(const TDesC& aPath) + { + RProcess me; + TInt cmdLength = me.CommandLineLength()+1; // for zero termination + TText16* cmdbuf = (TText16*)malloc(cmdLength*sizeof(TText16)); + if (cmdbuf==0) + return (wchar_t*)cmdbuf; // we are just doomed, so give up now + + TPtr16 cmdline(cmdbuf, cmdLength); + me.CommandLine(cmdline); + + // The .EXE recogniser supplies a command line which is the name of the file, + // followed by a space. This is usually not what's wanted, so remove the + // filename if it is an exact match for the start of the command line. + + if (cmdline.Find(aPath)==0) + { + cmdline.Delete(0, aPath.Length()); + } + cmdline.ZeroTerminate(); + return (wchar_t*)cmdbuf; + } + +#endif//EKA2 + +EXPORT_C void __crt0(int& argc, char**& argv, char**& envp) + { + // Find out the filename for argv[0] + + TBuf16 exepath(RProcess().FileName()); + + // Sort out argc/argv, creating an array of pointers into a copy of + // the commandline. + + wchar_t* cmdbuf = allocCommandLine(exepath); + char* cmd = wcstombs_alloc(cmdbuf); + free(cmdbuf); + char* filename = wcstombs_alloc((const wchar_t *)exepath.PtrZ()); + + argv = (char**)calloc(KMaxArgC, sizeof(char*)); + + // Check for memory allocation failures. + if (argv==0 || cmd==0 || filename== 0) + { + // Free any memory that could have been allocated before returning. + free(cmd); + free(filename); + return; // it's basically doomed at this point anyway + } + + // Split the command line into the separate arguments + // Follow the stdarg.c rules in the Win32 runtime, namely + // 1. space and tab are whitespace separators, except inside "..." pairs + // 2. strings of \ are literal unless followed by " (see below) + // 3. a pair of "" in a quoted string is a literal " + + const char KSpace= ' '; + const char KTab = '\t'; + const char KQuote= '"'; + const char KSlash= '\\'; + + argv[0]=filename; + argc = 1; + char *q = cmd; + const char* p = cmd; + FOREVER + { + char c; + TInt quoted=0; + + // skip leading whitespace + do + c=*p++; + while (c && (c==KSpace || c==KTab)); + + // update the argv,argc + if (c=='\0' || argc>=KMaxArgC) + break; + + argv[argc] = q; + argc++; + + // copy the argument from p to q + for (;c!='\0';c=*p++) + { + + // The UNC filenames format used, e.g. \\host\dir\file + // Hence the rather odd rules: for N>=0 + // 2N+1 slash + " => N slash + literal " + // 2N slash + " => N slash, start/end quoted substring + // N slash + ? => N slash + ? + + int slashcount=0; + while (c==KSlash) + { + *q++=c; // copy the slashes (might be too many) + slashcount++; + c=*p++; + } + if (c=='\0') + break; + if (c==KQuote) + { + q-=(slashcount-(slashcount/2)); // slashes followed by quote - adjust + if (slashcount&1) + { + *q++=c; // literal quote + continue; + } + if (quoted && *p==KQuote) + { + p++; + *q++=c; // "" inside quoted section = literal quote + continue; + } + quoted=!quoted; + continue; + } + if (!quoted && (c==KSpace || c==KTab)) + break; + *q++=c; + } + *q++='\0'; // terminate the copy + + if (c=='\0') + break; // end of command line + } + + // sort out the environment + + envp=0; + } + +EXPORT_C void __crt0(int& argc, wchar_t**& wargv, wchar_t**& wenvp) + { + // Find out the filename for argv[0] + + TBuf16 exepath(RProcess().FileName()); + + // Sort out argc/argv, creating an array of pointers into a copy of + // the commandline. + + wchar_t* cmd = allocCommandLine(exepath); + wchar_t* filename = wcsdup((const wchar_t *)exepath.PtrZ()); + wargv = (wchar_t**)calloc(KMaxArgC, sizeof(wchar_t*)); + + // Check for memory allocation failures. + if (wargv==0 || cmd==0 || filename== 0) + { + // Free any memory that could have been allocated before returning. + free(cmd); + free(filename); + return; // it's basically doomed at this point anyway + } + + // Split the command line into the separate arguments + // Follow the stdarg.c rules in the Win32 runtime, namely + // 1. space and tab are whitespace separators, except inside "..." pairs + // 2. strings of \ are literal unless followed by " (see below) + // 3. a pair of "" in a quoted string is a literal " + + const wchar_t KSpace= L' '; + const wchar_t KTab = L'\t'; + const wchar_t KQuote= L'"'; + const wchar_t KSlash= L'\\'; + + wargv[0]=filename; + argc = 1; + wchar_t *q = cmd; + wchar_t *p = cmd; + FOREVER + { + wchar_t c; + TInt quoted=0; + + // skip leading whitespace + do + c=*p++; + while (c && (c==KSpace || c==KTab)); + + // update the argv,argc + if (c=='\0' || argc>=KMaxArgC) + break; + + wargv[argc] = q; + argc++; + + // copy the argument from p to q + for (;c!=L'\0';c=*p++) + { + + // The UNC filenames format used, e.g. \\host\dir\file + // Hence the rather odd rules: for N>=0 + // 2N+1 slash + " => N slash + literal " + // 2N slash + " => N slash, start/end quoted substring + // N slash + ? => N slash + ? + + int slashcount=0; + while (c==KSlash) + { + *q++=c; // copy the slashes (might be too many) + slashcount++; + c=*p++; + } + if (c==L'\0') + break; + if (c==KQuote) + { + q-=(slashcount-(slashcount/2)); // slashes followed by quote - adjust + if (slashcount&1) + { + *q++=c; // literal quote + continue; + } + if (quoted && *p==KQuote) + { + p++; + *q++=c; // "" inside quoted section = literal quote + continue; + } + quoted=!quoted; + continue; + } + if (!quoted && (c==KSpace || c==KTab)) + break; + *q++=c; + } + *q++=L'\0'; // terminate the copy + + if (c==L'\0') + break; // end of command line + } + + // sort out the environment + + wenvp=0; + }