From 3e3228718225ae48148146bea2c22d1fadd17289 Mon Sep 17 00:00:00 2001
From: Felipe Castro <fefcas@gmail.com>
Date: Fri, 16 Aug 2013 22:15:15 -0300
Subject: [PATCH 22/22] |[build][examples] Added a dump program and some
 necessary code clean-up in ./src/ files.

---
 examples/Makefile.am       |   12 +-
 examples/dump.c            |  277 ++++++++++++++++++++++++++++++++++++++++++++
 examples/dump_objects.in.c |  182 +++++++++++++++++++++++++++++
 src/bits.h                 |   14 ---
 src/classes.c              |    4 +-
 src/common.c               |    9 +-
 src/common.h               |   43 +------
 src/decode.c               |    6 +-
 src/dwg.c                  |    9 +-
 src/dwg.h                  |   46 +++++---
 src/dwg.spec               |  127 ++++++++++----------
 src/encode.c               |    5 +-
 src/handle.c               |    4 +-
 src/header.c               |    4 +-
 src/section_locate.c       |    8 +-
 15 files changed, 593 insertions(+), 157 deletions(-)
 create mode 100644 examples/dump.c
 create mode 100644 examples/dump_objects.in.c

diff --git a/examples/Makefile.am b/examples/Makefile.am
index 0b04d35..1e96d55 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -17,7 +17,7 @@
 ## You should have received a copy of the GNU General Public License
 ## along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-check_PROGRAMS = load_dwg get_bmp test testSVG
+check_PROGRAMS = load_dwg get_bmp test testSVG dump
 
 if HAVE_LIBPS
 check_PROGRAMS += dwg_ps
@@ -36,6 +36,10 @@ load_dwg_SOURCES = load_dwg.c
 
 get_bmp_SOURCES = get_bmp.c
 
+dump_SOURCES = dump.c
+
+BUILT_SOURCES = dump_objects.c
+
 AM_CFLAGS = -Wextra -I$(top_srcdir)/src
 
 TESTS_ENVIRONMENT = \
@@ -44,4 +48,8 @@ TESTS_ENVIRONMENT = \
 
 TESTS = alive.test
 
-EXTRA_DIST = example.dwg sample.dwg suffix.c load_dwg.py $(TESTS)
+EXTRA_DIST = example.dwg sample.dwg suffix.c load_dwg.py dump_objects.in.c $(TESTS)
+
+dump_objects.c: dump_objects.in.c
+	$(CPP) -P $(AM_CFLAGS) dump_objects.in.c > dump_objects.c
+	indent dump_objects.c
diff --git a/examples/dump.c b/examples/dump.c
new file mode 100644
index 0000000..59c017e
--- /dev/null
+++ b/examples/dump.c
@@ -0,0 +1,277 @@
+/*****************************************************************************/
+/*  LibreDWG - free implementation of the DWG file format                    */
+/*                                                                           */
+/*  Copyright (C) 2013 Free Software Foundation, Inc.                        */
+/*                                                                           */
+/*  This library is free software, licensed under the terms of the GNU       */
+/*  General Public License as published by the Free Software Foundation,     */
+/*  either version 3 of the License, or (at your option) any later version.  */
+/*  You should have received a copy of the GNU General Public License        */
+/*  along with this program.  If not, see <http://www.gnu.org/licenses/>.    */
+/*****************************************************************************/
+
+/**
+ *     \file       dump.c
+ *     \brief      Dump functions
+ *     \author     written by Rodrigo Rodrigues da Silva
+ *     \author     modified by Felipe E. F. de Castro
+ *     \version    
+ *     \copyright  GNU General Public License (version 3 or later)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "dwg.h"
+#include "logging.h"
+
+#include "dump_objects.c"
+
+void
+dump_object (Dwg_Object * obj)
+{
+  Dwg_Version_Type dwg_version = obj->parent->header.version;
+
+  switch (obj->type)
+    {
+    case DWG_TYPE_TEXT:
+      dump_TEXT (obj);
+      break;
+    case DWG_TYPE_ATTRIB:
+      dump_ATTRIB (obj);
+      break;
+    case DWG_TYPE_ATTDEF:
+      dump_ATTDEF (obj);
+      break;
+    case DWG_TYPE_BLOCK:
+      dump_BLOCK (obj);
+      break;
+    case DWG_TYPE_ENDBLK:
+      dump_ENDBLK (obj);
+      break;
+    case DWG_TYPE_SEQEND:
+      dump_SEQEND (obj);
+      break;
+    case DWG_TYPE_INSERT:
+      dump_INSERT (obj);
+      break;
+    case DWG_TYPE_MINSERT:
+      dump_MINSERT (obj);
+      break;
+    case DWG_TYPE_VERTEX_2D:
+      dump_VERTEX_2D (obj);
+      break;
+    case DWG_TYPE_VERTEX_3D:
+      dump_VERTEX_3D (obj);
+      break;
+    case DWG_TYPE_VERTEX_MESH:
+      dump_VERTEX_MESH (obj);
+      break;
+    case DWG_TYPE_VERTEX_PFACE:
+      dump_VERTEX_PFACE (obj);
+      break;
+    case DWG_TYPE_VERTEX_PFACE_FACE:
+      dump_VERTEX_PFACE_FACE (obj);
+      break;
+    case DWG_TYPE_POLYLINE_2D:
+      dump_POLYLINE_2D (obj);
+      break;
+    case DWG_TYPE_POLYLINE_3D:
+      dump_POLYLINE_3D (obj);
+      break;
+    case DWG_TYPE_ARC:
+      dump_ARC (obj);
+      break;
+    case DWG_TYPE_CIRCLE:
+      dump_CIRCLE (obj);
+      break;
+    case DWG_TYPE_LINE:
+      dump_LINE (obj);
+      break;
+    case DWG_TYPE_DIMENSION_ORDINATE:
+      dump_DIMENSION_ORDINATE (obj);
+      break;
+    case DWG_TYPE_DIMENSION_LINEAR:
+      dump_DIMENSION_LINEAR (obj);
+      break;
+    case DWG_TYPE_DIMENSION_ALIGNED:
+      dump_DIMENSION_ALIGNED (obj);
+      break;
+    case DWG_TYPE_DIMENSION_ANG3PT:
+      dump_DIMENSION_ANG3PT (obj);
+      break;
+    case DWG_TYPE_DIMENSION_ANG2LN:
+      dump_DIMENSION_ANG2LN (obj);
+      break;
+    case DWG_TYPE_DIMENSION_RADIUS:
+      dump_DIMENSION_RADIUS (obj);
+      break;
+    case DWG_TYPE_DIMENSION_DIAMETER:
+      dump_DIMENSION_DIAMETER (obj);
+      break;
+    case DWG_TYPE_POINT:
+      dump_POINT (obj);
+      break;
+    case DWG_TYPE__3DFACE:
+      dump__3DFACE (obj);
+      break;
+    case DWG_TYPE_POLYLINE_PFACE:
+      dump_POLYLINE_PFACE (obj);
+      break;
+    case DWG_TYPE_POLYLINE_MESH:
+      dump_POLYLINE_MESH (obj);
+      break;
+    case DWG_TYPE_SOLID:
+      dump_SOLID (obj);
+      break;
+    case DWG_TYPE_TRACE:
+      dump_TRACE (obj);
+      break;
+    case DWG_TYPE_SHAPE:
+      dump_SHAPE (obj);
+      break;
+    case DWG_TYPE_VIEWPORT:
+      dump_VIEWPORT (obj);
+      break;
+    case DWG_TYPE_ELLIPSE:
+      dump_ELLIPSE (obj);
+      break;
+    case DWG_TYPE_SPLINE:
+      dump_SPLINE (obj);
+      break;
+    case DWG_TYPE_REGION:
+      dump_REGION (obj);
+      break;
+    case DWG_TYPE_3DSOLID:
+      dump__3DSOLID (obj);
+      break;
+      /* Check the type of the object */
+    case DWG_TYPE_BODY:
+      dump_BODY (obj);
+      break;
+    case DWG_TYPE_RAY:
+      dump_RAY (obj);
+      break;
+    case DWG_TYPE_XLINE:
+      dump_XLINE (obj);
+      break;
+    case DWG_TYPE_DICTIONARY:
+      dump_DICTIONARY (obj);
+      break;
+    case DWG_TYPE_MTEXT:
+      dump_MTEXT (obj);
+      break;
+    case DWG_TYPE_LEADER:
+      dump_LEADER (obj);
+      break;
+    case DWG_TYPE_TOLERANCE:
+      dump_TOLERANCE (obj);
+      break;
+    case DWG_TYPE_MLINE:
+      dump_MLINE (obj);
+      break;
+    case DWG_TYPE_BLOCK_CONTROL:
+      dump_BLOCK_CONTROL (obj);
+      break;
+    case DWG_TYPE_BLOCK_HEADER:
+      dump_BLOCK_HEADER (obj);
+      break;
+    case DWG_TYPE_LAYER_CONTROL:
+      dump_LAYER_CONTROL (obj);
+      break;
+    case DWG_TYPE_LAYER:
+      dump_LAYER (obj);
+      break;
+    case DWG_TYPE_SHAPEFILE_CONTROL:
+      dump_SHAPEFILE_CONTROL (obj);
+      break;
+    case DWG_TYPE_SHAPEFILE:
+      dump_SHAPEFILE (obj);
+      break;
+    case DWG_TYPE_LTYPE_CONTROL:
+      dump_LTYPE_CONTROL (obj);
+      break;
+    case DWG_TYPE_LTYPE:
+      dump_LTYPE (obj);
+      break;
+    case DWG_TYPE_VIEW_CONTROL:
+      dump_VIEW_CONTROL (obj);
+      break;
+    case DWG_TYPE_VIEW:
+      dump_VIEW (obj);
+      break;
+    case DWG_TYPE_UCS_CONTROL:
+      dump_UCS_CONTROL (obj);
+      break;
+    case DWG_TYPE_UCS:
+      dump_UCS (obj);
+      break;
+    case DWG_TYPE_VPORT_CONTROL:
+      dump_VPORT_CONTROL (obj);
+      break;
+    case DWG_TYPE_VPORT:
+      dump_VPORT (obj);
+      break;
+    case DWG_TYPE_APPID_CONTROL:
+      dump_APPID_CONTROL (obj);
+      break;
+    case DWG_TYPE_APPID:
+      dump_APPID (obj);
+      break;
+    case DWG_TYPE_DIMSTYLE_CONTROL:
+      dump_DIMSTYLE_CONTROL (obj);
+      break;
+    case DWG_TYPE_DIMSTYLE:
+      dump_DIMSTYLE (obj);
+      break;
+    case DWG_TYPE_VP_ENT_HDR_CONTROL:
+      dump_VP_ENT_HDR_CONTROL (obj);
+      break;
+    case DWG_TYPE_VP_ENT_HDR:
+      dump_VP_ENT_HDR (obj);
+      break;
+    case DWG_TYPE_GROUP:
+      dump_GROUP (obj);
+      break;
+    case DWG_TYPE_MLINESTYLE:
+      dump_MLINESTYLE (obj);
+      break;
+    default:
+      if (obj->type == obj->parent->dwg_ot_layout)
+	dump_LAYOUT (obj);
+      else
+	printf ("Unknown type: %u\n", obj->type);
+    }
+}
+
+int
+main (int argc, char *argv[])
+{
+  unsigned int i;
+  int success;
+  Dwg_Data dwg;
+
+  if (1 == argc)
+    {
+      puts ("No input file specified");
+      return 1;
+    }
+
+  dwg.num_objects = 0;
+  success = dwg_read_file (argv[1], &dwg);
+  if (success)
+    return (success);
+
+  puts ("-------------------");
+  puts ("DWG dumped data");
+  printf ("num_objects: %lu\n", dwg.num_objects);
+  puts ("-------------------");
+
+  for (i = 0; i < dwg.num_objects; i++)
+    {
+      printf ("[%u] ", i);
+      dump_object (&dwg.object[i]);
+    }
+
+  return 0;
+}
diff --git a/examples/dump_objects.in.c b/examples/dump_objects.in.c
new file mode 100644
index 0000000..31b4da5
--- /dev/null
+++ b/examples/dump_objects.in.c
@@ -0,0 +1,182 @@
+/*****************************************************************************/
+/*  LibreDWG - free implementation of the DWG file format                    */
+/*                                                                           */
+/*  Copyright (C) 2013 Free Software Foundation, Inc.                        */
+/*                                                                           */
+/*  This library is free software, licensed under the terms of the GNU       */
+/*  General Public License as published by the Free Software Foundation,     */
+/*  either version 3 of the License, or (at your option) any later version.  */
+/*  You should have received a copy of the GNU General Public License        */
+/*  along with this program.  If not, see <http://www.gnu.org/licenses/>.    */
+/*****************************************************************************/
+
+/**
+ *     \file       objects_dump.c.in
+ *     \brief      Dump object contents. It is pre-preprocessed to generate 'objects_dump.c'.
+ *     \author     written by Rodrigo Rodrigues da Silva
+ *     \author     modified by Felipe E. F. de Castro
+ *     \version    
+ *     \copyright  GNU General Public License (version 3 or later)
+ */
+
+/* Definitions copied from ../src/common.h
+ * They are needed in the ".spec" files, to generate 'objects_dump.c'.
+ */
+#define VERSION(v) if (obj->parent->header.version == v)
+#define VERSIONS(v1,v2) if (obj->parent->header.version >= v1 && obj->parent->header.version <= v2)
+#define OTHER_VERSIONS else
+#define PRE(v) if (obj->parent->header.version < v)
+#define SINCE(v) if (obj->parent->header.version >= v)
+#define PRIOR_VERSIONS else
+#define UNTIL(v) if (obj->parent->header.version <= v)
+#define LATER_VERSIONS else
+/* End of copied definitions  */
+
+#define FIELD(name,type)\
+  printf ("  " #name ": " FORMAT_##type "\n", _obj->name);
+
+#define FIELD_VALUE(name) _obj->name
+
+#define ANYCODE -1
+#define FIELD_HANDLE(name, handle_code)\
+  printf ("  " #name ": HANDLE(%1X.%d.%lu) absolute:%lu\n",\
+        _obj->name->handleref.code,\
+        _obj->name->handleref.size,\
+        _obj->name->handleref.value,\
+        _obj->name->absolute_ref);
+
+#define FIELD_B(name) FIELD(name, B);
+#define FIELD_BB(name) FIELD(name, BB);
+#define FIELD_BS(name) FIELD(name, BS);
+#define FIELD_BL(name) FIELD(name, BL);
+#define FIELD_BD(name) FIELD(name, BD);
+#define FIELD_RC(name) FIELD(name, RC);
+#define FIELD_RS(name) FIELD(name, RS);
+#define FIELD_RD(name) FIELD(name, RD);
+#define FIELD_RL(name) FIELD(name, RL);
+#define FIELD_MC(name) FIELD(name, MC);
+#define FIELD_MS(name) FIELD(name, MS);
+#define FIELD_TV(name) FIELD(name, TV);
+#define FIELD_T FIELD_TV	/*TODO: implement version dependant string fields */
+#define FIELD_BT(name) FIELD(name, BT);
+#define FIELD_4BITS(name)	//_obj->name = bit_read_4BITS(dat);
+
+// bit_read_BE(dat, &_obj->name.x, &_obj->name.y, &_obj->name.z);
+#define FIELD_BE(name)
+
+// FIELD_VALUE(name) = bit_read_DD(dat, _default);
+#define FIELD_DD(name, _default)
+#define FIELD_2DD(name, d1, d2) FIELD_DD(name.x, d1); FIELD_DD(name.y, d2);
+#define FIELD_2RD(name) FIELD(name.x, RD); FIELD(name.y, RD);
+#define FIELD_2BD(name) FIELD(name.x, BD); FIELD(name.y, BD);
+#define FIELD_3RD(name) FIELD(name.x, RD); FIELD(name.y, RD); FIELD(name.z, RD);
+#define FIELD_3BD(name) FIELD(name.x, BD); FIELD(name.y, BD); FIELD(name.z, BD);
+#define FIELD_3DPOINT(name) FIELD_3BD(name)
+#define FIELD_CMC(name)\
+    printf ("  " #name ": index %d\n", _obj->name.index);
+
+/* FIELD_VECTOR_N(name, type, size):
+ * reads data of the type indicated by 'type' 'size' times and stores
+ * it all in the vector called 'name' */
+#define FIELD_VECTOR_N(name, type, size)\
+    for (vcount=0; vcount< size; vcount++)\
+      {\
+        printf ("  " #name "[%d]: " FORMAT_##type "\n", vcount, _obj->name[vcount]);\
+      }\
+
+#define FIELD_VECTOR(name, type, size) FIELD_VECTOR_N(name, type, _obj->size)
+
+#define FIELD_2RD_VECTOR(name, size)\
+  for (vcount=0; vcount< _obj->size; vcount++)\
+    {\
+      FIELD_2RD(name[vcount]);\
+    }
+
+#define FIELD_2DD_VECTOR(name, size)\
+  FIELD_2RD(name[0]);\
+  for (vcount = 1; vcount < _obj->size; vcount++)\
+    {\
+      FIELD_2DD(name[vcount], FIELD_VALUE(name[vcount - 1].x), FIELD_VALUE(name[vcount - 1].y));\
+    }
+
+#define FIELD_3DPOINT_VECTOR(name, size)\
+  for (vcount=0; vcount< _obj->size; vcount++)\
+    {\
+      FIELD_3DPOINT(name[vcount]);\
+    }
+
+#define HANDLE_VECTOR_N(name, size, code)\
+  for (vcount=0; vcount<size; vcount++)\
+    {\
+      FIELD_HANDLE(name[vcount], code);\
+    }
+
+#define HANDLE_VECTOR(name, sizefield, code) HANDLE_VECTOR_N(name, FIELD_VALUE(sizefield), code)
+
+#define FIELD_XDATA(name, size)
+
+#define REACTORS(code)\
+  for (vcount=0; vcount<obj->tio.object->num_reactors; vcount++)\
+    {\
+      FIELD_HANDLE(reactors[vcount], code);\
+    }
+
+#define XDICOBJHANDLE(code)\
+  if (obj->parent->header.version >= R_2004)\
+    {\
+      if (!obj->tio.object->xdic_missing_flag)\
+        FIELD_HANDLE(xdicobjhandle, code);\
+    }\
+  else\
+    {\
+      FIELD_HANDLE(xdicobjhandle, code);\
+    }
+
+#define REPEAT_N(times, name, type) \
+  for (rcount=0; rcount<times; rcount++)
+
+#define REPEAT(times, name, type) \
+  for (rcount=0; rcount<_obj->times; rcount++)
+
+#define REPEAT2(times, name, type) \
+  for (rcount2=0; rcount2<_obj->times; rcount2++)
+
+#define REPEAT3(times, name, type) \
+  for (rcount3=0; rcount3<_obj->times; rcount3++)
+
+#define COMMON_ENTITY_HANDLE_DATA	// Empty
+
+#define DWG_ENTITY(token) \
+void \
+dump_##token (Dwg_Object * obj)\
+{\
+  unsigned int vcount, rcount, rcount2, rcount3;\
+  Dwg_Entity_##token *ent, *_obj;\
+  printf ("Entity " #token ":\n");\
+  ent = obj->tio.entity->tio.token;\
+  _obj=ent;\
+  printf ("  Handle: %1X.%d.%lu\n",\
+    obj->handle.code,\
+    obj->handle.size,\
+    obj->handle.value);
+
+#define DWG_ENTITY_END }
+
+#define DWG_OBJECT(token) \
+void \
+dump_##token (Dwg_Object * obj) \
+{ \
+  unsigned int vcount, rcount, rcount2, rcount3;\
+  Dwg_Object_##token *_obj;\
+  printf ("Object " #token ":\n");\
+  _obj = obj->tio.object->tio.token;\
+  printf ("  Handle: %1X.%d.%lu\n",\
+    obj->handle.code,\
+    obj->handle.size,\
+    obj->handle.value);
+
+#define DWG_OBJECT_END }
+
+#define IS_PRINT
+#include "dwg.spec"
+#undef IS_PRINT
diff --git a/src/bits.h b/src/bits.h
index daeb22d..e890e78 100644
--- a/src/bits.h
+++ b/src/bits.h
@@ -32,21 +32,7 @@
 #ifndef BITS_H
 #define BITS_H
 
-#ifndef DWG_H
 #include "dwg.h"
-#endif
-
-#include "common.h"
-
-/** Structure for DWG-files raw data storage */
-typedef struct _bit_chain
-{
-  unsigned char *chain;
-  long unsigned int size;
-  long unsigned int byte;
-  unsigned char bit;
-  Dwg_Version_Type version;
-} Bit_Chain;
 
 /* Functions for raw data manipulations
  */
diff --git a/src/classes.c b/src/classes.c
index 72ec3ee..5738875 100644
--- a/src/classes.c
+++ b/src/classes.c
@@ -90,7 +90,7 @@ read_R13_R15_section_classes(Bit_Chain *dat, Dwg_Data *dwg)
 
   if (ckr != ckr2)
     {
-      printf("section %d crc todo ckr: %x ckr2:%x \n",
+      LOG_ERROR("section %d CRC mismatch crc1: %x crc2:%x \n",
               dwg->header.section[1].number, ckr, ckr2);
       return -1;
     }
@@ -181,7 +181,7 @@ read_2004_section_classes(Bit_Chain *dat, Dwg_Data *dwg)
  
   if (ckr != ckr2)
     {
-      printf("Section %d crc todo ckr:%x ckr2:%x \n\n",
+      LOG_ERROR("Section %d CRC mismatch. crc1: %x crc2:%x \n",
               dwg->header.section[1].number, ckr, ckr2);
       return -1;
     }
diff --git a/src/common.c b/src/common.c
index 7c6e423..9db0c2b 100644
--- a/src/common.c
+++ b/src/common.c
@@ -13,16 +13,16 @@
 /**
  *     \file       common.c
  *     \brief      Common data arrays
- *     \author     written by Felipe Castro
+ *     \author     written and modified by Felipe Castro
  *     \author     modified by Felipe Corrêa da Silva Sances
  *     \author     modified by Rodrigo Rodrigues da Silva
  *     \version    
  *     \copyright  GNU General Public License (version 3 or later)
  */
 
+#include <stdio.h>
 #include "config.h"
 #include "common.h"
-#include "stdio.h"
 
 /** DWG sentinel */
 unsigned char *
@@ -53,8 +53,3 @@ dwg_sentinel(Dwg_Sentinel s)
 }
 
 
-/* TODO: update with new codes */
-/** DWG version codes */
-char version_codes[8][7] =
-  { "------", "AC1012", "AC1014", "AC1015", "AC1018", "AC1021", "AC1024", "------" };
-
diff --git a/src/common.h b/src/common.h
index 1de55ee..ee07755 100644
--- a/src/common.h
+++ b/src/common.h
@@ -13,7 +13,7 @@
 /**
  *     \file       common.h
  *     \brief      Common general functions and macro
- *     \author     written by Felipe Castro
+ *     \author     written and modified by Felipe Castro
  *     \author     modified by Felipe Corrêa da Silva Sances
  *     \author     modified by Rodrigo Rodrigues da Silva
  *     \version    
@@ -32,44 +32,6 @@
 #define UNTIL(v) if (dat->version <= v)
 #define LATER_VERSIONS else
 
-/** DWG version type */
-typedef enum DWG_VERSION_TYPE
-{
-  R_BEFORE, R_13, R_14, R_2000, R_2004, R_2007, R_2010, R_AFTER
-} Dwg_Version_Type;
-extern char version_codes[8][7];
-
-/** Data types (including compressed forms) used trough the file */
-typedef enum DWG_DATA_TYPE
-{
-  DWG_DT_B,   /**< bit (1 or 0) */
-  DWG_DT_BB,  /**< special 2-bit code (entmode in entities, for instance) */
-  DWG_DT_RC,  /**< raw char (not compressed) */
-  DWG_DT_RS,  /**< raw short (not compressed) */
-  DWG_DT_RD,  /**< raw double (not compressed) */
-  DWG_DT_RL,  /**< raw long (not compressed) */
-  DWG_DT_BS,  /**< bitshort */
-  DWG_DT_BL,  /**< bitlong */
-  DWG_DT_BD,  /**< bitdouble */
-  DWG_DT_MC,  /**< modular char */
-  DWG_DT_MS,  /**< modular short  */
-  DWG_DT_BE,  /**< BitExtrusion */
-  DWG_DT_DD,  /**< BitDouble With Default */
-  DWG_DT_BT,  /**< BitThickness */
-  DWG_DT_H,   /**< handle reference (see the HANDLE REFERENCES section) */
-  DWG_DT_CMC, /**< CmColor value */
-  DWG_DT_T,   /**< text (bitshort length, followed by the string) */
-  DWG_DT_TU,  /**< Unicode text (bitshort character length, followed by
-                   Unicode string, 2 bytes per character). Unicode text
-                   is read from the “string stream” within the object data,
-                   see the main Object description section for details. */
-  DWG_DT_2RD, /**< 2 raw doubles */
-  DWG_DT_3RD, /**< 3 raw doubles */
-  DWG_DT_2BD, /**< 2D point (2 bitdoubles) */
-  DWG_DT_3BD, /**< 3D point (3 bitdoubles) */
-  DWG_END_OF_HEADER_VARIABLES
-} Dwg_Data_Type;
-
 /** References of sentinels */
 typedef enum DWG_SENTINEL
 {
@@ -84,9 +46,6 @@ typedef enum DWG_SENTINEL
   DWG_SENTINEL_SECOND_HEADER_END
 } Dwg_Sentinel;
 
-Dwg_Data_Type
-dwg_var_map(Dwg_Version_Type version, int index);
-
 unsigned char *
 dwg_sentinel(Dwg_Sentinel sentinel);
 
diff --git a/src/decode.c b/src/decode.c
index 5ab2fef..30cc2ed 100644
--- a/src/decode.c
+++ b/src/decode.c
@@ -21,6 +21,7 @@
  *     \copyright  GNU General Public License (version 3 or later)
  */
 
+#include "dwg.h"
 #include "decode.h"
 #include "logging.h"
 #include "decode_r13_r15.h"
@@ -37,7 +38,10 @@ static unsigned int loglevel;
  */
 static bool env_var_checked_p;
 
-#define DWG_LOGLEVEL loglevel
+#  ifdef DWG_LOGLEVEL
+#    undef DWG_LOGLEVEL
+#  endif
+#  define DWG_LOGLEVEL loglevel
 #endif  // USE_TRACING
 
 #define REFS_PER_REALLOC 100
diff --git a/src/dwg.c b/src/dwg.c
index 315d25d..96e65d8 100644
--- a/src/dwg.c
+++ b/src/dwg.c
@@ -13,7 +13,7 @@
 /**
  *     \file       dwg.c
  *     \brief      Main functions and API
- *     \author     written by Felipe Castro
+ *     \author     written and modified by Felipe Castro
  *     \author     modified by Felipe Corrêa da Silva Sances
  *     \author     modified by Rodrigo Rodrigues da Silva
  *     \author     modified by Anderson Pierre Cardoso
@@ -27,12 +27,17 @@
 #include <string.h>
 #include <sys/stat.h>
 
+#include "dwg.h"
 #include "bits.h"
 #include "common.h"
 #include "decode.h"
-#include "dwg.h"
 #include "logging.h"
 
+/* TODO: update with new codes */
+/** DWG version codes */
+char version_codes[8][7] =
+  { "------", "AC1012", "AC1014", "AC1015", "AC1018", "AC1021", "AC1024", "------" };
+
 int
 dwg_read_file(char *filename, Dwg_Data *dwg_data)
 {
diff --git a/src/dwg.h b/src/dwg.h
index 538d2df..a136519 100644
--- a/src/dwg.h
+++ b/src/dwg.h
@@ -13,7 +13,7 @@
 /**
  *     \file       dwg.h
  *     \brief      Main include file
- *     \author     written by Felipe Castro
+ *     \author     written and modified by Felipe Castro
  *     \author     modified by Felipe Corrêa da Silva Sances
  *     \author     modified by Rodrigo Rodrigues da Silva
  *     \author     modified by Till Heuschmann
@@ -21,6 +21,7 @@
  *     \copyright  GNU General Public License (version 3 or later)
  */
 
+
 #ifndef DWG_H
 #define DWG_H
 
@@ -31,7 +32,7 @@
 
 #define BITCODE_DOUBLE double
 
-#define BITCODE_RC char
+#define BITCODE_RC unsigned char
 #define FORMAT_RC "%2x"
 #define BITCODE_MC long int
 #define FORMAT_MC "%l"
@@ -115,6 +116,29 @@ typedef struct _dwg_bitecode_3bd
 #define BITCODE_3DPOINT BITCODE_3BD
 
 /**
+ *    \enum    DWG_VERSION_TYPE
+ *    \brief   Version for the dwg data spec
+ */
+typedef enum DWG_VERSION_TYPE
+{
+  R_BEFORE=0, R_13, R_14, R_2000, R_2004, R_2007, R_2010, R_AFTER
+} Dwg_Version_Type;
+extern char version_codes[8][7];
+
+/**
+ *    \struct  _bit_chain
+ *    \brief   Bit chain of encoded dwg data
+ */
+typedef struct _bit_chain
+{
+  unsigned char *chain;
+  long unsigned int size;
+  long unsigned int byte;
+  unsigned char bit;
+  Dwg_Version_Type version;
+} Bit_Chain;
+
+/**
  *    \enum    DWG_OBJECT_SUPERTYPE
  *    \brief   Object supertypes that exist in dwg-files
  */
@@ -2858,18 +2882,6 @@ typedef struct _dwg_class
 } Dwg_Class;
 
 /**
- *    \struct  _dwg_chain
- *    \brief   Dwg_Chain same as Bit_Chain in "bits.h"
- */
-typedef struct _dwg_chain
-{
-  unsigned char *chain;
-  long unsigned int size;
-  long unsigned int byte;
-  unsigned char bit;
-} Dwg_Chain;
-
-/**
  *    \struct  _dwg_section
  *    \brief   Struct for DWG section
  */
@@ -2929,7 +2941,7 @@ typedef struct _dwg_struct
 {
   struct
   {
-    unsigned int version;
+    Dwg_Version_Type version;
     unsigned int codepage;
     unsigned int num_sections;
     Dwg_Section* section;
@@ -2938,9 +2950,9 @@ typedef struct _dwg_struct
   } header;
 
   #define DWG_UNKNOWN1_SIZE 123
-  Dwg_Chain unknown1;
+  Bit_Chain unknown1;
 
-  Dwg_Chain picture;
+  Bit_Chain picture;
 
   Dwg_Header_Variables header_vars;
   unsigned int num_classes;
diff --git a/src/dwg.spec b/src/dwg.spec
index cb04a27..70011a7 100644
--- a/src/dwg.spec
+++ b/src/dwg.spec
@@ -1,7 +1,7 @@
 /*****************************************************************************/
 /*  LibreDWG - free implementation of the DWG file format                    */
 /*                                                                           */
-/*  Copyright (C) 2009, 2010 Free Software Foundation, Inc.                  */
+/*  Copyright (C) 2009, 2010, 2013 Free Software Foundation, Inc.            */
 /*                                                                           */
 /*  This library is free software, licensed under the terms of the GNU       */
 /*  General Public License as published by the Free Software Foundation,     */
@@ -13,31 +13,22 @@
 /**
  *     \file       dwg.spec
  *     \brief      DWG entities and objects specification
- *     \author     written by Felipe Castro
+ *     \author     written and modified by Felipe Castro
  *     \author     modified by Rodrigo Rodrigues da Silva
  *     \author     modified by Till Heuschmann
  *     \version    
  *     \copyright  GNU General Public License (version 3 or later)
  */
 
-#ifdef IS_ENCODER
-#define ENCODER if (1)
-#define DECODER if (0)
-#endif
-
-#ifdef IS_DECODER
-#define ENCODER if (0)
-#define DECODER if (1)
-#endif
-
 #ifdef IS_PRINT
-#define ENCODER if (0)
-#define DECODER if (0)
+#undef IS_ENCODER
+#undef IS_DECODER
 #endif
 
 #define TODO_ENCODER fprintf(stderr, "TODO: Encoder\n");
 #define TODO_DECODER fprintf(stderr, "TODO: Decoder\n");
 
+#ifdef IS_PRINT
 /* ----------------------------------------
  * Private Functions
  */
@@ -46,6 +37,7 @@ decode_3dsolid(Bit_Chain* dat, Dwg_Object* obj, Dwg_Entity_3DSOLID* _obj);
 
 void
 encode_3dsolid(Bit_Chain* dat, Dwg_Object* obj, Dwg_Entity_3DSOLID* _obj);
+#endif
 
 DWG_ENTITY(UNUSED);
 
@@ -338,7 +330,7 @@ DWG_ENTITY(INSERT);
 
   SINCE(R_2000)
     {
-      DECODER
+#     ifdef IS_DECODER
         {
           FIELD(scale_flag, BB);
           if (FIELD_VALUE(scale_flag) == 3)
@@ -366,8 +358,9 @@ DWG_ENTITY(INSERT);
               FIELD_DD(scale.z, FIELD_VALUE(scale.x));
             }
         }
+#     endif
 
-      ENCODER
+#     ifdef IS_ENCODER
         {
           if (FIELD_VALUE(scale.x)==1.0 && FIELD_VALUE(scale.y)==1.0 && FIELD_VALUE(scale.z)==1.0)
             {
@@ -396,7 +389,8 @@ DWG_ENTITY(INSERT);
               FIELD_DD(scale.y, FIELD_VALUE(scale.x));
               FIELD_DD(scale.z, FIELD_VALUE(scale.x));
             }
-        }
+       }
+#    endif
     }
 
   FIELD(rotation_ang, BD);
@@ -455,7 +449,7 @@ DWG_ENTITY(MINSERT);
 
   SINCE(R_2000)
     {
-      DECODER
+#     ifdef IS_DECODER
         {
           FIELD(scale_flag, BB);
           if (FIELD_VALUE(scale_flag) == 3){
@@ -480,8 +474,9 @@ DWG_ENTITY(MINSERT);
               FIELD_DD(scale.z, FIELD_VALUE(scale.x));
             }
         }
+#     endif
 
-      ENCODER
+#     ifdef IS_ENCODER
         {
           if (FIELD_VALUE(scale.x) == FIELD_VALUE(scale.y) == FIELD_VALUE(scale.z) == 1.0)
             {
@@ -510,6 +505,7 @@ DWG_ENTITY(MINSERT);
               FIELD_DD(scale.z, FIELD_VALUE(scale.x));
              }
         }
+#     endif
     }
 
   FIELD(rotation_ang, BD);
@@ -564,7 +560,7 @@ DWG_ENTITY(VERTEX_2D);
 data when saving. So we explicitely implemented the encoder routine with the
 compression technique described in the spec. --Juca */
 
-  DECODER
+# ifdef IS_DECODER
     {
       FIELD(start_width, BD);
  
@@ -578,8 +574,9 @@ compression technique described in the spec. --Juca */
           FIELD(end_width, BD);
         }
     }
+# endif
 
-  ENCODER
+# ifdef IS_ENCODER
     {
       if (FIELD_VALUE(start_width) && FIELD_VALUE(start_width)==FIELD_VALUE(end_width))
         {
@@ -594,6 +591,7 @@ compression technique described in the spec. --Juca */
           FIELD(end_width, BD);
         }
     }
+# endif
 
   FIELD(bulge, BD);
   FIELD(tangent_dir, BD);
@@ -742,7 +740,7 @@ DWG_ENTITY(LINE);
 
   SINCE(R_2000)
     {
-      DECODER
+#     ifdef IS_DECODER
         {
           FIELD(Zs_are_zero, B);
           FIELD(start.x, RD);
@@ -761,8 +759,9 @@ DWG_ENTITY(LINE);
               FIELD_DD(end.z, FIELD_VALUE(start.z));
             }
         }
+#     endif
 
-      ENCODER
+#     ifdef IS_ENCODER
         {
           FIELD_VALUE(Zs_are_zero) = (FIELD_VALUE(start.z) == 0.0 && FIELD_VALUE(end.z) == 0.0);
           FIELD_B(Zs_are_zero);
@@ -776,6 +775,7 @@ DWG_ENTITY(LINE);
               FIELD_DD(end.z, FIELD_VALUE(start.z));
             }
         }
+#     endif
     }
 
   FIELD(thickness, BT);
@@ -956,7 +956,7 @@ DWG_ENTITY(_3DFACE);
     {
       FIELD_B(has_no_flags);
 
-      DECODER
+#     ifdef IS_DECODER
         {
           FIELD_B(z_is_zero);
           FIELD_RD(corner1.x);
@@ -970,8 +970,9 @@ DWG_ENTITY(_3DFACE);
               FIELD_RD(corner1.z);
             }
         }
+#     endif
 
-      ENCODER
+#     ifdef IS_ENCODER
         {
           FIELD_VALUE(z_is_zero) = (FIELD_VALUE(corner1.z) == 0);
           FIELD_B(z_is_zero);
@@ -982,6 +983,7 @@ DWG_ENTITY(_3DFACE);
               FIELD_RD(corner1.z);
             }
         }
+#     endif
 
       FIELD_DD(corner2.x, FIELD_VALUE(corner1.x));
       FIELD_DD(corner2.y, FIELD_VALUE(corner1.y));
@@ -1262,14 +1264,15 @@ DWG_ENTITY_END
 
 #define DECODE_3DSOLID decode_3dsolid(dat, obj, _obj);
 
-void decode_3dsolid(Bit_Chain* dat, Dwg_Object* obj, Dwg_Entity_3DSOLID* _obj){
-	Dwg_Data* dwg = obj->parent;
-  int vcount, rcount, rcount2;
-  int i=0;
-  int j=0;
+void decode_3dsolid(Bit_Chain* dat, Dwg_Object* obj, Dwg_Entity_3DSOLID* _obj)
+{
+  Dwg_Data* dwg = obj->parent;
+  unsigned int vcount, rcount, rcount2;
+  unsigned int i=0;
+  unsigned int j=0;
   int index;
   int total_size=0;
-  int num_blocks=0;
+  unsigned int num_blocks=0;
   FIELD_B(acis_empty);
   
   if (!FIELD_VALUE(acis_empty))
@@ -1390,38 +1393,32 @@ void encode_3dsolid(Bit_Chain* dat, Dwg_Object* obj, Dwg_Entity_3DSOLID* _obj){
 
 /*(37)*/
 DWG_ENTITY(REGION);
-  DECODER
-    {
-      DECODE_3DSOLID;
-    }
-  ENCODER
-    {
-      ENCODE_3DSOLID;
-    }
+# ifdef IS_DECODER
+    DECODE_3DSOLID;
+# endif
+# ifdef IS_ENCODER
+    ENCODE_3DSOLID;
+# endif
 DWG_ENTITY_END
 
 /*(38)*/
 DWG_ENTITY(_3DSOLID);
-  DECODER
-    {
+# ifdef IS_DECODER
       DECODE_3DSOLID;
-    }
-  ENCODER
-    {
+# endif
+# ifdef IS_ENCODER
       ENCODE_3DSOLID;
-    }
+# endif
 DWG_ENTITY_END
 
 /*(39)*/
 DWG_ENTITY(BODY);
-  DECODER
-    {
-      DECODE_3DSOLID;
-    }
-  ENCODER
-    {
-      ENCODE_3DSOLID;
-    }
+# ifdef IS_DECODER
+    DECODE_3DSOLID;
+# endif
+# ifdef IS_ENCODER
+    ENCODE_3DSOLID;
+# endif
 DWG_ENTITY_END
 
 /*(40)*/
@@ -1703,12 +1700,14 @@ DWG_OBJECT(BLOCK_HEADER);
   SINCE(R_2000)
     {
 
+#    ifdef IS_DECODER
       //skip non-zero bytes and a terminating zero:
       FIELD_VALUE(insert_count)=0;
       while (bit_read_RC(dat))
         {
           FIELD_VALUE(insert_count)++;
         }
+#    endif
 
       FIELD(block_description, TV);
 
@@ -1928,11 +1927,13 @@ DWG_OBJECT(VIEW);
   FIELD(front_clip, BD);
   FIELD(back_clip, BD);
   
+#ifdef IS_DECODER
   //FIELD(view_mode, RC); //??? 4bits
   bit_read_B(dat);
   bit_read_B(dat);
   bit_read_B(dat);
   bit_read_B(dat);
+#endif
 
   SINCE(R_2000)
     {
@@ -2146,18 +2147,21 @@ DWG_OBJECT_END
 DWG_OBJECT(DIMSTYLE_CONTROL);
 
   FIELD_BS (num_entries);
+
+# ifdef IS_DECODER
   SINCE(R_2000)
+    /*
+    This is not stated in the spec.
+    I've seen it in a R2000 file but not on a R14,
+    so I'll assume it is a R_2000+ field.
+    TODO: this should be checked with more sample files from various DWG versions.
+    ~Juca
+    */
     {
-      /*
-      This is not stated in the spec.
-       I've seen it in a R2000 file but not on a R14,
-       so I'll assume it is a R_2000+ field.
-      TODO: this should be checked with more sample files from various DWG versions.
-        ~Juca
-      */
       //FIELD_HANDLE (unknown_handle, ANYCODE);
       bit_read_RC(dat);  // I think it's just one byte
     }
+# endif
 
   FIELD_HANDLE (null_handle, 4);
   XDICOBJHANDLE(3);
@@ -3503,7 +3507,7 @@ DWG_ENTITY_END
 //pg.164
 DWG_OBJECT(XRECORD);
 
-  DECODER
+# ifdef IS_DECODER
     {
 	  FIELD_BL(numdatabytes);  	    
 	  FIELD_XDATA(rbuf, numdatabytes);
@@ -3520,6 +3524,7 @@ DWG_OBJECT(XRECORD);
 	  //XXX how to known when I run out of data?
 	  //BITCODE_H* objid_handles;
     }
+# endif
     
 DWG_OBJECT_END
 
diff --git a/src/encode.c b/src/encode.c
index 5f6e0ef..68b9a30 100644
--- a/src/encode.c
+++ b/src/encode.c
@@ -45,7 +45,10 @@ static unsigned int loglevel;
  */
 static bool env_var_checked_p;
 
-#define DWG_LOGLEVEL loglevel
+#  ifdef DWG_LOGLEVEL
+#    undef DWG_LOGLEVEL
+#  endif
+#  define DWG_LOGLEVEL loglevel
 #endif  // USE_TRACING
 
 /* Welcome to the dark side of the moon...
diff --git a/src/handle.c b/src/handle.c
index c861bff..016d0f5 100644
--- a/src/handle.c
+++ b/src/handle.c
@@ -113,7 +113,7 @@ read_R13_R15_section_object_map(Bit_Chain *dat, Dwg_Data *dwg)
 
       if (ckr != ckr2)
         {
-          printf("section %d crc todo ckr:%x ckr2:%x \n",
+          LOG_ERROR("Section %d CRC mismatch. crc1: %x crc2:%x \n",
                   dwg->header.section[2].number, ckr, ckr2);
           return -1;
         }
@@ -236,7 +236,7 @@ read_2004_section_handles(Bit_Chain *dat, Dwg_Data *dwg)
  
       if (ckr != ckr2)
         {
-          printf("Section Handle obj %d CRC todo ckr: %x ckr2: %x \n \n",
+          LOG_ERROR("Section Handle obj %d CRC mismatch. crc1: %x crc2:%x \n",
                   dwg->header.section[2].number, ckr, ckr2);
          return -1;
          }
diff --git a/src/header.c b/src/header.c
index a0f1f36..65064d4 100644
--- a/src/header.c
+++ b/src/header.c
@@ -65,7 +65,7 @@ read_R13_R15_section_header(Bit_Chain *dat, Dwg_Data *dwg)
 
   if (ckr != ckr2)
     {
-      printf("section %d crc todo ckr:%x ckr2:%x \n",
+      LOG_ERROR("Section %d CRC mismatch. crc1: %x crc2:%x \n",
              dwg->header.section[0].number, ckr, ckr2);
       return -1;
     }
@@ -103,7 +103,7 @@ read_2004_section_header(Bit_Chain *dat, Dwg_Data *dwg)
  
    if (ckr != ckr2)
      {
-       printf("Section %d CRC todo ckr: %x ckr2: %x \n\n",
+       LOG_ERROR("Section %d CRC mismatch. crc1: %x crc2:%x \n",
                dwg->header.section[0].number, ckr, ckr2);
        return -1;
     }
diff --git a/src/section_locate.c b/src/section_locate.c
index 94e7fff..bd20ecc 100644
--- a/src/section_locate.c
+++ b/src/section_locate.c
@@ -60,8 +60,8 @@ read_R13_R15_section_locate(Bit_Chain *dat, Dwg_Data *dwg)
 
   if (ckr != ckr2)
     {
-      printf("header crc todo ckr:%x ckr2:%x \n", ckr, ckr2);
-      return 1;
+      LOG_ERROR("Header CRC mismatch. crc1: %x crc2:%x\n", ckr, ckr2);
+      return -1;
     }
 
   if (bit_search_sentinel(dat, dwg_sentinel(DWG_SENTINEL_HEADER_END)))
@@ -144,8 +144,8 @@ read_R2004_section_map(Bit_Chain *dat, Dwg_Data *dwg, uint32_t comp_data_size,
 
   if (ckr != ckr2)
     {
-      printf("Header CRC todo ckr: %x ckr2: %x \n\n", ckr, ckr2);
-      return 1;
+      LOG_ERROR("Header CRC mismatch. crc1: %x crc2:%x\n", ckr, ckr2);
+      return -1;
     }
 
   free(decomp);
-- 
1.7.10.4

