about summary refs log tree commit diff
path: root/pkgs/os-specific
diff options
context:
space:
mode:
authorAndrew Childs <lorne@cons.org.nz>2020-09-18 17:10:03 +0900
committerAndrew Childs <lorne@cons.org.nz>2020-11-12 00:23:09 +0900
commitfd33052999bd2bb30ed8751a38d4bade17d07d01 (patch)
tree9fab2f4fbe67500e32e67871a025daf67dc38113 /pkgs/os-specific
parent8946ff8d71313fbe9634e242149f1e3fb6aa824b (diff)
darwin/print-reexports: nixpkgs-specific utility to inspect .tbd files
Used during bootstrap to check that re-exported libraries are not
dangling.
Diffstat (limited to 'pkgs/os-specific')
-rw-r--r--pkgs/os-specific/darwin/apple-sdk/print-reexports/default.nix17
-rw-r--r--pkgs/os-specific/darwin/apple-sdk/print-reexports/main.c129
2 files changed, 146 insertions, 0 deletions
diff --git a/pkgs/os-specific/darwin/apple-sdk/print-reexports/default.nix b/pkgs/os-specific/darwin/apple-sdk/print-reexports/default.nix
new file mode 100644
index 0000000000000..85e11096f06a0
--- /dev/null
+++ b/pkgs/os-specific/darwin/apple-sdk/print-reexports/default.nix
@@ -0,0 +1,17 @@
+{ stdenv, libyaml }:
+
+stdenv.mkDerivation {
+  name = "print-reexports";
+  src = stdenv.lib.sourceFilesBySuffices ./. [".c"];
+
+  buildInputs = [ libyaml ];
+
+  buildPhase = ''
+    $CC -lyaml -o $name main.c
+  '';
+
+  installPhase = ''
+    mkdir -p $out/bin
+    mv $name $out/bin
+  '';
+}
diff --git a/pkgs/os-specific/darwin/apple-sdk/print-reexports/main.c b/pkgs/os-specific/darwin/apple-sdk/print-reexports/main.c
new file mode 100644
index 0000000000000..7ad793eb4252f
--- /dev/null
+++ b/pkgs/os-specific/darwin/apple-sdk/print-reexports/main.c
@@ -0,0 +1,129 @@
+#include <stdio.h>
+#include <sys/errno.h>
+#include <yaml.h>
+
+static yaml_node_t *get_mapping_entry(yaml_document_t *document, yaml_node_t *mapping, const char *name) {
+  if (!mapping) {
+    fprintf(stderr, "get_mapping_entry: mapping is null\n");
+    return NULL;
+  }
+
+  for (
+      yaml_node_pair_t *pair = mapping->data.mapping.pairs.start;
+      pair < mapping->data.mapping.pairs.top;
+      ++pair
+  ) {
+    yaml_node_t *key = yaml_document_get_node(document, pair->key);
+
+    if (!key) {
+      fprintf(stderr, "get_mapping_entry: key (%i) is null\n", pair->key);
+      return NULL;
+    }
+
+    if (key->type != YAML_SCALAR_NODE) {
+      fprintf(stderr, "get_mapping_entry: key is not a scalar\n");
+      return NULL;
+    }
+
+    if (strncmp((const char *)key->data.scalar.value, name, key->data.scalar.length) != 0) {
+      continue;
+    }
+
+    return yaml_document_get_node(document, pair->value);
+  }
+
+  return NULL;
+}
+
+static int emit_reexports(yaml_document_t *document) {
+  yaml_node_t *root = yaml_document_get_root_node(document);
+
+  yaml_node_t *exports = get_mapping_entry(document, root, "exports");
+
+  if (!exports) {
+    fprintf(stderr, "emit_reexports: no exports found\n");
+    return 0;
+  }
+
+  if (exports->type != YAML_SEQUENCE_NODE) {
+    fprintf(stderr, "emit_reexports, value is not a sequence\n");
+    return 0;
+  }
+
+  for (
+      yaml_node_item_t *export = exports->data.sequence.items.start;
+      export < exports->data.sequence.items.top;
+      ++export
+  ) {
+    yaml_node_t *export_node = yaml_document_get_node(document, *export);
+
+    yaml_node_t *reexports = get_mapping_entry(document, export_node, "re-exports");
+
+    if (!reexports) {
+      continue;
+    }
+
+    for (
+        yaml_node_item_t *reexport = reexports->data.sequence.items.start;
+        reexport < reexports->data.sequence.items.top;
+        ++reexport
+    ) {
+      yaml_node_t *val = yaml_document_get_node(document, *reexport);
+
+      if (val->type != YAML_SCALAR_NODE) {
+        fprintf(stderr, "item is not a scalar\n");
+        return 0;
+      }
+
+      fwrite(val->data.scalar.value, val->data.scalar.length, 1, stdout);
+      putchar('\n');
+    }
+  }
+
+  return 1;
+}
+
+int main(int argc, char **argv) {
+  int result = 0;
+
+  if (argc != 2) {
+    fprintf(stderr, "Invalid usage\n");
+    result = 2;
+    goto done;
+  }
+
+  FILE *f = fopen(argv[1], "r");
+  if (!f) {
+    perror("opening input file");
+    result = errno;
+    goto done;
+  }
+
+  yaml_parser_t yaml_parser;
+  if (!yaml_parser_initialize(&yaml_parser)) {
+    fprintf(stderr, "Failed to initialize yaml parser\n");
+    result = 1;
+    goto err_file;
+  }
+
+  yaml_parser_set_input_file(&yaml_parser, f);
+
+  yaml_document_t yaml_document;
+
+  if(!yaml_parser_load(&yaml_parser, &yaml_document)) {
+    fprintf(stderr, "Failed to load yaml file\n");
+    result = 1;
+    goto err_yaml;
+  }
+
+  emit_reexports(&yaml_document);
+
+err_yaml:
+  yaml_parser_delete(&yaml_parser);
+
+err_file:
+  fclose(f);
+
+done:
+  return result;
+}