@@ -251,7 +251,11 @@ extension CompilationDatabase.Command: Codable {
251251    if  let  arguments =  try . decodeIfPresent ( [ String ] . self,  forKey:  . arguments)  { 
252252      self . commandLine =  arguments
253253    }  else  if  let  command =  try . decodeIfPresent ( String . self,  forKey:  . command)  { 
254+       #if os(Windows) 
255+       self . commandLine =  splitWindowsCommandLine ( command,  initialCommandName:  true ) 
256+       #else 
254257      self . commandLine =  splitShellEscapedCommand ( command) 
258+       #endif 
255259    }  else  { 
256260      throw  CompilationDatabaseDecodingError . missingCommandOrArguments
257261    } 
@@ -265,123 +269,3 @@ extension CompilationDatabase.Command: Codable {
265269    try . encodeIfPresent ( output,  forKey:  . output) 
266270  } 
267271} 
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