• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/perl
2# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3
4sub maxprefix {
5	my $p = shift(@_);
6	for (@_) {
7		chop $p until /^\Q$p/;
8	}
9	$p =~ s/_[^_]*$/_/;
10	$p = "CEC_OP_CEC_" if ($p =~ /CEC_OP_CEC_VERSION_/);
11	return $p;
12}
13
14my $cur_msg;
15
16sub process_func
17{
18	my $feature = shift;
19	my $func = shift;
20	my $func_args = $func;
21	$func =~ s/\(.*//;
22	my $msg = $func;
23	$msg =~ s/([a-z])/\U\1/g;
24	$func =~ s/cec_msg//;
25	my $opt = $func;
26	$opt =~ s/_([a-z])/\U\1/g;
27	$func_args =~ s/.*\((.*)\).*/\1/;
28	my $has_reply = $func_args =~ /^int reply/;
29	$func_args =~ s/^int reply,? ?//;
30	my $arg_names;
31	my $arg_ptrs;
32	my $name, $type, $size;
33	my $msg_dash_name, $msg_lc_name;
34	my @enum, $val;
35	my $usage;
36	my $has_digital = $func_args =~ /cec_op_digital_service_id/;
37	my $has_ui_command = $func_args =~ /cec_op_ui_command/;
38	my $has_short_aud_descr = $func_args =~ /num_descriptors/;
39
40	my @ops_args = split(/, */, $func_args);
41	if ($has_digital) {
42		$func_args =~ s/const struct cec_op_digital_service_id \*digital/__u8 service_id_method, __u8 dig_bcast_system, __u16 transport_id, __u16 service_id, __u16 orig_network_id, __u16 program_number, __u8 channel_number_fmt, __u16 major, __u16 minor/;
43	}
44	if ($has_ui_command) {
45		$func_args =~ s/const struct cec_op_ui_command \*ui_cmd/__u8 ui_cmd, __u8 has_opt_arg, __u8 play_mode, __u8 ui_function_media, __u8 ui_function_select_av_input, __u8 ui_function_select_audio_input, __u8 ui_bcast_type, __u8 ui_snd_pres_ctl, __u8 channel_number_fmt, __u16 major, __u16 minor/;
46	}
47	if ($has_short_aud_descr) {
48		$func_args =~ s/const __u32 \*descriptors/__u8 descriptor1, __u8 descriptor2, __u8 descriptor3, __u8 descriptor4/;
49		$func_args =~ s/const __u8 \*audio_format_id, const __u8 \*audio_format_code/__u8 audio_format_id1, __u8 audio_format_code1, __u8 audio_format_id2, __u8 audio_format_code2, __u8 audio_format_id3, __u8 audio_format_code3, __u8 audio_format_id4, __u8 audio_format_code4/;
50	}
51	my @args = split(/, */, $func_args);
52	my $has_struct = $func_args =~ /struct/;
53	return if ($func_args =~ /__u\d+\s*\*/);
54
55	my $cec_msg = $msg;
56	while ($cec_msg =~ /_/ && !exists($msgs{$cec_msg})) {
57		$cec_msg =~ s/_[^_]*$//;
58	}
59	return unless ($cec_msg =~ /_/);
60
61	my $msg_name = $cec_msg;
62	$msg_name =~ s/CEC_MSG_//;
63	$msg_dash_name = $msg;
64	$msg_dash_name =~ s/CEC_MSG_//;
65	$msg_dash_name =~ s/([A-Z])/\l\1/g;
66	$msg_dash_name =~ s/_/-/g;
67	$msg_lc_name = $msg;
68	$msg_lc_name =~ s/([A-Z])/\l\1/g;
69	$cur_msg = $msg;
70
71	if ($cec_msg eq $msg) {
72		if ($cec_msg =~ /_CDC_/ && !$cdc_case) {
73			$cdc_case = 1;
74			$logswitch .= "\tcase CEC_MSG_CDC_MESSAGE:\n";
75			$logswitch .= "\tswitch (msg->msg[4]) {\n";
76		}
77		if ($cec_msg =~ /_HTNG_/ && !$htng_case) {
78			$htng_case = 1;
79			$cdc_case = 0;
80			$std_logswitch = $logswitch;
81			$logswitch = "";
82		}
83		if ($cdc_case) {
84			$cdcmsgtable .= "\t{ $cec_msg, \"$msg_name\" },\n";
85		} elsif ($htng_case) {
86			$htngmsgtable .= "\t{ $cec_msg, \"$msg_name\" },\n";
87		} else {
88			$msgtable .= "\t{ $cec_msg, \"$msg_name\" },\n";
89		}
90		if (@args == 0) {
91			$logswitch .= "\tcase $cec_msg:\n";
92			$logswitch .= "\t\tprintf(\"$msg_name (0x%02x)\\n\", $cec_msg);\n";
93			$logswitch .= "\t\tbreak;\n\n";
94		} else {
95			$logswitch .= "\tcase $cec_msg: {\n";
96			foreach (@ops_args) {
97				($type, $name) = /(.*?) ?([a-zA-Z_]\w+)$/;
98				if ($type =~ /struct .*\*/) {
99					$type =~ s/ \*//;
100					$type =~ s/const //;
101				}
102				if ($name eq "rc_profile" || $name eq "dev_features") {
103					$logswitch .= "\t\tconst __u8 *$name = NULL;\n";
104				} elsif ($type eq "const char *") {
105					$logswitch .= "\t\tchar $name\[16\];\n";
106				} elsif ($type eq "const __u32 *") {
107					$logswitch .= "\t\t__u32 $name\[4\];\n";
108				} elsif ($type eq "const __u8 *") {
109					$logswitch .= "\t\t__u8 $name\[4\];\n";
110				} elsif ($type =~ /struct/) {
111					$logswitch .= "\t\t$type $name = {};\n";
112				} else {
113					$logswitch .= "\t\t$type $name;\n";
114				}
115			}
116			if ($cdc_case) {
117				$logswitch .= "\t\t__u16 phys_addr;\n";
118			}
119			my $ops_lc_name = $msg_lc_name;
120			$ops_lc_name =~ s/^cec_msg/cec_ops/;
121			$logswitch .= "\n\t\t$ops_lc_name(msg";
122			if ($cdc_case) {
123				$logswitch .= ", &phys_addr";
124			}
125			foreach (@ops_args) {
126				($type, $name) = /(.*?) ?([a-zA-Z_]\w+)$/;
127				if ($type eq "const char *" ||
128				    $type eq "const __u8 *" ||
129				    $type eq "const __u32 *") {
130					$logswitch .= ", $name";
131				} else {
132					$logswitch .= ", &$name";
133				}
134			}
135			$logswitch .= ");\n";
136			$logswitch .= "\t\tprintf(\"$msg_name (0x%02x):\\n\", $cec_msg);\n";
137			if ($cdc_case) {
138				$logswitch .= "\t\tlog_arg(&arg_phys_addr, \"phys-addr\", phys_addr);\n";
139			}
140			foreach (@ops_args) {
141				($type, $name) = /(.*?) ?([a-zA-Z_]\w+)$/;
142				my $dash_name = $name;
143				$dash_name =~ s/_/-/g;
144				if ($name eq "rc_profile" || $name eq "dev_features") {
145					$logswitch .= "\t\tlog_features(&arg_$name, \"$dash_name\", $name);\n";
146				} elsif ($name eq "digital") {
147					$logswitch .= "\t\tlog_digital(\"$dash_name\", &$name);\n";
148				} elsif ($name eq "ui_cmd") {
149					$logswitch .= "\t\tlog_ui_command(\"$dash_name\", &$name);\n";
150				} elsif ($name eq "vendor_id") {
151					$logswitch .= "\t\tlog_vendor_id(\"$dash_name\", $name);\n";
152				} elsif ($name eq "rec_src") {
153					$logswitch .= "\t\tlog_rec_src(\"$dash_name\", &$name);\n";
154				} elsif ($name eq "tuner_dev_info") {
155					$logswitch .= "\t\tlog_tuner_dev_info(\"$dash_name\", &$name);\n";
156				} elsif ($name eq "descriptors") {
157					$logswitch .= "\t\tlog_descriptors(\"$dash_name\", num_descriptors, $name);\n";
158				} elsif ($name eq "audio_format_id" || $name eq "audio_format_code") {
159					$logswitch .= "\t\tlog_u8_array(\"$dash_name\", num_descriptors, $name);\n";
160				} else {
161					$logswitch .= "\t\tlog_arg(&arg_$name, \"$dash_name\", $name);\n";
162				}
163			}
164			$logswitch .= "\t\tbreak;\n\t}\n";
165		}
166	}
167	return if $has_struct;
168
169	$options .= "\tOpt$opt,\n";
170	$messages .= "\t\t$cec_msg,\n";
171	if (@args == 0) {
172		$messages .= "\t\t0, { }, { },\n";
173		$long_opts .= "\t{ \"$msg_dash_name\", no_argument, 0, Opt$opt }, \\\n";
174		$usage .= "\t\"  --" . sprintf("%-30s", $msg_dash_name) . "Send $msg_name message (\" xstr($cec_msg) \")\\n\"\n";
175		$usage_msg{$msg} = $usage;
176		$switch .= "\tcase Opt$opt: {\n";
177		$switch .= "\t\t$msg_lc_name(&msg";
178		$switch .= ", reply" if $has_reply;
179		$switch .= ");\n\t\tbreak;\n\t}\n\n";
180	} else {
181		$long_opts .= "\t{ \"$msg_dash_name\", required_argument, 0, Opt$opt }, \\\n";
182		$usage .= "\t\"  --$msg_dash_name";
183		my $prefix = "\t\"    " . sprintf("%-30s", " ");
184		my $sep = " ";
185		foreach (@args) {
186			($type, $name) = /(.*?) ?([a-zA-Z_]\w+)$/;
187			$name =~ s/_/-/g;
188			$usage .= "$sep$name=<val>";
189			$sep = ",";
190		}
191		$usage .= "\\n\"\n";
192		foreach (@args) {
193			($type, $name) = /(.*?) ?([a-zA-Z_]\w+)$/;
194			@enum = @{$types{$name}};
195			next if !scalar(@enum);
196			$name =~ s/_/-/g;
197			$usage .= $prefix . "'$name' can have these values:\\n\"\n";
198			my $common_prefix = maxprefix(@enum);
199			foreach (@enum) {
200				my $e = $_;
201				s/^$common_prefix//;
202				s/([A-Z])/\l\1/g;
203				s/_/-/g;
204				$usage .= $prefix . "    $_ (\" xstr($e) \")\\n\"\n";
205			}
206		}
207		$usage .= $prefix . "Send $msg_name message (\" xstr($cec_msg) \")\\n\"\n";
208		$usage_msg{$msg} = $usage;
209		$switch .= "\tcase Opt$opt: {\n";
210		foreach (@args) {
211			($type, $name) = /(.*?) ?([a-zA-Z_]\w+)$/;
212			if ($type =~ /char/) {
213				$switch .= "\t\tconst char *$name = \"\";\n";
214			} else {
215				$switch .= "\t\t$type $name = 0;\n";
216			}
217		}
218		$switch .= "\n\t\twhile (*subs != '\\0') {\n";
219		$switch .= "\t\t\tswitch (cec_parse_subopt(&subs, opt->arg_names, &value)) {\n";
220		my $cnt = 0;
221		foreach (@args) {
222			($type, $name) = /(.*?) ?([a-zA-Z_]\w+)$/;
223			@enum = @{$types{$name}};
224			$switch .= "\t\t\tcase $cnt:\n";
225			if ($type =~ /char/) {
226				$switch .= "\t\t\t\t$name = value;\n";
227			} elsif (scalar(@enum) || $name eq "ui_cmd") {
228				$switch .= "\t\t\t\t$name = parse_enum(value, opt->args\[$cnt\]);\n";
229			} elsif ($name =~ /audio_out_delay/ || $name =~ /video_latency/) {
230				$switch .= "\t\t\t\t$name = parse_latency(value);\n";
231			} elsif ($name =~ /phys_addr/) {
232				$switch .= "\t\t\t\t$name = cec_parse_phys_addr(value);\n";
233			} else {
234				$switch .= "\t\t\t\t$name = strtol(value, 0L, 0);\n";
235			}
236			$switch .= "\t\t\t\tbreak;\n";
237			$cnt++;
238		}
239		$switch .= "\t\t\tdefault:\n";
240		$switch .= "\t\t\t\texit(1);\n";
241		$switch .= "\t\t\t}\n\t\t}\n";
242		$switch .= "\t\t$msg_lc_name(&msg";
243		$switch .= ", reply" if $has_reply;
244		foreach (@args) {
245			($type, $name) = /(.*?) ?([a-zA-Z_]\w+)$/;
246			$switch .= ", $name";
247		}
248		$switch .= ");\n\t\tbreak;\n\t}\n\n";
249
250		foreach (@args) {
251			($type, $name) = /(.*?) ?([a-zA-Z_]\w+)$/;
252			if ($arg_names ne "") {
253				$arg_names .= ", ";
254				$arg_ptrs .= ", ";
255			}
256			$arg_ptrs .= "&arg_$name";
257			$name =~ s/_/-/g;
258			$arg_names .= '"' . $name . '"';
259		}
260		$size = $#args + 1;
261		$messages .= "\t\t$size, { $arg_names },\n";
262		$messages .= "\t\t{ $arg_ptrs },\n";
263		foreach (@args) {
264			($type, $name) = /(.*?) ?([a-zA-Z_]\w+)$/;
265			@enum = @{$types{$name}};
266			$size = scalar(@enum);
267
268			if ($size && !defined($created_enum{$name})) {
269				$created_enum{$name} = 1;
270				$enums .= "static const struct cec_arg_enum_values type_$name\[\] = {\n";
271				my $common_prefix = maxprefix(@enum);
272				foreach (@enum) {
273					$val = $_;
274					s/^$common_prefix//;
275					s/([A-Z])/\l\1/g;
276					s/_/-/g;
277					$enums .= "\t{ \"$_\", $val },\n";
278				}
279				$enums .= "};\n\n";
280			}
281			if (!defined($created_arg{$name})) {
282				$created_arg{$name} = 1;
283				if ($type eq "__u8" && $size) {
284					$arg_structs .= "static const struct cec_arg arg_$name = {\n";
285					$arg_structs .= "\tCEC_ARG_TYPE_ENUM, $size, type_$name\n};\n\n";
286				} elsif ($type eq "__u8") {
287					$arg_structs .= "#define arg_$name arg_u8\n";
288				} elsif ($type eq "__u16") {
289					$arg_structs .= "#define arg_$name arg_u16\n";
290				} elsif ($type eq "__u32") {
291					$arg_structs .= "#define arg_$name arg_u32\n";
292				} elsif ($type eq "const char *") {
293					$arg_structs .= "#define arg_$name arg_string\n";
294				}
295			}
296		}
297	}
298	$messages .= "\t\t\"$msg_name\"\n";
299	$messages .= "\t}, {\n";
300	push @{$feature_usage{$feature}}, $msg;
301}
302
303while (<>) {
304	last if /\/\* Messages \*\//;
305}
306
307$comment = 0;
308$has_also = 0;
309$operand_name = "";
310$feature = "";
311
312while (<>) {
313	chomp;
314	last if /_CEC_UAPI_FUNCS_H/;
315	if (/^\/\*.*Feature \*\/$/) {
316		($feature) = /^\/\* (.*) Feature/;
317	}
318	elsif (/^\/\*.*General Protocol Messages \*\/$/) {
319		$feature = "Abort";
320	}
321	if ($operand_name ne "" && !/^#define/) {
322		@{$types{$operand_name}} = @ops;
323		undef @ops;
324		$operand_name = "";
325	}
326	if (/\/\*.*Operand \((.*)\)/) {
327		$operand_name = $1;
328		next;
329	}
330	s/\/\*.*\*\///;
331	if ($comment) {
332		if ($has_also) {
333			if (/CEC_MSG/) {
334				($also_msg) = /(CEC_MSG\S+)/;
335				push @{$feature_also{$feature}}, $also_msg;
336				if (!exists($feature_usage{$feature})) {
337					push @{$feature_usage{$feature}}, "";
338				}
339			}
340		} elsif (/^ \* Has also:$/) {
341			$has_also = 1;
342		}
343		$has_also = 0 if (/\*\//);
344		next unless /\*\//;
345		$comment = 0;
346		s/^.*\*\///;
347	}
348	if (/\/\*/) {
349		$comment = 1;
350		$has_also = 0;
351		next;
352	}
353	next if /^\s*$/;
354	if (/^\#define/) {
355		($name, $val) = /define (\S+)\s+(\S+)/;
356		if ($name =~ /^CEC_MSG/) {
357			$msgs{$name} = 1;
358		} elsif ($operand_name ne "" && $name =~ /^CEC_OP/) {
359			push @ops, $name;
360		}
361		next;
362	}
363}
364
365while (<>) {
366	chomp;
367	if (/^\/\*.*Feature \*\/$/) {
368		($feature) = /^\/\* (.*) Feature/;
369	}
370	elsif (/^\/\*.*General Protocol Messages \*\/$/) {
371		$feature = "Abort";
372	}
373	if (/\/\* broadcast \*\//) {
374		$usage_msg{$cur_msg} =~ s/"\)\\n"$/", bcast)\\n"/;
375	}
376	s/\/\*.*\*\///;
377	if ($comment) {
378		next unless /\*\//;
379		$comment = 0;
380		s/^.*\*\///;
381	}
382	if (/\/\*/) {
383		$comment = 1;
384		next;
385	}
386	next if /^\s*$/;
387	next if /cec_msg_reply_feature_abort/;
388	next if /cec_msg_htng_init/;
389	if (/^static (__)?inline(__)? void cec_msg.*\(.*\)/) {
390		s/static\s(__)?inline(__)?\svoid\s//;
391		s/struct cec_msg \*msg, //;
392		s/struct cec_msg \*msg//;
393		process_func($feature, $_);
394		next;
395	}
396	if (/^static (__)?inline(__)? void cec_msg/) {
397		$func = $_;
398		next;
399	}
400	if ($func ne "") {
401		$func .= $_;
402		next unless /\)$/;
403		$func =~ s/\s+/ /g;
404		$func =~ s/static\s(__)?inline(__)?\svoid\s//;
405		$func =~ s/struct cec_msg \*msg, //;
406		$func =~ s/struct cec_msg \*msg//;
407		process_func($feature, $func);
408		$func = "";
409	}
410}
411
412$options .= "\tOptHelpAll,\n";
413
414open(my $fh, '>', 'cec-parse-src-gen.h') or die "Could not open cec-parse-src-gen.h for writing";
415
416print $fh "\n\n";
417foreach (sort keys %feature_usage) {
418	$name = $_;
419	s/ /_/g;
420	s/([A-Z])/\l\1/g;
421	$usage_var = $_ . "_usage";
422	printf $fh "static const char *$usage_var =\n";
423	$usage = "";
424	foreach (@{$feature_usage{$name}}) {
425		$usage .= $usage_msg{$_};
426	}
427	foreach (@{$feature_also{$name}}) {
428		$usage .= $usage_msg{$_};
429	}
430	chop $usage;
431	$usage =~ s/"  --vendor-remote-button-up/VENDOR_EXTRA\n\t"  --vendor-remote-button-up/;
432	printf $fh "%s;\n\n", $usage;
433	s/_/-/g;
434	$opt = "OptHelp" . $name;
435	$opt =~ s/ //g;
436	$help .= "\tif (options[OptHelpAll] || options\[$opt\]) {\n";
437	$help .= "\t\tprintf(\"$name Feature:\\n\\n\");\n";
438	$help .= "\t\tprintf(\"\%s\\n\", $usage_var);\n\t}\n";
439}
440
441printf $fh "void cec_parse_usage_options(const char *options)\n{\n";
442printf $fh "%s}\n\n", $help;
443printf $fh "void cec_parse_msg_args(struct cec_msg &msg, int reply, const cec_msg_args *opt, int ch)\n{\n";
444printf $fh "\tchar *value, *subs = optarg;\n\n";
445printf $fh "\tswitch (ch) {\n";
446$switch =~ s/(service_id_method, dig_bcast_system, transport_id, service_id, orig_network_id, program_number, channel_number_fmt, major, minor)/args2digital_service_id(\1)/g;
447$switch =~ s/(ui_cmd, has_opt_arg, play_mode, ui_function_media, ui_function_select_av_input, ui_function_select_audio_input, ui_bcast_type, ui_snd_pres_ctl, channel_number_fmt, major, minor)/args2ui_command(\1)/g;
448$switch =~ s/(descriptor1, descriptor2, descriptor3, descriptor4)/args2short_descrs(\1)/g;
449$switch =~ s/(audio_format_id1, audio_format_code1, audio_format_id2, audio_format_code2, audio_format_id3, audio_format_code3, audio_format_id4, audio_format_code4)/args2short_aud_fmt_ids(audio_format_id1, audio_format_id2, audio_format_id3, audio_format_id4), args2short_aud_fmt_codes(audio_format_code1, audio_format_code2, audio_format_code3, audio_format_code4)/g;
450printf $fh "%s", $switch;
451printf $fh "\t}\n};\n\n";
452close $fh;
453
454open(my $fh, '>', 'cec-parse-gen.h') or die "Could not open cec-parse-gen.h for writing";
455foreach (sort keys %feature_usage) {
456	$name = $_;
457	s/ /-/g;
458	s/([A-Z])/\l\1/g;
459	$help_features .= sprintf("\t\"  --help-%-28s Show help for the $name feature\\n\" \\\n", $_);
460	$opt = "OptHelp" . $name;
461	$opt =~ s/ //g;
462	$options .= "\t$opt,\n";
463	$long_opts .= "\t{ \"help-$_\", no_argument, 0, $opt }, \\\n";
464}
465print $fh "enum cec_parse_options {\n\tOptMessages = 255,\n";
466printf $fh "%s\n\tOptLast = 512\n};\n\n", $options;
467
468printf $fh "#define CEC_PARSE_LONG_OPTS \\\n%s\n\n", $long_opts;
469printf $fh "#define CEC_PARSE_USAGE \\\n%s\n\n", $help_features;
470close $fh;
471
472open(my $fh, '>', 'cec-log-gen.h') or die "Could not open cec-log-gen.h for writing";
473printf $fh "%s%s\n", $enums, $arg_structs;
474printf $fh "static const struct cec_msg_args messages[] = {\n\t{\n";
475printf $fh "%s\t}\n};\n\n", $messages;
476
477print $fh <<'EOF';
478void cec_log_msg(const struct cec_msg *msg)
479{
480	if (msg->len == 1) {
481		printf("POLL\n");
482		goto status;
483	}
484
485	switch (msg->msg[1]) {
486EOF
487printf $fh "%s", $std_logswitch;
488print $fh <<'EOF';
489	default:
490		log_unknown_msg(msg);
491		break;
492	}
493	break;
494
495	default:
496		log_unknown_msg(msg);
497		break;
498	}
499
500status:
501	if ((msg->tx_status && !(msg->tx_status & CEC_TX_STATUS_OK)) ||
502	    (msg->rx_status && !(msg->rx_status & (CEC_RX_STATUS_OK | CEC_RX_STATUS_FEATURE_ABORT))))
503		printf("\t%s\n", cec_status2s(*msg).c_str());
504}
505
506static void log_htng_msg(const struct cec_msg *msg)
507{
508	if ((msg->tx_status && !(msg->tx_status & CEC_TX_STATUS_OK)) ||
509	    (msg->rx_status && !(msg->rx_status & (CEC_RX_STATUS_OK | CEC_RX_STATUS_FEATURE_ABORT))))
510		printf("\t%s\n", cec_status2s(*msg).c_str());
511
512	if (msg->len < 6)
513		return;
514
515	switch (msg->msg[5]) {
516EOF
517printf $fh "%s", $logswitch;
518print $fh <<'EOF';
519	default:
520		log_htng_unknown_msg(msg);
521		break;
522	}
523}
524EOF
525close $fh;
526
527open(my $fh, '>', 'cec-msgs-gen.h') or die "Could not open cec-msgs-gen.h for writing";
528printf $fh "struct msgtable {\n";
529printf $fh "\t__u8 opcode;\n";
530printf $fh "\tconst char *name;\n";
531printf $fh "};\n\n";
532printf $fh "static const struct msgtable msgtable[] = {\n";
533printf $fh "%s", $msgtable;
534printf $fh "\t{ CEC_MSG_VENDOR_COMMAND, \"VENDOR_COMMAND\" },\n";
535printf $fh "\t{ CEC_MSG_VENDOR_COMMAND_WITH_ID, \"VENDOR_COMMAND_WITH_ID\" },\n";
536printf $fh "\t{ CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN, \"VENDOR_REMOTE_BUTTON_DOWN\" },\n";
537printf $fh "\t{ CEC_MSG_CDC_MESSAGE, \"CDC_MESSAGE\" },\n";
538printf $fh "};\n\n";
539printf $fh "static const struct msgtable cdcmsgtable[] = {\n";
540printf $fh "%s", $cdcmsgtable;
541printf $fh "};\n\n";
542printf $fh "static const struct msgtable htngmsgtable[] = {\n";
543printf $fh "%s", $htngmsgtable;
544printf $fh "};\n";
545close $fh;
546