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