Author Topic: Can Selective Display be automated by reading defines from a file?  (Read 15719 times)

cappy2112

  • Community Member
  • Posts: 91
  • Hero Points: 0

I'm new to these macros.

I have a c project that has many # defines defined in a .H file.
There are hundreds of # defines in the .h file. There are too many defines to be able to paste into the Defines drop down box.

Instead of clicking on "Scan For Defines" under Selective Display,

I need to be able to

1. read in the defines in the file
2. Apply the defines to all of the projects in the project file.
3. Then show me the code (for any file in the project), as if I had processed it manually.

Can this be done with a macro?
If so, would someone mind pointing me to an example?

thanks

Graeme

  • Senior Community Member
  • Posts: 2793
  • Hero Points: 347
Re: Can Selective Display be automated by reading defines from a file?
« Reply #1 on: January 12, 2007, 09:45:00 PM »
Quote
I have a c project that has many # defines defined in a .H file.
There are hundreds of # defines in the .h file. There are too many defines to be able to paste into the Defines drop down box.

Not sure I understand but if what you want is the equivalent of manually answering "yes" to the dialog box that pops up for each #define then you can modify the code in seldisp.e like this.

At line 1360 of seldisp.e you will see the function _get_define_names.  It contains several pieces of code similar to this

Code: [Select]
         if (!pos(" "name" ",already_found_names)) {
            result=_message_box(nls("Define %s?",name),nls("Found #%s %s",directive,name),MB_YESNOCANCEL|MB_ICONQUESTION);
            already_found_names=" "name:+already_found_names;
            if (result==IDYES) {
               define_names=strip(define_names" "name);
            } else if (result==IDNO) {
            } else {
               break outerloop;
            }
         }

To get rid of the dialog box and just auto define everything, you can change this piece of code to this

Code: [Select]
         if (!pos(" "name" ",already_found_names)) {
            if (def_scan_for_defines_auto_answer)
                result = IDYES;
            else
                result=_message_box(nls("Define %s?",name),nls("Found #%s %s",directive,name),MB_YESNOCANCEL|MB_ICONQUESTION);
           
            already_found_names=" "name:+already_found_names;
            if (result==IDYES) {
               define_names=strip(define_names" "name);
            } else if (result==IDNO) {
            } else {
               break outerloop;
            }
         }

You need to define def_scan_for_defines_auto_answer like this
Code: [Select]
int def_scan_for_defines_auto_answer;
either in seldisp.e or in a macro file of your own like vusrmacs.e.

I suggest you first backup seldisp.e before changing it (or the whole slick macros folder) and also have the incremental backup mechanism enabled.  Also, after changing it, make a backup of it because installing a slick hotfix or upgrading slick might replace it.

To rebuild seldisp.e, type fp _get_define_names on the slick cmd line.  It should open seldisp.e in the editor.  On the macro menu, select "load module". 

To set the value of def_scan_for_defines_auto_answer to true, type set-var on the slick cmd line, enter the name def_scan_for_defines_auto_answer and press return, then enter a value of 1 for it.  This variable will remember its value across sessions of SE - you'll see it end up in vusrdefs.e after you save your configuration.

Note that the piece of code above applies to #ifdef  - there are other pieces of code for if, elif etc.
If you want to make the effort, you could capture the final value of the string already_found_names you'll see in that code and re-use it.

Graeme
« Last Edit: January 12, 2007, 09:48:48 PM by Graeme »

cappy2112

  • Community Member
  • Posts: 91
  • Hero Points: 0
Re: Can Selective Display be automated by reading defines from a file?
« Reply #2 on: January 13, 2007, 12:07:20 AM »
Not sure I understand but if what you want is the equivalent of manually answering "yes" to the dialog box that pops up for each #define then you can modify the code in seldisp.e like this.

The defines I'm working with control conditional compilation.
Since there are so many (over 1000 actually), it makes the code impossible to follow.

I'm trying to find an automated or semi-automated solution for the Firmware engineers here, to take the original source,
process it by removing the conditional compiles (which have been satisfied by a list of #defines), and produce a view of the source code
without all of the preprocessor directives.

Slick Edit is the only tool I've heard of that will even come close to doing it.

But having to answer yes/no, true false for 100's of lines in each file isn't helping.


I would also like to understand how to preprocess the conditional compile statements (#if #else, etc)
for ALL the files in the project.

Currently, my solution is

run a program I've written to go through each .C file, and write a list of definitions such as

TURBO_MODE TRUE
BLINK_LED      FALSE

to a file.

I then open this file, copy and paste this list of defines into the List Box under the SelectiveDisplay/Settings/Defines dialog.
This will then "preprocess" the conditional compile steps out of the source code (visually).


If I could find where the string of defines is stored in the project files, it might help, but it is not stored in any of the project files I've scanned, nor  in any file under Program Files/SlickEdit, nor in the registry.

Yet, when I start another Slick Edit session, the defines which were previously entered in the Settings/Defines dialog are persistant.








Graeme

  • Senior Community Member
  • Posts: 2793
  • Hero Points: 347
Re: Can Selective Display be automated by reading defines from a file?
« Reply #3 on: January 13, 2007, 01:23:29 AM »
Quote
If I could find where the string of defines is stored in the project files, it might help, but it is not stored in any of the project files I've scanned, nor  in any file under Program Files/SlickEdit, nor in the registry.

They're not stored per project - they're global to all projects.  They're in vrestore.slk in your config folder - in a section that starts with something like
_seldisp_form.ctldefines:3 0. 
To see where your config folder is, use help -> about.

BTW - you can make selective display persistent with an option in tools->options->general->auto-restore items.

Quote
I would also like to understand how to preprocess the conditional compile statements (#if #else, etc)
for ALL the files in the project.

I'm not sure I understand what you mean by this.  Are you saying you want to apply selective display, using the same list of #defines, to all files in the project as if you opened each file one by one and applied selective display to it?

If so, a possibility is as follows.  On the macro menu, turn on "record macro", then with macro recording active, click "selective display" on the view menu. Enter the options you want in the dialog and click ok.
Then stop recording the macro and select "edit" when asked to save the macro.

You might see some code like this
Code: [Select]
   _macro('R',1);
   preprocess('DD1');

I had a single define of DD1 entered in the list of defines.
Hence to apply selective display pre-processing to all open buffers you can *probably* do this (untested

Code: [Select]
int my_seldisp_callback()
{
   preprocess('DD1');
   return 0;
}

_command void my_seldisp() name_info(',')
{
   for_each_buffer('my_seldisp_callback');
}

This uses a fixed string of DD1 but you can get whatever list of defines you want from somewhere - including read from a file, but you'd no doubt want to read the file once only, not for every buffer.
Hence you could open all project files and run the my_seldisp macro.
The function preprocess works on the active buffer - type fp preprocess on the slick cmd line and you'll see it's in seldisp.e just before _get_define_names that I mentioned before.

Graeme
« Last Edit: January 13, 2007, 01:29:09 AM by Graeme »

cappy2112

  • Community Member
  • Posts: 91
  • Hero Points: 0
Re: Can Selective Display be automated by reading defines from a file?
« Reply #4 on: January 13, 2007, 01:46:48 AM »
Quote
They're not stored per project - they're global to all projects.  They're in vrestore.slk in your config folder - in a section that starts with something like
_seldisp_form.ctldefines:3 0. 
To see where your config folder is, use help -> about.

BTW - you can make selective display persistent with an option in tools->options->general->auto-restore items.
Great- that is what I am looking for!

Quote
I would also like to understand how to preprocess the conditional compile statements (#if #else, etc)
for ALL the files in the project.
I'm not sure I understand what you mean by this.  Are you saying you want to apply selective display, using the same list of #defines, to all files in the project as if you opened each file one by one and applied selective display to it?
Let me clarify this.
The defines which control conditional compilation for the whole project are stored in one .h file.

Each .c file probably uses a subset of those defines, although it is conceivable some .C files may use all of the conditional comilation defines (but not likely).

I need to develop an automated way to apply whatever conditional compilation defines are used by each .C file in the project.
I'm almost sure this could be done with Slick's scripting language, but I've just started using slick for the first time yesterday.
I'm barely familiar with it's editing features, let alone how to use the scripting language to preprocess a project's conditional compilation switches.

Thanks for the replies. I think this is pretty close to something that will work for all file sin the project, although I'm not suer about how to read the defines from a file, using the macro or scripting language

Graeme

  • Senior Community Member
  • Posts: 2793
  • Hero Points: 347
Re: Can Selective Display be automated by reading defines from a file?
« Reply #5 on: January 13, 2007, 03:05:34 AM »
To read from a file, you can use code like this - it returns a big long string - untested code.

Code: [Select]
static _str read_defines()
{
   int new_view, current_view;
   _str dname, dval, line, all_defines = '';
   current_view = _create_temp_view(new_view);
   if (current_view == '') {
       return '';
   }
   activate_view(new_view);

   if (get('somefile.txt')) {
      message('read failed - FILE: ' :+ 'somefile.txt');
   }
   else
   {
      top();
      while (true) {
         if (down())
            break;
         get_line(line);
         parse line with dname dval;
         if (dval == 'TRUE')
             all_defines = all_defines :+ dname;
      }
   }
   _delete_temp_view(new_view);
   activate_view(current_view);
   return all_defines;
}

"parse" is quite a useful thing but it's currently missing from the help - you can find info on it here
http://community.slickedit.com/index.php?topic=181.0

_create_temp_view creates a temporary non-visible "internal" buffer that you can write stuff to and search in etc. as if it was a visible buffer.

See also this thread.
http://community.slickedit.com/index.php?topic=90.0

Graeme

Graeme

  • Senior Community Member
  • Posts: 2793
  • Hero Points: 347
Re: Can Selective Display be automated by reading defines from a file?
« Reply #6 on: January 13, 2007, 03:22:20 AM »
Forgot to add a space between define names, so that should be
            all_defines = all_defines :+ ' ' :+ dname;

Graeme

 

cappy2112

  • Community Member
  • Posts: 91
  • Hero Points: 0
Re: Can Selective Display be automated by reading defines from a file?
« Reply #7 on: January 13, 2007, 11:46:35 PM »
Quote from: Graeme
To set the value of def_scan_for_defines_auto_answer to true, type set-var on the slick cmd line, enter the name

This slick cmd line sounds like a nice thing to have.

I'm using Version 10, but don't see the menu option to make it visible.

I hope I can use it to invoke the macros I'm creating.
How can I make it visible?

Graeme

  • Senior Community Member
  • Posts: 2793
  • Hero Points: 347
Re: Can Selective Display be automated by reading defines from a file?
« Reply #8 on: January 13, 2007, 11:55:15 PM »
Quote from: Graeme
To set the value of def_scan_for_defines_auto_answer to true, type set-var on the slick cmd line, enter the name

This slick cmd line sounds like a nice thing to have.

I'm using Version 10, but don't see the menu option to make it visible.

I hope I can use it to invoke the macros I'm creating.
How can I make it visible?

Click in the status bar or (depending on emulation), press ESC  - see emulation tables in the help.
Also read the section in the help file on using the slick cmd line.  If your macro is a _command macro, you cam also bind a key to it - in the key bindings dialog you will see all your command macros.

Graeme

cappy2112

  • Community Member
  • Posts: 91
  • Hero Points: 0
Re: Can Selective Display be automated by reading defines from a file?
« Reply #9 on: January 14, 2007, 02:39:37 AM »
Quote from: Graeme
Click in the status bar or (depending on emulation), press ESC  - see emulation tables in the help.
Also read the section in the help file on using the slick cmd line.  If your macro is a _command macro, you cam also bind a key to it - in the key bindings dialog you will see all your command macros.

This has been very helpfull and I have been trying to use the help file (particularly in the macro area), but not knowing the key phrases to search for is a problem.

For example, when I looked for the command line, slick cmd line, and other variations, I found nothing that referred to clicking in the status bar.

Now that I have access the command line, I can't seem to execute my macro.

The macro file is open (in a buffer that is), but when I type the name of the macro function, it is not executed.
I don't really want to bind to a keystroke, because the editor already has too many commands  and macros bound to keystrokes, I'd rather not have to memorize all new macro bindings I create.

I'm trying to add this to a gui using a form, so the users won't have to deal with the headaches I'm dealing with.

Ideally, they should only have to
1 go to a directory using a directory browser (in the gui form I'm creating)
2. select files either manually or with a filespec (*.c)
3. open all of these files in the editor
4. click on a button to invoke the Selective Display macro you helped me to create
Actually- this macro needs to open up a specific definition file for each of the source files, then apply these definitions to the appropriate source file. I did see your previous post about reading a file in. I will  work on that part after I find a way to execute the macro I've written.


cappy2112

  • Community Member
  • Posts: 91
  • Hero Points: 0
Re: Can Selective Display be automated by reading defines from a file?
« Reply #10 on: January 14, 2007, 03:32:04 AM »

I'm able to load/call the macro I've written now.
Now just need to

0. Load all files in project into buffers
1. iterate over all filenames in the project
2. call my macro with the filename for each file,
3. replace the file extension (.c, etc) in the argument passed to the macro which opens the file of defs, with .txt
4. open filename.txt for each file in project, and read in the defs for that file
5. apply the defs to selective display, foe each file

Things are starting to fall into place now.
I've found the tutorials for the Slick-C API guide, now just need to learn the specifics of the language.

Is there an api to load all project files into buffers, or load all .c, or .h files only into buffers?
I've looked under projects, and buffers, but didn't see anything obvious
project_load just brings up a dialog box

Graeme

  • Senior Community Member
  • Posts: 2793
  • Hero Points: 347
Re: Can Selective Display be automated by reading defines from a file?
« Reply #11 on: January 14, 2007, 09:57:35 AM »
If you type fp project-load on the slick cmd line, you'll be taken to the code for project load where you'll see this

Code: [Select]
      _create_temp_view(workspace_files_view_id);
      int i;
      _str WorkspacePath=strip_filename(_workspace_filename,'N');
      for (i=0;i<project_list._length();++i) {
         _str CurFilename=absolute(project_list[i],WorkspacePath);
         status=GetProjectFiles(
            CurFilename,workspace_files_view_id,"",null,"",false);
         /*if (status) {
            //_delete_temp_view(workspace_files_view_id);
            break;
         } */
      }
      activate_window(orig_view_id);

The call to GetProjectFiles, gets all the files in the project and writes their names into a temp buffer created by _create_temp_view.  Further down in project-load, you'll see it do top(), down(), getline() etc to read each filename - similar to that other code I posted.

BTW - on the slick website, (under support I think), you'll find a pdf doc containing lots of tips about writing macros  - it doesn't come with the slick distribution yet because it's new.  In the "string functions" section of the help, you'll find strip_filename which is useful for manipulating filenames.  You can use for_each_buffer to iterate through open buffers or just open each project file and immediately "preprocess" it.

I guess another thing useful to know is there are some special prefix names like _switchbuf  - if you start a function name with _switchbuf (e.g. _switchbuf_myfunc()) then it gets called when a buffer is switched to.  Search for call_list in slick macro source to see some other special prefix names - like _buffer_add.  I guess it's not a good idea to use leading underscores in your own function names.

Quote
This has been very helpfull and I have been trying to use the help file (particularly in the macro area), but not knowing the key phrases to search for is a problem.

For example, when I looked for the command line, slick cmd line, and other variations, I found nothing that referred to clicking in the status bar.

Yep, searching the chm can be hard.  I find searching the pdf (it's in the docs folder in case you haven't seen it) using acrobat 7 works better.  The help file calls it the "message line" and acrobat 7 allows string searching so if you search for "message line" (no quotes) you'll find the command line section.

Graeme

cappy2112

  • Community Member
  • Posts: 91
  • Hero Points: 0
Re: Can Selective Display be automated by reading defines from a file?
« Reply #12 on: January 14, 2007, 10:53:32 PM »
Graeme

project_load() has saved me hours (maybe days worth of plowing thru a new API and language syntax).
I can't thank you enough for putting up with my newbie questions, and providing very helpful replies!

I can almost use project_load as it is, then call my Selective display routine to apply the defs.
Since the project contains almost 500 files, I must filter the files displayed in the dialog by a filespec, like
ABC*.c, or *.h, etc.

I will try get_string() to get the filespec from the user
« Last Edit: January 14, 2007, 11:16:48 PM by cappy2112 »

Lisa

  • Senior Community Member
  • Posts: 238
  • Hero Points: 24
  • User-friendly geek-speak translator extraordinaire
Re: Can Selective Display be automated by reading defines from a file?
« Reply #13 on: January 15, 2007, 04:16:09 PM »
FYI - documentation for "parse" will be added to the Slick-C guide for v12. A better topic on the SlickEdit Command Line is also being added to the Help and SlickEdit User Guide, along with more (and improved) index markers, so you can find it.

-Lisa