1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/UCRT/UCRT0.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,309 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// Common code useful to all crt0 variants. This is kept in the DLL to allow us to
1.18 +// change it in future releases.
1.19 +//
1.20 +//
1.21 +
1.22 +#include <e32std.h>
1.23 +#include <e32base.h>
1.24 +#include <estlib.h>
1.25 +
1.26 +#include <unistd.h> // for chdir
1.27 +#include <stdlib.h> // for calloc
1.28 +#include <string.h> // for strdup
1.29 +
1.30 +const TInt KMaxArgC=25;
1.31 +
1.32 +static char* wcstombs_alloc (const wchar_t* aString)
1.33 + {
1.34 + if (aString==NULL)
1.35 + return NULL;
1.36 +
1.37 + size_t size = wcstombs(0, aString, 0);
1.38 + char* buf = (char*)malloc(size * sizeof(char));
1.39 +
1.40 + size = wcstombs(buf, aString, size);
1.41 + if (size == (size_t) -1)
1.42 + {
1.43 + free(buf);
1.44 + return NULL;
1.45 + }
1.46 + buf = (char*)realloc(buf, (size+1) * sizeof(char));
1.47 + return buf;
1.48 + }
1.49 +
1.50 +#ifdef EKA2
1.51 +
1.52 +static wchar_t* allocCommandLine(const TDesC& aPath)
1.53 + {
1.54 + TInt cmdLength = User::CommandLineLength()+1; // for zero termination
1.55 + TText16* cmdbuf = (TText16*)malloc(cmdLength*sizeof(TText16));
1.56 + if (cmdbuf==0)
1.57 + return (wchar_t*)cmdbuf; // we are just doomed, so give up now
1.58 +
1.59 + TPtr16 cmdline(cmdbuf, cmdLength);
1.60 + User::CommandLine(cmdline);
1.61 +
1.62 + // The .EXE recogniser supplies a command line which is the name of the file,
1.63 + // followed by a space. This is usually not what's wanted, so remove the
1.64 + // filename if it is an exact match for the start of the command line.
1.65 +
1.66 + if (cmdline.Find(aPath)==0)
1.67 + {
1.68 + cmdline.Delete(0, aPath.Length());
1.69 + }
1.70 + cmdline.ZeroTerminate();
1.71 + return (wchar_t*)cmdbuf;
1.72 + }
1.73 +
1.74 +#else//EKA2
1.75 +
1.76 +static wchar_t* allocCommandLine(const TDesC& aPath)
1.77 + {
1.78 + RProcess me;
1.79 + TInt cmdLength = me.CommandLineLength()+1; // for zero termination
1.80 + TText16* cmdbuf = (TText16*)malloc(cmdLength*sizeof(TText16));
1.81 + if (cmdbuf==0)
1.82 + return (wchar_t*)cmdbuf; // we are just doomed, so give up now
1.83 +
1.84 + TPtr16 cmdline(cmdbuf, cmdLength);
1.85 + me.CommandLine(cmdline);
1.86 +
1.87 + // The .EXE recogniser supplies a command line which is the name of the file,
1.88 + // followed by a space. This is usually not what's wanted, so remove the
1.89 + // filename if it is an exact match for the start of the command line.
1.90 +
1.91 + if (cmdline.Find(aPath)==0)
1.92 + {
1.93 + cmdline.Delete(0, aPath.Length());
1.94 + }
1.95 + cmdline.ZeroTerminate();
1.96 + return (wchar_t*)cmdbuf;
1.97 + }
1.98 +
1.99 +#endif//EKA2
1.100 +
1.101 +EXPORT_C void __crt0(int& argc, char**& argv, char**& envp)
1.102 + {
1.103 + // Find out the filename for argv[0]
1.104 +
1.105 + TBuf16<KMaxFileName+1> exepath(RProcess().FileName());
1.106 +
1.107 + // Sort out argc/argv, creating an array of pointers into a copy of
1.108 + // the commandline.
1.109 +
1.110 + wchar_t* cmdbuf = allocCommandLine(exepath);
1.111 + char* cmd = wcstombs_alloc(cmdbuf);
1.112 + free(cmdbuf);
1.113 + char* filename = wcstombs_alloc((const wchar_t *)exepath.PtrZ());
1.114 +
1.115 + argv = (char**)calloc(KMaxArgC, sizeof(char*));
1.116 +
1.117 + // Check for memory allocation failures.
1.118 + if (argv==0 || cmd==0 || filename== 0)
1.119 + {
1.120 + // Free any memory that could have been allocated before returning.
1.121 + free(cmd);
1.122 + free(filename);
1.123 + return; // it's basically doomed at this point anyway
1.124 + }
1.125 +
1.126 + // Split the command line into the separate arguments
1.127 + // Follow the stdarg.c rules in the Win32 runtime, namely
1.128 + // 1. space and tab are whitespace separators, except inside "..." pairs
1.129 + // 2. strings of \ are literal unless followed by " (see below)
1.130 + // 3. a pair of "" in a quoted string is a literal "
1.131 +
1.132 + const char KSpace= ' ';
1.133 + const char KTab = '\t';
1.134 + const char KQuote= '"';
1.135 + const char KSlash= '\\';
1.136 +
1.137 + argv[0]=filename;
1.138 + argc = 1;
1.139 + char *q = cmd;
1.140 + const char* p = cmd;
1.141 + FOREVER
1.142 + {
1.143 + char c;
1.144 + TInt quoted=0;
1.145 +
1.146 + // skip leading whitespace
1.147 + do
1.148 + c=*p++;
1.149 + while (c && (c==KSpace || c==KTab));
1.150 +
1.151 + // update the argv,argc
1.152 + if (c=='\0' || argc>=KMaxArgC)
1.153 + break;
1.154 +
1.155 + argv[argc] = q;
1.156 + argc++;
1.157 +
1.158 + // copy the argument from p to q
1.159 + for (;c!='\0';c=*p++)
1.160 + {
1.161 +
1.162 + // The UNC filenames format used, e.g. \\host\dir\file
1.163 + // Hence the rather odd rules: for N>=0
1.164 + // 2N+1 slash + " => N slash + literal "
1.165 + // 2N slash + " => N slash, start/end quoted substring
1.166 + // N slash + ? => N slash + ?
1.167 +
1.168 + int slashcount=0;
1.169 + while (c==KSlash)
1.170 + {
1.171 + *q++=c; // copy the slashes (might be too many)
1.172 + slashcount++;
1.173 + c=*p++;
1.174 + }
1.175 + if (c=='\0')
1.176 + break;
1.177 + if (c==KQuote)
1.178 + {
1.179 + q-=(slashcount-(slashcount/2)); // slashes followed by quote - adjust
1.180 + if (slashcount&1)
1.181 + {
1.182 + *q++=c; // literal quote
1.183 + continue;
1.184 + }
1.185 + if (quoted && *p==KQuote)
1.186 + {
1.187 + p++;
1.188 + *q++=c; // "" inside quoted section = literal quote
1.189 + continue;
1.190 + }
1.191 + quoted=!quoted;
1.192 + continue;
1.193 + }
1.194 + if (!quoted && (c==KSpace || c==KTab))
1.195 + break;
1.196 + *q++=c;
1.197 + }
1.198 + *q++='\0'; // terminate the copy
1.199 +
1.200 + if (c=='\0')
1.201 + break; // end of command line
1.202 + }
1.203 +
1.204 + // sort out the environment
1.205 +
1.206 + envp=0;
1.207 + }
1.208 +
1.209 +EXPORT_C void __crt0(int& argc, wchar_t**& wargv, wchar_t**& wenvp)
1.210 + {
1.211 + // Find out the filename for argv[0]
1.212 +
1.213 + TBuf16<KMaxFileName+1> exepath(RProcess().FileName());
1.214 +
1.215 + // Sort out argc/argv, creating an array of pointers into a copy of
1.216 + // the commandline.
1.217 +
1.218 + wchar_t* cmd = allocCommandLine(exepath);
1.219 + wchar_t* filename = wcsdup((const wchar_t *)exepath.PtrZ());
1.220 + wargv = (wchar_t**)calloc(KMaxArgC, sizeof(wchar_t*));
1.221 +
1.222 + // Check for memory allocation failures.
1.223 + if (wargv==0 || cmd==0 || filename== 0)
1.224 + {
1.225 + // Free any memory that could have been allocated before returning.
1.226 + free(cmd);
1.227 + free(filename);
1.228 + return; // it's basically doomed at this point anyway
1.229 + }
1.230 +
1.231 + // Split the command line into the separate arguments
1.232 + // Follow the stdarg.c rules in the Win32 runtime, namely
1.233 + // 1. space and tab are whitespace separators, except inside "..." pairs
1.234 + // 2. strings of \ are literal unless followed by " (see below)
1.235 + // 3. a pair of "" in a quoted string is a literal "
1.236 +
1.237 + const wchar_t KSpace= L' ';
1.238 + const wchar_t KTab = L'\t';
1.239 + const wchar_t KQuote= L'"';
1.240 + const wchar_t KSlash= L'\\';
1.241 +
1.242 + wargv[0]=filename;
1.243 + argc = 1;
1.244 + wchar_t *q = cmd;
1.245 + wchar_t *p = cmd;
1.246 + FOREVER
1.247 + {
1.248 + wchar_t c;
1.249 + TInt quoted=0;
1.250 +
1.251 + // skip leading whitespace
1.252 + do
1.253 + c=*p++;
1.254 + while (c && (c==KSpace || c==KTab));
1.255 +
1.256 + // update the argv,argc
1.257 + if (c=='\0' || argc>=KMaxArgC)
1.258 + break;
1.259 +
1.260 + wargv[argc] = q;
1.261 + argc++;
1.262 +
1.263 + // copy the argument from p to q
1.264 + for (;c!=L'\0';c=*p++)
1.265 + {
1.266 +
1.267 + // The UNC filenames format used, e.g. \\host\dir\file
1.268 + // Hence the rather odd rules: for N>=0
1.269 + // 2N+1 slash + " => N slash + literal "
1.270 + // 2N slash + " => N slash, start/end quoted substring
1.271 + // N slash + ? => N slash + ?
1.272 +
1.273 + int slashcount=0;
1.274 + while (c==KSlash)
1.275 + {
1.276 + *q++=c; // copy the slashes (might be too many)
1.277 + slashcount++;
1.278 + c=*p++;
1.279 + }
1.280 + if (c==L'\0')
1.281 + break;
1.282 + if (c==KQuote)
1.283 + {
1.284 + q-=(slashcount-(slashcount/2)); // slashes followed by quote - adjust
1.285 + if (slashcount&1)
1.286 + {
1.287 + *q++=c; // literal quote
1.288 + continue;
1.289 + }
1.290 + if (quoted && *p==KQuote)
1.291 + {
1.292 + p++;
1.293 + *q++=c; // "" inside quoted section = literal quote
1.294 + continue;
1.295 + }
1.296 + quoted=!quoted;
1.297 + continue;
1.298 + }
1.299 + if (!quoted && (c==KSpace || c==KTab))
1.300 + break;
1.301 + *q++=c;
1.302 + }
1.303 + *q++=L'\0'; // terminate the copy
1.304 +
1.305 + if (c==L'\0')
1.306 + break; // end of command line
1.307 + }
1.308 +
1.309 + // sort out the environment
1.310 +
1.311 + wenvp=0;
1.312 + }