sysvars.pl 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #!/usr/bin/perl
  2. use strict;
  3. use integer;
  4. use File::Basename;
  5. sub c_name($) {
  6. my($s) = @_;
  7. $s =~ s/[^A-Za-z0-9_]+/_/g;
  8. return $s;
  9. }
  10. die "Usage: $0 infile hfile cfile\n" unless (scalar @ARGV >= 3);
  11. my($infile, $hfile, $cfile) = @ARGV;
  12. my $err = 0;
  13. open(my $in, '<', $infile) or die "$0: $infile: $!\n";
  14. my $ns;
  15. my %vars;
  16. my %nsprefix;
  17. my $line = 0;
  18. while (defined(my $l = <$in>)) {
  19. $line++;
  20. $l =~ s/^\s+//;
  21. $l =~ s/\s+$//;
  22. next if ($l =~ /^(\#.*)?$/);
  23. if ($l =~ /^\@(\w+)(\s+([\w\.]+))?/) {
  24. $ns = $1;
  25. if (!defined($vars{$ns})) {
  26. $vars{$ns} = {};
  27. }
  28. $nsprefix{$ns} = $3;
  29. next;
  30. }
  31. if (!defined{$ns}) {
  32. print STDERR "$0:$infile:$line: variable without namespace\n";
  33. $err++;
  34. next;
  35. }
  36. my($var,$type,$defval) = split(/\s+/, $l);
  37. if (!defined($type)) {
  38. print STDERR "$0:$infile:$line: variable $var lacks type\n";
  39. $err++;
  40. next;
  41. }
  42. $vars{$ns}->{$var} = [$type, $defval];
  43. }
  44. close($in);
  45. exit 1 if ($err);
  46. my @nslist = sort keys(%vars);
  47. my %nsfirst;
  48. my %nscount;
  49. my @varname = (undef);
  50. my @varenum = ('sysvar_null');
  51. my @vartype = ("\t[sysvar_null] = SYSVAR_TYPE(nulltype),\n");
  52. my @vardef;
  53. my $cnt = 1;
  54. foreach my $ns (@nslist) {
  55. $nsfirst{$ns} = $cnt;
  56. foreach my $var (sort keys(%{$vars{$ns}})) {
  57. my($type, $defval) = @{$vars{$ns}->{$var}};
  58. push(@varname, $nsprefix{$ns}.$var);
  59. my $ename = c_name($ns.'.'.$var);
  60. push(@varenum, $ename);
  61. push(@vartype, "\t[$ename] = SYSVAR_TYPE($type),\n");
  62. if (defined($defval)) {
  63. # Add mangling here if needed
  64. push(@vardef, "\t[$ename] = { .v_$type = $defval },\n");
  65. }
  66. $cnt++;
  67. }
  68. $nscount{$ns} = $cnt - $nsfirst{$ns};
  69. }
  70. open(my $h, '>', $hfile) or die "$0:$hfile: $!\n";
  71. my $htag = c_name(uc(basename($hfile)));
  72. print $h "#ifndef $htag\n";
  73. print $h "#define $htag\n\n";
  74. print $h "#include \"sysvar_common.h\"\n\n";
  75. print $h "enum sysvar_ns {\n";
  76. print $h map { "\tsysvar_ns_$_,\n" } @nslist;
  77. print $h "\tsysvar_nscount\n};\n\n";
  78. print $h "enum sysvars {\n";
  79. print $h map { "\t$_,\n" } @varenum;
  80. print $h "\tsysvar_count\n};\n\n";
  81. push(@varenum, 'sysvar_count');
  82. foreach my $ns (@nslist) {
  83. print $h "#define sysvar_ns_${ns}_start ", $varenum[$nsfirst{$ns}], "\n";
  84. print $h "#define sysvar_ns_${ns}_end ", $varenum[$nsfirst{$ns}+$nscount{$ns}], "\n";
  85. print $h "#define sysvar_ns_${ns}_count ", $nscount{$ns}, "\n";
  86. }
  87. print $h "\n";
  88. print $h "extern const char * const sysvar_name[$cnt];\n";
  89. print $h "extern const sysvar_type_t sysvar_type[$cnt];\n";
  90. print $h "extern const sysvar_t sysvar_defval[$cnt];\n";
  91. print $h "extern sysvar_t sysvar_val[$cnt];\n";
  92. print $h "extern bool sysvar_isset[$cnt];\n";
  93. print $h "\n#endif /* $htag */\n";
  94. close($h);
  95. open(my $c, '>', $cfile) or die "$0:$cfile: $!\n";
  96. print $c "#include <stddef.h>\n";
  97. print $c "#include \"", basename($hfile), "\"\n\n";
  98. print $c "const char * const sysvar_name[$cnt] = {\n";
  99. print $c "\tNULL,\n";
  100. foreach my $ns (@nslist) {
  101. print $c "\n\t/* ---- $ns ---- */\n";
  102. my $v_end = $nsfirst{$ns} + $nscount{$ns};
  103. for (my $v = $nsfirst{$ns}; $v < $v_end; $v++) {
  104. print $c "\t\"", $varname[$v], "\",\n";
  105. }
  106. }
  107. print $c "};\n";
  108. print $c "const sysvar_type_t sysvar_type[$cnt] = {\n";
  109. print $c @vartype;
  110. print $c "};\n";
  111. print $c "const sysvar_t sysvar_defval[$cnt] = {\n";
  112. print $c @vardef;
  113. print $c "};\n";
  114. print $c "sysvar_t sysvar_val[$cnt];\n";
  115. print $c "bool sysvar_isset[$cnt];\n";
  116. close($c);