Author Topic: Customizing _c_generate_debug  (Read 2014 times)

flethuseo

  • Senior Community Member
  • Posts: 177
  • Hero Points: 2
Customizing _c_generate_debug
« on: May 16, 2014, 04:11:43 pm »
I need to customize my _c_generate_debug function in quickrefactor.e to create a different debug statement when it encounters the type ost_cppUtil::String. It needs to print the debug statement as follows: printf("var=%s\n", var.value());

I'm thinking that maybe the correct place to do so would be in the get_printf_type method, but I am not sure in which branch I should add it, or what the var_type string will be exactly?

Code: [Select]
static _str get_printf_type(_str var_type)
{
   _str type_string = "";

   // Special case char *. This check will need some more work to make it more accurate
   if( pos("char",var_type) != 0 &&
       pos("*",var_type) != 0) {
      type_string = "%s";
   } // TODO: Also need special case for VSPLSTR type
   else if(pos("VSPSZ",var_type) != 0){
      type_string = "%s";
   }
   else if(_c_is_builtin_type(var_type, false) == false) {
      type_string = "0x%x";
   } else {
      if(_c_builtin_assignment_compatible("int", var_type, false)) {
         type_string = "%d";
      } else if(_c_builtin_assignment_compatible("char", var_type, false)) {
         type_string = "%c";
      } else if(_c_builtin_assignment_compatible("float", var_type, false)) {
         type_string = "%f";
      } else if(_c_builtin_assignment_compatible("double", var_type, false)) {
         type_string = "%lf";
      } else if(_c_builtin_assignment_compatible("long", var_type, false)) {
         type_string = "%ld";
      } else if(_c_builtin_assignment_compatible("unsigned int", var_type, false)) {
         type_string = "%u";
      } else if(_c_builtin_assignment_compatible("unsigned long", var_type, false)) {
         type_string = "%ul";
      }
   }
   return type_string;
}

Also, where could I tell it to concatenate '.value()' where the variable is specified?

« Last Edit: May 16, 2014, 04:15:34 pm by flethuseo »

Graeme

  • Senior Community Member
  • Posts: 2136
  • Hero Points: 263
Re: Customizing _c_generate_debug
« Reply #1 on: May 17, 2014, 01:31:57 am »
I didn't know about generate_debug.
Do you know about the say() function.  If you add a call to say() in the _c_generate... function as follows, you should see that member_name has a value of ost_cppUtil::String for an object of this type.  So you can then check for it
if (var_def.member_name == 'ost_cppUtil::String') {
     // whatever
     return 0;
}



Code: [Select]
      // If a struct then print out all the members
      if(get_var_def(cm, var_def) == 0 && (var_def.type_name == 'struct' || var_def.type_name == 'class')) {

         say(var_def.member_name);  // <<<<<<<<<<<<<


flethuseo

  • Senior Community Member
  • Posts: 177
  • Hero Points: 2
Re: Customizing _c_generate_debug
« Reply #2 on: May 19, 2014, 06:23:29 pm »
It isn't returning 'ost_cppUtil::String', instead, it just returns 'ost_cppUtil' when I do:
say(var_def.member_name);

Do you know what may be causing this?
« Last Edit: May 19, 2014, 06:25:02 pm by flethuseo »

Graeme

  • Senior Community Member
  • Posts: 2136
  • Hero Points: 263
Re: Customizing _c_generate_debug
« Reply #3 on: May 19, 2014, 11:01:17 pm »
Try qualified_name or class_name instead of member_name.

flethuseo

  • Senior Community Member
  • Posts: 177
  • Hero Points: 2
Re: Customizing _c_generate_debug
« Reply #4 on: May 20, 2014, 03:00:43 pm »
Both of these fields show up as blank :\
Code: [Select]
      if(get_var_def(cm, var_def) == 0 && (var_def.type_name == 'struct' || var_def.type_name == 'class')) {
         say(var_def.member_name);
         say(var_def.qualified_name);
         say(var_def.class_name);
         say(var_def.file_name);
         VS_TAG_BROWSE_INFO member_list[];



« Last Edit: May 20, 2014, 03:04:51 pm by flethuseo »

Graeme

  • Senior Community Member
  • Posts: 2136
  • Hero Points: 263
Re: Customizing _c_generate_debug
« Reply #5 on: May 21, 2014, 12:28:02 am »
Looks like slick doesn't handle nested classes so well  - however if you add this code instead of your own say statements

         tag_browse_info_dump(cm);
         tag_browse_info_dump(var_def);

you'll see that cm.return_type will probably get you 'ost_cppUtil::String' so you can use that to do your special handling.
(I tried "generate debug" on "cm" in the slick c source code and found slick generated the special call to tag_browse_info_dump.)


flethuseo

  • Senior Community Member
  • Posts: 177
  • Hero Points: 2
Re: Customizing _c_generate_debug
« Reply #6 on: May 21, 2014, 02:46:40 pm »
Thank you Graeme. It works now:

 
Code: [Select]
  } else if(cm.type_name == 'param' || cm.type_name == 'var' || cm.type_name == 'gvar' || cm.type_name == 'lvar') {
      indent = get_line_leading_whitespace();

      _str var_access = prefix :+ cm.member_name;   // String used to access the var in the outputted code

      // Find end of statement. This handles multiple-line statements.
      search(";","@hXcs");

      // If a struct then print out all the members
      if(get_var_def(cm, var_def) == 0 && (var_def.type_name == 'struct' || var_def.type_name == 'class')) {

         /// New code for my functionality
         if (cm.return_type == "ost_cppUtil::String") {
            line := indent :+ 'debug_printf("' :+ var_access :+ '=';
            strappend(line, '%s' :+ '\n", ' :+ var_access :+ '.value());');
            insert_line(line);
            return 0;
         }
         /// New code for my functionality

         VS_TAG_BROWSE_INFO member_list[];
         struct VS_TAG_RETURN_TYPE visited:[];
         get_class_members(var_def, VS_TAGFILTER_VAR, VS_TAGCONTEXT_ACCESS_public, member_list, visited);
         for(i:=0; i < member_list._length(); i++) {