1: #!/usr/bin/perl -w
2: #
3: # Generate sudo_defs_table and associated defines
4: #
5: # Input should be formatted thusly:
6: #
7: # var_name
8: # TYPE
9: # description (or NULL)
10: # array of struct def_values if TYPE == T_TUPLE
11:
12: # Deal with optional -o (output) argument
13: if ($#ARGV > 0 && $ARGV[0] eq "-o") {
14: shift;
15: $header = $cfile = shift;
16: $header .= '.h';
17: $cfile .= '.c';
18: }
19: die "usage: $0 [input_file]\n" unless $#ARGV == -1 || $#ARGV == 0;
20:
21: $infile = $ARGV[0] || "def_data.in";
22: if (!defined($header)) {
23: $header = $infile;
24: $header =~ s/(\.in)?$/.h/;
25: }
26: if (!defined($cfile)) {
27: $cfile = $infile;
28: $cfile =~ s/(\.in)?$/.c/;
29: }
30:
31: open(IN, "<$infile") || die "$0: can't open $infile: $!\n";
32: open(HEADER, ">$header") || die "$0: can't open $header: $!\n";
33: open(CFILE, ">$cfile") || die "$0: can't open $cfile: $!\n";
34:
35: $count = 0;
36: @tuple_values = ( "never" );
37: @records = ();
38: while(<IN>) {
39: chomp;
40: s/\s*#.*$//;
41: next if /^\s*$/;
42:
43: if (/^\S/) {
44: # Store previous record and begin new one
45: $records[$count++] = [$var, $type, $desc, $values, $callback] if defined($var);
46:
47: $var = $_;
48: $type = '';
49: $desc = undef;
50: $values = undef;
51: $callback = undef;
52: $field = 0;
53: } else {
54: $field++;
55: s/^\s+//;
56: s/\s+$//;
57: if ($field == 1) {
58: # type
59: $type = $_;
60: } elsif ($field == 2) {
61: # description
62: if ($_ eq "NULL") {
63: $desc = "NULL";
64: } else {
65: # Strip leading and trailing double quote and escape the rest
66: s/^"//;
67: s/"$//;
68: s/"/\\"/g;
69: $desc = "N_(\"$_\")";
70: }
71: } elsif ($field == 3 || $field == 4) {
72: if (s/^\*//) {
73: $callback = $_;
74: } else {
75: die "$0: syntax error near line $.\n" if $type !~ /^T_TUPLE/;
76: $values = [ split ];
77: foreach $v (@$values) {
78: push(@tuple_values, $v) unless grep(/^$v$/, @tuple_values);
79: }
80: }
81: } else {
82: die "$0: syntax error near line $.\n";
83: }
84: }
85: }
86: $records[$count++] = [$var, $type, $desc, $values, $callback] if defined($var);
87:
88: # Print out value arrays
89: for ($i = 0; $i < $count; $i++) {
90: if (defined($records[$i]->[3])) {
91: die "Values list specified for non-tuple\n" unless
92: $records[$i]->[1] =~ /^T_TUPLE/;
93: printf CFILE "static struct def_values def_data_%s[] = {\n", $records[$i]->[0];
94: foreach (@{$records[$i]->[3]}) {
95: print CFILE " { \"$_\", $_ },\n";
96: }
97: print CFILE " { NULL, 0 },\n";
98: print CFILE "};\n\n";
99: }
100: }
101:
102: # Print each record
103: print CFILE "struct sudo_defs_types sudo_defs_table[] = {\n {\n";
104: for ($i = 0; $i < $count; $i++) {
105: &print_record($records[$i], $i);
106: }
107: print CFILE "\tNULL, 0, NULL\n }\n};\n";
108:
109: # Print out def_tuple
110: if (@tuple_values) {
111: print HEADER "\nenum def_tuple {\n";
112: for ($i = 0; $i <= $#tuple_values; $i++) {
113: printf HEADER "\t%s%s\n", $tuple_values[$i],
114: $i != $#tuple_values ? "," : "";
115: }
116: print HEADER "};\n";
117: }
118:
119: close(IN);
120: close(HEADER);
121: close(CFILE);
122:
123: sub print_record {
124: my ($rec, $recnum) = @_;
125: my ($i, $v, $defname);
126: # each variable gets a macro to access its value
127: for ($rec->[1]) {
128: if (/^T_INT/) { $v = "ival"; }
129: elsif (/^T_UINT/) { $v = "uival"; }
130: elsif (/^T_STR/) { $v = "str"; }
131: elsif (/^T_FLAG/) { $v = "flag"; }
132: elsif (/^T_MODE/) { $v = "mode"; }
133: elsif (/^T_LIST/) { $v = "list"; }
134: elsif (/^T_LOGFAC/) { $v = "ival"; }
135: elsif (/^T_LOGPRI/) { $v = "ival"; }
136: elsif (/^T_TUPLE/) { $v = "tuple"; }
137: elsif (/^T_FLOAT/) { $v = "fval"; }
138: else { die "$0: unknown defaults type: $_\n"; }
139: }
140: printf HEADER "#define %-23s (sudo_defs_table[$recnum].sd_un.${v})\n",
141: "def_$rec->[0]";
142:
143: $defname = "I_" . uc($rec->[0]);
144: printf HEADER "#define %-24s%d", $defname, $recnum;
145: #print HEADER "\t/* $rec->[2] */" if defined($rec->[2]);
146: print HEADER "\n";
147:
148: print CFILE "\t\"$rec->[0]\", $rec->[1],\n\t$rec->[2],\n";
149: if (defined($rec->[3])) {
150: printf CFILE "\tdef_data_$rec->[0],\n";
151: } else {
152: printf CFILE "\tNULL,\n";
153: }
154: printf CFILE "\t$rec->[4],\n" if defined($rec->[4]);
155: print CFILE " }, {\n";
156: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>