~ubuntu-branches/ubuntu/raring/codeblocks/raring-proposed

« back to all changes in this revision

Viewing changes to src/plugins/contrib/profiler/cbprofilerexec.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cosme Domínguez Díaz
  • Date: 2010-08-09 04:38:38 UTC
  • mfrom: (1.1.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20100809043838-a59ygguym4eg0jgw
Tags: 10.05-0ubuntu1
* New upstream release. Closes (LP: #322350)
 - Switch to dpkg-source 3.0 (quilt) format
 - Remove unneeded README.source
 - Add debian/get-source-orig script that removes all
   Windows prebuilt binaries
* Bump Standards-Version to 3.9.1
 - Stop shipping *.la files
* debian/control
 - Add cdbs package as Build-Depend
 - Add libbz2-dev and zlib1g-dev packages as
   Build-Depends (needed by libhelp_plugin.so)
 - Remove dpatch package of Build-Depends
 - Add codeblocks-contrib-debug package
 - Split architecture-independent files of codeblocks
   package in codeblocks-common package
* debian/rules
 - Switch to CDBS rules system
 - Add parallel build support
 - Add a call to debian/get-source-orig script
 - Use lzma compression (saves 23,5 MB of free space)
* debian/patches
 - Refresh 01_codeblocks_plugin_path
 - Add 02_no_Makefiles_in_debian_dir to remove any link
   in codeblocks build system to deleted Makefiles of debian directory
 - Drop 02_ftbfs_gcc44 and 03_ftbfs_glib221 (merged in upstream)
* debian/watch
 - Update to use the new host (berlios.de)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3
3
 * http://www.gnu.org/licenses/gpl-3.0.html
4
4
 *
5
 
 * $Revision: 4909 $
6
 
 * $Id: cbprofilerexec.cpp 4909 2008-02-27 13:15:26Z mortenmacfly $
7
 
 * $HeadURL: svn://svn.berlios.de/codeblocks/tags/8.02/src/plugins/contrib/profiler/cbprofilerexec.cpp $
 
5
 * $Revision: 6104 $
 
6
 * $Id: cbprofilerexec.cpp 6104 2010-01-23 12:56:12Z mortenmacfly $
 
7
 * $HeadURL: svn+ssh://jenslody@svn.berlios.de/svnroot/repos/codeblocks/trunk/src/plugins/contrib/profiler/cbprofilerexec.cpp $
8
8
 */
9
9
 
10
10
#include "sdk.h"
21
21
    #include "manager.h"
22
22
    #include "logmanager.h"
23
23
#endif
 
24
#include <wx/busyinfo.h>
24
25
#include <wx/colour.h>
25
26
#include <wx/ffile.h>
26
27
#include <wx/filedlg.h>
27
28
#include <wx/progdlg.h>
28
29
#include "cbprofilerexec.h"
29
30
 
30
 
BEGIN_EVENT_TABLE(CBProfilerExecDlg, wxDialog)
 
31
BEGIN_EVENT_TABLE(CBProfilerExecDlg, wxScrollingDialog)
31
32
    EVT_LIST_ITEM_ACTIVATED(XRCID("lstFlatProfile"), CBProfilerExecDlg::FindInCallGraph)
 
33
    EVT_LIST_ITEM_ACTIVATED(XRCID("lstCallGraph"),   CBProfilerExecDlg::JumpInCallGraph)
32
34
    EVT_BUTTON             (XRCID("btnExport"),      CBProfilerExecDlg::WriteToFile)
33
35
    EVT_LIST_COL_CLICK     (XRCID("lstFlatProfile"), CBProfilerExecDlg::OnColumnClick)
34
36
END_EVENT_TABLE()
39
41
 
40
42
int CBProfilerExecDlg::Execute(wxString exename, wxString dataname, struct_config config)
41
43
{
42
 
    //this->parent = parent;
43
 
 
44
44
    // gprof optional parameters
45
45
    wxString param = config.txtExtra;
46
 
    if (config.chkAnnSource) param << _T(" -A")  << config.txtAnnSource;
47
 
    if (config.chkMinCount)  param << _T(" -m ") << config.spnMinCount;
48
 
    if (config.chkBrief)     param << _T(" -b");
49
 
    if (config.chkFileInfo)  param << _T(" -i");
50
 
    if (config.chkNoStatic)  param << _T(" -a");
51
 
    if (config.chkSum)       param << _T(" -s");
 
46
    if (config.chkAnnSource && !config.txtAnnSource.IsEmpty()) param << _T(" -A")  << config.txtAnnSource;
 
47
    if (config.chkMinCount)                                    param << _T(" -m ") << config.spnMinCount;
 
48
    if (config.chkBrief)                                       param << _T(" -b");
 
49
    if (config.chkFileInfo)                                    param << _T(" -i");
 
50
    if (config.chkUnusedFunctions)                             param << _T(" -z");
 
51
    if (config.chkStaticCallGraph)                             param << _T(" -c");
 
52
    if (config.chkNoStatic)                                    param << _T(" -a");
 
53
    if (config.chkSum)                                         param << _T(" -s");
52
54
 
53
55
    wxString cmd;
54
56
    cmd << _T("gprof ") << param << _T(" \"") << exename << _T("\" \"") << dataname << _T("\"");
55
57
 
56
 
    wxProgressDialog progress(_("C::B Profiler plugin"),_("Launching gprof. Please wait..."));
57
 
    int pid = wxExecute(cmd, gprof_output, gprof_errors);
58
 
    progress.Update(100);
 
58
    int pid = -1;
 
59
 
 
60
    { // begin lifetime of wxBusyInfo
 
61
      wxBusyInfo wait(_("Please wait, while running gprof..."), this);
 
62
      Manager::Get()->GetLogManager()->DebugLog(F(_T("Profiler: Running command %s"), cmd.c_str()));
 
63
      pid = wxExecute(cmd, gprof_output, gprof_errors);
 
64
    } // end lifetime of wxBusyInfo
59
65
 
60
66
    if (pid == -1)
61
67
    {
62
 
        wxString msg = _("Unable to execute Gprof\nBe sure it is in the OS global path\nC::B Profiler could not complete the operation");
 
68
        wxString msg = _("Unable to execute gprof.\nBe sure the gprof executable is in the OS global path.\nC::B Profiler could not complete the operation.");
63
69
        cbMessageBox(msg, _("Error"), wxICON_ERROR | wxOK, (wxWindow*)Manager::Get()->GetAppWindow());
64
70
        Manager::Get()->GetLogManager()->DebugLog(msg);
65
71
 
67
73
    }
68
74
    else
69
75
    {
70
 
        wxXmlResource::Get()->LoadDialog(this, parent, _T("dlgCBProfilerExec"));
 
76
        wxXmlResource::Get()->LoadObject(this, parent, _T("dlgCBProfilerExec"),_T("wxScrollingDialog"));
71
77
        wxFont font(10, wxMODERN, wxNORMAL, wxNORMAL);
72
 
        outputFlatProfileArea=XRCCTRL(*this, "lstFlatProfile", wxListCtrl);
73
 
        outputHelpFlatProfileArea=XRCCTRL(*this, "txtHelpFlatProfile", wxTextCtrl);
 
78
        outputFlatProfileArea     = XRCCTRL(*this, "lstFlatProfile",     wxListCtrl);
 
79
        outputHelpFlatProfileArea = XRCCTRL(*this, "txtHelpFlatProfile", wxTextCtrl);
74
80
        outputHelpFlatProfileArea->SetFont(font);
75
 
        outputCallGraphArea=XRCCTRL(*this, "lstCallGraph", wxListCtrl);
76
 
        outputHelpCallGraphArea=XRCCTRL(*this, "txtHelpCallGraph", wxTextCtrl);
 
81
        outputCallGraphArea       = XRCCTRL(*this, "lstCallGraph",       wxListCtrl);
 
82
        outputHelpCallGraphArea   = XRCCTRL(*this, "txtHelpCallGraph",   wxTextCtrl);
77
83
        outputHelpCallGraphArea->SetFont(font);
78
 
        outputMiscArea=XRCCTRL(*this, "txtMisc", wxTextCtrl);
 
84
        outputMiscArea            = XRCCTRL(*this, "txtMisc",            wxTextCtrl);
79
85
        outputMiscArea->SetFont(font);
80
86
 
81
87
        if(!gprof_output.IsEmpty())
87
93
    return 0;
88
94
}
89
95
 
90
 
void CBProfilerExecDlg::ShowOutput(wxArrayString msg, bool error)
 
96
void CBProfilerExecDlg::ShowOutput(const wxArrayString& msg, bool error)
91
97
{
92
 
    wxString output;
93
 
    size_t   count = msg.GetCount();
94
 
    if ( !count )
 
98
    const size_t maxcount(msg.GetCount());
 
99
    if ( !maxcount )
95
100
        return;
96
101
 
97
102
    if (!error)
98
103
    {
99
 
        wxProgressDialog progress(_("C::B Profiler plugin"),_("Parsing profile information. Please wait..."));
 
104
        wxProgressDialog progress(_("C::B Profiler plugin"),_("Parsing profile information. Please wait..."), maxcount, NULL, wxPD_AUTO_HIDE|wxPD_APP_MODAL|wxPD_SMOOTH);
 
105
 
100
106
        // Parsing Flat Profile
101
 
        size_t n = 0;
102
 
        if (msg[n].Find(_T("Flat profile")) != -1)
103
 
            n = ParseFlatProfile(msg, n, progress);
 
107
        size_t count(0);
 
108
        if (msg[count].Find(_T("Flat profile")) != -1)
 
109
            ParseFlatProfile(msg, progress, maxcount, count);
104
110
 
105
111
        // Parsing Call Graph
106
 
        if (msg[n].Find(_T("Call graph")) != -1)
107
 
            n = ParseCallGraph(msg, ++n, progress);
 
112
        if (msg[count].Find(_T("Call graph"))   != -1)
 
113
            ParseCallGraph(msg, progress, maxcount, count);
108
114
 
109
115
        // The rest of the lines, if any, is printed in the Misc tab
110
 
        progress.Update((100*n)/(count-1),_("Parsing profile information. Please wait..."));
111
 
        for ( ; n < count; ++n )
112
 
        {
113
 
            output << msg[n] << _T("\n");
114
 
            progress.Update((100*n)/(count-1));
115
 
        }
116
 
        outputMiscArea->SetValue(output);
117
 
        progress.Update(100);
 
116
        ParseMisc(msg, progress, maxcount, count);
118
117
    }
119
118
    else
120
119
    {
121
 
        for (size_t n = 0; n < count; ++n )
 
120
        wxString output;
 
121
        for (size_t count(0); count < maxcount; ++count )
122
122
        {
123
 
            output << msg[n] << _T("\n");
 
123
            output << msg[count] << _T("\n");
124
124
        }
125
125
        outputMiscArea->SetValue(output);
126
 
        wxColour colour(255,0,0);
 
126
        const wxColour colour(255,0,0);
127
127
        outputMiscArea->SetForegroundColour(colour);
128
 
        XRCCTRL(*this, "tabs", wxNotebook)->SetSelection(2);
129
128
    }
 
129
 
130
130
    ShowModal();
131
131
}
132
132
 
136
136
 
137
137
void CBProfilerExecDlg::EndModal(int retCode)
138
138
{
139
 
    wxDialog::EndModal(retCode);
140
 
}
141
 
 
142
 
size_t CBProfilerExecDlg::ParseCallGraph(wxArrayString msg, size_t begin, wxProgressDialog &progress)
143
 
{
144
 
    size_t   n;
145
 
    size_t next = 0;
146
 
    wxListItem item;
147
 
 
 
139
    wxScrollingDialog::EndModal(retCode);
 
140
}
 
141
 
 
142
// Sorting function of the flat profile columns
 
143
int wxCALLBACK SortFunction(long item1, long item2, long sortData)
 
144
{
 
145
    CBProfilerExecDlg *dialog = (CBProfilerExecDlg*) sortData;
 
146
 
 
147
    wxListCtrl *listCtrl = dialog->GetoutputFlatProfileArea();
 
148
    int col = dialog->GetsortColumn();
 
149
    long itemId1 = listCtrl->FindItem(-1, item1);
 
150
    long itemId2 = listCtrl->FindItem(-1, item2);
 
151
 
 
152
    wxListItem listItem1, listItem2;
 
153
 
 
154
    listItem1.SetId(itemId1);
 
155
    listItem1.SetColumn(col);
 
156
    listItem1.SetMask(wxLIST_MASK_TEXT);
 
157
    listCtrl->GetItem(listItem1);
 
158
 
 
159
    listItem2.SetId(itemId2);
 
160
    listItem2.SetColumn(col);
 
161
    listItem2.SetMask(wxLIST_MASK_TEXT);
 
162
    listCtrl->GetItem(listItem2);
 
163
 
 
164
    // All the columns are composed with numbers except the last one
 
165
    if (col == 6)
 
166
    {
 
167
       if (dialog->GetsortAscending())
 
168
           return wxStrcmp(listItem1.GetText(), listItem2.GetText());
 
169
       else
 
170
           return wxStrcmp(listItem2.GetText(), listItem1.GetText());
 
171
    }
 
172
    else
 
173
    {
 
174
        double num1, num2;
 
175
        double success = listItem1.GetText().ToDouble(&num1);
 
176
        if (!success)
 
177
        {
 
178
            if (dialog->GetsortAscending()) return -1;
 
179
            else                            return 1;
 
180
        }
 
181
        success = listItem2.GetText().ToDouble(&num2);
 
182
        if (!success)
 
183
        {
 
184
            if (dialog->GetsortAscending()) return 1;
 
185
            else                            return -1;
 
186
        }
 
187
        if (dialog->GetsortAscending())
 
188
        {
 
189
            if (num1 < num2)      return -1;
 
190
            else if (num1 > num2) return 1;
 
191
            else                  return 0;
 
192
        }
 
193
        else
 
194
        {
 
195
            if (num1 > num2)      return -1;
 
196
            else if (num1 < num2) return 1;
 
197
            else                  return 0;
 
198
        }
 
199
    }
 
200
}
 
201
 
 
202
// Function called when a column header is clicked
 
203
void CBProfilerExecDlg::OnColumnClick(wxListEvent& event)
 
204
{
 
205
    if (event.GetColumn() != sortColumn)
 
206
        sortAscending = true;
 
207
    else
 
208
        sortAscending = !sortAscending;
 
209
 
 
210
    sortColumn = event.GetColumn();
 
211
    outputFlatProfileArea->SortItems(SortFunction, (long)this);
 
212
}
 
213
 
 
214
void CBProfilerExecDlg::ParseMisc(const wxArrayString& msg, wxProgressDialog &progress, const size_t maxcount, size_t &count)
 
215
{
 
216
    // parsing
 
217
    wxString output;
 
218
    progress.Update(count, _("Parsing miscellaneous information. Please wait..."));
 
219
    for ( ; count < maxcount; ++count )
 
220
    {
 
221
        if ((count%10) == 0) progress.Update(count);
 
222
        output << msg[count] << _T("\n");
 
223
    }
 
224
    outputMiscArea->SetValue(output);
 
225
}
 
226
 
 
227
void CBProfilerExecDlg::ParseCallGraph(const wxArrayString& msg, wxProgressDialog &progress, const size_t maxcount, size_t& count)
 
228
{
148
229
    // Setting colums names
149
 
    outputCallGraphArea->InsertColumn(0, _T("index"), wxLIST_FORMAT_CENTRE);
150
 
    outputCallGraphArea->InsertColumn(1, _T("% time"), wxLIST_FORMAT_CENTRE);
151
 
    outputCallGraphArea->InsertColumn(2, _T("self"), wxLIST_FORMAT_CENTRE);
 
230
    outputCallGraphArea->InsertColumn(0, _T("index"),    wxLIST_FORMAT_CENTRE);
 
231
    outputCallGraphArea->InsertColumn(1, _T("% time"),   wxLIST_FORMAT_CENTRE);
 
232
    outputCallGraphArea->InsertColumn(2, _T("self"),     wxLIST_FORMAT_CENTRE);
152
233
    outputCallGraphArea->InsertColumn(3, _T("children"), wxLIST_FORMAT_CENTRE);
153
 
    outputCallGraphArea->InsertColumn(4, _T("called"), wxLIST_FORMAT_CENTRE);
 
234
    outputCallGraphArea->InsertColumn(4, _T("called"),   wxLIST_FORMAT_CENTRE);
154
235
    outputCallGraphArea->InsertColumn(5, _T("name"));
155
236
 
156
237
    // Jump header lines
157
 
    while ((begin < msg.GetCount())&&(msg[begin].Find(_T("index % time")) == -1))
 
238
    progress.Update(count,_("Parsing call graph information. Please wait..."));
 
239
    while ( (count < maxcount) && (msg[count].Find(_T("index % time")) == -1) )
158
240
    {
159
 
        ++begin;
 
241
        if ((count%10) == 0) progress.Update(count);
 
242
        ++count;
160
243
    }
161
 
    ++begin;
162
 
 
163
 
    progress.Update((100*begin)/(msg.GetCount()-1),_("Parsing Call Graph information. Please wait..."));
 
244
    ++count;
164
245
 
165
246
    // Parsing Call Graph
166
 
    for (n = begin ; n < msg.GetCount(); ++n )
 
247
    size_t next(0);
 
248
    wxListItem item;
 
249
    wxString TOKEN;
 
250
 
 
251
    // setting listctrl default text colour for secondary lines
 
252
    const wxColour COLOUR(wxTheColourDatabase->Find(_T("GREY")));
 
253
 
 
254
    for ( ; count < maxcount; ++count )
167
255
    {
168
 
        if ((msg[n].IsEmpty())||(msg[n].Find(0x0C) != -1))
 
256
        if ((count%10) == 0) progress.Update(count);
 
257
 
 
258
        TOKEN = msg[count];
 
259
        if ( (TOKEN.IsEmpty()) || (TOKEN.Find(wxChar(0x0C)) != -1) )
169
260
            break;
170
 
        outputCallGraphArea->InsertItem(next,_T(""));
171
 
        char first_char = msg[n].GetChar(0);
 
261
 
 
262
        outputCallGraphArea->InsertItem(count,_T(""));
 
263
        char first_char = TOKEN.GetChar(0);
 
264
        // treating the empty separator lines
172
265
        if (first_char == '-')
173
266
        {
174
267
            outputCallGraphArea->SetItem(next, 0, _T(""));
179
272
        }
180
273
        else
181
274
        {
182
 
            outputCallGraphArea->SetItem(next, 0, ((msg[n].Mid(0,6)).Trim(true)).Trim(false));
183
 
            outputCallGraphArea->SetItem(next, 1, ((msg[n].Mid(6,6)).Trim(true)).Trim(false));
184
 
            outputCallGraphArea->SetItem(next, 2, ((msg[n].Mid(12,8)).Trim(true)).Trim(false));
185
 
            outputCallGraphArea->SetItem(next, 3, ((msg[n].Mid(20,8)).Trim(true)).Trim(false));
186
 
            outputCallGraphArea->SetItem(next, 4, ((msg[n].Mid(28,17)).Trim(true)).Trim(false));
187
 
            outputCallGraphArea->SetItem(next, 5, msg[n].Mid(45));
 
275
            outputCallGraphArea->SetItem(next, 0, TOKEN(0,6).Trim(true).Trim(false));
 
276
            outputCallGraphArea->SetItem(next, 1, TOKEN(6,6).Trim(true).Trim(false));
 
277
            outputCallGraphArea->SetItem(next, 2, TOKEN(12,8).Trim(true).Trim(false));
 
278
            outputCallGraphArea->SetItem(next, 3, TOKEN(20,8).Trim(true).Trim(false));
 
279
            outputCallGraphArea->SetItem(next, 4, TOKEN(28,17).Trim(true).Trim(false));
 
280
            outputCallGraphArea->SetItem(next, 5, TOKEN.Mid(45));
188
281
            if (first_char != '[')
189
282
            {
190
 
                item.Clear();
191
 
                item.SetId(next);
192
 
                item.SetTextColour(wxTheColourDatabase->Find(_T("GREY")));
193
 
                outputCallGraphArea->SetItem(item);
 
283
                outputCallGraphArea->SetItemTextColour(next,COLOUR);
194
284
            }
195
285
        }
196
 
        progress.Update((100*n)/(msg.GetCount()-1));
197
286
        ++next;
198
287
    }
199
288
 
202
291
    outputCallGraphArea->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER );
203
292
    outputCallGraphArea->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER );
204
293
    outputCallGraphArea->SetColumnWidth(3, wxLIST_AUTOSIZE_USEHEADER );
205
 
    outputCallGraphArea->SetColumnWidth(4, wxLIST_AUTOSIZE_USEHEADER );
 
294
    outputCallGraphArea->SetColumnWidth(4, wxLIST_AUTOSIZE );
206
295
    outputCallGraphArea->SetColumnWidth(5, wxLIST_AUTOSIZE);
207
296
 
208
297
    // Printing Call Graph Help
209
298
    wxString output_help;
210
 
    for ( ; n < msg.GetCount(); ++n )
 
299
    for ( ; count < maxcount; ++count )
211
300
    {
212
 
        if (msg[n].Find(0x0C) != -1)
 
301
        if ((count%10) == 0) progress.Update(count);
 
302
 
 
303
        TOKEN = msg[count];
 
304
        if (TOKEN.Find(wxChar(0x0C)) != -1)
213
305
            break;
214
 
        output_help << msg[n] << _T("\n");
215
 
        progress.Update((100*n)/(msg.GetCount()-1));
 
306
 
 
307
        output_help << TOKEN << _T("\n");
216
308
    }
217
309
    outputHelpCallGraphArea->SetValue(output_help);
218
310
 
219
 
    return ++n;
 
311
    ++count;
220
312
}
221
313
 
222
 
size_t CBProfilerExecDlg::ParseFlatProfile(wxArrayString msg, size_t begin, wxProgressDialog &progress)
 
314
void CBProfilerExecDlg::ParseFlatProfile(const wxArrayString& msg, wxProgressDialog &progress, const size_t maxcount, size_t &count)
223
315
{
224
 
    size_t   n;
225
 
    size_t next = 0;
226
 
 
227
316
    // Setting colums names
228
 
    outputFlatProfileArea->InsertColumn(0, _T("% time"), wxLIST_FORMAT_CENTRE);
229
 
    outputFlatProfileArea->InsertColumn(1, _T("cum. sec."), wxLIST_FORMAT_CENTRE);
230
 
    outputFlatProfileArea->InsertColumn(2, _T("self sec."), wxLIST_FORMAT_CENTRE);
231
 
    outputFlatProfileArea->InsertColumn(3, _T("calls"), wxLIST_FORMAT_CENTRE);
232
 
    outputFlatProfileArea->InsertColumn(4, _T("self s/call"), wxLIST_FORMAT_CENTRE);
233
 
    outputFlatProfileArea->InsertColumn(5, _T("total s/call"), wxLIST_FORMAT_CENTRE);
 
317
    outputFlatProfileArea->InsertColumn(0, _T("% time"),        wxLIST_FORMAT_CENTRE);
 
318
    outputFlatProfileArea->InsertColumn(1, _T("cum. sec."),     wxLIST_FORMAT_CENTRE);
 
319
    outputFlatProfileArea->InsertColumn(2, _T("self sec."),     wxLIST_FORMAT_CENTRE);
 
320
    outputFlatProfileArea->InsertColumn(3, _T("calls"),         wxLIST_FORMAT_CENTRE);
 
321
    outputFlatProfileArea->InsertColumn(4, _T("self ms/call"),  wxLIST_FORMAT_CENTRE);
 
322
    outputFlatProfileArea->InsertColumn(5, _T("total ms/call"), wxLIST_FORMAT_CENTRE);
234
323
    outputFlatProfileArea->InsertColumn(6, _T("name"));
235
324
 
236
325
    // Jump header lines
237
 
    while ((begin < msg.GetCount())&&(msg[begin].Find(_T("time   seconds")) == -1))
 
326
    progress.Update(count,_("Parsing flat profile information. Please wait..."));
 
327
    while ((count < maxcount)&&(msg[count].Find(_T("time   seconds")) == -1))
238
328
    {
239
 
        ++begin;
 
329
        ++count;
240
330
    }
241
 
    ++begin;
242
 
 
243
 
    progress.Update((100*begin)/(msg.GetCount()-1),_("Parsing Flat Profile information. Please wait..."));
244
 
 
245
 
 
 
331
    ++count;
 
332
 
 
333
    // Parsing Call Graph
 
334
    size_t next(0);
246
335
    unsigned int spacePos[6] = {6, 16, 25, 34, 43, 52};
247
 
    // Parsing Call Graph
248
 
    for (n = begin ; n < msg.GetCount(); ++n )
 
336
    wxString TOKEN;
 
337
    for ( ; count < maxcount; ++count )
249
338
    {
250
 
        if ((msg[n].IsEmpty())||(msg[n].Find(0x0C) != -1))
 
339
        if ((count%10) == 0) progress.Update(count);
 
340
 
 
341
        TOKEN = msg[count];
 
342
        if ( (TOKEN.IsEmpty()) || (TOKEN.Find(wxChar(0x0C)) != -1) )
251
343
            break;
 
344
 
252
345
        long item = outputFlatProfileArea->InsertItem(next,_T(""));
253
346
        outputFlatProfileArea->SetItemData(item, next);
254
347
        // check that we have spaces where spaces are supposed to be
255
 
                if (msg[n].Len() > spacePos[6]) {
256
 
                        bool need_parsing = false;
257
 
                        for (int i=0; i<6; ++i)
258
 
                        {
259
 
                                if (msg[n][spacePos[i]] != ' ')
260
 
                                {
261
 
                                        need_parsing = true;
262
 
                                        break;
263
 
                                }
264
 
                        }
265
 
                        // if profile output is not in perfect table format
266
 
                        // manually parse for space positions
267
 
                        if (need_parsing)
268
 
                        {
269
 
                                int count=0; int i=0; int len = msg[n].Len();
270
 
                                while (i < len && count < 6) {
271
 
                                        // we start with spaces
272
 
                                        while (msg[n][i] == ' ' && ++i < len);
273
 
                                        if (i>=len) break;
274
 
                                        // now we parse everything else than
275
 
                                        while (msg[n][i] != ' ' && ++i < len);
276
 
                                        if (i>=len) break;
277
 
                                        // found a new space position
278
 
                                        spacePos[count++] = i;
279
 
                                }
280
 
                        }
281
 
                }
 
348
        if (TOKEN.Len() > spacePos[5]) {
 
349
            bool need_parsing = false;
 
350
            for (int i=0; i<6; ++i)
 
351
            {
 
352
                if (TOKEN[spacePos[i]] != ' ')
 
353
                {
 
354
                    need_parsing = true;
 
355
                    break;
 
356
                }
 
357
            }
 
358
            // if profile output is not in perfect table format
 
359
            // manually parse for space positions
 
360
            if (need_parsing)
 
361
            {
 
362
                int count=0; int i=0; int len = TOKEN.Len();
 
363
                while (i < len && count < 6) {
 
364
                    // we start with spaces
 
365
                    while (TOKEN[i] == ' ' && ++i < len);
 
366
                    if (i>=len) break;
 
367
                    // now we parse everything else than
 
368
                    while (TOKEN[i] != ' ' && ++i < len);
 
369
                    if (i>=len) break;
 
370
                    // found a new space position
 
371
                    spacePos[count++] = i;
 
372
                }
 
373
            }
 
374
        }
282
375
 
283
 
        outputFlatProfileArea->SetItem(next, 0, ((msg[n].Mid(0,spacePos[0])).Trim(true)).Trim(false));
284
 
        for (int i=1; i<6; ++i)
285
 
                        outputFlatProfileArea->SetItem(next, i,
286
 
                                ((msg[n].Mid(spacePos[i-1],spacePos[i] - spacePos[i-1])).Trim(true)).Trim(false));
287
 
        outputFlatProfileArea->SetItem(next, 6, ((msg[n].Mid(spacePos[5])).Trim(true)).Trim(false));
 
376
        outputFlatProfileArea->SetItem(next, 0, ((TOKEN.Mid(0,spacePos[0])).Trim(true)).Trim(false));
 
377
        for (int i(1); i<6; ++i)
 
378
            outputFlatProfileArea->SetItem(next, i,((TOKEN.Mid(spacePos[i-1],spacePos[i] - spacePos[i-1])).Trim(true)).Trim(false));
 
379
        outputFlatProfileArea->SetItem(next, 6, ((TOKEN.Mid(spacePos[5])).Trim(true)).Trim(false));
288
380
 
289
381
/*
290
 
        outputFlatProfileArea->SetItem(next, 0, ((msg[n].Mid(0,6)).Trim(true)).Trim(false));
291
 
        outputFlatProfileArea->SetItem(next, 1, ((msg[n].Mid(6,10)).Trim(true)).Trim(false));
292
 
        outputFlatProfileArea->SetItem(next, 2, ((msg[n].Mid(16,9)).Trim(true)).Trim(false));
293
 
        outputFlatProfileArea->SetItem(next, 3, ((msg[n].Mid(25,9)).Trim(true)).Trim(false));
294
 
        outputFlatProfileArea->SetItem(next, 4, ((msg[n].Mid(34,9)).Trim(true)).Trim(false));
295
 
        outputFlatProfileArea->SetItem(next, 5, ((msg[n].Mid(43,9)).Trim(true)).Trim(false));
296
 
        outputFlatProfileArea->SetItem(next, 6, ((msg[n].Mid(52)).Trim(true)).Trim(false));
 
382
        outputFlatProfileArea->SetItem(next, 0, ((TOKEN.Mid(0,6)).Trim(true)).Trim(false));
 
383
        outputFlatProfileArea->SetItem(next, 1, ((TOKEN.Mid(6,10)).Trim(true)).Trim(false));
 
384
        outputFlatProfileArea->SetItem(next, 2, ((TOKEN.Mid(16,9)).Trim(true)).Trim(false));
 
385
        outputFlatProfileArea->SetItem(next, 3, ((TOKEN.Mid(25,9)).Trim(true)).Trim(false));
 
386
        outputFlatProfileArea->SetItem(next, 4, ((TOKEN.Mid(34,9)).Trim(true)).Trim(false));
 
387
        outputFlatProfileArea->SetItem(next, 5, ((TOKEN.Mid(43,9)).Trim(true)).Trim(false));
 
388
        outputFlatProfileArea->SetItem(next, 6, ((TOKEN.Mid(52)).Trim(true)).Trim(false));
297
389
*/
298
 
        progress.Update((100*n)/(msg.GetCount()-1));
299
390
        ++next;
300
391
    }
301
392
 
303
394
    outputFlatProfileArea->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER );
304
395
    outputFlatProfileArea->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER );
305
396
    outputFlatProfileArea->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER );
306
 
    outputFlatProfileArea->SetColumnWidth(3, wxLIST_AUTOSIZE_USEHEADER );
 
397
    outputFlatProfileArea->SetColumnWidth(3, wxLIST_AUTOSIZE );
307
398
    outputFlatProfileArea->SetColumnWidth(4, wxLIST_AUTOSIZE_USEHEADER );
308
399
    outputFlatProfileArea->SetColumnWidth(5, wxLIST_AUTOSIZE_USEHEADER );
309
400
    outputFlatProfileArea->SetColumnWidth(6, wxLIST_AUTOSIZE);
310
401
 
311
 
    wxString output_help;
312
402
    // Printing Flat Profile Help
313
 
    for ( ; n < msg.GetCount(); ++n )
 
403
    wxString output_help;
 
404
    for ( ; count < maxcount; ++count )
314
405
    {
315
 
        if (msg[n].Find(0x0C) != -1)
 
406
        if ((count%10) == 0) progress.Update(count);
 
407
 
 
408
        TOKEN = msg[count];
 
409
        if (TOKEN.Find(wxChar(0x0C)) != -1)
316
410
            break;
317
 
        output_help << msg[n] << _T("\n");
318
 
        progress.Update((100*n)/(msg.GetCount()-1));
 
411
 
 
412
        output_help << msg[count] << _T("\n");
319
413
    }
320
414
    outputHelpFlatProfileArea->SetValue(output_help);
321
415
 
322
 
    return ++n;
 
416
    ++count;
323
417
}
324
418
 
325
419
// This function writes the gprof output to a file
326
420
void CBProfilerExecDlg::WriteToFile(wxCommandEvent& event)
327
421
{
328
 
    wxFileDialog filedialog(parent, _("Save gprof output to file"),_T(""),_T(""),_T("*.*"),wxSAVE);
 
422
    wxFileDialog filedialog(parent,
 
423
                            _("Save gprof output to file"),
 
424
                            wxEmptyString,
 
425
                            wxEmptyString,
 
426
                            _T("*.*"),
 
427
                            wxFD_SAVE);
329
428
 
330
429
    if (filedialog.ShowModal() == wxID_OK)
331
430
    {
339
438
    }
340
439
}
341
440
 
342
 
// This function retrieve the selected function in the call graph tab
 
441
// This function retrieves the selected function in the call graph tab
343
442
void CBProfilerExecDlg::FindInCallGraph(wxListEvent& event)
344
443
{
345
444
    // We retrieve the name of the function on the line selected
348
447
    item.SetColumn(6);
349
448
    item.SetMask(wxLIST_MASK_TEXT);
350
449
    outputFlatProfileArea->GetItem(item);
351
 
    wxString function_name = item.GetText();
 
450
    const wxString function_name(item.GetText());
352
451
 
353
452
    // Then search this name in the call graph
354
 
    wxString indexColumn, functionColumn;
 
453
    wxString indexColumn;
355
454
    int n;
356
455
    for (n=0; n<outputCallGraphArea->GetItemCount(); ++n)
357
456
    {
368
467
            item.SetColumn(5);
369
468
            item.SetMask(wxLIST_MASK_TEXT);
370
469
            outputCallGraphArea->GetItem(item);
371
 
            functionColumn = item.GetText();
372
 
            if (functionColumn.Find(function_name) != -1)
373
 
                break;
374
 
        }
375
 
    }
376
 
 
377
 
    // Scrolling to the desired line in the "Call Graph" tab
378
 
    if (n < outputCallGraphArea->GetItemCount())
379
 
    {
380
 
        outputCallGraphArea->EnsureVisible(n);
381
 
        XRCCTRL(*this, "tabs", wxNotebook)->SetSelection(1);
382
 
    }
383
 
}
384
 
 
385
 
// Sorting function of the flat profile columns
386
 
int wxCALLBACK SortFunction(long item1, long item2, long sortData)
387
 
{
388
 
    CBProfilerExecDlg *dialog = (CBProfilerExecDlg*) sortData;
389
 
 
390
 
    wxListCtrl *listCtrl = dialog->GetoutputFlatProfileArea();
391
 
    int col = dialog->GetsortColumn();
392
 
    long itemId1 = listCtrl->FindItem(-1, item1);
393
 
    long itemId2 = listCtrl->FindItem(-1, item2);
394
 
 
395
 
    wxListItem listItem1, listItem2;
396
 
 
397
 
    listItem1.SetId(itemId1);
398
 
    listItem1.SetColumn(col);
399
 
    listItem1.SetMask(wxLIST_MASK_TEXT);
400
 
    listCtrl->GetItem(listItem1);
401
 
 
402
 
    listItem2.SetId(itemId2);
403
 
    listItem2.SetColumn(col);
404
 
    listItem2.SetMask(wxLIST_MASK_TEXT);
405
 
    listCtrl->GetItem(listItem2);
406
 
 
407
 
    // All the columns are composed with numbers except the last one
408
 
    if (col == 6)
409
 
    {
410
 
       if (dialog->GetsortAscending())
411
 
           return wxStrcmp(listItem1.GetText(), listItem2.GetText());
412
 
       else
413
 
           return wxStrcmp(listItem2.GetText(), listItem1.GetText());
414
 
    }
415
 
    else
416
 
    {
417
 
        double num1, num2;
418
 
        double success = listItem1.GetText().ToDouble(&num1);
419
 
        if (!success)
420
 
        {
421
 
            if (dialog->GetsortAscending()) return -1;
422
 
            else                            return 1;
423
 
        }
424
 
        success = listItem2.GetText().ToDouble(&num2);
425
 
        if (!success)
426
 
        {
427
 
            if (dialog->GetsortAscending()) return 1;
428
 
            else                            return -1;
429
 
        }
430
 
        if (dialog->GetsortAscending())
431
 
        {
432
 
            if (num1 < num2)      return -1;
433
 
            else if (num1 > num2) return 1;
434
 
            else                  return 0;
435
 
        }
436
 
        else
437
 
        {
438
 
            if (num1 > num2)      return -1;
439
 
            else if (num1 < num2) return 1;
440
 
            else                  return 0;
441
 
        }
442
 
    }
443
 
}
444
 
 
445
 
// Function called when a column header is clicked
446
 
void CBProfilerExecDlg::OnColumnClick(wxListEvent& event)
447
 
{
448
 
    if (event.GetColumn() != sortColumn)
449
 
        sortAscending = true;
450
 
    else
451
 
        sortAscending = !sortAscending;
452
 
 
453
 
    sortColumn = event.GetColumn();
454
 
    outputFlatProfileArea->SortItems(SortFunction, (long)this);
 
470
            if (item.GetText().Find(function_name) != -1)
 
471
                break;
 
472
        }
 
473
    }
 
474
 
 
475
    // Scrolling to the desired line in the "Call Graph" tab
 
476
    outputCallGraphArea->SetItemState(item,wxLIST_STATE_SELECTED,wxLIST_STATE_SELECTED);
 
477
    outputCallGraphArea->EnsureVisible(n);
 
478
    XRCCTRL(*this, "tabs", wxNotebook)->SetSelection(1);
 
479
}
 
480
 
 
481
// This function jumps to the selected function in the call graph tab
 
482
void CBProfilerExecDlg::JumpInCallGraph(wxListEvent& event)
 
483
{
 
484
    // We retrieve the name of the function on the line selected
 
485
    wxListItem item;
 
486
    item.SetId(event.GetIndex());
 
487
    item.SetColumn(5);
 
488
    item.SetMask(wxLIST_MASK_TEXT);
 
489
    outputCallGraphArea->GetItem(item);
 
490
    const wxString function_name(item.GetText());
 
491
 
 
492
    // Then search this name in the call graph
 
493
    wxString indexColumn;
 
494
    int n;
 
495
    const int maxcount(outputCallGraphArea->GetItemCount());
 
496
    for (n=0; n<maxcount; ++n)
 
497
    {
 
498
        item.Clear();
 
499
        item.SetId(n);
 
500
        item.SetColumn(0);
 
501
        item.SetMask(wxLIST_MASK_TEXT);
 
502
        outputCallGraphArea->GetItem(item);
 
503
        indexColumn = item.GetText();
 
504
 
 
505
        if ((indexColumn.Mid(0,1)).CompareTo(_T("[")) == 0)
 
506
        {
 
507
            item.Clear();
 
508
            item.SetId(n);
 
509
            item.SetColumn(5);
 
510
            item.SetMask(wxLIST_MASK_TEXT);
 
511
            outputCallGraphArea->GetItem(item);
 
512
 
 
513
            if (function_name.Find(item.GetText()) != wxNOT_FOUND)
 
514
                break;
 
515
        }
 
516
    }
 
517
 
 
518
    // Scrolling to the desired line in the "Call Graph" tab
 
519
    outputCallGraphArea->SetItemState(item,wxLIST_STATE_SELECTED,wxLIST_STATE_SELECTED);
 
520
    outputCallGraphArea->EnsureVisible(n);
455
521
}