<commit_before>package bindgen

import scalanative.native._


case class Args(files: Seq[String] = Seq(),
                chdir: String = ".",
                pkg: String = "scalanative.native.bindings",
                out: String = "",
                recursive: Boolean = false,
                debug: Boolean = false)

object CLI {
  val parser = new scopt.OptionParser[Args]("bindgen") {
    head("bindgen", "0.1")

    arg[String]("files...")
      .unbounded()
      .optional()
      .action((x, c) => c.copy(files = c.files :+ x))
      .text("""Header file(s) to be converted to Scala.""")

    opt[String]('C', "chdir")
      .valueName("DIR")
      .action((x, c) => c.copy(chdir = x))
      .text("""Change to DIR before performing any operations.""")

    opt[String]('P', "package")
      .valueName("PACKAGE")
      .action((x, c) => c.copy(pkg = x))
      .text("""Package name.""")

    opt[String]('o', "out")
      .optional
      .valueName("FILE")
      .action((x, c) => c.copy(out = x))
      .text("""Unified output file.""")

    opt[Unit]('r', "recursive")
      .action((_, c) => c.copy(recursive = true))
      .text("""Produces bindigs for #include(s) recursively.""")

    opt[Unit]('d', "debug")
      .action((_, c) => c.copy(debug = true))
      .text("""Emit Clang AST to stderr.""")

    help("help")
      .text("""prints this usage text""")
  }
}

object Main {

  def main(args: Array[String]): Unit = {
    val (left, right) = args.span(item => "--" != item)
    val cargs = if(right.isEmpty) Array[String]() else right.tail.toArray
    val errno: Int =
      CLI.parser.parse(left, Args()) match {
        case Some(a) => (new Generator(a, cargs)).process
        case None    => -1 // arguments are bad, error message will have been displayed
      }

    System.exit(errno)
  }
}

class Generator(args: Args, cargs: Array[String]) extends FileUtils {
  import scala.scalanative.bindings.clang._
  import scala.scalanative.bindings.clang.api._
  import scala.collection.mutable.ListBuffer

  import java.io.{File, FileOutputStream, PrintStream}

  private val tree    = new Object with Tree
  private val visitor = AST.visitor
  private val cerr    = new PrintStream(System.err)

  def process: Int = Zone { implicit z =>
    val clang_argc: CInt         = 0
    val clang_argv: Ptr[CString] = null //TODO: c.clang_args.zipWithIndex.foreach { case (p, i) => clang_argv(i) = p }

    val index: CXIndex = createIndex(0, 1)
    val xs =
      args.files.map { name =>
        if (args.debug) cerr.println(name)
        val tu: CXTranslationUnit =
          parseTranslationUnit(index,
                               toCString(name),
                               clang_argv,
                               clang_argc,
                               null,
                               0,
                               CXTranslationUnit_SkipFunctionBodies)
        assert(tu != null)
        if (tu == null) -1
        else {
          val root: CXCursor = getTranslationUnitCursor(tu)
          assert(root != null)
          val result = visitChildren(root, visitor, tree.cast[Data])
          //TODO assert(result == CXChildVisit_Continue)
          makeOutput(tree, resolve(args.chdir, args.out, name, ".h", ".scala"))
          disposeTranslationUnit(tu)
          result.toInt
        }
      }
    if (index != null) disposeIndex(index)
    0 //FIXME: obtain from iterator
  }
<commit_msg>Generator.process now returns sum(errno) from underlying Clang.<commit_after>package bindgen

import scalanative.native._


case class Args(files: Seq[String] = Seq(),
                chdir: String = ".",
                pkg: String = "scalanative.native.bindings",
                out: String = "",
                recursive: Boolean = false,
                verbose: Int = 0,
                debug: Boolean = false)

object CLI {
  val parser = new scopt.OptionParser[Args]("bindgen") {
    head("bindgen", "0.1")

    arg[String]("files...")
      .unbounded()
      .optional()
      .action((x, c) => c.copy(files = c.files :+ x))
      .text("""Header file(s) to be converted to Scala.""")

    opt[String]('C', "chdir")
      .valueName("DIR")
      .action((x, c) => c.copy(chdir = x))
      .text("""Change to DIR before performing any operations.""")

    opt[String]('P', "package")
      .valueName("PACKAGE")
      .action((x, c) => c.copy(pkg = x))
      .text("""Package name.""")

    opt[String]('o', "out")
      .optional
      .valueName("FILE")
      .action((x, c) => c.copy(out = x))
      .text("""Unified output file.""")

    opt[Unit]('r', "recursive")
      .action((_, c) => c.copy(recursive = true))
      .text("""Produces bindigs for #include(s) recursively.""")

    opt[Unit]('d', "debug")
      .action((_, c) => c.copy(debug = true))
      .text("""Emit Clang AST to stderr.""")

    opt[Unit]('v', "verbose")
      .action((_, c) => c.copy(verbose = c.verbose + 1))
      .text("""Increase verbosity.""")

    help("help")
      .text("""prints this usage text""")
  }
}

object Main {

  def main(args: Array[String]): Unit = {
    val (left, right) = args.span(item => "--" != item)
    val cargs = if(right.isEmpty) Array[String]() else right.tail.toArray
    val errno: Int =
      CLI.parser.parse(left, Args()) match {
        case Some(a) => (new Generator(a, cargs)).process
        case None    => -1 // arguments are bad, error message will have been displayed
      }

    System.exit(errno)
  }
}

class Generator(args: Args, cargs: Array[String]) extends FileUtils {
  import scala.scalanative.bindings.clang._
  import scala.scalanative.bindings.clang.api._
  import scala.collection.mutable.ListBuffer

  import java.io.{File, FileOutputStream, PrintStream}

  private val tree    = new Object with Tree
  private val visitor = AST.visitor
  private val cerr    = new PrintStream(System.err)

  def process: Int = Zone { implicit z =>
    val clang_argc: CInt         = 0
    val clang_argv: Ptr[CString] = null //TODO: c.clang_args.zipWithIndex.foreach { case (p, i) => clang_argv(i) = p }

    val index: CXIndex = createIndex(0, 1)
    val xs =
      args.files.map { name =>
        if (args.verbose > 0) cerr.println(name)
        val tu: CXTranslationUnit =
          parseTranslationUnit(index,
                               toCString(name),
                               clang_argv,
                               clang_argc,
                               null,
                               0,
                               CXTranslationUnit_SkipFunctionBodies)
        assert(tu != null)
        if (tu == null) -1
        else {
          val root: CXCursor = getTranslationUnitCursor(tu)
          assert(root != null)
          val result = visitChildren(root, visitor, tree.cast[Data]).toInt
          if(args.verbose > 0) println(s"${result} ${name}")
          if(result==0) makeOutput(tree, resolve(args.chdir, args.out, name, ".h", ".scala"))
          disposeTranslationUnit(tu)
          result
        }
      }
    if (index != null) disposeIndex(index)
    xs.sum
  }

{'fraction_non_alphanumeric': 0.1497318656505786, 'fraction_numerical': 0.0031047135196161446, 'mean_word_length': 2.1206516952884193, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5265412', 'n_tokens_mistral': 2291, 'n_tokens_neox': 2204, 'n_words': 539}