the only thing which really bugs me using Astyle is, that
wxWidgets-typical macro constructs like
BEGIN_EVENT_TABLE(MainFrame, wxFrame)
EVT_ERASE_BACKGROUND(MainFrame::OnEraseBackground)
EVT_SIZE(MainFrame::OnSize)
EVT_UPDATE_UI(idViewStatusbar, MainFrame::OnViewMenuUpdateUI)
EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, MainFrame::OnFileReopen)
EVT_PROJECT_ACTIVATE(MainFrame::OnProjectActivated)
EVT_SHOW_DOCK_WINDOW(MainFrame::OnRequestShowDockWindow)
END_EVENT_TABLE()
lose their format. this maybe owns potential for enhancements ...
News: I'ven't coded any kind of parser :)
Anyway, I just wanted to comment you about a little source formatter I found and its configuration concept. I'm talking about NiceC, where the idea is to make it learn from existing formatted code. Then I came with the idea of a "learning session".
Here's a scenario (images are for illustrative purposes):
You have Code::Blocks opened, the plugin installed, and a source file loaded. You go to Plugins and select SourceFormatter.
It'll display a dialog showing you the current styles (predefined + user defined), a button to create a new empty style, a button to create a new style from an existing one, a button to apply the style and another button to learn.
(http://gda.utp.edu.co/~ceniza/CodeBlocks/.images/sf/1.png)
You decide to create a new style, select it and click Learn.
Now tokens are found and a dialog pops-up. It'll allow you to configure some behavior based in the current scenario. Say it found a '{' that belongs to an if. Here you can select a set of actions based on some rules like: we're currently in an IF, previous token is, next token is, previous actions, next actions, ...
(http://gda.utp.edu.co/~ceniza/CodeBlocks/.images/sf/2.png)
That one needs more "tuning". An option to add custom states could also be added.
States are pushed in a stack. The IF one would be pushed when a LPAREN token is found and the previous token is IF. Who removes it? :)
The configuration dialog should allow you to see, remove, modify and add actions (dialog not defined yet).
Anyway, what you'd get with that action would be (comments for clarification; dots mean space; indentation is 4 spaces):
Original code:
Formatted code:
if.(1.+.1.==.5)// pre-action: Go to next line
{// post-action: Go to next line
....// post-action: Indent
Now it's your turn to say how much this idea sucks :D
Yesterday I committed the changes I made to the lexer a few days ago, and the first sketch of a formatter (nothing really).
So far the idea of the "rules" system sounds good. I'd need to define the default rules too.
It's a shame I didn't save those dialogs. More work to do again :(
There's a huge problem though: today is friday, 15:00+ here right now. My GF will surely want to come here saturday and sunday (and she won't help me with this plugin). Classes begin on monday.
limit(free_time, busy_time, all_time) | free_time = all_time - busy_time
0
:(
Naming things... how time consuming can this task be?
Anyway, here is a preliminar version of the basic structures for the rules:
struct Condition
{
TokenType cur_token;
TokenType pre_token;
TokenType next_token;
State cur_state;
};
struct Actions
{
std::vector<SingleAction> pre_actions;
std::vector<SingleAction> post_actions;
};
struct Rule // version 1
{
Condition cond;
Actions acts;
};
struct Rule : Condition, Actions // version 2 (I prefer this one)
{
// What else?
};
So far the function name could be something like matches. Overloading operator == wouldn't be that a good idea.
The function could look something like this:
// kids: don't code like this :P
inline int Condition::matches(const Condition &other)
{
return cur_token == other.cur_token ? 1 + (pre_token == other.pre_token) + (next_token == other.next_token) + (cur_state == other.cur_state) : 0;
}
Quite simple: if the current token is the same, count it and all others that match, else 0.
What if two rules return the same value (there wouldn't be duplicates, just same number of matches)?
If many return values != 0 but the one with biggest return value is unique, that one would be chosen.
Even though, there sould be another evaluation like this one (var == other.var || var == NOTHING || other.var == NOTHING). So, matches must return two values: exact matches and matches with "empty" variables. A struct, vector or pair<> would do that.
Now, the way to decide which one to apply would be (order is quite important when coding this, not here :P):
* The one with biggest return value for exact matches.
* If there's more than one with the same value, then the one of those with biggest total matches (those counting "empty" cases).
* If even that way there's more than one with both number of matches the same, what to do?
* If all returned 0 for exact matches, return the one with biggest total matches.
* If there's more than one with the same value, what to do?
* If both exact and total matches are 0, it's just a "NO MATCH". Apply default rule (easy to say, but what's the default rule?).
Feedback anyone? :)