//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2024 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// /// From SwiftPrivate.swift. /// Compute the prefix sum of `seq`. private func scan( _ seq: S, _ initial: U, _ combine: (U, S.Element) -> U ) -> [U] { var result: [U] = [] result.reserveCapacity(seq.underestimatedCount) var runningResult = initial for element in seq { runningResult = combine(runningResult, element) result.append(runningResult) } return result } func withArrayOfCStrings( _ args: [String], _ body: ([UnsafeMutablePointer?]) -> R ) -> R { let argsCounts = Array(args.map { $0.utf8.count + 1 }) let argsOffsets = [0] + scan(argsCounts, 0, +) let argsBufferSize = argsOffsets.last! var argsBuffer: [UInt8] = [] argsBuffer.reserveCapacity(argsBufferSize) for arg in args { argsBuffer.append(contentsOf: arg.utf8) argsBuffer.append(0) } return argsBuffer.withUnsafeMutableBufferPointer { (argsBuffer) in let ptr = UnsafeMutableRawPointer(argsBuffer.baseAddress!).bindMemory(to: CChar.self, capacity: argsBuffer.count) var cStrings: [UnsafeMutablePointer?] = argsOffsets.map { ptr + $0 } cStrings[cStrings.count - 1] = nil return body(cStrings) } }