Generated: Tue Feb 2 17:54:29 2010 from convstruct.pl 2009/09/26 211.4 KB.
# NAME: convstruct.pl # AIM: Convert a GCC structure declaration to one compatible with MSVC # # 20090827 - some improvements - seems to be working well. One idea would be # to have more than 1 structure definition hash, and thus be able to 'decode' # different instance declarations. And then combine instance declaration, and handle # each separatel... and finally, simply read the C/H files directly ;=)) # # 8/21/2009 - geoff mclane - http://geoffair.net/mperl/ use strict; use warnings; # use Data::Dumper; unshift(@INC, 'C:/GTools/perl'); require 'logfile.pl' or die "Unable to load logfile.pl ...\n"; # log file stuff my ($LF); my $pgmname = $0; if ($pgmname =~ /\w{1}:\\.*/) { my @tmpsp = split(/\\/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = "temp.$pgmname.txt"; open_log($outfile); my $out_file = 'tempstruct.txt'; my $in_file = "convstruct.txt"; # instance text my $done_file = 'convstruct-done.txt'; # features my $twinvq_spl = -1; my $do_test_num = $twinvq_spl; # test 1 to 18... or $twinvq_spl my $load_out = 1; # load the file written my $load_log = 1; # load the LOG file contents my $do_multi_sets = 0; # load of MULTIPLE structure, keeping each in a hash HoH my $strip_comments = 1; # strip comments from instance string my $twinvq_str = 'twinvq_str.txt'; my $twinvq_inst = 'twinvq_inst.txt'; # some debug groups my $dbg_str_parse = 0; # like set_debug_on_str_parse() if ($dbg_str_parse); # MAKE building structure VERY NOISY my $dbg_fill_action = 0; # like set_debug_on_fill_str() if ($dbg_fill_action); # make the filling of values VERY NOISY # and to gen a NULL/0 set my $gen_null_set = 0; # load all defineds structures, and generate a NULL for each my @gen_null_for = qw( DVprofile ); #my @gen_null_for = qw( AVInputFormat AVOutputFormat ); #my @gen_null_for = qw( AVCodec ); #my @gen_null_for = qw( URLProtocol ); my $inst_indent = " "; my $memb_indent = " "; my $max_spacing_out = 60; my $max_spacing_out2 = 48; # FEATURE (BIT) FLAGS my $FF_COMM = 1; # add comment after member - default as '//...' comment type my $FF_COM1 = 2; # add comment after member using '/*...*/' comment type my $FF_COMA = 4; # if add comments using '/*...*/, fill to align end my $FF_SORG = 8; # add show of ORIGINAL line my $FF_MSCV = 16; # add #ifdef _MSC_VER to output string my $FF_MSC2 = 32; # extract .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0}, my $FF_MSC3 = 64; # fix (enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE}, my $FF_MSC4 = 128; # fix .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, my $FF_MSC5 = 256; # fix like .channel_layouts = (int64_t[]){CH_LAYOUT_MONO,CH_LAYOUT_STEREO,...}, my $FF_BLLN = 512; # fix - try to break LONG lines my $max_long = 100; # if it contains ',' and is longer than this my $FF_NIND = 2048; # no indenting my $FF_NHED = 4096; # no heading my $FF_INLN = 6192; # no newline in stream # these are only added under certain program conditions my $FF_WPOS = 16384; # this member has a specific position my $FF_BLAN = 32768; # generate a BLANK instance block my $FF_WNUM = 65536; # we have an instance with set number of blocks in head my $FF_MSVC_SET = ($FF_MSCV | $FF_MSC2 | $FF_MSC3 | $FF_MSC4 | $FF_MSC5 | $FF_BLLN); # bit flags to modify member construction = 1 = put member name 2 = use /* ... */ my $features = ($FF_COMM | $FF_COM1 | $FF_COMA | $FF_MSVC_SET ); my $use_copy_hash = 1; my $bad_posn = -200; # MEMBER ARRAY my $str_tag = 'TAG'; my $mem_bgn = 'member'; # plus a number my $str_nam = 'NAME'; # name of 'structure' my $mem_cnt = "MEMBER_COUNT"; # count of members in structure my $mem_nxt = "NEXT_MEMEBR"; # and NEXT member # DECLARATION - like # Master - Note a 'master' ONLY contains ONE filled instance, but that 'instance' can consist of more # than ONE block, inst_name[NUMBER], in which case $mast_len contains this number # BUT the 'master' can also contain lots of NON-filled other structure definitions # ==================================================================================================== my $mast_inst = 'INSTANCE'; # name of 'instance' as a FULL LINE like 'str_name inst_name [] = {'... my $mast_iname = 'INAME'; # specific NAME of instance, like 'wav_muxer'... my $mast_len = 'LENGTH'; # block count of instances, if any, like inst_name[NUMBER] = { my $mast_copied = 'COPIED'; # count of FILLED members COPIED to master # Blocks my $str_off = 'OFFSET'; # to place the block member at a specific OFFSET, in a group of BLOCK my $str_done = 'DONE'; # Enumeration of values, like [AAA] my $str_enum = 'ENUMERATION'; # offsets into members array my $O_TYP = 0; # member type - int, uint8_t, enum AVCod *, ...etc my $O_NAM = 1; # member name - if a function pointer '(*func)(int a,...)' my $O_ORG = 2; # original structure line my $O_VAL = 3; # value found my $O_DEC = 4; # declaration line my $O_FNM = 5; # if a function pointer, like (*foo)(int a, char *p, ...), then 'foo' - it simple name here my $O_BIT = 6; # if a member is 'name : number' bits, then this contains the BITS number, else -1 # decode BIT fsflags used in sub add_line_2_hash my $F_HADID = 1; my $F_HADEND = 2; my $F_HADDOT = 4; my $F_HADMEM = 8; # added at least ONE member to the HASH # level dependant things kept my $L_EQU = 0; # equal sign my $L_CMA = 1; # comma my $L_DOT = 2; # dot my $L_QOT = 3; # double quotes my $L_QT1 = 4; # single quotes my $L_BRA = 5; # inc on '(' dec on ')' my $L_BRC = 6; # inc on '{' dec on '}' my $L_SQU = 7; # inc on '[' dec on ']' my ($act_href); my ($mast_ref_hoh); # DEBUG # a test and exit my $test_only = 0; # keyed to the structure name # individual debug actions my $dbg_spl = 1; # to show something special my $dbgext = 0; # show lots of stages in decode of structure - my $dbg00 = 0; # show prt("$lnn: deal with member [$line], split=$ac, type=$typ, next=$nxt\n" ) if ($dbg00); my $dbg01 = 0; # show each line of structure my $dbg02 = 0; # show structure collected... my $dbg03 = 0; # show def re-lining my $dbg04 = 0; # show discarded comments in building structure members my $dbg05 = 0; # show discarded comments 1 /*...*/ in filling structure my $dbg06 = 0; # show discarded comments 2 // to EOL in filling structure my $dbg07 = 0; # show prt( "Added [$equ] to key [$key], for off[$off]\n" ) my $dbg08 = 0; # show each line in structure filling my $dbg09 = 0; # show level information my $dbg10 = 0; # call show_full_hash_of_hashes( $rfullhash ) if ($dbg10); my $dbg11 = 0; # show discarded comments in enum parsing my $dbg12 = 0; # show brace stack levels my $dbg13 = 0; # show prt( "$msg:$lvl: [$ln]\n" ) if ($dbg13); in sub deal_with_enum_line($$$$$) { my $dbg14 = 0; # show the resultant HASH after enumeration parse - prt("***************\n".show_enum_hash(0,$rpf).... my $dbg15 = 0; # show prt("WARNING: [$k]=[$v], NOT [$wd]!\n"); for missed 'NAME' in hash my $dbg16 = 0; # show $msg = "Checking [$word] "; my $dbg17 = 0; # for $msg .= "$key => Enumeration HASH - $c2 items\n"; show each enumeration my $dbg18 = 0; # show block messages - open and close BLOCK - like prt( "$lnn:$lvl: Open new BLOCK... on [$ln]\n")... my $dbg19 = 0; # show prt( "$lnn:$lvl: [$ln] as offset [$off]\n"); my $dbg20 = 0; # show prt("Add [$ln] to hash...\n")... my $dbg21 = 0; # show prt("[dbg21] Got length [$snum](".length($snum).") - decode or lookup in enum...\n")... my $dbg22 = 0; # show prt("Doing is id - split $al...\n"); my $dbg23 = 0; # show prt("[dbg23] $lnn:deal_with_member: got BITS split name=[$sec], bits=[$bit]\n") if ($dbg23); my $dbg24 = 0; # show prt( "\n[dbg24] Display of $c structures loaded...\n" ); and each structure my $dbg25 = 0; # show prt( "[dbg25] Bulding structure hash... $len chars...\n" ) if ($dbg25); my $dbg26 = 0; # show prt("[dbg26] Start of structure: [$msg]\n") if ($dbg26); my $dbg27 = 0; # show prt("[dbg27] Closing: $msg\n") if ($dbg27); + line number, and word found = structure NAME my $dbg28 = 0; # show prt("[dbg28] get_total_block: key=[$k] has value [$t]\n") if ($dbg28); my $dbg29 = 0; # show prt( "[dbg29] Get struct instance string - total=$len, not-unique=$nuniq, blk/pos=$pcnt copied=$imax\n" ); my $dbg30 = 0; # show prt( "[dbg30] Keys:[$msg]\n"); my $dbg31 = 1; # show prt( "[dbg31] Returning potential name [$tg], from [$tx]\n" ) if ($dbg31); my @res_words = qw( static typedef struct unsigned int enum const char uint8_t short uint16_t long uint32_t int64_t ); my @warnings = (); sub get_dbg_str() { my $str = ''; if ($dbgext) { $str .= "ext "; } # show lots of stages in decode of structure - if ($dbg00) { $str .= "00 "; } # show prt("$lnn: deal with member [$line], split=$ac, type=$typ, next=$nxt\n" ) if ($dbg00); if ($dbg01) { $str .= "01 "; } # show each line of structure if ($dbg02) { $str .= "02 "; } # show structure collected... if ($dbg03) { $str .= "03 "; } # show def re-lining if ($dbg04) { $str .= "04 "; } # show discarded comments in building structure members if ($dbg05) { $str .= "05 "; } # show discarded comments 1 /*...*/ in filling structure if ($dbg06) { $str .= "06 "; } # show discarded comments 2 // to EOL in filling structure if ($dbg07) { $str .= "07 "; } # show prt( "Added [$equ] to key [$key], for off[$off]\n" ) if ($dbg08) { $str .= "08 "; } # show each line in structure filling if ($dbg09) { $str .= "09 "; } # show level information if ($dbg10) { $str .= "10 "; } # call show_full_hash_of_hashes( $rfullhash ) if ($dbg10); if ($dbg11) { $str .= "11 "; } # show discarded comments in enum parsing if ($dbg12) { $str .= "12 "; } # show brace stack levels if ($dbg13) { $str .= "13 "; } # show prt( "$msg:$lvl: [$ln]\n" ) if ($dbg13); in sub deal_with_enum_line if ($dbg14) { $str .= "14 "; } # show the resultant HASH after enumeration parse - prt("***************\n".show_enum_hash(0,$rpf).... if ($dbg15) { $str .= "15 "; } # show prt("WARNING: [$k]=[$v], NOT [$wd]!\n"); for missed 'NAME' in hash if ($dbg16) { $str .= "16 "; } # show $msg = "Checking [$word] "; if ($dbg17) { $str .= "17 "; } # for $msg .= "$key => Enumeration HASH - $c2 items\n"; show each enumeration if ($dbg18) { $str .= "18 "; } # show block messages - open and close BLOCK - like prt( "$lnn:$lvl: Open new BLOCK... on [$ln]\n") if ($dbg18); if ($dbg19) { $str .= "19 "; } # show prt( "$lnn:$lvl: [$ln] as offset [$off]\n"); if ($dbg20) { $str .= "20 "; } # show prt("Add [$ln] to hash...\n") if ($dbg20); if ($dbg21) { $str .= "21 "; } # show prt("[dbg21] Got length [$snum](".length($snum).") - decode or lookup in enum...\n") if ($dbg21); if ($dbg22) { $str .= "22 "; } # show prt("Doing is id - split $al...\n"); if ($dbg23) { $str .= "23 "; } # show prt("[dbg23] $lnn:deal_with_member: got BITS split name=[$sec], bits=[$bit]\n") if ($dbg23); if ($dbg24) { $str .= "24 "; } # show prt( "\n[dbg24] Display of $c structures loaded...\n" ); and each structure if ($dbg25) { $str .= "24 "; } # show prt( "[dbg25] Bulding structure hash... $len chars...\n" ) if ($dbg25); if ($dbg26) { $str .= "26 "; } # show prt("[dbg26] Start of structure: [$msg]\n") if ($dbg26); if ($dbg27) { $str .= "27 "; } # show prt("[dbg27] Closing: $msg\n") if ($dbg27); + line number, and word found = structure NAME if ($dbg28) { $str .= "28 "; } # show prt("[dbg28] get_total_block: key=[$k] has value [$t]\n") if ($dbg28); if ($dbg29) { $str .= "29 "; } # show prt( "[dbg29] Get struct instance string - total=$len, not-unique=$nuniq, blk/pos=$pcnt copied=$imax\n" ); if ($dbg30) { $str .= "30 "; } # show prt( "[dbg30] Keys:[$msg]\n"); if ($dbg31) { $str .= "31 "; } # show prt( "[dbg31] Returning potential name [$tg], from [$tx]\n" ) if ($dbg31); return $str; } sub prtw($) { my ($txt) = shift; prt($txt); $txt =~ s/\n$//; push(@warnings,$txt); } sub show_warnings() { if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS ...\n" ); foreach my $line (@warnings) { prt("$line\n" ); } } else { prt("\nNo warnings issued.\n"); } my $s = get_dbg_str(); prt( "WARNING: DEBUG ON [$s]\n" ) if length($s); prt("\n"); } sub my_exit($$) { my ($ret,$msg) = @_; prt($msg) if (length($msg)); show_warnings(); close_log($outfile,$load_log); exit($ret); } sub word_in_array($$) { my ($wd,$rar) = @_; foreach my $w (@{$rar}) { if ($w eq $wd) { return 1; } } return 0; } sub word_in_res_words($) { my ($wd) = shift; return word_in_array($wd, \@res_words); } sub get_unique_key($) { # ($str_tag) # something like "\@_".$str_tag."_\@", or... my ($k) = shift; return "!_".$k."_!"; } sub key_is_unique_type($) { # like say $k =~ /^\@_/, or ... my ($k) = shift; if ($k =~ /^!_(.+)_!$/) { return 1; } return 0; } sub show_struc_defines($$$) { my ($call, $rh, $wd) = @_; my $msg = ""; my $caller = (($call == 1) ? "word_is_rh_name: " : "word_is_rh_name_2: "); foreach my $k (keys %{$rh}) { if ($k =~ /^$mem_bgn/) { # $msg .= "{$k}"; } else { $msg .= "\n[$k = ".${$rh}{$k}."]"; } } prt( "$caller seeks [$wd], list is == $msg ==\n" ); } sub get_total_blocks($) { my ($rmh) = shift; my $k = get_unique_key($mast_len); my $t = $bad_posn; if (defined ${$rmh}{$k}) { $t = ${$rmh}{$k}; prt("[dbg28] get_total_block: key=[$k] has value [$t]\n") if ($dbg28); } else { prt("[dbg28] get_total_block: key=[$k] NOT DEFINED\n") if ($dbg28); } return $t; } sub get_copied_count($) { my ($rmh) = shift; my $k = get_unique_key($mast_copied); my $t = $bad_posn; if (defined ${$rmh}{$k}) { $t = ${$rmh}{$k}; prt("[dbg28] get_copied_count: key=[$k] has value [$t]\n") if ($dbg28); } else { prt("[dbg28] get_copied_count: key=[$k] NOT DEFINED\n") if ($dbg28); } return $t; } sub trim_ends($) { my ($t) = shift; $t = substr($t,1) while ($t =~ /^\s/); # clear leading $t = substr($t,0,length($t)-1) while ($t =~ /\s$/); # and trailing return $t; } ################################################ # My particular time 'translation' # 20090904 - added format to add hh:mm:ss (bit 1) sub YYYYMMDD($$) { # 0 1 2 3 4 5 6 7 8 my ($fm,$tm) = @_; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($tm); $year += 1900; $mon += 1; my $ymd = "$year/"; if ($mon < 10) { $ymd .= '0'.$mon.'/'; } else { $ymd .= "$mon/"; } if ($mday < 10) { $ymd .= '0'.$mday; } else { $ymd .= "$mday"; } if ($fm & 1) { $ymd .= " "; if ($hour < 10) { $ymd .= '0'.$hour; } else { $ymd .= $hour; } $ymd .= ':'; if ($min < 10) { $ymd .= '0'.$min; } else { $ymd .= $min; } $ymd .= ':'; if ($sec < 10) { $ymd .= '0'.$sec; } else { $ymd .= $sec; } } return $ymd; } sub add_to_done_file($) { my ($gcc) = shift; my $s = get_dbg_str(); if (length($s)) { prtw( "WARNING: This action NOT added to file [$done_file] due some DEBUG ON!\n" ); return 0; } my $tm = YYYYMMDD(1,time()); $gcc = "// =========================================================\n// $tm\n$gcc"; $gcc .= "\n" if !($gcc =~ /\n$/); $gcc .= "// =========================================================\n"; if (-f $done_file) { append2file($gcc,$done_file); } else { write2file($gcc,$done_file); } return 1; } ###################################################################################################### # ==================================================================================================== # EXAMPLE DATA # ==================================================================================================== # test 1 my $enum_pixfmt = <<EOF; enum PixelFormat { PIX_FMT_NONE= -1, PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) PIX_FMT_GRAY8, ///< Y , 8bpp PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white PIX_FMT_PAL8, ///< 8 bit with PIX_FMT_RGB32 palette PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG) PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG) PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG) PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing PIX_FMT_XVMC_MPEG2_IDCT, PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) PIX_FMT_BGR4, ///< packed RGB 1:2:1, 4bpp, (msb)1B 2G 1R(lsb) PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) PIX_FMT_RGB4, ///< packed RGB 1:2:1, 4bpp, (msb)1R 2G 1B(lsb) PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 for UV PIX_FMT_NV21, ///< as above, but U and V bytes are swapped PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG) PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, big-endian PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, little-endian PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1 PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1 PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers PIX_FMT_VAAPI_VLD, ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers PIX_FMT_YUV420PLE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian PIX_FMT_YUV420PBE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian PIX_FMT_YUV422PLE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian PIX_FMT_YUV422PBE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian PIX_FMT_YUV444PLE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian PIX_FMT_YUV444PBE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; EOF my $struct_details1 = <<EOF; typedef struct PixFmtInfo { const char *name; uint8_t nb_channels; /**< number of channels (including alpha) */ uint8_t color_type; /**< color type (see FF_COLOR_xxx constants) */ uint8_t pixel_type; /**< pixel storage type (see FF_PIXEL_xxx constants) */ uint8_t is_alpha : 1; /**< true if alpha can be specified */ uint8_t is_hwaccel : 1; /**< true if this is an HW accelerated format */ uint8_t x_chroma_shift; /**< X chroma subsampling factor is 2 ^ shift */ uint8_t y_chroma_shift; /**< Y chroma subsampling factor is 2 ^ shift */ uint8_t depth; /**< bit depth of the color components */ } PixFmtInfo; EOF my $gcc_struct1_short_test = <<EOF; static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { /* YUV formats */ [PIX_FMT_YUV420P] = { .name = "yuv420p", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_YUV422P] = { .name = "yuv422p", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 0, }, }; EOF my $gcc_struct1 = <<EOF; static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { /* YUV formats */ [PIX_FMT_YUV420P] = { .name = "yuv420p", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_YUV422P] = { .name = "yuv422p", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 0, }, [PIX_FMT_YUV444P] = { .name = "yuv444p", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_YUYV422] = { .name = "yuyv422", .nb_channels = 1, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 0, }, [PIX_FMT_UYVY422] = { .name = "uyvy422", .nb_channels = 1, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 0, }, [PIX_FMT_YUV410P] = { .name = "yuv410p", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 2, .y_chroma_shift = 2, }, [PIX_FMT_YUV411P] = { .name = "yuv411p", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 2, .y_chroma_shift = 0, }, [PIX_FMT_YUV440P] = { .name = "yuv440p", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 1, }, [PIX_FMT_YUV420PLE] = { .name = "yuv420ple", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 16, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_YUV422PLE] = { .name = "yuv422ple", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 16, .x_chroma_shift = 1, .y_chroma_shift = 0, }, [PIX_FMT_YUV444PLE] = { .name = "yuv444ple", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 16, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_YUV420PBE] = { .name = "yuv420pbe", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 16, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_YUV422PBE] = { .name = "yuv422pbe", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 16, .x_chroma_shift = 1, .y_chroma_shift = 0, }, [PIX_FMT_YUV444PBE] = { .name = "yuv444pbe", .nb_channels = 3, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 16, .x_chroma_shift = 0, .y_chroma_shift = 0, }, /* YUV formats with alpha plane */ [PIX_FMT_YUVA420P] = { .name = "yuva420p", .nb_channels = 4, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 1, }, /* JPEG YUV */ [PIX_FMT_YUVJ420P] = { .name = "yuvj420p", .nb_channels = 3, .color_type = FF_COLOR_YUV_JPEG, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_YUVJ422P] = { .name = "yuvj422p", .nb_channels = 3, .color_type = FF_COLOR_YUV_JPEG, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 0, }, [PIX_FMT_YUVJ444P] = { .name = "yuvj444p", .nb_channels = 3, .color_type = FF_COLOR_YUV_JPEG, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_YUVJ440P] = { .name = "yuvj440p", .nb_channels = 3, .color_type = FF_COLOR_YUV_JPEG, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 1, }, /* RGB formats */ [PIX_FMT_RGB24] = { .name = "rgb24", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_BGR24] = { .name = "bgr24", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_ARGB] = { .name = "argb", .nb_channels = 4, .is_alpha = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_RGB48BE] = { .name = "rgb48be", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 16, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_RGB48LE] = { .name = "rgb48le", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 16, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_RGB565BE] = { .name = "rgb565be", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 5, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_RGB565LE] = { .name = "rgb565le", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 5, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_RGB555BE] = { .name = "rgb555be", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 5, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_RGB555LE] = { .name = "rgb555le", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 5, .x_chroma_shift = 0, .y_chroma_shift = 0, }, /* gray / mono formats */ [PIX_FMT_GRAY16BE] = { .name = "gray16be", .nb_channels = 1, .color_type = FF_COLOR_GRAY, .pixel_type = FF_PIXEL_PLANAR, .depth = 16, }, [PIX_FMT_GRAY16LE] = { .name = "gray16le", .nb_channels = 1, .color_type = FF_COLOR_GRAY, .pixel_type = FF_PIXEL_PLANAR, .depth = 16, }, [PIX_FMT_GRAY8] = { .name = "gray", .nb_channels = 1, .color_type = FF_COLOR_GRAY, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, }, [PIX_FMT_MONOWHITE] = { .name = "monow", .nb_channels = 1, .color_type = FF_COLOR_GRAY, .pixel_type = FF_PIXEL_PLANAR, .depth = 1, }, [PIX_FMT_MONOBLACK] = { .name = "monob", .nb_channels = 1, .color_type = FF_COLOR_GRAY, .pixel_type = FF_PIXEL_PLANAR, .depth = 1, }, /* paletted formats */ [PIX_FMT_PAL8] = { .name = "pal8", .nb_channels = 4, .is_alpha = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PALETTE, .depth = 8, }, [PIX_FMT_XVMC_MPEG2_MC] = { .name = "xvmcmc", .is_hwaccel = 1, }, [PIX_FMT_XVMC_MPEG2_IDCT] = { .name = "xvmcidct", .is_hwaccel = 1, }, [PIX_FMT_VDPAU_MPEG1] = { .name = "vdpau_mpeg1", .is_hwaccel = 1, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_VDPAU_MPEG2] = { .name = "vdpau_mpeg2", .is_hwaccel = 1, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_VDPAU_H264] = { .name = "vdpau_h264", .is_hwaccel = 1, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_VDPAU_WMV3] = { .name = "vdpau_wmv3", .is_hwaccel = 1, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_VDPAU_VC1] = { .name = "vdpau_vc1", .is_hwaccel = 1, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_UYYVYY411] = { .name = "uyyvyy411", .nb_channels = 1, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 2, .y_chroma_shift = 0, }, [PIX_FMT_ABGR] = { .name = "abgr", .nb_channels = 4, .is_alpha = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_BGR565BE] = { .name = "bgr565be", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 5, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_BGR565LE] = { .name = "bgr565le", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 5, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_BGR555BE] = { .name = "bgr555be", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 5, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_BGR555LE] = { .name = "bgr555le", .nb_channels = 3, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 5, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_RGB8] = { .name = "rgb8", .nb_channels = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_RGB4] = { .name = "rgb4", .nb_channels = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 4, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_RGB4_BYTE] = { .name = "rgb4_byte", .nb_channels = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_BGR8] = { .name = "bgr8", .nb_channels = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_BGR4] = { .name = "bgr4", .nb_channels = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 4, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_BGR4_BYTE] = { .name = "bgr4_byte", .nb_channels = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_NV12] = { .name = "nv12", .nb_channels = 2, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_NV21] = { .name = "nv12", .nb_channels = 2, .color_type = FF_COLOR_YUV, .pixel_type = FF_PIXEL_PLANAR, .depth = 8, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_BGRA] = { .name = "bgra", .nb_channels = 4, .is_alpha = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, [PIX_FMT_RGBA] = { .name = "rgba", .nb_channels = 4, .is_alpha = 1, .color_type = FF_COLOR_RGB, .pixel_type = FF_PIXEL_PACKED, .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, /* VA API formats */ [PIX_FMT_VAAPI_MOCO] = { .name = "vaapi_moco", .is_hwaccel = 1, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_VAAPI_IDCT] = { .name = "vaapi_idct", .is_hwaccel = 1, .x_chroma_shift = 1, .y_chroma_shift = 1, }, [PIX_FMT_VAAPI_VLD] = { .name = "vaapi_vld", .is_hwaccel = 1, .x_chroma_shift = 1, .y_chroma_shift = 1, }, }; EOF # ==================================================================================================== # test 2 my $struct_details2 = <<EOF; typedef struct DVprofile { int dsf; /* value of the dsf in the DV header */ int video_stype; /* stype for VAUX source pack */ int frame_size; /* total size of one frame in bytes */ int difseg_size; /* number of DIF segments per DIF channel */ int n_difchan; /* number of DIF channels per frame */ AVRational time_base; /* 1/framerate */ int ltc_divisor; /* FPS from the LTS standpoint */ int height; /* picture height in pixels */ int width; /* picture width in pixels */ AVRational sar[2]; /* sample aspect ratios for 4:3 and 16:9 */ DVwork_chunk *work_chunks; /* each thread gets its own chunk of frame to work on */ uint32_t *idct_factor; /* set of iDCT factor tables */ enum PixelFormat pix_fmt; /* picture pixel format */ int bpm; /* blocks per macroblock */ const uint8_t *block_sizes; /* AC block sizes, in bits */ int audio_stride; /* size of audio_shuffle table */ int audio_min_samples[3]; /* min amount of audio samples */ /* for 48kHz, 44.1kHz and 32kHz */ int audio_samples_dist[5]; /* how many samples are supposed to be */ /* in each frame in a 5 frames window */ const uint8_t (*audio_shuffle)[9]; /* PCM shuffling table */ } DVprofile; EOF my $gcc_struct2 = <<EOF; static const DVprofile dv_profiles[] = { { .dsf = 0, // DISCARD THIS TYPE .video_stype = 0x0, .frame_size = 120000, /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */ .difseg_size = 10, .n_difchan = 1, .time_base = { 1001, 30000 }, .ltc_divisor = 30, .height = 480, .width = 720, .sar = {{10, 11}, {40, 33}}, .work_chunks = &work_chunks_dv25ntsc[0], .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = PIX_FMT_YUV411P, .bpm = 6, .block_sizes = block_sizes_dv2550, .audio_stride = 90, .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */ .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ .audio_shuffle = dv_audio_shuffle525, }, { .dsf = 1, .video_stype = 0x0, .frame_size = 144000, /* IEC 61834 - 625/50 (PAL) */ .difseg_size = 12, .n_difchan = 1, .time_base = { 1, 25 }, .ltc_divisor = 25, .height = 576, .width = 720, .sar = {{59, 54}, {118, 81}}, .work_chunks = &work_chunks_dv25pal[0], .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = PIX_FMT_YUV420P, .bpm = 6, .block_sizes = block_sizes_dv2550, .audio_stride = 108, .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, .audio_shuffle = dv_audio_shuffle625, }, { .dsf = 1, .video_stype = 0x0, .frame_size = 144000, /* SMPTE-314M - 625/50 (PAL) */ .difseg_size = 12, .n_difchan = 1, .time_base = { 1, 25 }, .ltc_divisor = 25, .height = 576, .width = 720, .sar = {{59, 54}, {118, 81}}, .work_chunks = &work_chunks_dv25pal411[0], .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = PIX_FMT_YUV411P, .bpm = 6, .block_sizes = block_sizes_dv2550, .audio_stride = 108, .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, .audio_shuffle = dv_audio_shuffle625, }, { .dsf = 0, .video_stype = 0x4, .frame_size = 240000, /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */ .difseg_size = 10, /* also known as "DVCPRO50" */ .n_difchan = 2, .time_base = { 1001, 30000 }, .ltc_divisor = 30, .height = 480, .width = 720, .sar = {{10, 11}, {40, 33}}, .work_chunks = &work_chunks_dv50ntsc[0], .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = PIX_FMT_YUV422P, .bpm = 6, .block_sizes = block_sizes_dv2550, .audio_stride = 90, .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */ .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ .audio_shuffle = dv_audio_shuffle525, }, { .dsf = 1, .video_stype = 0x4, .frame_size = 288000, /* SMPTE-314M - 625/50 (PAL) 50 Mbps */ .difseg_size = 12, /* also known as "DVCPRO50" */ .n_difchan = 2, .time_base = { 1, 25 }, .ltc_divisor = 25, .height = 576, .width = 720, .sar = {{59, 54}, {118, 81}}, .work_chunks = &work_chunks_dv50pal[0], .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = PIX_FMT_YUV422P, .bpm = 6, .block_sizes = block_sizes_dv2550, .audio_stride = 108, .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, .audio_shuffle = dv_audio_shuffle625, }, { .dsf = 0, .video_stype = 0x14, .frame_size = 480000, /* SMPTE-370M - 1080i60 100 Mbps */ .difseg_size = 10, /* also known as "DVCPRO HD" */ .n_difchan = 4, .time_base = { 1001, 30000 }, .ltc_divisor = 30, .height = 1080, .width = 1280, .sar = {{1, 1}, {1, 1}}, .work_chunks = &work_chunks_dv100ntsci[0], .idct_factor = &dv_idct_factor_hd1080[0], .pix_fmt = PIX_FMT_YUV422P, .bpm = 8, .block_sizes = block_sizes_dv100, .audio_stride = 90, .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */ .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ .audio_shuffle = dv_audio_shuffle525, }, { .dsf = 1, .video_stype = 0x14, .frame_size = 576000, /* SMPTE-370M - 1080i50 100 Mbps */ .difseg_size = 12, /* also known as "DVCPRO HD" */ .n_difchan = 4, .time_base = { 1, 25 }, .ltc_divisor = 25, .height = 1080, .width = 1440, .sar = {{1, 1}, {1, 1}}, .work_chunks = &work_chunks_dv100pali[0], .idct_factor = &dv_idct_factor_hd1080[0], .pix_fmt = PIX_FMT_YUV422P, .bpm = 8, .block_sizes = block_sizes_dv100, .audio_stride = 108, .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, .audio_shuffle = dv_audio_shuffle625, }, { .dsf = 0, .video_stype = 0x18, .frame_size = 240000, /* SMPTE-370M - 720p60 100 Mbps */ .difseg_size = 10, /* also known as "DVCPRO HD" */ .n_difchan = 2, .time_base = { 1001, 60000 }, .ltc_divisor = 60, .height = 720, .width = 960, .sar = {{1, 1}, {1, 1}}, .work_chunks = &work_chunks_dv100ntscp[0], .idct_factor = &dv_idct_factor_hd720[0], .pix_fmt = PIX_FMT_YUV422P, .bpm = 8, .block_sizes = block_sizes_dv100, .audio_stride = 90, .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32kHz */ .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ .audio_shuffle = dv_audio_shuffle525, }, { .dsf = 1, .video_stype = 0x18, .frame_size = 288000, /* SMPTE-370M - 720p50 100 Mbps */ .difseg_size = 12, /* also known as "DVCPRO HD" */ .n_difchan = 2, .time_base = { 1, 50 }, .ltc_divisor = 50, .height = 720, .width = 960, .sar = {{1, 1}, {1, 1}}, .work_chunks = &work_chunks_dv100palp[0], .idct_factor = &dv_idct_factor_hd720[0], .pix_fmt = PIX_FMT_YUV422P, .bpm = 8, .block_sizes = block_sizes_dv100, .audio_stride = 90, .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32kHz */ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, .audio_shuffle = dv_audio_shuffle625, } }; EOF # ==================================================================================================== # test 3 my $struct_details3 = <<EOF; /** * AVCodec. */ typedef struct AVCodec { /** * Name of the codec implementation. * The name is globally unique among encoders and among decoders (but an * encoder and a decoder can share the same name). * This is the primary way to find a codec from the user perspective. */ const char *name; enum CodecType type; enum CodecID id; int priv_data_size; int (*init)(AVCodecContext *); int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); int (*close)(AVCodecContext *); int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); /** * Codec capabilities. * see CODEC_CAP_* */ int capabilities; struct AVCodec *next; /** * Flush buffers. * Will be called when seeking */ void (*flush)(AVCodecContext *); const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} const enum PixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 /** * Descriptive name for the codec, meant to be more human readable than name. * You should use the NULL_IF_CONFIG_SMALL() macro to define it. */ const char *long_name; const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 const enum SampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 } AVCodec; EOF my $gcc_struct3_1 = <<EOF; AVCodec libfaac_encoder = { "libfaac", CODEC_TYPE_AUDIO, CODEC_ID_AAC, sizeof(FaacAudioContext), Faac_encode_init, Faac_encode_frame, Faac_encode_close, .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Codec)"), }; EOF my $gcc_struct3_2 = <<EOF; AVCodec libfaad2_decoder = { .name = "AAC_LATM", .type = CODEC_TYPE_AUDIO, .id = CODEC_ID_AAC_LATM, .priv_data_size = sizeof (FAACContext), .init = faac_decode_init, .close = faac_decode_end, .decode = faac_decode_frame, .long_name = "AAC over LATM", }; EOF my $gcc_struct3 = <<EOF; AVCodec ac3_encoder = { "ac3", CODEC_TYPE_AUDIO, CODEC_ID_AC3, sizeof(AC3EncodeContext), AC3_encode_init, AC3_encode_frame, AC3_encode_close, NULL, .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .channel_layouts = (int64_t[]){ CH_LAYOUT_MONO, CH_LAYOUT_STEREO, CH_LAYOUT_2_1, CH_LAYOUT_SURROUND, CH_LAYOUT_2_2, CH_LAYOUT_QUAD, CH_LAYOUT_4POINT0, CH_LAYOUT_5POINT0, CH_LAYOUT_5POINT0_BACK, (CH_LAYOUT_MONO | CH_LOW_FREQUENCY), (CH_LAYOUT_STEREO | CH_LOW_FREQUENCY), (CH_LAYOUT_2_1 | CH_LOW_FREQUENCY), (CH_LAYOUT_SURROUND | CH_LOW_FREQUENCY), (CH_LAYOUT_2_2 | CH_LOW_FREQUENCY), (CH_LAYOUT_QUAD | CH_LOW_FREQUENCY), (CH_LAYOUT_4POINT0 | CH_LOW_FREQUENCY), CH_LAYOUT_5POINT1, CH_LAYOUT_5POINT1_BACK, 0 }, }; EOF # ==================================================================================================== # test 4 my $struct_details4 = <<EOF; /** * Descriptor that unambiguously describes how the bits of a pixel are * stored in the up to 4 data planes of an image. It also stores the * subsampling factors and number of components. * * \@note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV * and all the YUV variants) AVPixFmtDescriptor just stores how values * are stored not what these values represent. */ typedef struct AVPixFmtDescriptor{ const char *name; uint8_t nb_channels; ///< The number of components each pixel has, (1-4) /** * Amount to shift the luma width right to find the chroma width. * For YV12 this is 1 for example. * chroma_width = -((-luma_width) >> log2_chroma_w) * The note above is needed to ensure rounding up. */ uint8_t log2_chroma_w; ///< chroma_width = -((-luma_width )>>log2_chroma_w) /** * Amount to shift the luma height right to find the chroma height. * For YV12 this is 1 for example. * chroma_height= -((-luma_height) >> log2_chroma_h) * The note above is needed to ensure rounding up. */ uint8_t log2_chroma_h; uint8_t flags; AVComponentDescriptor comp[4]; ///< parameters that describe how pixels are packed }AVPixFmtDescriptor; // #define PIX_FMT_BE 1 ///< big-endian // #define PIX_FMT_PAL 2 ///< Pixel format has a palette in data[1], values are indexes in this palette. // #define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end. EOF # and of AVCOmponentDecriptor my $struct_details4a = <<EOF; typedef struct AVComponentDescriptor{ uint16_t plane :2; ///< which of the 4 planes contains the component /** * Number of elements between 2 horizontally consecutive pixels minus 1. * Elements are bits for bitstream formats, bytes otherwise. */ uint16_t step_minus1 :3; /** * Number of elements before the component of the first pixel plus 1. * Elements are bits for bitstream formats, bytes otherwise. */ uint16_t offset_plus1 :3; uint16_t shift :3; ///< number of least significant bits that must be shifted away to get the value uint16_t depth_minus1 :4; ///< number of bits in the component minus 1 }AVComponentDescriptor; EOF my $gcc_struct4 = <<EOF; const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = { [PIX_FMT_YUV420P] = { .name = "yuv420p", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 1, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ }, }, [PIX_FMT_YUYV422] = { .name = "yuyv422", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 0, .comp = { {0,1,1,0,7}, /* Y */ {0,3,2,0,7}, /* U */ {0,3,4,0,7}, /* V */ }, }, [PIX_FMT_RGB24] = { .name = "rgb24", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,2,1,0,7}, /* R */ {0,2,2,0,7}, /* G */ {0,2,3,0,7}, /* B */ }, }, [PIX_FMT_BGR24] = { .name = "bgr24", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,2,1,0,7}, /* B */ {0,2,2,0,7}, /* G */ {0,2,3,0,7}, /* R */ }, }, [PIX_FMT_YUV422P] = { .name = "yuv422p", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 0, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ }, }, [PIX_FMT_YUV444P] = { .name = "yuv444p", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ }, }, [PIX_FMT_YUV410P] = { .name = "yuv410p", .nb_channels = 3, .log2_chroma_w= 2, .log2_chroma_h= 2, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ }, }, [PIX_FMT_YUV411P] = { .name = "yuv411p", .nb_channels = 3, .log2_chroma_w= 2, .log2_chroma_h= 0, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ }, }, [PIX_FMT_GRAY8] = { .name = "gray8", .nb_channels = 1, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,0,1,0,7}, /* Y */ }, }, [PIX_FMT_MONOWHITE] = { .name = "monowhite", .nb_channels = 1, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,0,1,0,0}, /* Y */ }, .flags = PIX_FMT_BITSTREAM, }, [PIX_FMT_MONOBLACK] = { .name = "monoblack", .nb_channels = 1, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,0,1,7,0}, /* Y */ }, .flags = PIX_FMT_BITSTREAM, }, [PIX_FMT_PAL8] = { .name = "pal8", .nb_channels = 1, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,0,1,0,7}, }, .flags = PIX_FMT_PAL, }, [PIX_FMT_YUVJ420P] = { .name = "yuvj420p", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 1, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ }, }, [PIX_FMT_YUVJ422P] = { .name = "yuvj422p", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 0, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ }, }, [PIX_FMT_YUVJ444P] = { .name = "yuvj444p", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ }, }, [PIX_FMT_UYVY422] = { .name = "uyvy422", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 0, .comp = { {0,1,2,0,7}, /* Y */ {0,3,1,0,7}, /* U */ {0,3,3,0,7}, /* V */ }, }, [PIX_FMT_UYYVYY411] = { .name = "uyyvyy411", .nb_channels = 3, .log2_chroma_w= 2, .log2_chroma_h= 0, .comp = { {0,3,2,0,7}, /* Y */ {0,5,1,0,7}, /* U */ {0,5,4,0,7}, /* V */ }, }, [PIX_FMT_BGR8] = { .name = "bgr8", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,0,1,6,1}, /* B */ {0,0,1,3,2}, /* G */ {0,0,1,0,2}, /* R */ }, }, [PIX_FMT_BGR4] = { .name = "bgr4", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,3,1,0,0}, /* B */ {0,3,2,0,1}, /* G */ {0,3,4,0,0}, /* R */ }, .flags = PIX_FMT_BITSTREAM, }, [PIX_FMT_BGR4_BYTE] = { .name = "bgr4_byte", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,0,1,3,0}, /* B */ {0,0,1,1,1}, /* G */ {0,0,1,0,0}, /* R */ }, }, [PIX_FMT_RGB8] = { .name = "rgb8", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,0,1,6,1}, /* R */ {0,0,1,3,2}, /* G */ {0,0,1,0,2}, /* B */ }, }, [PIX_FMT_RGB4] = { .name = "rgb4", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,3,1,0,0}, /* R */ {0,3,2,0,1}, /* G */ {0,3,4,0,0}, /* B */ }, .flags = PIX_FMT_BITSTREAM, }, [PIX_FMT_RGB4_BYTE] = { .name = "rgb4_byte", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,0,1,3,0}, /* R */ {0,0,1,1,1}, /* G */ {0,0,1,0,0}, /* B */ }, }, [PIX_FMT_NV12] = { .name = "nv12", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 1, .comp = { {0,0,1,0,7}, /* Y */ {1,1,1,0,7}, /* U */ {1,1,2,0,7}, /* V */ }, }, [PIX_FMT_NV21] = { .name = "nv21", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 1, .comp = { {0,0,1,0,7}, /* Y */ {1,1,1,0,7}, /* V */ {1,1,2,0,7}, /* U */ }, }, [PIX_FMT_ARGB] = { .name = "argb", .nb_channels = 4, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,3,1,0,7}, /* A */ {0,3,2,0,7}, /* R */ {0,3,3,0,7}, /* G */ {0,3,4,0,7}, /* B */ }, }, [PIX_FMT_RGBA] = { .name = "rgba", .nb_channels = 4, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,3,1,0,7}, /* R */ {0,3,2,0,7}, /* G */ {0,3,3,0,7}, /* B */ {0,3,4,0,7}, /* A */ }, }, [PIX_FMT_ABGR] = { .name = "abgr", .nb_channels = 4, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,3,1,0,7}, /* A */ {0,3,2,0,7}, /* B */ {0,3,3,0,7}, /* G */ {0,3,4,0,7}, /* R */ }, }, [PIX_FMT_BGRA] = { .name = "bgra", .nb_channels = 4, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,3,1,0,7}, /* B */ {0,3,2,0,7}, /* G */ {0,3,3,0,7}, /* R */ {0,3,4,0,7}, /* A */ }, }, [PIX_FMT_GRAY16BE] = { .name = "gray16be", .nb_channels = 1, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,1,0,15}, /* Y */ }, .flags = PIX_FMT_BE, }, [PIX_FMT_GRAY16LE] = { .name = "gray16le", .nb_channels = 1, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,1,0,15}, /* Y */ }, }, [PIX_FMT_YUV440P] = { .name = "yuv440p", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 1, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ }, }, [PIX_FMT_YUVJ440P] = { .name = "yuvj440p", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 1, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ }, }, [PIX_FMT_YUVA420P] = { .name = "yuva420p", .nb_channels = 4, .log2_chroma_w= 1, .log2_chroma_h= 1, .comp = { {0,0,1,0,7}, /* Y */ {1,0,1,0,7}, /* U */ {2,0,1,0,7}, /* V */ {3,0,1,0,7}, /* A */ }, }, [PIX_FMT_RGB48BE] = { .name = "rgb48be", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,5,1,0,15}, /* R */ {0,5,3,0,15}, /* G */ {0,5,5,0,15}, /* B */ }, .flags = PIX_FMT_BE, }, [PIX_FMT_RGB48LE] = { .name = "rgb48le", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,5,1,0,15}, /* R */ {0,5,3,0,15}, /* G */ {0,5,5,0,15}, /* B */ }, }, [PIX_FMT_RGB565BE] = { .name = "rgb565be", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,0,3,4}, /* R */ {0,1,1,5,5}, /* G */ {0,1,1,0,4}, /* B */ }, .flags = PIX_FMT_BE, }, [PIX_FMT_RGB565LE] = { .name = "rgb565le", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,2,3,4}, /* R */ {0,1,1,5,5}, /* G */ {0,1,1,0,4}, /* B */ }, }, [PIX_FMT_RGB555BE] = { .name = "rgb555be", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,0,2,4}, /* R */ {0,1,1,5,4}, /* G */ {0,1,1,0,4}, /* B */ }, .flags = PIX_FMT_BE, }, [PIX_FMT_RGB555LE] = { .name = "rgb555le", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,2,2,4}, /* R */ {0,1,1,5,4}, /* G */ {0,1,1,0,4}, /* B */ }, }, [PIX_FMT_BGR565BE] = { .name = "bgr565be", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,0,3,4}, /* B */ {0,1,1,5,5}, /* G */ {0,1,1,0,4}, /* R */ }, .flags = PIX_FMT_BE, }, [PIX_FMT_BGR565LE] = { .name = "bgr565le", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,2,3,4}, /* B */ {0,1,1,5,5}, /* G */ {0,1,1,0,4}, /* R */ }, }, [PIX_FMT_BGR555BE] = { .name = "bgr555be", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,0,2,4}, /* B */ {0,1,1,5,4}, /* G */ {0,1,1,0,4}, /* R */ }, .flags = PIX_FMT_BE, }, [PIX_FMT_BGR555LE] = { .name = "bgr555le", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,2,2,4}, /* B */ {0,1,1,5,4}, /* G */ {0,1,1,0,4}, /* R */ }, }, [PIX_FMT_YUV420PLE] = { .name = "yuv420ple", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 1, .comp = { {0,1,1,0,15}, /* Y */ {1,1,1,0,15}, /* U */ {2,1,1,0,15}, /* V */ }, }, [PIX_FMT_YUV420PBE] = { .name = "yuv420pbe", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 1, .comp = { {0,1,1,0,15}, /* Y */ {1,1,1,0,15}, /* U */ {2,1,1,0,15}, /* V */ }, .flags = PIX_FMT_BE, }, [PIX_FMT_YUV422PLE] = { .name = "yuv422ple", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 0, .comp = { {0,1,1,0,15}, /* Y */ {1,1,1,0,15}, /* U */ {2,1,1,0,15}, /* V */ }, }, [PIX_FMT_YUV422PBE] = { .name = "yuv422pbe", .nb_channels = 3, .log2_chroma_w= 1, .log2_chroma_h= 0, .comp = { {0,1,1,0,15}, /* Y */ {1,1,1,0,15}, /* U */ {2,1,1,0,15}, /* V */ }, .flags = PIX_FMT_BE, }, [PIX_FMT_YUV444PLE] = { .name = "yuv444ple", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,1,0,15}, /* Y */ {1,1,1,0,15}, /* U */ {2,1,1,0,15}, /* V */ }, }, [PIX_FMT_YUV444PBE] = { .name = "yuv444pbe", .nb_channels = 3, .log2_chroma_w= 0, .log2_chroma_h= 0, .comp = { {0,1,1,0,15}, /* Y */ {1,1,1,0,15}, /* U */ {2,1,1,0,15}, /* V */ }, .flags = PIX_FMT_BE, }, }; EOF # ==================================================================================================== # test 5 my $struct_details5 = <<EOF; typedef struct BlockNode{ int16_t mx; int16_t my; uint8_t ref; uint8_t color[3]; uint8_t type; /* //#define TYPE_SPLIT 1 #define BLOCK_INTRA 1 #define BLOCK_OPT 2 //#define TYPE_NOCOLOR 4 */ uint8_t level; //FIXME merge into type? }BlockNode; EOF my $gcc_struct5 = <<EOF; static const BlockNode null_block= { //FIXME add border maybe .color= {128,128,128}, .mx= 0, .my= 0, .ref= 0, .type= 0, .level= 0, }; EOF # ==================================================================================================== # test 6 my $struct_details6 = <<EOF; /** * AVHWAccel. */ typedef struct AVHWAccel { /** * Name of the hardware accelerated codec. * The name is globally unique among encoders and among decoders (but an * encoder and a decoder can share the same name). */ const char *name; /** * Type of codec implemented by the hardware accelerator. * * See CODEC_TYPE_xxx */ enum CodecType type; /** * Codec implemented by the hardware accelerator. * * See CODEC_ID_xxx */ enum CodecID id; /** * Supported pixel format. * * Only hardware accelerated formats are supported here. */ enum PixelFormat pix_fmt; /** * Hardware accelerated codec capabilities. * see FF_HWACCEL_CODEC_CAP_* */ int capabilities; struct AVHWAccel *next; /** * Called at the beginning of each frame or field picture. * * Meaningful frame information (codec specific) is guaranteed to * be parsed at this point. This function is mandatory. * * Note that buf can be NULL along with buf_size set to 0. * Otherwise, this means the whole frame is available at this point. * * \@param avctx the codec context * \@param buf the frame data buffer base * \@param buf_size the size of the frame in bytes * \@return zero if successful, a negative value otherwise */ int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); /** * Callback for each slice. * * Meaningful slice information (codec specific) is guaranteed to * be parsed at this point. This function is mandatory. * * \@param avctx the codec context * \@param buf the slice data buffer base * \@param buf_size the size of the slice in bytes * \@return zero if successful, a negative value otherwise */ int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); /** * Called at the end of each frame or field picture. * * The whole picture is parsed at this point and can now be sent * to the hardware accelerator. This function is mandatory. * * \@param avctx the codec context * \@return zero if successful, a negative value otherwise */ int (*end_frame)(AVCodecContext *avctx); /** * Size of HW accelerator private data. * * Private data is allocated with av_mallocz() before * AVCodecContext.get_buffer() and deallocated after * AVCodecContext.release_buffer(). */ int priv_data_size; } AVHWAccel; EOF my $gcc_struct6_1 = <<EOF; AVHWAccel mpeg2_vaapi_hwaccel = { .name = "mpeg2_vaapi", .type = CODEC_TYPE_VIDEO, .id = CODEC_ID_MPEG2VIDEO, .pix_fmt = PIX_FMT_VAAPI_VLD, .capabilities = 0, .start_frame = vaapi_mpeg2_start_frame, .end_frame = vaapi_mpeg2_end_frame, .decode_slice = vaapi_mpeg2_decode_slice, .priv_data_size = 0, }; EOF #if CONFIG_MPEG4_VAAPI_HWACCEL my $gcc_struct6_2 = <<EOF; AVHWAccel mpeg4_vaapi_hwaccel = { .name = "mpeg4_vaapi", .type = CODEC_TYPE_VIDEO, .id = CODEC_ID_MPEG4, .pix_fmt = PIX_FMT_VAAPI_VLD, .capabilities = 0, .start_frame = vaapi_mpeg4_start_frame, .end_frame = vaapi_mpeg4_end_frame, .decode_slice = vaapi_mpeg4_decode_slice, .priv_data_size = 0, }; EOF #if CONFIG_H263_VAAPI_HWACCEL my $gcc_struct6_3 = <<EOF; AVHWAccel h263_vaapi_hwaccel = { .name = "h263_vaapi", .type = CODEC_TYPE_VIDEO, .id = CODEC_ID_H263, .pix_fmt = PIX_FMT_VAAPI_VLD, .capabilities = 0, .start_frame = vaapi_mpeg4_start_frame, .end_frame = vaapi_mpeg4_end_frame, .decode_slice = vaapi_mpeg4_decode_slice, .priv_data_size = 0, }; EOF #if CONFIG_WMV3_VAAPI_HWACCEL my $gcc_struct6_4 = <<EOF; AVHWAccel wmv3_vaapi_hwaccel = { .name = "wmv3_vaapi", .type = CODEC_TYPE_VIDEO, .id = CODEC_ID_WMV3, .pix_fmt = PIX_FMT_VAAPI_VLD, .capabilities = 0, .start_frame = vaapi_vc1_start_frame, .end_frame = vaapi_vc1_end_frame, .decode_slice = vaapi_vc1_decode_slice, .priv_data_size = 0, }; EOF my $gcc_struct6 = <<EOF; AVHWAccel vc1_vaapi_hwaccel = { .name = "vc1_vaapi", .type = CODEC_TYPE_VIDEO, .id = CODEC_ID_VC1, .pix_fmt = PIX_FMT_VAAPI_VLD, .capabilities = 0, .start_frame = vaapi_vc1_start_frame, .end_frame = vaapi_vc1_end_frame, .decode_slice = vaapi_vc1_decode_slice, .priv_data_size = 0, }; EOF # ==================================================================================================== # test 7 my $struct_detailst_53 = <<EOF; typedef struct AVInputFormat { const char *name; const char *long_name; int priv_data_size; int (*read_probe)(AVProbeData *); int (*read_header)(struct AVFormatContext *,AVFormatParameters *ap); int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); int (*read_close)(struct AVFormatContext *); #if LIBAVFORMAT_VERSION_MAJOR < 53 int (*read_seek)(struct AVFormatContext *, int stream_index, int64_t timestamp, int flags); int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, int64_t *pos, int64_t pos_limit); int flags; const char *extensions; int value; int (*read_play)(struct AVFormatContext *); int (*read_pause)(struct AVFormatContext *); const struct AVCodecTag * const *codec_tag; int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); const AVMetadataConv *metadata_conv; struct AVInputFormat *next; } AVInputFormat; EOF my $struct_instance_blank_53 = <<EOF; AVInputFormat sinput_form_blank = { NULL, // const char *name; NULL, // const char *long_name; 0, // int priv_data_size; NULL, // int (*read_probe)(AVProbeData *); NULL, // int (*read_header)(struct AVFormatContext *,AVFormatParameters *ap); NULL, // int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); NULL, // int (*read_close)(struct AVFormatContext *); // #if LIBAVFORMAT_VERSION_MAJOR < 53 NULL, // int (*read_seek)(struct AVFormatContext *, int stream_index, int64_t timestamp, int flags); NULL, // int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, int64_t *pos, int64_t pos_limit); 0, // int flags; NULL, // const char *extensions; 0, // int value; NULL, // int (*read_play)(struct AVFormatContext *); NULL, // int (*read_pause)(struct AVFormatContext *); NULL, // const struct AVCodecTag * const *codec_tag; NULL, // int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); NULL, // const AVMetadataConv *metadata_conv; NULL // struct AVInputFormat *next; }; AVInputFormat aiff_demuxer = { "aiff", /* const char * name */ NULL_IF_CONFIG_SMALL("Audio IFF"), /* const char * long_name */ 0, /* int priv_data_size */ aiff_probe, /* int (*read_probe)(AVProbeData *) */ aiff_read_header, /* int (*read_header)(struct AVFormatContext *, AVFormatParameters *ap) */ aiff_read_packet, /* int (*read_packet)(struct AVFormatContext *, AVPacket *pkt) */ NULL, /* int (*read_close)(struct AVFormatContext *) */ pcm_read_seek, /* int flags */ NULL, /* const char * extensions */ 0, /* int value */ NULL, /* int (*read_play)(struct AVFormatContext *) */ NULL, /* int (*read_pause)(struct AVFormatContext *) */ (const AVCodecTag* const []){codec_aiff_tags, 0}, /* const struct AVCodecTag * const * codec_tag */ NULL, /* int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags) */ NULL, /* const AVMetadataConv * metadata_conv */ NULL /* struct AVInputFormat * next */ }; EOF my $struct_details7 = <<EOF; typedef struct AVInputFormat { const char *name; /** * Descriptive name for the format, meant to be more human-readable * than name. You should use the NULL_IF_CONFIG_SMALL() macro * to define it. */ const char *long_name; /** Size of private data so that it can be allocated in the wrapper. */ int priv_data_size; /** * Tell if a given file has a chance of being parsed as this format. * The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes * big so you do not have to check for that unless you need more. */ int (*read_probe)(AVProbeData *); /** Read the format header and initialize the AVFormatContext structure. Return 0 if OK. 'ap' if non-NULL contains additional parameters. Only used in raw format right now. 'av_new_stream' should be called to create new streams. */ int (*read_header)(struct AVFormatContext *, AVFormatParameters *ap); /** Read one packet and put it in 'pkt'. pts and flags are also set. 'av_new_stream' can be called only if the flag AVFMTCTX_NOHEADER is used. \@return 0 on success, < 0 on error. When returning an error, pkt must not have been allocated or must be freed before returning */ int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); /** Close the stream. The AVFormatContext and AVStreams are not freed by this function */ int (*read_close)(struct AVFormatContext *); //#if LIBAVFORMAT_VERSION_MAJOR < 53 - pesently compiling 52! /** * Seek to a given timestamp relative to the frames in * stream component stream_index. * \@param stream_index Must not be -1. * \@param flags Selects which direction should be preferred if no exact * match is available. * \@return >= 0 on success (but not necessarily the new offset) */ int (*read_seek)(struct AVFormatContext *, int stream_index, int64_t timestamp, int flags); //#endif /** * Gets the next timestamp in stream[stream_index].time_base units. * \@return the timestamp or AV_NOPTS_VALUE if an error occurred */ int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, int64_t *pos, int64_t pos_limit); /** Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER. */ int flags; /** If extensions are defined, then no probe is done. You should usually not use extension format guessing because it is not reliable enough */ const char *extensions; /** General purpose read-only value that the format can use. */ int value; /** Starts/resumes playing - only meaningful if using a network-based format (RTSP). */ int (*read_play)(struct AVFormatContext *); /** Pauses playing - only meaningful if using a network-based format (RTSP). */ int (*read_pause)(struct AVFormatContext *); const struct AVCodecTag * const *codec_tag; /** * Seeks to timestamp ts. * Seeking will be done so that the point from which all active streams * can be presented successfully will be closest to ts and within min/max_ts. * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. */ int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); const AVMetadataConv *metadata_conv; /* private fields */ struct AVInputFormat *next; } AVInputFormat; EOF my $gcc_struct7_1 = <<EOF; AVInputFormat aiff_demuxer = { "aiff", NULL_IF_CONFIG_SMALL("Audio IFF"), 0, aiff_probe, aiff_read_header, aiff_read_packet, NULL, pcm_read_seek, .codec_tag= (const AVCodecTag* const []){codec_aiff_tags, 0}, }; EOF my $gcc_struct7_2 = <<EOF; AVInputFormat ape_demuxer = { "ape", NULL_IF_CONFIG_SMALL("Monkey's Audio"), sizeof(APEContext), ape_probe, ape_read_header, ape_read_packet, ape_read_close, ape_read_seek, .extensions = "ape,apl,mac" }; EOF my $gcc_struct7_3 = <<EOF; AVInputFormat asf_demuxer = { "asf", NULL_IF_CONFIG_SMALL("ASF format"), sizeof(ASFContext), asf_probe, asf_read_header, asf_read_packet, asf_read_close, asf_read_seek, asf_read_pts, .metadata_conv = ff_asf_metadata_conv, }; EOF my $gcc_struct7 = <<EOF; AVInputFormat daud_demuxer = { "daud", NULL_IF_CONFIG_SMALL("D-Cinema audio format"), 0, NULL, daud_header, daud_packet, NULL, NULL, .extensions = "302", }; EOF # ==================================================================================================== # test 8 my $struct_details8 = <<EOF; typedef struct AVOutputFormat { const char *name; /** * Descriptive name for the format, meant to be more human-readable * than name. You should use the NULL_IF_CONFIG_SMALL() macro * to define it. */ const char *long_name; const char *mime_type; const char *extensions; /**< comma-separated filename extensions */ /** size of private data so that it can be allocated in the wrapper */ int priv_data_size; /* output support */ enum CodecID audio_codec; /**< default audio codec */ enum CodecID video_codec; /**< default video codec */ int (*write_header)(struct AVFormatContext *); int (*write_packet)(struct AVFormatContext *, AVPacket *pkt); int (*write_trailer)(struct AVFormatContext *); /** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER */ int flags; /** Currently only used to set pixel format if not YUV420P. */ int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *); int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, AVPacket *in, int flush); /** * List of supported codec_id-codec_tag pairs, ordered by "better * choice first". The arrays are all terminated by CODEC_ID_NONE. */ const struct AVCodecTag * const *codec_tag; enum CodecID subtitle_codec; /**< default subtitle codec */ const AVMetadataConv *metadata_conv; /* private fields */ struct AVOutputFormat *next; } AVOutputFormat; EOF my $gcc_struct8_1 = <<EOF; AVOutputFormat aiff_muxer = { "aiff", NULL_IF_CONFIG_SMALL("Audio IFF"), "audio/aiff", "aif,aiff,afc,aifc", sizeof(AIFFOutputContext), CODEC_ID_PCM_S16BE, CODEC_ID_NONE, aiff_write_header, aiff_write_packet, aiff_write_trailer, .codec_tag= (const AVCodecTag* const []){codec_aiff_tags, 0}, }; EOF my $gcc_struct8_2 = <<EOF; AVOutputFormat daud_muxer = { "daud", NULL_IF_CONFIG_SMALL("D-Cinema audio format"), NULL, "302", 0, CODEC_ID_PCM_S24DAUD, CODEC_ID_NONE, daud_write_header, daud_write_packet, .flags= AVFMT_NOTIMESTAMPS, }; EOF my $gcc_struct8_w_comm = <<EOF; // #if CONFIG_ASF_MUXER AVOutputFormat asf_muxer = { "asf", NULL_IF_CONFIG_SMALL("ASF format"), "video/x-ms-asf", "asf,wmv,wma", sizeof(ASFContext), // #if CONFIG_LIBMP3LAME CODEC_ID_MP3, // #else // CODEC_ID_MP2, // #endif CODEC_ID_MSMPEG4V3, asf_write_header, asf_write_packet, asf_write_trailer, .flags = AVFMT_GLOBALHEADER, .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0}, .metadata_conv = ff_asf_metadata_conv, }; // #endif EOF my $gcc_struct8_3 = <<EOF; AVOutputFormat asf_muxer = { "asf", NULL_IF_CONFIG_SMALL("ASF format"), "video/x-ms-asf", "asf,wmv,wma", sizeof(ASFContext), CODEC_ID_MP3, CODEC_ID_MSMPEG4V3, asf_write_header, asf_write_packet, asf_write_trailer, .flags = AVFMT_GLOBALHEADER, .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0}, .metadata_conv = ff_asf_metadata_conv, }; EOF my $gcc_struct8_wcomm = <<EOF; AVOutputFormat asf_stream_muxer = { "asf_stream", NULL_IF_CONFIG_SMALL("ASF format"), "video/x-ms-asf", "asf,wmv,wma", sizeof(ASFContext), #if CONFIG_LIBMP3LAME CODEC_ID_MP3, #else CODEC_ID_MP2, #endif CODEC_ID_MSMPEG4V3, asf_write_stream_header, asf_write_packet, asf_write_trailer, .flags = AVFMT_GLOBALHEADER, .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0}, .metadata_conv = ff_asf_metadata_conv, }; EOF my $gcc_struct8 = <<EOF; AVOutputFormat asf_stream_muxer = { "asf_stream", NULL_IF_CONFIG_SMALL("ASF format"), "video/x-ms-asf", "asf,wmv,wma", sizeof(ASFContext), CODEC_ID_MP3, CODEC_ID_MSMPEG4V3, asf_write_stream_header, asf_write_packet, asf_write_trailer, .flags = AVFMT_GLOBALHEADER, .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0}, .metadata_conv = ff_asf_metadata_conv, }; EOF # ==================================================================================================== # test 9 my $struct_details9 = <<EOF; struct RTPDynamicProtocolHandler { // fields from AVRtpDynamicPayloadType_s const char enc_name[50]; /* XXX: still why 50 ? ;-) */ enum CodecType codec_type; enum CodecID codec_id; // may be null int (*parse_sdp_a_line) (AVFormatContext *s, int st_index, PayloadContext *priv_data, const char *line); ///< Parse the a= line from the sdp field PayloadContext *(*open) (); ///< allocate any data needed by the rtp parsing for this dynamic data. void (*close)(PayloadContext *protocol_data); ///< free any data needed by the rtp parsing for this dynamic data. DynamicPayloadPacketHandlerProc parse_packet; ///< parse handler for this dynamic packet. struct RTPDynamicProtocolHandler_s *next; }; EOF my $gcc_struct9_1 = <<EOF; RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = { .enc_name = "vorbis", .codec_type = CODEC_TYPE_AUDIO, .codec_id = CODEC_ID_VORBIS, .parse_sdp_a_line = NULL, .open = vorbis_new_context, .close = vorbis_free_context, .parse_packet = vorbis_handle_packet }; EOF # RTP_ASF_HANDLER(asf_pfv, "x-asf-pf", CODEC_TYPE_VIDEO); my $gcc_struct9 = <<EOF; RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler = { .enc_name = "x-asf-pf", .codec_type = CODEC_TYPE_VIDEO, .codec_id = CODEC_ID_NONE, .parse_sdp_a_line = asfrtp_parse_sdp_line, .open = asfrtp_new_context, .close = asfrtp_free_context, .parse_packet = asfrtp_parse_packet, }; EOF # ==================================================================================================== # test 10 my $struct_details10 = <<EOF; typedef struct URLProtocol { const char *name; int (*url_open)(URLContext *h, const char *filename, int flags); int (*url_read)(URLContext *h, unsigned char *buf, int size); int (*url_write)(URLContext *h, unsigned char *buf, int size); int64_t (*url_seek)(URLContext *h, int64_t pos, int whence); int (*url_close)(URLContext *h); struct URLProtocol *next; int (*url_read_pause)(URLContext *h, int pause); int64_t (*url_read_seek)(URLContext *h, int stream_index, int64_t timestamp, int flags); int (*url_get_file_handle)(URLContext *h); } URLProtocol; EOF my $gcc_struct10 = <<EOF; URLProtocol tcp_protocol = { "tcp", tcp_open, tcp_read, tcp_write, NULL, /* seek */ tcp_close, .url_get_file_handle = tcp_get_file_handle, }; EOF # ==================================================================================================== # test 11 my $struct_details11 = <<EOF; typedef struct { uint32_t type; int64_t offset; int64_t size; /* total size (excluding the size and type fields) */ } MOVAtom; EOF my $gcc_struct11 = <<EOF; MOVAtom fake_atom = { .size = size - (url_ftell(pb) - start_pos) }; EOF # ==================================================================================================== # test 12 my $struct_details12 = <<EOF; /// muxer options struct typedef struct { nut_output_stream_tt output; ///< output stream function pointers nut_alloc_tt alloc; ///< memory allocation function pointers int write_index; ///< whether or not to write an index int realtime_stream; ///< Implies no write_index. int max_distance; ///< Valid values are 32-65536, the recommended value is 32768. Lower values give better seekability and error detection and recovery but cause higher overhead. nut_frame_table_input_tt * fti; ///< Framecode table, may be NULL. } nut_muxer_opts_tt; EOF my $gcc_struct12 = <<EOF; nut_muxer_opts_tt mopts = { .output = { .priv = bc, .write = av_write, }, .alloc = { av_malloc, av_realloc, av_free }, .write_index = 1, .realtime_stream = 0, .max_distance = 32768, .fti = NULL, }; EOF # ==================================================================================================== # test 13 my $struct_details13 = <<EOF; /// demuxer options struct typedef struct { nut_input_stream_tt input; ///< input stream function pointers nut_alloc_tt alloc; ///< memory allocation function pointers int read_index; ///< Seeks to end-of-file at beginning of playback to search for index. Implies cache_syncpoints. int cache_syncpoints; ///< Improves seekability and error recovery greatly, but costs some memory (0.5MB for very large files). void * info_priv; ///< opaque priv pointer to be passed to #new_info void (*new_info)(void * priv, nut_info_packet_tt * info); ///< Function to be called when info is found mid-stream. May be NULL. } nut_demuxer_opts_tt; EOF my $gcc_struct13 = <<EOF; nut_demuxer_opts_tt dopts = { .input = { .priv = bc, .seek = av_seek, .read = av_read, .eof = NULL, .file_pos = 0, }, .alloc = { av_malloc, av_realloc, av_free }, .read_index = 1, .cache_syncpoints = 1, }; EOF # ==================================================================================================== # test 14 my $struct_details14 = <<EOF; /// input stream struct typedef struct { void * priv; ///< opaque priv pointer to be passed to function calls size_t (*read)(void * priv, size_t len, uint8_t * buf); ///< Input stream read function, must return amount of bytes actually read. off_t (*seek)(void * priv, long long pos, int whence); ///< Input stream seek function, must return position in file after seek. int (*eof)(void * priv); ///< Returns if EOF has been met in stream in case of read error. off_t file_pos; ///< file position at beginning of read } nut_input_stream_tt; EOF my $gcc_struct14 = <<EOF; nut_input_stream_tt input = { .priv = bc, .seek = av_seek, .read = av_read, .eof = NULL, .file_pos = 0, }; EOF # ==================================================================================================== # test 15 my $struct_details15 = <<EOF; typedef struct { uint64_t pos; uint64_t back_ptr; // uint64_t global_key_pts; int64_t ts; } Syncpoint; EOF my $gcc_struct15_1 = <<EOF; Syncpoint dummy={.ts= pts*av_q2d(st->time_base)*AV_TIME_BASE}; EOF my $gcc_struct15 = <<EOF; Syncpoint nopts_sp= {.ts= AV_NOPTS_VALUE, .back_ptr= AV_NOPTS_VALUE}; EOF # ==================================================================================================== # test 16 my $struct_details16 = <<EOF; struct ogg_codec { const int8_t *magic; uint8_t magicsize; const int8_t *name; /** * Attempt to process a packet as a header * \@return 1 if the packet was a valid header, * 0 if the packet was not a header (was a data packet) * -1 if an error occurred or for unsupported stream */ int (*header)(AVFormatContext *, int); int (*packet)(AVFormatContext *, int); uint64_t (*gptopts)(AVFormatContext *, int, uint64_t); }; EOF my $gcc_struct16 = <<EOF; const struct ogg_codec ff_flac_codec = { .magic = "\177FLAC", .magicsize = 5, .header = flac_header }; EOF # ==================================================================================================== # test 17 my $struct_details17 = <<EOF; typedef struct FFPsyModel { const char *name; int (*init) (FFPsyContext *apc); FFPsyWindowInfo (*window)(FFPsyContext *ctx, const int16_t *audio, const int16_t *la, int channel, int prev_type); void (*analyze)(FFPsyContext *ctx, int channel, const float *coeffs, FFPsyWindowInfo *wi); void (*end) (FFPsyContext *apc); } FFPsyModel; EOF my $gcc_struct17 = <<EOF; const FFPsyModel ff_aac_psy_model = { .name = "3GPP TS 26.403-inspired model", .init = psy_3gpp_init, .window = psy_3gpp_window, .analyze = psy_3gpp_analyze, .end = psy_3gpp_end, }; EOF my $test_max = 17; #============ *TBD* # ==================================================================================================== # test ______ # /* Log level */ # #define X264_LOG_NONE (-1) # #define X264_LOG_ERROR 0 # #define X264_LOG_WARNING 1 # #define X264_LOG_INFO 2 # #define X264_LOG_DEBUG 3 # NEED TO SETUP AN ENUMERATION!!! my $gcc_struct_anon1 = <<EOF; static const int level_map[] = { [X264_LOG_ERROR] = AV_LOG_ERROR, [X264_LOG_WARNING] = AV_LOG_WARNING, [X264_LOG_INFO] = AV_LOG_INFO, [X264_LOG_DEBUG] = AV_LOG_DEBUG }; EOF # see convstranon.pl for this #define ID3v1_GENRE_MAX 125 my $ID3v1_GENRE_MAX = 125; my $gcc_struct_anon2 = <<EOF; const char *ff_id3v1_genre_str[$ID3v1_GENRE_MAX + 1] = { [0] = "Blues", [1] = "Classic Rock", [2] = "Country", ... [124] = "Euro-House", [125] = "Dance Hall", }; EOF # default test my $enum_details = $enum_pixfmt; my $struct_details = $struct_details1; my $gcc_struct = $gcc_struct1; sub set_test_strings($) { my ($tst) = shift; my $test = ''; if ($tst == 1) { # test 1 $enum_details = $enum_pixfmt; $struct_details = $struct_details1; $gcc_struct = $gcc_struct1; $test = $struct_details1; } elsif ($tst == 2) { # test 2 $enum_details = ''; $struct_details = $struct_details2; $gcc_struct = $gcc_struct2; $test = $struct_details2; } elsif ($tst == 3) { # test 3 $enum_details = ''; $struct_details = $struct_details3; $gcc_struct = $gcc_struct3; $test = $struct_details3; } elsif ($tst == 4) { # test 4 $enum_details = $enum_pixfmt;; $struct_details = $struct_details4; $gcc_struct = $gcc_struct4; $test = $struct_details4; } elsif ($tst == 5) { # test 5 $enum_details = ''; $struct_details = $struct_details5; $gcc_struct = $gcc_struct5; $test = $struct_details5; } elsif ($tst == 6) { # test 6 $enum_details = ''; $struct_details = $struct_details6; $gcc_struct = $gcc_struct6; $test = $struct_details6; } elsif ($tst == 7) { # test 7 $enum_details = ''; $struct_details = $struct_details7; $gcc_struct = $gcc_struct7; $test = $struct_details7; } elsif ($tst == 8) { # test 8 $enum_details = ''; $struct_details = $struct_details8; $gcc_struct = $gcc_struct8; $test = $struct_details8; } elsif ($tst == 9) { # test 9 $enum_details = ''; $struct_details = $struct_details9; $gcc_struct = $gcc_struct9; $test = $struct_details9; } elsif ($tst == 10) { # test 10 $enum_details = ''; $struct_details = $struct_details10; $gcc_struct = $gcc_struct10; $test = $struct_details10; } elsif ($tst == 11) { # test 11 $enum_details = ''; $struct_details = $struct_details11; $gcc_struct = $gcc_struct11; $test = $struct_details11; } elsif ($tst == 12) { # test 12 $enum_details = ''; $struct_details = $struct_details12; $gcc_struct = $gcc_struct12; $test = $struct_details12; } elsif ($tst == 13) { # test 13 $enum_details = ''; $struct_details = $struct_details13; $gcc_struct = $gcc_struct13; $test = $struct_details13; } elsif ($tst == 14) { # test 14 $enum_details = ''; $struct_details = $struct_details14; $gcc_struct = $gcc_struct14; $test = $struct_details14; } elsif ($tst == 15) { # test 15 $enum_details = ''; $struct_details = $struct_details15; $gcc_struct = $gcc_struct15; $test = $struct_details15; } elsif ($tst == 16) { # test 16 $enum_details = ''; $struct_details = $struct_details16; $gcc_struct = $gcc_struct16; $test = $struct_details16; } elsif ($tst == 17) { # test 17 $enum_details = ''; $struct_details = $struct_details17; $gcc_struct = $gcc_struct17; $test = $struct_details17; } elsif ($tst == $twinvq_spl) { # SPECIAL twinvq files if (( -f $twinvq_str ) && ( -f $twinvq_inst )) { if (open INF, "<$twinvq_str") { my @tvq_lns1 = <INF>; close INF; if (open INF2, "<$twinvq_inst") { my @tvq_lns2 = <INF2>; close INF2; $enum_details = ''; $struct_details = join("\n",@tvq_lns1)."\n"; $gcc_struct = join("\n",@tvq_lns2)."\n"; $test = $gcc_struct; } else { my_exit(1, "ERROR: twinvq: Unable to open [$twinvq_inst] file!\n" ); } } else { my_exit(1, "ERROR: twinvq: Unable to open [$twinvq_str] file!\n" ); } } else { my_exit(1, "ERROR: twinvq: Unable to find [$twinvq_str] or [$twinvq_inst] files!\n" ); } } else { my_exit(1, "ERROR: invalid do_test_num value = [$tst]!\n" ); } return $test; } # this is really only for DEBUG sub show_struct_hash($$) { # like (\%h); my ($dbg,$rh) = @_; my ($cnt, $key, $val, $msg, $mt, $typ, $len, $equ, $name, $mcnt, $fnm, $bit); $cnt = scalar keys(%$rh); if ($dbg & 2) { my $mind = $memb_indent; $msg = "// Output of structure "; $key = $str_nam; # 'NAME' my $strname = "UNKNOWN"; if (defined $$rh{$key}) { $val = $$rh{$key}; $val =~ s/;$//; $strname = $val; } $msg .= "$strname\n"; # first line $key = $str_tag; # 'TAG' if (defined $$rh{$key}) { $val = $$rh{$key}; $msg .= "$val {\n"; } # add members foreach $key (sort keys %$rh) { $val = $$rh{$key}; if ($key =~ /^$mem_bgn/) { # = member $val = $$rh{$key}; $typ = $$val[$O_TYP]; $name = $$val[$O_NAM]; $bit = $$val[$O_BIT]; $msg .= $mind; $msg .= "$typ "; $msg .= $name; $msg .= " : $bit" if ($bit != -1); $msg .= ";\n"; } } # and name at end $msg .= "} $strname ;\n"; return $msg; } prt( "=== Showing structure HASH... $cnt keys... flag = $dbg\n" ); $cnt = 0; $mt = 1; my %done = (); # keep DONE keys $mcnt = 0; foreach $key (keys %$rh) { if ($key =~ /^$mem_bgn/) { # = member $val = $$rh{$key}; $typ = $$val[$O_TYP]; # [0]; $name = $$val[$O_NAM]; # [1]; $equ = $$val[$O_VAL]; # [2]; $len = length($typ); $mt = $len if ($len > $mt); $mcnt++; } } $mt += 8; $key = $str_tag; # 'TAG' $done{$key} = 1; if (defined $$rh{$key}) { $val = $$rh{$key}; $cnt++; $msg = sprintf("%2d: ", $cnt); $msg .= "$val {"; prt("$msg\n"); } # member keys only - sorted, thus in ORDER # ADD what it equals, if ($dbg & 1) foreach $key (sort keys %$rh) { $val = $$rh{$key}; if ($key =~ /^$mem_bgn/) { # = member $done{$key} = 1; $cnt++; $msg = sprintf("%2d: ", $cnt); $msg .= "$key "; $typ = " type=[".$$val[$O_TYP]."]"; $typ .= ' ' while (length($typ) < $mt); $msg .= $typ; $msg .= " name=[".$$val[$O_NAM]."]"; $fnm = $$val[$O_FNM]; $msg .= "[$fnm]" if (length($fnm)); $bit = $$val[$O_BIT]; $msg .= ":$bit" if ($bit != -1); $equ = $$val[$O_VAL]; $msg .= ", equ[$equ]" if ($dbg & 1); prt( "$msg\n" ); } } $key = $str_nam; # 'NAME' $done{$key} = 1; if (defined $$rh{$key}) { $val = $$rh{$key}; $cnt++; $msg = sprintf("%2d: ", $cnt); $msg .= "} $val"; prt("$msg\n"); } foreach $key (sort keys %$rh) { if ( !(defined $done{$key}) ) { $val = $$rh{$key}; $done{$key} = 1; $cnt++; $msg = sprintf("%2d: ", $cnt); if ($key eq 'ENUMERATION') { # NOTE: This enumeration no longer kept in this block instance hash # enumerations are now kept in the MASTER hash my ($k2,$v2,$c2); $c2 = scalar keys(%{$val}); $msg .= "$key => Enumeration HASH - $c2 items"; if ($dbg17) { $msg .= "\n"; $c2 = 0; foreach $k2 (keys %{$val}) { $v2 = ${$val}{$k2}; $c2++; $msg .= " $c2: $k2 = $v2\n"; } $msg .= " End $c2 enumerations"; } } else { $msg .= "$key => $val"; } prt("$msg\n"); } } prt( "=== Done show of structure HASH... $cnt keys... flag = $dbg\n" ); $msg = ''; return $msg; } sub split_alphanum($) { my ($t) = shift; my ($mx,$i,$c,$tg); my @a = (); $mx = length($t); $tg = ''; # no length, yet for ($i = 0; $i < $mx; $i++) { $c = substr($t,$i,1); # get next char... if ($c =~ /\s/) { # if it is SPACEY push(@a,$tg) if length($tg); # stack tag, if length $tg = ''; # and clear } elsif ($c =~ /\w/) { if ( length($tg) && !($tg =~ /^\w+$/) ) { push(@a,$tg); # stack tag, if length and NOT alphanum $tg = ''; # 20090926 - clear tag } $tg .= $c; # add to tag } else { # not spacey, nor alphanumeric push(@a,$tg) if length($tg); # stack tag, if length $tg = $c; # and set this char } } push(@a,$tg) if length($tg); return @a; } sub get_potential_struct_name($) { my ($tx) = shift; my (@arr, $tg); @arr = split_alphanum($tx); foreach $tg (@arr) { if ($tg =~ /^\w+$/) { ### prt( "Seems alphanumeric [$tg]\n" ); if (!word_in_res_words($tg)) { prt( "[dbg31] Returning potential name [$tg], from [$tx]\n" ) if ($dbg31); return $tg; } } ### else { ### prt( "Seems punctuation [$tg]\n" ); ### } } return ""; } sub deal_with_member($$$$) { my ($lnn, $line, $rnxt, $rh) = @_; my (@arr, $ac, $typ, $bs, $j, $sec, $akey, $msg, $fnm, $pw, $bit); my $nxt_member = $$rnxt; # get the NEXT member value - starts 0 @arr = split(/\s/,$line); $ac = scalar @arr; $typ = $arr[0]; prt("[dbg00] $lnn:deal_with_member: [$line], split=$ac, type=$typ, nxt_mem=$nxt_member\n" ) if ($dbg00); if ($ac < 2) { prtw( "$lnn: WARNING: Line [$line] did not give two elements...\n" ); } else { ## if ($ac >= 2) { $pw = $arr[-1]; if ($pw =~ /\w+\{$/) { $pw = substr($pw,0, length($pw) - 1); push(@arr,'{'); $ac = scalar @arr; prt("[dbg00] $lnn:deal_with_member: put space ater name and '{'!\n" ) if ($dbg00); } $bs = 1; if ( ($ac > 2) && word_in_res_words($typ) ) { prt("[dbg00] $lnn:deal_with_member: type=$typ is res word\n" ) if ($dbg00); $fnm = $typ; while ($bs < $ac) { $pw = $fnm; $fnm = $arr[$bs]; prt("[dbg00] $lnn:deal_with_member: type=$typ check next $fnm\n" ) if ($dbg00); while ( (($pw eq 'enum')||($pw eq 'struct')||($pw eq 'const')) && (($bs + 1) < $ac) ) { $typ .= " $fnm"; $bs++; $pw = $fnm; $fnm = $arr[$bs]; } if ( ( word_in_res_words($fnm) || ($fnm eq '*') ) && (($bs + 1) < $ac) ) { $typ .= " $fnm"; $bs++; if ( (($fnm eq 'enum')||($fnm eq 'struct')||($pw eq 'const')) && (($bs + 1) < $ac) ) { $fnm = $arr[$bs]; $typ .= " $fnm"; $bs++; } } else { last; } } #if (($typ eq 'enum')||($typ eq 'const')) { # $typ .= " $arr[1]"; # $bs++ #} } $sec = ''; for ($j = $bs; $j < $ac; $j++) { $sec .= ' ' if length($sec); $sec .= $arr[$j]; } if (substr($sec,0,1) eq '*') { $typ .= ' *'; $sec = substr($sec,1); } $sec =~ s/\s$// while ($sec =~ /\s$/); $sec =~ s/;$//; $sec =~ s/\s$// while ($sec =~ /\s$/); # 20090825 - try to deal with function pointer, like '(*foo)(int *, char * p, ...)' $fnm = ''; if ($sec =~ /^\(\s*\*\s*(\w+)\s*\)\s*\(.*\)/) { $fnm = $1; } # 20090829 - added to handle BITS, line 'name : 2' $bit = -1; if ( $sec =~ /^(\w+)\s+:\s+(\d+)$/ ) { $sec = $1; $bit = $2; prt("[dbg23] $lnn:deal_with_member: got BITS split name=[$sec], bits=[$bit]\n") if ($dbg23); } $sec = trim_ends($sec); # 20090901 - ensure no SPACE added $nxt_member++; $akey = sprintf("%s%04d",$mem_bgn,$nxt_member); # member and number # 0 1 2 3 4 5 6 # offsets $O_TYP $O_NAM $O_ORG $O_VAL $O_DEC $O_FNM $O_BIT prt("[dbg00] $lnn:deal_with_member: added [$akey] = typ=[$typ] nam=[$sec] fnm=[$fnm] bit=[$bit] into hash\n" ) if ($dbg00); $$rh{$akey} = [ $typ, $sec, $line, "", "", $fnm, $bit ]; $msg = sprintf("%3d: ",$lnn); $msg .= "$line // $nxt_member"; prt("[dbg01] $msg\n") if ($dbg01); $$rnxt = $nxt_member; } } sub is_struct_tag($) { my ($txt) = shift; if ($txt =~ /^\s*\w+\s*\{/m) { ###prt( "txt[$txt] is struct tag\n" ); ###exit(1); return 1; } return 0; } # convert the GCC struct, to a MSVC struct # comments /* ... */ and // to end of line # 20090829 - change behaviour # when in the structure ONLY ';' semicolon ends a member line # not the newline character! sub build_struct_hash($) { my ($as) = shift; my %hash = (); my $next_member = 0; my $depth = 0; ## my $as = reline_structure_string(\$depth, $as_in); # need to read code string, and build a hash of type my ($i, $len, $ch, $word, $pc, $nc, $line, $stst, @arr, $sec, $j, $ac, $akey, $typ, $bs, $lnn, $msg, $com); my $pname = ''; # NAME of structure - VERY IMPORTANT $len = length($as); $word = ''; $line = ''; $stst = 0; $lnn = 1; $ch = ''; prt( "[dbg25|31] Bulding structure hash... $len chars...\n" ) if ($dbg25 || $dbg31); for ($i = 0; $i < $len; $i++) { $pc = $ch; $ch = substr($as,$i,1); # char by char $nc = (($i + 1) < $len) ? substr($as,$i+1,1) : " "; # if END OF LINE if ($ch eq "\n") { if (!$stst) { prt( "$lnn:$stst:extra: got end of line ($i) word=[$word] line=[$line]\n" ) if ($dbgext); if ($stst && length($line)) { # ($line, $rnxt, $rh) = @_; deal_with_member($lnn, $line, \$next_member, \%hash); } elsif (length($line)) { $msg = sprintf( "%3d: ", $lnn ); $msg .= $line; prtw("WARNING: NO struct start [$msg]\n"); } $lnn++; $line = ''; } next; } prt( "$lnn:$stst:extra: got space ($i) word=[$word] line=[$line]\n" ) if (($ch =~ /\s/) && $dbgext); next if ($ch =~ /\s/); # got the START of a WORD if ($stst && ($ch eq '}')) { $stst = 0; # end of member definitions prt( "$lnn:$stst:extra: got closing brace ($i) word=[$word] line=[$line]\n" ) if ($dbgext); if (length($word)) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; deal_with_member($lnn, $line, \$next_member, \%hash); $line = ''; } $i++; $word = ''; for (; $i < $len; $i++) { $pc = $ch; $ch = substr($as,$i,1); # char by char $nc = (($i + 1) < $len) ? substr($as,$i+1,1) : " "; $word .= $ch; last if ($ch eq ';'); } # $hash{'NAME'} = $word; $word = trim_ends($word); $word =~ s/;$//; $word = trim_ends($word); if (length($word)) { if (defined $hash{$str_nam}) { prtw("WARNING:$lnn: Replacing name [".$hash{$str_nam}."] with [$word] - CHECKME!\n"); } $hash{$str_nam} = $word; # SET NAME OF STRUCTURE - an important item } if ($dbg27) { $msg = sprintf( "%3d: ", $lnn ); $msg .= "}$word"; prt("[dbg27] Closing: $msg\n") ; } $word = ''; $line = ''; next; } $word = $ch; if ($ch eq '{') { prt( "$lnn:$stst:extra: got openning brace ($i) word=[$word] line=[$line]\n" ) if ($dbgext); if (length($line)) { #$hash{'TAG'} = $line; $hash{$str_tag} = $line; $line .= " $ch"; } else { $line = $ch; } $msg = sprintf( "%3d: ", $lnn ); $msg .= $line; $pname = get_potential_struct_name($line); prt("[dbg26] Start of structure: [$msg] pname=[$pname]\n") if ($dbg26); $line = ''; $stst = 1; # start of struct next; } $i++; if (($ch eq '/') && ($nc eq '*')) { prt( "$lnn:$stst:extra: got start of a comment /* ... */ ($i) word=[$word] line=[$line]\n" ) if ($dbgext); $i += 2; $com = '/*'; for (; $i < $len; $i++) { $pc = $ch; $ch = substr($as,$i,1); # char by char $lnn++ if ($ch eq "\n"); $nc = (($i + 1) < $len) ? substr($as,$i+1,1) : " "; if (($ch eq '*') && ($nc eq '/')) { $i++; $com .= $ch; $com .= $nc; $msg = sprintf( "%3d: ", $lnn ); $msg .= "Discarding:1: [$com]"; $word =~ s/\/$//; # remove this char from the word prt("[dbg04] $msg W[$word] L[$line]\n") if ($dbg04); $pc = $nc; last; } $com .= $ch; } next; } elsif (($ch eq '/') && ($nc eq '/')) { prt( "$lnn:$stst:extra: got start of a comment //... ($i) word=[$word] line=[$line]\n" ) if ($dbgext); #$i++; # jump this #$com = $ch; $word =~ s/\/$//; # remove this char from the word $com = $ch; for (; $i < $len; $i++) { $pc = $ch; $ch = substr($as,$i,1); # char by char if ($ch eq "\n") { $msg = sprintf( "%3d: ", $lnn ); $msg .= "Discarding:2: [$com]EOL"; prt("[dbg04] $msg W[$word] L[$line]\n") if ($dbg04); $i--; # back up to this important CHAR last; } $com .= $ch; $pc = $ch; } next; } for (; $i < $len; $i++) { # accumulating the next WORD $pc = $ch; $ch = substr($as,$i,1); # char by char $nc = (($i + 1) < $len) ? substr($as,$i+1,1) : " "; if ($ch =~ /\s/) { prt( "$lnn:$stst:extra: got space - exit with last - word=[$word] line=[$line] ($i)\n" ) if ($dbgext); last; } elsif ($ch eq '{') { # hmmm, the '{' would be attached to the word $i--; # back up to this char in string last; # exit here, to add this word to the line } elsif (($ch eq '/') && ($nc eq '*')) { prt( "$lnn:$stst:extra: got start of a comment /* ... */...(2) ($i) word=[$word] line=[$line]\n" ) if ($dbgext); $i += 2; $com = '/*'; for (; $i < $len; $i++) { $pc = $ch; $ch = substr($as,$i,1); # char by char $com .= $ch; $lnn++ if ($ch eq "\n"); $nc = (($i + 1) < $len) ? substr($as,$i+1,1) : " "; if (($ch eq '*') && ($nc eq '/')) { $i++; $com .= $ch.$nc; $msg = sprintf( "%3d: ", $lnn ); $msg .= "Discard2: [$com]"; prt("[dbg04] $msg W[$word] L[$line]\n") if ($dbg04); last; } } last; } elsif (($ch eq '/') && ($nc eq '/')) { prt( "$lnn:$stst:extra: got start of a comment //...(2) ($i) word=[$word] line=[$line]\n" ) if ($dbgext); $i += 2; $com = $ch.$nc; for (; $i < $len; $i++) { $pc = $ch; $ch = substr($as,$i,1); # char by char $nc = (($i + 1) < $len) ? substr($as,$i+1,1) : " "; if ($ch eq "\n") { $msg = sprintf( "%3d: ", $lnn ); $msg .= "Discard2: [$com]"; prt("[dbg04] $msg W[$word] L[$line]\n") if ($dbg04); last; } $com .= $ch; } last; } $word .= $ch; # add to word last if ($stst && ($ch eq ';')); } # exit on a spacey char - back up if spacey char is new line $i-- if ($ch eq "\n"); if (length($word)) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; # restart word } # if semicolon END OF LINE if ($stst && ($ch eq ';')) { prt( "$lnn:$stst:extra: got $ch = end of line struct line ($i) line=[$line]\n" ) if ($dbgext); deal_with_member($lnn, $line, \$next_member, \%hash) if (length($line)); $line = ''; } } if (length($line)) { $msg = sprintf( "%3d: ", $lnn ); $msg .= $line; prtw("WARNING: LINE NOT HANDLED $msg\n"); } if ($next_member == 0) { prt( "ERROR: structure hash has NO members!\n" ); my_exit(1, "$lnn lines, input=[$as]\n" ); } if (length($pname) && !(defined $hash{$str_nam})) { $hash{$str_nam} = $pname; # SET NAME OF STRUCTURE - an important item prt( "Set structure name to (potential) [$pname] - CHECK!\n" ); } $word = "NAME_UNKNOWN - WARNING - CHECKME!"; if (defined $hash{$str_nam}) { $word = $hash{$str_nam}; } prt("Done structure [$word] building... with $next_member members...\n") if ($dbg25); $hash{$mem_cnt} = $next_member; $hash{$mem_nxt} = 0; # start a next member counter #return %hash; return \%hash; } sub set_debug_on_str_parse() { ###$dbgext = 1; # show lots of stages in decode of structure - $dbg00 = 1; # show prt("$lnn: deal with member [$line], split=$ac, type=$typ, next=$nxt\n" ) if ($dbg00); $dbg01 = 1; # show each line of structure $dbg04 = 1; # show discarded comments in building structure members $load_log = 1; # load the LOG file contents $dbg25 = 1; # show prt( "[dbg25] Bulding structure hash... $len chars...\n" ) if ($dbg25); $dbg26 = 1; # show prt("[dbg26] Start of structure: [$msg]\n") if ($dbg26); $dbg27 = 1; # show prt("[dbg27] Closing: $msg\n") if ($dbg27); + line number, and word found = structure NAME $dbg02 = 1; # show after decode prtw( "WARNING: setting DEBUG on str parse (dbg 00, 01, 04) and load_log\n" ); } sub set_debug_on_fill_str() { # make the filling of values VERY NOISY $dbg03 = 1; # show def re-lining $dbg09 = 1; # show level information $dbg07 = 1; # show prt( "Added [$equ] to key [$key], for off[$off]\n" ) $dbg08 = 1; # show each line in structure filling $load_log = 1; # load the LOG file contents prtw( "WARNING: setting DEBUG on fill str (dbg 03, 09, 07) and load_log\n" ); } # level dependant things kept #my $L_EQU = 0; # equal sign #my $L_CMA = 1; # comma #my $L_DOT = 2; # dot #my $L_QOT = 3; # double quotes #my $L_QT1 = 4; # single quotes #my $L_BRA = 5; # inc on '(' dec on ')' #my $L_BRC = 6; # inc on '{' dec on '}' #my $L_SQU = 7; # inc on '[' dec on ']' sub brace_closes_in_this_line($) { my ($txt) = shift; # = (substr($ln,$i+1) my $ll = length($txt); my $brcnt = 1; # we have one OPEN brace at this point for (my $j = 0; $j < $ll; $j++) { my $c = substr($txt,$j,1); if ($c eq "\n") { last; # reached END OF LINE } elsif ($c eq '{') { $brcnt++; # bump counter } elsif ($c eq '}') { $brcnt-- if ($brcnt); } } if ($brcnt == 0) { return 1; } return 0; } sub just_space_to_semi_colon($) { # = substr($as,$i+1) my ($tx) = shift; my ($ll,$j,$c); $ll =length($tx); for ($j = 0; $j < $ll; $j++) { $c = substr($tx,$j,1); if ($c eq ';') { return 1; } elsif ($c =~ /\s/) { next; } return 0; } return 0; } # strip comments # /* ... */ and # // to EOL sub strip_comments($) { my ($ln) = shift; my $nln = ''; my $len = length($ln); my ($k, $pc, $cc, $nc); $cc = ''; for ($k = 0; $k < $len; $k++) { $pc = $cc; $cc = substr($ln,$k,1); $nc = (($k + 1) < $len) ? substr($ln,$k+1,1) : ''; if (($cc eq '/') && ($nc eq '*')) { # locked in comment /* ... */ $cc = $nc; $k += 2; for (; $k < $len; $k++) { $pc = $cc; $cc = substr($ln,$k,1); $nc = (($k + 1) < $len) ? substr($ln,$k+1,1) : ''; if (($cc eq '/') && ($pc eq '*')) { last; } } next; } elsif (($cc eq '/') && ($nc eq '/')) { # locked in comment /* ... */ $cc = $nc; $k += 2; for (; $k < $len; $k++) { $pc = $cc; $cc = substr($ln,$k,1); $nc = (($k + 1) < $len) ? substr($ln,$k+1,1) : ''; if ($cc eq "\n") { $k--; # back up to this char last; } } next; } $nln .= $cc; } return $nln; } # reline instance string # try to be very flexible, but keep certain things INLINE # ======================================================= sub reline_instance_string($$) { my ($rdep,$ln) = @_; my ($len, $i, $pc, $cc, $nc, $word, $line, $max, $bcnt, $dcnt, $lnn); my ($hadcoma, $haddot, $hadequ, $nln); my $ntxts = ''; $ln = strip_comments($ln) if ($strip_comments); $len = length($ln); $word = ''; $line = ''; my @brcstk = (); my @brkstk = (); my @depitems = (); # items EQU CMA DOT QOT QT1 BRA BRC SQU push(@depitems, [ 0, 0, 0, 0, 0, 0, 0, 0 ]); # add one extra prt( "Re-lining $len characters...\n" ); $max = 0; $dcnt = 0; $hadcoma = 0; $haddot = 0; $hadequ = 0; $bcnt = 0; # brace count = LEVEL $cc = "\n"; $lnn = 0; $nln = 0; for ($i = 0; $i < $len; $i++) { $pc = $cc; # update previous $cc = substr($ln,$i,1); # get current $nc = (($i + 1) < $len) ? substr($ln,$i+1,1) : " "; # and next if ($cc eq "\n") { $lnn++; $nln++; } # BEFORE character added # ====================== if ($cc eq "\n") { next if ($bcnt == 0); # join this to one line until first '{' if (length($word)) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; } # next if ($bcnt > 2); # 20090826 - above 2 keep inline next if ($bcnt >= 2); # 20090903 - above or equal 2 KEEP INLINE # 20090904 - keep a '.member = ' INLINE next if ($line =~ /^\.\w+\s+=\s*$/); if (length($line)) { prt("[dbg03] $lnn:$nln: [$line] lev=$bcnt\n") if ($dbg03); if (($haddot > 1) && ($hadequ > 1) && ($hadcoma > 1)) { my $ll = length($line); # maybe this line should be SPLIT, with second, or more '.', each to a NEW line... prt( "[dbg03] CHECK: SPLIT of line=[$line]\n" ) if ($dbg03); while ($ll) { my ($j, $c, $part); $hadcoma = 0; $haddot = 0; $hadequ = 0; $part = ''; for ($j = 0; $j < $ll; $j++) { $c = substr($line,$j,1); if (length($part) == 0) { next if ($c =~ /\s/); } $part .= $c; # add to part if ($c eq '.') { $haddot++; } elsif ($c eq '=') { $hadequ++; } elsif ($c eq ',') { if ($haddot && $hadequ) { $j++; # include comma last; } } } if (length($part)) { $ntxts .= $part; $ntxts .= "\n"; $nln++ if ($part ne $line); prt("[dbg03] $lnn:$nln: ADDING part=[$part] to new text. lev=$bcnt\n") if ($dbg03); } if ($j < length($line)) { $line = substr($line,$j); # reduce line to balance $ll = length($line); # and get length remaining } else { $line = ''; $ll = 0; } } } else { prt("[dbg03] $lnn:$nln: ADDING line=[$line] to new text. lev=$bcnt\n") if ($dbg03); $ntxts .= "$line"; $ntxts .= "\n"; # = $cc } $line = ''; } $hadcoma = 0; $haddot = 0; $hadequ = 0; next; } elsif ($cc =~ /\s/) { if (length($word)) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; } $pc = $cc; # update previous next; } elsif ($cc eq '{') { ### ***** OPEN BRACE ***** push(@brcstk,$i); $bcnt = scalar @brcstk; $max = $bcnt if ($bcnt > $max); # get MAXIMUM depth while ($max > $dcnt) { # items EQU CMA DOT QOT QT1 BRA BRC SQU push(@depitems, [ 0, 0, 0, 0, 0, 0, 0, 0 ]); # add one extra $dcnt++; } # clear seen items, at this depth/level $depitems[$bcnt][$L_EQU] = 0; # equal $depitems[$bcnt][$L_CMA] = 0; # comma $depitems[$bcnt][$L_DOT] = 0; # dot $depitems[$bcnt][$L_QOT] = 0; # double quotes $depitems[$bcnt][$L_QT1] = 0; # single quotes $depitems[$bcnt][$L_BRA] = 0; # brackets ( ) $depitems[$bcnt][$L_BRC] = 1; # brace { } $depitems[$bcnt][$L_SQU] = 0; # brace [ ] prt( "[dbg03] $lnn:$nln: OPEN brace - W=[$word] L=[$line] - bcnt=$bcnt\n" ) if ($dbg03); } elsif ($cc eq '}') { ### ***** CLOSE BRACE ***** if ($depitems[$bcnt][$L_BRC]) { $depitems[$bcnt][$L_BRC]--; } else { prtw( "WARNING:reline_def: Closing brace without open - level $dcnt\n" ); } if (@brcstk) { pop @brcstk; } else { prtw("WARNING:reline_def: Encountered $cc, with no stack!\n"); } $bcnt = scalar @brcstk; prt( "[dbg03] $lnn:$nln: CLOSE brace - W=[$word] L=[$line] - bcnt=$bcnt\n" ) if ($dbg03); } elsif ($cc eq '(') { $depitems[$bcnt][$L_BRA]++; # brackets ( ) push(@brkstk,$i); } elsif ($cc eq ')') { if ($depitems[$bcnt][$L_BRA]) { # brackets ( ) $depitems[$bcnt][$L_BRA]--; } else { prtw( "WARNING: closing bracket without open - level $dcnt\n" ); } if (@brkstk) { pop @brkstk; } else { prtw("WARNING: Encountered $cc, with no stack!\n"); } } # 20090831 - if end of structure stuff - bcnt==0, and this is the closer, '}', and the next is ';' # take a new line if (($bcnt == 0) && ($cc eq '}') && (($nc eq ';') || just_space_to_semi_colon( substr($ln,$i+1) ) ) ) { prt( "[dbg03] $lnn:$nln: Got '}s*;' = Take a NEW line! after W=[$word] L=[$line]\n" ) if ($dbg03); if (length($word)) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; } if (length($line)) { $ntxts .= $line; $ntxts .= "\n"; $nln++; $line = ''; } } # 20090901 - if a .member take a new line # 20090903 - BUT not if the previous char is \w - eg .name = "3GPP TS 26.403-inspired model", # this dot within the quotes should NOT be a NEW LINE # if (($cc eq '.') && ($nc =~ /\w/) && ($bcnt < 2)) { # if (($cc eq '.') && ($nc =~ /\w/) && ($bcnt < 2) && ($depitems[$bcnt][$L_QOT] == 0)) { # if ($cc eq '.') { # 20090926 - avoid splitting a DECIMAL number if ( ($cc eq '.') && ( !($pc =~ /\d/) ) ) { # if (($nc =~ /\w/) && ($bcnt < 2) && ($depitems[$bcnt][$L_QOT] == 0)) { if (($nc =~ /\w/) && ($depitems[$bcnt][$L_QOT] == 0)) { prt( "[dbg03] $lnn:$nln: Got '.w+' = Inserted NEW line before! W=[$word] L=[$line]\n" ) if ($dbg03); if (length($word)) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; } if (length($line)) { $ntxts .= $line; $ntxts .= "\n"; $nln++; $line = ''; } } else { if ($nc =~ /\w/) { #if ($bcnt < 2) { if ($depitems[$bcnt][$L_QOT] == 0) { my_exit(1, "FAILED IN TESTING!\n" ); } else { prt( "[dbg03] $lnn:$nln: Got '.\w+' & bcnt < 2 ($bcnt), but L_QOT=".$depitems[$bcnt][$L_QOT]." not 0 - Missed Inserted NEW line! W=[$word] L=[$line]\n" ) if ($dbg03); } #} else { # prt( "[dbg03] $lnn:$nln: Got '.\w+', but bcnt=$bcnt, not LT 2 - Missed Inserted NEW line! W=[$word] L=[$line]\n" ) if ($dbg03); #} } else { prt( "[dbg03] $lnn:$nln: Got '.', but NEXT not 'w' - Missed Inserted NEW line! W=[$word] L=[$line]\n" ) if ($dbg03); } } } $word .= $cc; # committed - add character prt("[dbg03] $lnn:$nln: Added char [$cc], to W=[$word] L=[$line] nc=spacey\n") if (($nc =~ /\s/) && $dbg03); # =============================== # after it is ADDED ###################################### if ($cc eq ',') { $hadcoma++; $depitems[$bcnt][$L_CMA]++; # comma } elsif ($cc eq '.') { $haddot++; $depitems[$bcnt][$L_DOT]++; # dot } elsif ($cc eq '=') { $hadequ++; $depitems[$bcnt][$L_EQU]++; # equ } elsif ($cc eq '"') { # 20090903 - ensure it is NOT escaped if ($pc ne "\\") { if ($depitems[$bcnt][$L_QOT]) { $depitems[$bcnt][$L_QOT]--; # double quotes } else { $depitems[$bcnt][$L_QOT]++; # double quotes } } } elsif ($cc eq "'") { if ($depitems[$bcnt][$L_QT1]) { $depitems[$bcnt][$L_QT1]--; # single quotes } else { $depitems[$bcnt][$L_QT1]++; # single quotes } } elsif ($cc eq '[') { $depitems[$bcnt][$L_SQU]++; # brace [ ] } elsif ($cc eq ']') { if ($depitems[$bcnt][$L_SQU]) { $depitems[$bcnt][$L_SQU]--; # double quotes } else { prtw( "WARNING: closing square bracket without open - level $dcnt\n" ); } # } elsif (($cc eq "{") && !($nc eq "\n")) #} elsif (($cc eq "{") && !($nc eq "\n") && !brace_closes_in_this_line(substr($ln,$i+1)) ) } elsif (($cc eq "{") && !($nc eq "\n") && # 20090831 - if brace count = 1, goto NEW line ( ($bcnt == 1) || !brace_closes_in_this_line(substr($ln,$i+1)) ) ) { #if (scalar @brcstk < 3) { #if ($bcnt < 3) { if ($bcnt < 2) { # 20090904 - reduce this to 2, from 3?!?!?!? $line .= ' ' if (length($line)); $line .= $word; $word = ''; $ntxts .= "$line"; $ntxts .= "\n"; $nln++; prt("[dbg03] $lnn:$nln: Due '{', [$line] to new line. (lev=$bcnt)\n") if ($dbg03); $line = ''; $pc = $cc; next; } } } # process each character # all done = clear any remaining items if (length($word)) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; } if (length($line)) { prt("[dbg03] $lnn:$nln: EL=[$line] bcnt=$bcnt\n") if ($dbg03); #$ntxts .= "$line$cc"; $ntxts .= "$line\n"; $line = ''; } # ======================================================================== # done relineing, and in exit if ( !@brcstk && !@brkstk ) { prt( "Appears brace and bracket stacks cleared.\n" ); } else { if (@brcstk) { prtw("\n*****************************\nWARNING: brace stack NOT cleared!\n*****************************\n"); } if (@brkstk) { prtw("\n*****************************\nWARNING: bracket stack NOT cleared!\n*****************************\n"); } my_exit(1, "reline_instance_string: FAILED!\n"); } $len = length($ntxts); prt( "Done Re-lining - got $len characters, depth=$max...\n" ); $$rdep = $max; # return MAX depth of BRACES write2file($ntxts,"tempntxt.txt"); prt( "Written re-lined text to 'tempntxt.txt'...\n" ); ### my_exit(1, "TEMP EXIT"); return $ntxts; } sub reline_instance_string_OK($$) { my ($rdep,$ln) = @_; my ($len, $i, $pc, $cc, $nc, $word, $line, $max, $bcnt); my ($hadcoma, $haddot, $hadequ); my $ntxts = ''; $len = length($ln); $word = ''; $line = ''; my @brcstk = (); my @brkstk = (); prt( "Re-lining $len characters...\n" ); $max = 0; $hadcoma = 0; $haddot = 0; $hadequ = 0; $bcnt = 0; $pc = "\n"; for ($i = 0; $i < $len; $i++) { $cc = substr($ln,$i,1); $nc = (($i + 1) < $len) ? substr($ln,$i+1,1) : " "; # BEFORE character added # ====================== if ($cc eq "\n") { next if ($bcnt == 0); # join this to one line until first '{' if (length($word)) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; } if (length($line)) { prt("[dbg03] $line\n") if ($dbg03); if (($haddot > 1) && ($hadequ > 1) && ($hadcoma > 1)) { my $ll = length($line); # maybe this line should be SPLIT, with second, or more '.', each to a NEW line... prt( "[dbg03] CHECK: SPLIT of line...\n" ) if ($dbg03); while ($ll) { my ($j, $c, $part); $hadcoma = 0; $haddot = 0; $hadequ = 0; $part = ''; for ($j = 0; $j < $ll; $j++) { $c = substr($line,$j,1); if (length($part) == 0) { next if ($c =~ /\s/); } $part .= $c; # add to part if ($c eq '.') { $haddot++; } elsif ($c eq '=') { $hadequ++; } elsif ($c eq ',') { if ($haddot && $hadequ) { $j++; # include comma last; } } } if (length($part)) { $ntxts .= $part; $ntxts .= "\n"; prt("[dbg03] $part\n") if ($dbg03); } if ($j < length($line)) { $line = substr($line,$j); # reduce line to balance $ll = length($line); # and get length remaining } else { $line = ''; $ll = 0; } } } else { $ntxts .= "$line"; $ntxts .= "\n"; # = $cc } $line = ''; } $hadcoma = 0; $haddot = 0; $hadequ = 0; $pc = $cc; # update previous next; } elsif ($cc =~ /\s/) { if (length($word)) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; } $pc = $cc; # update previous next; } elsif ($cc eq '{') { push(@brcstk,$i); $bcnt = scalar @brcstk; $max = $bcnt if ($bcnt > $max); # get MAXIMUM depth } elsif ($cc eq '}') { if (@brcstk) { pop @brcstk; $bcnt = scalar @brcstk; } else { prtw("WARNING: Encountered $cc, with no stack!\n"); } } elsif ($cc eq '(') { push(@brkstk,$i); } elsif ($cc eq ')') { if (@brkstk) { pop @brkstk; } else { prtw("WARNING: Encountered $cc, with no stack!\n"); } } # =============================== $word .= $cc; # =============================== # after it is ADDED ###################################### if (($cc eq "{") && !($nc eq "\n")) { #if (scalar @brcstk < 3) { if ($bcnt < 3) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; prt("[dbg03] $line\n") if ($dbg03); $ntxts .= "$line"; $ntxts .= "\n"; $line = ''; $pc = $cc; next; } } elsif ($cc eq ',') { $hadcoma++; } elsif ($cc eq '.') { $haddot++; } elsif ($cc eq '=') { $hadequ++; } $pc = $cc; # update previous } # all done = clear any remaining items if (length($word)) { $line .= ' ' if (length($line)); $line .= $word; $word = ''; } if (length($line)) { prt("[dbg03] $line\n") if ($dbg03); $ntxts .= "$line$cc"; $line = ''; } if ( !@brcstk && !@brkstk ) { prt( "Appears brace and bracket stacks cleared.\n" ); } else { if (@brcstk) { prtw("\n*****************************\nWARNING: brace stack NOT cleared!\n*****************************\n"); } if (@brkstk) { prtw("\n*****************************\nWARNING: bracket stack NOT cleared!\n*****************************\n"); } my_exit(1, "reline_instance_string_OK: FAILED!\n"); } $len = length($ntxts); prt( "Done Re-lining - got $len characters, depth=$max...\n" ); $$rdep = $max; # return MAX depth of BRACES return $ntxts; } sub get_struc_mem_names($) { my ($rh) = @_; my ($k, $v, $n, $n2); my $names = ''; foreach $k (keys %{$rh}) { if ($k =~ /^$mem_bgn/) { # member - use only MEMBER keys $v = ${$rh}{$k}; # extract the array $n = $$v[$O_NAM]; # [1] - get the name of the member $n2 = $$v[$O_FNM]; # function pointer name $names .= ' ' if length($names); if (length($n2)) { $names .= $n2; } else { $names .= $n; } } } return $names; } sub offset_in_hash($$) { my ($off,$rh) = @_; my ($k, $v, $n, $n2); foreach $k (keys %{$rh}) { if ($k =~ /^$mem_bgn/) { # member - use only MEMBER keys $v = ${$rh}{$k}; # extract the array $n = $$v[$O_NAM]; # [1] - get the name of the member if ($n eq $off) { return $k; } $n2 = $$v[$O_FNM]; # function pointer name if (length($n2) && ($n2 eq $off)) { return $k; } # 20090830 - what about names like 'enc_name[50]'... if ($n =~ /^(\w+)\s*\[/) { $n2 = $1; if ($n2 eq $off) { return $k } } # 20090827 - exclude this, can be a problem, like 'name' and 'long-name' for example #if ($n =~ /$off/) { # return $k; #} } } return ""; } sub word_is_rh_name($$) { my ($wd,$rh) = @_; my ($k,$v); $k = $str_nam; if (defined ${$rh}{$k}) { $v = trim_all(${$rh}{$k}); $v =~ s/;$//; # remove the semi-colon for the compare $v = trim_all($v); if ($v eq $wd) { return 1; } else { prt("[dbg15] Note: hash [$k]=[$v], NOT equal to [$wd]!\n") if ($dbg15); } } else { prtw("WARNING: No [$k] key in hash!\n"); } show_struc_defines( 1, $rh, $wd ); return 0; } sub instance_space_split($) { my ($txt) = shift; my @a = (); my $ll = length($txt); my ($j, $c, $wd); $wd = ''; for ($j = 0; $j < $ll; $j++) { $c = substr($txt,$j,1); #// char by char if ($c =~ /\s/) { # if a SPACEY char push(@a,$wd) if length($wd); # stack word, if any $wd = ''; # and clear word } elsif ($c =~ /\w/) { # if alpha numeric $wd .= $c; # store it } elsif ($c eq '[') { # 20090829 - ensure this '[' is together with ']', # and is split from name - so 'foo[1]' becomes 'foo [1]' push(@a,$wd) if length($wd); $wd = $c; $j++; for (; $j < $ll; $j++) { $c = substr($txt,$j,1); #// char by char $wd .= $c; if ($c eq ']') { push(@a,$wd) if length($wd); $wd = ''; last; } } } else { # not spacey, nor alphanumeric - is punctuation and other specials push(@a,$wd) if length($wd); $wd = $c; } } push(@a,$wd) if length($wd); return @a; } # is it something like # static const DVprofile dv_profiles[] = { sub is_instance_definition($$$) { my ($ln,$rh,$rmh) = @_; my ($len, $i, $cc, $word, $line, @arr, $sname, $iname, $al, $msg, $isize, $snum, $key, $stage); $len = length($ln); #@arr = split(/\s/,$ln); @arr = instance_space_split($ln); $al = scalar @arr; $line = ''; $iname = ''; $sname = ''; $snum = ''; $stage = 0; $isize = $bad_posn; # = -200; if ($dbg22) { prt("[dbg22] Doing is id - split $al...\n"); for ($i = 0; $i < $al; $i++) { $word = $arr[$i]; prt( "".($i + 1)." $word\n" ); } } if ( !($ln =~ /=\s*\{$/) ) { prt( "[dbg16] Line [$ln] is NOT instance definition...\n" ) if ($dbg16); return 0; } prt( "Line [$ln] looks like an instance definition...\n" ); for ($i = 0; $i < $al; $i++) { $word = $arr[$i]; next if ($word eq '}'); $msg = "Checking [$word] "; # skip over these words if ( word_in_array($word, \@res_words) ) { $line .= ' ' if (length($line)); $line .= $word; prt( "[dbg16] $msg - it is in res_words array\n" ) if ($dbg16); next; } # must have structure name, and instance name if (length($sname) && length($iname)) { next if ($word eq '='); next if ($word eq '{'); next if (($word eq '};')||($word =~ /}\s*;/)); next if ($word eq '}'); } # check if it is the structure name... #if ( word_is_rh_name($word,$rh) ) { # 20090903 - do NOT do this if already had 'sname' if ( (length($sname) == 0) && word_is_rh_name($word,$rh) ) { $sname = $word; $stage++; prt( "[dbg16] $msg - it is the struct name\n" ) if ($dbg16); next; } # must have structure NAME first # 20090829 - change in special space split ensures this SHOULD be the 'instance' name # this will FAIL on 'anonymous' structure if (length($sname) && !length($iname) ) { $iname = $word; $stage++; prt( "[dbg16] $msg - assumed instance name...\n" ) if ($dbg16); next; } #if ($word =~ /^[\w\[\]]$/ ) { #if ($word =~ /^\w+[\[\]\w]*$/) { #if (length($sname) && ($word =~ /^\w+\s*\[(\w*)\]$/)) #if (length($sname) && ($word =~ /^\w+\s*(\[(\w*)\])?$/)) #if (length($sname) && ($word =~ /^\w*\s*(\[(\w*)\])?$/)) { # 20090829 - allow no 'alphanums' before [...] if ( ($stage >= 2) && ($word =~ /^\[\s*(\w*)\s*\]$/) ) { # 20090829 - in fact new special split separates [...] if (defined $1) { $snum = $1; $snum =~ s/^\[//; $snum =~ s/\]$//; # 20090827 - clear any space $snum = trim_ends($snum); # $snum = substr($snum,1) while ($snum =~ /^\s/); # clear leading # $snum = substr($snum,0,length($snum)-1) while ($snum =~ /\s$/); # and trailing if (length($snum)) { prt("[dbg21] Got length [$snum](".length($snum).") - decode or lookup in enum...\n") if ($dbg21); if ($snum =~ /^\d+$/) { # is a whole number $isize = $snum; } else { # assume alphanumeric # $str_enum = 'ENUMERATION'; #if (defined ${$rh}{$str_enum}) { # my $reh = ${$rh}{$str_enum}; $key = get_unique_key($str_enum); if (defined ${$rmh}{$key}) { my $reh = ${$rmh}{$key}; foreach my $k (keys %{$reh}) { if ($k eq $snum) { $isize = ${$reh}{$k}; last; } } prtw("WARNING: $msg - found [$key], checked [$snum], but isize=[$isize]!\n") if ($isize < 0); #prtw("WARNING: $msg - found [$str_enum], but isize=[$isize]!\n") if ($isize < 0); } else { prtw( "WARNING: $msg gave [$snum] as size, but no [$str_enum] in ref hash!\n" ); } } } next; } #prt( "[dbg16] $msg - assumed instance name... num=[$snum], if any\n" ) if ($dbg16); #if (length($iname)) { # prtw( "WARNING: $msg - Already HAVE iname=[$iname]!\n" ); #} else { # $iname = $word; #} next; } # must have structure name, and instance name if (length($sname) && length($iname)) { next if ($word eq '='); next if ($word eq '{'); next if (($word eq '};')||($word =~ /}\s*;/)); next if ($word eq '}'); } prtw( "WARNING: $msg - NOT PARSED in is_instance_definition!\n" ); my_exit(1, "is_instance_definition: line=[$ln]\n" ); } if (length($sname) && length($iname)) { # put entries decoded in the MASTER HASH # ${$rh}{$str_inst} = $iname; $key = get_unique_key($mast_iname); ${$rmh}{$key} = $iname; # store ONLY in master HASH prt( "[dbg16] Set key=[$key], with iname=[$iname]\n" ) if ($dbg16); #${$rh}{$str_inst} = $ln; $key = get_unique_key($mast_inst); ${$rmh}{$key} = $ln; # store ONLY in master HASH #${$rh}{$str_len} = $isize if ($isize > 0); if ($isize > 0) { $key = get_unique_key($mast_len); ${$rmh}{$key} = $isize; # AND the SIZE of the structure, if ANY... prt( "[dbg16] Set key=[$key], with isize=[$isize]\n" ) if ($dbg16); } return 1; } return 0; } #my $F_HADID = 1; #my $F_HADEND = 2; #my $F_HADDOT = 4; sub add_line_2_hash($$$$$$) { my ($rfsflag, $lvl, $lnn, $ln, $rh, $rmh) = @_; my $wn = "WARNING:$lnn:$lvl:"; my ($key, $off, $equ); prt("[dbg20] Add [$ln] to hash...(fsflag=$$rfsflag)\n") if ($dbg20); if ($$rfsflag & $F_HADEND) { prtw("wn: add line called after structure CLOSED\n"); return; } elsif ($$rfsflag & $F_HADID) { ###if ($ln =~ /^\.(.+)=(.+)/) { if ($ln =~ /^\.\w{1}(.+)=(.+)/) { # begins with a dot entries... my @a = split('=',$ln); my $ca = scalar @a; if ($ca != 2) { prtw("$wn Split FAILED on [$ln]!\n"); } else { # got two elements $$rfsflag |= $F_HADDOT; $off = trim_all($a[0]); $equ = trim_all($a[1]); if ($off =~ /^\./) { $off = substr($off,1); $equ =~ s/,$//; $key = offset_in_hash($off,$rh); if (length($key)) { # success $$rh{$key}[$O_DEC] = "$ln"; $$rh{$key}[$O_VAL] = "$equ"; prt( "[dbg07] Added [$equ] to key [$key], for off[$off]\n" ) if ($dbg07); ${$rfsflag} |= $F_HADMEM; } else { prtw( "$wn NO FIND split [$off] = [$equ] NOT HANDLED! line[$ln] (4)\n" ); $key = get_struc_mem_names($rh); prtw( "list=[$key]\n" ); } } else { prtw( "$wn CHECK split [$off] = [$equ] NOT HANDLED! (5)\n" ); } } } else { # ========================================================================== # NOT a .abc=def, entry if ($ln eq '{') { prt( "[dbg18] $lnn:$lvl: Open new BLOCK... on [$ln]\n") if ($dbg18); } elsif ($lvl == 0) { if ($ln =~ /}\s*;/) { prt( "$lnn:$lvl: End of definitions... on [$ln]\n"); $$rfsflag |= $F_HADEND; # signal END of structure } else { prtw( "$wn line[$ln] NOT HANDLED! (1)\n" ); } } elsif ($lvl == 1) { if ($ln =~ /}\s*,/) { prt( "[dbg18] $lnn:$lvl: End of BLOCK... on [$ln]\n") if ($dbg18); } elsif ($ln eq '}') { # what is this??? but skip it anyway } else { if (!($$rfsflag & $F_HADDOT) && ($ln =~ /,$/)) { # assume a member VALUE $ln =~ s/,$//; # clear the comma $off = ${$rh}{$mem_nxt}; # get next member counter $off++; # bump to NEXT ${$rh}{$mem_nxt} = $off; $key = sprintf("%s%04d",$mem_bgn,$off); # member and number ${$rh}{$key}[$O_VAL] = $ln; prt( "[dbg18|20|07] $lnn:$lvl: Set member [$key] value to [$ln]\n") if ($dbg18 | $dbg20 | $dbg07); ${$rfsflag} |= $F_HADMEM; } else { prtw( "$wn line[$ln] NOT HANDLED! (2)\n" ); if (!($$rfsflag & $F_HADDOT)) { prt( "Have NOT had a DOT member!\n" ); } if (!($ln =~ /,$/)) { prt( "Line does NOT end in comma!\n" ); } my_exit(1, "FIX ME!\n"); } } } else { # handle things like - '[PIX_FMT_YUV420P] = {' if ($ln =~ /^\[(\w+)\]/) { $off = $1; prt( "[dbg19] $lnn:$lvl: [$ln] as offset [$off]\n") if ($dbg19); # $str_enum = 'ENUMERATION'; my $num = $bad_posn; #-200; my $key = get_unique_key($str_enum); if (defined ${$rmh}{$key}) { my $reh = ${$rmh}{$key}; foreach my $k (keys %{$reh}) { if ($k eq $off) { $num = ${$reh}{$k}; last; } } prt( "[dbg19] $lnn:$lvl: [$off] has val [$num]\n") if ($dbg19); # $copy_hash{$str_off} = $blknum; # OFFSET = order of this block (-1 = no order)!!! $key = $str_off; if ($num != $bad_posn) { ${$rh}{$key} = $num; # $bad_posn (was -200) is NO NUMBER, else a value given } } else { prtw( "$wn NO ENUMERATION rh! to solve $off\n" ); } } else { prtw( "$wn line[$ln] NOT HANDLED! (3)\n" ); } } } } else { if ( is_instance_definition($ln,$rh,$rmh) ) { $key = get_unique_key($mast_inst); $equ = ${$rmh}{$key}; prt( "$lnn:$lvl: Set Mast.Inst[$key]=[$equ]\n" ); $key = get_unique_key($mast_len); if (defined ${$rmh}{$key}) { $off = ${$rmh}{$key}; prt( "$lnn:$lvl: Set Mast.Leng[$key]=[$off]\n" ); } else { $off = $bad_posn; } $$rfsflag |= $F_HADID; # had ID } } prt("[dbg20] Done [$ln] to hash...(fsflag=$$rfsflag)\n") if ($dbg20); } sub test_depth($$) { my ($gcc, $rh) = @_; my $depth = 0; $dbg03 = 1; # set DEBUG ON $gcc = reline_instance_string(\$depth, $gcc); # remove some spaces... } sub clear_hash_values($) { my ($rh) = shift; my ($k,$v,$ko, $kd); $ko = $str_off; $kd = $str_done; foreach $k (keys %$rh) { if ($k =~ /^$mem_bgn/) { # member $$rh{$k}[$O_VAL] = ""; if (defined ${$rh}{$ko}) { delete $rh->{$ko}; } if (defined ${$rh}{$kd}) { delete $rh->{$kd}; } } } ${$rh}{$mem_nxt} = 0; # set the next member counter to zero } sub get_full_str_txt($$$$) { my ($sn, $ln, $tx, $rni) = @_; my $ft = "$sn tempinst = "; my ($j,$c,$max,$opn); $opn = 0; $max = length($ln); prt("For [$sn] have L=[$ln] T=[$tx]${$rni}\n"); for ($j = 0; $j < $max; $j++) { $c = substr($ln,$j,1); if ($c eq '{') { last; } } if ($c eq '{') { # use up any balance of the line $ft .= $c; $ft .= "\n"; $j++; $opn++; for (; $j < $max; $j++) { $c = substr($ln,$j,1); $c = ' ' if ($c eq "\n"); $ft .= $c; $opn++ if ($c eq '{'); if ($c eq '}') { $opn-- if ($opn); return $ft if ($opn == 0); } } $max = length($tx); $j = 0; } else { # else search begin in line $max = length($tx); for ($j = 0; $j < $max; $j++) { $c = substr($ln,$j,1); if ($c eq '{') { $ft .= $c; $ft .= "\n"; $opn++; $j++; last; } } } if ($opn) { my ($pc,$nc); $c = ''; for (; $j < $max; $j++) { $pc = $c; $c = substr($tx,$j,1); $nc = (($j + 1) < $max) ? substr($tx,$j+1,1) : ''; $c = ' ' if ($c eq "\n"); if ($c =~ /\s/) { #if (!($ft =~ /(\s|,)$/)) if ($ft =~ /\w$/) { $ft .= $c; } } else { if (($c eq '.')&&($nc =~ /\w/)) { $ft .= "\n"; } if (($c eq '=')&&($nc =~ /\w/)) { $ft .= " "; } $ft .= $c; } $opn++ if ($c eq '{'); if ($c eq '}') { $opn-- if ($opn); if ($opn == 0) { $ft =~ s/\}$//; # remove this TAIL item $ft .= "\n"; # go to new line $ft .= "};\n"; # add END ${$rni} += $j; # bump return - posn to restart in gcc text block return $ft; } } } } return ""; } sub complain_if_mast_len($) { my ($trmh) = shift; my $tk = get_unique_key($mast_len); if (defined ${$trmh}{$tk}) { prtw("WARNING: HOW DID [$tk] get defined to ".${$trmh}{$tk}."?\n"); } else { prtw("WARNING: Key [$tk] NOT DEFINED\n"); } } # my $mast_copied = 'COPIED'; # count of FILLED members COPIED to master sub bump_master_copied($) { my ($rmh) = shift; my $k = get_unique_key($mast_copied); if (defined ${$rmh}{$k}) { ${$rmh}{$k}++; } else { ${$rmh}{$k} = 1; } } sub copy_hash_to_master($$$) { my ($inst, $rh, $rmh) = @_; my ($msg, $k, $v); $msg = sprintf("$mem_bgn%08d", $inst); my %copy_hash = (); foreach $k (keys %{$rh}) { $v = $$rh{$k}; if ($k =~ /^$mem_bgn/) { # member $copy_hash{$k} = [@{$v}]; # store COPY of ARRAY } else { $copy_hash{$k} = $v; # store string, or hash-ref, or value, or ... } } ${$rmh}{$msg} = \%copy_hash; # THIS SEEMS TO WORK ;=)) } ## comments /* ... */, or // to end of line ##sub fill_struct_per_gcc($$) { # like ($gcc_struct, \%h); ## my ($gcc, $rh) = @_; sub fill_struct_per_gcc($$$$) { # like ($gcc_struct, \%h); my ($flg, $gcc, $rh, $rmh) = @_; my ($i, $len, $pc, $cc, $nc, $ic1, $ic2, $lnn); my ($bclvl, $bklvl, $line, $msg, $comm, $inst, $blknum); my ($k, $v, $v2); my $depth = 0; $gcc = reline_instance_string(\$depth, $gcc); # remove some spaces... my @brcstk = (); my @brkstk = (); my @depitems = (); my $flag = 0; $len = $depth; if ($len == 0) { my_exit(1, "CRITICAL ERROR: Got NO DEPTH!\n"); } push(@depitems, [ 0, 0, 0 ]); # add one extra while ($len) { push(@depitems, [ 0, 0, 0 ]); $len--; } $ic1 = 0; $ic2 = 0; $lnn = 1; $inst = 0; # expect mutiple instances $len = length($gcc); $bclvl = 0; $bklvl = 0; $blknum = -1; # order per as found prt( "Processing fill struct, $len chars, depth = $depth...\n" ); prt( "[$dbg08] content[$gcc]\n" ) if ($dbg08); for ($i = 0; $i < $len; $i++) { $cc = substr($gcc,$i,1); $nc = (($i + 1) < $len) ? substr($gcc,$i+1,1) : " "; if ($cc eq "\n") { if (length($line)) { # 20090901 - But this can be a '.' member, which is in fact another structure if (($line =~ /^\.(\w+)\s*/) && !($flg & 1)) { $k = $1; $v = offset_in_hash($k,$rh); if (length($v)) { # this IS a member name in this HASH my ($t,$n,$tk); $v2 = ${$rh}{$v}; $t = ${$v2}[$O_TYP]; $n = ${$v2}[$O_NAM]; my ($rmhoh2); # = get_master_hoh(); if (defined $mast_ref_hoh) { $rmhoh2 = $mast_ref_hoh; } else { $rmhoh2 = get_master_hoh(); $mast_ref_hoh = $rmhoh2; } # complain_if_mast_len($rmhoh2); if (defined ${$rmhoh2}{$t}) { $dbg16 = 1; my $nrh = ${$rmhoh2}{$t}; my $sn = ${$nrh}{$str_nam}; my $feats = $features; my $newi = $i + 1; # start from HERE # $feats &= ~($FF_MSCV | $FF_MSC2 | $FF_MSC3 | $FF_MSC4 | $FF_BLAN | $FF_COMM | $FF_COM1 | $FF_COMA | $FF_SORG); # remove unwanted items $feats &= ~($FF_MSVC_SET | $FF_BLAN | $FF_COMM | $FF_COM1 | $FF_COMA | $FF_SORG); # remove unwanted items $feats |= ($FF_INLN | $FF_NIND | $FF_NHED); # add in desired items prt( "$lnn: [$k] is member=[$v]=[$t $n] is another struct [$sn]\n" ); my $fline = get_full_str_txt($sn, $line, substr($gcc,$newi), \$newi); if ((length($fline)) && ($newi >= $i)) { prt( "Full line = [$fline]\n" ); my $filledrmhoh = fill_struct_per_gcc(1,$fline,$nrh,$rmhoh2); # complain_if_mast_len($filledrmhoh); prt( "$lnn: [$k] is member=[$v]=[$t $n] is another struct [$sn]\n" ); prt( "Full line = [$fline]\n" ); my $sstg = get_struct_inst_stg($feats,$filledrmhoh); # complain_if_mast_len($filledrmhoh); prt("Suggest = [$sstg]\n"); if ($sstg =~ /^\{(.+)\};$/) { # it looks OK prt( "$lnn: OK [$k] [$v]=[$t $n] struct [$sn] VALUE [$sstg] $newi\n" ); my $mxrem = $len - $newi; $mxrem = 16 if ($mxrem > 16); my $consum = substr($gcc,$i,$newi-$i); my $remtxt = substr($gcc,$newi,$mxrem); prt( "Check restart - consumed\n[$consum]\nrestart at\n[$remtxt]\n" ); $sstg =~ s/;$//; $line =~ s/{$//; $line .= $sstg; $i = $newi; } else { prtw( "WARNING: instance string does NOT conform [$sstg]!\n" ); } } } else { prt( "$lnn: [$k] is member=[$v]=[$t $n] in the hash\n" ); } #my_exit(1, "TEMPORARY EXIT\n"); } } $msg = sprintf("%3d: ", $lnn); $msg .= "[$line] passed to add_line_2_hash()"; prt( "[dbg08] $msg\n" ) if ($dbg08); ###add_line_2_hash($bclvl, $lnn, $line, $rh, \%mh); add_line_2_hash(\$flag, $bclvl, $lnn, $line, $rh, $rmh); $line = ''; } $lnn++; #if ($lnn == 2) { exit(1); } if ($ic2) { $msg = sprintf("%3d: ", $lnn); $msg .= "Discard: [$comm]"; prt( "[dbg06] $msg\n" ) if ($dbg06); } $ic2 = 0; $pc = $cc; next; } if ($ic1) { # locked in comment - stay to END $comm .= $cc; if (($cc eq '/') && ($pc eq '*')) { $ic1 = 0; # end of comment $msg = sprintf("%3d: ", $lnn); $msg .= "Discard: [$comm]"; prt( "[dbg05] $msg\n" ) if ($dbg05); } } elsif ($ic2) { # locked in comment - stay to end of line $comm .= $cc; } else { if (($cc eq '/') && ($nc eq '*')){ $ic1 = 1; # process a comment $comm = $cc; # start $pc = $cc; # update previous char next; } if (($cc eq '/') && ($nc eq '/')){ $ic2 = 1; # start comment, until EOL $comm = $cc; # start comment $pc = $cc; # update prev char next; } ##################################################################### $line .= $cc; # ADD to line if ($cc eq '{') { push(@brcstk,[$i, $lnn] ); $bclvl++; # clear depth flags $depitems[$bclvl][0] = 0; $depitems[$bclvl][1] = 0; $depitems[$bclvl][2] = 0; } elsif ($cc eq '}') { if (@brcstk) { # show depth items prt( "[dbg09] $bclvl: equ=[".$depitems[$bclvl][0]."], coma=[".$depitems[$bclvl][1]."] dot [".$depitems[$bclvl][2]."]\n" ) if ($dbg09); if (($depitems[$bclvl][0] > 0)&&($depitems[$bclvl][2] > 0)) { # we have a completed instance - COPY, and SAVE TO master HASH # ============================================================ # At this time this hash copy is in the ORDER found, # but by using the [OFF_NUM] = { notation, this could be # set at a specific block number (in ascii, but could probably use number?) $msg = sprintf("$mem_bgn%08d", $inst); $inst++; if ($use_copy_hash) { my %copy_hash = (); foreach $k (keys %{$rh}) { $v = $$rh{$k}; if ($k =~ /^$mem_bgn/) { # member $copy_hash{$k} = [@{$v}]; # store COPY of ARRAY } else { $copy_hash{$k} = $v; # store string, or hash-ref, or value, or ... } } # $copy_hash{$str_off} = $blknum; # OFFSET = order of this block (-1 = no order)!!! #$mh{$msg} = [ %copy_hash ]; #$master_hash{$msg} = \%copy_hash; # THIS SEEMS TO WORK ;=)) ${$rmh}{$msg} = \%copy_hash; # THIS SEEMS TO WORK ;=)) } else { # can NOT seem to get ANY of these working!!! my $href2 = {%{$rh}}; # copy an (anonymous) hash ??? maybe, maybe NOT!!! #$mh{$msg} = $href2; #$master_hash{$msg} = [ $href2 ]; ${$rmh}{$msg} = [ $href2 ]; #$mh{$msg} = {%{$rh}}; ### my $href_copy = $rh; ### $mh{$msg} = [ $href_copy ]; } # clear the current HASH values clear_hash_values($rh); # ready for NEXT $flag &= ~$F_HADMEM; # now copied, so remove bit bump_master_copied($rmh); } pop @brcstk; } else { prtw("$lnn:$i: WARNING:fill_str: Encountered $cc, with no stack!\n"); } $bclvl-- if ($bclvl); } elsif ($cc eq '(') { push(@brkstk, [$i, $lnn] ); $bklvl++; } elsif ($cc eq ')') { if (@brkstk) { pop @brkstk; } else { prtw("$lnn:$i: WARNING:fill_str: Encountered $cc, with no stack!\n"); } $bklvl-- if ($bklvl); } elsif ($cc eq '=') { $depitems[$bclvl][0]++; } elsif ($cc eq ',') { # this is an important CLOSE of an entry # but it has to be processed at the SAME level only $depitems[$bclvl][1]++; prt( "[dbg08] Had COMMA, at level=$bclvl L=[$line]\n" ) if ($dbg08); } elsif (($cc eq '.') && ($nc =~ /\w/)) { $depitems[$bclvl][2]++; } } $pc = $cc; } if ($flag & $F_HADMEM) { $msg = sprintf("$mem_bgn%08d", $inst); $inst++; if ($use_copy_hash) { my %copy_hash = (); foreach $k (keys %{$rh}) { $v = $$rh{$k}; if ($k =~ /^$mem_bgn/) { # member $copy_hash{$k} = [@{$v}]; # store COPY of ARRAY } else { $copy_hash{$k} = $v; # store string, or hash-ref, or value, or ... } } # $copy_hash{$str_off} = $blknum; # OFFSET = order of this block (-1 = no order)!!! #$mh{$msg} = [ %copy_hash ]; #$master_hash{$msg} = \%copy_hash; # THIS SEEMS TO WORK ;=)) ${$rmh}{$msg} = \%copy_hash; # THIS SEEMS TO WORK ;=)) } else { # can NOT seem to get ANY of these working!!! my $href2 = {%{$rh}}; # copy an (anonymous) hash ??? maybe, maybe NOT!!! #$mh{$msg} = $href2; #$master_hash{$msg} = [ $href2 ]; ${$rmh}{$msg} = [ $href2 ]; #$mh{$msg} = {%{$rh}}; ### my $href_copy = $rh; ### $mh{$msg} = [ $href_copy ]; } # clear the current HASH values clear_hash_values($rh); # ready for NEXT $flag &= ~$F_HADMEM; # now copied, so remove bit bump_master_copied($rmh); } if (@brcstk) { prtw( "WARNING: ".scalar @brcstk." items in brace stack!\n" ); } if (@brkstk) { prtw( "WARNING: ".scalar @brkstk." items in bracket stack!\n" ); } $ic1 = 0; $ic2 = 0; foreach $k (keys %{$rmh}) { $ic1++; if (!key_is_unique_type($k)) { $ic2++; } } $k = get_total_blocks($rmh); if ($k > 0) { $cc = "total = $k"; } else { $cc = "with no total blocks"; } prt("Done fill struct, with $ic1 members, $ic2 blocks, $cc...\n" ); ##return \%mh; return $rmh; } sub set_debug_on_fill() { $dbg08 = 1; # show each line in structure filling } sub get_hash_instance($) { my ($rh) = shift; my ($msg, $key, $val, $equ, $cnt); $cnt = 0; foreach $key (keys %$rh) { $val = $$rh{$key}; if ($key =~ /^$mem_bgn/) { # member $cnt++; } } $msg = ''; $key = $str_tag; # 'TAG' if (defined $$rh{$key}) { $val = $$rh{$key}; $msg .= "$val {\n"; } foreach $key (sort keys %$rh) { $val = $$rh{$key}; $cnt-- if ($cnt); if ($key =~ /^member/) { $equ = $$val[$O_VAL]; $msg .= " $equ"; $msg .= ',' if ($cnt); $msg .= "\n"; } } $key = $str_nam; # 'NAME' if (defined $$rh{$key}) { $val = $$rh{$key}; $msg .= "} $val ;\n"; } prt("************************************************\n"); prt($msg); prt("************************************************\n"); return $msg; } # 20090825 - add dealing with feature flags # these are only added under certain program conditions # my $FF_BLAN = 512; # generate a BLANK instance block # my $FF_WNUM = 1024; # we have an instance with set number of blocks in head # my $FF_WPOS = 2048; # this member has a specific position sub get_hash_instance2($$$$$) { my ($feat, $max, $cur, $rh, $rmh) = @_; my ($msg, $key, $val, $equ, $cnt, $iind, $mind, $typ, $nam, $min, $tst, $tlen, $min2, $org); my ($fnm,$iname,$cont,$tmp, $tmp2); my $add_blln = 1; $iname = "Unknown_FIXME"; # start as UNKNOWN $cnt = 0; foreach $key (keys %$rh) { $val = $$rh{$key}; if ($key =~ /^$mem_bgn/) { # member $cnt++; } } $mind = $memb_indent; $iind = $inst_indent; $mind = $memb_indent.$inst_indent if ($max > 1); $key = get_unique_key($mast_iname); if (defined ${$rmh}{$key}) { $iname = ${$rmh}{$key}; # get the instance NAME } $min = 0; $min2 = 0; if ($feat & $FF_COMM) { foreach $key (sort keys %$rh) { $val = $$rh{$key}; if ($key =~ /^$mem_bgn/) { # member $typ = $$val[$O_TYP]; $equ = $$val[$O_VAL]; $fnm = $$val[$O_FNM]; # get function name, if ANY $nam = $$val[$O_NAM]; $org = $$val[$O_ORG]; if (length($equ) == 0) { if (($typ =~ /\*$/) || (length($fnm) && ($nam =~ /\*/))) { $equ = "NULL"; } elsif ($typ =~ /enum\s+CodecID/) { $equ = 'CODEC_ID_NONE'; } else { $equ = "0"; } } # 20090904 - watch for these shortenned names, like $tmp = "_s_AVC_".$iname; if (($feat & $FF_MSC2) && ($equ =~ /\(\s*const\s+AVCodecTag\s*\*\s*const\s*\[\]\s*\)\s*\{(.+)\}/)) { $tlen = length($mind) + 1 + 7 + length($iname) + 1; } elsif (($feat & $FF_MSC3) && ($equ =~ /\(\s*enum\s+PixelFormat\s*\[\s*\]\s*\)\s*\{(.+)\}/)) { $tlen = length($mind) + 1 + 7 + length($iname) + 1; } elsif (($feat & $FF_MSC4) && ($equ =~ /\(\s*enum\s+SampleFormat\s*\[\s*\]\s*\)\s*\{(.+)\}/)) { $tlen = length($mind) + 1 + 7 + length($iname) + 1; } elsif (($feat & $FF_MSC5) && ($equ =~ /\(\s*(\w+)\s*\[\s*\]\s*\)\s*\{(.+)\}/)) { $tmp2 = $1; $cont = $2; $tmp = "_s_".$tmp2."_".$iname; $tlen = length($tmp); } else { $tst = "$mind $equ,"; $tlen = length($tst); } $min = $tlen if ($tlen > $min); $tst = "$typ $nam"; $tlen = length($tst); $min2 = $tlen if ($tlen > $min2); } } } # 20090903 limit the 'spacing' added $min = $max_spacing_out if ($min > $max_spacing_out); $min2 = $max_spacing_out2 if ($min2 > $max_spacing_out2); # START building string returned # ============================== $msg = ''; # blank it if ($cur == 1) { # if FIRST instance #$key = get_unique_key($mast_iname); #if (defined ${$rmh}{$key}) { # $iname = ${$rmh}{$key}; # get the instance NAME #} if ($feat & $FF_NHED) { $msg .= "{ "; } else { $key = get_unique_key($mast_inst); # 'INSTANCE' - should have been SAVED if (defined ${$rmh}{$key}) { $val = ${$rmh}{$key}; $msg .= "$val"; # should be up to and including ' = {' } else { # kludge an instance $key = $str_tag; # 'TAG' if (defined $$rh{$key}) { $val = $$rh{$key}; $msg .= "$val UNKNOWN_FIXME"; $msg .= "[$max]" if ($max > 1); $msg .= " {"; # start the HEADER } else { # ok MUST have SOME instance heading, so $key = $str_nam; # name of structure if (defined $$rh{$key}) { $val = $$rh{$key}; $msg .= "typedef struct $val INSTANCE_FIXME[] = {\n"; } else { $msg .= "typedef struct NAME_FIXME INSTANCE_FIXME[] = {"; } } } if ($feat & $FF_COMM) { if ($feat & $FF_WNUM) { $val = get_total_blocks($rmh); if ($val > 0) { if ($feat & $FF_COM1) { $msg .= " /* total blocks = $val */" } else { $msg .= " // total blocks = $val" } } } } } # skip header or not if ($feat & $FF_INLN) { $msg .= " " if ($msg =~ /\w$/); } else { $msg .= "\n"; # done the HEADER } # AFTER HEADER if ($max > 1) { $msg .= $iind."{"; if ($feat & $FF_COMM) { if ($feat & $FF_COM1) { $msg .= " /* block = $cur */" } else { $msg .= " // block = $cur" } } $msg .= "\n"; } } else { $msg .= $iind."{"; # open next instance if ($feat & $FF_COMM) { if ($feat & $FF_COM1) { $msg .= " /* block = $cur */" } else { $msg .= " // block = $cur" } } $msg .= $iind."\n"; # open next instance } # add the values of the members # ============================= foreach $key (sort keys %$rh) { $val = $$rh{$key}; if ($key =~ /^$mem_bgn/) { # member $cnt-- if ($cnt); # decement counter, to know last member if ($feat & $FF_SORG) { $org = $$val[$O_DEC]; $msg .= $mind."/* $org */\n"; } $typ = $$val[$O_TYP]; # [0] $nam = $$val[$O_NAM]; # [1] $equ = $$val[$O_VAL]; # [3] $fnm = $$val[$O_FNM]; # get function name, if ANY #$equ = "0" if (length($equ) == 0); if (length($equ) == 0) { if (($typ =~ /\*$/) || (length($fnm) && ($nam =~ /\*/))) { $equ = "NULL"; } elsif ($typ =~ /enum\s+CodecID/) { $equ = 'CODEC_ID_NONE'; } else { $equ = "0"; } } # IF generating a BLANK strcuture view if ($feat & $FF_BLAN) { # if ($typ =~ /\*$/) if (($typ =~ /\*$/) || (length($fnm) && ($nam =~ /\*/))) { $equ = "NULL"; } else { $equ = "0"; } } # potential MODIFIERS of the $equ string # 1 - if AVCodecTag if ($feat & $FF_MSC2) { # watch for .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0}, if ($equ =~ /AVCodecTag/) { ### prt("CHECKME [$equ]\n"); # (const AVCodecTag* const []){ff_codec_wav_tags, 0} if ($equ =~ /\(\s*const\s+AVCodecTag\s*\*\s*const\s*\[\]\s*\)\s*\{(.+)\}/) { $cont = $1; $tmp = "_s_AVC_".$iname; prt( "Fixing [$iname][$tmp] for AVCodecTag [$cont]!\n" ); if ($cont =~ /^(\s*\w+\s*,)+\s*0\s*$/) { # 20090907 - get this RIGHT! # need like 'static const AVCodecTag * _s_AVC_wav_demuxer[] = {ff_codec_wav_tags, 0}; $tst = "static const AVCodecTag * ".$tmp."[] = {$cont};\n"; # $tst = "static AVCodecTag ".$tmp."[] = {$cont};\n"; $msg = $tst.$msg; $equ = $tmp; } else { prtw( "WARNING: On [$equ], does not look right [$cont]!\n" ); my_exit(1, "FIXME\n"); } } else { prtw( "WARNING: Did regex FAIL on [$equ]! - CHECKME!\n" ); } } } # 2 - if enum PixelFormat if ($feat & $FF_MSC3) { # fix (enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE}, if ($equ =~ /enum\s+PixelFormat/) { if ($equ =~ /\(\s*enum\s+PixelFormat\s*\[\s*\]\s*\)\s*\{(.+)\}/) { $cont = $1; $tmp = "_s_PF_".$iname; prt( "Fixing [$iname][$tmp] for PixelFormat [$cont]!\n" ); if ($cont =~ /^(\s*\w+\s*,)+\s*(\w+|0)\s*$/) { $tst = "static const enum PixelFormat ".$tmp."[] = {$cont};\n"; $msg = $tst.$msg; #$equ = "(const enum PixelFormat *)$tmp"; $equ = "$tmp"; } else { prtw( "WARNING: On [$equ], does not look right [$cont]! CHECKME!\n" ); my_exit(1, "get_hash_instance2: FIXME!"); } } else { prtw( "WARNING:2: Did regex FAIL on [$equ]! - CHECKME!\n" ); my_exit(1, "get_hash_instance2: FIXME!"); } } } # 3 - if enum SampleFormat if ($feat & $FF_MSC4) { # (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE} if ($equ =~ /enum\s+SampleFormat/) { if ($equ =~ /\(\s*enum\s+SampleFormat\s*\[\s*\]\s*\)\s*\{(.+)\}/) { $cont = $1; $tmp = "_s_SF_".$iname; prt( "Fixing [$iname][$tmp] for SampleFormat [$cont]!\n" ); if ($cont =~ /^(\s*\w+\s*,)+\s*(\w+|0)\s*$/) { $tst = "static const enum SampleFormat ".$tmp."[] = {$cont};\n"; $msg = $tst.$msg; $equ = "$tmp"; } else { prtw( "WARNING: On [$equ], does not look right [$cont]! CHECKME!\n" ); my_exit(1, "get_hash_instance: FIXME!"); } } else { prtw( "WARNING: Did regex FAIL on [$equ]! - CHECKME!\n" ); my_exit(1, "get_hash_instance: FIXME!"); } } } # 4 if an anonymous structure in structure if ($feat & $FF_MSC5) { # (int64_t[]){ CH_LAYOUT_MONO, CH_LAYOUT_STEREO, ..., 0 } /* const int64_t * channel_layouts */ if ($equ =~ /\(\s*(\w+)\s*\[\s*\]\s*\)\s*\{(.+)\}/) { $tmp2 = $1; $cont = $2; $tmp = "_s_".$tmp2."_".$iname; prt( "Fixing [$iname][$tmp] for anon array [$cont]!\n" ); #if ($cont =~ /^(\s*(\w+|\||\(|\))\s*,)+\s*(\w+|\||0|\(|\))\s*$/) { $tst = "static $tmp2 ".$tmp."[] = {$cont};\n"; $msg = $tst.$msg; $equ = "$tmp"; #} else { # prtw( "ERROR: On\n[$equ]\ndoes not look right\n[$cont]!\nCHECKME!\n" ); # exit(1); } } if ( $add_blln && ($feat & $FF_BLLN) && (length($equ) > $max_long) && ($equ =~ /,/)) { # we can TRY to SPLIT the equ, if very LONG my @arr = split(",",$equ); # split on the COMMA my $acnt = scalar @arr; my $ntxt = ''; $tst = ''; $tst .= "\n" if ($cur == 1); # start a NEW line, if FIRST member for (my $a = 0; $a < $acnt; $a++) { if ($feat & $FF_NIND) { $ntxt .= ',' if (length($ntxt)); } else { if (length($ntxt) == 0) { $ntxt = "$mind "; } else { $ntxt .= ','; } } $ntxt .= $arr[$a]; if (length($ntxt) > $max_long) { if (($a + 1) < $acnt) { $ntxt .= ','; } $tst .= $ntxt."\n"; $ntxt = ''; } } $tst .= $ntxt if (length($ntxt)); } else { if ($feat & $FF_NIND) { $tst = "$equ"; } else { $tst = "$mind $equ"; } } # CLOSING the definition $tst .= ',' if ($cnt); # if NOT last member # Adding a comment after the definition if ($feat & $FF_COMM) { $tst .= ' ' while (length($tst) < $min); } $msg .= $tst; if ($feat & $FF_COMM) { $tst = "$typ $nam"; if ($feat & $FF_COM1) { if ($feat & $FF_COMA) { $tst .= ' ' while (length($tst) < $min2); } $msg .= " /* $tst */"; } else { $msg .= " // $tst"; } } if ($feat & $FF_INLN) { $msg .= " " if ($msg =~ /(\w|,)$/); } else { $msg .= "\n"; # to next line } } } if ($cur == $max) { # last instance $msg .= "\n"; # 20090927 - add a NEW line at the END $msg .= $iind."}\n" if ($max > 1); $msg .= "};"; $msg .= "\n"; # 20090927 - add a NEW line at the END } elsif ($max > 1) { $msg .= $iind."},"; # not last, so just close instance - more to come } $msg .= "\n" if !($feat & $FF_INLN); #prt("************************************************\n"); #prt($msg); #prt("************************************************\n"); return $msg; } sub find_block_at($$$) { my ( $cnt, $rmh, $rrh ) = @_; my ($k, $rh, $kd, $k2, $pos); $kd = $str_done; $k2 = $str_off; foreach $k (keys %{$rmh}) { if ( !key_is_unique_type($k)) { # like say $k =~ /^\@_/, or ... $rh = ${$rmh}{$k}; ${$rrh} = $rh; if (${$rh}{$kd} == 0) { # not done if (defined ${$rh}{$k2}) { $pos = ${$rh}{$k2}; if ($pos >= 0) { if ($pos == $cnt) { return 1; } } } } } } # ok FAILED to find block with THIS POSITION set # take the NEXT block, with NO position set foreach $k (keys %{$rmh}) { if ( !key_is_unique_type($k)) { # like say $k =~ /^\@_/, or ... $rh = ${$rmh}{$k}; ${$rrh} = $rh; if (${$rh}{$kd} == 0) { # not done if (defined ${$rh}{$k2}) { $pos = ${$rh}{$k2}; if ($pos >= 0) { # this has a position mark - must WAIT its turn } else { # bad positon mark is like NO position mark return 1; } } else { # no position entry return 1; } } } } return 0; # no record FOUND - gen a BLANK } # deal with .codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0}, sub extract_avcodectag($$$) { my ($txt,$rh,$rmh) = @_; my (@arr,$line,$cont,$iname,$key); @arr = split(/\n/,$txt); $key = get_unique_key($mast_iname); $iname = ${$rmh}{$key}; # stored ONLY in master HASH foreach $line (@arr) { if ($line =~ /\s*const\s+AVCodecTag\s*\*\s*const\s*\[\]\s*\)\s*\{(.+)\}\s*,/) { $cont = $1; my_exit(1, "NEED FIX of [$iname] for [$cont]!\n" ); } } } sub get_struct_inst_stg($$) { my ($feat_in,$rmh) = @_; my ($msg, $imax, $ccnt, $rh, $k1, $k2, $len, $pcnt, $pos, $f, $kd, $feat, $nuniq); $imax = 0; $pcnt = 0; my %hposn = (); my @aposn = (); $len = get_total_blocks($rmh); $imax = get_copied_count($rmh); $k2 = $str_off; $kd = $str_done; $feat = $feat_in; $feat |= $FF_WNUM if ($len > 0); # we HAVE a fixed NUMBER to do $nuniq = 0; $msg = ''; foreach $k1 (keys %{$rmh}) { # skip unique keys in master if ( !key_is_unique_type($k1)) { # like say $k =~ /^\@_/, or ... $rh = ${$rmh}{$k1}; ${$rh}{$kd} = 0; # mark as NOT done if ($k1 =~ /^$mem_bgn/) { # ONLY check 'member' keys if (defined ${$rh}{$k2}) { $pos = ${$rh}{$k2}; if ($pos >= 0) { $pcnt++; $hposn{$pos} = $k1; push(@aposn,[ $pos, $k1 ]); $feat |= $FF_WPOS; # at least ONE member with BLOCK position } } } $nuniq++; # count not unique members in master $msg .= ' ' if length($msg); $msg .= $k1; } } prt( "[dbg29] Get struct instance string - total=$len, not-unique=$nuniq, blk/pos=$pcnt copied=$imax\n" ) if ($dbg29); prt( "[dbg30] Keys:[$msg]\n") if ($dbg30); if (scalar keys(%hposn) != $pcnt) { prtw("WARNING: Some position values are repeated! Generation may NOT be SANE!\n"); } # start of MESSAGE returned # ========================= $msg = ''; $msg .= "#ifdef _MSC_VER /* until MSVC supports dot(.) aligned members, etc */\n" if ($feat & $FF_MSCV); $ccnt = 0; # start block counter if ($pcnt > 0) { $imax = $len if ($len > $imax); while( $ccnt < $len ) { $f = $feat; # reset FEATURES if ( !find_block_at( $ccnt, $rmh, \$rh ) ) { $f |= $FF_BLAN; } $ccnt++; $msg .= get_hash_instance2($f, $imax, $ccnt, $rh, $rmh); if ( !( $f & $FF_BLAN ) ) { # if NOT a BLANK ${$rh}{$kd} = 1; # MARK AS DONE } } } else { # no block has a specified position - use decoded position foreach $k1 (sort keys %{$rmh}) { if (!key_is_unique_type($k1)) { # like say $k =~ /^\@_/, or ... if ($k1 =~ /^$mem_bgn/) { # ONLY check 'member' keys $rh = ${$rmh}{$k1}; $ccnt++; $msg .= get_hash_instance2($feat, $imax, $ccnt, $rh, $rmh); } } } $f = $feat | $FF_BLAN; while ($ccnt < $len) { $ccnt++; $msg .= get_hash_instance2($f, $imax, $ccnt, $rh, $rmh); } } $msg .= "#else /* !_MSC_VER */\n#endif /* _MSC_VER y/n */\n" if ($feat & $FF_MSCV); if ($ccnt < $len) { $msg .= "// WARNING: Still to generate ".($len - $ccnt)." BLANK blocks\n"; prtw( "WARNING: Still to generate ".($len - $ccnt)." BLANK blocks\n" ); } # no, should be done during fetch # $msg = extract_avcodectag($msg,$rh,$rmh) if ($feat & $FF_MSC2); return $msg; } sub show_full_hash_of_hashes($) { my ($rfh) = shift; my ($k1, $rh, $k2, $v2, @ar, $ct); $ct = scalar keys(%$rfh); prt( "\nShowing full information on $ct keys...\n" ); $ct = 0; foreach $k1 (sort keys %$rfh) { $ct++; if (key_is_unique_type($k1)) { $v2 = ${$rfh}{$k1}; prt( "MK:$ct: Unique key [$k1] = value [$v2]\n" ); } else { prt( "MK:$ct: Showing $k1 hash... \n" ); $rh = ${$rfh}{$k1}; # extract REFERENCE #prt( Dumper($rh) ); show_struct_hash(1, $rh); } } prt( "Done full information show of $ct keys...\n" ); } sub process_comment($$$$$) { my ($onc,$i,$len,$stg,$rlnn) = @_; my ($comm, $nc, $cc, $pc); $comm = '/'; $comm .= $onc; $i += 2; $cc = $onc; for (; $i < $len; $i++) { $pc = $cc; $cc = substr($stg,$i,1); $nc = (($i + 1) < $len) ? substr($stg,$i+1,1) : " "; if ($onc eq '/') { if ($cc eq "\n") { $i--; last; } $comm .= $cc; } else { $comm .= $cc; $$rlnn++ if ($cc eq "\n"); if (($cc eq '/')&&($pc eq '*')) { last; } } } prt( "[dbg11] Discarded comment [$comm]\n" ) if ($dbg11); return $i; } sub do_br_stack($$$) { my ($cc, $ln, $rbr) = @_; my ($lv); if ($cc eq '{') { push(@{$rbr},$ln); $lv = scalar @{$rbr}; prt( "[dbg12] $ln: Brace stack increased to $lv...\n" ) if ($dbg12); } elsif ($cc eq '}') { if (@{$rbr}) { pop @{$rbr}; $lv = scalar @{$rbr}; prt( "[dbg12] $ln: Brace stack decreased to $lv...\n" ) if ($dbg12); } else { prtw("WARNING: Found $cc, BUT NO STACK!\n"); } } } sub deal_with_enum_line($$$$$) { my ($lvl, $ln, $lnn, $rh, $rnxt) = @_; my ($msg, $len, $itm, $val, $key, $cnt); $len = length($ln); if ($len) { $msg = sprintf("%4d",$lnn); prt( "[dbg13] $msg:$lvl: [$ln]\n" ) if ($dbg13); if ($lvl == 0) { if ($ln =~ /^\w+$/) { $key = get_unique_key($str_tag); # something like "\@_".$str_tag."_\@", or... ${$rh}{$key} = $ln; } else { if ($ln eq '{') { prt( "$lnn:$lvl: Enumeration OPENED on [$ln] line...\n" ); } elsif ($ln eq '};') { $cnt = scalar keys(%{$rh}); prt( "$lnn:$lvl: Enumeration CLOSED with $cnt keys on [$ln] line.\n" ); } elsif ($ln =~ /^}\s*(\w*)\s*;$/) { if (defined $1) { $val = $1; $key = get_unique_key($str_nam); # like say "\@_".$str_nam."_\@", or... ${$rh}{$key} = $val; $cnt = scalar keys(%{$rh}); prt( "$lnn:$lvl: Enumeration CLOSED, with name=[$val] - $cnt keys\n" ); } else { $cnt = scalar keys(%{$rh}); prt( "$lnn:$lvl: Enumeration CLOSED - no name - $cnt keys\n" ); } } else { prtw( "WARNING: $lnn:$lvl: Unknown level 0 item [$ln]\n" ); } } } else { $ln =~ s/,$//; # lose the comma ending, if any if ($ln =~ /^\s*\{\s*$/) { prt( "$lnn:$lvl: Enumeration OPENED with [$ln] line.\n" ); } elsif ($ln =~ /.+=.+/) { my @a = split('=',$ln); if (scalar @a == 2) { $itm = trim_all($a[0]); $val = trim_all($a[1]); ${$rh}{$itm} = $val; $val++; $$rnxt = $val; } else { prtw( "WARNING: $lnn:$lvl: Split NOT 2 [$ln]\n" ); } } else { $itm = $ln; $val = $$rnxt; ${$rh}{$itm} = $val; $$rnxt++; } } } } sub show_enum_hash($$) { my ($flag,$rh) = @_; my ($k, $v, $min, $max, $msg, $nxt, $lmin, $len, $tmp, $cnt, $in, $iv, $iind, $mcnt); my ($rmsg, $line); $min = 9999999999999999999; $max = -1; $lmin = 0; $iind = $memb_indent; $cnt = scalar keys(%{$rh}); prt( "Show of 'enum' hash... flag = $flag\n" ) if ($flag); $mcnt = 0; $msg = ''; foreach $k (keys %{$rh}) { $v = ${$rh}{$k}; if (key_is_unique_type($k)) { # like say $k =~ /^\@_/, or ... prt("$k = $v\n") if ($flag & 1); } else { $len = length($k); $lmin = $len if ($len > $lmin); $min = $v if ($v < $min); $max = $v if ($v > $max); $mcnt++; } } prt( "Enum min=[$min], max=[$max]\n" ) if ($flag & 1); my %h; foreach $k (keys %{$rh}) { $v = ${$rh}{$k}; if ( !key_is_unique_type($k) ) { # like say $k =~ /^\@_/ $tmp = "$k"; $tmp .= ' ' while (length($tmp) < $lmin); prt("$tmp = $v\n") if ($flag & 2); # establish ORDERED hash key $msg = sprintf("member%08d", $v); $h{$msg} = ["$tmp = $v", $k, $v]; } } # OUTPUT the ENUMERATIONS, as coded ###################################### $k = get_unique_key($str_tag); # get say "\@_".$str_tag."_\@" prt( "enum" ) if ($flag); $rmsg = 'enum'; if (defined ${$rh}{$k}) { prt( " ".${$rh}{$k} ) if ($flag); $rmsg .= ' '; $rmsg .= ${$rh}{$k}; } prt( " {\n" ) if ($flag); $rmsg .= " {\n"; $nxt = 0; $cnt = $mcnt; foreach $k (sort keys %h) { $v = $h{$k}[0]; $in = $h{$k}[1]; $iv = $h{$k}[2]; $cnt-- if ($cnt); $line = $iind."$in"; if ($iv != $nxt) { $nxt = $iv; $line .= " = $nxt"; } $line .= "," if ($cnt); $line .= "\n"; if ($flag & 2) { #prt("$k = $v\n"); prt("$v\n"); } else { prt("$line") if ($flag); } $rmsg .= $line; $nxt++; } prt( "}" ) if ($flag); $rmsg .= "}"; $k = get_unique_key($str_nam); # like say "\@_".$str_nam."_\@", or ... if (defined ${$rh}{$k}) { prt( ${$rh}{$k} ) if ($flag); $rmsg .= ${$rh}{$k}; } prt( ";\n" ) if ($flag); $rmsg .= ";\n"; ###################################### prt( "Done show of 'enum' hash... flag = $flag\n" ) if ($flag); return $rmsg; } sub get_hash_ref_enum($) { # =($enum_pixfmt); my ($stg) = shift; my ($len, $i, $pc, $cc, $nc, $word, $line, $comm, $lnn, $msg, $lvl, $nxt); my %h = (); $len = length($stg); if ($len == 0) { prt("No 'enum' details...\n"); return \%h; } prt("Decoding $len chars for an enum...\n"); my @brstk = (); $cc = ''; $word = ''; $line = ''; $lnn = 1; $lvl = 0; $nxt = 0; for ($i = 0; $i < $len; $i++) { $pc = $cc; $cc = substr($stg,$i,1); if (($cc eq '{')||($cc eq '}')) { if ($cc eq '}') { do_br_stack($cc,$lnn,\@brstk); $lvl = scalar @brstk; prt( "[dbg12] $lnn: Brace stack = $lvl\n" ) if ($dbg12); } deal_with_enum_line($lvl,$line,$lnn,\%h,\$nxt); $line = ''; if ($cc eq '{') { do_br_stack($cc,$lnn,\@brstk); $lvl = scalar @brstk; prt( "[dbg12] $lnn: Brace stack = $lvl\n" ) if ($dbg12); } } $nc = (($i + 1) < $len) ? substr($stg,$i+1,1) : " "; $lnn++ if ($cc eq "\n"); if (($cc eq '/')&&($nc eq '*')) { # entered comment /*...*/ - stay until END $i = process_comment($nc,$i,$len,$stg,\$lnn); next; } if (($cc eq '/')&&($nc eq '/')) { # entered comment // - stay until END OF LINE $i = process_comment($nc,$i,$len,$stg,\$lnn); next; } next if ($cc =~ /\s/); # start of a word, on a line $word = $cc; $i++; for (; $i < $len; $i++) { $pc = $cc; $cc = substr($stg,$i,1); if (($cc eq '{')||($cc eq '}')) { if ($cc eq '}') { do_br_stack($cc,$lnn,\@brstk); $lvl = scalar @brstk; prt( "[dbg12] $lnn: Brace stack = $lvl\n" ) if ($dbg12); } deal_with_enum_line($lvl,$line,$lnn,\%h,\$nxt); $line = ''; if ($cc eq '{') { do_br_stack($cc,$lnn,\@brstk); $lvl = scalar @brstk; prt( "[dbg12] $lnn: Brace stack = $lvl\n" ) if ($dbg12); } } $nc = (($i + 1) < $len) ? substr($stg,$i+1,1) : " "; if ($cc =~ /\s/) { last; } $word .= $cc; } if ($word eq 'enum') { last; } } if ($i >= $len) { prtw( "WARNING: FAILED to find 'enum' before end...\n" ); return \%h; } prt( "Found enum... after $i chars\n" ); for (; $i < $len; $i++) { $pc = $cc; $cc = substr($stg,$i,1); if ($cc eq "\n") { deal_with_enum_line($lvl,$line,$lnn,\%h,\$nxt); $line = ''; } if (($cc eq '{')||($cc eq '}')) { if ($cc eq '}') { do_br_stack($cc,$lnn,\@brstk); $lvl = scalar @brstk; prt( "[dbg12] $lnn: Brace stack = $lvl\n" ) if ($dbg12); } deal_with_enum_line($lvl,$line,$lnn,\%h,\$nxt); $line = ''; if ($cc eq '{') { do_br_stack($cc,$lnn,\@brstk); $lvl = scalar @brstk; prt( "[dbg12] $lnn: Brace stack = $lvl\n" ) if ($dbg12); } } $lnn++ if ($cc eq "\n"); $nc = (($i + 1) < $len) ? substr($stg,$i+1,1) : " "; if (($cc eq '/')&&($nc eq '*')) { # entered comment /*...*/ - stay until END $i = process_comment($nc,$i,$len,$stg,\$lnn); next; } if (($cc eq '/')&&($nc eq '/')) { # entered comment // - stay until END OF LINE $i = process_comment($nc,$i,$len,$stg,\$lnn); next; } next if ($cc =~ /\s/); $word = $cc; if ($cc eq '{') { $line .= ' ' if length($line); $line .= $word; $word = ''; deal_with_enum_line($lvl,$line,$lnn,\%h,\$nxt); $line = ''; next; } $i++; # bump, and get to END OF WORD for (; $i < $len; $i++) { $pc = $cc; $cc = substr($stg,$i,1); if (($cc eq '{')||($cc eq '}')) { if ($cc eq '}') { do_br_stack($cc,$lnn,\@brstk); $lvl = scalar @brstk; prt( "[dbg12] $lnn: Brace stack = $lvl\n" ) if ($dbg12); } deal_with_enum_line($lvl,$line,$lnn,\%h,\$nxt); $line = ''; if ($cc eq '{') { do_br_stack($cc,$lnn,\@brstk); $lvl = scalar @brstk; prt( "[dbg12] $lnn: Brace stack = $lvl\n" ) if ($dbg12); } } $nc = (($i + 1) < $len) ? substr($stg,$i+1,1) : " "; if (($cc eq '/')&&($nc eq '*')) { # entered comment /*...*/ - stay until END $i = process_comment($nc,$i,$len,$stg,\$lnn); next; } if (($cc eq '/')&&($nc eq '/')) { # entered comment // - stay until END OF LINE $i = process_comment($nc,$i,$len,$stg,\$lnn); next; } if ($cc =~ /\s/) { last; } $word .= $cc; if (($cc eq ',')||($cc eq '{')) { $line .= ' ' if length($line); $line .= $word; $word = ''; deal_with_enum_line($lvl,$line,$lnn,\%h,\$nxt); $line = ''; } } $line .= ' ' if length($line); $line .= $word; } # get any residual deal_with_enum_line($lvl,$line,$lnn,\%h,\$nxt); #$msg = sprintf("%4d:", $lnn); #prt( "$msg [$line]\n" ) if (length($line)); #$line = ''; if (@brstk) { prtw("WARNING: brace stack NOT closed!\n"); } return \%h; } sub do_struct_conv($$$$$) { my ($feat,$enum,$struct,$inst,$out) = @_; my %master_hash = (); my $rmh = \%master_hash; my $rpf = get_hash_ref_enum($enum); prt("[dbg14]\n***************\n".show_enum_hash(0,$rpf)."***************\n") if ($dbg14); # show_enum_hash(1,$rpf); # close_log($outfile,$load_log); # exit(1); set_debug_on_str_parse() if ($dbg_str_parse); # MAKE building structure VERY NOISY my $ref_h = build_struct_hash($struct); #${$ref_h}{$str_enum} = $rpf; # 'ENUMERATION' ${$rmh}{get_unique_key($str_enum)} = $rpf; # 'ENUMERATION' #show_struct_hash(0, \%h) if ($dbg02); show_struct_hash(0, $ref_h) if ($dbg02); if ($test_only) { test_depth($inst, $ref_h); my_exit(1, "test_only is on\n"); } set_debug_on_fill_str() if ($dbg_fill_action); # make the filling of values VERY NOISY fill_struct_per_gcc(0, $inst, $ref_h, $rmh); show_full_hash_of_hashes( $rmh ) if ($dbg10); my $sstg = get_struct_inst_stg($feat,$rmh); # minimum instance string 'n i={0};' if (length($sstg) < 8) { prtw( "WARNING: Instance string TOO SHORT (".length($sstg).")! No FILE written\n" ); } else { write2file( $sstg, $out); prt( "Written to $out...\n" ); system($out) if ($load_out);; } #prt( "\nShow of HASH, with values...\n" ); #show_struct_hash(1, \%h); #prt( "Done show of contents...\n" ); #write2file( get_hash_instance(\%h), 'tempstruct.txt'); prt( "All done...\n" ); } sub get_master_hoh() { my ($i); my %hash = (); my ($msg,$sav31); $sav31 = $dbg31; # dbg31 can be confusing, if doing a single instance, so OFF it $dbg31 = 0 if ( !$do_multi_sets ); for ($i = 1; $i <= $test_max; $i++) { # prt( "Loading test $i...\n" ); my $sd = set_test_strings($i); # set the appropriate strings my $rh = build_struct_hash($struct_details); ###my $rh = build_struct_hash($sd); my $key = $str_nam; # 'NAME' if (defined $$rh{$key}) { my $val = $$rh{$key}; #$msg = show_struct_hash(2, $rh); #prt("$msg"); if (defined $hash{$val}) { prtw("WARNING: Loading $i test - Already got def for [$val]...\n"); } else { $hash{$val} = { %{$rh} }; } } else { prtw("WARNING: failed to get NAME [$key] for test $i...\n"); } } $dbg31 = $sav31; return \%hash; } sub get_master_hoh2() { my ($i); my %hash2 = (); my ($msg,$sav31); $sav31 = $dbg31; # dbg31 can be confusing, if doing a single instance, so OFF it $dbg31 = 0 if ( !$do_multi_sets ); for ($i = 1; $i <= $test_max; $i++) { # prt( "Loading test $i...\n" ); my $sd = set_test_strings($i); # set the appropriate strings my $rh = build_struct_hash($struct_details); ###my $rh = build_struct_hash($sd); my $key = $str_nam; # 'NAME' if (defined $$rh{$key}) { my $val = $$rh{$key}; #$msg = show_struct_hash(2, $rh); #prt("$msg"); if (defined $hash2{$val}) { prtw("WARNING:2: Already got def for [$val]...\n"); } else { $hash2{$val} = { %{$rh} }; } } else { prtw("WARNING: failed to get NAME [$key] for test $i...\n"); } } $dbg31 = $sav31; return \%hash2; } sub show_str_hash($) { my ($rsh) = shift; my ($k,$rv,$m,$c); $c = scalar keys(%{$rsh}); if ($dbg24) { prt( "\n[dbg24] Display of $c structures loaded...\n" ); } else { prt( "Display of $c structures loaded...\n" ); } foreach $k (sort keys %{$rsh}) { $rv = ${$rsh}{$k}; $m = show_struct_hash(2, $rv); prt("$m\n"); } prt( "Done $c structures loaded...\n" ); } sub get_loaded_names_array_ref($) { my ($rsh) = shift; my @name = (); my ($k, $rv, $nm); foreach $k (sort keys %{$rsh}) { $rv = ${$rsh}{$k}; $nm = 'Unknown'; if (defined ${$rv}{$str_nam}) { $nm = ${$rv}{$str_nam}; $nm =~ s/;$//; } push(@name,$nm); } return \@name; } # do we have this STRUCTURE defined in the hash of hashes? sub word_is_rh_name_2($$$) { my ($wd,$rhoh,$rrh) = @_; my ($msg, $k); prt( "check word [$wd] is in HoH! " ); if (defined ${$rhoh}{$wd}) { ${$rrh} = ${$rhoh}{$wd}; $act_href = ${$rhoh}{$wd}; prt( "OK rh2 should be set!\n" ); return 1; } prt( " NO\n" ); show_struc_defines( 2, $rhoh, $wd ); return 0; } # is it something like # 'static const DVprofile dv_profiles[] = {' # But at this point do NOT know which structure is being defined # ???????? dv_profile = { sub is_instance_definition_2($$$$) { my ($ln,$rhoh,$rmh,$rrh2) = @_; my ($len, $i, $cc, $word, $line, @arr, $sname, $iname, $al, $msg, $isize, $snum, $key, $stage); $len = length($ln); #@arr = split(/\s/,$ln); @arr = instance_space_split($ln); $al = scalar @arr; $line = ''; $iname = ''; $sname = ''; $snum = ''; $stage = 0; $isize = $bad_posn; # = -200; if ($dbg22) { prt("[dbg22] Doing is id - split $al...\n"); for ($i = 0; $i < $al; $i++) { $word = $arr[$i]; prt( "".($i + 1)." $word\n" ); } } if ( !($ln =~ /=\s*\{$/) ) { prt( "[dbg16] Line [$ln] is NOT instance definition...\n" ) if ($dbg16); return 0; } prt( "Line [$ln] looks like an instance definition 2...\n" ); for ($i = 0; $i < $al; $i++) { $word = $arr[$i]; next if ($word eq '}'); $msg = "Checking [$word] "; # skip over these words if ( word_in_array($word, \@res_words) ) { $line .= ' ' if (length($line)); $line .= $word; prt( "[dbg16] $msg - it is in res_words array\n" ) if ($dbg16); next; } # if got structure name, and instance name if (length($sname) && length($iname)) { next if ($word eq '='); next if ($word eq '{'); next if (($word eq '};')||($word =~ /}\s*;/)); next if ($word eq '}'); } # check if it is the structure name... if ( !length($sname) && word_is_rh_name_2($word,$rhoh,$rrh2) ) { $rrh2 = $act_href; $sname = $word; $stage++; prt( "[dbg16] $msg - it is the struct name\n" ) if ($dbg16); next; } # must have structure NAME first # 20090829 - change in special space split ensures this SHOULD be the 'instance' name # this will FAIL on 'anonymous' structure if (length($sname) && !length($iname) ) { $iname = $word; $stage++; prt( "[dbg16] $msg - assumed instance name...\n" ) if ($dbg16); next; } #if ($word =~ /^[\w\[\]]$/ ) { #if ($word =~ /^\w+[\[\]\w]*$/) { #if (length($sname) && ($word =~ /^\w+\s*\[(\w*)\]$/)) #if (length($sname) && ($word =~ /^\w+\s*(\[(\w*)\])?$/)) #if (length($sname) && ($word =~ /^\w*\s*(\[(\w*)\])?$/)) { # 20090829 - allow no 'alphanums' before [...] if ( ($stage >= 2) && ($word =~ /^\[\s*(\w*)\s*\]$/) ) { # 20090829 - in fact new special split separates [...] if (defined $1) { $snum = $1; $snum =~ s/^\[//; $snum =~ s/\]$//; # 20090827 - clear any space $snum = trim_ends($snum); # $snum = substr($snum,1) while ($snum =~ /^\s/); # clear leading # $snum = substr($snum,0,length($snum)-1) while ($snum =~ /\s$/); # and trailing if (length($snum)) { prt("[dbg21] Got length [$snum](".length($snum).") - decode or lookup in enum...\n") if ($dbg21); if ($snum =~ /^\d+$/) { # is a whole number $isize = $snum; } else { # assume alphanumeric # $str_enum = 'ENUMERATION'; #if (defined ${$rh}{$str_enum}) { # my $reh = ${$rh}{$str_enum}; $key = get_unique_key($str_enum); if (defined ${$rmh}{$key}) { my $reh = ${$rmh}{$key}; foreach my $k (keys %{$reh}) { if ($k eq $snum) { $isize = ${$reh}{$k}; last; } } prtw("WARNING: $msg - found [$key], checked [$snum], but isize=[$isize]!\n") if ($isize < 0); #prtw("WARNING: $msg - found [$str_enum], but isize=[$isize]!\n") if ($isize < 0); } else { prtw( "WARNING: $msg gave [$snum] as size, but no [$str_enum] in ref hash!\n" ); } } } next; } #prt( "[dbg16] $msg - assumed instance name... num=[$snum], if any\n" ) if ($dbg16); #if (length($iname)) { # prtw( "WARNING: $msg - Already HAVE iname=[$iname]!\n" ); #} else { # $iname = $word; #} next; } # must have structure name, and instance name if (length($sname) && length($iname)) { next if ($word eq '='); next if ($word eq '{'); next if (($word eq '};')||($word =~ /}\s*;/)); next if ($word eq '}'); } prtw( "WARNING: $msg - NOT PARSED in is_instance_definition! 2\n" ); my_exit(1, "is_instance_definition_2: line=[$ln]\n" ); } if (length($sname) && length($iname)) { # put entries decoded in the MASTER HASH # ${$rh}{$str_inst} = $iname; $key = get_unique_key($mast_iname); ${$rmh}{$key} = $iname; # store ONLY in master HASH #${$rh}{$str_inst} = $ln; $key = get_unique_key($mast_inst); ${$rmh}{$key} = $ln; # store ONLY in master HASH #${$rh}{$str_len} = $isize if ($isize > 0); if ($isize > 0) { $key = get_unique_key($mast_len); ${$rmh}{$key} = $isize; # AND the SIZE of the structure, if ANY... } return 1; } return 0; } sub add_line_2_hash_2($$$$$$$) { my ($rfsflag, $lvl, $lnn, $ln, $rhoh, $rmh, $rrh2) = @_; my $wn = "WARNING:$lnn:$lvl:"; my ($key, $off, $equ); $ln = trim_ends($ln); prt("[dbg20] Add [$ln] to hash...(fsflag=$$rfsflag)\n") if ($dbg20); if ($$rfsflag & $F_HADEND) { prtw("wn: add line called after structure CLOSED\n"); return; } elsif ($$rfsflag & $F_HADID) { ###if ($ln =~ /^\.(.+)=(.+)/) { if ($ln =~ /^\.\w{1}(.+)=(.+)/) { # begins with a dot entries... my @a = split('=',$ln); my $ca = scalar @a; if ($ca != 2) { prtw("$wn Split FAILED on [$ln]!\n"); } else { # got two elements $$rfsflag |= $F_HADDOT; $off = trim_all($a[0]); $equ = trim_all($a[1]); if ($off =~ /^\./) { $off = substr($off,1); $equ =~ s/,$//; $rrh2 = $act_href; $key = offset_in_hash($off,$rrh2); if (length($key)) { # success $$rrh2{$key}[$O_DEC] = "$ln"; $$rrh2{$key}[$O_VAL] = "$equ"; prt( "[dbg07] Added [$equ] to key [$key], for off[$off]\n" ) if ($dbg07); ${$rfsflag} |= $F_HADMEM; } else { prtw( "$wn NO FIND split 2[$off] = [$equ] NOT HANDLED! line[$ln] (4)\n" ); $key = get_struc_mem_names($rrh2); prtw( "list=[$key]\n" ); } } else { prtw( "$wn CHECK split [$off] = [$equ] NOT HANDLED! (5)\n" ); } } } else { # ========================================================================== # NOT a .abc=def, entry if ($ln eq '{') { prt( "[dbg18] $lnn:$lvl: Open new BLOCK... on [$ln]\n") if ($dbg18); } elsif ($lvl == 0) { if ($ln =~ /}\s*;/) { prt( "$lnn:$lvl: End of definitions 2... on [$ln]\n"); $$rfsflag |= $F_HADEND; # signal END of structure } else { prtw( "$wn line[$ln] NOT HANDLED! (1)\n" ); } } elsif ($lvl == 1) { if ($ln =~ /}\s*,/) { prt( "[dbg18] $lnn:$lvl: End of BLOCK... on [$ln]\n") if ($dbg18); } elsif ($ln eq '}') { # what is this??? but skip it anyway } else { #if (!($$rfsflag & $F_HADDOT) && ($ln =~ /,$/)) { # 20090903 - found a case where a space was added if (!($$rfsflag & $F_HADDOT) && ($ln =~ /,$/)) { # assume a member VALUE $ln =~ s/,$//; # clear the comma $rrh2 = $act_href; $off = ${$rrh2}{$mem_nxt}; # get next member counter $off++; # bump to NEXT ${$rrh2}{$mem_nxt} = $off; $key = sprintf("%s%04d",$mem_bgn,$off); # member and number ${$rrh2}{$key}[$O_VAL] = $ln; prt( "[dbg18|20|07] $lnn:$lvl: Set member 2 [$key] value to [$ln]\n") if ($dbg18 | $dbg20 | $dbg07); ${$rfsflag} |= $F_HADMEM; } else { prtw( "$wn line[$ln] NOT HANDLED 2! (2)\n" ); if ($$rfsflag & $F_HADDOT) { prt( "Had a DOT member!\n" ); } if (!($ln =~ /,$/)) { prt( "Line does NOT end in comma!\n" ); } my_exit(1, "add_line_2_hash_2: FIXME!\n"); } } } else { # handle things like - '[PIX_FMT_YUV420P] = {' if ($ln =~ /^\[(\w+)\]/) { $off = $1; prt( "[dbg19] $lnn:$lvl: [$ln] as offset [$off]\n") if ($dbg19); # $str_enum = 'ENUMERATION'; my $num = $bad_posn; #-200; my $key = get_unique_key($str_enum); if (defined ${$rmh}{$key}) { my $reh = ${$rmh}{$key}; foreach my $k (keys %{$reh}) { if ($k eq $off) { $num = ${$reh}{$k}; last; } } prt( "[dbg19] $lnn:$lvl: [$off] has val [$num]\n") if ($dbg19); # $copy_hash{$str_off} = $blknum; # OFFSET = order of this block (-1 = no order)!!! $key = $str_off; if ($num != $bad_posn) { ${$rrh2}{$key} = $num; # $bad_posn (was -200) is NO NUMBER, else a value given } } else { prtw( "$wn NO ENUMERATION rh! to solve $off\n" ); } } else { prtw( "$wn line[$ln] NOT HANDLED! (3)\n" ); } } } } else { if ( is_instance_definition_2($ln,$rhoh,$rmh,$rrh2) ) { ${$rrh2} = $act_href; $key = get_unique_key($mast_inst); $equ = ${$rmh}{$key}; prt( "$lnn:$lvl: Set Mast.Inst[$key]=[$equ]\n" ); $key = get_unique_key($mast_len); if (defined ${$rmh}{$key}) { $off = ${$rmh}{$key}; prt( "$lnn:$lvl: Set Mast.Leng[$key]=[$off]\n" ); } else { $off = $bad_posn; } $$rfsflag |= $F_HADID; # had ID } } prt("[dbg20] Done [$ln] to hash...(fsflag=$$rfsflag)\n") if ($dbg20); } ## comments /* ... */, or // to end of line ##sub fill_struct_per_gcc($$) { # like ($gcc_struct, \%h); ## my ($gcc, $rh) = @_; sub fill_struct_per_gcc_2($$$$) { # like ($gcc_struct, \%h); my ($flg, $gcc, $rhoh, $rmh) = @_; my ($i, $len, $pc, $cc, $nc, $ic1, $ic2, $lnn); my ($bclvl, $bklvl, $line, $msg, $comm, $inst, $blknum, $cnt); my ($k, $v); my $depth = 0; $gcc = reline_instance_string(\$depth, $gcc); # remove some spaces... my @brcstk = (); my @brkstk = (); my @depitems = (); my $flag = 0; my ($rh2); ## this is the structure HASH, when found! $len = $depth; if ($len == 0) { prt("CRITICAL ERROR: Got NO DEPTH!\n"); exit 1; } push(@depitems, [ 0, 0, 0 ]); # add one extra while ($len) { push(@depitems, [ 0, 0, 0 ]); $len--; } $ic1 = 0; $ic2 = 0; $lnn = 1; $inst = 0; # expect mutiple instances $len = length($gcc); $bclvl = 0; $bklvl = 0; $blknum = -1; # order per as found prt( "Processing fill struct 2, $len chars, depth = $depth...\n" ); for ($i = 0; $i < $len; $i++) { $cc = substr($gcc,$i,1); $nc = (($i + 1) < $len) ? substr($gcc,$i+1,1) : " "; if ($cc eq "\n") { if (length($line)) { $msg = sprintf("%3d: ", $lnn); $msg .= $line; prt( "[dbg08] $msg\n" ) if ($dbg08); ###add_line_2_hash($bclvl, $lnn, $line, $rh, \%mh); add_line_2_hash_2(\$flag, $bclvl, $lnn, $line, $rhoh, $rmh, \$rh2); $line = ''; } $lnn++; #if ($lnn == 2) { exit(1); } if ($ic2) { $msg = sprintf("%3d: ", $lnn); $msg .= "Discard: [$comm]"; prt( "[dbg06] $msg\n" ) if ($dbg06); } $ic2 = 0; $pc = $cc; next; } if ($ic1) { # locked in comment - stay to END $comm .= $cc; if (($cc eq '/') && ($pc eq '*')) { $ic1 = 0; # end of comment $msg = sprintf("%3d: ", $lnn); $msg .= "Discard: [$comm]"; prt( "[dbg05] $msg\n" ) if ($dbg05); } } elsif ($ic2) { # locked in comment - stay to end of line $comm .= $cc; } else { if (($cc eq '/') && ($nc eq '*')){ $ic1 = 1; # process a comment $comm = $cc; # start $pc = $cc; # update previous char next; } if (($cc eq '/') && ($nc eq '/')){ $ic2 = 1; # start comment, until EOL $comm = $cc; # start comment $pc = $cc; # update prev char next; } ##################################################################### $line .= $cc; # ADD to line if ($cc eq '{') { push(@brcstk,[$i, $lnn] ); $bclvl++; # clear depth flags $depitems[$bclvl][0] = 0; $depitems[$bclvl][1] = 0; $depitems[$bclvl][2] = 0; } elsif ($cc eq '}') { if (@brcstk) { # show depth items prt( "[dbg09] $bclvl: equ=[".$depitems[$bclvl][0]."], coma=[".$depitems[$bclvl][1]."] dot [".$depitems[$bclvl][2]."]\n" ) if ($dbg09); if (($depitems[$bclvl][0] > 0)&&($depitems[$bclvl][2] > 0)) { # we have a completed instance - COPY, and SAVE TO master HASH # ============================================================ # At this time this hash copy is in the ORDER found, # but by using the [OFF_NUM] = { notation, this could be # set at a specific block number (in ascii, but could probably use number?) my %copy_hash = (); $cnt = scalar keys(%{$rh2}); prt( "Copying $cnt keys of block hash...\n" ); $msg = sprintf("$mem_bgn%08d", $inst); $inst++; foreach $k (keys %{$rh2}) { $v = $$rh2{$k}; if ($k =~ /^$mem_bgn/) { # member $copy_hash{$k} = [@{$v}]; # store COPY of ARRAY } else { $copy_hash{$k} = $v; # store string, or hash-ref, or value, or ... } } # clear the current HASH values ${$rmh}{$msg} = \%copy_hash; # THIS SEEMS TO WORK ;=)) clear_hash_values($rh2); # ready for NEXT $flag &= ~$F_HADMEM; # now copied, so remove bit bump_master_copied($rmh); } pop @brcstk; } else { prtw("$lnn:$i: WARNING: Encountered $cc, with no stack!\n"); } $bclvl-- if ($bclvl); } elsif ($cc eq '(') { push(@brkstk, [$i, $lnn] ); $bklvl++; } elsif ($cc eq ')') { if (@brkstk) { pop @brkstk; } else { prtw("$lnn:$i: WARNING: Encountered $cc, with no stack!\n"); } $bklvl-- if ($bklvl); } elsif ($cc eq '=') { $depitems[$bclvl][0]++; } elsif ($cc eq ',') { $depitems[$bclvl][1]++; } elsif (($cc eq '.') && ($nc =~ /\w/)) { $depitems[$bclvl][2]++; } } $pc = $cc; } if (@brcstk) { prtw( "WARNING: ".scalar @brcstk." items in brace stack!\n" ); } if (@brkstk) { prtw( "WARNING: ".scalar @brkstk." items in bracket stack!\n" ); } if ($flag & $F_HADMEM) { # not yet COPIED my %copy_hash = (); $cnt = scalar keys(%{$rh2}); prt( "Copying $cnt keys of block hash...\n" ); $msg = sprintf("$mem_bgn%08d", $inst); $inst++; foreach $k (keys %{$rh2}) { $v = $$rh2{$k}; if ($k =~ /^$mem_bgn/) { # member $copy_hash{$k} = [@{$v}]; # store COPY of ARRAY } else { $copy_hash{$k} = $v; # store string, or hash-ref, or value, or ... } } # clear the current HASH values ${$rmh}{$msg} = \%copy_hash; # THIS SEEMS TO WORK ;=)) clear_hash_values($rh2); # ready for NEXT $flag &= ~$F_HADMEM; # now copied, so remove bit bump_master_copied($rmh); } $ic1 = 0; $ic2 = 0; foreach $k (keys %{$rmh}) { $ic1++; if (!key_is_unique_type($k)) { $ic2++; } } $k = get_total_blocks($rmh); if ($k > 0) { $cc = "total = $k"; } else { $cc = "with no total blocks"; } prt("Done fill struct, with $ic1 members, $ic2 blocks, $cc...\n" ); ##return \%mh; return $rmh; } sub process_in_file($$$$) { my ($feat, $inf, $rsh, $out) = @_; my (@lines, $gcc, $tmp); my %master_hash = (); my $rmh = \%master_hash; if (open INF, "<$inf") { @lines = <INF>; close INF; $gcc = join("\n",@lines); $gcc .= "\n"; set_debug_on_fill_str() if ($dbg_fill_action); # make the filling of values VERY NOISY my $mh = fill_struct_per_gcc_2(0, $gcc,$rsh,$rmh); show_full_hash_of_hashes( $mh ) if ($dbg10); my $sstg = get_struct_inst_stg($feat,$rmh); # minimum instance string 'n i={0};' if (length($sstg) < 8) { prtw( "WARNING: Instance string TOO SHORT (".length($sstg).")! No FILE written\n" ); } else { $tmp = join("",@lines); $tmp .= "\n" if ($tmp =~ /\n$/); $tmp .= $sstg; add_to_done_file($tmp); write2file( $sstg, $out); prt( "Written to $out...\n" ); system($out) if ($load_out);; } } else { prt("ERROR: can not open file [$inf]...\n" ); } } sub output_null_set() { my ($rsh, $rarr, $nm, $txt, $rh, $k, $sstg); my ($k1,$ccnt,$inst,$f, $key); my $ocnt = 0; # load of ALL structures $rsh = get_master_hoh(); ##show_str_hash($rsh); $rarr = get_loaded_names_array_ref($rsh); prt("Names: cnt=".(scalar @{$rarr}).", [".join(" ",@{$rarr})."]\n"); $inst = 0; $k = get_unique_key($mast_copied); ${$rsh}{$k} = 1; # SET master count to 1 COPIED $f = ($FF_BLAN | $FF_COMM | $FF_COM1 | $FF_COMA); $f = ($FF_BLAN | $FF_COMM | $FF_COM1 | $FF_COMA); $ocnt = 0; foreach $nm (@{$rarr}) { $ocnt++; $txt = "$nm $nm"."_NULL = {"; prt("// $ocnt: Doing: $txt\n"); $key = get_unique_key($mast_inst); # 'INSTANCE' - set in master ${$rsh}{$key} = $txt; if (defined ${$rsh}{$nm}) { $rh = ${$rsh}{$nm}; #prt( "Found it in master...\n" ); #foreach $k (keys %{$rh}) { # prt( "Key: $k\n" ); #} copy_hash_to_master($inst, $rh, $rsh); # $inst++; # overwrite previous - saves clearing $ccnt = 0; if (scalar( @gen_null_for ) > 0) { next if !(word_in_array($nm, \@gen_null_for)); ##$f = $FF_BLAN; # only a BLANK $f = ($FF_BLAN | $FF_COMM | $FF_COMA); } foreach $k1 (sort keys %{$rsh}) { if (!key_is_unique_type($k1)) { # like say $k =~ /^\@_/, or ... if ($k1 =~ /^$mem_bgn/) { # ONLY check 'member' keys $rh = ${$rsh}{$k1}; $ccnt++; $sstg = get_struct_inst_stg($f,$rsh); ### $msg .= get_hash_instance2($feat, $imax, $ccnt, $rh, $rmh); prt( "$sstg\n" ); } } } # prt( "Got $ccnt member count...\n" ); # will always be 1 in this case } else { prtw( "WARNING: [$nm] NOT in master HoH!\n" ); } #exit(1); } my_exit(0,"process_a_file: Clean exit"); } sub process_a_file($$$) { my ($feat,$file,$out) = @_; # load of ALL structures my $rsh = get_master_hoh(); show_str_hash($rsh) if ($dbg24); process_in_file( $feat, $file, $rsh, $out ); my_exit(0,"output_null_set: Clean exit"); } output_null_set() if ($gen_null_set); process_a_file($features, $in_file, $out_file) if ($do_multi_sets); prt( "Doing s SINGLE instance... Test number = $do_test_num (test $do_test_num)\n" ); set_test_strings($do_test_num); # set the appropriate strings do_struct_conv($features, $enum_details, $struct_details, $gcc_struct, $out_file); my_exit(0,"Clean exit"); # eof - convstruct.pl