-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generate values in C-compatibility headers by compiling C values.
- Loading branch information
Showing
7 changed files
with
195 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
load("//toolchain:ic_rule.bzl", "ic_library") | ||
|
||
def generated_ic_library(name, **kwargs): | ||
if len(kwargs["srcs"]) != 1: | ||
fail("Must provide exactly one source template.") | ||
return | ||
|
||
native.genrule( | ||
name = "internal_generate_c_values_{}_src".format(name), | ||
outs = ["internal_generate_c_values_{}_src.cc".format(name)], | ||
cmd = "./$(location //toolchain/stdlib/compat/c/internal:generate_c_values) \"{}\" {} > $@".format( | ||
"".join(["#include <{}>\n".format(i) for i in kwargs["includes"]]), | ||
" ".join(["{} {}".format(*kv) for kv in kwargs["symbols"].items()]) | ||
), | ||
tools = ["//toolchain/stdlib/compat/c/internal:generate_c_values"], | ||
visibility = ["//visibility:private"], | ||
) | ||
|
||
native.cc_binary( | ||
name = "internal_generate_c_values_{}_bin".format(name), | ||
srcs = [":internal_generate_c_values_{}_src".format(name)], | ||
visibility = ["//visibility:private"], | ||
) | ||
|
||
native.genrule( | ||
name = "internal_generate_c_values_{}_gen".format(name), | ||
outs = ["internal_generate_c_values_{}".format(name)], | ||
cmd = "./$(location //toolchain/stdlib/compat/c:internal_generate_c_values_{}_bin) > $@".format( | ||
name | ||
), | ||
tools = ["//toolchain/stdlib/compat/c:internal_generate_c_values_{}_bin".format(name)], | ||
visibility = ["//visibility:private"], | ||
) | ||
|
||
native.genrule( | ||
name = "internal_generate_{}".format(name), | ||
outs = ["{}.ic".format(name)], | ||
srcs = kwargs["srcs"] + [":internal_generate_c_values_{}_gen".format(name)], | ||
cmd = "./$(location //toolchain/stdlib/compat/c/internal:generate) $(location {}) $(location {}) > $@".format( | ||
kwargs["srcs"][0], | ||
":internal_generate_c_values_{}_gen".format(name), | ||
), | ||
tools = ["//toolchain/stdlib/compat/c/internal:generate"], | ||
visibility = ["//visibility:private"], | ||
) | ||
|
||
ic_library( | ||
name = name, | ||
srcs = [":internal_generate_{}".format(name)], | ||
deps = kwargs["deps"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#include <cstdio> | ||
#include <string> | ||
#include <type_traits> | ||
|
||
struct string_view { | ||
char const * ptr; | ||
size_t length; | ||
}; | ||
|
||
string_view FindReplacement(std::string const &s, std::string const & needle) { | ||
size_t index = s.find(needle); | ||
if (index == std::string::npos) { std::abort(); } | ||
if (index + needle.size() + 1 >= s.size()) { std::abort(); } | ||
if (s[index + needle.size()] != '\t') { std::abort(); } | ||
size_t start = index + needle.size() + 1; | ||
size_t end = s.find("\n", start); | ||
if (end == std::string::npos) { std::abort(); } | ||
string_view sv; | ||
sv.ptr = s.data() + start; | ||
sv.length = end - start; | ||
return sv; | ||
} | ||
|
||
bool ReadFileToString(char const *file_name, std::string &result) { | ||
auto *f = std::fopen(file_name, "r"); | ||
if (not f) { return false; } | ||
std::fseek(f, 0, SEEK_END); | ||
size_t file_size = std::ftell(f); | ||
std::rewind(f); | ||
result.clear(); | ||
result.resize(file_size, '\0'); | ||
size_t count = std::fread(&result[0], 1, result.size(), f); | ||
(void)count; | ||
std::fclose(f); | ||
return true; | ||
} | ||
|
||
int main(int argc, char const *argv[]) { | ||
std::string content, replacements; | ||
std::printf("// Generated from %s.\n", argv[1]); | ||
if (not ReadFileToString(argv[1], content)) { return 1; } | ||
if (not ReadFileToString(argv[2], replacements)) { return 1; } | ||
|
||
while (true) { | ||
auto index = content.find("{{{"); | ||
if (index == std::string::npos) { | ||
std::printf("%*s", static_cast<int>(content.size()), content.data()); | ||
break; | ||
} | ||
|
||
auto end_index = content.find("}}}", index); | ||
if (end_index == std::string::npos) { std::abort(); } | ||
|
||
string_view s = FindReplacement( | ||
replacements, content.substr(index + 3, end_index - index - 3)); | ||
std::printf("%.*s%.*s", static_cast<int>(index), content.data(), | ||
static_cast<int>(s.length), s.ptr); | ||
|
||
content = content.substr(end_index + 3); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include <cstdio> | ||
#include <cstdlib> | ||
#include <cstring> | ||
|
||
char const *FormatSpecifier(char const *type) { | ||
if (std::strcmp(type, "int") == 0) { return "d"; } | ||
if (std::strcmp(type, "char") == 0) { return "c"; } | ||
if (std::strcmp(type, "double") == 0) { return "f"; } | ||
if (std::strcmp(type, "float") == 0) { return "f"; } | ||
std::abort(); | ||
} | ||
|
||
int main(int argc, char const *argv[]) { | ||
std::puts("#include <cstdio>"); | ||
std::puts(argv[1]); | ||
std::puts("int main() {"); | ||
for (int i = 2; i < argc; i += 2) { | ||
std::printf(" std::printf(\"%s\\t%%%s\\n\", static_cast<%s>(%s));\n", | ||
argv[i], FormatSpecifier(argv[i + 1]), argv[i + 1], argv[i]); | ||
} | ||
std::puts(" return 0;\n}"); | ||
|
||
return 0; | ||
} | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// This module provides an interface to functions in the <time.h> C-header file. | ||
|
||
let c ::= import "std.compat.c.types" | ||
|
||
let clock_t ::= c.long | ||
let time_t ::= c.long | ||
let tm ::= builtin.opaque() | ||
let timespec ::= builtin.opaque() | ||
let size_t ::= c.unsigned_long // TODO: generate this type. | ||
|
||
let CLOCKS_PER_SEC :: clock_t = {{{CLOCKS_PER_SEC}}} | ||
let TIME_UTC ::= {{{TIME_UTC}}} | ||
|
||
let clock ::= builtin.foreign("clock", () -> clock_t) | ||
let difftime ::= builtin.foreign("difftime", (time_t, time_t) -> c.double) | ||
let mktime ::= builtin.foreign("mktime", *tm -> time_t) | ||
let time ::= builtin.foreign("time", *time_t -> time_t) | ||
let timespec_get ::= builtin.foreign("timespec_get", (*timespec, c.int) -> c.int) | ||
let asctime ::= builtin.foreign("asctime", *tm -> [*]char) | ||
let ctime ::= builtin.foreign("ctime", *time_t -> [*]char) | ||
let gmtime ::= builtin.foreign("gmtime", *time_t -> *tm) | ||
let localtime ::= builtin.foreign("localtime", *time_t -> *tm) | ||
let strftime ::= builtin.foreign("strftime", ([*]char, size_t, [*]char, *tm) -> size_t) | ||
|
||
// Additionally, the <time.h> C-header defines the constant `NULL`, for which | ||
// there is no corresponding value in this module. For such uses, prefer the | ||
// Icarus native `null` constant. |