FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Debugging with ddbg

 
Post new topic   Reply to topic     Forum Index -> Descent
View previous topic :: View next topic  
Author Message
JoeCoder



Joined: 29 Oct 2005
Posts: 294

PostPosted: Sat Mar 27, 2010 4:14 pm    Post subject: Debugging with ddbg Reply with quote

I haven't been able to get ddbg working with Descent. When I set a breakpoint, the absolute path is sent to ddbg which claims the file can't be found. I tried ddbg from the command line and it worked there, but setting breakpoints worked only when I used a relative path to my source.

I tried the three most recent versions of ddbg with the same problem in each.

I found this discussion which shows the problem has been discussed before.

thanks in advance
Back to top
View user's profile Send private message
JoeCoder



Joined: 29 Oct 2005
Posts: 294

PostPosted: Sat Apr 03, 2010 5:42 pm    Post subject: Reply with quote

I needed a debugger so I could inspect my variables, so the next best thing was being able to recursively dump data structures to console. I didn't want to make up another format, so I used Json.

It's worked quite well. It recursively handles classes, structs, arrays, aa's, and even pointers (at least the first element). And with the useReferences option it can handle any circular data structures by printing the json path name whenever an element is encountered the second time.

To use, just do:
Stdout(Json.encode(myVar)).newline;

The code is D1+Tango but should be easy to port. Hopefully this can be useful to more than just me.

Code:
import tango.core.Traits;
import tango.text.convert.Format;

/// TODO: enums
struct Json
{
   ///
   static struct Options
   {
      char[] tab = "    ";       ///
      char[] lineReturn = "\n";  ///
      int maxDepth = 16;         ///
      int maxArrayLength = 64;   ///
      int floatPrecision = 6;    /// TODO
      int uintAsHex = false;     /// TODO
      bool useReferences = true; /// Print a reference to an object instead of adding it more than once.
      
      private int currentDepth = 0;
      
      static Options opCall()
      {   Options result;
         return result;
      }
   }
   
   private char[][Object] references;
   private char[][void*] pointers;
   
   /**
    * Convert a primitive, object, or array to a Json string */
   static char[] encode(T)(T object, Options options=Options())
   {   Json json; // makes instance of references on the stack, keeps things thread-sate
      return json.internalEncode(object, options);
   }
   
   private char[] internalEncode(T)(T object, Options options=Options(), char[] path="this")
   {
      static if (is(T : bool)) // bool
         return object ? "true" : "false";         
      else if (is(T : real))  // byte-ulong, float-real, and enum
         return Format("{}", object);
      else static if (isCharType!(T) || isStringType!(T)) // char-dchar, char[]-dchar[]
         return "\"" ~ object ~ '"';
      else  static if (isArrayType!(T) || isAssocArrayType!(T) || is(T : Object) || is(T==struct)) // aggregate type, recurse
      {   
         if (options.currentDepth >= options.maxDepth)
            return "Max Depth Exceeded";                  
         options.currentDepth++;
         
         // Repeat tabs to indentation level
         char[] tab = "";
         for (int i=0; i<options.currentDepth; i++)
            tab ~= options.tab;
         char[] tab2 = tab[0..$-options.tab.length]; // one tab less         
         
         static if (isArrayType!(T))
         {   // Show arrays inline?
            bool inl = is(ElementTypeOfArray!(T) : real);
            
            // dynamic array from object
            T array = (object.length > options.maxArrayLength) ? object[0..options.maxArrayLength] : object;
         
            char[] result = "[";
            if (!inl)
               result ~= options.lineReturn;
               
            foreach (int index, ElementTypeOfArray!(T) value; array)
            {   char[] newPath = Format("%s [{}]", path, index);
               char[] comma = index<object.length-1 ? "," : "";
               result ~= (inl ? " " : tab) ~ internalEncode(value, options, newPath) ~ comma ~ (inl ? "" : options.lineReturn);      
            }
            return result ~ (inl ? " " : tab2) ~ "]";      
         }
         else static if (isAssocArrayType!(T))
         {   KeyTypeOfAA!(T)[] keys = object.keys;
            if (keys.length > options.maxArrayLength)
               keys = keys[0..options.maxArrayLength];
         
            char[] result = "{" ~ options.lineReturn;
            
            foreach (int index, KeyTypeOfAA!(T) name; keys)
            {   ValTypeOfAA!(T) value = object[name];
               char[] newPath = Format("%s [{}]", path, name);
               char[] comma = index<keys.length-1 ? "," : "";
               result ~= tab ~ Format("{}: ", name) ~ internalEncode(value, options, newPath) ~ comma ~ options.lineReturn;      
            }
            return result ~ tab2 ~ "}";
         }
         else static if (is(T : Object) || is(T==struct)) // class or struct
         {   
            static if (is(T : Object))
            {   if (!object)
                  return "null";
               else if (options.useReferences)
               {   if (object in references)
                     return references[object];                  
                  references[object] = path; // store new reference
            }   }
               
            char[] result = "{" ~ options.lineReturn;
            foreach (int index, _; object.tupleof)
            {   char[] name = shortName(object.tupleof[index].stringof);
               char[] comma = index<object.tupleof.length-1 ? "," : "";
               result ~= tab ~ name ~ ": " ~ internalEncode(object.tupleof[index], options, path~"."~name) ~ comma ~ options.lineReturn;
            }
            return result ~ tab2 ~ "}";
         }    
         else static if (is(T : void*) && !is(T==void*)) // pointers, dereference through recursion
         {   
            if (options.currentDepth >= options.maxDepth)
               return "Max Depth Exceeded";                  
            options.currentDepth++;
            
            if (!object)
               return "null";
            else if (options.useReferences && object in pointers)
               return pointers[object];
            pointers[object] = path;
            
            return internalEncode(*object);
         
         }
      }
      return "null";
   }

   private static bool isStringType(T)()
   {   static if (isArrayType!(T))
         return isCharType!(ElementTypeOfArray!(T));
      return false;
   }

   private static char[] shortName(char[] fullyQualifiedName) {
      for (int i = fullyQualifiedName.length-1; i >= 0; i--)     
         if (fullyQualifiedName[i] == '.')
            return fullyQualifiedName[i+1..$];
      return "enum_"~fullyQualifiedName;
   }
}
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Descent All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group