3 /*static void ParseListValue(List<String> list, char * equal)
7 string = CopyString(equal);
11 comma = strstr(start, ",");
14 list.Add(CopyString(start));
24 enum OpenedFileState { unknown, opened, closed };
25 enum ValgrindLeakCheck
27 no, summary, yes, full;
31 get { return OnGetString(null, null, null); }
34 const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
36 if(this >= no && this <= full)
39 strcpy(tempString, valgrindLeakCheckNames[this]);
40 return valgrindLeakCheckNames[this];
42 if(tempString && tempString[0])
47 static const char * valgrindLeakCheckNames[ValgrindLeakCheck] = { "no", "summary", "yes", "full" };
55 OpenedFileState state;
56 int lineNumber, position;
60 property bool trackingAllowed
62 get { return !holdTracking && ide && ide.workspace && !ide.workspace.holdTracking; }
65 void CaretMove(int line, int charPos)
67 if(trackingAllowed && (line != lineNumber || position != charPos))
71 ide.workspace.modified = true;
75 void ScrollChange(Point scroll)
79 this.scroll.x = scroll.x;
80 this.scroll.y = scroll.y;
81 ide.workspace.modified = true;
89 List<OpenedFileInfo> files = ide.workspace.openedFiles;
90 Iterator<OpenedFileInfo> it { files };
91 if(it.Find(this) && it.pointer != files.GetLast())
93 files.Move(it.pointer, files.GetPrev(files.GetLast()));
94 ide.workspace.modified = true;
108 char * workspaceFile;
110 char * commandLineArgs;
111 property const char * commandLineArgs { set { delete commandLineArgs; if(value) commandLineArgs = CopyString(value); } }
113 property const char * debugDir { set { delete debugDir; if(value) debugDir = CopyString(value); } }
117 property const char * compiler
119 set { delete compiler; if(value && value[0]) compiler = CopyString(value); }
120 get { return compiler && compiler[0] ? compiler : null; }
123 List<String> sourceDirs { };
124 Array<NamedString> environmentVars { };
125 List<Breakpoint> breakpoints { };
126 List<Watch> watches { };
127 List<OpenedFileInfo> openedFiles { };
128 List<Project> projects { };
137 userData = this, delay = 1.0;
140 static bool skip = true;
148 ide.MenuDebugStart(ide.debugStartResumeItem, 0);
149 ide.debugStart = false;
151 else if(ide.debugHideIDE)
153 bool visible = ide.debugger.state != running;
154 if(ideMainFrame.visible != visible)
156 ideMainFrame.visible = visible;
158 ideMainFrame.Activate();
165 property const char * workspaceFile
169 char dir[MAX_DIRECTORY];
170 if(workspaceFile) delete workspaceFile;
171 if(workspaceDir) delete workspaceDir;
172 workspaceFile = CopyString(value);
173 StripLastDirectory(workspaceFile, dir);
174 workspaceDir = CopyUnixPath(dir);
176 get { return workspaceFile; }
179 property const char * projectDir
185 Project prj = projects.firstIterator.data;
186 return prj.topNode ? prj.topNode.path : null;
193 /*property Project project
203 projectDir = CopyString(project.topNode.path);
205 if(!project.config && activeConfig && activeConfig[0])
208 for(cfg = project.configurations.first; cfg; cfg = cfg.next)
209 if(!strcmp(cfg.name, activeConfig))
211 project.config = cfg;
214 project.config = project.configurations.first;
217 get { return project; }
223 // TODO: save these new settings when json format is ready
225 ValgrindLeakCheck vgLeakCheck;
230 vgLeakCheck = summary;
238 file = FileOpen(workspaceFile, write);
242 for(bp : breakpoints)
247 file.Printf("Breakpoint=1,%d,%s,%s\n", bp.line, bp.absoluteFilePath, bp.relativeFilePath);
249 file.Printf("Breakpoint=0,%d,%s,%s\n", bp.line, bp.absoluteFilePath, bp.relativeFilePath);
254 file.Printf("Watch=%s\n", wh.expression);
256 for(dir : sourceDirs)
257 file.Printf("SourceDir=%s\n", dir);
259 if(debugDir && debugDir[0])
260 file.Printf("DebugDir=%s\n", debugDir);
262 if(commandLineArgs && commandLineArgs[0])
263 file.Printf("CommandLineArgs=%s\n", commandLineArgs);
267 char indentation[128*3];
268 char path[MAX_LOCATION];
270 file.Printf("\nECERE Workspace File\n");
271 file.Printf("\nVersion 0.02\n");
272 file.Printf("\nWorkspace\n");
273 file.Printf("\n Active Compiler = %s\n", compiler ? compiler : defaultCompilerName);
274 file.Printf("\n Active Bit Depth = %d\n", bitDepth);
278 file.Printf("\n Projects\n\n");
281 char location[MAX_LOCATION];
282 MakePathRelative(prj.topNode.path, workspaceDir, location);
283 MakeSlashPath(location);
284 PathCatSlash(location, prj.topNode.name);
285 //strcat(location, ".epj");
287 file.Printf(" %s %s\n", "-", location);
290 file.Printf(" Active Configuration = %s\n", prj.config.name);
291 for(cfg : prj.configurations)
293 if(cfg.compilingModified)
294 file.Printf(" Modified Compiler Config = %s\n", cfg.name);
295 else if(cfg.linkingModified)
296 file.Printf(" Modified Linker Config = %s\n", cfg.name);
301 file.Printf("\n Execution Data\n");
302 if(commandLineArgs && commandLineArgs[0])
304 file.Printf("\n Command Line Arguments = ");
305 file.Puts(commandLineArgs);
309 if(environmentVars.count)
311 file.Printf("\n Environment Variables\n\n");
312 for(v : environmentVars)
322 file.Printf("\n Debugger Data\n");
323 // This really belonged in Execution Data...
324 if(debugDir && debugDir[0])
325 file.Printf("\n Debug Working Directory = %s\n", debugDir);
328 file.Printf("\n Source Directories\n");
329 for(dir : sourceDirs)
330 file.Printf(" = %s\n", dir);
333 for(bp : breakpoints)
340 file.Printf("\n Breakpoints\n\n");
348 file.Printf("\n Watches\n\n");
353 if(openedFiles.count)
355 file.Printf("\n Opened Files\n\n");
356 for(ofi : openedFiles)
360 char relativePath[MAX_LOCATION];
361 if(IsPathInsideOf(ofi.path, workspaceDir))
363 MakePathRelative(ofi.path, workspaceDir, relativePath);
364 MakeSlashPath(relativePath);
365 location = relativePath;
371 file.Printf(" %s %s:%d:%d:%d:%d:%s\n", chr, ofi.state == closed ? "C" : "O", ofi.lineNumber, ofi.position, ofi.scroll.x, ofi.scroll.y, location);
380 char * CopyAbsolutePathFromRelative(const char * relative)
382 char name[MAX_LOCATION];
383 char absolute[MAX_LOCATION];
385 ProjectNode node = null;
387 GetLastDirectory(relative, name);
390 if((node = p.topNode.Find(name, false)))
398 node.GetFullFilePath(absolute);
399 return CopyString(absolute);
405 strcpy(absolute, p.topNode.path);
406 PathCatSlash(absolute, relative);
407 if(FileExists(absolute))
414 return CopyString(absolute);
416 strcpy(absolute, workspaceDir); //projectDir // CHECK?
417 PathCatSlash(absolute, relative);
418 if(FileExists(absolute))
419 return CopyString(absolute);
422 for(dir : sourceDirs)
424 strcpy(absolute, dir);
425 PathCatSlash(absolute, relative);
426 if(FileExists(absolute))
427 return CopyString(absolute);
434 char * CopyUnixPathWorkspaceRelativeOrAbsolute(const char * path)
436 if(IsPathInsideOf(path, workspaceDir))
438 char relativePath[MAX_LOCATION];
439 MakePathRelative(path, workspaceDir, relativePath);
440 return CopyUnixPath(relativePath);
443 return CopyUnixPath(path);
446 char * MakeRelativePath(char * buffer, const char * path)
448 char * result = null;
451 MakePathRelative(path, workspaceDir, buffer);
452 MakeSlashPath(buffer);
458 char * GetRelativePathForProject(char * buffer, Project project)
460 char * result = null;
461 if(buffer && project && project.topNode.path)
463 MakePathRelative(project.topNode.path, workspaceDir, buffer);
464 MakeSlashPath(buffer);
465 PathCatSlash(buffer, project.topNode.name);
471 Array<ProjectNode> GetAllProjectNodes(const char *fullPath, bool skipExcluded)
473 Array<ProjectNode> nodes = null;
474 for(project : projects)
477 if((node = project.topNode.FindByFullPath(fullPath, false)))
479 if(!skipExcluded || !node.GetIsExcluded(project.config))
481 if(!nodes) nodes = { };
489 Project GetFileOwner(const char * absolutePath, const char * objectFileExt)
491 Project owner = null;
494 if(prj.topNode.FindByFullPath(absolutePath, false))
501 GetObjectFileNode(absolutePath, &owner, null, objectFileExt);
505 void GetRelativePath(const char * absolutePath, char * relativePath, Project * owner, const char * objectFileExt)
507 Project prj = GetFileOwner(absolutePath, objectFileExt);
511 prj = projects.firstIterator.data;
514 MakePathRelative(absolutePath, prj.topNode.path, relativePath);
515 MakeSlashPath(relativePath);
518 relativePath[0] = '\0';
521 ProjectNode GetObjectFileNode(const char * filePath, Project * project, char * fullPath, const char * objectFileExt)
523 ProjectNode node = null;
524 char ext[MAX_EXTENSION];
525 GetExtension(filePath, ext);
528 IntermediateFileType type = IntermediateFileType::FromExtension(ext);
531 char fileName[MAX_FILENAME];
532 GetLastDirectory(filePath, fileName);
535 DotMain dotMain = DotMain::FromFileName(fileName);
536 for(prj : ide.workspace.projects)
538 if((node = prj.FindNodeByObjectFileName(fileName, type, dotMain, null, objectFileExt)))
544 const char * cfgName = prj.config ? prj.config.name : "";
545 char name[MAX_FILENAME];
546 CompilerConfig compiler = ideSettings.GetCompilerConfig(prj.lastBuildCompilerName);
547 DirExpression objDir = prj.GetObjDir(compiler, prj.config, bitDepth);
548 strcpy(fullPath, prj.topNode.path);
549 PathCatSlash(fullPath, objDir.dir);
550 node.GetObjectFileName(name, prj.configsNameCollisions[cfgName], type, dotMain, objectFileExt);
551 PathCatSlash(fullPath, name);
564 OpenedFileInfo UpdateOpenedFileInfo(const char * fileName, OpenedFileState state)
566 char filePath[MAX_LOCATION];
567 OpenedFileInfo ofi = null;
568 GetSlashPathBuffer(filePath, fileName);
569 for(item : openedFiles)
571 if(!fstrcmp(item.path, filePath))
581 ofi = OpenedFileInfo { path = CopyString(filePath) };
582 openedFiles.Add(ofi);
590 Iterator<OpenedFileInfo> it { openedFiles };
592 openedFiles.Delete(it.pointer);
599 void UpdateSourceDirsArray(Array<String> dirs)
604 sourceDirs.Add(CopyString(s));
606 DropInvalidBreakpoints(null);
611 void RemoveProject(Project project)
613 Iterator<Project> it { projects };
617 for(bp : breakpoints)
618 DropInvalidBreakpoints(project);
620 ide.findInFilesDialog.RemoveProjectItem(project);
621 ide.UpdateToolBarActiveConfigs(false);
627 void SelectActiveConfig(const char * configName)
630 for(prj : ide.workspace.projects)
632 for(cfg : prj.configurations)
634 if(cfg.name && !strcmp(cfg.name, configName))
645 ide.UpdateToolBarActiveConfigs(true);
646 ide.projectView.Update(null);
649 ide.AdjustDebugMenus();
652 bool FindPath(ProjectNode node, const char * path)
654 if(node.type == file)
656 // TODO: Should this code be moved into a ProjectNode::absolutePath property? Taken from NodeProperties.ec
657 char filePath[MAX_LOCATION];
658 GetSlashPathBuffer(filePath, node.project.topNode.path);
659 PathCatSlash(filePath, node.path);
660 PathCatSlash(filePath, node.name);
662 if(!fstrcmp(filePath, path))
669 if(FindPath(n, path))
676 void ChangeBreakpoint(DataRow row, const char * location)
678 Breakpoint bp = (Breakpoint)(intptr)row.tag;
681 char * currentLoc = bp.CopyUserLocationString();
682 if(strcmp(location, currentLoc))
685 bp.location = location;
687 newLoc = bp.CopyUserLocationString();
688 if(strcmp(newLoc, currentLoc))
690 ide.breakpointsView.UpdateBreakpoint(row);
698 // adding a breakpoint by typing it in the breakpoints view
699 // todo, parse location
700 // if good, make add breakpoint, make sure possibly previously entered ignore and level are reflected in breakpoint
703 //bp = Breakpoint { };
704 //row.tag = (int64)bp;
705 //breakpoints.Add(bp);
711 void ChangeBreakpointIgnore(DataRow row, int ignore)
713 Breakpoint bp = (Breakpoint)(intptr)row.tag;
721 void ChangeBreakpointLevel(DataRow row, int level)
723 Breakpoint bp = (Breakpoint)(intptr)row.tag;
731 void ChangeBreakpointCondition(DataRow row, const char * condition)
733 Breakpoint bp = (Breakpoint)(intptr)row.tag;
734 if(bp && !(!bp.condition && !(condition && condition[0])))
738 bp.condition = Watch { };
739 bp.condition.expression = CopyString(condition);
742 else if(!(condition && condition[0]))
748 else if(strcmp(condition, bp.condition.expression))
751 bp.condition = Watch { };
752 bp.condition.expression = CopyString(condition);
758 void RemoveBreakpoint(Breakpoint bp)
761 ide.breakpointsView.RemoveBreakpoint(bp);
762 ide.debugger.UpdateRemovedBreakpoint(bp);
764 Iterator<Breakpoint> it { breakpoints };
766 breakpoints.Remove(it.pointer);
770 for(document = ide.firstChild; document; document = document.next)
772 const char * fileName = document.fileName;
773 if(document.isDocument && fileName && document.created)
775 char winFilePath[MAX_LOCATION];
776 const char * slashPath = GetSlashPathBuffer(winFilePath, fileName);
778 if(!fstrcmp(slashPath, bp.absoluteFilePath))
780 CodeEditor codeEditor = (CodeEditor)document;
781 int boxH = codeEditor.editBox.clientSize.h;
782 Box box { 0, 0, 19, boxH - 1 };
783 document.Update(box);
793 void ParseLoadedBreakpoints()
795 for(bp : breakpoints; bp.location)
798 ide.breakpointsView.UpdateBreakpoint(bp.row);
802 void DropInvalidBreakpoints(Project removedProject)
805 for(bpLink = breakpoints.first; bpLink; bpLink = next)
807 Breakpoint bp = (Breakpoint)(intptr)bpLink.data;
814 if(bp.project == removedProject)
816 ide.breakpointsView.RemoveBreakpoint(bp);
817 RemoveBreakpoint(bp);
822 Project project = bp.project;
827 if(FindPath(p.topNode, bp.absoluteFilePath))
832 // Handle symbol loader modules:
834 char moduleName[MAX_FILENAME];
836 GetLastDirectory(bp.absoluteFilePath, moduleName);
837 // Tweak for automatically resolving symbol loader modules
838 sl = strstr(moduleName, ".main.ec");
839 if(sl && (*sl = 0, !strcmpi(moduleName, p.name)))
850 for(dir : sourceDirs)
852 if(IsPathInsideOf(bp.absoluteFilePath, dir))
860 ide.breakpointsView.RemoveBreakpoint(bp);
861 RemoveBreakpoint(bp);
867 ide.breakpointsView.Update(null);
872 delete workspaceFile;
874 delete commandLineArgs;
886 ide.outputView.buildBox.Clear();
887 ide.outputView.debugBox.Clear();
888 ide.callStackView.Clear();
889 ide.watchesView.Clear();
890 ide.threadsView.Clear();
891 ide.breakpointsView.Clear();
893 property::debugDir = "";
895 SetSourceDirs(sourceDirs);
904 environmentVars.Free();
913 Workspace LoadWorkspace(const char * filePath, const char * fromProjectFile)
916 Workspace workspace = null;
918 file = FileOpen(filePath, read);
921 OldList openedFilesNotFound { };
924 char subSection[128];
926 workspace = Workspace { compiler = ideSettings.defaultCompiler, workspaceFile = filePath };
935 Breakpoint bp = null;
937 file.GetLine(buffer, 65536 - 1);
938 TrimLSpaces(buffer, buffer);
939 TrimRSpaces(buffer, buffer);
946 TrimLSpaces(equal, equal);
947 if(!strcmpi(section, "Debugger Data") && !strcmpi(subSection, "Watches"))
950 workspace.watches.Add(wh);
951 wh.expression = CopyString(equal);
953 else if(!strcmpi(section, "Debugger Data") && !strcmpi(subSection, "Breakpoints"))
958 wh.expression = CopyString(equal);
962 else if(!strcmpi(section, "Execution Data") && !strcmpi(subSection, "Environment Variables"))
964 String value = strchr(equal, '=');
969 TrimRSpaces(equal, equal);
970 TrimLSpaces(value, value);
971 workspace.environmentVars.Add({ equal, value });
975 else if(buffer[0] == '*')
979 TrimLSpaces(equal, equal);
980 if(!strcmpi(section, "Debugger Data") && !strcmpi(subSection, "Breakpoints"))
982 char * strEnabled = null;
983 char * strIgnore = null;
984 char * strLevel = null;
985 char * strLine = null;
986 char * strFile = null;
989 if(strEnabled && strEnabled[0])
991 strIgnore = strstr(strEnabled, ",");
995 if(strIgnore && strIgnore[0])
997 strLevel = strstr(strIgnore, ",");
1001 if(strLevel && strLevel[0])
1003 strLine = strstr(strLevel, ",");
1007 if(strLine && strLine[0])
1009 strFile = strstr(strLine, ",");
1013 if(strEnabled && strEnabled[0] && strIgnore && strIgnore[0] &&
1014 strLevel && strLevel[0] && strLine && strLine[0] && strFile && strFile[0])
1021 TrimLSpaces(strEnabled, strEnabled);
1022 TrimRSpaces(strEnabled, strEnabled);
1023 TrimLSpaces(strIgnore, strIgnore);
1024 TrimRSpaces(strIgnore, strIgnore);
1025 TrimLSpaces(strLevel, strLevel);
1026 TrimRSpaces(strLevel, strLevel);
1027 TrimLSpaces(strLevel, strLevel);
1028 TrimRSpaces(strLevel, strLevel);
1029 TrimLSpaces(strFile, strFile);
1030 TrimRSpaces(strFile, strFile);
1032 enabled = (strEnabled[0] == '1');
1033 ignore = atoi(strIgnore);
1034 level = atoi(strLevel);
1035 line = atoi(strLine);
1037 bp = { type = user, enabled = enabled, ignore = ignore, level = level, line = line };
1038 workspace.breakpoints.Add(bp);
1039 bp.location = strFile;
1043 else if(buffer[0] == '=' || buffer[0] == '-')
1047 TrimLSpaces(equal, equal);
1048 if(!strcmpi(section, "Debugger Data") && !strcmpi(subSection, "Source Directories"))
1049 workspace.sourceDirs.Add(CopyString(equal));
1050 else if(!strcmpi(section, "Opened Files"))
1052 OpenedFileState state = opened;
1056 char absolutePath[MAX_LOCATION];
1057 strcpy(absolutePath, workspace.workspaceDir);
1060 char * comma = strchr(equal, ',');
1064 lineNumber = atoi(equal);
1068 else if(version >= 0.02)
1070 char * column = strchr(equal, ':');
1074 if(strcmpi(equal, "O"))
1078 column = strchr(equal, ':');
1082 lineNumber = atoi(equal);
1085 column = strchr(equal, ':');
1089 position = atoi(equal);
1092 column = strchr(equal, ':');
1096 scroll.x = atoi(equal);
1099 column = strchr(equal, ':');
1103 scroll.y = atoi(equal);
1112 PathCatSlash(absolutePath, equal);
1114 if(state == closed || FileExists(absolutePath))
1115 workspace.openedFiles.Add(OpenedFileInfo { path = CopyString(absolutePath), state = state, lineNumber = lineNumber, position = position, scroll = scroll });
1117 openedFilesNotFound.Add(NamedItem { name = CopyString(equal) });
1119 else if(!strcmpi(section, "Projects"))
1121 char projectFilePath[MAX_LOCATION];
1123 strcpy(projectFilePath, workspace.workspaceDir);
1124 PathCatSlash(projectFilePath, equal);
1125 newProject = LoadProject(projectFilePath, null);
1128 workspace.projects.Add(newProject);
1129 newProject.StartMonitoring();
1131 else if(workspace.projects.count == 0)
1138 // TODO: show message or something when added project fails to load
1139 // http://ecere.com/mantis/view.php?id=524
1143 else if(!strcmpi(buffer, "ECERE Workspace File"));
1144 else if(!strcmpi(buffer, "Version 0a"))
1146 else if(!strncmp(buffer, "Version ", 8))
1147 version = atof(&buffer[8]);
1148 else if(!strcmpi(buffer, "Workspace"))
1149 strcpy(section, buffer);
1150 else if(!strcmpi(buffer, "Projects"))
1151 strcpy(section, buffer);
1152 else if(!strcmpi(buffer, "Execution Data"))
1153 strcpy(section, buffer);
1154 else if(!strcmpi(buffer, "Debugger Data"))
1155 strcpy(section, buffer);
1156 else if(!strcmpi(buffer, "Source Directories"))
1157 strcpy(subSection, buffer);
1158 else if(!strcmpi(buffer, "Breakpoints"))
1159 strcpy(subSection, buffer);
1160 else if(!strcmpi(buffer, "Watches"))
1161 strcpy(subSection, buffer);
1162 else if(!strcmpi(buffer, "Environment Variables"))
1163 strcpy(subSection, buffer);
1164 else if(!strcmpi(buffer, "Opened Files"))
1165 strcpy(section, buffer);
1166 else if(!strcmpi(buffer, "")) // | These two lines were commented out
1167 strcpy(subSection, buffer); // | Do they serve a purpose? They were there for copy paste when adding a new subsection
1170 equal = strstr(buffer, "=");
1173 if(!strcmpi(section, "Workspace"))
1176 TrimRSpaces(buffer, buffer);
1178 TrimLSpaces(equal, equal);
1179 if(!strcmpi(buffer, "Active Compiler"))
1181 CompilerConfig compiler = ideSettings.GetCompilerConfig(equal);
1183 workspace.compiler = defaultCompilerName;
1185 workspace.compiler = equal;
1188 if(!strcmpi(buffer, "Active Bit Depth"))
1190 int bitDepth = atoi(equal);
1191 if(!(bitDepth == 32 || bitDepth == 64))
1193 workspace.bitDepth = bitDepth;
1194 ide.toolBar.activeBitDepth.SelectRow(ide.toolBar.activeBitDepth.FindRow(bitDepth));
1197 else if(!strcmpi(section, "Execution Data"))
1200 TrimRSpaces(buffer, buffer);
1202 TrimLSpaces(equal, equal);
1203 if(!strcmpi(buffer, "Command Line Arguments"))
1204 workspace.commandLineArgs = equal;
1206 if(!strcmpi(buffer, "Environment Variables"))
1208 workspace.environmentVars.Free();
1209 delete workspace.environmentVars;
1210 workspace.environmentVars = { };
1214 else if(!strcmpi(section, "Debugger Data"))
1217 TrimRSpaces(buffer, buffer);
1219 TrimLSpaces(equal, equal);
1220 if(!strcmpi(buffer, "Debug Working Directory"))
1221 workspace.debugDir = equal;
1226 TrimRSpaces(buffer, buffer);
1228 TrimLSpaces(equal, equal);
1229 if(!strcmpi(buffer, "Active Configuration"))
1232 if(workspace.projects.last)
1234 prj = workspace.projects.lastIterator.data;
1235 for(cfg : prj.configurations)
1237 if(!strcmp(cfg.name, equal))
1245 else if(!strcmpi(buffer, "Modified Compiler Config") || !strcmpi(buffer, "Modified Linker Config"))
1248 if(workspace.projects.last)
1250 prj = workspace.projects.lastIterator.data;
1251 for(cfg : prj.configurations)
1253 if(!strcmp(cfg.name, equal))
1255 if(strstr(buffer, "Compiler"))
1256 cfg.compilingModified = true;
1258 cfg.linkingModified = true;
1264 else if(!strcmpi(buffer, "CommandLineArgs"))
1265 workspace.commandLineArgs = equal;
1266 else if(!strcmpi(buffer, "Breakpoint"))
1269 char * lineNum = strstr(equal, ",");
1280 char * absPath = strstr(lineNum, ",");
1287 char * relPath = strstr(absPath, ",");
1294 bp = { type = user, enabled = enabled, level = -1 };
1295 workspace.breakpoints.Add(bp);
1296 bp.line = atoi(lineNum);
1297 bp.location = relPath;
1305 else if(!strcmpi(buffer, "Watch"))
1308 workspace.watches.Add(wh);
1309 wh.expression = CopyString(equal);
1311 else if(!strcmpi(buffer, "SourceDir"))
1313 workspace.sourceDirs.Add(CopyString(equal));
1315 else if(!strcmpi(buffer, "DebugDir"))
1317 workspace.debugDir = equal;
1329 if(!workspace.projects.first)
1333 project = LoadProject(fromProjectFile /*projectFilePath*/, null);
1336 char projectFilePath[MAX_LOCATION];
1337 strcpy(projectFilePath, workspace.workspaceFile);
1338 ChangeExtension(projectFilePath, ProjectExtension, projectFilePath);
1339 project = LoadProject(projectFilePath, null);
1343 project.StartMonitoring();
1344 workspace.projects.Add(project);
1345 workspace.name = CopyString(project.name);
1349 MessageBox { type = ok, master = ide, contents = $"Workspace load file failed", text = $"Workspace Load File Error" }.Modal();
1355 if(openedFilesNotFound.first)
1359 String files = new char[MAX_LOCATION * 16];
1361 String msg = new char[MAX_LOCATION * 16 + 2048];
1365 item = openedFilesNotFound.first;
1369 for(item = openedFilesNotFound.first; item; item = item.next)
1374 strcat(files, "\n...");
1377 strcat(files, "\n");
1378 strcat(files, item.name);
1381 sprintf(title, $"File%s not found", s);
1382 sprintf(msg, $"The following file%s could not be re-opened.%s", s, files);
1384 MessageBox { type = ok, master = ide, contents = msg, text = title }.Modal();
1389 openedFilesNotFound.Free(OldLink::Free);
1392 openedFilesNotFound.Free(OldLink::Free);
1394 else if(fromProjectFile)
1396 //MessageBox { type = Ok, master = ide, contents = "Worspace load file failed", text = "Worspace Load File Error" }.Modal();
1397 //char projectFile[MAX_LOCATION];
1400 //strcpy(projectFile, filePath);
1401 //ChangeExtension(projectFile, ProjectExtension, projectFile);
1402 newProject = LoadProject(fromProjectFile /*projectFile*/, null);
1406 newProject.StartMonitoring();
1407 workspace = Workspace { workspaceFile = filePath };
1409 workspace.projects.Add(newProject);
1416 ide.ChangeFileDialogsDirectory(workspace.workspaceDir, false);
1418 if(!workspace.compiler || !workspace.compiler[0])
1419 workspace.compiler = defaultCompilerName;