ide;debugger; improved AdjustDebugMenus code.
[sdk] / ide / src / ide.ec
index 0b78bcf..fa2957b 100644 (file)
@@ -407,6 +407,7 @@ class IDEWorkSpace : Window
    MenuItem * driverItems, * skinItems;
    StatusField pos { width = 150 };
    StatusField ovr, caps, num;
+   DualPipe documentor;
 
    BitmapResource back                 { ":ecereBack.jpg", window = this };
    BitmapResource bmpBp                { ":codeMarks/breakpoint.png", window = this };
@@ -470,7 +471,7 @@ class IDEWorkSpace : Window
 
       void OnSelectFrame(int frameIndex)
       {
-         ide.debugger.GoToStackFrameLine(frameIndex, true);
+         ide.debugger.GoToStackFrameLine(frameIndex, true, true);
          if(frameIndex >= 0)
             ide.debugger.SelectFrame(frameIndex);
       }
@@ -1106,6 +1107,7 @@ class IDEWorkSpace : Window
             return true;
          }
       }
+#ifndef __WIN32__
       MenuDivider { debugMenu };
       MenuItem debugUseValgrindItem
       {
@@ -1117,23 +1119,84 @@ class IDEWorkSpace : Window
                ide.workspace.useValgrind = selection.checked;
                ide.workspace.Save();
             }
-            ide.AdjustValgrindChecks();
+            ide.AdjustValgrindMenus();
             return true;
          }
       }
-      MenuItem debugValgrindFullLeakCheckItem
+      Menu debugValgrindLeakCheckItem { debugMenu, $"Valgrind Leak Check", h };
+         MenuItem debugValgrindNoLeakCheckItem      { debugValgrindLeakCheckItem, $"No"     , f, id = ValgrindLeakCheck::no     , checkable = true, disabled = true; NotifySelect = ValgrindLCSelect; }
+         MenuItem debugValgrindSummaryLeakCheckItem { debugValgrindLeakCheckItem, $"Summary", f, id = ValgrindLeakCheck::summary, checkable = true, disabled = true; NotifySelect = ValgrindLCSelect, checked = true; }
+         MenuItem debugValgrindYesLeakCheckItem     { debugValgrindLeakCheckItem, $"Yes"    , f, id = ValgrindLeakCheck::yes    , checkable = true, disabled = true; NotifySelect = ValgrindLCSelect; }
+         MenuItem debugValgrindFullLeakCheckItem    { debugValgrindLeakCheckItem, $"Full"   , f, id = ValgrindLeakCheck::full   , checkable = true, disabled = true; NotifySelect = ValgrindLCSelect; }
+         bool ValgrindLCSelect(MenuItem selection, Modifiers mods)
+         {
+            if(ide.workspace)
+            {
+               if(selection.checked)
+               {
+                  ValgrindLeakCheck vgLeakCheck = (ValgrindLeakCheck)selection.id;
+
+                  debugValgrindNoLeakCheckItem.checked      = debugValgrindNoLeakCheckItem.id      == vgLeakCheck;
+                  debugValgrindSummaryLeakCheckItem.checked = debugValgrindSummaryLeakCheckItem.id == vgLeakCheck;
+                  debugValgrindYesLeakCheckItem.checked     = debugValgrindYesLeakCheckItem.id     == vgLeakCheck;
+                  debugValgrindFullLeakCheckItem.checked    = debugValgrindFullLeakCheckItem.id    == vgLeakCheck;
+
+                  ide.workspace.vgLeakCheck = vgLeakCheck;
+                  ide.workspace.Save();
+               }
+               else
+                  selection.checked = true;
+            }
+            return true;
+         }
+      Menu debugValgrindRedzoneSizeItem { debugMenu, $"Valgrind Redzone Size", z };
+         MenuItem debugValgrindRSDefaultItem { debugValgrindRedzoneSizeItem, $"Default", f, id =  -1, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect, checked = true; }
+         MenuItem debugValgrindRS0Item       { debugValgrindRedzoneSizeItem, $"0"      , f, id =   0, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }
+         MenuItem debugValgrindRS16Item      { debugValgrindRedzoneSizeItem, $"16"     , f, id =  16, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }
+         MenuItem debugValgrindRS32Item      { debugValgrindRedzoneSizeItem, $"32"     , f, id =  32, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }
+         MenuItem debugValgrindRS64Item      { debugValgrindRedzoneSizeItem, $"64"     , f, id =  64, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }
+         MenuItem debugValgrindRS128Item     { debugValgrindRedzoneSizeItem, $"128"    , f, id = 128, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }
+         MenuItem debugValgrindRS256Item     { debugValgrindRedzoneSizeItem, $"256"    , f, id = 256, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }
+         MenuItem debugValgrindRS512Item     { debugValgrindRedzoneSizeItem, $"512"    , f, id = 512, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }
+         bool ValgrindRSSelect(MenuItem selection, Modifiers mods)
+         {
+            if(ide.workspace)
+            {
+               if(selection.checked)
+               {
+                  int vgRedzoneSize = (int)selection.id;
+
+                  debugValgrindRSDefaultItem.checked = debugValgrindRSDefaultItem.id == vgRedzoneSize;
+                  debugValgrindRS0Item.checked       = debugValgrindRS0Item.id       == vgRedzoneSize;
+                  debugValgrindRS16Item.checked      = debugValgrindRS16Item.id      == vgRedzoneSize;
+                  debugValgrindRS32Item.checked      = debugValgrindRS32Item.id      == vgRedzoneSize;
+                  debugValgrindRS64Item.checked      = debugValgrindRS64Item.id      == vgRedzoneSize;
+                  debugValgrindRS128Item.checked     = debugValgrindRS128Item.id     == vgRedzoneSize;
+                  debugValgrindRS256Item.checked     = debugValgrindRS256Item.id     == vgRedzoneSize;
+                  debugValgrindRS512Item.checked     = debugValgrindRS512Item.id     == vgRedzoneSize;
+
+                  ide.workspace.vgRedzoneSize = vgRedzoneSize;
+                  ide.workspace.Save();
+               }
+               else
+                  selection.checked = true;
+            }
+            return true;
+         }
+      MenuItem debugValgrindTrackOriginsItem
       {
-         debugMenu, $"Valgrind: Full Leak Check", d, disabled = true, checkable = true;
+         debugMenu, $"Valgrind Track Origins", k, checkable = true, disabled = true;
          bool NotifySelect(MenuItem selection, Modifiers mods)
          {
             if(ide.workspace)
             {
-               ide.workspace.vgFullLeakCheck = selection.checked;
+               ide.workspace.vgTrackOrigins = selection.checked;
                ide.workspace.Save();
             }
             return true;
          }
-      }
+      };
+#endif
       MenuDivider { debugMenu };
       MenuItem debugStepIntoItem
       {
@@ -1141,8 +1204,7 @@ class IDEWorkSpace : Window
          bitmap = { ":actions/stepInto.png" };
          bool NotifySelect(MenuItem selection, Modifiers mods)
          {
-            if(projectView)
-               projectView.DebugStepInto();
+            if(projectView) projectView.DebugStepInto();
             return true;
          }
       }
@@ -1152,8 +1214,16 @@ class IDEWorkSpace : Window
          bitmap = { ":actions/stepOver.png" };
          bool NotifySelect(MenuItem selection, Modifiers mods)
          {
-            if(projectView)
-               projectView.DebugStepOver(false);
+            if(projectView) projectView.DebugStepOver(false);
+            return true;
+         }
+      }
+      MenuItem debugSkipStepOverItem
+      {
+         debugMenu, $"Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
+         bool NotifySelect(MenuItem selection, Modifiers mods)
+         {
+            if(projectView) projectView.DebugStepOver(true);
             return true;
          }
       }
@@ -1163,35 +1233,50 @@ class IDEWorkSpace : Window
          bitmap = { ":actions/stepOut.png" };
          bool NotifySelect(MenuItem selection, Modifiers mods)
          {
-            if(projectView)
-               projectView.DebugStepOut(false);
+            if(projectView) projectView.DebugStepOut(false);
             return true;
          }
       }
-      MenuPlacement debugRunToCursorItem { debugMenu, $"Run To Cursor", c };
-      MenuItem debugSkipStepOverItem
+      MenuItem debugSkipStepOutItem
       {
-         debugMenu, $"Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
+         debugMenu, $"Step Out Skipping Breakpoints", n, Key { f11, ctrl = true, shift = true }, disabled = true;
+         bitmap = { ":actions/skipBreaks.png" };
          bool NotifySelect(MenuItem selection, Modifiers mods)
          {
-            if(projectView)
-               projectView.DebugStepOver(true);
+            if(projectView) projectView.DebugStepOut(true);
             return true;
          }
       }
-      MenuItem debugSkipStepOutItem
+#if 0
+      MenuItem debugStepUntilItem
       {
-         debugMenu, $"Step Out Skipping Breakpoints", t, Key { f11, ctrl = true, shift = true }, disabled = true;
-         bitmap = { ":actions/skipBreaks.png" };
+         debugMenu, $"Step Over Until Next Line", x, disabled = true;
          bool NotifySelect(MenuItem selection, Modifiers mods)
          {
-            if(projectView)
-               projectView.DebugStepOut(true);
+            if(projectView) projectView.DebugStepUntil(false);
             return true;
          }
       }
+      MenuItem debugSkipStepUntilItem
+      {
+         debugMenu, $"Step Over Until Next Line Skipping Breakpoints", e, Key { f10, shift = true, alt = true }, disabled = true;
+         bool NotifySelect(MenuItem selection, Modifiers mods)
+         {
+            if(projectView) projectView.DebugStepUntil(true);
+            return true;
+         }
+      }
+#endif
+      MenuPlacement debugRunToCursorItem { debugMenu, $"Run To Cursor", c };
       MenuPlacement debugSkipRunToCursorItem { debugMenu, $"Run To Cursor Skipping Breakpoints", u };
-      MenuPlacement debugSkipRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", l };
+      MenuPlacement debugRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level", l };
+      MenuPlacement debugSkipRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", g };
+#if 0
+      MenuPlacement debugBpRunToCursorItem { debugMenu, $"BP Run To Cursor" };
+      MenuPlacement debugBpSkipRunToCursorItem { debugMenu, $"BP Run To Cursor Skipping Breakpoints" };
+      MenuPlacement debugBpRunToCursorAtSameLevelItem { debugMenu, $"BP Run To Cursor At Same Level" };
+      MenuPlacement debugBpSkipRunToCursorAtSameLevelItem { debugMenu, $"BP Run To Cursor At Same Level Skipping Breakpoints" };
+#endif
       //MenuDivider { debugMenu };
       //MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t };
    MenuPlacement imageMenu { menu, $"Image", i };
@@ -1351,7 +1436,7 @@ class IDEWorkSpace : Window
       MenuDivider { viewMenu };
       MenuItem viewColorPicker
       {
-         viewMenu, $"Color Picker...", c, Key { c, ctrl = true , shift = true };
+         viewMenu, $"Color Picker...", l, Key { c, ctrl = true , shift = true };
          bool NotifySelect(MenuItem selection, Modifiers mods)
          {
             ColorPicker colorPicker { master = this };
@@ -1394,18 +1479,26 @@ class IDEWorkSpace : Window
          helpMenu, $"API Reference", r, f1;
          bool NotifySelect(MenuItem selection, Modifiers mods)
          {
-            char * p = new char[MAX_LOCATION];
-            p[0] = '\0';
-            strncpy(p, settingsContainer.moduleLocation, MAX_LOCATION); p[MAX_LOCATION-1] = '\0';
-            PathCat(p, "documentor");
-#if defined(__WIN32__)
-            ChangeExtension(p, "exe", p);
-#endif
-            if(FileExists(p).isFile)
-               Execute(p);
+            if(!documentor)
+            {
+               char * p = new char[MAX_LOCATION];
+               p[0] = '\0';
+               strncpy(p, settingsContainer.moduleLocation, MAX_LOCATION); p[MAX_LOCATION-1] = '\0';
+               PathCat(p, "documentor");
+   #if defined(__WIN32__)
+               ChangeExtension(p, "exe", p);
+   #endif
+               if(!FileExists(p).isFile)
+                  strcpy(p, "documentor");
+
+               documentor = DualPipeOpen({ input = true, output = true, showWindow = true }, p);
+               delete p;
+            }
             else
-               Execute("documentor");
-            delete p;
+            {
+               Process_ShowWindows(documentor.GetProcessID());
+               // documentor.Puts("Activate\n");
+            }
             return true;
          }
       }
@@ -1838,19 +1931,38 @@ class IDEWorkSpace : Window
       toolBar.activeConfig.disabled       = unavailable;
       toolBar.activeCompiler.disabled     = unavailable;
       toolBar.activeBitDepth.disabled     = unavailable;
+
+#ifndef __WIN32__
       debugUseValgrindItem.disabled       = unavailable;
+      AdjustValgrindMenus();
+#endif
 
-      AdjustValgrindChecks();
       AdjustFileMenus();
       AdjustBuildMenus();
       AdjustDebugMenus();
    }
 
-   void AdjustValgrindChecks()
+#ifndef __WIN32__
+   void AdjustValgrindMenus()
    {
       bool unavailable = !project || !debugUseValgrindItem.checked;
-      debugValgrindFullLeakCheckItem.disabled    = unavailable;
+      debugValgrindNoLeakCheckItem.disabled        = unavailable;
+      debugValgrindSummaryLeakCheckItem.disabled   = unavailable;
+      debugValgrindYesLeakCheckItem.disabled       = unavailable;
+      debugValgrindFullLeakCheckItem.disabled      = unavailable;
+
+      debugValgrindTrackOriginsItem.disabled       = unavailable;
+
+      debugValgrindRSDefaultItem.disabled          = unavailable;
+      debugValgrindRS0Item.disabled                = unavailable;
+      debugValgrindRS16Item.disabled               = unavailable;
+      debugValgrindRS32Item.disabled               = unavailable;
+      debugValgrindRS64Item.disabled               = unavailable;
+      debugValgrindRS128Item.disabled              = unavailable;
+      debugValgrindRS256Item.disabled              = unavailable;
+      debugValgrindRS512Item.disabled              = unavailable;
    }
+#endif
 
    property bool hasOpenedCodeEditors
    {
@@ -1953,62 +2065,64 @@ class IDEWorkSpace : Window
             projectView.buildInProgress == buildingMainProject;
    } }
 
-   property bool isBreakpointTogglingUnavailable { get {
-      return !project;
-   } }
-
-   property bool isDebuggerExecuting { get {
-      if(!ide.debugger)
-         return false;
-      else
-         return ide.debugger.state == running;
-   } }
+   property bool isBreakpointTogglingUnavailable { get { return !project; } }
+   property bool isDebuggerRunning { get { if(ide.debugger) return ide.debugger.state == running; return false; } }
+   property bool isDebuggerStopped { get { if(ide.debugger) return ide.debugger.state == stopped; return false; } }
 
    void AdjustDebugMenus()
    {
       bool unavailable = areDebugMenusUnavailable;
+      bool running = isDebuggerRunning;
+      bool stopped = isDebuggerStopped;
       bool active = debugger.isActive;
-      bool bpNoToggle = isBreakpointTogglingUnavailable;
-      bool executing = isDebuggerExecuting;
-      //bool holding = debugger.state == stopped;
+      bool noBreakpointToggle = !project;
 
-      debugStartResumeItem.disabled       = unavailable || executing;
+      bool isNotRunning    = unavailable || !running;
+      bool isNotNotRunning = unavailable || running;
+      bool isNotStopped    = unavailable || !stopped;
+      bool isNotActive     = unavailable || !active;
+
+      debugStartResumeItem.disabled       = isNotNotRunning;
       debugStartResumeItem.text           = active ? $"Resume" : $"Start";
       debugStartResumeItem.NotifySelect   = active ? MenuDebugResume : MenuDebugStart;
       if(toolBar)
       {
-         toolBar.buttonDebugStartResume.disabled      = unavailable || executing;
+         toolBar.buttonDebugStartResume.disabled      = isNotNotRunning;
          toolBar.buttonDebugStartResume.toolTip       = active ? $"Resume" : $"Start";
       }
 
-      debugBreakItem.disabled             = unavailable || !executing;
-      debugStopItem.disabled              = unavailable || !active;
-      debugRestartItem.disabled           = unavailable || !active;
+      debugBreakItem.disabled             = isNotRunning;
+      debugStopItem.disabled              = isNotActive;
+      debugRestartItem.disabled           = isNotActive;
       if(toolBar)
       {
-         toolBar.buttonDebugPause.disabled            = unavailable || !executing;
-         toolBar.buttonDebugStop.disabled             = unavailable || !active;
-         toolBar.buttonDebugRestart.disabled          = unavailable || !active;
+         toolBar.buttonDebugPause.disabled            = isNotRunning;
+         toolBar.buttonDebugStop.disabled             = isNotActive;
+         toolBar.buttonDebugRestart.disabled          = isNotActive;
       }
 
-      debugStepIntoItem.disabled          = unavailable || executing;
-      debugStepOverItem.disabled          = unavailable || executing;
-      debugStepOutItem.disabled           = unavailable || executing || !active;
-      debugSkipStepOverItem.disabled      = unavailable || executing;
-      debugSkipStepOutItem.disabled       = unavailable || executing || !active;
+      debugStepIntoItem.disabled          = isNotNotRunning;
+      debugStepOverItem.disabled          = isNotNotRunning;
+      debugSkipStepOverItem.disabled      = isNotNotRunning;
+      debugStepOutItem.disabled           = isNotStopped;
+      debugSkipStepOutItem.disabled       = isNotStopped;
+#if 0
+      debugStepUntilItem.disabled         = isNotStopped;
+      debugSkipStepUntilItem.disabled     = isNotStopped;
+#endif
       if(toolBar)
       {
-         toolBar.buttonDebugStepInto.disabled         = unavailable || executing;
-         toolBar.buttonDebugStepOver.disabled         = unavailable || executing;
-         toolBar.buttonDebugStepOut.disabled          = unavailable || executing || !active;
-         toolBar.buttonDebugSkipStepOver.disabled     = unavailable || executing;
-         // toolBar.buttonDebugSkipStepOutItem.disabled  = unavailable || executing;
+         toolBar.buttonDebugStepInto.disabled         = isNotNotRunning;
+         toolBar.buttonDebugStepOver.disabled         = isNotNotRunning;
+         toolBar.buttonDebugSkipStepOver.disabled     = isNotNotRunning;
+         toolBar.buttonDebugStepOut.disabled          = isNotStopped;
+         //toolBar.buttonDebugSkipStepOutItem.disabled  = isNotNotRunning;
       }
       if((Designer)GetActiveDesigner())
       {
          CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
          if(codeEditor)
-            codeEditor.AdjustDebugMenus(unavailable, bpNoToggle, executing);
+            codeEditor.AdjustDebugMenus();
       }
    }
 
@@ -2194,6 +2308,27 @@ class IDEWorkSpace : Window
 
                         workspace.timer.Start();
 
+#if !defined(__WIN32__)
+                        // Valgrind Debug menu updates
+                        debugUseValgrindItem.checked = workspace.useValgrind;
+
+                        debugValgrindNoLeakCheckItem.checked      = workspace.vgLeakCheck == no;
+                        debugValgrindSummaryLeakCheckItem.checked = workspace.vgLeakCheck == summary;
+                        debugValgrindYesLeakCheckItem.checked     = workspace.vgLeakCheck == yes;
+                        debugValgrindFullLeakCheckItem.checked    = workspace.vgLeakCheck == full;
+
+                        debugValgrindRSDefaultItem.checked = workspace.vgRedzoneSize == -1;
+                        debugValgrindRS0Item.checked       = workspace.vgRedzoneSize == 0;
+                        debugValgrindRS16Item.checked      = workspace.vgRedzoneSize == 16;
+                        debugValgrindRS32Item.checked      = workspace.vgRedzoneSize == 32;
+                        debugValgrindRS64Item.checked      = workspace.vgRedzoneSize == 64;
+                        debugValgrindRS128Item.checked     = workspace.vgRedzoneSize == 128;
+                        debugValgrindRS256Item.checked     = workspace.vgRedzoneSize == 256;
+                        debugValgrindRS512Item.checked     = workspace.vgRedzoneSize == 512;
+
+                        debugValgrindTrackOriginsItem.checked = workspace.vgTrackOrigins;
+#endif
+
                         findInFilesDialog.mode = FindInFilesMode::project;
                         findInFilesDialog.currentDirectory = ide.project.topNode.path;
                         
@@ -2814,8 +2949,8 @@ class IDEWorkSpace : Window
             if(projectView && projectView.project)
             {
                bool isCObject = false;
-               ProjectNode node = projectView.GetNodeFromWindow(client, null, false);
-               if(!node && (node = projectView.GetNodeFromWindow(client, null, true)))
+               ProjectNode node = projectView.GetNodeFromWindow(client, null, false, false);
+               if(!node && (node = projectView.GetNodeFromWindow(client, null, false, true)))
                   isCObject = true;
                if(node)
                {
@@ -2837,10 +2972,10 @@ class IDEWorkSpace : Window
                            ProjectNode node = null;
                            for(p : ide.workspace.projects)
                            {
-                              node = projectView.GetNodeFromWindow(activeClient, p, false);
+                              node = projectView.GetNodeFromWindow(activeClient, p, true, false);
                               if(node) break;
                            }
-                           if(!node && (node = projectView.GetNodeFromWindow(activeClient, null, true)))
+                           if(!node && (node = projectView.GetNodeFromWindow(activeClient, null, true, true)))
                               isCObject = true;
                            if(node)
                            {
@@ -3302,6 +3437,12 @@ class IDEWorkSpace : Window
       delete driverItems;
       delete skinItems;
       delete ideSettings;
+      if(documentor)
+      {
+         documentor.Puts("Quit\n");
+         documentor.Wait();
+         delete documentor;
+      }
    }
 }
 
@@ -3522,6 +3663,33 @@ class IDEApp : GuiApplication
       return true;
    }
 
+   bool Cycle(bool idle)
+   {
+      if(ide.documentor)
+      {
+         if(ide.documentor.Peek())
+         {
+            char line[1024];
+            ide.documentor.GetLine(line, sizeof(line));
+            if(!strcmpi(line, "Exited"))
+            {
+               ide.documentor.CloseInput();
+               ide.documentor.CloseOutput();
+               ide.documentor.Wait();
+               delete ide.documentor;
+            }
+         }
+         if(ide.documentor && ide.documentor.eof)
+         {
+            ide.documentor.CloseInput();
+            ide.documentor.CloseOutput();
+            ide.documentor.Wait();
+            delete ide.documentor;
+         }
+      }
+      return true;
+   }
+
    bool LoadIncludeFile()
    {
       bool result = false;