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