[build-path-prefix-map-spec] 03/50: Add applying examples in C and python
Ximin Luo
infinity0 at debian.org
Fri Mar 10 15:17:18 UTC 2017
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository build-path-prefix-map-spec.
commit 1062dd30c16c36e40d1387ec239779d5e76a64f2
Author: Ximin Luo <infinity0 at debian.org>
Date: Fri Jan 13 19:58:24 2017 +0100
Add applying examples in C and python
---
.gitignore | 1 +
Makefile | 22 +++++++++++
apply.out.1 | 3 ++
apply.out.2 | 3 ++
source_prefix_map.h | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++
split.c | 70 +++++++++++++++++++++++++++++++++
split.py | 20 ++++++++++
7 files changed, 228 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8f893d3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/split
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..039bacf
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+ALL = split
+ALL_CHECK = split split.py
+
+.PHONY: all
+all: $(ALL)
+
+%: %.c
+ gcc -o "$@" "$<"
+
+.PHONY: check-apply
+check-apply: apply.out.1 apply.out.2 $(ALL_CHECK)
+ set -ex; for i in $(ALL_CHECK); do \
+ SOURCE_PREFIX_MAP='/a/b=yyy=ERROR /a=lol /b=foo /a/b=yyy=secreteh' \
+ ./$$i /a/d /b/1234 /a/b=yyy/xxx | diff -ru - apply.out.1; \
+ done
+ set -ex; for i in $(ALL_CHECK); do \
+ ./$$i /a/d /b/1234 /a/b=yyy/xxx | diff -ru - apply.out.2; \
+ done
+
+.PHONY: clean
+clean:
+ rm -f $(ALL)
diff --git a/apply.out.1 b/apply.out.1
new file mode 100644
index 0000000..bca0b1d
--- /dev/null
+++ b/apply.out.1
@@ -0,0 +1,3 @@
+lol/d
+foo/1234
+secreteh/xxx
diff --git a/apply.out.2 b/apply.out.2
new file mode 100644
index 0000000..2021286
--- /dev/null
+++ b/apply.out.2
@@ -0,0 +1,3 @@
+/a/d
+/b/1234
+/a/b=yyy/xxx
diff --git a/source_prefix_map.h b/source_prefix_map.h
new file mode 100644
index 0000000..b256095
--- /dev/null
+++ b/source_prefix_map.h
@@ -0,0 +1,109 @@
+/* This file also contains C code, in a real implementation it would be split. */
+
+/* Some memory management primitives, basically copied from GCC. */
+
+#include <malloc.h>
+#include <alloca.h> // this is non-standard but is included in the GCC sources
+#include <string.h>
+
+#define XNEW(T) ((T *) malloc (sizeof (T)))
+#define XNEWVEC(T, N) ((T *) malloc (sizeof (T) * (N)))
+
+char *
+xstrdup (const char *s)
+{
+ register size_t len = strlen (s) + 1;
+ register char *ret = XNEWVEC (char, len);
+ return (char *) memcpy (ret, s, len);
+}
+
+char *
+xstrndup (const char *s, size_t n)
+{
+ char *result;
+ size_t len = strlen (s);
+
+ if (n < len)
+ len = n;
+
+ result = XNEWVEC (char, len + 1);
+
+ result[len] = '\0';
+ return (char *) memcpy (result, s, len);
+}
+
+/* Rest of it, including Applying the variable */
+
+struct prefix_map
+{
+ const char *old_prefix;
+ const char *new_prefix;
+ size_t old_len;
+ size_t new_len;
+ struct prefix_map *next;
+};
+
+const char *
+apply_prefix_map (const char *old_name, char *new_name,
+ struct prefix_map *map_head)
+{
+ struct prefix_map *map;
+ const char *name;
+
+ for (map = map_head; map; map = map->next)
+ if (strncmp (old_name, map->old_prefix, map->old_len) == 0)
+ break;
+ if (!map)
+ return old_name;
+
+ name = old_name + map->old_len;
+ memcpy (new_name, map->new_prefix, map->new_len);
+ memcpy (new_name + map->new_len, name, strlen (name) + 1);
+ return new_name;
+}
+
+struct prefix_maps
+{
+ struct prefix_map *head;
+ size_t max_replace;
+};
+
+void
+add_prefix_map (struct prefix_map *map, struct prefix_maps *maps)
+{
+ map->next = maps->head;
+ maps->head = map;
+
+ if (map->new_len > maps->max_replace)
+ maps->max_replace = map->new_len;
+}
+
+/*
+ * This function does not consume nor take ownership of filename; the caller is
+ * responsible for freeing it, if and only if it was already responsible for
+ * freeing it before the call.
+ *
+ * It allocates new memory only in the case that a mapping was made. That is,
+ * if and only if filename != return-value, then the caller is responsible for
+ * freeing return-value.
+*/
+const char *
+remap_prefix_alloc (const char *filename, struct prefix_maps *maps, void *(*alloc)(size_t size))
+{
+ size_t maxlen = strlen (filename) + maps->max_replace + 1;
+ char *newname = (char *) alloca (maxlen);
+ const char *name = apply_prefix_map (filename, newname, maps->head);
+
+ if (name == filename)
+ return filename;
+
+ size_t len = strlen (newname) + 1;
+ return (char *) memcpy (alloc (len), newname, len);
+}
+
+// Like remap_prefix_alloc but with the system allocator.
+const char *
+remap_prefix (const char *filename, struct prefix_maps *maps)
+{
+ return remap_prefix_alloc (filename, maps, malloc);
+}
diff --git a/split.c b/split.c
new file mode 100644
index 0000000..a9c92e1
--- /dev/null
+++ b/split.c
@@ -0,0 +1,70 @@
+#include "source_prefix_map.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Parsing the variable. */
+/* For Applying the variable, see source_prefix_map.h. */
+
+int
+parse_prefix_map (const char *arg, struct prefix_map *map)
+{
+ const char *p;
+ p = strrchr (arg, '=');
+ if (!p)
+ return 0;
+ map->old_prefix = xstrndup (arg, p - arg);
+ map->old_len = p - arg;
+ p++;
+ map->new_prefix = xstrdup (p);
+ map->new_len = strlen (p);
+ return 1;
+}
+
+int
+parse_prefix_maps (const char *arg, struct prefix_maps *maps)
+{
+ size_t len = strlen (arg);
+ char *copy = (char *) alloca (len + 1);
+ memcpy (copy, arg, len + 1); // strtok modifies the string so we have to copy it
+
+ char *sep = "\t", *end;
+ char *tok = strtok_r (copy, sep, &end);
+ while (tok != NULL)
+ {
+ struct prefix_map *map = XNEW (struct prefix_map);
+ if (!parse_prefix_map (tok, map))
+ {
+ fprintf (stderr, "invalid value for prefix-map: %s\n", tok);
+ free (map);
+ return 0;
+ }
+
+ add_prefix_map (map, maps);
+ tok = strtok_r (NULL, sep, &end);
+ }
+
+ return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+ struct prefix_maps source_prefix_map = { NULL, 0 };
+
+ const char *arg;
+ arg = getenv ("SOURCE_PREFIX_MAP");
+ if (arg)
+ if (!parse_prefix_maps (arg, &source_prefix_map))
+ {
+ fprintf (stderr, "parse_prefix_map failed\n");
+ return 1;
+ }
+
+ for (int i = 1; i < argc; i++)
+ {
+ fprintf (stderr, "%s", argv[i]);
+ printf ("%s\n", remap_prefix (argv[i], &source_prefix_map));
+ }
+
+ return 0;
+}
diff --git a/split.py b/split.py
new file mode 100755
index 0000000..041375e
--- /dev/null
+++ b/split.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python3
+
+import os
+import sys
+
+# Parsing the variable
+
+val = os.getenv("SOURCE_PREFIX_MAP", "")
+pm = [r.rsplit("=", 1) for r in reversed(list(filter(None, val.split('\t'))))]
+
+# Applying the variable
+
+def normprefix(string):
+ for src, dst in pm:
+ if string.startswith(src):
+ return dst + string[len(src):]
+ return string
+
+for v in sys.argv[1:]:
+ print(normprefix(v))
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/build-path-prefix-map-spec.git
More information about the Reproducible-commits
mailing list