glibc/scripts/gen-tunables.awk
DJ Delorie 8859607eaa tunables: sort tunables list (BZ 30027)
Sort tunables list at the time it's generated.  Note: adding new
tunables will cause other tunable IDs to change, but that was
the case before anyway.  POSIX does not guarantee the order of "foo
in bar" AWK operators, so the order was indeterminate before anyway.
Even depending on the order to be the same across multiple calls,
such as in this script, is undefined, so sorting the list resolves
that also.

Note that sorting is not dependent on the user's locale.
2024-06-12 14:45:18 -04:00

195 lines
4.8 KiB
Awk

# Generate dl-tunable-list.h from dl-tunables.list
BEGIN {
min_of["STRING"]="0"
max_of["STRING"]="0"
min_of["INT_32"]="INT32_MIN"
max_of["INT_32"]="INT32_MAX"
min_of["UINT_64"]="0"
max_of["UINT_64"]="UINT64_MAX"
min_of["SIZE_T"]="0"
max_of["SIZE_T"]="SIZE_MAX"
tunable=""
ns=""
top_ns=""
max_name_len=0
max_alias_len=0
}
# Skip over blank lines and comments.
/^#/ {
next
}
/^[ \t]*$/ {
next
}
# Beginning of either a top namespace, tunable namespace or a tunable, decided
# on the current value of TUNABLE, NS or TOP_NS.
$2 == "{" {
if (top_ns == "") {
top_ns = $1
}
else if (ns == "") {
ns = $1
}
else if (tunable == "") {
tunable = $1
}
else {
printf ("Unexpected occurrence of '{': %s:%d\n", FILENAME, FNR)
exit 1
}
next
}
# End of either a top namespace, tunable namespace or a tunable.
$1 == "}" {
if (tunable != "") {
# Tunables definition ended, now fill in default attributes.
if (!types[top_ns,ns,tunable]) {
types[top_ns,ns,tunable] = "STRING"
}
if (!minvals[top_ns,ns,tunable]) {
minvals[top_ns,ns,tunable] = min_of[types[top_ns,ns,tunable]]
}
if (!maxvals[top_ns,ns,tunable]) {
maxvals[top_ns,ns,tunable] = max_of[types[top_ns,ns,tunable]]
}
if (!env_alias[top_ns,ns,tunable]) {
env_alias[top_ns,ns,tunable] = "{0}"
}
len = length(top_ns"."ns"."tunable)
if (len > max_name_len)
max_name_len = len
tunable = ""
}
else if (ns != "") {
ns = ""
}
else if (top_ns != "") {
top_ns = ""
}
else {
printf ("syntax error: extra }: %s:%d\n", FILENAME, FNR)
exit 1
}
next
}
# Everything else, which could either be a tunable without any attributes or a
# tunable attribute.
{
if (ns == "") {
printf("Line %d: Invalid tunable outside a namespace: %s\n", NR, $0)
exit 1
}
if (tunable == "") {
# We encountered a tunable without any attributes, so note it with a
# default.
types[top_ns,ns,$1] = "STRING"
next
}
# Otherwise, we have encountered a tunable attribute.
split($0, arr, ":")
attr = gensub(/^[ \t]+|[ \t]+$/, "", "g", arr[1])
val = gensub(/^[ \t]+|[ \t]+$/, "", "g", arr[2])
if (attr == "type") {
types[top_ns,ns,tunable] = val
}
else if (attr == "minval") {
minvals[top_ns,ns,tunable] = val
}
else if (attr == "maxval") {
maxvals[top_ns,ns,tunable] = val
}
else if (attr == "env_alias") {
env_alias[top_ns,ns,tunable] = sprintf("\"%s\"", val)
len = length(val)
if (len > max_alias_len)
max_alias_len = len
}
else if (attr == "default") {
if (types[top_ns,ns,tunable] == "STRING") {
default_val[top_ns,ns,tunable] = sprintf(".strval = \"%s\"", val);
}
else {
default_val[top_ns,ns,tunable] = sprintf(".numval = %s", val)
}
}
}
END {
if (ns != "") {
print "Unterminated namespace. Is a closing brace missing?"
exit 1
}
# TYPES is an associative array where the index is the data
# TYPESA is an indexed array where the value is the data
# We sort TYPESA
typecount = asorti (types, typesa)
print "/* AUTOGENERATED by gen-tunables.awk. */"
print "#ifndef _TUNABLES_H_"
print "# error \"Do not include this file directly.\""
print "# error \"Include tunables.h instead.\""
print "#endif"
print "#include <dl-procinfo.h>\n"
# Now, the enum names
print "\ntypedef enum"
print "{"
for (i = 1; i <= typecount; i++) {
tnm = typesa[i];
split (tnm, indices, SUBSEP);
t = indices[1];
n = indices[2];
m = indices[3];
printf (" TUNABLE_ENUM_NAME(%s, %s, %s),\n", t, n, m);
}
print "} tunable_id_t;\n"
print "\n#ifdef TUNABLES_INTERNAL"
# Internal definitions.
print "# define TUNABLE_NAME_MAX " (max_name_len + 1)
print "# define TUNABLE_ALIAS_MAX " (max_alias_len + 1)
print "# include \"dl-tunable-types.h\""
# Finally, the tunable list.
print "static tunable_t tunable_list[] attribute_relro __attribute_used__ = {"
for (i = 1; i <= typecount; i++) {
tnm = typesa[i];
split (tnm, indices, SUBSEP);
t = indices[1];
n = indices[2];
m = indices[3];
printf (" {TUNABLE_NAME_S(%s, %s, %s)", t, n, m)
printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, {%s}, false, %s},\n",
types[t,n,m], minvals[t,n,m], maxvals[t,n,m], default_val[t,n,m],
default_val[t,n,m], env_alias[t,n,m]);
}
print "};"
# Map of tunable with environment variables aliases used during parsing. */
print "\nstatic const tunable_id_t tunable_env_alias_list[] ="
printf "{\n"
for (i = 1; i <= typecount; i++) {
tnm = typesa[i];
split (tnm, indices, SUBSEP);
t = indices[1];
n = indices[2];
m = indices[3];
if (env_alias[t,n,m] != "{0}") {
printf (" TUNABLE_ENUM_NAME(%s, %s, %s),\n", t, n, m);
}
}
printf "};\n"
print "#endif"
}