gen-tunables.awk 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. # Generate dl-tunable-list.h from dl-tunables.list
  2. BEGIN {
  3. min_of["STRING"]="0"
  4. max_of["STRING"]="0"
  5. min_of["INT_32"]="INT32_MIN"
  6. max_of["INT_32"]="INT32_MAX"
  7. min_of["UINT_64"]="0"
  8. max_of["UINT_64"]="UINT64_MAX"
  9. min_of["SIZE_T"]="0"
  10. max_of["SIZE_T"]="SIZE_MAX"
  11. tunable=""
  12. ns=""
  13. top_ns=""
  14. max_name_len=0
  15. max_alias_len=0
  16. }
  17. # Skip over blank lines and comments.
  18. /^#/ {
  19. next
  20. }
  21. /^[ \t]*$/ {
  22. next
  23. }
  24. # Beginning of either a top namespace, tunable namespace or a tunable, decided
  25. # on the current value of TUNABLE, NS or TOP_NS.
  26. $2 == "{" {
  27. if (top_ns == "") {
  28. top_ns = $1
  29. }
  30. else if (ns == "") {
  31. ns = $1
  32. }
  33. else if (tunable == "") {
  34. tunable = $1
  35. }
  36. else {
  37. printf ("Unexpected occurrence of '{': %s:%d\n", FILENAME, FNR)
  38. exit 1
  39. }
  40. next
  41. }
  42. # End of either a top namespace, tunable namespace or a tunable.
  43. $1 == "}" {
  44. if (tunable != "") {
  45. # Tunables definition ended, now fill in default attributes.
  46. if (!types[top_ns,ns,tunable]) {
  47. types[top_ns,ns,tunable] = "STRING"
  48. }
  49. if (!minvals[top_ns,ns,tunable]) {
  50. minvals[top_ns,ns,tunable] = min_of[types[top_ns,ns,tunable]]
  51. }
  52. if (!maxvals[top_ns,ns,tunable]) {
  53. maxvals[top_ns,ns,tunable] = max_of[types[top_ns,ns,tunable]]
  54. }
  55. if (!env_alias[top_ns,ns,tunable]) {
  56. env_alias[top_ns,ns,tunable] = "{0}"
  57. }
  58. len = length(top_ns"."ns"."tunable)
  59. if (len > max_name_len)
  60. max_name_len = len
  61. tunable = ""
  62. }
  63. else if (ns != "") {
  64. ns = ""
  65. }
  66. else if (top_ns != "") {
  67. top_ns = ""
  68. }
  69. else {
  70. printf ("syntax error: extra }: %s:%d\n", FILENAME, FNR)
  71. exit 1
  72. }
  73. next
  74. }
  75. # Everything else, which could either be a tunable without any attributes or a
  76. # tunable attribute.
  77. {
  78. if (ns == "") {
  79. printf("Line %d: Invalid tunable outside a namespace: %s\n", NR, $0)
  80. exit 1
  81. }
  82. if (tunable == "") {
  83. # We encountered a tunable without any attributes, so note it with a
  84. # default.
  85. types[top_ns,ns,$1] = "STRING"
  86. next
  87. }
  88. # Otherwise, we have encountered a tunable attribute.
  89. split($0, arr, ":")
  90. attr = gensub(/^[ \t]+|[ \t]+$/, "", "g", arr[1])
  91. val = gensub(/^[ \t]+|[ \t]+$/, "", "g", arr[2])
  92. if (attr == "type") {
  93. types[top_ns,ns,tunable] = val
  94. }
  95. else if (attr == "minval") {
  96. minvals[top_ns,ns,tunable] = val
  97. }
  98. else if (attr == "maxval") {
  99. maxvals[top_ns,ns,tunable] = val
  100. }
  101. else if (attr == "env_alias") {
  102. env_alias[top_ns,ns,tunable] = sprintf("\"%s\"", val)
  103. len = length(val)
  104. if (len > max_alias_len)
  105. max_alias_len = len
  106. }
  107. else if (attr == "default") {
  108. if (types[top_ns,ns,tunable] == "STRING") {
  109. default_val[top_ns,ns,tunable] = sprintf(".strval = \"%s\"", val);
  110. }
  111. else {
  112. default_val[top_ns,ns,tunable] = sprintf(".numval = %s", val)
  113. }
  114. }
  115. }
  116. END {
  117. if (ns != "") {
  118. print "Unterminated namespace. Is a closing brace missing?"
  119. exit 1
  120. }
  121. # TYPES is an associative array where the index is the data
  122. # TYPESA is an indexed array where the value is the data
  123. # We sort TYPESA
  124. typecount = asorti (types, typesa)
  125. print "/* AUTOGENERATED by gen-tunables.awk. */"
  126. print "#ifndef _TUNABLES_H_"
  127. print "# error \"Do not include this file directly.\""
  128. print "# error \"Include tunables.h instead.\""
  129. print "#endif"
  130. # Now, the enum names
  131. print "\ntypedef enum"
  132. print "{"
  133. for (i = 1; i <= typecount; i++) {
  134. tnm = typesa[i];
  135. split (tnm, indices, SUBSEP);
  136. t = indices[1];
  137. n = indices[2];
  138. m = indices[3];
  139. printf (" TUNABLE_ENUM_NAME(%s, %s, %s),\n", t, n, m);
  140. }
  141. print "} tunable_id_t;\n"
  142. print "\n#ifdef TUNABLES_INTERNAL"
  143. # Internal definitions.
  144. print "# define TUNABLE_NAME_MAX " (max_name_len + 1)
  145. print "# define TUNABLE_ALIAS_MAX " (max_alias_len + 1)
  146. print "# include \"dl-tunable-types.h\""
  147. # Finally, the tunable list.
  148. print "static tunable_t tunable_list[] attribute_relro __attribute_used__ = {"
  149. for (i = 1; i <= typecount; i++) {
  150. tnm = typesa[i];
  151. split (tnm, indices, SUBSEP);
  152. t = indices[1];
  153. n = indices[2];
  154. m = indices[3];
  155. printf (" {TUNABLE_NAME_S(%s, %s, %s)", t, n, m)
  156. printf (", {TUNABLE_TYPE_%s, %s, %s}, {%s}, {%s}, false, %s},\n",
  157. types[t,n,m], minvals[t,n,m], maxvals[t,n,m], default_val[t,n,m],
  158. default_val[t,n,m], env_alias[t,n,m]);
  159. }
  160. print "};"
  161. # Map of tunable with environment variables aliases used during parsing. */
  162. print "\nstatic const tunable_id_t tunable_env_alias_list[] ="
  163. printf "{\n"
  164. for (i = 1; i <= typecount; i++) {
  165. tnm = typesa[i];
  166. split (tnm, indices, SUBSEP);
  167. t = indices[1];
  168. n = indices[2];
  169. m = indices[3];
  170. if (env_alias[t,n,m] != "{0}") {
  171. printf (" TUNABLE_ENUM_NAME(%s, %s, %s),\n", t, n, m);
  172. }
  173. }
  174. printf "};\n"
  175. print "#endif"
  176. }