(root)/
libredwg-0.13/
examples/
log_unknown_dxf.pl
#!/usr/bin/perl
=head1 USAGE

    perl examples/log_unknown_dxf.pl examples/alldwg.inc
    make -C examples alldxf_0.inc

    Creates the 3 examples/alldxf_*.inc includes from the examples/alldwg.inc
    parsed from the logs, and mixed with the values from the matching DXF sources.

    In C we cannot statically initialize variable-sized arrays of structs,
    so we split it up into 3 parts.

e.g.

    { "MATERIAL", "004014080405aa6a9aa404014080405aa6a9aa404000000000000e03f4080405aa6a9aa4054080405aa6a9aa4050201016a9aa6a90150201016a9aa6a900aa4fe41d0801e40130018401e4019401c802aaa1803824882e464030dfbfb8", "11", "Drawing_2007.log", "test/test-data/Drawing_2007.dxf", 0x96, 746 },

Search 0 MATERIAL + Handle 96 in test/test-data/Drawing_2007.dxf =>

      0
    MATERIAL
      5
    96
-     1
-   ByLayer
-    94
-          63
=>
    FIELD_T   1  "ByLayer"    => dwg.spec: FIELD_T (name, 1);
    FIELD_BL 94 63  (int32_t) => dwg.spec: FIELD_BL (channel_flags, 94);

calc. number of same-typed: value fields as num.

=cut

use strict;
use File::Basename qw(dirname);

# DXF types
use constant UNKNOWN => 0;
use constant B       => 1;
use constant NUM     => 2; #BL, BS, RL, RS or RC
use constant HDL     => 3;
use constant STR     => 4;
use constant HEXSTR  => 5;
use constant DBL     => 6;
use B ();

#require dirname(__FILE__)."/unstable.pm";
my $dir = dirname(__FILE__);
open my $f0, ">", "$dir/alldxf_0.inc" or die "$!";
open my $f1a, ">", "$dir/alldxf_1.inc" or die "$!";
open my $f2, ">", "$dir/alldxf_2.inc" or die "$!";
my $i = 0;
my (%skip, %dupl);

if (0) {
  open my $skip_fh, "<", "examples/alldwg.skip"
    or warn "examples/alldwg.skip missing";
  while (<$skip_fh>) {
    my @F = split(' ');
    shift @F;
    # NAME-HANDLE-BITSIZE
    $F[2] =~ s/^0x//;
    $skip{"$F[0]-$F[2]-$F[3]"} = \@F;
  }
  close $skip_fh;
}

my @ASSOCACTION_fields = (
    90  => 'class_version',
    90  => 'geometry_status',
    330 => 'owningnetwork',
    360 => 'actionbody',
    90  => 'action_index',
    90  => 'max_assoc_dep_index',
    90  => 'num_deps',
    360 => 'dep',

    # class_version > 1:
    90  => '',                         # 0
    90  => 'num_owned_params',
    360 => 'owned_params',
    90  => '',                         # 0
    90  => 'num_owned_value_params',
    360 => 'owned_value_params',
);

my @AcDbAssocPathBasedSurfaceActionBody = (
    100 => 'AcDbAssocActionBody',
    90  => 'aab_version',
    100 => 'AcDbAssocParamBasedActionBody',
    90  => 'pab_status',
    90  => 'pab_l2',
    90  => 'num_deps',
    360 => 'writedeps',
    90  => 'pab_l4',
    90  => 'pab_l5',
    330 => 'readdeps',
    1   => 'description',
    100 => 'AcDbAssocSurfaceActionBody',
    90  => 'sab_status',
    290 => 'sab_b1',
    90  => 'sab_l2',
    290 => 'sab_b2',
    70  => 'sab_s1',
    100 => 'AcDbAssocPathBasedSurfaceActionBody',
    90  => 'pbsab_status'
);

my @AcDbAssocAnnotationActionBody = (
    100 => 'AcDbAssocActionBody',
    90  => 'aab_version',
    100 => 'AcDbAssocParamBasedActionBody',
    90  => 'pab_status',
    90  => 'pab_l2',
    90  => 'num_deps',
    360 => 'writedeps',
    90  => 'pab_l4',
    90  => 'pab_l5',
    330 => 'readdeps',
    1   => 'description',
    100 => 'AcDbAssocSurfaceActionBody',
    90  => 'sab_status',
    290 => 'sab_b1',
    90  => 'sab_l2',
    290 => 'sab_b2',
    70  => 'sab_s1',
    100 => 'AcDbAssocPathBasedSurfaceActionBody',
    90  => 'pbsab_status'
);

my @AcDbEvalExpr = (
    100 => 'AcDbEvalExpr',
    90  => 'evalexpr.nodeid',
    0   => 'evalexpr.parentid',
    98  => 'evalexpr.major',
    99  => 'evalexpr.minor',
    70  => 'evalexpr.value_code',
    40  => 'evalexpr.value.num40',
    10  => 'evalexpr.value.pt2d',
    11  => 'evalexpr.value.pt3d',
    1   => 'evalexpr.value.text1',
    90  => 'evalexpr.value.long90',
    91  => 'evalexpr.value.handle91',
    70  => 'evalexpr.value.short70'
);

sub trans {
  my ($code, $name, $num) = @_;
  $num = 16 unless $num;
  my @arr;
  for (0 .. $num -1 ) {
    push @arr, ($code, $name. "[$_]");
  }
  return @arr;
}

my @AcDbShHistoryNode = (
  100 => 'AcDbShHistoryNode',
  90    => 'history_node.major',
  91  => 'history_node.minor',
  trans (40, 'history_node.trans'),
  62  => 'history_node.color',
  92  => 'history_node.step_id',
  347 => 'history_node.material'
  );

my @DIMASSOC_Ref = (
  1 => 'DIMASSOC_Ref.classname',
  72 => 'DIMASSOC_Ref.osnap_type',
  331 => 'DIMASSOC_Ref.mainobjs',
  73 => 'DIMASSOC_Ref.main_subent_type',
  91 => 'DIMASSOC_Ref.main_gsmarker',
  301 => 'DIMASSOC_Ref.xrefobj',
  40 => 'DIMASSOC_Ref.osnap_dist',
  10 => 'DIMASSOC_Ref.osnap_pt.x',
  20 => 'DIMASSOC_Ref.osnap_pt.y',
  30 => 'DIMASSOC_Ref.osnap_pt.z',
  75 => 'DIMASSOC_Ref.has_lastpt_ref',
  # rarely:
  332 => 'DIMASSOC_Ref.intsectobj',
  74 => 'DIMASSOC_Ref.intsect_subent_type');

# dxf names, not obj names.
# The name in the all*.inc files.
# which comes from the (?:Unhandled|Unstable) Class (object|entity) \d+ (\w+) warning
# which uses the klass->dxfname.
my $known = {
  ACAD_EVALUATION_GRAPH => [
    96 => 'has_graph',
    97 => 'unknown1',
    91 => 'nodeid',
    93 => 'edge_flags',
    95 => 'num_evalexpr',
    92 => 'node_edge1',
    92 => 'node_edge2',
    92 => 'node_edge3',
    92 => 'node_edge4',
    360 => 'evalexpr'
    ],
  DBCOLOR => [
    62  => 'color',
    420 => 'rgb',
    430 => 'name',
    330 => 'ownerhandle',
    ],
  MATERIAL => [
    330 => 'ownerhandle',
    1 => 'name',
    2 => 'description',
    70 => 'ambient_color.flag',
    40 => 'ambient_color.factor',
    90 => 'ambient_color.rgb',
    71 => 'diffuse_color.flag',
    41 => 'diffuse_color.factor',
    92 => 'diffuse_color.rgb',
    72 => 'diffusemap.source',
    3  => 'diffusemap.filename',
    42 => 'diffusemap.blendfactor',
    73 => 'diffusemap.projection',
    74 => 'diffusemap.tiling',
    75 => 'diffusemap.autotransform',
    trans (43, 'diffusemap.transmatrix'),
    44 => 'specular_gloss_factor',
    76 => 'specular_color.flag',
    45 => 'specular_color.factor',
    92 => 'specular_color.rbg',
    77 => 'specularmap.source',
    4  => 'specularmap.filename',
    46 => 'specularmap.blendfactor',
    78 => 'specularmap.projection',
    74 => 'specularmap.tiling',
    170 => 'specularmap.autotransform',
    trans (47, 'specularmap.transmatrix'),
    171 => 'reflectionmap.source',
    6   => 'reflectionmap.filename',
    48  => 'reflectionmap.blendfactor',
    172 => 'reflectionmap.projection',
    173 => 'reflectionmap.tiling',
    174 => 'reflectionmap.autotransform',
    trans (49, 'reflectionmap.transmatrix'),
    140 => 'opacity_percent',
    175 => 'opacitymap.source',
    7   => 'opacitymap.filename',
    141 => 'opacitymap.blendfactor',
    176 => 'opacitymap.projection',
    177 => 'opacitymap.tiling',
    178 => 'opacitymap.autotransform',
    142 => 'opacitymap.transmatrix[0]',
    142 => 'opacitymap.transmatrix[1]',
    142 => 'opacitymap.transmatrix[2]',
    142 => 'opacitymap.transmatrix[3]',
    142 => 'opacitymap.transmatrix[4]',
    142 => 'opacitymap.transmatrix[5]',
    142 => 'opacitymap.transmatrix[6]',
    142 => 'opacitymap.transmatrix[7]',
    142 => 'opacitymap.transmatrix[8]',
    142 => 'opacitymap.transmatrix[9]',
    142 => 'opacitymap.transmatrix[10]',
    142 => 'opacitymap.transmatrix[11]',
    142 => 'opacitymap.transmatrix[12]',
    142 => 'opacitymap.transmatrix[13]',
    142 => 'opacitymap.transmatrix[14]',
    142 => 'opacitymap.transmatrix[15]',
    179 => 'bumpmap.source',
    8   => 'bumpmap.filename',
    143 => 'bumpmap.blendfactor',
    270 => 'bumpmap.projection',
    271 => 'bumpmap.tiling',
    272 => 'bumpmap.autotransform',
    144 => 'bumpmap.transmatrix[0]',
    144 => 'bumpmap.transmatrix[1]',
    144 => 'bumpmap.transmatrix[2]',
    144 => 'bumpmap.transmatrix[3]',
    144 => 'bumpmap.transmatrix[4]',
    144 => 'bumpmap.transmatrix[5]',
    144 => 'bumpmap.transmatrix[6]',
    144 => 'bumpmap.transmatrix[7]',
    144 => 'bumpmap.transmatrix[8]',
    144 => 'bumpmap.transmatrix[9]',
    144 => 'bumpmap.transmatrix[10]',
    144 => 'bumpmap.transmatrix[11]',
    144 => 'bumpmap.transmatrix[12]',
    144 => 'bumpmap.transmatrix[13]',
    144 => 'bumpmap.transmatrix[14]',
    144 => 'bumpmap.transmatrix[15]',
    145 => 'refraction_index',
    273 => 'refractionmap.source',
    9   => 'refractionmap.filename',
    146 => 'refractionmap.blendfactor',
    274 => 'refractionmap.projection',
    275 => 'refractionmap.tiling',
    276 => 'refractionmap.autotransform',
    147 => 'refractionmap.transmatrix[0]',
    147 => 'refractionmap.transmatrix[1]',
    147 => 'refractionmap.transmatrix[2]',
    147 => 'refractionmap.transmatrix[3]',
    147 => 'refractionmap.transmatrix[4]',
    147 => 'refractionmap.transmatrix[5]',
    147 => 'refractionmap.transmatrix[6]',
    147 => 'refractionmap.transmatrix[7]',
    147 => 'refractionmap.transmatrix[8]',
    147 => 'refractionmap.transmatrix[9]',
    147 => 'refractionmap.transmatrix[10]',
    147 => 'refractionmap.transmatrix[11]',
    147 => 'refractionmap.transmatrix[12]',
    147 => 'refractionmap.transmatrix[13]',
    147 => 'refractionmap.transmatrix[14]',
    147 => 'refractionmap.transmatrix[15]',
    148 => 'translucence',
    149 => 'self_illumination',
    468 => 'reflectivity',
    93 => 'illumination_model',
    94 => 'channel_flags',
    282 => 'mode',

    460 => 'color_bleed_scale',
    461 => 'indirect_bump_scale',
    462 => 'reflectance_scale',
    463 => 'transmittance_scale',
    290 => 'two_sided_material',
    464 => 'luminance',
    #270 => 'luminance_mode',
    #271 => 'normalmap.method',
    #465 => 'normalmap.strength',
    #72 => 'normalmap.source',
    #3   => 'normalmap.filename',
    #42 => 'normalmap.blendfactor',
    #73 => 'normalmap.projection',
    #74 => 'normalmap.tiling',
    #75 => 'normalmap.autotransform',
    #43 => 'normalmap.transmatrix[0]',
    #43 => 'normalmap.transmatrix[1]',
    #43 => 'normalmap.transmatrix[2]',
    #43 => 'normalmap.transmatrix[3]',
    #43 => 'normalmap.transmatrix[4]',
    #43 => 'normalmap.transmatrix[5]',
    #43 => 'normalmap.transmatrix[6]',
    #43 => 'normalmap.transmatrix[7]',
    #43 => 'normalmap.transmatrix[8]',
    #43 => 'normalmap.transmatrix[9]',
    #43 => 'normalmap.transmatrix[10]',
    #43 => 'normalmap.transmatrix[11]',
    #43 => 'normalmap.transmatrix[12]',
    #43 => 'normalmap.transmatrix[13]',
    #43 => 'normalmap.transmatrix[14]',
    #43 => 'normalmap.transmatrix[15]',
    293 => 'is_anonymous',
    272 => 'global_illumination',
    273 => 'final_gather',
    300 => 'genprocname',
    291 => 'genprocvalbool',
    271 => 'genprocvalint',
    469 => 'genprocvalreal',
    301 => 'genprocvaltext',
    292 => 'genproctableend',
    62 => 'genprocvalcolorindex',
    420 => 'genprocvalcolorrgb',
    430 => 'genprocvalcolorname',
    #270 => 'map_utile',
    148 => 'translucence',
    90 => 'self_illumination',
    468 => 'reflectivity',
    93 => 'illumination_model',
    94 => 'channel_flags',
    ],
  PLOTSETTINGS => [
    1 => 'page_setup_name',
    2 => 'printer_cfg_file',
    3 => 'paper_size',
    6 => 'plotview',
    40 => 'left_margin',
    41 => 'bottom_margin',
    42 => 'right_margin',
    43 => 'top_margin',
    44 => 'paper_width',
    45 => 'paper_height',
    4 => 'canonical_media_name',
    46 => 'plot_origin',
    48 => 'plot_window_ll',
    140 => 'plot_window_ur',
    142 => 'num_custom_print_scale',
    143 => 'den_custom_print_scale',
    70 => 'plot_layout',
    72 => 'plot_paper_units',
    73 => 'plot_rotation',
    74 => 'plot_type',
    7 => 'stylesheet',
    75 => 'std_scale_type',
    147 => 'std_scale_factor',
    148 => 'paper_image_origin',
    76 => 'shade_plot_mode',
    77 => 'shade_plot_res_level',
    78 => 'shade_plot_custom_dpi',
    333 => 'shadeplot',
    ],
  ACDBASSOCACTION => [
    @ASSOCACTION_fields,
    90 => 'num_deps',
    90 => 'status',
    ],
  ACDBASSOCDEPENDENCY => [
    #100 => 'AcDbAssocDependency',
    90 => 'class_version',
    90 => 'status',
    290 => 'isread_dep',
    290 => 'iswrite_dep',
    290 => 'isobjectstate_dep',
    290 => 'unknown_b4',
    90 => 'order',
    290 => 'unknown_b5',
    #330 => 'ownerhandle',
    330 => 'owner',
    330 => 'readdep',
    330 => 'node',
    360 => 'writedep',
    90 => 'depbodyid',
    ],
  ACDBASSOCALIGNEDDIMACTIONBODY => [
    90 => 'aab_version',
    #100 => 'AcDbAssocParamBasedActionBody',
    90 => 'pab_status',
    90 => 'pab_l2',
    90 => 'num_deps',
    360 => 'writedep',
    90 => 'pab_l4',
    90 => 'pab_l5',
    330 => 'readdep',
    #100 => ACDBASSOCALIGNEDDIMACTIONBODY,
    90 => 'dcm_status',
    330 => 'd_node',
    330 => 'r_node',
    ],
  ACDBASSOCNETWORK => [
    @ASSOCACTION_fields,
    #100 => 'AcDbAssocNetwork',
    90 => 'unknown_n1',
    90 => 'unknown_n2',
    90 => 'num_actions',
    330 => 'actions',
    ],
  ACDBASSOCBLENDSURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocBlendSurfaceActionBody',
    90 => 'class_version',
    290 => 'b1',
    291 => 'b2',
    292 => 'b3',
    72 => 'blend_options',
    293 => 'b4',
    294 => 'b5',
    73 => 'bs2',
    ],
  ACDBASSOCPATCHSURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocPlaneSurfaceActionBody',
    90 => 'class_version',
    ],
  ACDBASSOCPLANESURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocPlaneSurfaceActionBody',
    90 => 'psab_status',
    ],
  ACDBASSOCEDGECHAMFERSURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocEdgeChamferActionBody',
  ],
  ACDBASSOCEDGEFILLETSURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocEdgeFilletActionBody',
  ],
  ACDBASSOCEXTRUDEDSURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocExtrudedSurfaceActionBody',
    90 => 'esab_status',
  ],
  ACDBASSOCFILLETSURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocFilletSurfaceActionBody',
    90 => 'class_version',
    70 => 'status',
    10 => 'pt1',
    10 => 'pt2',
  ],
  ACDBASSOCLOFTEDSURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocLoftedSurfaceActionBody',
    90 => 'lsab_status',
  ],
  ACDBASSOCREVOLVEDSURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocRevolvedSurfaceActionBody',
    90 => 'rsab_status',
  ],
  ACDBASSOCSWEPTSURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocSweptSurfaceActionBody',
    90 => 'ssab_status',
    ],
  ACDBASSOCTRIMSURFACEACTIONBODY => [
    @AcDbAssocPathBasedSurfaceActionBody,
    100 => 'AcDbAssocBlendSurfaceActionBody',
    90 => 'class_version',
    290 => 'b1',
    290 => 'b2',
    40 => 'distance',
    ],
  ACDBASSOCRESTOREENTITYSTATEACTIONBODY => [
    100 => 'AcDbAssocActionBody',
    90 => 'aap_version',
    100 => 'AcDbAssocRestoreEntityStateActionBody',
    90 => 'class_version',
    5 => 'entity',
  ],
  ACDBASSOMLEADERACTIONBODY => [
    @AcDbAssocAnnotationActionBody,
    100 => 'AcDbAssocMLeaderActionBody',
    90 => 'class_version',
    90 => 'num_actions',
    # 90 => 'actions[0].depid',
    330 => 'actions[0].dep',
  ],
  ACDBASSOCALIGNEDDIMACTIONBODY => [
    @AcDbAssocAnnotationActionBody,
    100 => 'AcDbAssocAlignedDimActionBody',
    90 => 'class_version',
    330 => 'r_node',
    330 => 'd_node',
  ],
  ACDBASSOC3POINTANGULARDIMACTIONBODY => [
    @AcDbAssocAnnotationActionBody,
    100 => 'Assoc3PointAngularDimActionBody',
    90 => 'class_version',
    330 => 'r_node',
    330 => 'd_node',
    330 => 'assocdep',
  ],
  ACDBASSOCORDINATEDIMACTIONBODY => [
    @AcDbAssocAnnotationActionBody,
    100 => 'AssocOrdinatedDimActionBody',
    90 => 'class_version',
    330 => 'r_node',
    330 => 'd_node',
  ],
  ACDBASSOCROTATEDDIMACTIONBODY => [
    @AcDbAssocAnnotationActionBody,
    100 => 'AssocRotatedDimActionBody',
    90 => 'class_version',
    330 => 'r_node',
    330 => 'd_node',
  ],
  ACDBPERSSUBENTMANAGER => [
    100 => 'AcDbPersSubentManager',
    90 => 'class_version',
    90 => 'unknown_bl1',
    90 => 'unknown_bl2',
    90 => 'unknown_bl3',
    90 => 'unknown_bl4',
    90 => 'unknown_bl5',
    90 => 'unknown_bl6',
    ],
  ACDBASSOCPERSSUBENTMANAGER => [
    100 => 'AcDbAssocPersSubentManager',
    90 => 'class_version',
    90 => 'unknown_bl1',
    90 => 'unknown_bl2',
    90 => 'unknown_bl3',
    90 => 'unknown_bl4',
    90 => 'unknown_bl5',
    90 => 'unknown_bl6',
    90 => 'unknown_bl6a',
    90 => 'unknown_bl7a',
    90 => 'unknown_bl7',
    90 => 'unknown_bl7',
    90 => 'unknown_bl8',
    90 => 'unknown_bl9',
    90 => 'unknown_bl10',
    90 => 'unknown_bl11',
    90 => 'unknown_bl12',
    90 => 'unknown_bl13',
    90 => 'unknown_bl14',
    90 => 'unknown_bl15',
    90 => 'unknown_bl16',
    90 => 'unknown_bl17',
    90 => 'unknown_bl18',
    90 => 'unknown_bl19',
    90 => 'unknown_bl20',
    90 => 'unknown_bl21',
    90 => 'unknown_bl22',
    90 => 'unknown_bl23',
    90 => 'unknown_bl24',
    90 => 'unknown_bl25',
    90 => 'unknown_bl26',
    90 => 'unknown_bl27',
    90 => 'unknown_bl28',
    90 => 'unknown_bl29',
    90 => 'unknown_bl30',
    90 => 'unknown_bl31',
    90 => 'unknown_bl32',
    90 => 'unknown_bl33',
    90 => 'unknown_bl34',
    90 => 'unknown_bl35',
    90 => 'unknown_bl36',
    290 => 'unknown_b37',
    ],
  ACDBASSOC2DCONSTRAINTGROUP => [
    @ASSOCACTION_fields,
    10 => 'workplane',
    360 => 'h1',
    90 => 'l6',
    360 => 'h2',
    360 => 'h3',
    90 => 'l7',
    90 => 'l8',
    1  => 't1', # AcConstrainedCircle
    330 => 'h4',
    90 => 'cl1',
    70 => 'cs1',
    90 => 'cl2',
    90 => 'cl3',
    330 => 'h5',
    90 => 'cl4',
    10 => 'c1',
    10 => 'c2',
    10 => 'c3',
    40 => 'w1',
    40 => 'w2',
    40 => 'w3',
    1 => 't2', # AcConstrainedImplicitPoint
    ],
  ACDBASSOCOSNAPPOINTREFACTIONPARAM => [
    90 => 'status',
    90 => 'flags',
    90 => 'num_actions',
    360 => 'writedep',
    330 => 'actions',
    #40 => 'unknown3',
    #...
    ],
  ACDBASSOCGEOMDEPENDENCY => [
    # 100 AcDbAssocDependency
    90 => 'class_version',
    90 => 'dependent_on_object_status',
    290 => 'has_cached_value',
    290 => 'is_actionevaluation_in_progress',
    290 => 'is_attached_to_object',
    290 => 'is_delegating_to_owning_action',
    90 => 'bs90_2',
    330 => 'h330_1',
    290 => 'b290_5',
    330 => 'h330_2',
    330 => 'h330_3',
    360 => 'h360',
    90 => 'bs90_3',
    # 100 AcDbAssocGeomDependency
    90 => 'bs90_4',
    290 => 'b290_6',
    1 => 't', # AcDbAssocSingleEdgePersSubentId
    290 => 'dependent_on_compound_object',
    ],
  ACSH_BOX_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShBox',
    90 => 'major',
    91 => 'minor',
    40 => 'length',
    41 => 'width',
    42 => 'height',
    ],
  ACSH_WEDGE_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShWedge',
    90 => 'major',
    91 => 'minor',
    40 => 'length',
    41 => 'width',
    42 => 'height',
    ],
  ACSH_SPHERE_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShSphere',
    90 => 'major',
    91 => 'minor',
    40 => 'radius',
    ],
  ACSH_CYLINDER_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShCylinder',
    90 => 'major',
    91 => 'minor',
    40 => 'height',
    41 => 'major_radius',
    42 => 'minor_radius',
    43 => 'x_radius',
    ],
  ACSH_CONE_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShCone',
    90 => 'major',
    91 => 'minor',
    40 => 'base_radius',
    41 => 'top_major_radius',
    42 => 'top_minor_radius',
    43 => 'top_x_radius',
    ],
  ACSH_PYRAMID_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShPyramid',
    90 => 'major',
    91 => 'minor',
    40 => 'height',
    92 => 'sides',
    41 => 'radius',
    42 => 'topradius',
    ],
  ACSH_FILLET_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShFillet',
    90 => 'major',
    91 => 'minor',
    92 => 'bl92',
    93 => 'num_edges',
    94 => 'edges',
    95 => 'num_radiuses',
    41 => 'radiuses',
    96 => 'num_startsetbacks',
    97 => 'num_endsetbacks',
    43 => 'endsetbacks',
    42 => 'startsetbacks',
    ],
  ACSH_CHAMFER_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShChamfer',
    90 => 'major',
    91 => 'minor',
    92 => 'bl92',
    41 => 'base_dist',
    42 => 'other_dist',
    93 => 'num_edges',
    94 => 'edges',
    95 => 'bl95',
    ],
  ACSH_TORUS_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShTorus',
    90 => 'major',
    91 => 'minor',
    40 => 'major_radius',
    41 => 'minor_radius',
    ],
  ACSH_BREP_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShBrep',
    90 => 'major',
    91 => 'minor',
    70 => 'modeler_format_version',
    ],
  ACSH_BOOLEAN_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    100 => 'AcDbShBoolean',
    90 => 'major',
    91 => 'minor',
    280 => 'operation',
    92 => 'operand1',
    93 => 'operand2',
    ],
  ACSH_SWEEP_CLASS => [
    @AcDbEvalExpr,
    @AcDbShHistoryNode,
    100 => 'AcDbShPrimitive',
    # 100 => AcDbShSweepBase
    90 => 'shsw_bl90',
    91 => 'shsw_bl91',
    10 => 'basept',
    92 => 'shsw_bl92',
    90 => 'shsw_text_size',
    310 => 'shsw_text',
    93 => 'shsw_bl93',
    90 => 'shsw_text2_size',
    310 => 'shsw_text2',
    42 => 'draft_angle',
    43 => 'start_draft_dist',
    44 => 'end_draft_dist',
    45 => 'scale_factor',
    48 => 'twist_angle',
    49 => 'align_angle',
    46 => 'sweepentity_transform',
    47 => 'pathentity_transform',
    70 => 'align_option',
    71 => 'miter_option',
    290 => 'has_align_start',
    292 => 'bank',
    293 => 'check_intersections',
    294 => 'shsw_b294',
    295 => 'shsw_b295',
    296 => 'shsw_b296',
    11 => 'pt2',
    ],
  ACSH_HISTORY_CLASS => [
    # 100 => AcDbEvalExpr
    90 => 'class_version',
    98 => 'ee_bl98',
    99 => 'ee_bl99',
    # 100 => AcDbShHistoryNode
    90 => 'shhn_bl90',
    91 => 'shhn_bl91',
    40 => 'shhn_pts',
    62 => 'color',
    92 => 'shhn_b92',
    347 => 'shhn_bl347',
    ],
  ARC_DIMENSION => [
    210 => 'extrusion',
    2 => 'block_name',
    10 => 'def_pt',
    11 => 'text_midpt',
    31 => 'elevation',
    70 => 'flag',
    1 => 'user_text',
    53 => 'text_rotation',
    51 => 'horiz_dir',
    40 => 'leader_len',
    54 => 'ins_rotation',
    71 => 'attachment',
    72 => 'lspace_style',
    41 => 'lspace_factor',
    42 => 'act_measurement',
    3 => 'dimstyle',
    73 => 'unknown',
    74 => 'flip_arrow1',
    75 => 'flip_arrow2',
    12 => 'clone_ins_pt',

    10 => 'def_pt',
    13 => 'xline1_pt',
    14 => 'xline2_pt',
    15 => 'center_pt',
    16 => 'leader1_pt',
    17 => 'leader2_pt',
    40 => 'leader_len',
    41 => 'arc_start_param',
    42 => 'arc_end_param',
    70 => 'is_partial',
    ],
  DATALINK => [
    70 => 'class_version',
    1 => 'data_adapter',
    300 => 'description',
    301 => 'tooltip',
    302 => 'connection_string',
    90 => 'option',
    91 => 'update_option',
    92 => 'bl92',
    170 => 'year',
    171 => 'month',
    172 => 'day',
    173 => 'hour',
    174 => 'minute',
    175 => 'seconds',
    176 => 'msec',
    177 => 'path_option',
    93 => 'bl93',
    304 => 'update_status',
    94 => 'num_customdata',
    #305 => '', # CUSTOMDATA
    #1 => '', # DATAMAP_BEGIN
    330 => 'customdata.target',
    304 => 'customdata.text',
    360 => 'hardowner',
    #309 => '', # DATAMAP_END
    ],
  DIMASSOC => [
    330 => 'dimensionobj',
    90 => 'associativity',
    70 => 'trans_space_flag',
    71 => 'rotated_type',
    @DIMASSOC_Ref,
    @DIMASSOC_Ref,
    @DIMASSOC_Ref,
    @DIMASSOC_Ref,
    92 => 'intsect_gsmarker',
    301 => 'xrefobj',
    302 => 'intsectxrefobj',
    302 => 'intsectxrefobj',
    ],
  LIGHT => [
    90 => 'class_version',
    1 => 'name',
    70 => 'type',
    290 => 'status',
    90 => 'color.rgb', #r2000 only
    63 => 'color',
    291 => 'plot_glyph',
    40 => 'intensity',
    10 => 'position',
    11 => 'target',
    72 => 'attenuation_type',
    292 => 'use_attenuation_limits',
    41 => 'attenuation_start_limit',
    42 => 'attenuation_end_limit',
    50 => 'hotspot_angle',
    51 => 'falloff_angle',
    293 => 'cast_shadows',
    73 => 'shadow_type',
    91 => 'shadow_map_size',
    280 => 'shadow_map_softness',
    #0 => 'lamp_color_preset',
    #0 => 'lamp_color_type',
    #0 => 'physical_intensity_method',
    #0 => 'drawable_type',
    #0 => 'glyph_display_type',
    #0 => 'glyph_display',
    ],
  NAVISWORKSMODELDEF => [
    #100 => AcDbNavisworksModelDef
    1 => 'path',
    290 => 'status',
    10 => 'min_extent',
    11 => 'max_extent',
    290 => 'host_drawing_visibility',
    ],
  RENDERENVIRONMENT => [
    # 100 => AcDbRenderEnvironment
    90 => 'class_version',
    290 => 'fog_enabled',
    290 => 'fog_background_enabled',
    280 => 'fog_color',
    40 => 'fog_density_near',
    40 => 'fog_density_far',
    40 => 'fog_distance_near',
    40 => 'fog_distance_far',
    290 => 'environ_image_enabled',
    1 => 'environ_image_filename',
    ],
  RENDERSETTINGS => [
    # 100 => AcDbRenderSettings
    90 => 'class_version',
    1 => 'name',
    290 => 'fog_enabled',
    290 => 'fog_background_enabled',
    290 => 'backfaces_enabled',
    290 => 'environ_image_enabled',
    1 => 'environ_image_filename',
    1 => 'description',
    90 => 'display_index',
    290 => 'has_predefined',
    ],
  RAPIDRTRENDERSETTINGS => [
    # 100 => AcDbRenderSettings
    90 => 'class_version',
    1 => 'name',
    290 => 'fog_enabled',
    290 => 'fog_background_enabled',
    290 => 'backfaces_enabled',
    290 => 'environ_image_enabled',
    1 => 'environ_image_filename',
    1 => 'description',
    90 => 'display_index',
    290 => 'has_predefined',
    # 100 => AcDbRapidRTRenderSettings
    90 => 'rapidrt_version',
    70 => 'render_target',
    90 => 'render_level',
    90 => 'render_time',
    70 => 'lighting_model',
    70 => 'filter_type',
    40 => 'filter_width',
    40 => 'filter_height',
    290 => 'has_predefined',
    ],
  MENTALRAYRENDERSETTINGS => [
    # 100 => AcDbRenderSettings
    90 => 'class_version',
    1 => 'name',
    290 => 'fog_enabled',
    290 => 'fog_background_enabled',
    290 => 'backfaces_enabled',
    290 => 'environ_image_enabled',
    1 => 'environ_image_filename',
    1 => 'description',
    90 => 'display_index',
    290 => 'has_predefined',
    # 100 => AcDbMentalRayRenderSettings
    90 => 'mr_version',
    90 => 'sampling1',
    90 => 'sampling2',
    70 => 'sampling_mr_filter',
    40 => 'sampling_filter1',
    40 => 'sampling_filter2',
    40 => 'sampling_contrast_color1',
    40 => 'sampling_contrast_color2',
    40 => 'sampling_contrast_color3',
    40 => 'sampling_contrast_color4',
    70 => 'shadow_mode',
    290 => 'shadow_maps_enabled',
    290 => 'ray_tracing_enabled',
    90 => 'ray_trace_depth1',
    90 => 'ray_trace_depth2',
    90 => 'ray_trace_depth3',
    290 => 'global_illumination_enabled',
    90 => 'gi_sample_count',
    290 => 'gi_sample_radius_enabled',
    40 => 'gi_sample_radius',
    90 => 'gi_photons_per_light',
    90 => 'photon_trace_depth1',
    90 => 'photon_trace_depth2',
    90 => 'photon_trace_depth3',
    290 => 'final_gathering_enabled',
    90 => 'fg_ray_count',
    290 => 'fg_sample_radius_state1',
    290 => 'fg_sample_radius_state2',
    290 => 'fg_sample_radius_state3',
    40 => 'fg_sample_radius1',
    40 => 'fg_sample_radius2',
    40 => 'light_luminance_scale',
    70 => 'diagnostics_mode',
    70 => 'diagnostics_grid_mode',
    40 => 'diagnostics_grid_float',
    70 => 'diagnostics_photon_mode',
    70 => 'diagnostics_bsp_mode',
    290 => 'export_mi_enabled',
    1 => 'mr_description',
    90 => 'tile_size',
    70 => 'tile_order',
    90 => 'memory_limit',
    290 => 'diagnostics_samples_mode',
    40 => 'energy_multiplier',
    ],
  RENDERGLOBAL => [
    # 100 => AcDbRenderGlobal
    90 => 'class_version',
    90 => 'procedure',
    90 => 'destination',
    290 => 'save_enabled',
    1 => 'save_filename',
    90 => 'image_width',
    90 => 'image_height',
    290 => 'predef_presets_first',
    290 => 'highlevel_info',
    ],
  RENDERENTRY => [
    90 => 'class_version',
    1 => 'image_file_name',
    1 => 'preset_name',
    1 => 'view_name',
    90 => 'dimension_x',
    90 => 'dimension_y',
    70 => 'start_year',
    70 => 'start_month',
    70 => 'start_day',
    70 => 'start_minute',
    70 => 'start_second',
    70 => 'start_msec',
    40 => 'render_time',
    90 => 'memory_amount',
    90 => 'material_count',
    90 => 'light_count',
    90 => 'triangle_count',
    90 => 'display_index',
  ],
  SUN => [
    90 => 'class_version',
    290 => 'is_on',
    291 => 'has_shadow',
    292 => 'is_dst',
    421 => 'unknown',
    40 => 'intensity',
    291 => 'has_shadow',
    91 => 'julian_day',
    92 => 'time',
    292 => 'is_dst',
    #0 => 'altitude',
    #0 => 'azimuth',
    #0 => 'direction',
    70 => 'shadow_type',
    280 => 'shadow_softness',
    71 => 'shadow_mapsize',
    330 => 'ownerhandle',
    63 => 'color',
    ],
  SUNSTUDY => [
    90 => 'class_version',
    1 => 'setup_name',
    2 => 'description',
    70 => 'output_type',
    290 => 'use_subset',
    3 => 'sheet_set_name',
    4 => 'sheet_subset_name',
    291 => 'select_dates_from_calendar',
    91 => 'num_dates',
    90 => 'dates.julian_day',
    90 => 'dates.time',
    292 => 'select_range_of_dates',
    93 => 'start_time',
    94 => 'end_time',
    95 => 'interval',
    91 => 'num_hours',
    290 => 'hours',
    74 => 'shade_plot_type',
    75 => 'numvports',
    76 => 'numrows',
    77 => 'numcols',
    40 => 'spacing',
    293 => 'lock_viewports',
    294 => 'label_viewports',
    330 => 'ownerhandle',
    340 => 'page_setup_wizard',
    341 => 'view',
    342 => 'visual_style',
    343 => 'text_style',
    ],
  ACAD_TABLE => [
    #SUBCLASS (AcDbBlockReference)
    10 => 'insertion_point',
    41 => 'scale.x',
    #0 => 'scale_flag',
    42 => 'scale.y',
    43 => 'scale.z',
    50 => 'rotation',
    210 => 'extrusion',
    66 => 'has_attribs',
    #0 => 'num_owned',
    90 => 'flag_for_table_value',
    11 => 'horiz_direction',
    92 => 'num_cols',
    91 => 'num_rows',
    142 => 'col_widths',
    141 => 'row_heights',
    #SUBCLASS (AcDbDataCell)
    171 => 'cells.type',
    172 => 'cells.flags',
    173 => 'cells.merged_value',
    174 => 'cells.autofit_flag',
    175 => 'cells.merged_width_flag',
    176 => 'cells.merged_height_flag',
    145 => 'cells.rotation_value',
    1 => 'cells.text_value',
    144 => 'cells.block_scale',
    #0 => 'cells.additional_data_flag',
    179 => 'cells.num_attr_defs',
    #0 => 'cells.attr_def_index',
    300 => 'cells.attr_def_text',
    #0 => 'cells.additional_data_flag',
    177 => 'cells.cell_flag_override',
    178 => 'cells.virtual_edge_flag',
    170 => 'cells.cell_alignment',
    283 => 'cells.background_fill_none',
    63 => 'cells.background_color',
    64 => 'cells.content_color',
    7 => 'cells.text_style',
    140 => 'cells.text_height',
    69 => 'cells.top_grid_color',
    279 => 'cells.top_grid_linewt',
    289 => 'cells.top_visibility',
    65 => 'cells.right_grid_color',
    275 => 'cells.right_grid_linewt',
    285 => 'cells.right_visibility',
    66 => 'cells.bottom_grid_color',
    276 => 'cells.bottom_grid_linewt',
    286 => 'cells.bottom_visibility',
    68 => 'cells.left_grid_color',
    278 => 'cells.left_grid_linewt',
    288 => 'cells.left_visibility',
    #0 => 'cells.unknown',
    #0 => 'has_table_overrides',
    93 => 'table_flag_override',
    280 => 'title_suppressed',
    281 => 'header_suppressed',
    70 => 'flow_direction',
    40 => 'horiz_cell_margin',
    41 => 'vert_cell_margin',
    64 => 'title_row_color',
    64 => 'header_row_color',
    64 => 'data_row_color',
    283 => 'title_row_fill_none',
    283 => 'header_row_fill_none',
    283 => 'data_row_fill_none',
    63 => 'title_row_fill_color',
    63 => 'header_row_fill_color',
    63 => 'data_row_fill_color',
    170 => 'title_row_alignment',
    170 => 'header_row_alignment',
    170 => 'data_row_alignment',
    7 => 'title_text_style',
    7 => 'header_text_style',
    7 => 'data_text_style',
    140 => 'title_row_height',
    140 => 'header_row_height',
    140 => 'data_row_height',
    #0 => 'has_border_color_overrides',
    94 => 'border_color_overrides_flag',
    64 => 'title_horiz_top_color',
    65 => 'title_horiz_ins_color',
    66 => 'title_horiz_bottom_color',
    63 => 'title_vert_left_color',
    68 => 'title_vert_ins_color',
    69 => 'title_vert_right_color',
    64 => 'header_horiz_top_color',
    65 => 'header_horiz_ins_color',
    66 => 'header_horiz_bottom_color',
    63 => 'header_vert_left_color',
    68 => 'header_vert_ins_color',
    69 => 'header_vert_right_color',
    64 => 'data_horiz_top_color',
    65 => 'data_horiz_ins_color',
    66 => 'data_horiz_bottom_color',
    63 => 'data_vert_left_color',
    68 => 'data_vert_ins_color',
    69 => 'data_vert_right_color',
    #0 => 'has_border_lineweight_overrides',
    95 => 'border_lineweight_overrides_flag',
    #0 => 'title_horiz_top_linewt',
    #0 => 'title_horiz_ins_linewt',
    #0 => 'title_horiz_bottom_linewt',
    #0 => 'title_vert_left_linewt',
    #0 => 'title_vert_ins_linewt',
    #0 => 'title_vert_right_linewt',
    #0 => 'header_horiz_top_linewt',
    #0 => 'header_horiz_ins_linewt',
    #0 => 'header_horiz_bottom_linewt',
    #0 => 'header_vert_left_linewt',
    #0 => 'header_vert_ins_linewt',
    #0 => 'header_vert_right_linewt',
    #0 => 'data_horiz_top_linewt',
    #0 => 'data_horiz_ins_linewt',
    #0 => 'data_horiz_bottom_linewt',
    #0 => 'data_vert_left_linewt',
    #0 => 'data_vert_ins_linewt',
    #0 => 'data_vert_right_linewt',
    #0 => 'has_border_visibility_overrides',
    96 => 'border_visibility_overrides_flag',
    0 => 'title_horiz_top_visibility',
    0 => 'title_horiz_ins_visibility',
    0 => 'title_horiz_bottom_visibility',
    0 => 'title_vert_left_visibility',
    0 => 'title_vert_ins_visibility',
    0 => 'title_vert_right_visibility',
    0 => 'header_horiz_top_visibility',
    0 => 'header_horiz_ins_visibility',
    0 => 'header_horiz_bottom_visibility',
    0 => 'header_vert_left_visibility',
    0 => 'header_vert_ins_visibility',
    0 => 'header_vert_right_visibility',
    0 => 'data_horiz_top_visibility',
    0 => 'data_horiz_ins_visibility',
    0 => 'data_horiz_bottom_visibility',
    0 => 'data_vert_left_visibility',
    0 => 'data_vert_ins_visibility',
    0 => 'data_vert_right_visibility',
    2 => 'block_header',
    #0 => 'first_attrib',
    #0 => 'last_attrib',
    #0 => 'seqend',
    342 => 'table_style_id',
    344 => 'cells.cell_handle',
    340 => 'cells.cell_handle',
    331 => 'cells.attr_def_id',
    7 => 'cells.text_style_override',
    7 => 'title_row_style_override',
    7 => 'header_row_style_override',
    7 => 'data_row_style_override',
    0 => 'unknown_bs',
    11 => 'hor_dir',
    #0 => 'has_break_data',
    #0 => 'break_flag',
    #0 => 'break_flow_direction',
    #0 => 'break_spacing',
    #0 => 'break_unknown1',
    #0 => 'break_unknown2',
    #0 => 'num_break_heights',
    #0 => 'break_heights.position',
    #0 => 'break_heights.height',
    #0 => 'break_heights.flag',
    #0 => 'num_break_rows',
    #0 => 'break_rows.position',
    #0 => 'break_rows.start',
    ],
  TABLECONTENT => [
    #100 => AcDbDataTableContent
    1 => 'ldata.name',
    300 => 'ldata.desc',
    90 => 'tdata.num_cols',
    300 => 'tdata.cols.name',
    91 => 'tdata.cols.custom_data',
    #Cell_Style_Fields(tdata.cols.cell_style);
    90 => 'tdata.num_rows',
    90 => 'row.num_cells',
    90 => 'cell.flag',
    300 => 'cell.tooltip',
    91 => 'cell.customdata',
    90 => 'cell.num_customdata_items',
    300 => 'cell.customdata_items.name',
    92 => 'cell.has_linked_data',
    340 => 'cell.data_link',
    93 => 'cell.num_rows',
    94 => 'cell.num_cols',
    96 => 'cell.unknown',
    95 => 'cell.num_cell_contents',
    90 => 'content.type',
    # Table_Value(content.value)
    340 => 'content.handle',
    91 => 'content.num_attrs',
    330 => 'attr.attdef',
    301 => 'attr.value',
    92 => 'attr.index',
    # Content_Format(content.content_format);
    90 => 'cell.style_id',
    91 => 'cell.has_geom_data',
    91 => 'cell.geom_data_flag',
    40 => 'cell.unknown_d40',
    41 => 'cell.unknown_d41',
    #0 => 'cell.has_cell_geom',
    330 => 'cell.tablegeometry',
    94 => 'cell.num_geometry',
    10 => 'geom.dist_top_left',
    11 => 'geom.dist_center',
    43 => 'geom.content_width',
    44 => 'geom.content_height',
    45 => 'geom.width',
    46 => 'geom.height',
    95 => 'geom.unknown',
    91 => 'row.custom_data',
    90 => 'row.num_customdata_items',
    300 => 'row.customdata_items.name',
    #Table_Value(row.customdata_items[rcount3].value);
    #Cell_Style_Fields(row.cell_style);
    90 => 'row.style_id',
    40 => 'row.height',
    #0 => 'tdata.num_field_refs',
    #0 => 'tdata.field_refs',
    90 => 'fdata.num_merged_cells',
    91 => 'merged.top_row',
    92 => 'merged.left_col',
    93 => 'merged.bottom_row',
    94 => 'merged.right_col',
    340 => 'table_style, 3',
    ],
  TABLEGEOMETRY => [
    90 => 'num_rows',
    91 => 'num_cols',
    92 => 'num_cells',
    93 => 'cells.geom_data_flag',
    40 => 'cells.width_w_gap',
    41 => 'cells.height_w_gap',
    330 => 'cells.tablegeometry',
    94 => 'cells.num_geometry',
    10 => 'cell.geometry.dist_top_left',
    11 => 'cell.geometry.dist_center',
    43 => 'cell.geometry.content_width',
    44 => 'cell.geometry.content_height',
    45 => 'cell.geometry.width',
    46 => 'cell.geometry.height',
    95 => 'cell.geometry.unknown',
    ],
  TABLESTYLE => [
    100 => 'AcDbTableStyle',
    3 => 'name',
    70 => 'flow_direction',
    71 => 'flags',
    40 => 'horiz_cell_margin',
    41 => 'vert_cell_margin',
    280 => 'title_suppressed',
    281 => 'header_suppressed',
    7 => 'rowstyles.text_style',
    140 => 'rowstyles.text_height',
    170 => 'rowstyles.text_alignment',
    62 => 'rowstyles.text_color',
    63 => 'rowstyles.fill_color',
    283 => 'rowstyles.has_bgcolor',
    274 => 'rowstyles.borders.linewt',
    284 => 'rowstyles.borders.visible',
    264 => 'rowstyles.borders.color',
    275 => 'rowstyles.borders.linewt',
    285 => 'rowstyles.borders.visible',
    265 => 'rowstyles.borders.color',
    276 => 'rowstyles.borders.linewt',
    286 => 'rowstyles.borders.visible',
    266 => 'rowstyles.borders.color',
    277 => 'rowstyles.borders.linewt',
    287 => 'rowstyles.borders.visible',
    267 => 'rowstyles.borders.color',
    278 => 'rowstyles.borders.linewt',
    288 => 'rowstyles.borders.visible',
    268 => 'rowstyles.borders.color',
    279 => 'rowstyles.borders.linewt',
    289 => 'rowstyles.borders.visible',
    269 => 'rowstyles.borders.color',
    90 => 'rowstyles.data_type',
    91 => 'rowstyles.unit_type',
    1 => 'rowstyles.format_string',
    ],
  ACDB_ALDIMOBJECTCONTEXTDATA_CLASS => [
    100 => 'AcDbObjectContextData',
    70 => 'class_version',
    290 => 'is_default',
    100 => 'AcDbAnnotScaleObjectContextData',
    340 => 'scale',
    100 => 'AcDbDimensionObjectContextData',
    2 => 'name',
    10 => 'def_pt',
    293 => 'b293',
    294 => 'b294',
    140 => 'bd140',
    298 => 'b298',
    291 => 'b291',
    70 => 'flag',
    292 => 'b292',
    71 => 'bs71',
    280 => 'b280',
    295 => 'b295',
    296 => 'b296',
    297 => 'b297',
    100 => 'AcDbAlignedDimensionObjectContextData',
    11 => '_11pt',
    ],
  ACDB_BLKREFOBJECTCONTEXTDATA_CLASS => [
    100 => 'AcDbObjectContextData',
    70 => 'class_version',
    290 => 'is_default',
    100 => 'AcDbAnnotScaleObjectContextData',
    340 => 'scale',
    ],
  ACDB_LEADEROBJECTCONTEXTDATA_CLASS => [
    100 => 'AcDbObjectContextData',
    70 => 'class_version',
    290 => 'is_default',
    100 => 'AcDbAnnotScaleObjectContextData',
    340 => 'scale',
    70 => 'num_points',
    10 => 'points[0]',
    10 => 'points[1]',
    10 => 'points[2]',
    11 => 'x_direction',
    290 => 'b290', # arrowhead_on?
    12 => 'inspt_offset',
    13 => 'endptproj',
    ],
  ACDB_MLEADEROBJECTCONTEXTDATA_CLASS => [
    100 => 'AcDbObjectContextData',
    70 => 'class_version',
    290 => 'defaultflag',
    100 => 'AcDbAnnotScaleObjectContextData',
    340 => 'scale',
    ],
  ACDB_TEXTOBJECTCONTEXTDATA_CLASS => [
    100 => 'AcDbObjectContextData',
    70 => 'class_version',
    290 => 'is_default',
    100 => 'AcDbAnnotScaleObjectContextData',
    340 => 'scale',
    70 => 'flag',
    50 => 'rotation',
    10 => 'ins_pt',
    11 => 'alignment_pt',
    ],
  ACDB_MTEXTATTRIBUTEOBJECTCONTEXTDATA_CLASS => [
    100 => 'AcDbObjectContextData',
    70 => 'class_version',
    290 => 'in_dwg',
    90 => 'is_default',
    100 => 'AcDbAnnotScaleObjectContextData',
    340 => 'scale',
  ],
  ACDB_MTEXTOBJECTCONTEXTDATA_CLASS => [
    100 => 'AcDbObjectContextData',
    70 => 'class_version',
    290 => 'is_default',
    100 => 'AcDbAnnotScaleObjectContextData',
    340 => 'scale',
    70 => 'flag',
    11 => 'ins_pt',
    10 => 'x_axis_dir',
    40 => 'text_height',
    41 => 'rect_width',
    42 => 'extents_width',
    43 => 'extents_height',
    71 => 'attachment',
    72 => 'drawing_dir',
    73 => 'linespace_style',
    44 => 'linespace_factor',
    45 => 'bd45',
    74 => 'bs74',
    46 => 'rect_height',
    ],
  # keep it for dxf_test
  MULTILEADER => [
    270 => 'class_version',
    70 => 'ctx.class_version',
    #0 => 'ctx.has_xdic_file',
    290 => 'ctx.is_default',
    340 => 'ctx.scale_handle',
    302 => 'LEADER{',
    #0 => 'ctx.num_leaders',
    290 => 'lev1.is_valid',
    291 => 'lev1.unknown',
    10 => 'lev1.connection',
    11 => 'lev1.direction',
    #0 => 'lev1.num_breaks',
    12 => 'lev1.breaks.start',
    13 => 'lev1.breaks.end',
    90 => 'lev1.index',
    40 => 'lev1.landing_distance',
    304 => 'LEADER_LINE{',
    #0 => 'lev2.num_points',
    10 => 'lev2.points',
    #0 => 'lev2.num_breaks',
    90 => 'lev2.segment_index',
    11 => 'lev2.breaks.start',
    12 => 'lev2.breaks.end',
    91 => 'lev2.index',
    170 => 'lev2.type',
    92 => 'lev2.color',
    340 => 'lev2.type_handle',
    171 => 'lev2.weight',
    40 => 'lev2.arrow_size',
    341 => 'lev2.arrow_handle',
    93 => 'lev2.flags',
    305 => '}',
    271 => 'lev1.attach_dir',
    303 => '}',
    40 => 'ctx.scale',
    10 => 'ctx.content_base',
    41 => 'ctx.text_height',
    140 => 'ctx.arrow_size',
    145 => 'ctx.landing_gap',
    174 => 'ctx.text_left',
    175 => 'ctx.text_right',
    176 => 'ctx.text_alignment',
    177 => 'ctx.attach_type',
    290 => 'ctx.has_content_txt',
    304 => 'ctx.txt.label',
    11 => 'ctx.txt.normal',
    340 => 'ctx.txt.style',
    12 => 'ctx.txt.location',
    13 => 'ctx.txt.direction',
    42 => 'ctx.txt.rotation',
    43 => 'ctx.txt.width',
    44 => 'ctx.txt.height',
    45 => 'ctx.txt.line_spacing_factor',
    170 => 'ctx.txt.line_spacing_style',
    90 => 'ctx.txt.color',
    171 => 'ctx.txt.alignment',
    172 => 'ctx.txt.flow',
    91 => 'ctx.txt.bg_color',
    141 => 'ctx.txt.bg_scale',
    92 => 'ctx.txt.bg_transparency',
    291 => 'ctx.txt.is_bg_fill',
    292 => 'ctx.txt.is_bg_mask_fill',
    173 => 'ctx.txt.col_type',
    293 => 'ctx.txt.is_height_auto',
    142 => 'ctx.txt.col_width',
    143 => 'ctx.txt.col_gutter',
    294 => 'ctx.txt.is_col_flow_reversed',
    #0 => 'ctx.txt.num_col_sizes',
    144 => 'ctx.txt.col_sizes',
    295 => 'ctx.txt.word_break',
    #0 => 'ctx.txt.unknown',
    296 => 'ctx.has_content_blk',
    341 => 'ctx.blk.block_table',
    14 => 'ctx.blk.normal',
    15 => 'ctx.blk.location',
    16 => 'ctx.blk.scale',
    46 => 'ctx.blk.rotation',
    93 => 'ctx.blk.color',
    47 => 'ctx.blk.transform',
    110 => 'ctx.base',
    111 => 'ctx.base_dir',
    112 => 'ctx.base_vert',
    297 => 'ctx.is_normal_reversed',
    273 => 'ctx.text_top',
    272 => 'ctx.text_bottom',
    301 => '}',
    340 => 'mleaderstyle',
    90 => 'flags',
    170 => 'type',
    91 => 'color',
    341 => 'ltype',
    171 => 'linewt',
    290 => 'landing',
    291 => 'dog_leg',
    41 => 'landing_dist',
    342 => 'arrow_head',
    42 => 'arrow_head_size',
    172 => 'style_content',
    343 => 'text_style',
    95 => 'text_left',
    95 => 'text_right',
    174 => 'text_angletype',
    175 => 'attach_type',
    92 => 'text_color',
    292 => 'text_frame',
    344 => 'block_style',
    93 => 'block_color',
    10 => 'block_scale',
    43 => 'block_rotation',
    176 => 'style_attachment',
    293 => 'is_annotative',
    #0 => 'num_arrowheads',
    94 => 'arrowheads.is_default',
    345 => 'arrowheads.arrowhead',
    #0 => 'num_blocklabels',
    330 => 'blocklabels.attdef',
    302 => 'blocklabels.label_text',
    177 => 'blocklabels.ui_index',
    44 => 'blocklabels.width',
    294 => 'neg_textdir',
    178 => 'ipe_alignment',
    179 => 'justification',
    45 => 'scale_factor',
    271 => 'attach_dir',
    273 => 'attach_top',
    272 => 'attach_bottom',
    295 => 'text_extended',
    ],
  POSITIONMARKER => [ # GEOPOSITIONMARKER
    100 => 'AcDbGeoPositionMarker',
    90 => 'class_version',
    10 => 'position',
    40 => 'radius',
    1 => 'notes',
    40 => 'landing_gap',
    290 => 'mtext_visible',
    280 => 'text_alignment',
    290 => 'enable_frame_text',
    101 => 'Embedded Object',
    ],
  EXTRUDEDSURFACE => [
    #100 => AcDbModelerGeometry,
    70 => 'modeler_format_version',
    #100 => AcDbSurface,
    71 => 'u_isolines',
    72 => 'v_isolines',
    #100 => AcDbExtrudedSurface
    90 => 'class_version',
    10 => 'sweep_vector',
    40 => 'sweep_transmatrix', #x16
    42 => 'draft_angle',
    43 => 'draft_start_distance',
    44 => 'draft_end_distance',
    45 => 'twist_angle',
    48 => 'scale_factor',
    49 => 'align_angle',
    46 => 'sweep_entity_transmatrix',
    47 => 'path_entity_transmatrix',
    290 => 'solid',
    290 => 'sweep_alignment_flags',
    292 => 'align_start',
    293 => 'bank',
    294 => 'base_point_set',
    295 => 'sweep_entity_transform_computed',
    296 => 'path_entity_transform_computed',
    11 => 'reference_vector_for_controlling_twist',
    ],
  LOFTEDSURFACE => [
    #100 => AcDbModelerGeometry,
    70 => 'modeler_format_version',
    #100 => AcDbSurface,
    71 => 'u_isolines',
    72 => 'v_isolines',
    #100 => AcDbLoftedSurface
    40 => 'loft_entity_transmatrix', #x16
    #90 => 'class_version',
    70 => 'plane_normal_lofting_type',
    41 => 'start_draft_angle',
    42 => 'end_draft_angle',
    43 => 'start_draft_magnitude',
    44 => 'end_draft_magnitude',
    290 => 'arc_length_parameterization',
    291 => 'no_twist',
    292 => 'align_direction',
    293 => 'simple_surfaces',
    294 => 'closed_surfaces',
    295 => 'solid',
    296 => 'ruled_surface',
    297 => 'virtual_guide',
    90  => 'num_cross_sections',
    310 => 'cross_sections',
    90  => 'num_guide_curves',
    310 => 'guide_curves',
    5   => 'path_curve',
    ],
  REVOLVEDSURFACE => [
    #100 => AcDbModelerGeometry,
    70 => 'modeler_format_version',
    #100 => AcDbSurface,
    71 => 'u_isolines',
    72 => 'v_isolines',
    #100 => AcDbRevolvedSurface
    90 => 'class_version',
    90 => 'id',
    90 => 'num_bindata',
    310 => 'bindata',
    10 => 'axis_point',
    11 => 'axis_vector',
    40 => 'revolve_angle',
    41 => 'start_angle',
    42 => 'revolved_entity_transmatrix',
    43 => 'draft_angle',
    44 => 'draft_start_distance',
    45 => 'draft_end_distance',
    46 => 'twist_angle',
    290 => 'solid',
    291 => 'close_to_axis',
    ],
  SWEPTSURFACE => [
    #100 => AcDbModelerGeometry,
    70 => 'modeler_format_version',
    #100 => AcDbSurface,
    71 => 'u_isolines',
    72 => 'v_isolines',
    #100 => AcDbSweptSurface
    90 => 'class_version',
    90 => 'swept_entity_id',
    90 => 'num_sweepdata',
    310 => 'sweepdata',
    90 => 'path_entity_id',
    90 => 'num_pathdata',
    310 => 'pathdata',
    40 => 'sweep_entity_transmatrix',
    41 => 'path_entity_transmatrix',
    42 => 'draft_angle',
    43 => 'draft_start_distance',
    44 => 'draft_end_distance',
    45 => 'twist_angle',
    48 => 'scale_factor',
    290 => 'solid',
    70 => 'sweep_alignment',
    292 => 'align_start',
    293 => 'bank',
    294 => 'base_point_set',
    295 => 'sweep_entity_transform_computed',
    296 => 'path_entity_transform_computed',
    11 => 'reference_vector_for_controlling_twist',
    ],
  NURBSURFACE => [
    100 => 'AcDbModelerGeometry',
    70 => 'modeler_format_version',
    100 => 'AcDbSurface',
    71 => 'u_isolines',
    72 => 'v_isolines',
    100 => 'AcDbNurbSurface',
    170 => 'short170',
    290 => 'cv_hull_display',
    10 => 'uvec1',
    11 => 'vvec1',
    12 => 'uvec2',
    13 => 'vvec2',
    ],
  PLANESURFACE => [
    #100 => AcDbModelerGeometry,
    70 => 'modeler_format_version',
    #100 => AcDbSurface,
    71 => 'u_isolines',
    72 => 'v_isolines',
    100 => 'AcDbPlaneSurface',
    90 => 'class_version',
    ],
  MESH => [
    90 => 'class_version',
    # 100 => AcDbSubDMesh
    71 => 'dlevel',
    72 => 'is_watertight',
    91 => 'num_subdiv_vertex',
    10 => 'subdiv_vertex',
    92 => 'num_vertex',
    10 => 'vertex',
    93 => 'num_faces',
    90 => 'faces',
    94 => 'num_edges',
    90 => 'edges.from',
    90 => 'edges.to',
    95 => 'num_crease',
    # 90?  BD crease
    ],
  GEOMAPIMAGE => [
    # 100 => AcDbGeomapImage
    90 => 'class_version',
    10 => 'pt0',
    13 => 'size',
    70 => 'display_props',
    280 => 'clipping',
    281 => 'brightness',
    282 => 'contrast',
    283 => 'fade',
    ],
  UNDERLAY => [
    10 => 'ins_pt',
    41 => 'scale',
    50 => 'angle',
    210 => 'extrusion',
    11 => 'clip_boundary->pt',
    280 => 'flag',
    281 => 'contrast',
    282 => 'fade',
    340 => 'definition_id',
    ],
  UNDERLAYDEFINITION => [
    1 => 'filename',
    2 => 'name',
    ],
  VISUALSTYLE => [
    2 => 'description',
    70 => 'style_type',
    177 => 'ext_lighting_model',
    291 => 'internal_only',
    71 => 'face_lighting_model',
    72 => 'face_lighting_quality',
    73 => 'face_color_mode',
    40 => 'face_opacity',
    41 => 'face_specular',
    90 => 'face_modifier',
    62 => 'color',
    420 => 'color.rgb',
    63 => 'face_mono_color',
    421 => 'face_mono_color.rgb',
    74 => 'edge_model',
    91 => 'edge_style',
    64 => 'edge_intersection_color',
    65 => 'edge_obscured_color',
    75  => 'edge_obscured_ltype',
    175 => 'edge_intersection_ltype',
    42 => 'edge_crease_angle',
    92 => 'edge_modifier',
    66 => 'edge_color',
    43 => 'edge_opacity',
    76 => 'edge_width',
    77 => 'edge_overhang',
    78 => 'edge_jitter',
    67 => 'edge_silhouette_color',
    79 => 'edge_silhouette_width',
    170 => 'edge_halo_gap',
    171 => 'edge_isolines',
    290 => 'edge_do_hide_precision',
    174 => 'edge_style_apply',
    93 => 'display_settings',
    44 => 'display_brightness',
    173 => 'display_shadow_type',
    45 => 'bd2007_45',
    ],
  HELIX => [
    90 => 'major_version',
    91 => 'maint_version',
    10 => 'axis_base_pt.x',
    20 => 'axis_base_pt.y',
    30 => 'axis_base_pt.z',
    11 => 'start_pt.x',
    21 => 'start_pt.y',
    31 => 'start_pt.z',
    12 => 'axis_vector.x',
    22 => 'axis_vector.y',
    32 => 'axis_vector.z',
    40 => 'radius',
    41 => 'turns',
    42 => 'height',
    290 => 'handedness',
    280 => 'constraint_type',
    ],
  ACDBDETAILVIEWSTYLE => [
    100 => 'AcDbModelDocViewStyle',
    70 => 'class_version',
    3 => 'name',
    290 => 'is_modified_for_recompute',
    100 => 'AcDbDetailViewStyle',
    70 => 'identifier_placement',
    90 => 'model_edge',
    280 => 'show_arrowheads',
    71 => 'connection_line_weight',
    62 => 'connection_line_color',
    62 => 'identifier_color',
    62 => 'arrow_symbol_color',
    62 => 'boundary_line_color',
    62 => 'viewlabel_text_color',
    40 => 'identifier_height',
    42 => 'identifier_offset',
    340 => 'identifier_style',
    340 => 'arrow_symbol',
    40 => 'arrow_symbol_size',
    71 => 'boundary_line_weight',
    340 => 'boundary_line_type',
    340 => 'viewlabel_text_style',
    340 => 'connection_line_type',
    40 => 'viewlabel_text_height',
    300 => 'viewlabel_field',
    42 => 'viewlabel_offset',
    70 => 'viewlabel_attachment',
    72 => 'viewlabel_alignment',
    90 => 'viewlabel_pattern',
    280 => 'show_viewlabel',
    71 => 'borderline_weight',
    62 => 'borderline_color',
    340 => 'borderline_type',
    ],
  ACDBSECTIONVIEWSTYLE => [
    100 => 'AcDbModelDocViewStyle',
    70 => 'class_version',
    3 => 'name',
    290 => 'is_modified_for_recompute',
    300 => 'description',
    90 => 'identifier_exclude_characters',
    100 => 'AcDbSectionViewStyle',
    62 => 'identifier_color',
    40 => 'identifier_height',
    62 => 'plane_line_color',
    42 => 'identifier_offset',
    300 => 'viewlabel_text',
    40 => 'identifier_position',
    90 => 'viewlabel_pattern',
    62 => 'arrow_symbol_color',
    90 => 'hatch_pattern',
    62 => 'bend_line_color',
    40 => 'arrow_symbol_size',
    40 => 'arrow_position',
    62 => 'viewlabel_text_color',
    40 => 'bend_line_length',
    62 => 'hatch_color',
    62 => 'hatch_bg_color',
    340 => 'identifier_style',
    340 => 'arrow_start_symbol',
    340 => 'arrow_end_symbol',
    40 => 'arrow_symbol_extension_length',
    71 => 'plane_line_weight',
    340 => 'plane_line_type',
    340 => 'bend_line_type',
    340 => 'viewlabel_text_style',
    0 => 'bend_line_weight',
    0 => 'end_line_length',
    40 => 'viewlabel_text_height',
    300 => 'viewlabel_field',
    42 => 'viewlabel_offset',
    70 => 'viewlabel_attachment',
    72 => 'viewlabel_alignment',
    0 => 'hatch_scale',
    0 => 'hatch_angles',
    0 => 'hatch_transparency',
    290 => 'is_continuous_labeling',
    290 => 'show_arrowheads',
    290 => 'show_viewlabel',
    290 => 'show_all_plane_lines',
    290 => 'show_all_bend_indentifiers',
    290 => 'show_end_and_bend_lines',
    ],
  SECTIONOBJECT => [
    # AcDbSection
    90 => 'state',
    91 => 'flags',
    1 => 'name',
    10 => 'vert_dir',
    40 => 'top_height',
    41 => 'bottom_height',
    70 => 'indicator_alpha',
    62 => 'indicator_color',
    92 => 'num_verts',
    11 => 'verts.x',
    21 => 'verts.y',
    31 => 'verts.z',
    93 => 'num_blverts',
    12 => 'blverts.x',
    22 => 'blverts.y',
    32 => 'blverts.z',
    360 => 'section_settings',
  ],
  LAYERFILTER => [
    2 => 'name',
    3 => 'description',
    ],
  LAYOUTPRINTCONFIG => [
    93 => 'flag',
    ],
  ATEXT => [
      1 => 'text_value',
      2 => 't2',
      3 => 't3',
      7 => 'style',
      10 => 'center',
      40 => 'radius',
      41 => 'xscale',
      42 => 'text_size',
      43 => 'char_spacing',
      44 => 'offset_from_arc',
      45 => 'right_offset',
      46 => 'left_offset',
      50 => 'start_angle',
      51 => 'end_angle',
      70 => 'is_reverse',
      71 => 'text_direction',
      72 => 'alignment',
      73 => 'text_position',
      74 => 'font_19',
      75 => 'bs2',
      76 => 'is_underlined',
      77 => 'bs1',
      78 => 'font',
      79 => 'is_shx',
      90 => 'color.index',
      210 => 'extrusion',
      280 => 'wizard_flag',
      330 => 'arc_handle',
    ],
  RTEXT => [
      10 => 'pt',
      210 => 'extrusion',
      50 => 'rotation',
      50 => 'height',
      7 => 'style',
      70 => 'flags',
      1 => 'text_value',
    ],
  ACDB_BLOCKREPRESENTATION_DATA => [
    70 => 'flag',
    340 => 'block',
    ],
  ACMECOMMANDHISTORY => [
    ],
  ACMESCOPE => [
    ],
  ACMESTATEMGR => [
    ],
};

my $firstline = "/* ex: set ro ft=c: -*- mode: c; buffer-read-only: t -*- */\n"
              . "/* generated by make regen-unknown, do not modify */\n\n";
print $f0 $firstline;
print $f0 "// name, dxf, handle, bytes, is_entity, num_bits, commonsize, hdloff, ".
          "strsize, hdlsize, bitsize, fieldptr\n";
print $f1a $firstline;
print $f2 $firstline;
my ($f, $f1, $foundobj, $prevdxf, $prevobj, $foundOBJECTS);
my $seekfirstobj = 0;

LINE:
while (<>) {
  my @F = split(' ');

  my $obj = substr($F[1],1,-2); # "MATERIAL",
  my $log = substr($F[2],1,-2); # "xxx.log",
  my $dxf = $F[5];
  my $fdxf = substr($dxf, 1, -2);
  if ($dxf eq 'NULL,') {
    if (-f "$dir/../$fdxf") {
      warn "$dxf magically re-appeared\n";
    } else {
      if (!exists $skip{$log}) {
        warn "skip no dxf for $log\n";
        $skip{$log}++;
      }
      next LINE; # -n
    }
  }
  if ($dxf !~ /\.dxf",/) {
    warn "skip wrong dxf $dxf in $_\n";
    next LINE; # -n
  }
  if (!-f $fdxf) {
    if (!-f "../$fdxf") {
      $fdxf = "$dir/../$dxf";
      if (!-f "$fdxf") {
        warn "$fdxf not found";
      }
    } else {
      $fdxf = "../$fdxf";
    }
  }
  #next LINE if $F[0] =~ m|//{|; # skip duplicates
  $dxf   = substr($dxf, 1, -2);
  my $hdl   = "".substr($F[3],2,-1); # 0xXXX,
  my $hexhdl = hex($hdl);
  my $bytes = substr($F[4],1,-2);
  my $is_entity  = substr($F[6],0,-1);
  my $num_bits   = substr($F[7],0,-1);
  my $commonsize = substr($F[8],0,-1);
  my $hdloff     = substr($F[9],0,-1);
  my $strsize    = substr($F[10],0,-1);
  my $hdlsize    = substr($F[11],0,-1);
  my $bitsize    = substr($F[12],0,-1);
  if ($skip{"$obj-$hdl-$num_bits"}) { # skip empty unknowns
    warn "skip empty $obj-$hdl-$num_bits $dxf\n";
    next LINE;
  }
  # picat runs out of memory there
  if ($num_bits > 50000) {
    warn "skip overlarge $obj-$hdl-$num_bits $dxf\n";
    next LINE;
  }

  my $unknown = pack ("H*", $bytes);
  $unknown = join("", map { sprintf("\\%03o", $_) } unpack("C*", $unknown));
  $unknown = substr($unknown, 0, $num_bits);

  if (exists $dupl{"$obj-$unknown"}) {
    warn "skip duplicate $obj-$hdl-$num_bits $dxf\n";
    next LINE;
  } else {
    $dupl{"$obj-$unknown"}++;
  }
  #warn "$dxf: $obj HANDLE($hdl)\n";
  # 9080187 5160203 9080187 201AA 51E0204 90C0202 35200204 20640A8 2D22020C 90A01D1
  #if ($hdl =~ /^([0-9A-F]){1,4}0([0-9A-F]+)$/) {
  #  $hdl = $2;
  #  #warn "=> try HANDLE($hdl)\n";
  #}

  # linear search in dxf file for this obj-handle

  my ($foundhdl, @FIELD, $in_entity);
  my ($react, $xdict, $seen100, @avail, @availcopy);

  if (!$f or $fdxf ne $prevdxf) {
    close $f if $f;
    $foundOBJECTS = $seekfirstobj ? 1 : 0;
    $seekfirstobj = 0;
    open $f, "$fdxf" or next LINE;
    $prevdxf = $fdxf;
  }
  if ($obj ne $prevobj) {
    # FIXME: Only needed when ENTITIES changes to OBJECTS. Within a SECTION
    # the handles strictly rise.
    seek $f, $seekfirstobj, 0;
    # also enforce a new dxffile, as the prev obj might have been be after the current one
    # and we cannot walk back.
    $prevobj = $obj;
    print $f1a "#include \"alldxf_$obj.inc\"\n";
    close $f1 if $f1;
    # objects ARE sorted
    open $f1, ">", "$dir/alldxf_$obj.inc" or next LINE;
    print $f1 $firstline;
    print $f1 "// code, value, bits, pre_bits, num_bits, type, name, num, pos[]\n";

#  } else {
#    open $f1, ">>", "$dir/alldxf_$obj.inc" or next LINE;
  }
  
  if ($obj =~ /^(?:PDF|DWF|DGN)UNDERLAY/) {
    @avail = @{$known->{UNDERLAY}};
  }
  elsif ($obj =~ /^(?:PDF|DWF|DGN)DEFINITION/) {
    @avail = @{$known->{UNDERLAYDEFINITION}};
  }
  @avail = @{$known->{$obj}} if exists $known->{$obj};
  @availcopy = @avail;

  # cannot walk back
  while (my $code = <$f>) {
    $code =~ s/\cM\cJ//;
    my $v = <$f>;
    my $name = "";
    $v =~ s/\cM\cJ//;
    $v =~ s/^\s*//;
    $foundOBJECTS = ($code == '  2' && $v =~ /^(ENTITIES|OBJECTS)$/) ? 1 : 0;
    if ($code eq '  0') { # next obj
      $foundobj = $v eq $obj;
      if ($foundhdl) {
        $foundhdl = 0;
        # search FIELD for duplicates
        my %sorted = ();
        for (@FIELD) {
          my $t = dxf_type($_->[0]);
          $sorted{"$t:$_->[1]"}++;
        }
        for (@FIELD) {
          my $t = dxf_type($_->[0]);
          my $count = $sorted{"$t:$_->[1]"};
          emit_field($f1, $obj, $count, @$_);
        }
        @FIELD = ();
        print $f1 "    { 0, NULL, NULL, 0, BITS_UNKNOWN, NULL, 0, {-1,-1,-1,-1,-1}}\n};\n";
        last;
      }
    }
    elsif ($code eq '  5') {
      $seekfirstobj = tell $f if !$seekfirstobj && $foundOBJECTS;
      if ($foundobj) {
        $name = "handle";
        $foundhdl = $v eq $hdl;
        if ($foundhdl) {
          warn "found $obj $hdl in $dxf\n";
          print $f0  "  { \"$obj\", \"$dxf\", 0x$hdl, /* $i */\n";
          printf $f0  "    \"%s\", %d, %d, %d, %d, %d, %d, %d, NULL },\n",
            $unknown, $is_entity, $num_bits, $commonsize, $hdloff, $strsize,
            $hdlsize, $bitsize;

          print $f1 "/* $obj $hdl in $dxf */\n";
          print $f1 "static struct _unknown_field unknown_dxf_${obj}_${i}\[\] = {\n";
          print $f2 "unknown_dxf\[$i\].fields = unknown_dxf_${obj}_${i};\n";
          @FIELD = ();
          @avail = @availcopy;
          $i++;
        }
      }
      elsif ($foundOBJECTS && hex($v) > $hexhdl) {
        warn "not found $obj $hdl in $dxf\n";
        last;
      }
    }
    if ($foundhdl) {
      my $x;
      $code =~ s/\s//g;
      # fill-in the field name, from heuristics and some already known classes
      if ($code == 5) {
        $name = "handle";
      } elsif ($code == 330) {
        if ($react) {
          $react--;
          $name = "reactors[$react]";
          $react++; $react++;
        } elsif (!$seen100) {
          $name = "ownerhandle";
        }
      } elsif ($code == 360 and $xdict) {
        $name = "xdicobjhandle";
      } elsif ($code == 100) {
        if ($v eq 'AcDbEntity') { $in_entity++ }
        else { $in_entity = 0 }
        $seen100++;
        if ($v eq 'AcDbModelerGeometry') {
          push @FIELD, [$code, $v, $name];
          push @FIELD, [1, "ACIS BinaryFile", "bin_sat_data"];
          next;
        }
      } elsif ($code == 102) {
        if ($v eq '{ACAD_REACTORS') {
          $react = 1;
        } elsif ($v eq '{ACAD_XDICTIONARY') {
          $xdict = 1;
        } elsif ($v eq '}') {
          $xdict = 0; $react = 0;
        }
      } elsif ($code == 430 && $obj eq 'DBCOLOR' &&
               $v =~ /DIC COLOR GUIDE\(R\)\$DIC (\d+)/)
      {
        push @FIELD, [430, "DIC $1", "name"];
        $v = "DIC COLOR GUIDE(R)";
        $name = "catalog";
      } elsif ($x = find_name($code, $obj, \@avail, \@FIELD)) {
        $name = $x;
        @avail = @availcopy unless @avail; # if exhausted via loop, restart
      } elsif ($code == 8) {
        $name = "layer";
      } elsif ($code >= 60 && $code <= 65) {
        $name = "color";
      } elsif ($code == 7) {
        $name = "ltype";
      }
      if ($in_entity && is_common_entity($code, $v, $name)) {
        push @FIELD, [$code, $v, $name, 1];
      } elsif ($code >= 1000) { # no EED
        push @FIELD, [$code, $v, $name, 1];
      } elsif ($code == 5 && !$seen100) {
        push @FIELD, [$code, $v, $name, 1];
      } else {
        push @FIELD, [$code, $v, $name];
      }
    }
  }
  # stay in there. only close on new obj or changed dxf
  #close $f;
}
close $f; close $f0; close $f1; close $f1a; close $f2;

sub is_common_entity {
  my ($code, $v, $name) = @_;
  return 1 if $code == 8 or $code == 6 or $code == 7 or $code == 62 or
              $code == 92 or $code == 160 or
              $code == 310 or $code == 420 or $code == 440;
}

sub dxf_type {
  my $code = shift;
  if ($code < 5) {
    return STR;
  } elsif ($code == 5) {
    return HDL;
  } elsif ($code < 10) {
    return STR;
  } elsif ($code < 60) {
    return DBL;
  } elsif ($code < 100) {
    return NUM;
  } elsif ($code == 102) {
    return STR;
  } elsif ($code == 105) {
    return HDL;
  } elsif ($code < 110) {
    return STR;
  } elsif ($code < 160) {
    return DBL;
  } elsif ($code < 210) {
    return NUM;
  } elsif ($code < 240) {
    return DBL;
  } elsif ($code < 289) {
    return NUM;
  } elsif ($code < 299) {
    return B;
  } elsif ($code < 320) {
    return STR;
  } elsif ($code < 370) {
    return HDL;
  } elsif ($code < 390) {
    return NUM;
  } elsif ($code < 400) {
    return HDL;
  } elsif ($code < 410) {
    return NUM;
  } elsif ($code < 420) {
    return STR;
  } elsif ($code < 430) {
    return NUM;
  } elsif ($code < 440) {
    return STR;
  } elsif ($code < 460) {
    return NUM;
  } elsif ($code < 470) {
    return DBL;
  } elsif ($code < 480) {
    return STR;
  } elsif ($code < 481) {
    return HDL;
  } elsif ($code < 1010) { # eed fields:
    return STR;
  } elsif ($code < 1060) {
    return DBL;
  } elsif ($code <= 1071) {
    return NUM;
  }
  warn "unknown DXF code $code\n";
  return UNKNOWN;
}

sub find_name {
  my ($code, $obj, $avail, $fieldsref) = @_;
  my @f = @$avail;
  return undef if !@f;
  my $len = scalar @f;
  for my $j (0..(2*$len)-1) {
    my $c = $f[$j];
    if ($c == $code) {
      # delete ($c,$n) from $avail
      splice @$avail, $j, 2;
      my $n = $f[$j+1];
      return $n;
    }
  }
  return undef;
}

sub emit_field {
  my ($f, $obj, $count, $code, $v, $name, $hidden) = @_;
  #warn "$code: $v\n";
  #return if $code == 100;
  $v =~ s/\\/\\\\/g;
  $v =~ s/"/\\"/g;
  # encode $v via cquote
  my $vq = B::cstring ($v);
  $count = 0 unless $count;
  # code, value, bytes, bitsize, type, name, num, pos[]
  if ($hidden) {
    print $f "  //";
  } else {
    print $f "    ";
  }
  my $bits = 0;
  my $type = "BITS_UNKNOWN";
  # need stronger hints for some fields
  if ($obj eq 'DIMASSOC') {
    if ($name =~ /(osnap_type|trans_space_flag)$/) {
      $type = "BITS_RC";
      $bits = 8;
    }
    elsif ($name =~ /has_lastpt_ref/) { # weird dxf code
      $type = "BITS_B";
      $bits = 1;
    }
    elsif ($name =~ /\.osnap_/) {
      $type = "BITS_BD";
    }
  }
  print $f "{ $code, $vq, NULL, $bits, $type, \"$name\", $count, {-1,-1,-1,-1,-1} },\n";
}