2 * Copyright 2007-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
7 #include <ArgumentVector.h>
16 struct ArgumentVector::Parser
{
17 ParseError
Parse(const char* commandLine
, const char*& _errorLocation
)
19 // init temporary arg/argv storage
21 fCurrentArgStarted
= false;
25 for (; *commandLine
; commandLine
++) {
26 char c
= *commandLine
;
28 // whitespace delimits args and is otherwise ignored
34 const char* errorBase
= commandLine
;
38 // quoted string -- no quoting
39 while (*++commandLine
!= '\'') {
42 _errorLocation
= errorBase
;
43 return UNTERMINATED_QUOTED_STRING
;
50 // quoted string -- some quoting
51 while (*++commandLine
!= '"') {
54 _errorLocation
= errorBase
;
55 return UNTERMINATED_QUOTED_STRING
;
61 _errorLocation
= errorBase
;
62 return UNTERMINATED_QUOTED_STRING
;
65 // only '\' and '"' can be quoted, otherwise the
66 // the '\' is treated as a normal char
67 if (c
!= '\\' && c
!= '"')
79 _errorLocation
= errorBase
;
80 return TRAILING_BACKSPACE
;
98 const std::vector
<std::string
>& ArgVector() const
103 size_t TotalStringSize() const
105 return fTotalStringSize
;
109 void _PushCurrentArg()
111 if (fCurrentArgStarted
) {
112 fArgVector
.push_back(fCurrentArg
);
113 fTotalStringSize
+= fCurrentArg
.length() + 1;
114 fCurrentArgStarted
= false;
118 void _PushCharacter(char c
)
120 if (!fCurrentArgStarted
) {
122 fCurrentArgStarted
= true;
130 std::string fCurrentArg
;
131 bool fCurrentArgStarted
;
132 std::vector
<std::string
> fArgVector
;
133 size_t fTotalStringSize
;
137 ArgumentVector::ArgumentVector()
145 ArgumentVector::~ArgumentVector()
152 ArgumentVector::DetachArguments()
154 char** arguments
= fArguments
;
161 ArgumentVector::ParseError
162 ArgumentVector::Parse(const char* commandLine
, const char** _errorLocation
)
164 free(DetachArguments());
167 const char* errorLocation
= commandLine
;
171 error
= parser
.Parse(commandLine
, errorLocation
);
173 if (error
== NO_ERROR
) {
174 // Create a char* array and copy everything into a single
176 int count
= parser
.ArgVector().size();
177 size_t arraySize
= (count
+ 1) * sizeof(char*);
178 fArguments
= (char**)malloc(
179 arraySize
+ parser
.TotalStringSize());
180 if (fArguments
!= 0) {
181 char* argument
= (char*)(fArguments
+ count
+ 1);
182 for (int i
= 0; i
< count
; i
++) {
183 fArguments
[i
] = argument
;
184 const std::string
& sourceArgument
= parser
.ArgVector()[i
];
185 size_t argumentSize
= sourceArgument
.length() + 1;
186 memcpy(argument
, sourceArgument
.c_str(), argumentSize
);
187 argument
+= argumentSize
;
190 fArguments
[count
] = NULL
;
199 if (error
!= NO_ERROR
&& _errorLocation
!= NULL
)
200 *_errorLocation
= errorLocation
;