route_types.pl 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #!/usr/bin/perl
  2. ##
  3. ## Scan a file of route-type definitions (see eg route_types.txt) and
  4. ## generate a corresponding header file with:
  5. ##
  6. ## - enum of Zserv route-types
  7. ## - redistribute strings for the various Quagga daemons
  8. ##
  9. ## See route_types.txt for the format.
  10. ##
  11. ##
  12. ## Copyright (C) 2009 David Lamparter.
  13. ## This file is part of GNU Zebra.
  14. ##
  15. ## GNU Zebra is free software; you can redistribute it and/or modify it
  16. ## under the terms of the GNU General Public License as published by the
  17. ## Free Software Foundation; either version 2, or (at your option) any
  18. ## later version.
  19. ##
  20. ## GNU Zebra is distributed in the hope that it will be useful, but
  21. ## WITHOUT ANY WARRANTY; without even the implied warranty of
  22. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  23. ## General Public License for more details.
  24. ##
  25. ## You should have received a copy of the GNU General Public License
  26. ## along with GNU Zebra; see the file COPYING. If not, write to the Free
  27. ## Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  28. ## 02111-1307, USA.
  29. ##
  30. use strict;
  31. # input processing
  32. #
  33. my @protos;
  34. my %protodetail;
  35. my %daemons;
  36. while (<STDIN>) {
  37. # skip comments and empty lines
  38. next if (/^\s*(#|$)/);
  39. # strip whitespace
  40. chomp;
  41. $_ =~ s/^\s*//;
  42. $_ =~ s/\s*$//;
  43. # match help strings
  44. if (/^(ZEBRA_ROUTE_[^\s]+)\s*,\s*"(.*)"$/) {
  45. $protodetail{$1}->{'longhelp'} = $2;
  46. next;
  47. }
  48. $_ =~ s/\s*,\s*/,/g;
  49. # else: 7-field line
  50. my @f = split(/,/, $_);
  51. unless (@f == 7) {
  52. die "invalid input on route_types line $.\n";
  53. }
  54. my $proto = $f[0];
  55. $f[3] = $1 if ($f[3] =~ /^'(.*)'$/);
  56. $f[6] = $1 if ($f[6] =~ /^"(.*)"$/);
  57. $protodetail{$proto} = {
  58. "number" => scalar @protos,
  59. "type" => $f[0],
  60. "cname" => $f[1],
  61. "daemon" => $f[2],
  62. "char" => $f[3],
  63. "ipv4" => int($f[4]),
  64. "ipv6" => int($f[5]),
  65. "shorthelp" => $f[6],
  66. };
  67. push @protos, $proto;
  68. $daemons{$f[2]} = {
  69. "ipv4" => int($f[4]),
  70. "ipv6" => int($f[5])
  71. } unless ($f[2] eq "NULL");
  72. }
  73. # output
  74. printf <<EOF, $ARGV[0];
  75. /* Auto-generated from route_types.txt by %s. */
  76. /* Do not edit! */
  77. #ifndef _QUAGGA_ROUTE_TYPES_H
  78. #define _QUAGGA_ROUTE_TYPES_H
  79. /* Zebra route's types. */
  80. EOF
  81. push @protos, "ZEBRA_ROUTE_MAX";
  82. my (@protosv4, @protosv6) = ((), ());
  83. for (my $c = 0; $c < @protos; $c++) {
  84. my $p = $protos[$c];
  85. printf "#define %-32s %d\n", $p, $c;
  86. push @protosv4, $p if ($protodetail{$p}->{"ipv4"});
  87. push @protosv6, $p if ($protodetail{$p}->{"ipv6"});
  88. }
  89. pop @protos;
  90. sub codelist {
  91. my (@protos) = @_;
  92. my (@lines) = ();
  93. my $str = " \"Codes: ";
  94. for my $p (@protos) {
  95. my $s = sprintf("%s - %s, ",
  96. $protodetail{$p}->{"char"},
  97. $protodetail{$p}->{"shorthelp"});
  98. if (length($str . $s) > 70) {
  99. $str =~ s/ $//;
  100. push @lines, $str . "%s\" \\\n";
  101. $str = " \" ";
  102. }
  103. $str .= $s;
  104. }
  105. $str =~ s/ $//;
  106. push @lines, $str . "%s\" \\\n";
  107. push @lines, " \" > - selected route, * - FIB route%s%s\", \\\n";
  108. my @nl = ();
  109. for (my $c = 0; $c < @lines + 1; $c++) {
  110. push @nl, "VTY_NEWLINE"
  111. }
  112. return join("", @lines) ." ". join(", ", @nl);
  113. }
  114. print "\n";
  115. printf "#define SHOW_ROUTE_V4_HEADER \\\n%s\n", codelist(@protosv4);
  116. printf "#define SHOW_ROUTE_V6_HEADER \\\n%s\n", codelist(@protosv6);
  117. print "\n";
  118. sub collect {
  119. my ($daemon, $ipv4, $ipv6) = @_;
  120. my (@names, @help) = ((), ());
  121. for my $p (@protos) {
  122. next if ($protodetail{$p}->{"daemon"} eq $daemon && $daemon ne "zebra");
  123. next unless (($ipv4 && $protodetail{$p}->{"ipv4"})
  124. || ($ipv6 && $protodetail{$p}->{"ipv6"}));
  125. push @names, $protodetail{$p}->{"cname"};
  126. push @help, " \"".$protodetail{$p}->{"longhelp"}."\\n\"";
  127. }
  128. return ("\"(" . join("|", @names) . ")\"", join(" \\\n", @help));
  129. }
  130. for my $daemon (sort keys %daemons) {
  131. next unless ($daemons{$daemon}->{"ipv4"} || $daemons{$daemon}->{"ipv6"});
  132. printf "/* %s */\n", $daemon;
  133. if ($daemons{$daemon}->{"ipv4"} && $daemons{$daemon}->{"ipv6"}) {
  134. my ($names, $help) = collect($daemon, 1, 1);
  135. printf "#define QUAGGA_REDIST_STR_%s \\\n %s\n", uc $daemon, $names;
  136. printf "#define QUAGGA_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help;
  137. ($names, $help) = collect($daemon, 1, 0);
  138. printf "#define QUAGGA_IP_REDIST_STR_%s \\\n %s\n", uc $daemon, $names;
  139. printf "#define QUAGGA_IP_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help;
  140. ($names, $help) = collect($daemon, 0, 1);
  141. printf "#define QUAGGA_IP6_REDIST_STR_%s \\\n %s\n", uc $daemon, $names;
  142. printf "#define QUAGGA_IP6_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help;
  143. } else {
  144. my ($names, $help) = collect($daemon,
  145. $daemons{$daemon}->{"ipv4"}, $daemons{$daemon}->{"ipv6"});
  146. printf "#define QUAGGA_REDIST_STR_%s \\\n %s\n", uc $daemon, $names;
  147. printf "#define QUAGGA_REDIST_HELP_STR_%s \\\n%s\n", uc $daemon, $help;
  148. }
  149. print "\n";
  150. }
  151. print <<EOF;
  152. #ifdef QUAGGA_DEFINE_DESC_TABLE
  153. struct zebra_desc_table
  154. {
  155. unsigned int type;
  156. const char *string;
  157. char chr;
  158. };
  159. #define DESC_ENTRY(T,S,C) [(T)] = { (T), (S), (C) }
  160. static const struct zebra_desc_table route_types[] = {
  161. EOF
  162. for (my $c = 0; $c < @protos; $c++) {
  163. my $p = $protos[$c];
  164. printf " DESC_ENTRY\t(%s\t \"%s\",\t'%s' ),\n",
  165. $p.",", $protodetail{$p}->{"cname"}, $protodetail{$p}->{"char"};
  166. }
  167. print <<EOF;
  168. };
  169. #undef DESC_ENTRY
  170. #endif /* QUAGGA_DEFINE_DESC_TABLE */
  171. #endif /* _QUAGGA_ROUTE_TYPES_H */
  172. EOF