Skip to content

Commit 11d65bd

Browse files
authored
Merge pull request #76 from kornilova-l/tools
Tooling project
2 parents 69310c6 + e0e460e commit 11d65bd

File tree

4 files changed

+175
-20
lines changed

4 files changed

+175
-20
lines changed

build.sbt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ inThisBuild(
1818

1919
val tests = project
2020
.in(file("tests"))
21+
.dependsOn(tools)
2122
.aggregate(samples)
2223
.settings(
2324
fork in Test := true,
@@ -85,3 +86,5 @@ lazy val samples = project
8586
(Test / compile).value
8687
}
8788
)
89+
90+
lazy val tools = project in file("tools")

tests/src/test/scala/org/scalanative/bindgen/BindgenSpec.scala

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package org.scalanative.bindgen
22

3-
import java.io.{File, PrintWriter}
3+
import java.io.File
44
import org.scalatest.FunSpec
55
import scala.io.Source
6-
import scala.sys.process._
76

87
class BindgenSpec extends FunSpec {
98
describe("Bindgen") {
@@ -19,24 +18,15 @@ class BindgenSpec extends FunSpec {
1918
}
2019

2120
def bindgen(inputFile: File, name: String, outputFile: File): Unit = {
22-
val cmd = Seq(
23-
bindgenPath,
24-
inputFile.getAbsolutePath,
25-
"--name",
26-
name,
27-
"--link",
28-
"bindgentests",
29-
"--package",
30-
"org.scalanative.bindgen.samples",
31-
"--exclude-prefix=__",
32-
"--"
33-
)
34-
val output = Process(cmd).lineStream.mkString("\n")
35-
36-
new PrintWriter(outputFile) {
37-
write(output)
38-
close()
39-
}
21+
Bindgen()
22+
.bindgenExecutable(new File(bindgenPath))
23+
.header(inputFile)
24+
.name(name)
25+
.link("bindgentests")
26+
.packageName("org.scalanative.bindgen.samples")
27+
.excludePrefix("__")
28+
.generate()
29+
.writeToFile(outputFile)
4030
}
4131

4232
def contentOf(file: File) =
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package org.scalanative.bindgen
2+
3+
import java.io.File
4+
5+
import scala.collection.immutable
6+
import scala.sys.process.Process
7+
8+
sealed trait Bindgen {
9+
10+
/**
11+
* Set bindgen executable
12+
*/
13+
def bindgenExecutable(executable: File): Bindgen
14+
15+
/**
16+
* Set header file for which bindings will be generated
17+
*/
18+
def header(header: File): Bindgen
19+
20+
/**
21+
* Library to link with, e.g. -luv for libuv
22+
*/
23+
def link(library: String): Bindgen
24+
25+
/**
26+
* Name of Scala object that contains bindings.
27+
* Default is set to library name.
28+
*/
29+
def name(name: String): Bindgen
30+
31+
/**
32+
* Package name of generated Scala file
33+
*/
34+
def packageName(packageName: String): Bindgen
35+
36+
/**
37+
* Declarations will be removed if their names
38+
* contain given prefix
39+
*/
40+
def excludePrefix(prefix: String): Bindgen
41+
42+
/**
43+
* Additional argument to append to the compiler command line
44+
*/
45+
def extraArg(args: String*): Bindgen
46+
47+
/**
48+
* Additional argument to append to the compiler command line
49+
*/
50+
def extraArgBefore(args: String*): Bindgen
51+
52+
/**
53+
* Run binding generator
54+
*/
55+
def generate(): Bindings
56+
}
57+
58+
object Bindgen {
59+
def apply(): Bindgen = Impl()
60+
61+
private final case class Impl(
62+
executable: Option[File] = None,
63+
library: Option[String] = None,
64+
header: Option[File] = None,
65+
name: Option[String] = None,
66+
packageName: Option[String] = None,
67+
excludePrefix: Option[String] = None,
68+
extraArg: immutable.Seq[String] = immutable.Seq[String](),
69+
extraArgBefore: immutable.Seq[String] = immutable.Seq[String]())
70+
extends Bindgen {
71+
72+
def bindgenExecutable(executable: File): Bindgen = {
73+
require(executable.exists())
74+
copy(executable = Option(executable))
75+
}
76+
77+
def header(header: File): Bindgen = {
78+
require(header.exists())
79+
copy(header = Option(header))
80+
}
81+
82+
def link(library: String): Bindgen = {
83+
require(!library.isEmpty)
84+
copy(library = Option(library))
85+
}
86+
87+
def name(name: String): Bindgen = {
88+
require(!name.isEmpty)
89+
copy(name = Option(name))
90+
}
91+
92+
def packageName(packageName: String): Bindgen = {
93+
require(!packageName.isEmpty)
94+
copy(packageName = Option(packageName))
95+
}
96+
97+
def excludePrefix(prefix: String): Bindgen = {
98+
require(!prefix.isEmpty)
99+
copy(excludePrefix = Option(prefix))
100+
}
101+
102+
def extraArg(args: String*): Bindgen = {
103+
require(args.forall(_.nonEmpty))
104+
copy(extraArg = extraArg ++ args)
105+
}
106+
107+
def extraArgBefore(args: String*): Bindgen = {
108+
require(args.forall(_.nonEmpty))
109+
copy(extraArgBefore = extraArgBefore ++ args)
110+
}
111+
112+
private def validateFields(): Unit = {
113+
require(executable.isDefined, "The executable must be specified")
114+
require(header.isDefined, "Header file must be specified")
115+
require(library.isDefined, "Library name must be specified")
116+
}
117+
118+
def generate(): Bindings = {
119+
validateFields()
120+
121+
val name = this.name.getOrElse(library.get)
122+
123+
var cmd = Seq(
124+
executable.get.getAbsolutePath,
125+
header.get.getAbsolutePath,
126+
"--name",
127+
name,
128+
"--link",
129+
library.get
130+
)
131+
132+
if (packageName.isDefined) {
133+
cmd ++= Seq("--package", packageName.get)
134+
}
135+
136+
if (excludePrefix.isDefined) {
137+
cmd ++= Seq("--exclude-prefix", excludePrefix.get)
138+
}
139+
140+
extraArg.foreach(arg => cmd ++= Seq("--extra-arg", arg))
141+
extraArgBefore.foreach(arg => cmd ++= Seq("--extra-arg-before", arg))
142+
143+
cmd :+= "--"
144+
145+
val output = Process(cmd).lineStream.mkString("\n")
146+
147+
new Bindings(output)
148+
}
149+
}
150+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.scalanative.bindgen
2+
3+
import java.io.{File, PrintWriter}
4+
5+
class Bindings(private val bindings: String) {
6+
def writeToFile(file: File): Unit = {
7+
new PrintWriter(file) {
8+
write(bindings)
9+
close()
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)