@@ -251,7 +251,11 @@ extension CompilationDatabase.Command: Codable {
251
251
if let arguments = try container. decodeIfPresent ( [ String ] . self, forKey: . arguments) {
252
252
self . commandLine = arguments
253
253
} else if let command = try container. decodeIfPresent ( String . self, forKey: . command) {
254
+ #if os(Windows)
255
+ self . commandLine = splitWindowsCommandLine ( command, initialCommandName: true )
256
+ #else
254
257
self . commandLine = splitShellEscapedCommand ( command)
258
+ #endif
255
259
} else {
256
260
throw CompilationDatabaseDecodingError . missingCommandOrArguments
257
261
}
@@ -265,123 +269,3 @@ extension CompilationDatabase.Command: Codable {
265
269
try container. encodeIfPresent ( output, forKey: . output)
266
270
}
267
271
}
268
-
269
- /// Split and unescape a shell-escaped command line invocation.
270
- ///
271
- /// Examples:
272
- ///
273
- /// ```
274
- /// abc def -> ["abc", "def"]
275
- /// abc\ def -> ["abc def"]
276
- /// abc"\""def -> ["abc\"def"]
277
- /// abc'\"'def -> ["abc\\"def"]
278
- /// ```
279
- ///
280
- /// See clang's `unescapeCommandLine()`.
281
- public func splitShellEscapedCommand( _ cmd: String ) -> [ String ] {
282
- struct Parser {
283
- var content : Substring
284
- var i : Substring . UTF8View . Index
285
- var result : [ String ] = [ ]
286
-
287
- var ch : UInt8 { self . content. utf8 [ i] }
288
- var done : Bool { self . content. endIndex == i }
289
-
290
- init ( _ string: Substring ) {
291
- self . content = string
292
- self . i = self . content. utf8. startIndex
293
- }
294
-
295
- mutating func next( ) {
296
- i = content. utf8. index ( after: i)
297
- }
298
-
299
- mutating func next( expect c: UInt8 ) {
300
- assert ( c == ch)
301
- next ( )
302
- }
303
-
304
- mutating func parse( ) -> [ String ] {
305
- while !done {
306
- switch ch {
307
- case UInt8 ( ascii: " " ) : next ( )
308
- default : parseString ( )
309
- }
310
- }
311
- return result
312
- }
313
-
314
- mutating func parseString( ) {
315
- var str = " "
316
- STRING: while !done {
317
- switch ch {
318
- case UInt8 ( ascii: " " ) : break STRING
319
- case UInt8 ( ascii: " \" " ) : parseDoubleQuotedString ( into: & str)
320
- case UInt8 ( ascii: " \' " ) : parseSingleQuotedString ( into: & str)
321
- default : parsePlainString ( into: & str)
322
- }
323
- }
324
- result. append ( str)
325
- }
326
-
327
- mutating func parseDoubleQuotedString( into str: inout String ) {
328
- next ( expect: UInt8 ( ascii: " \" " ) )
329
- var start = i
330
- while !done {
331
- switch ch {
332
- case UInt8 ( ascii: " \" " ) :
333
- str += content [ start..< i]
334
- next ( )
335
- return
336
- case UInt8 ( ascii: " \\ " ) :
337
- str += content [ start..< i]
338
- next ( )
339
- start = i
340
- if !done { fallthrough }
341
- default :
342
- next ( )
343
- }
344
- }
345
- str += content [ start..< i]
346
- }
347
-
348
- mutating func parseSingleQuotedString( into str: inout String ) {
349
- next ( expect: UInt8 ( ascii: " \' " ) )
350
- let start = i
351
- while !done {
352
- switch ch {
353
- case UInt8 ( ascii: " \' " ) :
354
- str += content [ start..< i]
355
- next ( )
356
- return
357
- default :
358
- next ( )
359
- }
360
- }
361
- str += content [ start..< i]
362
- }
363
-
364
- mutating func parsePlainString( into str: inout String ) {
365
- var start = i
366
- while !done {
367
- let _ch = ch
368
- switch _ch {
369
- case UInt8 ( ascii: " \" " ) , UInt8 ( ascii: " \' " ) , UInt8 ( ascii: " " ) :
370
- str += content [ start..< i]
371
- return
372
- case UInt8 ( ascii: " \\ " ) :
373
- str += content [ start..< i]
374
- next ( )
375
- start = i
376
- if !done { fallthrough }
377
- default :
378
- next ( )
379
- }
380
- }
381
- str += content [ start..< i]
382
- }
383
- }
384
-
385
- var parser = Parser ( cmd [ ... ] )
386
- return parser. parse ( )
387
- }
0 commit comments