about summary refs log tree commit diff
path: root/scripts/gen-conf.awk
blob: 1370646f585c293d3a0194ae19c406ea4dfb8f31 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# Generate confdefs-defs.h with definitions for {CONF}_DEF for each
# configuration variable that getconf or sysconf may use.  Currently it is
# equipped only to generate such macros for specification macros and for
# SYSCONF macros in the _POSIX namespace.

BEGIN {
  PROCINFO["sorted_in"] = "@val_type_asc"
  prefix = ""
}

$1 ~ /^#/ || $0 ~ /^\s*$/ {
  next
}

# Begin a new prefix.
$2 == "{" {
  split ($1, arr, ":")
  type = arr[1]
  prefix = arr[2]
  if (arr[3] != "")
    sc_prefix = arr[3]
  else
    sc_prefix = "_SC"
  next
}

$1 == "}" {
  prefix = ""
  type = ""
  sc_prefix = ""
  next
}

{
  if (prefix == "" && type == "" && sc_prefix == "") {
    print "Syntax error" > "/dev/stderr"
    exit 1
  }

  # The prefix and variable names are indices and the value indicates what type
  # of variable it is.  The possible options are:
  # CONFSTR: A configuration string
  # SYSCONF: A numeric value
  # SPEC: A specification
  sc_prefixes[prefix][$1] = sc_prefix
  conf[prefix][$1] = type
}

ENDFILE {
  print "/* Autogenerated by gen-conf.awk.  */\n"

  # Generate macros that specify if a sysconf macro is defined and/or set.
  for (p in conf) {
    for (c in conf[p]) {
      printf "#ifndef _%s_%s\n", p, c
      printf "# define _%s_%s_DEF CONF_DEF_UNDEFINED\n", p, c
      # CONFSTR have string values and they are not set or unset.
      if (conf[p][c] != "CONFSTR") {
	printf "#else\n"
	printf "# if _%s_%s > 0\n", p, c
	printf "#  define _%s_%s_DEF CONF_DEF_DEFINED_SET\n", p, c
	printf "# else\n"
	printf "#  define _%s_%s_DEF CONF_DEF_DEFINED_UNSET\n", p, c
	printf "# endif\n"
      }
      printf "#endif\n\n"

      # Build a name -> sysconf number associative array to print a C array at
      # the end.
      if (conf[p][c] == "SPEC") {
	name = sprintf ("%s_%s", p, c)
	num = sprintf ("%s_%s", sc_prefixes[p][c], c)
	spec[name] = num
      }
    }
  }

  # Print the specification array.  Define the macro NEED_SPEC_ARRAY before
  # including confdefs.h to make it available in the compilation unit.
  print "#if NEED_SPEC_ARRAY"
  print "static const struct { const char *name; int num; } specs[] ="
  print "  {"
  for (s in spec) {
    printf "    { \"%s\", %s },\n", s, spec[s]
  }
  print "  };"
  print "static const int nspecs = sizeof (specs) / sizeof (specs[0]);"
  print "#endif"
}