convstruct.pl to HTML.

index -|- end

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

index -|- top

checked by tidy  Valid HTML 4.01 Transitional