1#!/usr/bin/perl 2# SPDX-License-Identifier: GPL-2.0-only */ 3# Copyright 2022 Collabora Ltd. 4 5my $outdir = "."; 6my %outtype = ( "common" => 1, "trace" => 1, "retrace" => 1 ); 7 8while ($ARGV[0] =~ /^-/) { 9 my $arg = shift @ARGV; 10 11 ($outdir = shift @ARGV) && next if $arg eq "-o"; 12 (%outtype = (shift @ARGV => 1)) && next if $arg eq '-t'; 13 (help() && exit 0) if $arg eq '-h'; 14 last if $arg eq '--'; 15 16 print stderr "invalid option $arg, use $0 -h for help\n"; 17 exit 1; 18} 19 20sub help() { 21 print stderr <<EOF; 22$0 - Generate files for V4L2 tracer 23 24usage: $0 [-o dir] [-t (common|trace|retrace)] [-h] header [header2] ... 25 26 -o dir set output directory 27 -t x generate particular trace files, the default is to generate 28 them all 29 -h print this help text and quit 30EOF 31} 32 33sub convert_type_to_json_type { 34 my $type = shift; 35 if ($type eq __u8 || $type eq char || $type eq __u16 || $type eq __s8 || $type eq __s16 || $type eq __s32 || $type eq 'int' || 36 $type eq 'v4l2_av1_warp_model' || $type eq 'v4l2_av1_frame_restoration_type' || $type eq 'v4l2_av1_frame_type' || 37 $type eq 'v4l2_av1_interpolation_filter' || $type eq 'v4l2_av1_tx_mode') { 38 return "int"; 39 } 40 if ($type eq __u32 || $type eq __le32 || $type eq __s64) { 41 return "int64"; 42 } 43 44 # unsigned appears just twice in videodev2.h and in both cases it is 'unsigned long' 45 if ($type eq __u64 || $type eq 'v4l2_std_id' || $type eq 'unsigned') { 46 return "uint64"; 47 } 48 if ($type eq struct || $type eq union || $type eq void) { 49 return; 50 } 51 print "v4l2_tracer: error: couldn't convert \'$type\' to json_object type.\n"; 52 return; 53} 54 55sub get_index_letter { 56 my $index = shift; 57 if ($index eq 0) {return "i";} 58 if ($index eq 1) {return "j";} 59 if ($index eq 2) {return "k";} 60 if ($index eq 3) {return "l";} 61 if ($index eq 4) {return "m";} 62 if ($index eq 5) {return "n";} 63 if ($index eq 6) {return "o";} # "p" is saved for pointer 64 if ($index eq 8) {return "q";} 65 return "z"; 66} 67 68$flag_func_name; 69 70sub flag_gen { 71 my $flag_type = shift; 72 73 if ($flag_type =~ /fwht/) { 74 $flag_func_name = v4l2_ctrl_fwht_params_; 75 } elsif ($flag_type =~ /vp8_loop_filter/) { 76 $flag_func_name = v4l2_vp8_loop_filter_; 77 } else { 78 ($flag_func_name) = ($_) =~ /#define (\w+_)FL.+/; 79 $flag_func_name = lc $flag_func_name; 80 } 81 82 printf $fh_common_info_h "constexpr flag_def %sflag_def[] = {\n", $flag_func_name; 83 84 ($flag) = ($_) =~ /#define\s+(\w+)\s+.+/; 85 printf $fh_common_info_h "\t{ $flag, \"$flag\" },\n"; # get the first flag 86 87 while (<>) { 88 next if ($_ =~ /^\/?\s?\*.*/); # skip comments between flags if any 89 next if $_ =~ /^\s*$/; # skip blank lines between flags if any 90 last if ((grep {!/^#define\s+\w+_FL/} $_) && (grep {!/^#define V4L2_VP8_LF/} $_)); 91 ($flag) = ($_) =~ /#\s*define\s+(\w+)\s+.+/; 92 93 # don't include flags that are masks 94 next if ($flag_func_name eq v4l2_buf_) && ($flag =~ /.*TIMESTAMP.*/ || $flag =~ /.*TSTAMP.*/); 95 next if ($flag_func_name eq v4l2_ctrl_fwht_params_) && ($flag =~ /.*COMPONENTS.*/ || $flag =~ /.*PIXENC.*/); 96 next if ($flag =~ /.*MEDIA_LNK_FL_LINK_TYPE.*/); 97 next if ($flag =~ /.*MEDIA_ENT_ID_FLAG_NEXT.*/); 98 99 printf $fh_common_info_h "\t{ $flag, \"$flag\" },\n"; 100 } 101 printf $fh_common_info_h "\t{ 0, \"\" }\n};\n\n"; 102} 103 104sub enum_gen { 105 ($enum_name) = ($_) =~ /enum (\w+) {/; 106 printf $fh_common_info_h "constexpr val_def %s_val_def[] = {\n", $enum_name; 107 while (<>) { 108 last if $_ =~ /};/; 109 ($name) = ($_) =~ /\s+(\w+)\s?.*/; 110 next if ($name ne uc $name); # skip comments that don't start with * 111 next if ($_ =~ /^\s*\/?\s?\*.*/); # skip comments 112 next if $name =~ /^\s*$/; # skip blank lines 113 printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $name, $name; 114 } 115 printf $fh_common_info_h "\t{ -1, \"\" }\n};\n\n"; 116} 117 118sub val_def_gen { 119 my $last_val = shift; 120 my $sentinel = shift; 121 if (length $sentinel == 0) { 122 $sentinel = "-1"; # _flag_def arrays end with 0, _val_def arrays end in -1 123 } 124 ($val) = ($_) =~ /^#define\s*(\w+)\s*/; 125 printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $val, $val; 126 127 # in case there is only one value e.g. flags for V4L2_DEC_CMD_START 128 if ($val eq $last_val) { 129 printf $fh_common_info_h "\t{ $sentinel, \"\" }\n};\n\n"; 130 return; 131 } 132 while (<>) { 133 next if ($_ =~ /^\s*\/?\s?\*.*/); # skip comments 134 next if ($_ =~ /^\s*$/); # skip blank lines 135 ($val) = ($_) =~ /^#define\s*(\w+)\s*/; 136 next if ($val eq ""); # skip lines that don't start with define e.g. V4L2_STD_ATSC_16_VSB 137 printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $val, $val; 138 last if ($val eq $last_val); 139 } 140 printf $fh_common_info_h "\t{ $sentinel, \"\" }\n};\n\n"; 141} 142 143sub flag_def_gen { 144 my $last_flag = shift; 145 val_def_gen($last_flag, 0); 146} 147 148sub clean_up_line { 149 my $line = shift; 150 chomp($line); 151 $line =~ s/^\s+//; # remove leading whitespace 152 $line =~ s/.*\# define.*//; # zero out line if it has defines inside a structure (e.g. v4l2_jpegcompression) 153 $line =~ s/^\s*\/?\s?\*.*//; # zero out line if it has comments where the line starts with start with /* / * or just * 154 $line =~ s/\s*\/\*.*//; # remove comments /* */ at the end of a line following a member 155 $line =~ s/\s*\/\/.*//; # remove comments // at the end of a line following a member 156 $line =~ s/\*\/$//; # zero out line if it has comments that begin without any slashs or asterisks but end with */ 157 # zero out lines that don't have a ; or { because they are comments but without any identifying slashes or asteriks 158 if ($line !~ /.*[\;|\{].*/) { 159 $line =~ s/.*//; 160 } 161 $line =~ s/.*reserved.*//; # zero out lines with reserved members, they will segfault on retracing 162 $line =~ s/.*raw_data.*//; 163 # don't remove semi-colon at end because some functions will look for it 164 return $line; 165} 166 167sub get_val_def_name { 168 my $member = shift; 169 my $struct_name = shift; 170 @structs_that_use_v4l2_buf_type = qw(v4l2_fmtdesc v4l2_requestbuffers v4l2_buffer v4l2_crop 171 v4l2_exportbuffer v4l2_cropcap v4l2_selection 172 v4l2_sliced_vbi_cap v4l2_format v4l2_streamparm); 173 @structs_that_use_v4l2_ctrl_type = qw(v4l2_queryctrl v4l2_query_ext_ctrl v4l2_event_ctrl); 174 @structs_that_use_v4l2_tuner_type = qw(v4l2_tuner v4l2_frequency); 175 if ($member eq "type") { 176 foreach (@structs_that_use_v4l2_buf_type) { 177 if ($struct_name eq $_) { 178 return "v4l2_buf_type_val_def"; 179 } 180 } 181 foreach (@structs_that_use_v4l2_tuner_type) { 182 if ($struct_name eq $_) { 183 return "v4l2_tuner_type_val_def"; 184 } 185 } 186 foreach (@structs_that_use_v4l2_ctrl_type) { 187 if ($struct_name eq $_) { 188 return "v4l2_ctrl_type_val_def"; 189 } 190 } 191 if ($struct_name eq "v4l2_frmsizeenum") { 192 return "v4l2_frmsizetypes_val_def"; 193 } 194 if ($struct_name eq "v4l2_frmivalenum") { 195 return "v4l2_frmivaltypes_val_def"; 196 } 197 if ($struct_name eq "v4l2_input") { 198 return $val_def_name = "input_type_val_def"; 199 } 200 if ($struct_name eq "v4l2_output") { 201 return $val_def_name = "output_type_val_def"; 202 } 203 if ($struct_name eq "v4l2_event" || $struct_name eq "v4l2_event_subscription") { 204 return $val_def_name = "event_val_def"; 205 } 206 return "nullptr"; # will print as hex string 207 } 208 if ($member eq "pixelformat" || $member eq "pixel_format") { 209 return "v4l2_pix_fmt_val_def"; 210 } 211 if ($member =~ /cmd/) { 212 if ($struct_name =~ /v4l2_decoder_cmd/) { 213 return "decoder_cmd_val_def"; 214 } 215 if ($struct_name =~ /v4l2_encoder_cmd/) { 216 return "encoder_cmd_val_def"; 217 } 218 } 219 if ($member =~ /memory/) { 220 return "v4l2_memory_val_def"; 221 } 222 @structs_that_use_v4l2_field = qw(v4l2_pix_format v4l2_buffer v4l2_framebuffer v4l2_window 223 v4l2_pix_format_mplane v4l2_event_vsync); 224 if ($member eq "field") { 225 foreach (@structs_that_use_v4l2_field) { 226 if ($struct_name eq $_) { 227 return "v4l2_field_val_def"; 228 } 229 } 230 return "nullptr"; # will print as hex string 231 } 232 if ($member =~ /^id$/) { 233 if ($struct_name =~ /.*control|query.*/) { 234 return "control_val_def"; 235 } 236 return "nullptr"; # will print as hex string 237 } 238 if ($member =~ /capability|outputmode|capturemode/) { 239 if ($struct_name =~ /.*v4l2_captureparm|v4l2_outputparm.*/) { 240 return "streamparm_val_def"; 241 } 242 } 243 if ($member =~ /colorspace/) { 244 return "v4l2_colorspace_val_def"; 245 } 246 if ($member =~ /ycbcr_enc/) { 247 return "v4l2_ycbcr_encoding_val_def"; 248 } 249 if ($member =~ /quantization/) { 250 return "v4l2_quantization_val_def"; 251 } 252 if ($member =~ /xfer_func/) { 253 return "v4l2_xfer_func_val_def"; 254 } 255 if (($member eq "status") && ($struct_name eq "v4l2_input")) { 256 $val_def_name = "input_field_val_def"; 257 } 258 if ($member eq "audmode") { 259 return "tuner_audmode_val_def"; 260 } 261 if ($member eq "target" && $struct_name eq "v4l2_selection") { 262 return "selection_target_val_def"; 263 } 264} 265 266sub get_flag_def_name { 267 my $member = shift; 268 my $struct_name = shift; 269 if ($member =~ /flags/) { 270 if ($struct_name =~ /buffers$/) { 271 return "v4l2_memory_flag_def"; 272 } 273 if ($struct_name =~ /.*pix_format.*/) { 274 return "v4l2_pix_fmt_flag_def"; 275 } 276 if ($struct_name =~ /.*ctrl$/) { 277 return "v4l2_ctrl_flag_def"; 278 } 279 if ($struct_name =~ /.*fmtdesc$/) { 280 return "v4l2_fmt_flag_def"; 281 } 282 if ($struct_name =~ /.*selection$/) { 283 return "v4l2_sel_flag_def"; 284 } 285 if ($struct_name eq "v4l2_event_subscription") { 286 return "v4l2_event_sub_flag_def"; 287 } 288 return "nullptr"; 289 } 290 291 if ($member =~ /.*cap.*/) { 292 # v4l2_requestbuffers, v4l2_create_buffers 293 if ($struct_name =~ /buffers$/) { 294 return "v4l2_buf_cap_flag_def"; 295 } 296 # v4l2_capability 297 if ($struct_name =~ /capability$/) { 298 return "v4l2_cap_flag_def"; 299 } 300 if ($struct_name eq "v4l2_tuner") { 301 return "tuner_cap_flag_def"; 302 } 303 } 304 if ($member eq "rxsubchans") { 305 return "tuner_rxsub_flag_def"; 306 } 307 if ($member eq "changes") { 308 if ($struct_name eq "v4l2_event_ctrl") { 309 return "v4l2_event_ctrl_ch_flag_def"; 310 } 311 } 312 return ""; 313} 314 315# trace a struct nested in another struct in videodev2.h 316sub handle_struct { 317 printf $fh_trace_cpp "\t//$line\n"; 318 printf $fh_retrace_cpp "\t//$line\n"; 319 320 # this is a multi-lined nested struct so iterate through it 321 if ($line !~ /.*;$/) { 322 $suppress_struct = true; 323 return; 324 } 325 326 # don't trace struct pointers 327 if ($line =~ /\*/) { 328 return; 329 } 330 # don't trace struct arrays 331 if ($line =~ /\[/) { 332 return; 333 } 334 335 my ($struct_tag) = ($line) =~ /\s*struct (\w+)\s+.*/; 336 337 # structs defined outside of videodev2.h 338 if ($struct_tag =~ /v4l2_ctrl|timeval|timespec/) { 339 return; 340 } 341 342 # e.g. $struct_tag_parent = v4l2_captureparm, $struct_tag = v4l2_fract, $struct_var = timeperframe 343 my $struct_tag_parent = $struct_name; 344 my ($struct_var) = ($line) =~ /(\w+)\;$/; 345 printf $fh_trace_cpp "\ttrace_%s_gen(&p->%s, %s_obj, \"%s\");\n", $struct_tag, $struct_var, $struct_tag_parent, $struct_var; 346 347 printf $fh_retrace_cpp "\tvoid *%s_ptr = (void *) retrace_%s_gen(%s_obj, \"%s\");\n", $struct_var, $struct_tag, $struct_tag_parent, $struct_var; 348 printf $fh_retrace_cpp "\tp->$struct_var = *static_cast<struct %s*>(%s_ptr);\n", $struct_tag, $struct_var; 349 printf $fh_retrace_cpp "\tfree(%s_ptr);\n\n", $struct_var; 350} 351 352# trace a union in videodev2.h 353sub handle_union { 354 my @params = @_; 355 my $struct_name = @params[0]; 356 357 $in_union = true; 358 $suppress_union = true; 359 printf $fh_trace_cpp "\t//union\n"; 360 printf $fh_retrace_cpp "\t//union\n"; 361 362 if ($struct_name =~ /^v4l2_pix_format/) { 363 $suppress_union = false; 364 } 365 366 if ($struct_name =~ /^v4l2_format$/) { 367 printf $fh_trace_cpp "\tswitch (p->type) {\n"; 368 printf $fh_trace_cpp "\tcase V4L2_BUF_TYPE_VIDEO_CAPTURE:\n\tcase V4L2_BUF_TYPE_VIDEO_OUTPUT:\n"; 369 printf $fh_trace_cpp "\t\ttrace_v4l2_pix_format_gen(&p->fmt.pix, %s_obj);\n\t\tbreak;\n", $struct_name; 370 printf $fh_trace_cpp "\tcase V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:\n\tcase V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:\n"; 371 printf $fh_trace_cpp "\t\ttrace_v4l2_pix_format_mplane_gen(&p->fmt.pix, %s_obj);\n\t\tbreak;\n", $struct_name; 372 printf $fh_trace_cpp "\tdefault:\n\t\tbreak;\n\t}\n"; 373 374 printf $fh_retrace_cpp "\tswitch (p->type) {\n"; 375 printf $fh_retrace_cpp "\tcase V4L2_BUF_TYPE_VIDEO_CAPTURE:\n\tcase V4L2_BUF_TYPE_VIDEO_OUTPUT: {\n"; 376 printf $fh_retrace_cpp "\t\tvoid *pix_ptr = (void *) retrace_v4l2_pix_format_gen(v4l2_format_obj);\n"; 377 printf $fh_retrace_cpp "\t\tp->fmt.pix = *static_cast<struct v4l2_pix_format*>(pix_ptr);\n"; 378 printf $fh_retrace_cpp "\t\tfree(pix_ptr);\n\t\tbreak;\n\t}\n"; 379 380 printf $fh_retrace_cpp "\tcase V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:\n\tcase V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: {\n"; 381 printf $fh_retrace_cpp "\t\tvoid *pix_mp_ptr = (void *) retrace_v4l2_pix_format_mplane_gen(v4l2_format_obj);\n"; 382 printf $fh_retrace_cpp "\t\tp->fmt.pix_mp = *static_cast<struct v4l2_pix_format_mplane*>(pix_mp_ptr);\n"; 383 printf $fh_retrace_cpp "\t\tfree(pix_mp_ptr);\n\t\tbreak;\n\t}\n"; 384 385 printf $fh_retrace_cpp "\tdefault:\n\t\tbreak;\n\t}\n"; 386 } 387 388 if ($struct_name eq "v4l2_frmsizeenum") { 389 printf $fh_trace_cpp "\tswitch (p->type) {\n"; 390 printf $fh_trace_cpp "\tcase V4L2_FRMSIZE_TYPE_DISCRETE:\n"; 391 printf $fh_trace_cpp "\t\ttrace_v4l2_frmsize_discrete_gen(&p->discrete, %s_obj);\n\t\tbreak;\n", $struct_name; 392 printf $fh_trace_cpp "\tcase V4L2_FRMSIZE_TYPE_STEPWISE:\n\tcase V4L2_FRMSIZE_TYPE_CONTINUOUS:\n"; 393 printf $fh_trace_cpp "\t\ttrace_v4l2_frmsize_stepwise_gen(&p->stepwise, %s_obj);\n\t\tbreak;\n", $struct_name; 394 printf $fh_trace_cpp "\tdefault:\n\t\tbreak;\n\t}\n"; 395 } 396 397 if ($struct_name eq "v4l2_frmivalenum") { 398 printf $fh_trace_cpp "\tswitch (p->type) {\n"; 399 printf $fh_trace_cpp "\tcase V4L2_FRMIVAL_TYPE_DISCRETE:\n"; 400 printf $fh_trace_cpp "\t\ttrace_v4l2_fract_gen(&p->discrete, %s_obj);\n\t\tbreak;\n", $struct_name; 401 printf $fh_trace_cpp "\tcase V4L2_FRMIVAL_TYPE_STEPWISE:\n\tcase V4L2_FRMIVAL_TYPE_CONTINUOUS:\n"; 402 printf $fh_trace_cpp "\t\ttrace_v4l2_frmival_stepwise_gen(&p->stepwise, %s_obj);\n\t\tbreak;\n", $struct_name; 403 printf $fh_trace_cpp "\tdefault:\n\t\tbreak;\n\t}\n"; 404 } 405 406 if ($struct_name eq "v4l2_event") { 407 printf $fh_trace_cpp "\tswitch (p->type) {\n"; 408 printf $fh_trace_cpp "\tcase V4L2_EVENT_VSYNC:\n"; 409 printf $fh_trace_cpp "\t\ttrace_v4l2_event_vsync_gen(&p->u, %s_obj);\n\t\tbreak;\n", $struct_name; 410 printf $fh_trace_cpp "\tcase V4L2_EVENT_CTRL:\n"; 411 printf $fh_trace_cpp "\t\ttrace_v4l2_event_ctrl_gen(&p->u, %s_obj);\n\t\tbreak;\n", $struct_name; 412 printf $fh_trace_cpp "\tcase V4L2_EVENT_FRAME_SYNC:\n"; 413 printf $fh_trace_cpp "\t\ttrace_v4l2_event_frame_sync_gen(&p->u, %s_obj);\n\t\tbreak;\n", $struct_name; 414 printf $fh_trace_cpp "\tcase V4L2_EVENT_SOURCE_CHANGE:\n"; 415 printf $fh_trace_cpp "\t\ttrace_v4l2_event_src_change_gen(&p->u, %s_obj);\n\t\tbreak;\n", $struct_name; 416 printf $fh_trace_cpp "\tcase V4L2_EVENT_MOTION_DET:\n"; 417 printf $fh_trace_cpp "\t\ttrace_v4l2_event_motion_det_gen(&p->u, %s_obj);\n\t\tbreak;\n", $struct_name; 418 printf $fh_trace_cpp "\tdefault:\n\t\tbreak;\n\t}\n"; 419 } 420 421 return $suppress_union; 422} 423 424# generate functions for structs in videodev2.h 425sub struct_gen { 426 ($struct_name) = ($_) =~ /struct (\w+) {/; 427 428 # it's not being used and was generating a warning 429 if ($struct_name =~ /v4l2_mpeg_vbi_ITV0/) { 430 return; 431 } 432 printf $fh_trace_cpp "void trace_%s_gen(void *arg, json_object *parent_obj, std::string key_name = \"\")\n{\n", $struct_name; 433 printf $fh_trace_h "void trace_%s_gen(void *arg, json_object *parent_obj, std::string key_name = \"\");\n", $struct_name; 434 printf $fh_trace_cpp "\tjson_object *%s_obj = json_object_new_object();\n", $struct_name; 435 printf $fh_trace_cpp "\tstruct %s *p = static_cast<struct %s*>(arg);\n\n", $struct_name, $struct_name; 436 437 printf $fh_retrace_h "struct %s *retrace_%s_gen(json_object *parent_obj, std::string key_name = \"\");\n", $struct_name, $struct_name; 438 printf $fh_retrace_cpp "struct %s *retrace_%s_gen(json_object *parent_obj, std::string key_name = \"\")\n{\n", $struct_name, $struct_name; 439 440 printf $fh_retrace_cpp "\tstruct %s *p = (struct %s *) calloc(1, sizeof(%s));\n\n", $struct_name, $struct_name, $struct_name; 441 printf $fh_retrace_cpp "\tjson_object *%s_obj;\n", $struct_name; 442 printf $fh_retrace_cpp "\tif (key_name.empty())\n"; 443 printf $fh_retrace_cpp "\t\tjson_object_object_get_ex(parent_obj, \"%s\", &%s_obj);\n", $struct_name, $struct_name; 444 printf $fh_retrace_cpp "\telse\n"; 445 printf $fh_retrace_cpp "\t\tjson_object_object_get_ex(parent_obj, key_name.c_str(), &%s_obj);\n\n", $struct_name; 446 447 $suppress_union = false; 448 $suppress_struct = false; 449 while ($line = <>) { 450 chomp($line); 451 $member = ""; 452 if ($line =~ /}.*;/) { 453 if ($suppress_struct eq true) { 454 printf $fh_trace_cpp "\t//end of struct $line\n"; 455 printf $fh_retrace_cpp "\t//end of struct $line\n"; 456 $suppress_struct = false; 457 next; 458 } elsif ($in_union eq true) { 459 if ($suppress_union eq true) { 460 $suppress_union = false; # end of union 461 } 462 printf $fh_trace_cpp "\t//end of union $line\n"; 463 printf $fh_retrace_cpp "\t//end of union $line\n"; 464 $in_union = false; 465 next; 466 } else { 467 last; 468 } 469 } 470 last if $line =~ /^} __attribute__.*/; 471 472 $line = clean_up_line($line); 473 next if $line =~ /^\s*$/; # ignore blank lines 474 475 @words = split /[\s\[]/, $line; # split on whitespace and also'[' to get char arrays 476 @words = grep {/^\D/} @words; # remove values that start with digit from inside [] 477 @words = grep {!/\]/} @words; # remove values with brackets e.g. V4L2_H264_REF_LIST_LEN] 478 479 ($type) = $words[0]; 480 481 # unions inside the struct 482 if ($type eq 'union') { 483 handle_union($struct_name); 484 next; 485 } 486 # suppress anything inside a union including structs nested inside a union 487 if ($suppress_union eq true) { 488 printf $fh_trace_cpp "\t//$line\n"; 489 printf $fh_retrace_cpp "\t//$line\n"; 490 next; 491 } 492 493 # struct members inside the struct 494 if ($type eq 'struct') { 495 handle_struct(); 496 next; 497 } 498 if ($suppress_struct eq true) { 499 printf $fh_trace_cpp "\t//$line\n"; 500 printf $fh_retrace_cpp "\t//$line\n"; 501 next; 502 } 503 504 $json_type = convert_type_to_json_type($type); 505 506 ($member) = $words[scalar @words - 1]; 507 $member =~ s/;//; # remove the ; 508 509 if ($member =~ /service_lines/) { 510 printf $fh_trace_cpp "\t//$line\n"; 511 printf $fh_retrace_cpp "\t//$line\n"; 512 next; 513 } 514 515 # Don't trace members that are pointers 516 if ($member =~ /\*/) { 517 printf $fh_trace_cpp "\t//$line\n"; 518 printf $fh_retrace_cpp "\t//$line\n"; 519 next; 520 } 521 522 if ($line =~ /dims\[V4L2_CTRL_MAX_DIMS\]/) { 523 printf $fh_trace_cpp "\t\/\* $line \*\/\n"; # add comment 524 printf $fh_trace_cpp "\tjson_object *dims_obj = json_object_new_array();\n"; 525 printf $fh_trace_cpp "\tfor (int i = 0; i < (std::min((int) p->nr_of_dims, V4L2_CTRL_MAX_DIMS)); i++) {\n"; 526 printf $fh_trace_cpp "\t\tjson_object_array_add(dims_obj, json_object_new_int64(p->dims[i]));\n\t}\n"; 527 printf $fh_trace_cpp "\tjson_object_object_add(%s_obj, \"$member\", dims_obj);\n", $struct_name; 528 529 printf $fh_retrace_cpp "\t\/\* $line \*\/\n"; # add comment 530 printf $fh_retrace_cpp "\tjson_object *dims_obj;\n"; 531 printf $fh_retrace_cpp "\tif (json_object_object_get_ex(%s_obj, \"$member\", &%s_obj)) {\n", $struct_name, $member; 532 printf $fh_retrace_cpp "\t\tfor (int i = 0; i < (std::min((int) p->nr_of_dims, V4L2_CTRL_MAX_DIMS)); i++) {\n"; 533 printf $fh_retrace_cpp "\t\t\tif (json_object_array_get_idx(dims_obj, i))\n"; 534 printf $fh_retrace_cpp "\t\t\t\tp->dims[i] = (__u32) json_object_get_int64(json_object_array_get_idx(dims_obj, i));\n\t\t}\n\t}\n"; 535 next; 536 } 537 538 printf $fh_retrace_cpp "\tjson_object *%s_obj;\n", $member; 539 540 # struct v4l2_pix_format 541 if ($member =~ /priv/) { 542 printf $fh_trace_cpp "\tif (p->priv == V4L2_PIX_FMT_PRIV_MAGIC)\n"; 543 printf $fh_trace_cpp "\t\tjson_object_object_add(%s_obj, \"%s\", json_object_new_string(\"V4L2_PIX_FMT_PRIV_MAGIC\"));\n", $struct_name, $member; 544 printf $fh_trace_cpp "\telse\n"; 545 printf $fh_trace_cpp "\t\tjson_object_object_add(%s_obj, \"%s\", json_object_new_string(\"\"));\n", $struct_name, $member; 546 547 printf $fh_retrace_cpp "\tif (json_object_object_get_ex(%s_obj, \"$member\", &%s_obj)) {\n", $struct_name, $member; 548 printf $fh_retrace_cpp "\t\tif (json_object_get_string(priv_obj) == nullptr)\n\t\t\treturn p;\n"; 549 printf $fh_retrace_cpp "\t\tstd::string priv_str = json_object_get_string(priv_obj);\n"; 550 printf $fh_retrace_cpp "\t\tif (!priv_str.empty())\n"; 551 printf $fh_retrace_cpp "\t\t\tp->priv = V4L2_PIX_FMT_PRIV_MAGIC;\n\t}\n"; 552 next; 553 } 554 555 printf $fh_trace_cpp "\tjson_object_object_add(%s_obj, \"%s\", json_object_new_", $struct_name, $member; 556 printf $fh_retrace_cpp "\tif (json_object_object_get_ex(%s_obj, \"$member\", &%s_obj))\n", $struct_name, $member; 557 558 # Convert char array members to string 559 if ($line =~ /.*\[.*/) { 560 if ($member =~ /.*name|driver|card|bus_info|description|model|magic|serial|userbits|APP_data|COM_data|linemask|data|start|count|raw|.*/) { 561 printf $fh_trace_cpp "string(reinterpret_cast<const char *>(p->$member)));\n"; 562 563 printf $fh_retrace_cpp "\t\tif (json_object_get_string(%s_obj) != nullptr)\n", $member; 564 my @char_array_size = ($line) =~ /\[(\w+)\]/g; 565 printf $fh_retrace_cpp "\t\t\tmemcpy(p->$member, json_object_get_string(%s_obj), @char_array_size);\n\n", $member; 566 next; 567 } 568 } 569 570 # special strings 571 if ($member =~ /version/) { 572 printf $fh_trace_cpp "string(ver2s(p->$member).c_str()));\n"; 573 printf $fh_retrace_cpp "\t\tmemset(&p->$member, 0, sizeof(p->$member));\n\n"; # driver can fill in version 574 next; 575 } 576 577 printf $fh_retrace_cpp "\t\tp->$member = "; 578 579 if ($struct_name =~ /^v4l2_buffer$/) { 580 if ($member =~ /flags/) { 581 printf $fh_trace_cpp "string(fl2s_buffer(p->$member).c_str()));\n"; 582 printf $fh_retrace_cpp "(%s) s2flags_buffer(json_object_get_string(%s_obj));\n\n", $type, $member, $flag_def_name; 583 next; 584 } 585 } 586 587 # strings 588 $val_def_name = get_val_def_name($member, $struct_name); 589 if ($val_def_name !~ /^\s*$/) { 590 printf $fh_trace_cpp "string(val2s(p->$member, %s).c_str()));\n", $val_def_name; 591 printf $fh_retrace_cpp "(%s) s2val(json_object_get_string(%s_obj), %s);\n", $type, $member, $val_def_name; 592 next; 593 } 594 595 $flag_def_name = get_flag_def_name($member, $struct_name); 596 if ($flag_def_name !~ /^\s*$/) { 597 printf $fh_trace_cpp "string(fl2s(p->$member, %s).c_str()));\n", $flag_def_name; 598 printf $fh_retrace_cpp "(%s) s2flags(json_object_get_string(%s_obj), %s);\n\n", $type, $member, $flag_def_name; 599 next; 600 } 601 602 # integers 603 printf $fh_trace_cpp "$json_type(p->$member));\n"; 604 printf $fh_retrace_cpp "(%s) json_object_get_%s(%s_obj);\n\n", $type, $json_type, $member; 605 606 # special treatment for v4l2_pix_format_mplane member plane_fmt[VIDEO_MAX_PLANES] 607 # it can only be traced after num_planes is known 608 if ($member =~ /num_planes/) { 609 printf $fh_trace_cpp "\tjson_object *plane_fmt_obj = json_object_new_array();\n"; 610 printf $fh_trace_cpp "\tfor (int i = 0; i < (std::min((int) p->num_planes, VIDEO_MAX_PLANES)); i++) {\n"; 611 printf $fh_trace_cpp "\t\tjson_object *element_obj = json_object_new_object();\n"; 612 printf $fh_trace_cpp "\t\ttrace_v4l2_plane_pix_format_gen(&(p->plane_fmt[i]), element_obj);\n"; 613 printf $fh_trace_cpp "\t\tjson_object *element_no_key_obj;\n"; 614 printf $fh_trace_cpp "\t\tjson_object_object_get_ex(element_obj, \"v4l2_plane_pix_format\", &element_no_key_obj);\n"; 615 printf $fh_trace_cpp "\t\tjson_object_array_add(plane_fmt_obj, element_no_key_obj);\n\t}\n"; 616 printf $fh_trace_cpp "\tjson_object_object_add(v4l2_pix_format_mplane_obj, \"plane_fmt\", plane_fmt_obj);\n\n"; 617 618 printf $fh_retrace_cpp "\tjson_object *plane_fmt_obj;\n"; 619 printf $fh_retrace_cpp "\tif (json_object_object_get_ex(v4l2_pix_format_mplane_obj, \"plane_fmt\", &plane_fmt_obj)) {\n"; 620 printf $fh_retrace_cpp "\t\tfor (int i = 0; i < (std::min((int) p->num_planes, VIDEO_MAX_PLANES)); i++) {\n"; 621 printf $fh_retrace_cpp "\t\t\tif (json_object_array_get_idx(plane_fmt_obj, i)) {\n"; 622 printf $fh_retrace_cpp "\t\t\t\tjson_object *element_obj = json_object_new_object();\n"; 623 printf $fh_retrace_cpp "\t\t\t\tjson_object_object_add(element_obj, \"v4l2_plane_pix_format\", json_object_array_get_idx(plane_fmt_obj, i));\n"; 624 printf $fh_retrace_cpp "\t\t\t\tvoid *ptr = (void *) retrace_v4l2_plane_pix_format_gen(element_obj);\n"; 625 printf $fh_retrace_cpp "\t\t\t\tp->plane_fmt[i] = *static_cast<struct v4l2_plane_pix_format *>(ptr);\n"; 626 printf $fh_retrace_cpp "\t\t\t\tfree(ptr);\n"; 627 printf $fh_retrace_cpp "\t\t\t}\n\t\t}\n\t}\n\n"; 628 } 629 } 630 631 # The key name option allows a struct to be traced when it is nested inside another struct. 632 printf $fh_trace_cpp "\n\tif (key_name.empty())\n"; 633 printf $fh_trace_cpp "\t\tjson_object_object_add(parent_obj, \"%s\", %s_obj);\n", $struct_name, $struct_name; 634 printf $fh_trace_cpp "\telse\n"; 635 printf $fh_trace_cpp "\t\tjson_object_object_add(parent_obj, key_name.c_str(), %s_obj);\n", $struct_name; 636 printf $fh_trace_cpp "}\n\n"; 637 638 printf $fh_retrace_cpp "\treturn p;\n}\n"; 639} 640 641# generate functions for structs in v4l2-controls.h 642sub struct_gen_ctrl { 643 ($struct_name) = ($_) =~ /struct (\w+) {/; 644 645 printf $fh_trace_h "void trace_%s_gen(void *ptr, json_object *parent_obj);\n", $struct_name; 646 printf $fh_trace_cpp "void trace_%s_gen(void *ptr, json_object *parent_obj)\n{\n", $struct_name; 647 printf $fh_trace_cpp "\tjson_object *%s_obj = json_object_new_object();\n", $struct_name; 648 printf $fh_trace_cpp "\tstruct %s *p = static_cast<struct %s*>(ptr);\n", $struct_name, $struct_name; 649 650 printf $fh_retrace_h "struct %s *retrace_%s_gen(json_object *ctrl_obj);\n", $struct_name, $struct_name; 651 printf $fh_retrace_cpp "struct %s *retrace_%s_gen(json_object *ctrl_obj)\n{\n", $struct_name, $struct_name; 652 printf $fh_retrace_cpp "\tstruct %s *p = (struct %s *) calloc(1, sizeof(%s));\n", $struct_name, $struct_name, $struct_name; 653 printf $fh_retrace_cpp "\tjson_object *%s_obj;\n", $struct_name; 654 # if a key value isn't found, assume it is retracing an element of an array 655 # e.g. in struct v4l2_ctrl_h264_pred_weights 656 printf $fh_retrace_cpp "\tif (!json_object_object_get_ex(ctrl_obj, \"%s\", &%s_obj))\n", $struct_name, $struct_name; 657 printf $fh_retrace_cpp "\t\t%s_obj = ctrl_obj;\n", $struct_name; 658 659 while ($line = <>) { 660 chomp($line); 661 last if $line =~ /};/; 662 $line = clean_up_line($line); 663 next if $line =~ /^\s*$/; # ignore blank lines 664 $line =~ s/;$//; # remove semi-colon at the end 665 @words = split /[\s\[]/, $line; # also split on '[' to avoid arrays 666 @words = grep {/^\D/} @words; # remove values that start with digit from inside [] 667 @words = grep {!/\]/} @words; # remove values with brackets e.g. V4L2_H264_REF_LIST_LEN] 668 669 ($type) = $words[0]; 670 if ($type eq 'enum') { 671 $type = $words[1]; 672 } 673 $json_type = convert_type_to_json_type($type); 674 675 ($member) = $words[scalar @words - 1]; 676 677 # generate members that are arrays 678 if ($line =~ /.*\[.*/) { 679 680 # e.g. two dimensional array [x][y] 681 my @dimensions = ($line) =~ /\[(.*?)\]/g; 682 683 #for struct v4l2_av1_tile_info [V4L2_AV1_MAX_TILE_ROWS + 1] 684 if (grep {$_ =~ /\+/} @dimensions) { 685 $member = $words[scalar @words - 3]; 686 } 687 688 printf $fh_trace_cpp "\t\/\* %s \*\/\n", $line; # add comment 689 printf $fh_trace_cpp "\tjson_object *%s_obj = json_object_new_array();\n", $member; 690 printf $fh_retrace_cpp "\n\t\/\* %s \*\/\n", $line; # add comment 691 692 $dimensions_count = scalar @dimensions; 693 if ($dimensions_count > 1) { 694 printf $fh_retrace_cpp "\tint count_%s = 0;\n", $member; 695 } 696 printf $fh_retrace_cpp "\tjson_object *%s_obj;\n", $member; 697 printf $fh_retrace_cpp "\tif (json_object_object_get_ex(%s_obj, \"%s\", &%s_obj)) {\n", $struct_name, $member, $member; 698 699 for (my $idx = 0; $idx < $dimensions_count; $idx = $idx + 1) { 700 $size = $dimensions[$idx]; 701 $index_letter = get_index_letter($idx); 702 printf $fh_trace_cpp "\t" x ($idx + 1); 703 printf $fh_trace_cpp "for (size_t %s = 0; %s < %s\; %s++) {\n", $index_letter, $index_letter, $size, $index_letter; 704 705 printf $fh_retrace_cpp "\t" x ($idx + 1); 706 printf $fh_retrace_cpp "\t"; 707 printf $fh_retrace_cpp "for (size_t %s = 0; %s < %s\; %s++) {\n", $index_letter, $index_letter, $size, $index_letter; 708 } 709 printf $fh_trace_cpp "\t" x ($dimensions_count + 1); 710 printf $fh_retrace_cpp "\t" x ($dimensions_count + 1); 711 printf $fh_retrace_cpp "\t"; 712 713 # handle arrays of structs e.g. struct v4l2_ctrl_h264_pred_weights weight_factors 714 if ($type =~ /struct/) { 715 my $struct_tag = @words[1]; 716 my $struct_var = $member; 717 printf $fh_trace_cpp "json_object *element_obj = json_object_new_object();\n"; 718 printf $fh_trace_cpp "\t" x ($dimensions_count + 1); 719 printf $fh_trace_cpp "trace_%s_gen(&(p->%s", $struct_tag, $struct_var; 720 for (my $idx = 0; $idx < $dimensions_count; $idx = $idx + 1) { 721 printf $fh_trace_cpp "[%s]", get_index_letter($idx); 722 } 723 printf $fh_trace_cpp "), element_obj);\n"; 724 printf $fh_trace_cpp "\t" x ($dimensions_count + 1); 725 printf $fh_trace_cpp "json_object *element_no_key_obj;\n"; 726 printf $fh_trace_cpp "\t" x ($dimensions_count + 1); 727 printf $fh_trace_cpp "json_object_object_get_ex(element_obj, \"%s\", &element_no_key_obj);\n", $struct_tag; 728 printf $fh_trace_cpp "\t" x ($dimensions_count + 1); 729 printf $fh_trace_cpp "json_object_array_add(%s_obj, element_no_key_obj);\n", $struct_var; 730 731 printf $fh_retrace_cpp "void *%s_ptr", $struct_var; 732 printf $fh_retrace_cpp " = (void *) retrace_%s_gen(json_object_array_get_idx(%s_obj, ", $struct_tag, $struct_var; 733 if ($dimensions_count > 1) { 734 printf $fh_retrace_cpp "count_%s++", $struct_var; 735 } else { 736 printf $fh_retrace_cpp "i"; 737 } 738 printf $fh_retrace_cpp "));\n"; 739 740 printf $fh_retrace_cpp "\t" x ($dimensions_count + 1); 741 printf $fh_retrace_cpp "\tp->%s", $struct_var; 742 for (my $idx = 0; $idx < $dimensions_count; $idx = $idx + 1) { 743 printf $fh_retrace_cpp "[%s]", get_index_letter($idx); 744 } 745 printf $fh_retrace_cpp " = *static_cast<struct %s*>(%s_ptr);\n", $struct_tag, $struct_var; 746 747 printf $fh_retrace_cpp "\t" x ($dimensions_count + 1); 748 printf $fh_retrace_cpp "\tfree(%s_ptr);\n", $struct_var; 749 } else { 750 # handle arrays of ints 751 printf $fh_trace_cpp "json_object_array_add(%s_obj, json_object_new_%s(p->%s", $member, $json_type, $member; 752 for (my $idx = 0; $idx < $dimensions_count; $idx = $idx + 1) { 753 printf $fh_trace_cpp "[%s]", get_index_letter($idx); 754 } 755 printf $fh_trace_cpp "));\n"; 756 757 # add a check to avoid accessing a null array index 758 printf $fh_retrace_cpp "if (json_object_array_get_idx(%s_obj, ", $member; 759 if ($dimensions_count > 1) { 760 printf $fh_retrace_cpp "count_%s", $member; 761 } else { 762 printf $fh_retrace_cpp "i"; 763 } 764 printf $fh_retrace_cpp "))\n"; 765 766 printf $fh_retrace_cpp "\t" x ($dimensions_count + 1); 767 printf $fh_retrace_cpp "\t\t"; 768 printf $fh_retrace_cpp "p->%s", $member; 769 for (my $idx = 0; $idx < $dimensions_count; $idx = $idx + 1) { 770 printf $fh_retrace_cpp "[%s]", get_index_letter($idx); 771 } 772 773 printf $fh_retrace_cpp " = ($type) json_object_get_%s(json_object_array_get_idx(%s_obj, ", $json_type, $member; 774 if ($dimensions_count > 1) { 775 printf $fh_retrace_cpp "count_%s++", $member; 776 } else { 777 printf $fh_retrace_cpp "i"; 778 } 779 printf $fh_retrace_cpp "));\n"; 780 } 781 # closing brackets for all array types 782 for (my $idx = $dimensions_count - 1; $idx >= 0 ; $idx = $idx - 1) { 783 printf $fh_trace_cpp "\t" x ($idx + 1); 784 printf $fh_trace_cpp "}\n"; 785 786 printf $fh_retrace_cpp "\t" x ($idx + 1); 787 printf $fh_retrace_cpp "\t"; 788 printf $fh_retrace_cpp "}\n"; 789 } 790 printf $fh_retrace_cpp "\t}\n"; 791 printf $fh_trace_cpp "\tjson_object_object_add(%s_obj, \"%s\", %s_obj);\n\n", $struct_name, $member, $member; 792 next; 793 } 794 795 # member that is a struct but not an array of structs 796 # e.g. $struct_tag_parent = v4l2_ctrl_vp8_frame, $struct_tag = v4l2_vp8_segment, $struct_var = segment 797 if ($type =~ /struct/) { 798 my $struct_tag_parent = $struct_name; 799 my ($struct_tag) = ($line) =~ /\s*struct (\w+)\s+.*/; 800 my ($struct_var) = $member; 801 printf $fh_trace_cpp "\t\/\* %s \*\/\n", $line; 802 printf $fh_trace_cpp "\ttrace_%s_gen(&p->%s, %s_obj);\n", $struct_tag, $struct_var, $struct_tag_parent; 803 804 printf $fh_retrace_cpp "\n\t\/\* %s \*\/\n", $line; 805 printf $fh_retrace_cpp "\tjson_object *%s_obj;\n", $struct_var; 806 printf $fh_retrace_cpp "\tif (!json_object_object_get_ex(%s_obj, \"%s\", &%s_obj))\n", $struct_tag_parent, $struct_tag, $struct_var; 807 printf $fh_retrace_cpp "\t\treturn p;\n", $struct_tag_parent, $struct_tag, $struct_var; 808 809 printf $fh_retrace_cpp "\tvoid *%s_ptr = (void *) retrace_%s_gen(%s_obj);\n", $struct_var, $struct_tag, $struct_var; 810 printf $fh_retrace_cpp "\tp->$struct_var = *static_cast<struct %s*>(%s_ptr);\n", $struct_tag, $struct_var; 811 printf $fh_retrace_cpp "\tfree(%s_ptr);\n", $struct_var; 812 next; 813 } 814 815 printf $fh_trace_cpp "\tjson_object_object_add(%s_obj, \"%s\", json_object_new_", $struct_name, $member; 816 printf $fh_retrace_cpp "\n\tjson_object *%s_obj;\n", $member; 817 printf $fh_retrace_cpp "\tif (json_object_object_get_ex(%s_obj, \"%s\", &%s_obj))\n", $struct_name, $member, $member; 818 819 # strings 820 if ($member =~ /flags/) { 821 if ($struct_name eq "v4l2_ctrl_fwht_params") { 822 printf $fh_trace_cpp "string(fl2s_fwht(p->$member).c_str()));\n"; 823 printf $fh_retrace_cpp "\t\tp->%s = ($type) s2flags_fwht(json_object_get_string(%s_obj));\n", $member, $member, $flag_func_name; 824 } else { 825 printf $fh_trace_cpp "string(fl2s(p->$member, %sflag_def).c_str()));\n", $flag_func_name; 826 printf $fh_retrace_cpp "\t\tp->%s = ($type) s2flags(json_object_get_string(%s_obj), %sflag_def);\n", $member, $member, $flag_func_name; 827 } 828 next; 829 } 830 831 # Add members with a single string value (e.g. enums, #define) 832 $val_def_name = get_val_def_name($member, $struct_name); 833 if ($val_def_name !~ /^\s*$/) { 834 printf $fh_trace_cpp "string(val2s(p->$member, %s).c_str()));\n", $val_def_name; 835 printf $fh_retrace_cpp "\t\tp->%s = ($type) s2val(json_object_get_string(%s_obj), $val_def_name);\n", $member, $member; 836 next; 837 } 838 839 # integers 840 printf $fh_trace_cpp "%s(p->%s));\n", $json_type, $member; 841 printf $fh_retrace_cpp "\t\tp->%s = ($type) json_object_get_%s(%s_obj);\n", $member, $json_type, $member; 842 } 843 844 printf $fh_trace_cpp "\tjson_object_object_add(parent_obj, \"%s\", %s_obj);\n", $struct_name, $struct_name; 845 printf $fh_trace_cpp "}\n\n"; 846 847 printf $fh_retrace_cpp "\n\treturn p;\n"; 848 printf $fh_retrace_cpp "}\n\n"; 849} 850 851sub do_open($$) { 852 my ($type, $fname) = @_; 853 my $fh; 854 855 if (defined $outtype{$type}) { 856 $fname = "$outdir/$fname"; 857 } else { 858 $fname = "/dev/null"; 859 } 860 861 open($fh, "> $fname") or die "Could not open $fname for writing"; 862 863 return $fh; 864} 865 866 867$fh_trace_cpp = do_open("trace", "trace-gen.cpp"); 868printf $fh_trace_cpp "/* SPDX-License-Identifier: GPL-2.0-only */\n/*\n * Copyright 2022 Collabora Ltd.\n"; 869printf $fh_trace_cpp " *\n * AUTOMATICALLY GENERATED BY v4l2-tracer-gen.pl DO NOT EDIT\n */\n\n"; 870printf $fh_trace_cpp "#include \"v4l2-tracer-common.h\"\n\n"; 871 872$fh_trace_h = do_open("trace", "trace-gen.h"); 873printf $fh_trace_h "/* SPDX-License-Identifier: GPL-2.0-only */\n/*\n * Copyright 2022 Collabora Ltd.\n"; 874printf $fh_trace_h " *\n * AUTOMATICALLY GENERATED BY v4l2-tracer-gen.pl DO NOT EDIT\n */\n\n"; 875printf $fh_trace_h "\#ifndef TRACE_GEN_H\n"; 876printf $fh_trace_h "\#define TRACE_GEN_H\n\n"; 877 878$fh_retrace_cpp = do_open("retrace", "retrace-gen.cpp"); 879printf $fh_retrace_cpp "/* SPDX-License-Identifier: GPL-2.0-only */\n/*\n * Copyright 2022 Collabora Ltd.\n"; 880printf $fh_retrace_cpp " *\n * AUTOMATICALLY GENERATED BY v4l2-tracer-gen.pl DO NOT EDIT\n */\n\n"; 881printf $fh_retrace_cpp "#include \"v4l2-tracer-common.h\"\n\n"; 882 883$fh_retrace_h = do_open("retrace", "retrace-gen.h"); 884printf $fh_retrace_h "/* SPDX-License-Identifier: GPL-2.0-only */\n/*\n * Copyright 2022 Collabora Ltd.\n"; 885printf $fh_retrace_h " *\n * AUTOMATICALLY GENERATED BY v4l2-tracer-gen.pl DO NOT EDIT\n */\n\n"; 886printf $fh_retrace_h "\#ifndef RETRACE_GEN_H\n"; 887printf $fh_retrace_h "\#define RETRACE_GEN_H\n\n"; 888 889$fh_common_info_h = do_open("common", "v4l2-tracer-info-gen.h"); 890printf $fh_common_info_h "/* SPDX-License-Identifier: GPL-2.0-only */\n/*\n * Copyright 2022 Collabora Ltd.\n"; 891printf $fh_common_info_h " *\n * AUTOMATICALLY GENERATED BY v4l2-tracer-gen.pl DO NOT EDIT\n */\n\n"; 892printf $fh_common_info_h "\#ifndef V4L2_TRACER_INFO_GEN_H\n"; 893printf $fh_common_info_h "\#define V4L2_TRACER_INFO_GEN_H\n\n"; 894printf $fh_common_info_h "#include \"v4l2-tracer-common.h\"\n\n"; 895 896$in_v4l2_controls = true; 897 898while (<>) { 899 if (grep {/#define __LINUX_VIDEODEV2_H/} $_) { 900 $in_v4l2_controls = false; 901 } 902 if (grep {/^#define.+FWHT_FL_.+/} $_) { 903 flag_gen("fwht"); 904 } elsif (grep {/^#define V4L2_VP8_LF.*/} $_) { 905 flag_gen("vp8_loop_filter"); 906 } elsif (grep {/^#define.+_FL_.+/} $_) { 907 flag_gen(); 908 } elsif (grep {/^#define.+_FLAG_.+/} $_) { 909 flag_gen(); 910 } 911 if ($in_v4l2_controls eq true) { 912 if (grep {/^struct/} $_) { 913 struct_gen_ctrl(); 914 } 915 } else { 916 if (grep {/^struct/} $_) { 917 struct_gen(); 918 } 919 } 920 921 if (grep {/^enum/} $_) { 922 enum_gen(); 923 } 924 925 if (grep {/^#define\s+(V4L2_CID\w*)\s*.*/} $_) { 926 push (@controls, $_); 927 } 928 929 if (grep {/^#define V4L2_CTRL_CLASS_USER\s+/} $_) { 930 printf $fh_common_info_h "constexpr val_def ctrlclass_val_def[] = {\n"; 931 val_def_gen("V4L2_CTRL_CLASS_COLORIMETRY"); 932 next; 933 } 934 if (grep {/^#define V4L2_CAP_VIDEO_CAPTURE/} $_) { 935 printf $fh_common_info_h "constexpr flag_def v4l2_cap_flag_def[] = {\n"; 936 flag_def_gen("V4L2_CAP_DEVICE_CAPS"); 937 next; 938 } 939 if (grep {/^#define V4L2_PIX_FMT_RGB332\s+/} $_) { 940 printf $fh_common_info_h "constexpr val_def v4l2_pix_fmt_val_def[] = {\n"; 941 val_def_gen("V4L2_PIX_FMT_IPU3_SRGGB10"); 942 next; 943 } 944 if (grep {/^#define V4L2_BUF_CAP_SUPPORTS_MMAP\s+/} $_) { 945 printf $fh_common_info_h "constexpr flag_def v4l2_buf_cap_flag_def[] = {\n"; 946 flag_def_gen("V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS"); 947 next; 948 } 949 if (grep {/^#define V4L2_STD_PAL_B\s+/} $_) { 950 printf $fh_common_info_h "constexpr flag_def std_flag_def[] = {\n"; 951 flag_def_gen("V4L2_STD_ALL"); 952 next 953 } 954 if (grep {/^#define V4L2_MODE_HIGHQUALITY\s+/} $_) { 955 printf $fh_common_info_h "constexpr val_def streamparm_val_def[] = {\n"; 956 val_def_gen("V4L2_CAP_TIMEPERFRAME"); 957 next; 958 } 959 if (grep {/^#define V4L2_INPUT_TYPE_TUNER\s+/} $_) { 960 printf $fh_common_info_h "constexpr val_def input_type_val_def[] = {\n"; 961 val_def_gen("V4L2_INPUT_TYPE_TOUCH"); 962 next 963 } 964 if (grep {/^#define V4L2_IN_ST_NO_POWER\s+/} $_) { 965 printf $fh_common_info_h "constexpr val_def input_field_val_def[] = {\n"; 966 val_def_gen("V4L2_IN_ST_VTR"); 967 next 968 } 969 if (grep {/^#define V4L2_IN_CAP_DV_TIMINGS\s+/} $_) { 970 printf $fh_common_info_h "constexpr flag_def input_cap_flag_def[] = {\n"; 971 flag_def_gen("V4L2_IN_CAP_NATIVE_SIZE"); 972 next 973 } 974 if (grep {/^#define V4L2_OUTPUT_TYPE_MODULATOR\s+/} $_) { 975 printf $fh_common_info_h "constexpr val_def output_type_val_def[] = {\n"; 976 val_def_gen("V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY"); 977 next 978 } 979 if (grep {/^#define V4L2_OUT_CAP_DV_TIMINGS\s+/} $_) { 980 printf $fh_common_info_h "constexpr flag_def output_cap_flag_def[] = {\n"; 981 flag_def_gen("V4L2_OUT_CAP_NATIVE_SIZE"); 982 next 983 } 984 if (grep {/^#define V4L2_TUNER_CAP_LOW\s+/} $_) { 985 printf $fh_common_info_h "constexpr flag_def tuner_cap_flag_def[] = {\n"; 986 flag_def_gen("V4L2_TUNER_CAP_1HZ"); 987 next 988 } 989 if (grep {/^#define V4L2_TUNER_SUB_MONO\s+/} $_) { 990 printf $fh_common_info_h "constexpr flag_def tuner_rxsub_flag_def[] = {\n"; 991 flag_def_gen("V4L2_TUNER_SUB_RDS"); 992 next 993 } 994 if (grep {/^#define V4L2_TUNER_MODE_MONO\s+/} $_) { 995 printf $fh_common_info_h "constexpr val_def tuner_audmode_val_def[] = {\n"; 996 val_def_gen("V4L2_TUNER_MODE_LANG1_LANG2"); 997 next 998 } 999 1000 if (grep {/^#define V4L2_ENC_CMD_START\s+/} $_) { 1001 printf $fh_common_info_h "constexpr val_def encoder_cmd_val_def[] = {\n"; 1002 val_def_gen("V4L2_ENC_CMD_RESUME"); 1003 next; 1004 } 1005 if (grep {/^#define V4L2_DEC_CMD_START\s+/} $_) { 1006 printf $fh_common_info_h "constexpr val_def decoder_cmd_val_def[] = {\n"; 1007 val_def_gen("V4L2_DEC_CMD_FLUSH"); 1008 next; 1009 } 1010 if (grep {/^#define V4L2_DEC_CMD_START_MUTE_AUDIO\s+/} $_) { 1011 printf $fh_common_info_h "constexpr flag_def v4l2_decoder_cmd_start_flag_def[] = {\n"; 1012 flag_def_gen("V4L2_DEC_CMD_START_MUTE_AUDIO"); 1013 next; 1014 } 1015 if (grep {/^#define V4L2_DEC_CMD_PAUSE_TO_BLACK\s+/} $_) { 1016 printf $fh_common_info_h "constexpr flag_def v4l2_decoder_cmd_pause_flag_def[] = {\n"; 1017 flag_def_gen("V4L2_DEC_CMD_PAUSE_TO_BLACK"); 1018 next; 1019 } 1020 if (grep {/^#define V4L2_DEC_CMD_STOP_TO_BLACK\s+/} $_) { 1021 printf $fh_common_info_h "constexpr flag_def v4l2_decoder_cmd_stop_flag_def[] = {\n"; 1022 flag_def_gen("V4L2_DEC_CMD_STOP_IMMEDIATELY"); 1023 next; 1024 } 1025 if (grep {/^#define V4L2_EVENT_ALL\s+/} $_) { 1026 printf $fh_common_info_h "constexpr val_def event_val_def[] = {\n"; 1027 val_def_gen("V4L2_EVENT_PRIVATE_START"); 1028 next; 1029 } 1030 if (grep {/^#define V4L2_EVENT_CTRL_CH_VALUE\s+/} $_) { 1031 printf $fh_common_info_h "constexpr flag_def v4l2_event_ctrl_ch_flag_def[] = {\n"; 1032 flag_def_gen("V4L2_EVENT_CTRL_CH_DIMENSIONS"); 1033 next 1034 } 1035 if (grep {/^#define\s+(VIDIOC_\w*)\s*.*/} $_) { 1036 push (@ioctls, $_); 1037 } 1038 1039 if (grep {/^#define\s+(MEDIA_IOC\w*)\s*.*/} $_) { 1040 push (@ioctls, $_); 1041 } 1042 1043 if (grep {/^#define\s+(MEDIA_REQUEST_IOC\w*)\s*.*/} $_) { 1044 push (@ioctls, $_); 1045 } 1046 if (grep {/^#define V4L2_SEL_TGT_CROP\s+/} $_) { 1047 printf $fh_common_info_h "constexpr val_def selection_target_val_def[] = {\n"; 1048 val_def_gen("V4L2_SEL_TGT_COMPOSE_PADDED"); 1049 next; 1050 } 1051} 1052 1053printf $fh_common_info_h "constexpr val_def control_val_def[] = {\n"; 1054foreach (@controls) { 1055 ($control) = ($_) =~ /^#define\s*(\w+)\s*/; 1056 next if ($control =~ /BASE$/); 1057 printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $control, $control; 1058} 1059printf $fh_common_info_h "\t{ -1, \"\" }\n};\n"; 1060 1061printf $fh_common_info_h "constexpr val_def ioctl_val_def[] = {\n"; 1062foreach (@ioctls) { 1063 ($ioctl) = ($_) =~ /^#define\s*(\w+)\s*/; 1064 printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $ioctl, $ioctl; 1065} 1066printf $fh_common_info_h "\t{ -1, \"\" }\n};\n"; 1067 1068 1069printf $fh_trace_h "\n#endif\n"; 1070close $fh_trace_h; 1071# Delete the last of two new lines to avoid a whitespace error 1072truncate($fh_trace_cpp, tell($fh_trace_cpp) - 1); 1073close $fh_trace_cpp; 1074 1075printf $fh_retrace_h "\n#endif\n"; 1076close $fh_retrace_h; 1077close $fh_retrace_cpp; 1078 1079printf $fh_common_info_h "\n#endif\n"; 1080close $fh_common_info_h; 1081