merge the formfield patch from ooo-build
[ooovba.git] / sal / systools / win32 / uwinapi / CommandLineToArgvW.cpp
blob8c6ae1472a9b07c77b641bf2942782dd2763491d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: CommandLineToArgvW.cpp,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
31 #pragma warning(disable:4740)
32 #endif
34 #include "macros.h"
36 #ifdef __cplusplus
37 #define local inline
38 #else
39 #define local static
40 #endif
42 local LPCWSTR SkipBlanks( LPCWSTR lpScan )
44 while ( ' ' == *lpScan || '\t' == *lpScan )
45 lpScan++;
47 return lpScan;
51 local LPCWSTR SkipArgument( LPCWSTR lpScan )
53 BOOL fQuoted = FALSE;
54 LPCWSTR lpArgEnd = NULL;
58 switch ( *lpScan )
60 case ' ':
61 case '\t':
62 if ( fQuoted )
63 lpScan++;
64 else
65 lpArgEnd = lpScan;
66 break;
67 case '\"':
68 lpScan++;
69 fQuoted = !fQuoted;
70 break;
71 case '\0':
72 lpArgEnd = lpScan;
73 break;
74 default:
75 lpScan++;
76 break;
78 } while( *lpScan && !lpArgEnd );
80 return lpScan;
84 IMPLEMENT_THUNK( shell32, WINDOWS, LPWSTR *, WINAPI, CommandLineToArgvW, ( LPCWSTR lpCmdLineW, int *pNumArgs ) )
86 LPWSTR *lpArgvW = NULL;
88 if ( !lpCmdLineW || !*lpCmdLineW )
90 CHAR szFileName[MAX_PATH];
92 DWORD dwResult = GetModuleFileNameA( NULL, szFileName, MAX_PATH );
94 if ( dwResult && dwResult < MAX_PATH )
96 int cchNeeded = MultiByteToWideChar( CP_ACP, 0, szFileName, -1, NULL, 0 );
98 lpArgvW = (LPWSTR *)GlobalAlloc( 0, cchNeeded * sizeof(WCHAR) + sizeof(LPWSTR) );
100 if ( lpArgvW )
102 lpArgvW[0] = (LPWSTR)(lpArgvW + 1);
104 MultiByteToWideChar( CP_ACP, 0, szFileName, -1, lpArgvW[0], cchNeeded );
105 *pNumArgs = 1;
107 else
108 SetLastError( ERROR_OUTOFMEMORY );
111 else
113 LPCWSTR lpScan = lpCmdLineW;
114 int nTokens = 0;
115 int cchNeeded = 0;
117 // Count arguments and required size
119 while ( *lpScan )
121 lpScan = SkipBlanks( lpScan );
122 if ( *lpScan )
124 LPCWSTR lpArgEnd = SkipArgument( lpScan );
126 nTokens++;
127 cchNeeded += lpArgEnd - lpScan + 1;
128 lpScan = lpArgEnd;
132 // Allocate space for one additional NULL pointer to terminate list
134 lpArgvW = (LPWSTR *)GlobalAlloc( 0, sizeof(LPWSTR) * (nTokens + 1) + sizeof(WCHAR) * cchNeeded );
136 if ( lpArgvW )
138 // Collect arguments
140 LPWSTR lpDestination = (LPWSTR)&lpArgvW[nTokens + 1];
142 lpScan = lpCmdLineW;
143 nTokens = 0;
145 while ( *lpScan )
147 lpScan = SkipBlanks( lpScan );
148 if ( *lpScan )
150 LPCWSTR lpArgEnd = SkipArgument( lpScan );
152 lpArgvW[nTokens++] = lpDestination;
154 while ( lpScan < lpArgEnd )
156 if ( '\"' != *lpScan )
157 *lpDestination++ = *lpScan;
159 lpScan++;
161 *lpDestination++ = 0;
165 lpArgvW[nTokens] = NULL;
167 *pNumArgs = nTokens;
169 else
170 SetLastError( ERROR_OUTOFMEMORY );
174 return lpArgvW;