[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH v2 4/5] build: introduce tool for adding CONFIG_ prefix for kconfig symbols



There are two reasons to have prefix CONFIG_:
1) This makes code a bit more understandable - one can distinguish
   internal macros from configuration ones
2) The fixdep heavily relies on it while detecting configuration
   build dependencies

But kconfig symbols are all over the Unikraft code. Replacing them
manually error-prone, and impossible to review. So a tool has been
implemented which will do the dirty job, and which has much smaller
codebase - possible to keep in a normal human mind.

The next "make" invocation will generate file
build/kconfig/all_kconfig_syms.list, containing all symbols declared
in all Config.uk files.

This list is used by rename_config.py script, which will scan all
files in the current git repository and will do the replacement.

The script is replacing only exact matches, so you can run it multiple
times without getting artifacts like "CONFIG_CONFIG_SYMBOL".

Any external library/application can also be converted to the new
system using this tool.

Signed-off-by: Yuri Volchkov <yuri.volchkov@xxxxxxxxx>
---
 support/kconfig/confdata.c       |  54 +++++++++++++-
 support/scripts/rename_config.py | 117 +++++++++++++++++++++++++++++++
 2 files changed, 170 insertions(+), 1 deletion(-)
 create mode 100755 support/scripts/rename_config.py

diff --git a/support/kconfig/confdata.c b/support/kconfig/confdata.c
index 4d8c9ac..ee6246d 100644
--- a/support/kconfig/confdata.c
+++ b/support/kconfig/confdata.c
@@ -654,6 +654,40 @@ conf_write_heading(FILE *fp, struct conf_printer *printer, 
void *printer_arg)
        printer->print_comment(fp, buf, printer_arg);
 }
 
+/*
+ * List printer
+ *
+ * This printer is used when generating the 'all_kconfig_syms.list' file
+ */
+static void
+list_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
+{
+       if (!sym->name)
+               return;
+
+       switch (sym->type) {
+       case S_BOOLEAN:
+       case S_TRISTATE:
+       case S_HEX:
+       case S_STRING:
+       case S_INT:
+               fprintf(fp, "%s%s\n",
+                       CONFIG_, sym->name);
+               break;
+       default:
+               break;
+       }
+}
+static void
+list_print_comment(FILE *fp, const char *value, void *arg)
+{
+}
+
+static struct conf_printer list_printer_cb = {
+       .print_symbol =  list_print_symbol,
+       .print_comment = list_print_comment,
+};
+
 /*
  * Write out a minimal config.
  * All values that has default values are skipped as this is redundant.
@@ -972,7 +1006,7 @@ int conf_write_autoconf(void)
 {
        struct symbol *sym;
        const char *name;
-       FILE *out, *tristate, *out_h;
+       FILE *out, *tristate, *out_h, *all_syms;
        int i;
        char dir[PATH_MAX+1], buf[PATH_MAX+1];
        char *s;
@@ -1012,6 +1046,21 @@ int conf_write_autoconf(void)
                return 1;
        }
 
+       strcpy(buf,  conf_get_autoconfig_name());
+       s = strrchr(buf, '/');
+       if (s)
+               strcpy(s + 1, "all_kconfig_syms.list");
+       else
+               strcpy(buf, "all_kconfig_syms.list");
+
+       all_syms = fopen(buf, "w");
+       if (!all_syms) {
+               fclose(out);
+               fclose(tristate);
+               fclose(out_h);
+               return 1;
+       }
+
        conf_write_heading(out, &kconfig_printer_cb, NULL);
 
        conf_write_heading(tristate, &tristate_printer_cb, NULL);
@@ -1019,6 +1068,8 @@ int conf_write_autoconf(void)
        conf_write_heading(out_h, &header_printer_cb, NULL);
 
        for_all_symbols(i, sym) {
+               conf_write_symbol(all_syms, sym, &list_printer_cb, NULL);
+
                sym_calc_value(sym);
                if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
                        continue;
@@ -1033,6 +1084,7 @@ int conf_write_autoconf(void)
        fclose(out);
        fclose(tristate);
        fclose(out_h);
+       fclose(all_syms);
 
        name = getenv("KCONFIG_AUTOHEADER");
        if (!name)
diff --git a/support/scripts/rename_config.py b/support/scripts/rename_config.py
new file mode 100755
index 0000000..3b5195c
--- /dev/null
+++ b/support/scripts/rename_config.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+#
+# This scripts adds prefix CONFIG_ to every kconfig symbol in the
+# Unikraft/lib/app repository.
+#
+# Why bother:
+# 1) This makes code a bit more understandable - one can distinguish
+#    internal macros from configuration ones
+# 2) The fixdep heavily relies on it while detecting configuration
+#    build dependencies
+#
+# Why script:
+# The kconfig symbols are all over the Unikraft code. Replacing them
+# manually error-prone and impossible to review. So a tool has been
+# implemented which will do the dirty job, and which has much smaller
+# codebase - possible to keep in a normal human mind.
+#
+# How:
+# The script reads a list of all symbols declared in all Config.uk
+# from file build/kconfig/all_kconfig_syms.list. The file is generated
+# by make.  Then it scans all files in the current git repository and
+# does the replacement.
+#
+# Script replaces only exact matches, so you can run it multiple
+# times without getting artifacts like "CONFIG_CONFIG_SYMBOL".
+#
+# Any external library/application can also be converted to the new
+# system using this tool.
+
+import argparse
+import subprocess
+import re
+import os, sys
+
+def rename_one(sym_name, files):
+    sed_regexp = 's/%s/CONFIG_%s/g' %(sym_name,sym_name)
+    subprocess.check_call(['sed', '-i', '-e', sed_regexp] + files)
+
+def process_file(fname, symbols):
+    f = open(fname, "r")
+    buf = f.read()
+    f.close()
+
+    prefix = r"([\(\{\[\s!\,])"
+    suffix = r"([\)\}\]\s\,])"
+
+    # Have to run twice to cover overlapping tokens. For example in
+    # the text "UK_CONFIG UK_CONFIG" only first occurrence will be
+    # replaced
+    for i in range(2):
+        for old in symbols:
+            new = r"CONFIG_" + old
+            buf = re.sub(prefix + old + suffix, r"\1" + new + r"\2", buf)
+
+    f = open(fname, "w")
+    f.write(buf)
+    f.close()
+
+def main():
+    parser = argparse.ArgumentParser(description="group config rename")
+    parser.add_argument("-s", "--symbols", action="store",
+                        default="build/kconfig/all_kconfig_syms.list",
+                        help="File containing all symbols to rename")
+    parser.add_argument("--ignore", action="append",
+                        default=[],
+                        help="Ignore regular expression")
+    parser.add_argument("-f", '--files', action="store",
+                        nargs='+', default=None,
+                        help="Files to modify. If not specified 'git ls-files'"
+                        + "is used to get list of files")
+
+    opt = parser.parse_args()
+
+    ignore_str = "|".join(opt.ignore)
+    if len(ignore_str) > 0:
+        ignore_str = "(%s)" % ignore_str
+
+    this_file_name = os.path.relpath(__file__)
+    warn_files = subprocess.check_output("git ls-files -m".split())
+    warn_files = warn_files.decode().strip().split("\n")
+    warn_files = [x for x in warn_files if (x != this_file_name)
+                  and (x != '')]
+    if len(warn_files) > 0:
+        sys.exit("You have unstaged changes.\nPlease commit or stash them.")
+
+    if opt.files:
+        files = opt.files
+    else:
+        files = subprocess.check_output("git ls-files".split())
+        files = files.decode().strip().split("\n")
+        files = [x for x in files if (not x.endswith("Config.uk"))
+                and (not x.endswith("MAINTAINERS.md"))]
+
+    files = [x for x in files if re.fullmatch(ignore_str, x) == None]
+
+    f = open(opt.symbols)
+    symbols = f.read().strip()
+    f.close()
+    symbols = re.sub("CONFIG_", "", symbols)
+    symbols = symbols.split()
+
+    symbols.remove('UK_CODENAME')
+    symbols.remove('UK_FULLVERSION')
+
+    for fname in files:
+        process_file(fname, symbols)
+
+    warn_files = subprocess.check_output("git ls-files -m".split())
+    warn_files = warn_files.decode().strip().split("\n")
+    warn_files = [x for x in warn_files if (x.endswith("rst"))]
+    if len(warn_files) > 0:
+        print("WARNING: you might want to undo modifications to these files:")
+        for i in warn_files:
+            print("\t%s" % i)
+
+if __name__ == "__main__":
+    main()
-- 
2.17.0


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.