5 分钟用 Swift 写个 ripripgrep

MrKrabs · 3 天前 · 103 次点击

你别管什么 NFC ,NFD ,咱只是想搜出日语呢

import Foundation
import ArgumentParser

@main
struct Ripripgrep: ParsableCommand {

  @Option(name: .shortAndLong)
  var patterns: [String]

  @Argument(help: "use stdin if no args")
  var files: [String] = []

  func validate() throws {
    if patterns.isEmpty {
      fatalError("no patterns!")
    }
  }

  struct Worker {
    var line: UnsafeMutablePointer<CChar>?
    var linecap = 0
    let patterns: [Regex<AnyRegexOutput>]

    mutating func start(stream: UnsafeMutablePointer<FILE>) {
      while case let linelen = getline(&line, &linecap, stream),
            linelen > 0 {
        let line = String(decoding: UnsafeRawBufferPointer(start: line!, count: linelen-1), as: UTF8.self)
        if patterns.allSatisfy({ line.contains($0) }) {
          print(line)
        }
      }
    }
  }

  func run() throws {

    var worker = Worker(patterns: try patterns.map { try Regex($0).ignoresCase() })

    if files.isEmpty {
      // use stdin
      worker.start(stream: stdin)
    } else {
      for file in files {
        let stream = fopen(file, "rb")!
        defer { fclose(stream) }
        worker.start(stream: stream)
      }
    }
  }

}

举报· 103 次点击
登录 注册 站外分享
快来抢沙发
0 条回复  
返回顶部