├── testapps ├── fortran │ ├── inc.f95 │ ├── makefile │ ├── start_gede.sh │ └── test.f95 ├── coredump │ ├── run_and_crash.sh │ ├── start_gede.sh │ ├── makefile │ └── test.c ├── rust │ ├── makefile │ ├── start_gede.sh │ └── test.rs ├── golang │ ├── makefile │ ├── start_gede.sh │ └── test.go ├── basic │ ├── makefile │ ├── start_gede.sh │ └── test.bas ├── tutorial_c │ ├── func.h │ ├── makefile │ ├── func.c │ └── main.c ├── ada │ ├── start_gede.sh │ ├── makefile │ └── test.adb ├── c_code │ ├── start_gede.sh │ ├── makefile │ ├── other.c │ └── test.c ├── threads │ ├── start_gede.sh │ ├── makefile │ └── test.c ├── ansicolor │ ├── makefile │ ├── start_gede.sh │ └── test.c └── stdlib_cxx │ ├── otherclass.h │ ├── makefile │ ├── otherclass.cpp │ └── test.cpp ├── testapp ├── subdir │ ├── subfile.h │ └── subfile.c ├── makefile └── test.c ├── src ├── res │ ├── file.png │ ├── next.png │ ├── quit.png │ ├── stop.png │ ├── continue.png │ ├── folder.png │ ├── restart.png │ ├── step_out.png │ ├── step_into.png │ └── step_over.png ├── start_gede.sh ├── start_gdbserver.sh ├── syntaxhighlighter.cpp ├── varctl.cpp ├── tabwidgetadv.cpp ├── tabwidgetadv.h ├── qtutil.h ├── version.h ├── resource.qrc ├── qtutil.cpp ├── autosignalblocker.h ├── variableinfowindow.h ├── parsecharqueue.h ├── aboutdialog.h ├── execombobox.h ├── gdbmiparser.h ├── colorbutton.h ├── memorydialog.h ├── varctl.h ├── locator.h ├── log.h ├── util.h ├── gotodialog.h ├── config.h ├── syntaxhighlighter.h ├── memorywidget.h ├── execombobox.cpp ├── parsecharqueue.cpp ├── syntaxhighlighterada.h ├── syntaxhighlightergolang.h ├── syntaxhighlighterrust.h ├── settingsdialog.h ├── syntaxhighlightercxx.h ├── syntaxhighlighterbasic.h ├── colorbutton.cpp ├── syntaxhighlighterfortran.h ├── processlistdialog.h ├── codeviewtab.h ├── watchvarctl.h ├── tagscanner.h ├── processlistdialog.ui ├── aboutdialog.cpp ├── opendialog.h ├── codeviewtab.ui ├── adatagscanner.h ├── rusttagscanner.h ├── autovarctl.h ├── tagmanager.h ├── gotodialog.ui ├── consolewidget.h ├── tree.h ├── variableinfowindow.cpp ├── memorydialog.cpp ├── gd.pro ├── codeview.h ├── ini.h ├── memorydialog.ui ├── aboutdialog.ui ├── log.cpp ├── settings.h ├── tree.cpp ├── tagmanager.cpp ├── gd.cpp ├── com.h ├── codeviewtab.cpp ├── processlistdialog.cpp ├── mainwindow.h ├── util.cpp ├── tagscanner.cpp └── core.h ├── makefile ├── tests ├── ini │ ├── test_ini.pro │ └── test_ini.cpp ├── tagtest │ ├── tagtest.pro │ └── tagtest.cpp └── highlightertest │ ├── hltest.pro │ └── hltest.cpp ├── README └── LICENSE /testapps/fortran/inc.f95: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testapp/subdir/subfile.h: -------------------------------------------------------------------------------- 1 | 2 | void subfunc(int a); 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/res/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nanoseb/gede/HEAD/src/res/file.png -------------------------------------------------------------------------------- /src/res/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nanoseb/gede/HEAD/src/res/next.png -------------------------------------------------------------------------------- /src/res/quit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nanoseb/gede/HEAD/src/res/quit.png -------------------------------------------------------------------------------- /src/res/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nanoseb/gede/HEAD/src/res/stop.png -------------------------------------------------------------------------------- /src/res/continue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nanoseb/gede/HEAD/src/res/continue.png -------------------------------------------------------------------------------- /src/res/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nanoseb/gede/HEAD/src/res/folder.png -------------------------------------------------------------------------------- /src/res/restart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nanoseb/gede/HEAD/src/res/restart.png -------------------------------------------------------------------------------- /src/res/step_out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nanoseb/gede/HEAD/src/res/step_out.png -------------------------------------------------------------------------------- /src/res/step_into.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nanoseb/gede/HEAD/src/res/step_into.png -------------------------------------------------------------------------------- /src/res/step_over.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nanoseb/gede/HEAD/src/res/step_over.png -------------------------------------------------------------------------------- /src/start_gede.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make 4 | cd ../testapp 5 | ../src/gede --args ./test 6 | 7 | -------------------------------------------------------------------------------- /testapps/coredump/run_and_crash.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ulimit -c 500000000 4 | 5 | ./test 6 | 7 | -------------------------------------------------------------------------------- /testapps/rust/makefile: -------------------------------------------------------------------------------- 1 | 2 | test: test.rs 3 | rustc -g $^ 4 | 5 | clean: 6 | rm -f test 7 | 8 | -------------------------------------------------------------------------------- /testapps/fortran/makefile: -------------------------------------------------------------------------------- 1 | 2 | test: test.f95 3 | gfortran -cpp -g -o $@ $^ 4 | 5 | clean: 6 | rm -f test 7 | 8 | -------------------------------------------------------------------------------- /testapp/subdir/subfile.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | void subfunc(int a) 4 | { 5 | a *= 2; 6 | a *= 2; 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /testapps/golang/makefile: -------------------------------------------------------------------------------- 1 | 2 | test: test.go 3 | go build -gcflags=all="-N -l" $^ 4 | 5 | clean: 6 | rm -f test 7 | 8 | -------------------------------------------------------------------------------- /src/start_gdbserver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd ../testapp 6 | ls -l ./test 7 | gdbserver localhost:2345 ./test 8 | 9 | -------------------------------------------------------------------------------- /testapps/basic/makefile: -------------------------------------------------------------------------------- 1 | 2 | test: test.bas 3 | /opt/freebasic/bin/fbc -g -lang fb test.bas 4 | 5 | clean: 6 | rm -f test 7 | 8 | -------------------------------------------------------------------------------- /testapps/coredump/start_gede.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make -C ../../src 4 | #cd ../testapps/coredump 5 | ../../src/gede 6 | 7 | 8 | -------------------------------------------------------------------------------- /testapps/tutorial_c/func.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE_FUNC_H 2 | #define FILE_FUNC_H 3 | 4 | const char *my_function(int a); 5 | 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /testapps/basic/start_gede.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make -C ../../src 4 | #cd ../testapps/coredump 5 | ../../src/gede --args ./test 6 | 7 | 8 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | ./build.py --verbose 4 | 5 | install: 6 | ./build.py install 7 | 8 | clean: 9 | ./build.py clean 10 | 11 | 12 | -------------------------------------------------------------------------------- /testapps/ada/start_gede.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make 4 | make -C ../../src 5 | #cd ../testapps/coredump 6 | ../../src/gede --args ./test 7 | 8 | 9 | -------------------------------------------------------------------------------- /testapps/c_code/start_gede.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | make 4 | make -C ../../src 5 | #cd ../testapps/coredump 6 | ../../src/gede --args ./test 7 | 8 | 9 | -------------------------------------------------------------------------------- /testapps/golang/start_gede.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make 4 | make -C ../../src 5 | #cd ../testapps/coredump 6 | ../../src/gede --args ./test 7 | 8 | 9 | -------------------------------------------------------------------------------- /testapps/rust/start_gede.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make 4 | make -C ../../src 5 | #cd ../testapps/coredump 6 | ../../src/gede --args ./test 7 | 8 | 9 | -------------------------------------------------------------------------------- /testapps/fortran/start_gede.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make 4 | make -C ../../src 5 | #cd ../testapps/coredump 6 | ../../src/gede --args ./test 7 | 8 | 9 | -------------------------------------------------------------------------------- /testapps/threads/start_gede.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make 4 | make -C ../../src 5 | #cd ../testapps/coredump 6 | ../../src/gede --args ./test 7 | 8 | 9 | -------------------------------------------------------------------------------- /testapps/ansicolor/makefile: -------------------------------------------------------------------------------- 1 | CFLAGS+=-g -Wall -O0 2 | LDFLAGS+=-g 3 | 4 | all: test 5 | 6 | test: test.o 7 | $(CC) -o $@ $^ $(LDFLAGS) 8 | 9 | 10 | clean: 11 | rm -f test 12 | rm -f *.o 13 | 14 | -------------------------------------------------------------------------------- /testapps/c_code/makefile: -------------------------------------------------------------------------------- 1 | CFLAGS+=-g -Wall -O0 2 | LDFLAGS+=-g 3 | 4 | all: test 5 | 6 | test: other.o test.o 7 | $(CC) -o $@ $^ $(LDFLAGS) 8 | 9 | 10 | clean: 11 | rm -f test 12 | rm -f *.o 13 | 14 | -------------------------------------------------------------------------------- /testapps/threads/makefile: -------------------------------------------------------------------------------- 1 | CFLAGS+=-g -Wall -O0 2 | LDFLAGS+=-g -lpthread 3 | 4 | all: test 5 | 6 | test: test.o 7 | $(CC) -o $@ $^ $(LDFLAGS) 8 | 9 | 10 | clean: 11 | rm -f test 12 | rm -f *.o 13 | 14 | -------------------------------------------------------------------------------- /testapps/coredump/makefile: -------------------------------------------------------------------------------- 1 | CFLAGS+=-g -Wall -O0 2 | LDFLAGS+=-g 3 | 4 | all: test 5 | 6 | test: test.o 7 | $(CC) -o $@ $^ $(LDFLAGS) 8 | 9 | 10 | clean: 11 | rm -f test 12 | rm -f *.o 13 | rm -f core 14 | 15 | -------------------------------------------------------------------------------- /testapps/tutorial_c/makefile: -------------------------------------------------------------------------------- 1 | CFLAGS+=-m64 -g -O0 -Wall 2 | LDFLAGS+=-m64 3 | 4 | OBJ=func.o main.o 5 | 6 | test: func.o main.o 7 | $(CC) -o $@ $^ $(LDFLAGS) 8 | 9 | 10 | clean: 11 | rm -f test 12 | rm -f $(OBJ) 13 | 14 | -------------------------------------------------------------------------------- /testapp/makefile: -------------------------------------------------------------------------------- 1 | CFLAGS+=-g -O0 -Wall 2 | LDFLAGS+=-lpthread 3 | OBJ=subdir/subfile.o test.o 4 | 5 | test: subdir/subfile.o test.o 6 | $(CC) -o $@ $^ $(LDFLAGS) 7 | 8 | 9 | clean: 10 | rm -f test 11 | rm -f $(OBJ) 12 | 13 | 14 | -------------------------------------------------------------------------------- /testapps/ada/makefile: -------------------------------------------------------------------------------- 1 | 2 | all: test.adb 3 | gnatmake -g $^ 4 | 5 | clean: 6 | rm -f test 7 | rm -f *.o 8 | rm -f *.ali 9 | rm -f *.ads 10 | rm -f b~*.* 11 | 12 | distclean: 13 | make clean 14 | rm -f gede_gdb_log.txt 15 | 16 | .PHONY: all distclean clean 17 | 18 | -------------------------------------------------------------------------------- /testapps/ansicolor/start_gede.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make -C ../../src 4 | make 5 | #cd ../testapps/coredump 6 | 7 | #../../src/gede 8 | 9 | 10 | #../../src/gede --args /bin/bash 11 | #../../src/gede --args ../../src/gede --args ./test 12 | ../../src/gede --args ./test 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/syntaxhighlighter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | 10 | #include "syntaxhighlighter.h" 11 | 12 | -------------------------------------------------------------------------------- /testapps/tutorial_c/func.c: -------------------------------------------------------------------------------- 1 | #include "func.h" 2 | 3 | const char *my_function(int a) 4 | { 5 | int b; 6 | const char *str; 7 | b = a; 8 | 9 | if(b > 2) 10 | str = "Greater than 2"; 11 | else 12 | str = "Less or equal to 2"; 13 | 14 | return str; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /testapps/stdlib_cxx/otherclass.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE__OTHERCLASS_H 2 | #define FILE__OTHERCLASS_H 3 | 4 | class OtherClass 5 | { 6 | public: 7 | OtherClass(); 8 | 9 | void otherClassFunc1(); 10 | int otherClassFunc2(int a,int b); 11 | }; 12 | 13 | 14 | #endif // FILE__OTHERCLASS_H 15 | -------------------------------------------------------------------------------- /src/varctl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #include "varctl.h" 10 | 11 | #include 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /testapps/c_code/other.c: -------------------------------------------------------------------------------- 1 | 2 | void func() 3 | { 4 | volatile int a = 1; 5 | a++; 6 | a++; 7 | a++; 8 | } 9 | 10 | void func21() 11 | { 12 | int q; 13 | q = 0; 14 | q++; 15 | q++; 16 | } 17 | 18 | void func22() 19 | { 20 | 21 | } 22 | 23 | void other_func() 24 | { 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /testapps/golang/test.go: -------------------------------------------------------------------------------- 1 | // Example program 2 | package main 3 | import ("fmt") 4 | 5 | func myfunc(a int) int { 6 | return a + 2 7 | } 8 | 9 | /* Example main */ 10 | func main() { 11 | var a int = 2 12 | if a > 1 { 13 | a = a +1 14 | } 15 | a = myfunc(a) 16 | fmt.Println("Hello!\n") 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /testapps/stdlib_cxx/makefile: -------------------------------------------------------------------------------- 1 | CXXFLAGS+=-g -Wall -O0 2 | 3 | OBJ=test.o otherclass.o 4 | 5 | all: test 6 | 7 | test: $(OBJ) 8 | $(CXX) -o $@ $^ 9 | 10 | 11 | clean: 12 | rm -f test 13 | rm -f *.o 14 | 15 | distclean: 16 | @(MAKE) clean 17 | chmod a-x *.cpp 18 | chmod a-x makefile 19 | #rm -f *~ 20 | chmod a+x start_gede.sh 21 | 22 | -------------------------------------------------------------------------------- /src/tabwidgetadv.cpp: -------------------------------------------------------------------------------- 1 | #include "tabwidgetadv.h" 2 | 3 | #include 4 | 5 | 6 | 7 | TabWidgetAdv::TabWidgetAdv(QWidget * parent) 8 | : QTabWidget(parent) 9 | { 10 | 11 | } 12 | 13 | TabWidgetAdv::~TabWidgetAdv() 14 | { 15 | 16 | 17 | } 18 | 19 | int TabWidgetAdv::tabAt(QPoint pos) 20 | { 21 | return tabBar()->tabAt(pos); 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /testapps/stdlib_cxx/otherclass.cpp: -------------------------------------------------------------------------------- 1 | #include "otherclass.h" 2 | 3 | 4 | 5 | OtherClass::OtherClass() 6 | { 7 | 8 | } 9 | 10 | 11 | int OtherClass::otherClassFunc2(int a,int b) 12 | { 13 | int y; 14 | y = a+b; 15 | y++; 16 | return y; 17 | } 18 | 19 | void OtherClass::otherClassFunc1() 20 | { 21 | int a; 22 | a++; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/tabwidgetadv.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE__TABWIDGETADV_H 2 | #define FILE__TABWIDGETADV_H 3 | 4 | #include 5 | #include 6 | 7 | class TabWidgetAdv : public QTabWidget 8 | { 9 | Q_OBJECT 10 | public: 11 | TabWidgetAdv(QWidget * parent = 0 ); 12 | ~TabWidgetAdv(); 13 | 14 | int tabAt(QPoint pos); 15 | 16 | 17 | }; 18 | 19 | 20 | #endif // FILE__TABWIDGETADV_H 21 | -------------------------------------------------------------------------------- /src/qtutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2016 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | #ifndef FILE__QTUTIL_H 9 | #define FILE__QTUTIL_H 10 | 11 | #include 12 | 13 | bool isInteger(QString str); 14 | 15 | 16 | #endif 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__VERSION_H 10 | #define FILE__VERSION_H 11 | 12 | #define GD_MAJOR 2 13 | #define GD_MINOR 16 14 | #define GD_PATCH 2 15 | 16 | 17 | #endif // FILE__VERSION_H 18 | 19 | -------------------------------------------------------------------------------- /src/resource.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | res/next.png 4 | res/stop.png 5 | res/quit.png 6 | res/restart.png 7 | res/step_over.png 8 | res/step_into.png 9 | res/continue.png 10 | res/file.png 11 | res/folder.png 12 | res/step_out.png 13 | 14 | 15 | -------------------------------------------------------------------------------- /testapps/fortran/test.f95: -------------------------------------------------------------------------------- 1 | ! comment 2 | 3 | #include "inc.f95" 4 | 5 | #ifdef NEVER 6 | integer :: n 7 | #endif 8 | 9 | Subroutine sfunc1() 10 | print *, "Hello \\ World again!\\" 11 | end Subroutine sfunc1 12 | 13 | Program hello 14 | integer :: y 15 | real :: x 16 | x = 1.1 17 | x = 2.3 18 | y = 2 19 | x = 3.4 20 | y = 3 21 | print *, "Hello World!" 22 | call sfunc1() 23 | end program hello 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /testapps/tutorial_c/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "func.h" 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | int i; 8 | int loops; 9 | 10 | if(argc > 1) 11 | loops = atoi(argv[1]); 12 | 13 | for(i = 0;i < loops;i++) 14 | { 15 | int a; 16 | const char* str; 17 | 18 | a = i; 19 | str = my_function(a); 20 | 21 | printf("a:%d str:%s\n", a, str); 22 | } 23 | 24 | 25 | return 0; 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/qtutil.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2016 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #include "qtutil.h" 10 | 11 | 12 | 13 | bool isInteger(QString str) 14 | { 15 | if(str.size() == 0) 16 | return false; 17 | if(str[0] == '-') 18 | return true; 19 | if(str[0].isDigit()) 20 | return true; 21 | return false; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /tests/ini/test_ini.pro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | lessThan(QT_MAJOR_VERSION, 5) { 5 | QT += gui core 6 | } 7 | else { 8 | QT += gui core widgets 9 | } 10 | 11 | TEMPLATE = app 12 | 13 | SOURCES += test_ini.cpp 14 | 15 | 16 | SOURCES+=../../src/settings.cpp ../../src/ini.cpp 17 | HEADERS+=../../src/settings.h ../../src/ini.h 18 | 19 | SOURCES+=../../src/log.cpp 20 | HEADERS+=../../src/log.h 21 | SOURCES+=../../src/util.cpp 22 | HEADERS+=../../src/util.h 23 | 24 | 25 | 26 | QMAKE_CXXFLAGS += -I../../src -g 27 | 28 | 29 | TARGET=test_ini 30 | 31 | -------------------------------------------------------------------------------- /testapps/rust/test.rs: -------------------------------------------------------------------------------- 1 | 2 | // A single line comment 3 | 4 | #[cfg(feature = "test")] 5 | fn test(a: i32, b: i32) -> u8 { 6 | return a+10+b; 7 | } 8 | 9 | 10 | fn testf(a: f32, b: f32) -> f32 { 11 | return a+b+10.0; 12 | } 13 | 14 | /* 15 | * a multi line comment 16 | */ 17 | 18 | fn main2() -> i32 { 19 | let mut a = 2; 20 | let b = testf(1.3, 1.4); 21 | while a <= 10 { 22 | println!("Hello, world: {} {}!", a, b); 23 | a += 1; 24 | } 25 | return a; 26 | } 27 | 28 | 29 | fn main() { 30 | 31 | main2(); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/autosignalblocker.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE__AUTO_SIGNAL_BLOCKER_H 2 | #define FILE__AUTO_SIGNAL_BLOCKER_H 3 | 4 | #include 5 | 6 | class AutoSignalBlocker 7 | { 8 | private: 9 | bool m_signalBlocked; 10 | QObject *m_obj; 11 | 12 | public: 13 | AutoSignalBlocker(QObject *obj) 14 | :m_obj(obj) 15 | { 16 | m_signalBlocked = m_obj->blockSignals(true); 17 | }; 18 | virtual ~AutoSignalBlocker() 19 | { 20 | m_obj->blockSignals(m_signalBlocked); 21 | } 22 | 23 | private: 24 | AutoSignalBlocker(){}; 25 | 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/variableinfowindow.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE__VARIABLEINFOWINDOW_H 2 | #define FILE__VARIABLEINFOWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class VariableInfoWindow : public QWidget 10 | { 11 | public: 12 | 13 | VariableInfoWindow(QFont *font); 14 | virtual ~VariableInfoWindow(); 15 | 16 | 17 | void show(QString expr); 18 | void hide(); 19 | 20 | protected: 21 | void paintEvent(QPaintEvent *pe); 22 | void resizeEvent(QResizeEvent *re); 23 | 24 | private: 25 | QString m_expr; 26 | QString m_text; 27 | QFont *m_font; 28 | }; 29 | 30 | #endif // FILE__VARIABLEINFOWINDOW_H 31 | 32 | -------------------------------------------------------------------------------- /src/parsecharqueue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2020 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__STRINGQUEUE_H 10 | #define FILE__STRINGQUEUE_H 11 | 12 | #include 13 | 14 | class ParseCharQueue 15 | { 16 | public: 17 | 18 | ParseCharQueue(QString str); 19 | virtual ~ParseCharQueue(); 20 | 21 | QChar popNext(bool *isEscaped = NULL); 22 | void revertPop(); 23 | bool isEmpty(); 24 | 25 | private: 26 | QString m_list; 27 | int m_idx; 28 | bool m_isEscMode; 29 | }; 30 | 31 | 32 | #endif // FILE__STRINGQUEUE_H 33 | 34 | -------------------------------------------------------------------------------- /src/aboutdialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__ABOUTDIALOG_H 10 | #define FILE__ABOUTDIALOG_H 11 | 12 | #include 13 | 14 | #include "settings.h" 15 | #include "ui_aboutdialog.h" 16 | 17 | 18 | class AboutDialog : public QDialog 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | 24 | AboutDialog(QWidget *parent, Settings *cfg); 25 | 26 | 27 | private: 28 | QString getGdbVersion(QString gdbPath); 29 | 30 | 31 | Ui_AboutDialog m_ui; 32 | 33 | }; 34 | 35 | #endif // FILE__ABOUTDIALOG_H 36 | 37 | -------------------------------------------------------------------------------- /src/execombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE__EXECOMBOBOX_H 2 | #define FILE__EXECOMBOBOX_H 3 | 4 | #include 5 | 6 | 7 | class ExeComboBox : public QComboBox 8 | { 9 | Q_OBJECT 10 | public: 11 | 12 | enum SearchAreas 13 | { 14 | UseEnvPath = (0x1<<0), 15 | UseCurrentDir = (0x1<<1), 16 | }; 17 | 18 | ExeComboBox(QWidget *parent = NULL); 19 | virtual ~ExeComboBox(); 20 | 21 | void setFilter(QRegExp filter) { m_filter = filter; }; 22 | 23 | void setSearchAreas(int areas) { m_areas = areas; }; 24 | 25 | private: 26 | void fillIn(); 27 | void showPopup(); 28 | 29 | private: 30 | QRegExp m_filter; 31 | int m_areas; 32 | }; 33 | 34 | 35 | 36 | #endif // FILE__EXECOMBOBOX_H 37 | -------------------------------------------------------------------------------- /testapps/threads/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void func() 6 | { 7 | volatile int a = 1; 8 | a++; 9 | a++; 10 | a++; 11 | } 12 | 13 | 14 | 15 | void *thread_func(void *ptr) 16 | { 17 | unsigned int i = 0; 18 | while(1) 19 | { 20 | i++; 21 | usleep(1000); 22 | } 23 | return NULL; 24 | } 25 | 26 | 27 | 28 | typedef enum {CUSTOM_ENUM1, CUSTOM_ENUM2} CustomEnum; 29 | int main(int argc,char *argv[]) 30 | { 31 | volatile int j = 0; 32 | pthread_t th; 33 | 34 | pthread_create(&th, NULL, thread_func, 0); 35 | 36 | while(1) 37 | { 38 | j++; 39 | j++; 40 | j++; 41 | usleep(10*1000); 42 | } 43 | return 0; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/gdbmiparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__GDBMI_VALUE_PARSER_H 10 | #define FILE__GDBMI_VALUE_PARSER_H 11 | 12 | #include "tree.h" 13 | #include 14 | #include "com.h" 15 | #include "core.h" 16 | 17 | 18 | class GdbMiParser 19 | { 20 | public: 21 | 22 | GdbMiParser(){}; 23 | 24 | static int parseVariableData(CoreVar *var, QList *tokenList); 25 | static QList tokenizeVarString(QString str); 26 | 27 | 28 | static void setData(CoreVar *var, QString data); 29 | 30 | }; 31 | 32 | 33 | #endif // FILE__GDBMI_VALUE_PARSER_H 34 | 35 | -------------------------------------------------------------------------------- /tests/tagtest/tagtest.pro: -------------------------------------------------------------------------------- 1 | lessThan(QT_MAJOR_VERSION, 5) { 2 | QT += gui core 3 | } 4 | else { 5 | QT += gui core widgets 6 | } 7 | 8 | TEMPLATE = app 9 | 10 | SOURCES+=tagtest.cpp 11 | 12 | SOURCES+=../../src/tagscanner.cpp 13 | HEADERS+=../../src/tagscanner.h 14 | 15 | SOURCES+=../../src/log.cpp 16 | HEADERS+=../../src/log.h 17 | SOURCES+=../../src/util.cpp 18 | HEADERS+=../../src/util.h 19 | 20 | 21 | SOURCES += ../../src/rusttagscanner.cpp 22 | HEADERS += ../../src/rusttagscanner.h 23 | 24 | SOURCES += ../../src/adatagscanner.cpp 25 | HEADERS += ../../src/adatagscanner.h 26 | 27 | 28 | SOURCES += ../../src/ini.cpp ../../src/settings.cpp 29 | HEADERS += ../../src/ini.h ../../src/settings.h 30 | 31 | QMAKE_CXXFLAGS += -I../../src -g 32 | 33 | 34 | TARGET=tagtest 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/colorbutton.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE__COLORBUTTON_H 2 | #define FILE__COLORBUTTON_H 3 | 4 | #include 5 | 6 | /** 7 | * @brief A button used to select colors. Pressing the button triggers a color select dialog. 8 | * 9 | * The button will have a square in the selected color drawn on top of the button. 10 | */ 11 | class MColorButton : public QPushButton 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | 17 | MColorButton(QWidget *parent); 18 | virtual ~MColorButton(); 19 | 20 | void setColor(QColor clr); 21 | QColor getColor(); 22 | 23 | private: 24 | virtual void paintEvent ( QPaintEvent * e ); 25 | void showColorSelectDialog(QColor *color); 26 | 27 | private slots: 28 | void onButtonClicked(); 29 | 30 | private: 31 | QColor m_clr; 32 | }; 33 | 34 | #endif // FILE__COLORBUTTON_H 35 | -------------------------------------------------------------------------------- /testapps/ada/test.adb: -------------------------------------------------------------------------------- 1 | -------------------------- 2 | -- A simple ada example 3 | -- 4 | --------------------------- 5 | 6 | with Text_IO; use Text_IO; 7 | 8 | procedure test is 9 | j : integer; 10 | str : string(1..5); 11 | c : character; 12 | n : natural; 13 | 14 | function min(a, b : integer) return integer is 15 | begin 16 | if a < b then 17 | return a; 18 | else 19 | return b; 20 | end if; 21 | end min; 22 | 23 | begin 24 | 25 | str := "hej" & "!!"; 26 | 27 | n := 10; 28 | 29 | c := 'a'; 30 | 31 | j := min(1, 12); 32 | j := 2**3; 33 | Put_Line("Hello world!!"); 34 | 35 | for i in 1.. 10 loop 36 | j := j + 1; 37 | Put_Line("loop"); 38 | end loop; 39 | 40 | end test; 41 | 42 | -------------------------------------------------------------------------------- /testapps/coredump/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void func() 4 | { 5 | int *ptr = 0; 6 | volatile int a = 1; 7 | a++; 8 | a++; 9 | a++; 10 | 11 | *ptr = 2; 12 | } 13 | 14 | typedef enum {CUSTOM_ENUM1, CUSTOM_ENUM2} CustomEnum; 15 | int main(int argc,char *argv[]) 16 | { 17 | struct 18 | { 19 | int a; 20 | struct 21 | { 22 | int b; 23 | }s2; 24 | }s; 25 | float f1; 26 | char *varStr; 27 | enum {ENUM1, ENUM2}varEnum; 28 | CustomEnum customEnum1; 29 | 30 | f1 = 0.0; 31 | s.a = 0; 32 | s.s2.b = 1; 33 | varEnum = ENUM1; 34 | varEnum = ENUM2; 35 | while(1) 36 | { 37 | f1 += 0.1; 38 | func(); 39 | s.a++; 40 | s.s2.b++; 41 | s.s2.b++; 42 | s.a++; 43 | 44 | } 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /tests/tagtest/tagtest.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "tagscanner.h" 3 | #include "log.h" 4 | 5 | #include 6 | #if QT_VERSION < 0x050000 7 | #include 8 | #endif 9 | #include 10 | 11 | int dummy; 12 | 13 | 14 | void dummyfunc() 15 | { 16 | dummy++; 17 | 18 | } 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | Settings cfg; 23 | QString filename = "tagtest.cpp"; 24 | QApplication app(argc,argv); 25 | TagScanner scanner; 26 | 27 | for(int i = 1;i < argc;i++) 28 | { 29 | const char *curArg = argv[i]; 30 | if(curArg[0] != '-') 31 | filename = curArg; 32 | } 33 | scanner.init(&cfg); 34 | 35 | 36 | 37 | QList taglist; 38 | if(scanner.scan(filename, &taglist)) 39 | errorMsg("Failed to scan"); 40 | 41 | scanner.dump(taglist); 42 | 43 | return 0; 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/memorydialog.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE_MEMORYDIALOG_H 2 | #define FILE_MEMORYDIALOG_H 3 | 4 | #include "ui_memorydialog.h" 5 | 6 | 7 | #include 8 | #include 9 | 10 | 11 | class MemoryDialog : public QDialog, public IMemoryWidget 12 | { 13 | Q_OBJECT 14 | public: 15 | MemoryDialog(QWidget *parent = NULL); 16 | 17 | virtual QByteArray getMemory(quint64 startAddress, int count); 18 | void setStartAddress(quint64 addr); 19 | 20 | void setConfig(Settings *cfg); 21 | 22 | public slots: 23 | void onVertScroll(int pos); 24 | void onUpdate(); 25 | 26 | private: 27 | quint64 inputTextToAddress(QString text); 28 | void wheelEvent(QWheelEvent * event); 29 | 30 | private: 31 | Ui_MemoryDialog m_ui; 32 | quint64 m_startScrollAddress; //!< The minimum address the user can scroll to. 33 | }; 34 | 35 | 36 | 37 | 38 | 39 | #endif // FILE_MEMORYDIALOG_H 40 | 41 | -------------------------------------------------------------------------------- /src/varctl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__VAR_CTL_H 10 | #define FILE__VAR_CTL_H 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | class VarCtl : public QObject 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | VarCtl(){}; 24 | 25 | 26 | enum DispFormat 27 | { 28 | DISP_NATIVE = 0, 29 | DISP_DEC, 30 | DISP_BIN, 31 | DISP_HEX, 32 | DISP_CHAR, 33 | }; 34 | typedef struct 35 | { 36 | DispFormat dispFormat; 37 | bool isExpanded; 38 | QString lastData; 39 | }DispInfo; 40 | 41 | typedef QMap DispInfoMap; 42 | 43 | 44 | 45 | }; 46 | 47 | #endif // FILE__VAR_CTL_H 48 | -------------------------------------------------------------------------------- /tests/highlightertest/hltest.pro: -------------------------------------------------------------------------------- 1 | lessThan(QT_MAJOR_VERSION, 5) { 2 | QT += gui core 3 | } 4 | else { 5 | QT += gui core widgets 6 | } 7 | 8 | TEMPLATE = app 9 | 10 | SOURCES+=hltest.cpp 11 | 12 | SOURCES+=../../src/syntaxhighlighter.cpp ../../src/syntaxhighlighterbasic.cpp ../../src/syntaxhighlightercxx.cpp 13 | SOURCES+=../../src/syntaxhighlighterrust.cpp 14 | HEADERS+=../../src/syntaxhighlighter.h ../../src/syntaxhighlighterbasic.h ../../src/syntaxhighlightercxx.h 15 | HEADERS+=../../src/syntaxhighlighterrust.h 16 | 17 | SOURCES+=../../src/syntaxhighlighterfortran.cpp 18 | HEADERS+=../../src/syntaxhighlighterfortran.h 19 | 20 | SOURCES+=../../src/parsecharqueue.cpp 21 | HEADERS+=../../src/parsecharqueue.h 22 | 23 | 24 | SOURCES+=../../src/settings.cpp ../../src/ini.cpp 25 | HEADERS+=../../src/settings.h ../../src/ini.h 26 | 27 | SOURCES+=../../src/log.cpp 28 | HEADERS+=../../src/log.h 29 | SOURCES+=../../src/util.cpp 30 | HEADERS+=../../src/util.h 31 | 32 | 33 | 34 | QMAKE_CXXFLAGS += -I../../src -g 35 | 36 | 37 | TARGET=hltest 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/locator.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE__LOCATOR_H 2 | #define FILE__LOCATOR_H 3 | 4 | #include 5 | #include 6 | 7 | #include "tagmanager.h" 8 | 9 | class Location 10 | { 11 | public: 12 | Location(QString filename_, int lineno_); 13 | Location() {}; 14 | 15 | void dump(); 16 | 17 | public: 18 | QString m_filename; 19 | int m_lineNo; 20 | }; 21 | 22 | class Locator 23 | { 24 | public: 25 | Locator(TagManager *mgr, QList *sourceFiles); 26 | virtual ~Locator(); 27 | 28 | void setCurrentFile(QString filename); 29 | QVector locate(QString expr); 30 | QVector locateFunction(QString name); 31 | 32 | QStringList searchExpression(QString expressionStart); 33 | 34 | QStringList searchExpression(QString filename, QString expressionStart); 35 | 36 | private: 37 | QStringList findFile(QString defFilename); 38 | 39 | public: 40 | TagManager *m_mgr; 41 | QString m_currentFilename; 42 | QList *m_sourceFiles; 43 | }; 44 | 45 | #endif // FILE__LOCATOR_H 46 | 47 | -------------------------------------------------------------------------------- /src/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__LOG_H 10 | #define FILE__LOG_H 11 | 12 | #include 13 | 14 | class ILogger 15 | { 16 | public: 17 | ILogger() {}; 18 | virtual ~ILogger() {}; 19 | 20 | virtual void ILogger_onWarnMsg(QString text) = 0; 21 | virtual void ILogger_onErrorMsg(QString text) = 0; 22 | virtual void ILogger_onInfoMsg(QString text) = 0; 23 | 24 | }; 25 | 26 | #ifndef ENABLE_DEBUGMSG 27 | #define debugMsg(fmt...) do{}while(0) 28 | #else 29 | void debugMsg_(const char *file, int lineNo, const char *fmt,...); 30 | #define debugMsg(fmt...) debugMsg_(__FILE__, __LINE__, fmt) 31 | #endif 32 | 33 | void errorMsg(const char *fmt,...); 34 | void warnMsg(const char *fmt,...); 35 | void infoMsg(const char *fmt,...); 36 | 37 | 38 | void loggerRegister(ILogger *logger); 39 | void loggerUnregister(ILogger *logger); 40 | 41 | 42 | #endif // FILE__LOG_H 43 | 44 | 45 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Gede 2 | ---- 3 | 4 | Gede was written by Johan Henriksson. 5 | See LICENSE file for license information. 6 | 7 | The icons used are from the NetBeans project and licensed under the 8 | terms of the NetBeans License Agreement. 9 | 10 | Dependencies 11 | ============ 12 | 13 | Gede depends on Qt4/Qt5 and exuberant-ctags. 14 | 15 | Make sure that you have all dependencies installed. 16 | 17 | On Debian/Ubuntu/Mint: 18 | 19 | # sudo apt-get install g++ 20 | # sudo apt-get install exuberant-ctags 21 | # sudo apt-get install qt4-designer qt4-qmake libqt4-dev libssl-dev 22 | 23 | On Redhat/Centos: 24 | 25 | # sudo yum install gcc 26 | # sudo yum install gcc-c++ 27 | # sudo yum install ctags 28 | # sudo yum install qt4-designer qt-devel 29 | 30 | On FreeBSD: 31 | 32 | # pkg install gdb 33 | # pkg install universal-ctags-g20180225 34 | # pkg install qt5 35 | # pkg install gcc 36 | 37 | 38 | Building 39 | ======== 40 | 41 | Extract: 42 | 43 | # tar -xvJf gede-x.y.z.tar.xz 44 | 45 | 46 | Compile and install (to /usr/local/bin): 47 | 48 | # sudo make install 49 | 50 | Gede can now be launched: 51 | 52 | # gede 53 | 54 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__UTIL_H 10 | #define FILE__UTIL_H 11 | 12 | #include 13 | 14 | #define MIN(a,b) ((a)<(b)) 15 | #define MAX(a,b) ((a)>(b)) 16 | 17 | //#define stringToCStr(str) str.toAscii().constData() 18 | #define stringToCStr(str) qPrintable(str) 19 | 20 | 21 | QString getFilenamePart(QString fullPath); 22 | void dividePath(QString fullPath, QString *filename, QString *folderPath); 23 | QString getExtensionPart(QString filename); 24 | 25 | unsigned char hexStringToU8(const char *str); 26 | long long stringToLongLong(const char* str); 27 | long long stringToLongLong(QString str); 28 | QString longLongToHexString(long long num); 29 | 30 | QString simplifyPath(QString path); 31 | 32 | typedef enum{ DISTRO_DEBIAN, DISTRO_UBUNTU, DISTRO_UNKNOWN} DistroType; 33 | void detectDistro(DistroType *type, QString *distroDesc); 34 | 35 | QString addrToString(quint64 addr); 36 | 37 | bool exeExists(QString name, bool checkCurrentDir = false); 38 | 39 | 40 | 41 | #endif // FILE__UTIL_H 42 | 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2017, Johan Henriksson 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | 12 | -------------------------------------------------------------------------------- /testapps/stdlib_cxx/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | 9 | 10 | 11 | class MyClass 12 | { 13 | public: 14 | MyClass() {}; 15 | 16 | int a; 17 | char *str; 18 | 19 | static void func2() 20 | { 21 | printf("hello global!\n"); 22 | }; 23 | 24 | 25 | 26 | 27 | }; 28 | 29 | using namespace std; 30 | int main(int argc,char *argv[]) 31 | { 32 | MyClass myclass1; 33 | string cxx_str; 34 | vector g_vectorInt; 35 | list g_listInt; 36 | struct { 37 | const char *a_str; 38 | int a_int; 39 | }c_struct; 40 | char *d_str; 41 | int e_int; 42 | const char *f_str = "hej"; 43 | const char g_str[] = "hej"; 44 | const int h_vec[] = {1,2,3}; 45 | const int *i_vec = NULL; 46 | struct { 47 | vector list1; 48 | int j_struct_int; 49 | }j_struct; 50 | double k_double = 1.2; 51 | 52 | MyClass::func2(); 53 | 54 | cxx_str = "ett"; 55 | cxx_str = "tva"; 56 | 57 | i_vec = (const int*)0x10; 58 | g_vectorInt.push_back(1); 59 | g_vectorInt.push_back(2); 60 | 61 | g_listInt.push_back(1); 62 | g_listInt.push_back(2); 63 | 64 | while(1) 65 | { 66 | e_int++; 67 | } 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/gotodialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__GOTODIALOG_H 10 | #define FILE__GOTODIALOG_H 11 | 12 | #include 13 | #include 14 | 15 | #include "ui_gotodialog.h" 16 | 17 | #include "settings.h" 18 | #include "locator.h" 19 | 20 | class GoToDialog : public QDialog 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | 26 | GoToDialog(QWidget *parent, Locator *locator, Settings *cfg, QString currentFilename); 27 | virtual ~GoToDialog(); 28 | 29 | void getSelection(QString *filename, int *lineno); 30 | 31 | void saveSettings(Settings *cfg); 32 | 33 | public slots: 34 | void onGo(); 35 | void onSearchTextEdited( const QString & text ); 36 | void onItemClicked ( QListWidgetItem * item ); 37 | 38 | private: 39 | void showListWidget(bool show ); 40 | bool eventFilter(QObject *obj, QEvent *event); 41 | 42 | void onComboBoxTabKey(); 43 | QString getCurrentLineEditText(); 44 | QString cleanupLinEditText(QString rawText); 45 | 46 | 47 | private: 48 | 49 | Ui_GoToDialog m_ui; 50 | QString m_currentFilename; 51 | Locator *m_locator; 52 | 53 | }; 54 | 55 | #endif // FILE__ABOUTDIALOG_H 56 | 57 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__CONFIG_H 10 | #define FILE__CONFIG_H 11 | 12 | #define PROJECT_CONFIG_FILENAME "gede2.ini" 13 | 14 | #define GLOBAL_CONFIG_DIR ".config/gede2" 15 | 16 | #define PROJECT_GLOBAL_CONFIG_FILENAME "proj_gede2.ini" 17 | 18 | #define GLOBAL_CONFIG_FILENAME "gede2.ini" 19 | 20 | #define GDB_LOG_FILE "gede_gdb_log.txt" 21 | 22 | // etags command and argument to use to get list of tags 23 | #define ETAGS_CMD1 "ctags" // Used on Linux 24 | #define ETAGS_CMD2 "exctags" // Used on freebsd 25 | #define ETAGS_ARGS " -f - --excmd=number --fields=+nmsSk" 26 | 27 | 28 | // Max number of recently used goto locations to save 29 | #define MAX_GOTO_RUI_COUNT 10 30 | 31 | // Width of items in the GoTo list widget. 32 | #define GOTO_LISTWIDGET_ITEM_WIDTH 240 33 | 34 | 35 | // Expand all classes if the total number of members is below this number 36 | #define CLASS_LIST_AUTO_EXPAND_COUNT 40 37 | 38 | // Which fileextension does rust use? 39 | #define RUST_FILE_EXTENSION ".rs" 40 | 41 | // Which fileextension does go use? 42 | #define GOLANG_FILE_EXTENSION ".go" 43 | 44 | // Which fileextension does ada use? 45 | #define ADA_FILE_EXTENSION ".adb" 46 | 47 | 48 | 49 | #endif // FILE__CONFIG_H 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/syntaxhighlighter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__SYNTAXHIGHLIGHTER 10 | #define FILE__SYNTAXHIGHLIGHTER 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "settings.h" 18 | 19 | 20 | struct TextField 21 | { 22 | QColor m_color; 23 | QString m_text; 24 | enum {COMMENT, WORD, NUMBER, KEYWORD, CPP_KEYWORD, INC_STRING, STRING, SPACES} m_type; 25 | 26 | bool isHash() const { return m_text == "#" ? true : false; }; 27 | bool isSpaces() const { return m_type == SPACES ? true : false; }; 28 | int getLength() { return m_text.length(); }; 29 | }; 30 | 31 | 32 | class SyntaxHighlighter 33 | { 34 | public: 35 | SyntaxHighlighter(){}; 36 | virtual ~SyntaxHighlighter(){}; 37 | 38 | virtual void colorize(QString text) = 0; 39 | 40 | virtual QVector getRow(unsigned int rowIdx) = 0; 41 | virtual unsigned int getRowCount() = 0; 42 | virtual void reset() = 0; 43 | 44 | virtual bool isKeyword(QString text) const = 0; 45 | virtual bool isSpecialChar(char c) const = 0; 46 | virtual bool isSpecialChar(TextField *field) const = 0; 47 | virtual void setConfig(Settings *cfg) = 0; 48 | }; 49 | 50 | #endif // #ifndef FILE__SYNTAXHIGHLIGHTER 51 | -------------------------------------------------------------------------------- /src/memorywidget.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE__MEMORYWIDGET_H 2 | #define FILE__MEMORYWIDGET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | #include "settings.h" 11 | 12 | 13 | class IMemoryWidget 14 | { 15 | public: 16 | virtual QByteArray getMemory(quint64 startAddress, int count) = 0; 17 | 18 | }; 19 | 20 | class MemoryWidget : public QWidget 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | 26 | MemoryWidget(QWidget *parent = NULL); 27 | virtual ~MemoryWidget(); 28 | 29 | void paintEvent ( QPaintEvent * event ); 30 | void setInterface(IMemoryWidget *inf); 31 | 32 | void setConfig(Settings *cfg); 33 | 34 | private: 35 | int getRowHeight(); 36 | quint64 getAddrAtPos(QPoint pos); 37 | int getHeaderHeight(); 38 | char byteToChar(quint8 d); 39 | 40 | virtual void keyPressEvent(QKeyEvent *e); 41 | 42 | public slots: 43 | void setStartAddress(quint64 addr); 44 | void onCopy(); 45 | 46 | private: 47 | void mousePressEvent(QMouseEvent * event); 48 | void mouseMoveEvent ( QMouseEvent * event ); 49 | void mouseReleaseEvent(QMouseEvent * event); 50 | 51 | private: 52 | QFont m_font; 53 | QFontMetrics *m_fontInfo; 54 | 55 | bool m_selectionStartValid; 56 | quint64 m_startAddress; 57 | quint64 m_selectionStart, m_selectionEnd; 58 | IMemoryWidget *m_inf; 59 | QMenu m_popupMenu; 60 | int m_addrCharWidth; 61 | }; 62 | 63 | #endif // FILE__MEMORYWIDGET_H 64 | 65 | -------------------------------------------------------------------------------- /src/execombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "execombobox.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | 8 | ExeComboBox::ExeComboBox(QWidget *parent) 9 | : QComboBox(parent) 10 | ,m_filter(".*") 11 | ,m_areas(UseEnvPath) 12 | { 13 | 14 | } 15 | 16 | ExeComboBox::~ExeComboBox() 17 | { 18 | 19 | } 20 | 21 | void ExeComboBox::showPopup () 22 | { 23 | if(count() == 0) 24 | { 25 | fillIn(); 26 | } 27 | 28 | QComboBox::showPopup(); 29 | } 30 | 31 | 32 | 33 | /** 34 | * @brief Searches for and fills in any gdb instances found. 35 | */ 36 | void ExeComboBox::fillIn() 37 | { 38 | QStringList pathList; 39 | if((m_areas & UseEnvPath) == UseEnvPath) 40 | { 41 | const char *pathStr = getenv("PATH"); 42 | if(pathStr) 43 | pathList = QString(pathStr).split(":"); 44 | } 45 | if((m_areas & UseCurrentDir) == UseCurrentDir) 46 | { 47 | pathList.append("./"); 48 | } 49 | for(int i = 0;i < pathList.size();i++) 50 | { 51 | QString exePath = pathList[i]; 52 | 53 | QDir dir(exePath); 54 | dir.setFilter(QDir::Files | QDir::Executable); 55 | QFileInfoList list = dir.entryInfoList(); 56 | for (int i = 0; i < list.size(); ++i) 57 | { 58 | QFileInfo fileInfo = list.at(i); 59 | QString fileName = fileInfo.fileName(); 60 | if(fileName.contains(m_filter)) 61 | { 62 | addItem(fileInfo.filePath()); 63 | } 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/parsecharqueue.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2020 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #include "parsecharqueue.h" 10 | 11 | 12 | ParseCharQueue::ParseCharQueue(QString str) 13 | : m_list(str) 14 | ,m_idx(0) 15 | ,m_isEscMode(false) 16 | { 17 | 18 | } 19 | 20 | 21 | ParseCharQueue::~ParseCharQueue() 22 | { 23 | 24 | } 25 | 26 | 27 | 28 | QChar ParseCharQueue::popNext(bool *isEscaped) 29 | { 30 | QChar c = ' '; 31 | if(isEscaped) 32 | *isEscaped = false; 33 | 34 | if(m_idx < m_list.size()) 35 | { 36 | c = m_list[m_idx++]; 37 | if(m_isEscMode) 38 | { 39 | m_isEscMode = false; 40 | if(isEscaped) 41 | *isEscaped = true; 42 | } 43 | else if(c == '\\') 44 | { 45 | m_isEscMode = true; 46 | } 47 | } 48 | return c; 49 | } 50 | 51 | bool ParseCharQueue::isEmpty() 52 | { 53 | if(m_idx < m_list.size()) 54 | return false; 55 | return true; 56 | } 57 | 58 | void ParseCharQueue::revertPop() 59 | { 60 | if(m_idx > 0) 61 | m_idx--; 62 | 63 | if(m_isEscMode) 64 | m_isEscMode = false; 65 | else 66 | { 67 | if(m_idx > 1) 68 | { 69 | QChar prev = m_list[m_idx-1]; 70 | if(prev == '\\') 71 | m_isEscMode = true; 72 | } 73 | } 74 | } 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/syntaxhighlighterada.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__SYNTAXHIGHLIGHTERADA_H 10 | #define FILE__SYNTAXHIGHLIGHTERADA_H 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "settings.h" 19 | #include "syntaxhighlighter.h" 20 | 21 | 22 | 23 | class SyntaxHighlighterAda : public SyntaxHighlighter 24 | { 25 | public: 26 | SyntaxHighlighterAda(); 27 | virtual ~SyntaxHighlighterAda(); 28 | 29 | void colorize(QString text); 30 | 31 | QVector getRow(unsigned int rowIdx); 32 | unsigned int getRowCount() { return m_rows.size(); }; 33 | void reset(); 34 | 35 | bool isKeyword(QString text) const; 36 | bool isSpecialChar(char c) const; 37 | bool isSpecialChar(TextField *field) const; 38 | void setConfig(Settings *cfg); 39 | 40 | private: 41 | class Row 42 | { 43 | public: 44 | Row(); 45 | 46 | TextField *getLastNonSpaceField(); 47 | void appendField(TextField* field); 48 | int getCharCount(); 49 | 50 | QVector m_fields; 51 | }; 52 | private: 53 | void pickColor(TextField *field); 54 | 55 | private: 56 | Settings *m_cfg; 57 | QVector m_rows; 58 | QHash m_keywords; 59 | }; 60 | 61 | #endif // #ifndef FILE__SYNTAXHIGHLIGHTER_H 62 | -------------------------------------------------------------------------------- /src/syntaxhighlightergolang.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__SYNTAXHIGHLIGHTERGO_H 10 | #define FILE__SYNTAXHIGHLIGHTERGO_H 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "settings.h" 19 | #include "syntaxhighlighter.h" 20 | 21 | 22 | 23 | class SyntaxHighlighterGo : public SyntaxHighlighter 24 | { 25 | public: 26 | SyntaxHighlighterGo(); 27 | virtual ~SyntaxHighlighterGo(); 28 | 29 | void colorize(QString text); 30 | 31 | QVector getRow(unsigned int rowIdx); 32 | unsigned int getRowCount() { return m_rows.size(); }; 33 | void reset(); 34 | 35 | bool isKeyword(QString text) const; 36 | bool isSpecialChar(char c) const; 37 | bool isSpecialChar(TextField *field) const; 38 | void setConfig(Settings *cfg); 39 | 40 | private: 41 | class Row 42 | { 43 | public: 44 | Row(); 45 | 46 | TextField *getLastNonSpaceField(); 47 | void appendField(TextField* field); 48 | int getCharCount(); 49 | 50 | QVector m_fields; 51 | }; 52 | private: 53 | void pickColor(TextField *field); 54 | 55 | private: 56 | Settings *m_cfg; 57 | QVector m_rows; 58 | QHash m_keywords; 59 | }; 60 | 61 | #endif // #ifndef FILE__SYNTAXHIGHLIGHTER_H 62 | -------------------------------------------------------------------------------- /src/syntaxhighlighterrust.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__SYNTAXHIGHLIGHTERRUST_H 10 | #define FILE__SYNTAXHIGHLIGHTERRUST_H 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "settings.h" 19 | #include "syntaxhighlighter.h" 20 | 21 | 22 | 23 | class SyntaxHighlighterRust : public SyntaxHighlighter 24 | { 25 | public: 26 | SyntaxHighlighterRust(); 27 | virtual ~SyntaxHighlighterRust(); 28 | 29 | void colorize(QString text); 30 | 31 | QVector getRow(unsigned int rowIdx); 32 | unsigned int getRowCount() { return m_rows.size(); }; 33 | void reset(); 34 | 35 | bool isKeyword(QString text) const; 36 | bool isSpecialChar(char c) const; 37 | bool isSpecialChar(TextField *field) const; 38 | void setConfig(Settings *cfg); 39 | 40 | private: 41 | class Row 42 | { 43 | public: 44 | Row(); 45 | 46 | TextField *getLastNonSpaceField(); 47 | void appendField(TextField* field); 48 | int getCharCount(); 49 | 50 | QVector m_fields; 51 | }; 52 | private: 53 | void pickColor(TextField *field); 54 | 55 | private: 56 | Settings *m_cfg; 57 | QVector m_rows; 58 | QHash m_keywords; 59 | }; 60 | 61 | #endif // #ifndef FILE__SYNTAXHIGHLIGHTER_H 62 | -------------------------------------------------------------------------------- /src/settingsdialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__SETTINGSDIALOG_H 10 | #define FILE__SETTINGSDIALOG_H 11 | 12 | #include 13 | 14 | #include "settings.h" 15 | #include "ui_settingsdialog.h" 16 | 17 | 18 | class SettingsDialog : public QDialog 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | 24 | SettingsDialog(QWidget *parent, Settings *cfg); 25 | 26 | void getConfig(Settings *cfg); 27 | 28 | private: 29 | void loadConfig(); 30 | void updateGui(); 31 | 32 | 33 | private slots: 34 | 35 | void onSelectFont(); 36 | void onSelectMemoryFont(); 37 | void onSelectOutputFont(); 38 | void onSelectGdbOutputFont(); 39 | void onSelectGedeOutputFont(); 40 | 41 | void showFontSelection(QString *fontFamily, int *fontSize); 42 | void onButtonBoxClicked(QAbstractButton* button); 43 | 44 | private: 45 | Ui_SettingsDialog m_ui; 46 | Settings *m_cfg; 47 | 48 | QString m_settingsFontFamily; 49 | int m_settingsFontSize; 50 | QString m_settingsMemoryFontFamily; 51 | int m_settingsMemoryFontSize; 52 | QString m_settingsOutputFontFamily; 53 | int m_settingsOutputFontSize; 54 | QString m_settingsGdbOutputFontFamily; 55 | int m_settingsGdbOutputFontSize; 56 | QString m_settingsGedeOutputFontFamily; 57 | int m_settingsGedeOutputFontSize; 58 | 59 | QStringList m_sourceIgnoreDirs; 60 | }; 61 | 62 | #endif // FILE__SETTINGSDIALOG_H 63 | 64 | -------------------------------------------------------------------------------- /src/syntaxhighlightercxx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__SYNTAXHIGHLIGHTERCXX_H 10 | #define FILE__SYNTAXHIGHLIGHTERCXX_H 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "settings.h" 19 | #include "syntaxhighlighter.h" 20 | 21 | 22 | 23 | class SyntaxHighlighterCxx : public SyntaxHighlighter 24 | { 25 | public: 26 | SyntaxHighlighterCxx(); 27 | virtual ~SyntaxHighlighterCxx(); 28 | 29 | void colorize(QString text); 30 | 31 | QVector getRow(unsigned int rowIdx); 32 | unsigned int getRowCount() { return m_rows.size(); }; 33 | void reset(); 34 | 35 | bool isCppKeyword(QString text) const; 36 | bool isKeyword(QString text) const; 37 | bool isSpecialChar(char c) const; 38 | bool isSpecialChar(TextField *field) const; 39 | void setConfig(Settings *cfg); 40 | 41 | private: 42 | class Row 43 | { 44 | public: 45 | Row(); 46 | 47 | TextField *getLastNonSpaceField(); 48 | void appendField(TextField* field); 49 | int getCharCount(); 50 | 51 | bool isCppRow; 52 | QVector m_fields; 53 | }; 54 | private: 55 | void pickColor(TextField *field); 56 | 57 | private: 58 | Settings *m_cfg; 59 | QVector m_rows; 60 | QHash m_keywords; 61 | QHash m_cppKeywords; 62 | }; 63 | 64 | #endif // #ifndef FILE__SYNTAXHIGHLIGHTER_H 65 | -------------------------------------------------------------------------------- /src/syntaxhighlighterbasic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__SYNTAXHIGHLIGHTERBASIC_H 10 | #define FILE__SYNTAXHIGHLIGHTERBASIC_H 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "settings.h" 19 | #include "syntaxhighlighter.h" 20 | 21 | 22 | 23 | class SyntaxHighlighterBasic : public SyntaxHighlighter 24 | { 25 | public: 26 | SyntaxHighlighterBasic(); 27 | virtual ~SyntaxHighlighterBasic(); 28 | 29 | void colorize(QString text); 30 | 31 | QVector getRow(unsigned int rowIdx); 32 | unsigned int getRowCount() { return m_rows.size(); }; 33 | void reset(); 34 | 35 | bool isCppKeyword(QString text) const; 36 | bool isKeyword(QString text) const; 37 | bool isSpecialChar(char c) const; 38 | bool isSpecialChar(TextField *field) const; 39 | void setConfig(Settings *cfg); 40 | 41 | private: 42 | class Row 43 | { 44 | public: 45 | Row(); 46 | 47 | TextField *getLastNonSpaceField(); 48 | void appendField(TextField* field); 49 | int getCharCount(); 50 | 51 | bool isCppRow; 52 | QVector m_fields; 53 | }; 54 | private: 55 | void pickColor(TextField *field); 56 | 57 | private: 58 | Settings *m_cfg; 59 | QVector m_rows; 60 | QHash m_keywords; 61 | QHash m_cppKeywords; 62 | }; 63 | 64 | #endif // #ifndef FILE__SYNTAXHIGHLIGHTER_H 65 | -------------------------------------------------------------------------------- /testapps/basic/test.bas: -------------------------------------------------------------------------------- 1 | Declare Function func(ByVal arg1 As Double) As Double 2 | 3 | #define TEXT_DEFINE "Hello" 4 | 5 | /' Multiline comment. Row1 6 | Row2. 7 | '/ 8 | rem Single line program 9 | Dim C aS InteGer 10 | 'Start of program 11 | Dim A As Integer 12 | Dim D As Double 13 | CLS 14 | 15 | 16 | sub example_sub() 17 | Dim userInput As String 18 | Input "What is your name?", userInput 19 | Print "Hello " ; userInput ; "!" 20 | end sub 21 | 22 | example_sub() 23 | 24 | PRINT "Looping" 25 | PRINT TEXT_DEFINE 26 | 27 | A=0 28 | DO 29 | D=func(1.2) 30 | A=A+1 31 | ? "A =";A 32 | Loop Until A=5 33 | 34 | PRINT "Loop done and C =";A 35 | SLEEP 36 | 'End of program 37 | 38 | End 39 | 40 | 41 | Function func99(ByVal cmd As Integer) As String 42 | Dim cmdStr as String 43 | Select Case cmd 44 | Case 0 45 | cmdStr = !"{\"system\":{\"test1\":{\"test2\":0}}}" 46 | 47 | Case 1 48 | cmdStr = !"{\"system\":{\"test2\":{\"test2\":1}}}" 49 | 50 | Case 2 51 | cmdStr = !"{\"system\":{\"test3\":{\"test3\":1}}}" 52 | End select 53 | return cmdStr 54 | end function 55 | 56 | Function func(ByVal arg1 As Double) As Double 57 | Dim res As Double 58 | res = arg1 * 1.123 59 | arg1 = arg1 * 3.45 60 | return res 61 | End Function 62 | 63 | Function func2(ByVal arg1 As Double) As Double 64 | Dim res As Double 65 | res = arg1 * 1.123 66 | arg1 = arg1 * 3.45 67 | print res 68 | return res 69 | End Function 70 | 71 | 72 | Function func3(ByVal arg1 As Double) As Double 73 | Dim res As Double 74 | res = arg1 * 1.123 75 | arg1 = arg1 * 3.45 76 | return res 77 | End Function 78 | -------------------------------------------------------------------------------- /src/colorbutton.cpp: -------------------------------------------------------------------------------- 1 | #include "colorbutton.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | MColorButton::MColorButton(QWidget *parent) 9 | : QPushButton(parent) 10 | ,m_clr(Qt::black) 11 | { 12 | connect(this, SIGNAL(clicked()), SLOT(onButtonClicked())); 13 | 14 | } 15 | 16 | MColorButton::~MColorButton() 17 | { 18 | 19 | } 20 | 21 | /** 22 | * @brief Sets the current color. 23 | */ 24 | void MColorButton::setColor ( QColor clr) 25 | { 26 | m_clr = clr; 27 | update(); 28 | } 29 | 30 | /** 31 | * @brief Returns the current selected color. 32 | */ 33 | QColor MColorButton::getColor() 34 | { 35 | return m_clr; 36 | } 37 | 38 | /** 39 | * @brief Paint function. 40 | */ 41 | void MColorButton::paintEvent ( QPaintEvent * e ) 42 | { 43 | QPushButton::paintEvent(e); 44 | QPainter painter(this); 45 | 46 | QRect size(10,6,frameSize().width()-20,frameSize().height()-12); 47 | painter.fillRect(size, QBrush(m_clr)); 48 | 49 | painter.setPen(Qt::black); 50 | painter.drawRect(size); 51 | 52 | 53 | // QRect textRect = QRect(QPoint(10,0), frameSize()); 54 | // painter.drawText( textRect, Qt::AlignVCenter | Qt::AlignLeft, "Example"); 55 | 56 | } 57 | 58 | 59 | /** 60 | * @brief Shows a dialog for selecting a color. 61 | */ 62 | void MColorButton::showColorSelectDialog(QColor *color) 63 | { 64 | QColor newColor; 65 | newColor = QColorDialog::getColor(*color, this); 66 | 67 | if(newColor.isValid()) 68 | *color = newColor; 69 | 70 | update(); 71 | } 72 | 73 | 74 | /** 75 | * @brief The user has pressed the button. 76 | */ 77 | void MColorButton::onButtonClicked() 78 | { 79 | showColorSelectDialog(&m_clr); 80 | 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /tests/ini/test_ini.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../src/ini.h" 3 | 4 | #include 5 | 6 | void writeInit() 7 | { 8 | Ini ini1; 9 | 10 | QSize size(123,456); 11 | ini1.setSize("size_test/size", size); 12 | 13 | ini1.setString("string", "string_value"); 14 | ini1.setInt("int", 11); 15 | QByteArray byteArray; 16 | byteArray += 0xde; 17 | byteArray += 0xad; 18 | ini1.setByteArray("byteArray", byteArray); 19 | QByteArray emptyByteArray; 20 | ini1.setByteArray("emptyByteArray", emptyByteArray); 21 | assert(ini1.getInt("int") == 11); 22 | ini1.setString("group2/string", "group2/string_data"); 23 | ini1.setString("group1/string", "group1/string_data\u00c4"); 24 | 25 | ini1.setDouble("floatv", 123.456); 26 | ini1.save("test.ini"); 27 | } 28 | 29 | void readIni() 30 | { 31 | QByteArray byteArray; 32 | Ini ini2; 33 | 34 | ini2.appendLoad("test.ini"); 35 | assert(QString(ini2.getString("string")) == QString("string_value")); 36 | assert(ini2.getInt("int") == 11); 37 | ini2.getByteArray("byteArray", &byteArray); 38 | assert(byteArray.size() == 2); 39 | assert(byteArray[0] == (char)0xDE); 40 | assert(byteArray[1] == (char)0xAD); 41 | 42 | assert(ini2.getDouble("floatv", 999.888) == 123.456); 43 | 44 | QString s = ini2.getString("group1/string"); 45 | assert(s == "group1/string_data\u00c4"); 46 | 47 | QSize size; 48 | size = ini2.getSize("size_test/size", QSize(0,0)); 49 | assert(size.width() == 123); 50 | assert(size.height() == 456); 51 | 52 | } 53 | 54 | int main(int argc,char *argv[]) 55 | { 56 | Q_UNUSED(argc); 57 | Q_UNUSED(argv); 58 | 59 | writeInit(); 60 | 61 | 62 | readIni(); 63 | 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /src/syntaxhighlighterfortran.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__SYNTAXHIGHLIGHTERFORTRAN_H 10 | #define FILE__SYNTAXHIGHLIGHTERFORTRAN_H 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "settings.h" 19 | #include "syntaxhighlighter.h" 20 | #include "parsecharqueue.h" 21 | 22 | 23 | class SyntaxHighlighterFortran : public SyntaxHighlighter 24 | { 25 | public: 26 | SyntaxHighlighterFortran(); 27 | virtual ~SyntaxHighlighterFortran(); 28 | 29 | void colorize(QString text); 30 | void colorize(ParseCharQueue text); 31 | 32 | QVector getRow(unsigned int rowIdx); 33 | unsigned int getRowCount() { return m_rows.size(); }; 34 | void reset(); 35 | 36 | bool isCppKeyword(QString text) const; 37 | bool isKeyword(QString text) const; 38 | bool isSpecialChar(char c) const; 39 | bool isSpecialChar(TextField *field) const; 40 | void setConfig(Settings *cfg); 41 | bool isSpecialChar(QChar c) const; 42 | 43 | private: 44 | class Row 45 | { 46 | public: 47 | Row(); 48 | 49 | TextField *getLastNonSpaceField(); 50 | void appendField(TextField* field); 51 | int getCharCount(); 52 | 53 | bool isCppRow; 54 | QVector m_fields; 55 | }; 56 | private: 57 | void pickColor(TextField *field); 58 | 59 | private: 60 | Settings *m_cfg; 61 | QVector m_rows; 62 | QHash m_keywords; 63 | QHash m_cppKeywords; 64 | }; 65 | 66 | #endif // #ifndef FILE__SYNTAXHIGHLIGHTER_H 67 | -------------------------------------------------------------------------------- /src/processlistdialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__PROCESSLISTDIALOG_H 10 | #define FILE__PROCESSLISTDIALOG_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include "settings.h" 17 | #include "ui_processlistdialog.h" 18 | 19 | 20 | 21 | class ProcessInfo 22 | { 23 | public: 24 | QString cmdline; 25 | int pid; 26 | int uid; 27 | QDateTime mtime; // The start time of the process 28 | 29 | QString getCmdline() const { return cmdline; }; 30 | int getPid() const { return pid;}; 31 | int getUid() const { return uid; }; 32 | }; 33 | 34 | QList getProcessListByUser(int ownerUid = -1); 35 | QList getProcessListAllUsers(); 36 | QList getProcessListThisUser(); 37 | 38 | class ProcessListWidgetItem : public QTreeWidgetItem 39 | { 40 | public: 41 | ProcessListWidgetItem(); 42 | 43 | 44 | ProcessListWidgetItem( const ProcessInfo &info ); 45 | virtual ~ProcessListWidgetItem(); 46 | 47 | 48 | bool operator<(const QTreeWidgetItem &other) const; 49 | 50 | ProcessInfo m_prc; 51 | }; 52 | 53 | 54 | class ProcessListDialog : public QDialog 55 | { 56 | Q_OBJECT 57 | 58 | public: 59 | 60 | ProcessListDialog(QWidget *parent = NULL); 61 | 62 | void selectPid(int pid); 63 | int getSelectedProcess(); 64 | 65 | private slots: 66 | 67 | void onItemDoubleClicked(QTreeWidgetItem *item, int column); 68 | 69 | private: 70 | void fillInList(); 71 | 72 | private: 73 | 74 | Ui_ProcessListDialog m_ui; 75 | 76 | }; 77 | 78 | #endif // FILE__PROCESSLISTDIALOG_H 79 | 80 | -------------------------------------------------------------------------------- /src/codeviewtab.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__CODEVIEWTAB_H 10 | #define FILE__CODEVIEWTAB_H 11 | 12 | #include "ui_codeviewtab.h" 13 | 14 | #include "tagscanner.h" 15 | #include 16 | #include 17 | 18 | class CodeViewTab : public QWidget 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | CodeViewTab(QWidget *parent); 24 | virtual ~CodeViewTab(); 25 | 26 | void ensureLineIsVisible(int lineIdx); 27 | 28 | void setConfig(Settings *cfg); 29 | void disableCurrentLine(); 30 | 31 | void setCurrentLine(int currentLine); 32 | 33 | int incSearchStart(QString text) { return m_ui.codeView->incSearchStart(text); }; 34 | int incSearchNext() { return m_ui.codeView->incSearchNext(); }; 35 | int incSearchPrev() { return m_ui.codeView->incSearchPrev(); }; 36 | void clearIncSearch() { m_ui.codeView->clearIncSearch(); }; 37 | 38 | int open(QString filename, QList tagList); 39 | 40 | void setInterface(ICodeView *inf); 41 | 42 | void setBreakpoints(const QVector &numList); 43 | 44 | QString getFilePath() { return m_filepath; }; 45 | 46 | void updateLastAccessStamp() { m_lastOpened = QTime::currentTime(); }; 47 | QTime getLastAccessTime() { return m_lastOpened; }; 48 | private: 49 | 50 | void fillInFunctions(QList tagList); 51 | 52 | public slots: 53 | void onFuncListItemActivated(int index); 54 | 55 | private: 56 | Ui_CodeViewTab m_ui; 57 | QString m_filepath; 58 | Settings *m_cfg; 59 | QList m_tagList; 60 | QTime m_lastOpened; //!< When the tab was last accessed 61 | }; 62 | 63 | #endif 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/watchvarctl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef WATCHVAR_CTL_H 10 | #define WATCHVAR_CTL_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | #include "core.h" 19 | #include "varctl.h" 20 | 21 | 22 | class WatchVarCtl : public VarCtl 23 | { 24 | Q_OBJECT 25 | 26 | public: 27 | WatchVarCtl(); 28 | 29 | void setWidget(QTreeWidget *varWidget); 30 | 31 | void ICore_onWatchVarChanged(VarWatch &watch); 32 | void ICore_onWatchVarChildAdded(VarWatch &watch); 33 | void addNewWatch(QString varName); 34 | void deleteSelected(); 35 | 36 | void onKeyPress(QKeyEvent *keyEvent); 37 | 38 | private: 39 | QString getWatchId(QTreeWidgetItem* item); 40 | 41 | void selectedChangeDisplayFormat(VarCtl::DispFormat fmt); 42 | 43 | QString getDisplayString(QString watchId); 44 | 45 | void sync(QTreeWidgetItem * parentItem, VarWatch &watch); 46 | 47 | public slots: 48 | void onWatchWidgetItemDoubleClicked(QTreeWidgetItem *item, int column); 49 | void onWatchWidgetCurrentItemChanged ( QTreeWidgetItem * current, int column ); 50 | void onWatchWidgetItemExpanded(QTreeWidgetItem *item ); 51 | void onWatchWidgetItemCollapsed(QTreeWidgetItem *item); 52 | 53 | void onContextMenu ( const QPoint &pos); 54 | 55 | 56 | void onDisplayAsDec(); 57 | void onDisplayAsHex(); 58 | void onDisplayAsBin(); 59 | void onDisplayAsChar(); 60 | void onRemoveWatch(); 61 | 62 | private: 63 | void fillInVars(); 64 | 65 | private: 66 | QTreeWidget *m_varWidget; 67 | VarCtl::DispInfoMap m_watchVarDispInfo; 68 | QMenu m_popupMenu; 69 | 70 | }; 71 | 72 | #endif // WATCHVAR_CTL_H 73 | -------------------------------------------------------------------------------- /testapps/c_code/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | //rad1 3 | //kalle 4 | //tab1 5 | //tab2 6 | //tab3 7 | // |tab1_again 8 | // |tab2_again 9 | //kalle 10 | //nisse 11 | 12 | #define EMPTY "" 13 | 14 | 15 | void long_func_with_many_arguments(int a_very_long_function_variable_name_xxxxxxx, int another_very_long_variable_name___, int another_another_very_long_variable_name___, int another_another_very_long_variable_name___2) 16 | { 17 | } 18 | 19 | 20 | typedef enum {CUSTOM_ENUM1, CUSTOM_ENUM2} CustomEnum; 21 | int main(int argc,char *argv[]) 22 | { 23 | char sbuffer[1024]; 24 | const char **strList; 25 | const char *strListData[] = {"hej", "kalle"}; 26 | int i3[] = { 111,222}; 27 | struct 28 | { 29 | int a; 30 | struct 31 | { 32 | int b; 33 | }s2; 34 | }s; 35 | int a = 1001; 36 | char c = 'Z'; 37 | float f1; 38 | char *varStr; 39 | enum {ENUM1, ENUM2}varEnum; 40 | unsigned char d = 0; 41 | CustomEnum customEnum1; 42 | int i; 43 | 44 | sbuffer[0] = '1'; 45 | sbuffer[1] = '2'; 46 | sbuffer[2] = '3'; 47 | for(i = 3;i <= 9;i++) 48 | sbuffer[i] = '0'+i; 49 | 50 | printf("hello"EMPTY" >"); 51 | printf("<\n"); 52 | 53 | varStr = "stri\n\r\t\03ng1"; 54 | varStr = "string2"; 55 | f1 = 0.0; 56 | s.a = 0; 57 | s.s2.b = 1; 58 | varEnum = ENUM1; 59 | varEnum = ENUM2; 60 | c = '\''; 61 | a++; 62 | 63 | strList = strListData; 64 | 65 | switch(s.a) 66 | { 67 | case 0: 68 | { 69 | printf("Hej!\n"); 70 | };break; 71 | default:;break; 72 | } 73 | 74 | while(1) 75 | { 76 | c++; 77 | f1 += 0.1; 78 | func(); 79 | s.a++; 80 | s.s2.b++; 81 | s.s2.b++; 82 | s.a++; 83 | d++; 84 | } 85 | return 0; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /testapps/ansicolor/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | #define YELLOW_CODE "\033[1;33m" 7 | #define GREEN_CODE "\033[1;32m" 8 | #define RED_CODE "\033[1;31m" 9 | #define NO_CODE "\033[1;0m" 10 | 11 | #define INT_TO_STR_(i) #i 12 | #define INT_TO_STR(i) INT_TO_STR_(i) 13 | 14 | #define ANSI_ERASE_SCREEN "\033[2J" 15 | #define ANSI_CURSOR_HOME(r,c) "\033[" INT_TO_STR(r) ";" INT_TO_STR(c) "H" 16 | 17 | char* letterToStr(int c) 18 | { 19 | static char rsp[3] = { '\0','\0','\0'}; 20 | if(isalpha(c) || isdigit(c)) 21 | { 22 | rsp[0] = (char)c; 23 | rsp[1] = '\0'; 24 | } 25 | else if(c == '\n') 26 | strcpy(rsp, "\\n"); 27 | return rsp; 28 | } 29 | 30 | int main(int argc,char *argv[]) 31 | { 32 | char c; 33 | int i; 34 | printf("erase me!\n"); 35 | printf(ANSI_ERASE_SCREEN); 36 | fflush(stdout); 37 | 38 | 39 | for(i = 0;i < 300;i++) 40 | { 41 | printf("xxxxxxxxxx.row%d\n", i); 42 | // sleep(2); 43 | } 44 | 45 | printf(ANSI_CURSOR_HOME(1,4)); 46 | printf("456"); 47 | fflush(stdout); 48 | getchar(); 49 | printf(ANSI_CURSOR_HOME(2,2)); 50 | fflush(stdout); 51 | printf("23"); 52 | fflush(stdout); 53 | printf(ANSI_CURSOR_HOME(4,2)); 54 | fflush(stdout); 55 | 56 | for(i = 0;i < 10;i++) 57 | { 58 | printf(RED_CODE "RED" NO_CODE "\n"); 59 | printf(GREEN_CODE "GREEN" NO_CODE "\n"); 60 | printf(YELLOW_CODE "YELLOW" NO_CODE "\n"); 61 | printf(RED_CODE "RED" NO_CODE "MIXED_WITH" YELLOW_CODE "YELLOW" NO_CODE "AND" GREEN_CODE "GREEN" NO_CODE "\n"); 62 | printf("DEFAULT" "\n"); 63 | printf("%d Input:", i); 64 | do 65 | { 66 | c = getc(stdin); 67 | printf("Got: '%d' '%s'\n", (int)c, letterToStr(c)); 68 | if(c == -1) 69 | return 1; 70 | } while(c != '\n'); 71 | 72 | 73 | } 74 | return 0; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/tagscanner.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE_TAGS_H 10 | #define FILE_TAGS_H 11 | 12 | #include 13 | #include 14 | #include "settings.h" 15 | 16 | 17 | 18 | class Tag 19 | { 20 | public: 21 | Tag(); 22 | void dump() const; 23 | 24 | QString getName() const { return m_name; }; 25 | QString getLongName() const; 26 | QString getSignature() const { return m_signature; }; 27 | void setSignature(QString signature) { m_signature = signature; }; 28 | void setLineNo(int lineNo) { m_lineNo = lineNo;}; 29 | int getLineNo() const { return m_lineNo; }; 30 | QString getFilePath() const { return m_filepath; }; 31 | QString getClassName() const { return m_className;}; 32 | bool isFunc() const { return (m_type == TAG_FUNC) ? true : false; }; 33 | bool isClassMember() const { return m_className.isEmpty() ? false : true; }; 34 | 35 | QString m_className; 36 | QString m_name; 37 | QString m_filepath; 38 | enum { TAG_FUNC, TAG_VARIABLE} m_type; 39 | private: 40 | QString m_signature; 41 | int m_lineNo; 42 | }; 43 | 44 | 45 | class TagScanner 46 | { 47 | public: 48 | 49 | TagScanner(); 50 | ~TagScanner(); 51 | 52 | void init(Settings *cfg); 53 | 54 | int scan(QString filepath, QList *taglist); 55 | void dump(const QList &taglist); 56 | 57 | private: 58 | int parseOutput(QByteArray output, QList *taglist); 59 | 60 | void checkForCtags(); 61 | 62 | static int execProgram(QString name, QStringList argList, 63 | QByteArray *stdoutContent, 64 | QByteArray *stderrContent); 65 | 66 | 67 | Settings *m_cfg; 68 | }; 69 | 70 | 71 | #endif 72 | 73 | -------------------------------------------------------------------------------- /src/processlistdialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | ProcessListDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 705 10 | 468 11 | 12 | 13 | 14 | Process List 15 | 16 | 17 | 18 | 19 | 20 | true 21 | 22 | 23 | 24 | 1 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Qt::Horizontal 33 | 34 | 35 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | buttonBox 45 | accepted() 46 | ProcessListDialog 47 | accept() 48 | 49 | 50 | 248 51 | 254 52 | 53 | 54 | 157 55 | 274 56 | 57 | 58 | 59 | 60 | buttonBox 61 | rejected() 62 | ProcessListDialog 63 | reject() 64 | 65 | 66 | 316 67 | 260 68 | 69 | 70 | 286 71 | 274 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/aboutdialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #include "aboutdialog.h" 10 | 11 | #include 12 | 13 | #include "version.h" 14 | #include "util.h" 15 | #include "log.h" 16 | 17 | 18 | 19 | AboutDialog::AboutDialog(QWidget *parent, Settings *cfg) 20 | : QDialog(parent) 21 | { 22 | 23 | m_ui.setupUi(this); 24 | 25 | // 26 | QString verStr; 27 | verStr.sprintf("Version: v%d.%d.%d", GD_MAJOR, GD_MINOR, GD_PATCH); 28 | m_ui.label_version->setText(verStr); 29 | 30 | // 31 | QString buildStr; 32 | buildStr = __DATE__; 33 | buildStr += " "; 34 | buildStr += __TIME__; 35 | m_ui.label_buildDate->setText("Built: " + buildStr); 36 | 37 | 38 | QString qtVersionStr; 39 | qtVersionStr.sprintf("Qt: %s (compiled) / %s (running)", QT_VERSION_STR, qVersion()); 40 | m_ui.label_qtVersion->setText(qtVersionStr); 41 | 42 | 43 | QString gdbPath = "Gdb: " + cfg->m_gdbPath + " ('" + getGdbVersion(cfg->m_gdbPath) + "')"; 44 | m_ui.label_gdbPath->setText(gdbPath); 45 | 46 | QString distroName; 47 | detectDistro(NULL, &distroName); 48 | QString osText = "Running on " + distroName; 49 | m_ui.label_os->setText(osText); 50 | 51 | } 52 | 53 | 54 | QString AboutDialog::getGdbVersion(QString gdbPath) 55 | { 56 | QString versionStr; 57 | QProcess process; 58 | process.start(gdbPath, 59 | QStringList("--version"), 60 | QIODevice::ReadWrite | QIODevice::Text); 61 | if(!process.waitForFinished(2000)) 62 | { 63 | errorMsg("Failed to launch gdb to get version: %d", process.exitCode()); 64 | } 65 | else 66 | { 67 | QStringList versionStrList = QString(process.readAllStandardOutput()).split('\n'); 68 | if(versionStrList.size() >= 1) 69 | versionStr = versionStrList[0]; 70 | } 71 | return versionStr; 72 | } 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/opendialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__ABOUTDIALOG_H 10 | #define FILE__ABOUTDIALOG_H 11 | 12 | #include 13 | 14 | #include "settings.h" 15 | #include "core.h" 16 | #include "ui_opendialog.h" 17 | 18 | 19 | class OpenDialog : public QDialog 20 | { 21 | Q_OBJECT 22 | 23 | public: 24 | 25 | OpenDialog(QWidget *parent); 26 | 27 | void setProgram(QString program); 28 | void setArguments(QString program); 29 | QString getProgram(); 30 | QString getArguments(); 31 | 32 | QString getCoreDumpFile(); 33 | 34 | void setCoreDumpFile(QString coreDumpFile); 35 | 36 | void setInitialBreakpoint(QString list); 37 | QString getInitialBreakpoint(); 38 | 39 | 40 | void setTcpRemoteHost(QString host); 41 | QString getTcpRemoteHost(); 42 | 43 | void setTcpRemotePort(int port); 44 | int getTcpRemotePort(); 45 | 46 | bool getDownload(); 47 | void setDownload(bool enable); 48 | 49 | 50 | void setMode(ConnectionMode mode); 51 | ConnectionMode getMode(); 52 | 53 | void setInitCommands(QStringList commandList); 54 | QStringList getInitCommands(); 55 | 56 | void setGdbPath(QString path); 57 | QString getGdbPath(); 58 | 59 | int getRunningPid(); 60 | void setRunningPid(int pid); 61 | 62 | 63 | void loadConfig(Settings &cfg); 64 | void saveConfig(Settings *cfg); 65 | 66 | 67 | private: 68 | void onBrowseForProgram(QString *path); 69 | 70 | private slots: 71 | void onConnectionTypeLocal(bool checked); 72 | void onConnectionTypeTcp(bool checked); 73 | void onConnectionTypeCoreDump(bool checked); 74 | void onConnectionTypePid(bool checked); 75 | 76 | void onSelectProgram(); 77 | void onSelectCoreFile(); 78 | 79 | void onSelectRunningPid(); 80 | 81 | private: 82 | Ui_OpenDialog m_ui; 83 | 84 | }; 85 | 86 | #endif // FILE__ABOUTDIALOG_H 87 | 88 | -------------------------------------------------------------------------------- /src/codeviewtab.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeViewTab 4 | 5 | 6 | 7 | 0 8 | 0 9 | 771 10 | 525 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 1 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 34 | 35 | 36 | 0 37 | 0 38 | 39 | 40 | 41 | 42 | 20 43 | 0 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | true 52 | 53 | 54 | 55 | 56 | 0 57 | 0 58 | 769 59 | 500 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | CodeView 70 | QWidget 71 |
codeview.h
72 | 1 73 |
74 |
75 | 76 | 77 |
78 | -------------------------------------------------------------------------------- /src/adatagscanner.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__ADATAGS_H 10 | #define FILE__ADATAGS_H 11 | 12 | #include "tagscanner.h" 13 | #include "syntaxhighlighter.h" 14 | 15 | 16 | /** 17 | * @brief Tag scanner for the Ada language. 18 | * 19 | * This class scans a rust language file and extract function definitions from it. 20 | */ 21 | class AdaTagScanner 22 | { 23 | public: 24 | 25 | AdaTagScanner(); 26 | virtual ~AdaTagScanner(); 27 | 28 | int scan(QString filepath, QList *taglist); 29 | 30 | 31 | void setConfig(Settings *cfg); 32 | 33 | private: 34 | 35 | void tokenize(QString text); 36 | 37 | void reset(); 38 | 39 | bool isKeyword(QString text) const; 40 | bool isSpecialChar(char c) const; 41 | bool isSpecialChar(TextField *field) const; 42 | 43 | private: 44 | class Token 45 | { 46 | public: 47 | typedef enum {STRING, COMMENT, NUMBER,WORD, KEYWORD} Type; 48 | 49 | Token(int lineNr) : m_lineNr(lineNr) {}; 50 | Token(int lineNr, Type t) : m_type(t), m_lineNr(lineNr) {}; 51 | 52 | QString getText() const { return text;}; 53 | void setText(QString txt) { text = txt;}; 54 | 55 | QString toDesc(); 56 | 57 | void setType(Type t) { m_type = t; }; 58 | Type getType() const { return m_type; }; 59 | 60 | int getLineNr() const { return m_lineNr; }; 61 | 62 | private: 63 | Type m_type; 64 | QString text; 65 | int m_lineNr; 66 | }; 67 | 68 | void parse(QList *taglist); 69 | 70 | private: 71 | bool eatToken(QString text); 72 | Token* popToken(); 73 | Token* peekToken(); 74 | Token* pushToken(QString text, Token::Type type, int lineNr); 75 | Token* pushToken(char text, Token::Type type, int lineNr); 76 | void clearTokenList(); 77 | 78 | private: 79 | Settings *m_cfg; 80 | QHash m_keywords; 81 | QString m_filepath; 82 | QList m_tokens; 83 | }; 84 | 85 | #endif // FILE__ADATAGS_H 86 | -------------------------------------------------------------------------------- /src/rusttagscanner.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__RUSTTAGS_H 10 | #define FILE__RUSTTAGS_H 11 | 12 | #include "tagscanner.h" 13 | #include "syntaxhighlighter.h" 14 | 15 | 16 | /** 17 | * @brief Tag scanner for the Rust language. 18 | * 19 | * This class scans a rust language file and extract function definitions from it. 20 | */ 21 | class RustTagScanner 22 | { 23 | public: 24 | 25 | RustTagScanner(); 26 | virtual ~RustTagScanner(); 27 | 28 | int scan(QString filepath, QList *taglist); 29 | 30 | 31 | void setConfig(Settings *cfg); 32 | 33 | private: 34 | 35 | void tokenize(QString text); 36 | 37 | void reset(); 38 | 39 | bool isKeyword(QString text) const; 40 | bool isSpecialChar(char c) const; 41 | bool isSpecialChar(TextField *field) const; 42 | 43 | private: 44 | class Token 45 | { 46 | public: 47 | typedef enum {STRING, COMMENT, NUMBER,WORD, KEYWORD} Type; 48 | 49 | Token(int lineNr) : m_lineNr(lineNr) {}; 50 | Token(int lineNr, Type t) : m_type(t), m_lineNr(lineNr) {}; 51 | 52 | QString getText() const { return text;}; 53 | void setText(QString txt) { text = txt;}; 54 | 55 | QString toDesc(); 56 | 57 | void setType(Type t) { m_type = t; }; 58 | Type getType() const { return m_type; }; 59 | 60 | int getLineNr() const { return m_lineNr; }; 61 | 62 | private: 63 | Type m_type; 64 | QString text; 65 | int m_lineNr; 66 | }; 67 | 68 | void parse(QList *taglist); 69 | 70 | private: 71 | bool eatToken(QString text); 72 | Token* popToken(); 73 | Token* peekToken(); 74 | Token* pushToken(QString text, Token::Type type, int lineNr); 75 | Token* pushToken(char text, Token::Type type, int lineNr); 76 | void clearTokenList(); 77 | 78 | private: 79 | Settings *m_cfg; 80 | QHash m_keywords; 81 | QString m_filepath; 82 | QList m_tokens; 83 | }; 84 | 85 | #endif // FILE__RUSTTAGS_H 86 | -------------------------------------------------------------------------------- /testapp/test.c: -------------------------------------------------------------------------------- 1 | // FIRST_ROW 2 | #include 3 | #include 4 | #include "subdir/subfile.h" 5 | #include 6 | 7 | 8 | struct 9 | { 10 | int a; 11 | struct 12 | { 13 | int b; 14 | struct 15 | { 16 | int d; 17 | }c; 18 | }; 19 | } glob_struct; 20 | 21 | struct 22 | { 23 | int a; 24 | struct 25 | { 26 | int b; 27 | }; 28 | } g; 29 | 30 | 31 | // Single row comment 32 | 33 | /** 34 | Multiline comment 35 | */ 36 | 37 | void testfunc(int v) 38 | { 39 | int i = 2/1; 40 | while(v--) 41 | { 42 | i--; 43 | } 44 | } 45 | 46 | void *thread_func(void *ptr) 47 | { 48 | unsigned int i = 0; 49 | while(1) 50 | { 51 | i++; 52 | usleep(1000); 53 | } 54 | return NULL; 55 | } 56 | 57 | void sleep_forever() 58 | { 59 | int a = 0; 60 | 61 | while(1) 62 | { 63 | usleep(1000); 64 | a++; 65 | a++; 66 | } 67 | } 68 | 69 | int main(int argc, char*argv[]) 70 | { 71 | double k = 0.0; 72 | int i = 0; 73 | int j = 0; 74 | pthread_t th; 75 | struct { 76 | int a; 77 | char *b_str; 78 | struct 79 | { 80 | int sub_a; 81 | int sub_b; 82 | }sub1; 83 | }local_struct; 84 | char *str = "hej"; 85 | 86 | local_struct.a = 3; 87 | local_struct.a++; 88 | local_struct.a++; 89 | 90 | 91 | 92 | printf("Hej1\n"); 93 | printf("Hej2\n"); 94 | printf("Hej3\n"); 95 | printf("Hej4\n"); 96 | 97 | glob_struct.a = 1; 98 | glob_struct.a = 2; 99 | glob_struct.a = 3; 100 | glob_struct.c.d = 3; 101 | 102 | 103 | 104 | 105 | 106 | pthread_create(&th, NULL, thread_func, 0); 107 | 108 | 109 | 110 | subfunc(1); 111 | testfunc(10); 112 | 113 | for(i = 1;i < argc;i++) 114 | { 115 | printf(">%s<\n", argv[i]); 116 | } 117 | argc--; 118 | while(1) 119 | { 120 | k += 0.12; 121 | local_struct.a++; 122 | i++; 123 | j++; 124 | j++; 125 | // sleep_forever(); 126 | usleep(10*1000); 127 | } 128 | return 0; 129 | } 130 | // LAST_ROW 131 | -------------------------------------------------------------------------------- /src/autovarctl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__AUTO_VAR_CTL_H 10 | #define FILE__AUTO_VAR_CTL_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | #include "core.h" 19 | #include "varctl.h" 20 | #include "settings.h" 21 | 22 | /** 23 | * @brief Displays local variables (on the stack). 24 | */ 25 | class AutoVarCtl : public VarCtl 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | AutoVarCtl(); 31 | 32 | void setWidget(QTreeWidget *autoWidget); 33 | 34 | void ICore_onWatchVarChanged(VarWatch &watch); 35 | void ICore_onWatchVarChildAdded(VarWatch &watch); 36 | void addNewWatch(QString varName); 37 | 38 | 39 | void setConfig(Settings *cfg); 40 | 41 | void ICore_onLocalVarChanged(QStringList varNames); 42 | 43 | void onKeyPress(QKeyEvent *keyEvent); 44 | 45 | void ICore_onStateChanged(ICore::TargetState state); 46 | private: 47 | quint64 getAddress(VarWatch &w); 48 | QString getWatchId(QTreeWidgetItem* item); 49 | 50 | void selectedChangeDisplayFormat(VarCtl::DispFormat fmt); 51 | QString getTreeWidgetItemPath(QTreeWidgetItem *item); 52 | 53 | QString getDisplayString(QString watchId, QString varPath); 54 | 55 | 56 | public slots: 57 | void onAutoWidgetItemDoubleClicked(QTreeWidgetItem *item, int column); 58 | void onAutoWidgetCurrentItemChanged ( QTreeWidgetItem * current, int column ); 59 | void onAutoWidgetItemExpanded(QTreeWidgetItem *item ); 60 | void onAutoWidgetItemCollapsed(QTreeWidgetItem *item); 61 | 62 | void onContextMenu ( const QPoint &pos); 63 | void onShowMemory(); 64 | 65 | 66 | void onDisplayAsDec(); 67 | void onDisplayAsHex(); 68 | void onDisplayAsBin(); 69 | void onDisplayAsChar(); 70 | 71 | private: 72 | void clear(); 73 | 74 | private: 75 | QTreeWidget *m_autoWidget; 76 | QMenu m_popupMenu; 77 | 78 | VarCtl::DispInfoMap m_autoVarDispInfo; 79 | Settings m_cfg; 80 | QColor m_textColor; //!< Color to use for text in the widget 81 | }; 82 | 83 | 84 | 85 | #endif // FILE__AUTO_VAR_CTL_H 86 | 87 | -------------------------------------------------------------------------------- /src/tagmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE__TAGMANAGER_H 2 | #define FILE__TAGMANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "tagscanner.h" 13 | 14 | class FileInfo; 15 | 16 | struct ScannerResult 17 | { 18 | QString m_filePath; 19 | QList m_tagList; 20 | }; 21 | 22 | class ScannerWorker : public QThread 23 | { 24 | Q_OBJECT 25 | 26 | public: 27 | ScannerWorker(); 28 | 29 | void run(); 30 | 31 | void abort(); 32 | void waitAll(); 33 | 34 | void requestQuit(); 35 | void queueScan(QString filePath); 36 | 37 | bool isIdle(); 38 | 39 | void setConfig(Settings cfg); 40 | 41 | private: 42 | void scan(QString filePath); 43 | 44 | signals: 45 | void onScanDone(QString filePath, QList *taglist); 46 | 47 | private: 48 | TagScanner m_scanner; 49 | 50 | #ifndef NDEBUG 51 | Qt::HANDLE m_dbgMainThread; 52 | #endif 53 | 54 | QMutex m_mutex; 55 | QWaitCondition m_wait; 56 | QWaitCondition m_doneCond; 57 | QList m_workQueue; 58 | bool m_quit; 59 | Settings m_cfg; 60 | bool m_isIdle; 61 | 62 | }; 63 | 64 | 65 | class TagManager : public QObject 66 | { 67 | 68 | Q_OBJECT 69 | 70 | private: 71 | TagManager(){}; 72 | public: 73 | TagManager(Settings &cfg); 74 | virtual ~TagManager(); 75 | 76 | 77 | int queueScan(QStringList filePathList); 78 | void scan(QString filePath, QList *tagList); 79 | 80 | void waitAll(); 81 | 82 | void abort(); 83 | 84 | void getTags(QString filePath, QList *tagList); 85 | 86 | void lookupTag(QString name, QList *tagList); 87 | 88 | void setConfig(Settings &cfg); 89 | signals: 90 | void onAllScansDone(); 91 | 92 | private slots: 93 | void onScanDone(QString filePath, QList *tags); 94 | 95 | private: 96 | ScannerWorker m_worker; 97 | TagScanner m_tagScanner; 98 | 99 | #ifndef NDEBUG 100 | Qt::HANDLE m_dbgMainThread; 101 | #endif 102 | QMap m_db; 103 | 104 | Settings m_cfg; 105 | }; 106 | 107 | 108 | #endif // FILE__TAGMANAGER_H 109 | -------------------------------------------------------------------------------- /tests/highlightertest/hltest.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "syntaxhighlighterrust.h" 3 | #include "syntaxhighlightercxx.h" 4 | #include "syntaxhighlighterbasic.h" 5 | #include "syntaxhighlighterfortran.h" 6 | #include "log.h" 7 | #include "util.h" 8 | 9 | #include 10 | #if QT_VERSION < 0x050000 11 | #include 12 | #endif 13 | #include 14 | #include 15 | 16 | int dumpUsage() 17 | { 18 | printf("Usage: ./hltest SOURCE_FILE.c\n"); 19 | printf("Description:\n"); 20 | printf(" Dumps syntax highlight info for a source file\n"); 21 | return 1; 22 | } 23 | 24 | 25 | int main(int argc, char *argv[]) 26 | { 27 | QApplication app(argc,argv); 28 | QString inputFilename; 29 | 30 | // Parse arguments 31 | for(int i = 1;i < argc;i++) 32 | { 33 | const char *curArg = argv[i]; 34 | if(curArg[0] == '-') 35 | return dumpUsage(); 36 | else 37 | { 38 | inputFilename = curArg; 39 | } 40 | } 41 | if(inputFilename.isEmpty()) 42 | return dumpUsage(); 43 | 44 | // Open file 45 | QFile file(inputFilename); 46 | if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) 47 | { 48 | printf("Unable to open %s\n", qPrintable(inputFilename)); 49 | return 1; 50 | } 51 | 52 | // Read entire content 53 | QString text; 54 | while (!file.atEnd()) 55 | { 56 | QByteArray line = file.readLine(); 57 | text += line; 58 | } 59 | 60 | Settings cfg; 61 | 62 | SyntaxHighlighter *scanner = NULL; 63 | if(inputFilename.endsWith(".rs")) 64 | scanner = new SyntaxHighlighterRust(); 65 | else if(inputFilename.endsWith(".bas")) 66 | scanner = new SyntaxHighlighterBasic(); 67 | else if(inputFilename.endsWith(".f95")) 68 | scanner = new SyntaxHighlighterFortran(); 69 | else 70 | scanner = new SyntaxHighlighterCxx(); 71 | 72 | scanner->setConfig(&cfg); 73 | 74 | scanner->colorize(text); 75 | 76 | for(unsigned int rowIdx = 0;rowIdx < scanner->getRowCount();rowIdx++) 77 | { 78 | QVector colList = scanner->getRow(rowIdx); 79 | printf("%3d | ", rowIdx); 80 | for(int colIdx = 0; colIdx < colList.size();colIdx++) 81 | { 82 | TextField* field = colList[colIdx]; 83 | printf("'\033[1;32m%s\033[1;0m' ", stringToCStr(field->m_text)); 84 | } 85 | printf("\n"); 86 | } 87 | delete scanner; 88 | 89 | 90 | return 0; 91 | } 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/gotodialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | GoToDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 375 10 | 146 11 | 12 | 13 | 14 | Go To Line 15 | 16 | 17 | true 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 0 27 | 0 28 | 29 | 30 | 31 | true 32 | 33 | 34 | 35 | 36 | 37 | 38 | Go 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | DejaVu Sans 49 | 7 50 | 51 | 52 | 53 | (help) 54 | 55 | 56 | 57 | 58 | 59 | 60 | QListView::LeftToRight 61 | 62 | 63 | true 64 | 65 | 66 | QListView::Adjust 67 | 68 | 69 | QListView::ListMode 70 | 71 | 72 | true 73 | 74 | 75 | 200 76 | 77 | 78 | false 79 | 80 | 81 | true 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /src/consolewidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__CONSOLEWIDGET_H 10 | #define FILE__CONSOLEWIDGET_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "settings.h" 19 | 20 | 21 | class ConsoleWidget : public QWidget 22 | { 23 | Q_OBJECT 24 | public: 25 | ConsoleWidget(QWidget *parent = NULL); 26 | virtual ~ConsoleWidget(); 27 | 28 | void appendLog(QString text); 29 | 30 | void clearAll(); 31 | 32 | void setMonoFont(QFont font); 33 | void setConfig(Settings *cfg); 34 | void setScrollBar(QScrollBar *verticalScrollBar); 35 | 36 | public slots: 37 | void onCopyContent(); 38 | void onClearAll(); 39 | void onScrollBar_valueChanged(int value); 40 | void onTimerTimeout(); 41 | 42 | private: 43 | void decodeCSI(QChar c); 44 | void resizeEvent ( QResizeEvent * event ); 45 | int getRowHeight(); 46 | void insert(QChar c); 47 | void showPopupMenu(QPoint pos); 48 | void mousePressEvent( QMouseEvent * event ); 49 | bool eventFilter(QObject *obj, QEvent *event); 50 | QColor getFgColor(int code); 51 | QColor getBgColor(int code); 52 | 53 | int getRowsPerScreen(); 54 | void setOrigoY(int origoY ); 55 | void updateScrollBars(); 56 | 57 | protected: 58 | void paintEvent ( QPaintEvent * event ); 59 | void keyPressEvent ( QKeyEvent * event ); 60 | 61 | public: 62 | 63 | QFont m_font; 64 | QFontMetrics *m_fontInfo; 65 | 66 | public: 67 | 68 | enum { ST_IDLE, ST_OSC_PARAM, ST_OSC_STRING, ST_SECBYTE, ST_CSI_PARAM, ST_CSI_INTER } m_ansiState; 69 | 70 | QString m_ansiParamStr; 71 | QString m_ansiInter; 72 | QString m_ansiOscString; 73 | int m_fgColor; 74 | int m_bgColor; 75 | 76 | struct Block 77 | { 78 | public: 79 | int m_fgColor; 80 | int m_bgColor; 81 | QString text; 82 | }; 83 | typedef QVector Line; 84 | QVector m_lines; 85 | 86 | enum {STEADY, HIDDEN, BLINK_ON, BLINK_OFF} m_cursorMode; 87 | int m_cursorX; // Current cursor position column (0=first column) 88 | int m_cursorY; // Current cursor position row index (0=first row) 89 | int m_origoY; //!< Upper displayable line index for cursor pos 0 (0=first line) 90 | int m_dispOrigoY; //!< Upper displayable line (0=first line) 91 | QMenu m_popupMenu; 92 | Settings *m_cfg; 93 | QScrollBar *m_verticalScrollBar; 94 | QTimer m_timer; 95 | }; 96 | 97 | #endif // FILE__CONSOLEWIDGET_H 98 | 99 | -------------------------------------------------------------------------------- /src/tree.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__TREE_H 10 | #define FILE__TREE_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | class TreeNode 20 | { 21 | public: 22 | TreeNode(); 23 | TreeNode(QString name); 24 | virtual ~TreeNode(); 25 | 26 | TreeNode *findChild(QString path) const; 27 | 28 | void addChild(TreeNode *child); 29 | TreeNode *getChild(int i) const { return m_children[i]; }; 30 | int getChildCount() const { return m_children.size(); }; 31 | QString getData() const { return m_data; }; 32 | int getDataInt(int defaultValue = 0) const; 33 | 34 | QString getChildDataString(QString childName) const; 35 | int getChildDataInt(QString path, int defaultValue = 0) const; 36 | long long getChildDataLongLong(QString path, long long defaultValue = 0) const; 37 | 38 | void setData(QString data) { m_data = data; }; 39 | void dump(); 40 | 41 | QString getName() const { return m_name; }; 42 | 43 | void removeAll(); 44 | 45 | 46 | void copy(const TreeNode &other); 47 | private: 48 | void dump(int parentCnt); 49 | 50 | 51 | private: 52 | TreeNode *m_parent; 53 | QString m_name; 54 | QString m_data; 55 | QVector m_children; 56 | QHash m_childMap; 57 | 58 | private: 59 | TreeNode(const TreeNode &) { }; 60 | 61 | }; 62 | 63 | 64 | class Token; 65 | 66 | 67 | class Tree 68 | { 69 | public: 70 | Tree(); 71 | 72 | 73 | 74 | void dump() { m_root.dump();}; 75 | 76 | 77 | QString getString(QString path) const; 78 | int getInt(QString path, int defaultValue = 0) const; 79 | long long getLongLong(QString path) const; 80 | 81 | TreeNode *getChildAt(int idx) { return m_root.getChild(idx);}; 82 | int getRootChildCount() const { return m_root.getChildCount();}; 83 | 84 | TreeNode* findChild(QString path) const; 85 | 86 | TreeNode* getRoot() { return &m_root; }; 87 | void copy(const Tree &other); 88 | 89 | void removeAll(); 90 | 91 | private: 92 | 93 | TreeNode fromStringToTree(QString str); 94 | QList tokenize(QString str); 95 | Token* pop_token(); 96 | Token* peek_token(); 97 | 98 | void parseGroup(TreeNode *parentNode); 99 | void parseVar(TreeNode *parentNode); 100 | void parseVarList(TreeNode *parentNode); 101 | void parseData(TreeNode *ownerNode); 102 | void parseDataList(TreeNode *ownerNode); 103 | 104 | private: 105 | Tree(const Tree &) {}; 106 | private: 107 | 108 | TreeNode m_root; 109 | }; 110 | 111 | #endif // FILE__TREE_H 112 | -------------------------------------------------------------------------------- /src/variableinfowindow.cpp: -------------------------------------------------------------------------------- 1 | #include "variableinfowindow.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "core.h" 7 | 8 | 9 | VariableInfoWindow::VariableInfoWindow(QFont *font) 10 | : QWidget() 11 | ,m_font(font) 12 | { 13 | // setAttribute(Qt::WA_TranslucentBackground); 14 | setWindowFlags(windowFlags() | Qt::ToolTip); //Qt::WindowStaysOnTopHint); 15 | 16 | //setFrameStyle(QFrame::Panel | QFrame::Raised); 17 | 18 | } 19 | 20 | 21 | VariableInfoWindow::~VariableInfoWindow() 22 | { 23 | 24 | } 25 | 26 | 27 | void VariableInfoWindow::hide() 28 | { 29 | m_expr = ""; 30 | QWidget::hide(); 31 | } 32 | 33 | void VariableInfoWindow::show(QString expr) 34 | { 35 | Core &core = Core::getInstance(); 36 | 37 | if(expr != m_expr) 38 | { 39 | QString value; 40 | 41 | core.evaluateExpression(expr, &value); 42 | 43 | m_expr = expr; 44 | m_text = m_expr + "=" + value; 45 | if(m_text.length() > 120) 46 | m_text = m_text.left(120) + "..."; 47 | 48 | QFontMetrics m_fontInfo(*m_font); 49 | int textHeight = m_fontInfo.lineSpacing()+1; 50 | 51 | int w = 10 + m_fontInfo.width(m_text)+10; 52 | int h = 5 + textHeight + 5; 53 | 54 | resize(w,h); 55 | 56 | } 57 | QWidget::show(); 58 | } 59 | 60 | void drawFrame(QPainter &paint, const QRect &r) 61 | { 62 | QLine lines[4]; 63 | lines[0] = QLine(r.topLeft(), r.topRight()); 64 | lines[1] = QLine(r.topRight(), r.bottomRight()); 65 | lines[2] = QLine(r.bottomLeft(), r.bottomRight()); 66 | lines[3] = QLine(r.topLeft(), r.bottomLeft()); 67 | 68 | paint.drawLines(lines,4); 69 | } 70 | 71 | 72 | void VariableInfoWindow::paintEvent(QPaintEvent *event) 73 | { 74 | Q_UNUSED(event); 75 | 76 | QColor textColor = palette().color(QPalette::WindowText); 77 | 78 | // Create painter 79 | QPainter paint; 80 | paint.begin(this); 81 | 82 | 83 | QRect border = QRect(QPoint(0,0), size()); 84 | 85 | // Set font 86 | paint.setFont(*m_font); 87 | QFontMetrics m_fontInfo(*m_font); 88 | 89 | // Draw text 90 | paint.setPen(textColor); 91 | paint.drawText(10, 5+m_fontInfo.ascent(), m_text); 92 | 93 | // Draw widget frame 94 | paint.setPen(QColor(0x45,0x45,0x45)); 95 | drawFrame(paint, border); 96 | paint.setPen(QColor(0xa3,0xa3,0xa3)); 97 | paint.drawLine(1,1, 1, height()-2); 98 | paint.drawLine(1, height()-2, width()-2, height()-2); 99 | paint.setPen(QColor(0x87,0x87,0x87)); 100 | paint.drawLine(2,1, width()-2, 1); 101 | paint.drawLine(width()-2, 1, width()-2, height()-3); 102 | 103 | paint.end(); 104 | 105 | } 106 | 107 | void VariableInfoWindow::resizeEvent(QResizeEvent *re) 108 | { 109 | Q_UNUSED(re); 110 | setMask(rect()); 111 | 112 | //QWidget::resizeEvent(re); 113 | } 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /src/memorydialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | 10 | #include "memorydialog.h" 11 | 12 | #include "core.h" 13 | #include "util.h" 14 | 15 | #define SCROLL_ADDR_RANGE 0x10000ULL 16 | 17 | QByteArray MemoryDialog::getMemory(quint64 startAddress, int count) 18 | { 19 | Core &core = Core::getInstance(); 20 | 21 | QByteArray b; 22 | core.gdbGetMemory(startAddress, count, &b); 23 | 24 | return b; 25 | } 26 | 27 | MemoryDialog::MemoryDialog(QWidget *parent) 28 | : QDialog(parent) 29 | { 30 | 31 | m_ui.setupUi(this); 32 | 33 | m_ui.verticalScrollBar->setRange(0, SCROLL_ADDR_RANGE/16); 34 | connect(m_ui.verticalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(onVertScroll(int))); 35 | 36 | m_ui.memorywidget->setInterface(this); 37 | 38 | setStartAddress(0x0); 39 | 40 | connect(m_ui.pushButton_update, SIGNAL(clicked()), SLOT(onUpdate())); 41 | 42 | 43 | } 44 | 45 | /** 46 | * @brief Converts a string entered by the user to an address. 47 | */ 48 | quint64 MemoryDialog::inputTextToAddress(QString text) 49 | { 50 | // Remove leading zeroes 51 | while(text.startsWith('0') && text.length() > 1) 52 | text = text.mid(1); 53 | 54 | // Starts with a '0x...' or '0X..'? 55 | if(text.startsWith("x") || text.startsWith("X")) 56 | text = "0" + text; 57 | else if(text.lastIndexOf(QRegExp("[a-zA-Z]+")) != -1) 58 | { 59 | text = "0x" + text; 60 | } 61 | 62 | return stringToLongLong(text); 63 | } 64 | 65 | 66 | void MemoryDialog::onUpdate() 67 | { 68 | quint64 addr = inputTextToAddress(m_ui.lineEdit_address->text()); 69 | setStartAddress(addr); 70 | } 71 | 72 | void MemoryDialog::setStartAddress(quint64 addr) 73 | { 74 | quint64 addrAligned = addr & ~0xfULL; 75 | 76 | if(addrAligned < (SCROLL_ADDR_RANGE/2)) 77 | m_startScrollAddress = 0; 78 | else 79 | m_startScrollAddress = addrAligned - (SCROLL_ADDR_RANGE/2); 80 | 81 | m_ui.memorywidget->setStartAddress(addrAligned); 82 | m_ui.verticalScrollBar->setValue((addrAligned-m_startScrollAddress)/16); 83 | 84 | QString addrText = addrToString(addr); 85 | m_ui.lineEdit_address->setText(addrText); 86 | } 87 | 88 | 89 | void MemoryDialog::onVertScroll(int pos) 90 | { 91 | quint64 addr = m_startScrollAddress + ((quint64)pos*16ULL); 92 | m_ui.memorywidget->setStartAddress(addr); 93 | } 94 | 95 | void MemoryDialog::setConfig(Settings *cfg) 96 | { 97 | m_ui.memorywidget->setConfig(cfg); 98 | } 99 | 100 | 101 | void MemoryDialog::wheelEvent(QWheelEvent *event) 102 | { 103 | int dy = -event->delta()/32; 104 | int oldPos = m_ui.verticalScrollBar->value(); 105 | m_ui.verticalScrollBar->setValue(oldPos+dy); 106 | } 107 | -------------------------------------------------------------------------------- /src/gd.pro: -------------------------------------------------------------------------------- 1 | 2 | lessThan(QT_MAJOR_VERSION, 5) { 3 | QT += gui core 4 | } 5 | else { 6 | QT += gui core widgets 7 | } 8 | 9 | 10 | TEMPLATE = app 11 | 12 | SOURCES+=gd.cpp 13 | 14 | SOURCES+=parsecharqueue.cpp 15 | HEADERS+=parsecharqueue.h 16 | 17 | SOURCES+=mainwindow.cpp 18 | HEADERS+=mainwindow.h 19 | 20 | SOURCES+=codeview.cpp 21 | HEADERS+=codeview.h 22 | 23 | SOURCES+=gdbmiparser.cpp core.cpp 24 | HEADERS+=gdbmiparser.h core.h 25 | 26 | SOURCES+=com.cpp 27 | HEADERS+=com.h 28 | 29 | SOURCES+=log.cpp 30 | HEADERS+=log.h 31 | 32 | SOURCES+=qtutil.cpp util.cpp 33 | HEADERS+=qtutil.h util.h 34 | 35 | SOURCES+=tree.cpp 36 | HEADERS+=tree.h 37 | 38 | SOURCES+=aboutdialog.cpp 39 | HEADERS+=aboutdialog.h 40 | 41 | SOURCES+=syntaxhighlighter.cpp syntaxhighlighterbasic.cpp syntaxhighlightercxx.cpp 42 | SOURCES+=syntaxhighlighterrust.cpp 43 | SOURCES+=syntaxhighlighterfortran.cpp 44 | HEADERS+=syntaxhighlighter.h syntaxhighlighterbasic.h syntaxhighlightercxx.h 45 | HEADERS+=syntaxhighlighterrust.h 46 | HEADERS+=syntaxhighlighterfortran.h 47 | SOURCES+=syntaxhighlightergolang.cpp 48 | HEADERS+=syntaxhighlightergolang.h 49 | SOURCES+=syntaxhighlighterada.cpp 50 | HEADERS+=syntaxhighlighterada.h 51 | HEADERS+=adatagscanner.h 52 | SOURCES+=adatagscanner.cpp 53 | 54 | SOURCES+=ini.cpp 55 | HEADERS+=ini.h 56 | 57 | SOURCES+= opendialog.cpp 58 | HEADERS+=opendialog.h 59 | 60 | SOURCES+=settings.cpp 61 | HEADERS+=settings.h 62 | 63 | SOURCES+=tagscanner.cpp tagmanager.cpp 64 | HEADERS+=tagscanner.h tagmanager.h 65 | 66 | SOURCES+=rusttagscanner.cpp 67 | HEADERS+=rusttagscanner.h 68 | 69 | HEADERS+=config.h 70 | 71 | SOURCES+=varctl.cpp watchvarctl.cpp autovarctl.cpp 72 | HEADERS+=varctl.h watchvarctl.h autovarctl.h 73 | 74 | SOURCES+=consolewidget.cpp 75 | HEADERS+=consolewidget.h 76 | 77 | 78 | SOURCES+=settingsdialog.cpp 79 | HEADERS+=settingsdialog.h 80 | FORMS += settingsdialog.ui 81 | 82 | SOURCES+=codeviewtab.cpp 83 | HEADERS+=codeviewtab.h 84 | FORMS += codeviewtab.ui 85 | 86 | SOURCES+=memorydialog.cpp memorywidget.cpp 87 | HEADERS+=memorydialog.h memorywidget.h 88 | FORMS += memorydialog.ui 89 | 90 | SOURCES += processlistdialog.cpp 91 | HEADERS += processlistdialog.h 92 | FORMS += processlistdialog.ui 93 | 94 | FORMS += mainwindow.ui 95 | FORMS += aboutdialog.ui 96 | FORMS += opendialog.ui 97 | 98 | SOURCES+=colorbutton.cpp 99 | HEADERS+=colorbutton.h 100 | 101 | HEADERS+=autosignalblocker.h 102 | 103 | SOURCES+= execombobox.cpp 104 | HEADERS+= execombobox.h 105 | 106 | SOURCES+=variableinfowindow.cpp 107 | HEADERS+=variableinfowindow.h 108 | 109 | SOURCES+=tabwidgetadv.cpp 110 | HEADERS+=tabwidgetadv.h 111 | 112 | SOURCES+=gotodialog.cpp 113 | HEADERS+=gotodialog.h 114 | FORMS+=gotodialog.ui 115 | 116 | SOURCES+=locator.cpp 117 | HEADERS+=locator.h 118 | 119 | RESOURCES += resource.qrc 120 | 121 | #QMAKE_CXXFLAGS += -I./ -g 122 | 123 | QMAKE_CXXFLAGS += -I./ -DNDEBUG 124 | 125 | 126 | 127 | TARGET=gede 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /src/codeview.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__CODEVIEW_H 10 | #define FILE__CODEVIEW_H 11 | 12 | #include 13 | #include 14 | #include "syntaxhighlightercxx.h" 15 | #include "syntaxhighlighterbasic.h" 16 | #include "syntaxhighlighterfortran.h" 17 | #include "syntaxhighlightergolang.h" 18 | #include "syntaxhighlighterrust.h" 19 | #include "syntaxhighlighterada.h" 20 | 21 | 22 | #include "settings.h" 23 | #include 24 | #include "variableinfowindow.h" 25 | 26 | 27 | class ICodeView 28 | { 29 | public: 30 | ICodeView(){}; 31 | 32 | virtual void ICodeView_onRowDoubleClick(int lineNo) = 0; 33 | virtual void ICodeView_onContextMenu(QPoint pos, int lineNo, QStringList symbolList) = 0; 34 | virtual void ICodeView_onContextMenuIncFile(QPoint pos, int lineNo, QString incFile) = 0; 35 | 36 | 37 | }; 38 | 39 | 40 | class CodeView : public QWidget 41 | { 42 | Q_OBJECT 43 | 44 | public: 45 | 46 | CodeView(); 47 | virtual ~CodeView(); 48 | 49 | typedef enum {CODE_CXX, CODE_FORTRAN, CODE_BASIC,CODE_RUST, CODE_GOLANG, CODE_ADA} CodeType; 50 | 51 | void setPlainText(QString content, CodeType type); 52 | 53 | void setConfig(Settings *cfg); 54 | void paintEvent ( QPaintEvent * event ); 55 | 56 | void setCurrentLine(int lineNo); 57 | void disableCurrentLine(); 58 | 59 | void setInterface(ICodeView *inf) { m_inf = inf; }; 60 | 61 | void setBreakpoints(QVector numList); 62 | 63 | int getRowHeight(); 64 | 65 | 66 | int incSearchStart(QString text); 67 | int incSearchNext(); 68 | int incSearchPrev(); 69 | void clearIncSearch(); 70 | 71 | private: 72 | void idxToRowColumn(int idx, int *rowIdx, int *colIdx); 73 | int doIncSearch(QString pattern, int startPos, bool searchForward); 74 | void hideInfoWindow(); 75 | 76 | 77 | public slots: 78 | void onTimerTimeout(); 79 | 80 | 81 | private: 82 | int getBorderWidth(); 83 | void mouseReleaseEvent( QMouseEvent * event ); 84 | void mouseDoubleClickEvent( QMouseEvent * event ); 85 | void mousePressEvent(QMouseEvent * event); 86 | void mouseMoveEvent(QMouseEvent * event); 87 | void focusOutEvent ( QFocusEvent * event ); 88 | 89 | public: 90 | QFont m_font; 91 | QFontMetrics *m_fontInfo; 92 | int m_cursorY; 93 | ICodeView *m_inf; 94 | QVector m_breakpointList; 95 | SyntaxHighlighter *m_highlighter; 96 | Settings *m_cfg; 97 | QString m_text; 98 | QTimer m_timer; 99 | VariableInfoWindow m_infoWindow; 100 | 101 | 102 | int m_incSearchStartPosRow; 103 | int m_incSearchStartPosColumn; 104 | QString m_incSearchText; 105 | int m_incSearchStartPosIdx; 106 | }; 107 | 108 | 109 | #endif // FILE__CODEVIEW_H 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/ini.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__INI_H 10 | #define FILE__INI_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | class IniGroup; 19 | class Ini; 20 | 21 | class IniEntry 22 | { 23 | public: 24 | IniEntry(const IniEntry &other); 25 | IniEntry(QString name_); 26 | 27 | int getValueAsInt() const; 28 | double getValueAsFloat() const; 29 | QString getValueAsString() const; 30 | 31 | typedef enum {TYPE_BYTE_ARRAY, TYPE_SIZE, TYPE_STRING, TYPE_FLOAT, TYPE_INT, TYPE_COLOR} EntryType; 32 | 33 | QString getName() const { return m_name; }; 34 | 35 | private: 36 | QString m_name; 37 | QVariant m_value; 38 | EntryType m_type; 39 | 40 | friend IniGroup; 41 | friend Ini; 42 | }; 43 | 44 | class IniGroup 45 | { 46 | public: 47 | IniGroup(const IniGroup &other); 48 | IniGroup(QString name_); 49 | IniGroup(); 50 | virtual ~IniGroup(); 51 | 52 | void removeAll(); 53 | void dump() const; 54 | IniEntry *findEntry(QString entryName); 55 | IniEntry *addEntry(QString name, IniEntry::EntryType type); 56 | void copy(const IniGroup &src); 57 | 58 | QString getName() const { return m_name; }; 59 | 60 | private: 61 | QString m_name; 62 | QVector m_entries; 63 | 64 | friend Ini; 65 | }; 66 | 67 | class Ini 68 | { 69 | public: 70 | 71 | Ini(); 72 | Ini(const Ini &src); 73 | 74 | virtual ~Ini(); 75 | 76 | Ini& operator= (const Ini &src); 77 | void copy(const Ini &src); 78 | 79 | void setByteArray(QString name, const QByteArray &byteArray); 80 | void setInt(QString name, int value); 81 | void setString(QString name, QString value); 82 | void setStringList(QString name, QStringList value); 83 | void setBool(QString name, bool value); 84 | void setColor(QString name, QColor value); 85 | void setSize(QString name, QSize size); 86 | void setDouble(QString name, double value); 87 | 88 | bool getBool(QString name, bool defaultValue = false); 89 | void getByteArray(QString name, QByteArray *byteArray); 90 | int getInt(QString name, int defaultValue = -1); 91 | QColor getColor(QString name, QColor defaultValue); 92 | QString getString(QString name, QString defaultValue = ""); 93 | QStringList getStringList(QString name, QStringList defaultValue); 94 | QSize getSize(QString name, QSize defaultSize); 95 | double getDouble(QString name, double defValue); 96 | 97 | 98 | int appendLoad(QString filename); 99 | int save(QString filename); 100 | void dump(); 101 | 102 | private: 103 | IniEntry *addEntry(QString groupName, QString name, IniEntry::EntryType type); 104 | void divideName(QString name, QString *groupName, QString *entryName); 105 | IniGroup *findGroup(QString groupName); 106 | void removeAll(); 107 | IniEntry *findEntry(QString name); 108 | IniEntry *addEntry(QString name, IniEntry::EntryType type); 109 | int decodeValueString(IniEntry *entry, QString specialKind, QByteArray valueStr); 110 | QString encodeValueString(const IniEntry &entry); 111 | 112 | private: 113 | QVector m_entries; 114 | }; 115 | 116 | #endif // FILE__INI_H 117 | 118 | -------------------------------------------------------------------------------- /src/memorydialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MemoryDialog 4 | 5 | 6 | Qt::ApplicationModal 7 | 8 | 9 | 10 | 0 11 | 0 12 | 833 13 | 587 14 | 15 | 16 | 17 | Memory 18 | 19 | 20 | true 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Address 29 | 30 | 31 | 32 | 33 | 34 | 35 | <html><head/><body><p>Address in hex. Example 0x23.</p></body></html> 36 | 37 | 38 | 39 | 40 | 41 | 42 | Update 43 | 44 | 45 | true 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 0 58 | 0 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Qt::Vertical 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Qt::Horizontal 76 | 77 | 78 | QDialogButtonBox::Close 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | MemoryWidget 87 | QWidget 88 |
memorywidget.h
89 | 1 90 |
91 |
92 | 93 | 94 | 95 | buttonBox 96 | accepted() 97 | MemoryDialog 98 | accept() 99 | 100 | 101 | 248 102 | 254 103 | 104 | 105 | 157 106 | 274 107 | 108 | 109 | 110 | 111 | buttonBox 112 | rejected() 113 | MemoryDialog 114 | reject() 115 | 116 | 117 | 316 118 | 260 119 | 120 | 121 | 286 122 | 274 123 | 124 | 125 | 126 | 127 |
128 | -------------------------------------------------------------------------------- /src/aboutdialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | AboutDialog 4 | 5 | 6 | Qt::ApplicationModal 7 | 8 | 9 | 10 | 0 11 | 0 12 | 376 13 | 237 14 | 15 | 16 | 17 | About Gede 18 | 19 | 20 | 21 | 22 | 23 | Gede is written by Johan Henriksson 24 | 25 | 26 | 27 | 28 | 29 | 30 | Copyright (C) 2014-2017 31 | 32 | 33 | 34 | 35 | 36 | 37 | Version: 38 | 39 | 40 | 41 | 42 | 43 | 44 | Qt::Horizontal 45 | 46 | 47 | 48 | 49 | 50 | 51 | <Build Date> 52 | 53 | 54 | 55 | 56 | 57 | 58 | <html><head/><body><p>&lt;Qt version&gt;</p></body></html> 59 | 60 | 61 | 62 | 63 | 64 | 65 | <Gdb Path> 66 | 67 | 68 | 69 | 70 | 71 | 72 | <OS> 73 | 74 | 75 | 76 | 77 | 78 | 79 | Qt::Vertical 80 | 81 | 82 | 83 | 20 84 | 40 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | Qt::Horizontal 93 | 94 | 95 | QDialogButtonBox::Ok 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | buttonBox 105 | accepted() 106 | AboutDialog 107 | accept() 108 | 109 | 110 | 248 111 | 254 112 | 113 | 114 | 157 115 | 274 116 | 117 | 118 | 119 | 120 | buttonBox 121 | rejected() 122 | AboutDialog 123 | reject() 124 | 125 | 126 | 316 127 | 260 128 | 129 | 130 | 286 131 | 274 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /src/log.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #include "log.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace gedelog 18 | { 19 | struct LogEntry 20 | { 21 | public: 22 | typedef enum { TYPE_WARN, TYPE_INFO, TYPE_ERROR} Type; 23 | 24 | LogEntry(Type t, QString msg) : m_type(t), m_text(msg) {}; 25 | virtual ~LogEntry() {}; 26 | 27 | 28 | Type m_type; 29 | QString m_text; 30 | 31 | }; 32 | } 33 | 34 | using namespace gedelog; 35 | 36 | 37 | static QMutex g_mutex; 38 | static ILogger *g_logger = NULL; 39 | static QList m_pendingEntries; 40 | 41 | 42 | #ifdef WIN32 43 | #define YELLOW_CODE "" 44 | #define GREEN_CODE "" 45 | #define RED_CODE "" 46 | #define NO_CODE "" 47 | #else 48 | #define YELLOW_CODE "\033[1;33m" 49 | #define GREEN_CODE "\033[1;32m" 50 | #define RED_CODE "\033[1;31m" 51 | #define NO_CODE "\033[1;0m" 52 | #endif 53 | 54 | 55 | 56 | void loggerRegister(ILogger *logger) 57 | { 58 | QMutexLocker locker(&g_mutex); 59 | g_logger = logger; 60 | 61 | while(!m_pendingEntries.isEmpty()) 62 | { 63 | LogEntry entry = m_pendingEntries.takeFirst(); 64 | if(entry.m_type == LogEntry::TYPE_INFO) 65 | g_logger->ILogger_onInfoMsg(entry.m_text); 66 | else if(entry.m_type == LogEntry::TYPE_WARN) 67 | g_logger->ILogger_onWarnMsg(entry.m_text); 68 | else 69 | g_logger->ILogger_onErrorMsg(entry.m_text); 70 | } 71 | 72 | } 73 | 74 | void loggerUnregister(ILogger *logger) 75 | { 76 | QMutexLocker locker(&g_mutex); 77 | Q_UNUSED(logger); 78 | 79 | g_logger = NULL; 80 | } 81 | 82 | 83 | void debugMsg_(const char *filename, int lineNo, const char *fmt, ...) 84 | { 85 | va_list ap; 86 | char buffer[1024]; 87 | QTime curTime = QTime::currentTime(); 88 | 89 | QMutexLocker locker(&g_mutex); 90 | 91 | va_start(ap, fmt); 92 | 93 | vsnprintf(buffer, sizeof(buffer), fmt, ap); 94 | 95 | 96 | va_end(ap); 97 | 98 | printf("%2d.%03d| DEBUG | %s:%d| %s\n", 99 | curTime.second()%100, curTime.msec(), 100 | filename, lineNo, buffer); 101 | } 102 | 103 | 104 | void errorMsg(const char *fmt, ...) 105 | { 106 | va_list ap; 107 | char buffer[1024]; 108 | QTime curTime = QTime::currentTime(); 109 | 110 | QMutexLocker locker(&g_mutex); 111 | 112 | va_start(ap, fmt); 113 | vsnprintf(buffer, sizeof(buffer), fmt, ap); 114 | 115 | 116 | va_end(ap); 117 | 118 | 119 | if(g_logger) 120 | g_logger->ILogger_onErrorMsg(buffer); 121 | else 122 | { 123 | m_pendingEntries.append(LogEntry(LogEntry::TYPE_ERROR, buffer)); 124 | 125 | printf(RED_CODE "%2d.%03d| ERROR | %s" NO_CODE "\n", 126 | curTime.second()%100, curTime.msec(), 127 | buffer); 128 | 129 | } 130 | 131 | } 132 | 133 | 134 | void warnMsg(const char *fmt, ...) 135 | { 136 | va_list ap; 137 | char buffer[1024]; 138 | QTime curTime = QTime::currentTime(); 139 | 140 | QMutexLocker locker(&g_mutex); 141 | 142 | va_start(ap, fmt); 143 | vsnprintf(buffer, sizeof(buffer), fmt, ap); 144 | 145 | 146 | va_end(ap); 147 | 148 | 149 | if(g_logger) 150 | g_logger->ILogger_onWarnMsg(buffer); 151 | else 152 | { 153 | m_pendingEntries.append(LogEntry(LogEntry::TYPE_WARN, buffer)); 154 | 155 | printf(YELLOW_CODE "%2d.%03d| WARN | %s" NO_CODE "\n", 156 | curTime.second()%100, curTime.msec(), 157 | buffer); 158 | } 159 | } 160 | 161 | 162 | 163 | void infoMsg(const char *fmt, ...) 164 | { 165 | va_list ap; 166 | char buffer[1024]; 167 | QTime curTime = QTime::currentTime(); 168 | 169 | QMutexLocker locker(&g_mutex); 170 | 171 | va_start(ap, fmt); 172 | vsnprintf(buffer, sizeof(buffer), fmt, ap); 173 | 174 | 175 | va_end(ap); 176 | 177 | if(g_logger) 178 | g_logger->ILogger_onInfoMsg(buffer); 179 | else 180 | { 181 | m_pendingEntries.append(LogEntry(LogEntry::TYPE_INFO, buffer)); 182 | 183 | printf("%2d.%03d| INFO | %s\n", 184 | curTime.second()%100, curTime.msec(), 185 | buffer); 186 | } 187 | } 188 | 189 | 190 | -------------------------------------------------------------------------------- /src/settings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE_SETTINGS_H 10 | #define FILE_SETTINGS_H 11 | 12 | #include 13 | #include 14 | #include "ini.h" 15 | 16 | 17 | enum ConnectionMode 18 | { 19 | MODE_LOCAL = 0, //!< Local program 20 | MODE_COREDUMP, //!< Core dump file 21 | MODE_TCP, //!< TCP/IP connection to a gdbserver 22 | MODE_PID //!< Connect to a running process 23 | 24 | }; 25 | 26 | class SettingsBreakpoint 27 | { 28 | public: 29 | 30 | QString m_filename; 31 | int m_lineNo; 32 | }; 33 | 34 | 35 | class Settings 36 | { 37 | public: 38 | Settings(); 39 | 40 | void load(); 41 | void save(); 42 | void loadDefaultsGui(); 43 | void loadDefaultsAdvanced(); 44 | 45 | static QStringList getDefaultCxxKeywordList(); 46 | static QStringList getDefaultCppKeywordList(); 47 | static QStringList getDefaultBasicKeywordList(); 48 | static QStringList getDefaultRustKeywordList(); 49 | static QStringList getDefaultAdaKeywordList(); 50 | static QStringList getDefaultFortranKeywordList(); 51 | static QStringList getDefaultGoKeywordList(); 52 | 53 | QString getProgramPath(); 54 | 55 | int getTabIndentCount() const { return m_tabIndentCount; }; 56 | 57 | QStringList getGoToList(); 58 | void setGoToList(QStringList list); 59 | 60 | static void setProjectConfig(QString filename); 61 | 62 | private: 63 | void loadProjectConfig(); 64 | void loadGlobalConfig(); 65 | 66 | void saveProjectConfig(); 67 | void saveGlobalConfig(); 68 | 69 | public: 70 | bool m_globalProjConfig; 71 | 72 | QStringList m_argumentList; 73 | ConnectionMode m_connectionMode; 74 | int m_tcpPort; 75 | QString m_tcpHost; 76 | QStringList m_initCommands; 77 | QString m_gdbPath; 78 | QString m_lastProgram; 79 | QString m_coreDumpFile; 80 | bool m_download; 81 | 82 | QString m_fontFamily; 83 | int m_fontSize; 84 | QString m_memoryFontFamily; 85 | int m_memoryFontSize; 86 | QString m_outputFontFamily; 87 | int m_outputFontSize; 88 | QString m_gdbOutputFontFamily; 89 | int m_gdbOutputFontSize; 90 | QString m_gedeOutputFontFamily; 91 | int m_gedeOutputFontSize; 92 | 93 | QStringList m_sourceIgnoreDirs; 94 | 95 | bool m_reloadBreakpoints; 96 | QString m_initialBreakpoint; 97 | 98 | QList m_breakpoints; 99 | 100 | QColor m_clrBackground; 101 | QColor m_clrComment; 102 | QColor m_clrString; 103 | QColor m_clrIncString; 104 | QColor m_clrKeyword; 105 | QColor m_clrCppKeyword; 106 | QColor m_clrCurrentLine; 107 | QColor m_clrNumber; 108 | QColor m_clrForeground; 109 | QColor m_clrSelection; // Selection in codeview 110 | 111 | QByteArray m_gui_mainwindowState; 112 | QByteArray m_gui_mainwindowGeometry; 113 | QByteArray m_gui_splitter1State; 114 | QByteArray m_gui_splitter2State; 115 | QByteArray m_gui_splitter3State; 116 | QByteArray m_gui_splitter4State; 117 | 118 | bool m_viewWindowStack; 119 | bool m_viewWindowThreads; 120 | bool m_viewWindowBreakpoints; 121 | bool m_viewWindowWatch; 122 | bool m_viewWindowAutoVariables; 123 | bool m_viewWindowTargetOutput; 124 | bool m_viewWindowGedeOutput; 125 | bool m_viewWindowGdbOutput; 126 | bool m_viewWindowFileBrowser; 127 | bool m_viewFuncFilter; 128 | bool m_viewClassFilter; 129 | 130 | 131 | bool m_tagSortByName; 132 | bool m_tagShowLineNumbers; 133 | 134 | bool m_showLineNo; 135 | 136 | bool m_enableDebugLog; 137 | QString m_guiStyleName; // The GUI style to use (Eg: "cleanlooks"). 138 | 139 | int m_progConScrollback; // Number of lines of console output to save 140 | 141 | QColor m_progConColorFg; 142 | QColor m_progConColorBg; 143 | QColor m_progConColorCursor; 144 | QColor m_progConColorNorm[8]; 145 | QColor m_progConColorBright[8]; 146 | 147 | int m_progConBackspaceKey; 148 | int m_progConDelKey; 149 | 150 | int m_runningPid; 151 | 152 | int m_tabIndentCount; 153 | typedef enum { HOLLOW_RECT = 0, FILLED_RECT } CurrentLineStyle; 154 | CurrentLineStyle m_currentLineStyle; 155 | 156 | int m_maxTabs; //!< Max number of opened tabs at the same time 157 | 158 | int m_variablePopupDelay; //!< Number of milliseconds before the variables value should be displayed in a popup. 159 | QStringList m_gotoRuiList; 160 | 161 | private: 162 | static QString g_projConfigFilename; //!< Filename of the project config file. 163 | }; 164 | 165 | 166 | 167 | #endif // FILE_SETTINGS_H 168 | 169 | -------------------------------------------------------------------------------- /src/tree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #include "tree.h" 10 | 11 | #include 12 | #include 13 | 14 | #include "log.h" 15 | #include "util.h" 16 | 17 | TreeNode::TreeNode() 18 | : m_parent(NULL) 19 | { 20 | 21 | } 22 | 23 | TreeNode::TreeNode(QString name) 24 | : m_parent(NULL) 25 | ,m_name(name) 26 | { 27 | 28 | } 29 | 30 | int TreeNode::getDataInt(int defaultValue) const 31 | { 32 | bool ok = false; 33 | int val = m_data.toInt(&ok,0); 34 | if(ok) 35 | return val; 36 | return defaultValue; 37 | } 38 | 39 | void TreeNode::addChild(TreeNode *child) 40 | { 41 | child->m_parent = this; 42 | 43 | m_children.push_back(child); 44 | m_childMap[child->m_name] = child; 45 | 46 | } 47 | 48 | 49 | void TreeNode::copy(const TreeNode &other) 50 | { 51 | 52 | // Remove all children 53 | removeAll(); 54 | 55 | // Set name and data 56 | m_name = other.m_name; 57 | m_data = other.m_data; 58 | 59 | // Copy all children 60 | for(int i = 0;i < other.m_children.size();i++) 61 | { 62 | const TreeNode* otherNode = other.m_children[i]; 63 | TreeNode* thisNode = new TreeNode; 64 | thisNode->copy(*otherNode); 65 | 66 | addChild(thisNode); 67 | } 68 | 69 | } 70 | 71 | 72 | 73 | 74 | TreeNode::~TreeNode() 75 | { 76 | for(int i = 0;i < m_children.size();i++) 77 | { 78 | TreeNode* node = m_children[i]; 79 | delete node; 80 | } 81 | 82 | } 83 | 84 | 85 | 86 | void TreeNode::removeAll() 87 | { 88 | for(int i = 0;i < m_children.size();i++) 89 | { 90 | TreeNode* node = m_children[i]; 91 | delete node; 92 | } 93 | m_children.clear(); 94 | 95 | } 96 | 97 | 98 | 99 | void TreeNode::dump(int parentCnt) 100 | { 101 | QString text; 102 | text.sprintf("+- %s='%s'", 103 | stringToCStr(m_name), stringToCStr(m_data)); 104 | 105 | for(int i = 0;i < parentCnt;i++) 106 | text = " " + text; 107 | debugMsg("%s", stringToCStr(text)); 108 | for(int i = 0;i < (int)m_children.size();i++) 109 | { 110 | TreeNode *node = m_children[i]; 111 | node->dump(parentCnt+1); 112 | } 113 | 114 | } 115 | 116 | 117 | 118 | void TreeNode::dump() 119 | { 120 | 121 | dump(0); 122 | } 123 | 124 | 125 | Tree::Tree() 126 | { 127 | } 128 | 129 | 130 | 131 | 132 | 133 | int TreeNode::getChildDataInt(QString childName, int defaultValue) const 134 | { 135 | TreeNode *child = findChild(childName); 136 | if(child) 137 | return child->getDataInt(defaultValue); 138 | return defaultValue; 139 | } 140 | 141 | 142 | QString TreeNode::getChildDataString(QString childName) const 143 | { 144 | TreeNode *child = findChild(childName); 145 | if(child) 146 | return child->m_data; 147 | return ""; 148 | } 149 | 150 | long long TreeNode::getChildDataLongLong(QString childPath, long long defaultValue) const 151 | { 152 | TreeNode *child = findChild(childPath); 153 | if(child) 154 | return stringToLongLong(stringToCStr(child->m_data)); 155 | return defaultValue; 156 | } 157 | 158 | 159 | TreeNode *TreeNode::findChild(QString path) const 160 | { 161 | QString childName; 162 | QString restPath; 163 | int indexPos; 164 | 165 | // Find the seperator in the string 166 | indexPos = path.indexOf('/'); 167 | if(indexPos == 0) 168 | return findChild(path.mid(1)); 169 | 170 | // Get the first child name 171 | if(indexPos == -1) 172 | childName = path; 173 | else 174 | { 175 | childName = path.left(indexPos); 176 | restPath = path.mid(indexPos+1); 177 | } 178 | 179 | if(childName.startsWith('#')) 180 | { 181 | QString numStr = childName.mid(1); 182 | int idx = atoi(stringToCStr(numStr))-1; 183 | if(0 <= idx && idx < getChildCount()) 184 | { 185 | TreeNode *child = getChild(idx); 186 | if(restPath.isEmpty()) 187 | return child; 188 | else 189 | return child->findChild(restPath); 190 | } 191 | } 192 | else 193 | { 194 | 195 | TreeNode *child; 196 | 197 | if(m_childMap.contains(childName)) 198 | { 199 | child = m_childMap[childName]; 200 | assert(child->m_name == childName); 201 | if(restPath.isEmpty()) 202 | return child; 203 | else 204 | return child->findChild(restPath); 205 | } 206 | else 207 | { 208 | // Look for the child 209 | for(int u = 0;u < getChildCount();u++) 210 | { 211 | child = getChild(u); 212 | 213 | if(child->getName() == childName) 214 | { 215 | if(restPath.isEmpty()) 216 | return child; 217 | else 218 | return child->findChild(restPath); 219 | } 220 | } 221 | } 222 | } 223 | 224 | return NULL; 225 | } 226 | 227 | 228 | 229 | QString Tree::getString(QString path) const 230 | { 231 | return m_root.getChildDataString(path); 232 | } 233 | 234 | 235 | int Tree::getInt(QString path, int defaultValue) const 236 | { 237 | return m_root.getChildDataInt(path, defaultValue); 238 | } 239 | 240 | 241 | long long Tree::getLongLong(QString path) const 242 | { 243 | return m_root.getChildDataLongLong(path); 244 | } 245 | 246 | TreeNode* Tree::findChild(QString path) const 247 | { 248 | return m_root.findChild(path); 249 | } 250 | 251 | 252 | 253 | void Tree::removeAll() 254 | { 255 | m_root.removeAll(); 256 | } 257 | 258 | 259 | void Tree::copy(const Tree &other) 260 | { 261 | m_root.copy(other.m_root); 262 | 263 | } 264 | 265 | 266 | 267 | -------------------------------------------------------------------------------- /src/tagmanager.cpp: -------------------------------------------------------------------------------- 1 | //#define ENABLE_DEBUGMSG 2 | 3 | 4 | /* 5 | * Copyright (C) 2018 Johan Henriksson. 6 | * All rights reserved. 7 | * 8 | * This software may be modified and distributed under the terms 9 | * of the BSD license. See the LICENSE file for details. 10 | */ 11 | 12 | #include "tagmanager.h" 13 | 14 | #include "tagscanner.h" 15 | #include "mainwindow.h" 16 | #include "log.h" 17 | #include "util.h" 18 | 19 | 20 | ScannerWorker::ScannerWorker() 21 | : m_isIdle(true) 22 | { 23 | #ifndef NDEBUG 24 | m_dbgMainThread = QThread::currentThreadId (); 25 | #endif 26 | m_quit = false; 27 | } 28 | 29 | 30 | void ScannerWorker::requestQuit() 31 | { 32 | m_quit = true; 33 | m_wait.wakeAll(); 34 | } 35 | 36 | void ScannerWorker::abort() 37 | { 38 | QMutexLocker locker(&m_mutex); 39 | m_workQueue.clear(); 40 | } 41 | 42 | bool ScannerWorker::isIdle() 43 | { 44 | QMutexLocker locker(&m_mutex); 45 | return m_isIdle; 46 | } 47 | 48 | 49 | void ScannerWorker::run() 50 | { 51 | assert(m_dbgMainThread != QThread::currentThreadId ()); 52 | 53 | 54 | m_scanner.init(&m_cfg); 55 | 56 | while(m_quit == false) 57 | { 58 | m_mutex.lock(); 59 | m_wait.wait(&m_mutex); 60 | while(!m_workQueue.isEmpty()) 61 | { 62 | m_isIdle = false; 63 | QString filePath = m_workQueue.takeFirst(); 64 | m_mutex.unlock(); 65 | 66 | scan(filePath); 67 | 68 | m_mutex.lock(); 69 | } 70 | m_isIdle = true; 71 | m_mutex.unlock(); 72 | m_doneCond.wakeAll(); 73 | } 74 | } 75 | 76 | 77 | void ScannerWorker::setConfig(Settings cfg) 78 | { 79 | QMutexLocker am(&m_mutex); 80 | m_cfg = cfg; 81 | } 82 | 83 | 84 | void ScannerWorker::waitAll() 85 | { 86 | m_mutex.lock(); 87 | while(!m_workQueue.isEmpty() || m_isIdle == false) 88 | { 89 | m_doneCond.wait(&m_mutex); 90 | } 91 | m_mutex.unlock(); 92 | 93 | } 94 | 95 | void ScannerWorker::queueScan(QString filePath) 96 | { 97 | m_mutex.lock(); 98 | m_isIdle = false; 99 | m_workQueue.append(filePath); 100 | m_mutex.unlock(); 101 | m_wait.wakeAll(); 102 | } 103 | 104 | 105 | 106 | 107 | void ScannerWorker::scan(QString filePath) 108 | { 109 | QList *taglist = new QList; 110 | 111 | 112 | assert(m_dbgMainThread != QThread::currentThreadId ()); 113 | 114 | 115 | m_scanner.scan(filePath, taglist); 116 | 117 | 118 | emit onScanDone(filePath, taglist); 119 | } 120 | 121 | 122 | TagManager::TagManager(Settings &cfg) 123 | { 124 | #ifndef NDEBUG 125 | m_dbgMainThread = QThread::currentThreadId (); 126 | #endif 127 | 128 | m_worker.setConfig(cfg); 129 | m_worker.start(); 130 | 131 | connect(&m_worker, SIGNAL(onScanDone(QString, QList* )), this, SLOT(onScanDone(QString, QList* ))); 132 | 133 | m_cfg = cfg; 134 | m_tagScanner.init(&m_cfg); 135 | 136 | } 137 | 138 | TagManager::~TagManager() 139 | { 140 | m_worker.requestQuit(); 141 | m_worker.wait(); 142 | 143 | 144 | foreach (ScannerResult* info, m_db) 145 | { 146 | delete info; 147 | } 148 | } 149 | 150 | void TagManager::waitAll() 151 | { 152 | m_worker.waitAll(); 153 | } 154 | 155 | 156 | 157 | void TagManager::onScanDone(QString filePath, QList *tags) 158 | { 159 | assert(m_dbgMainThread == QThread::currentThreadId ()); 160 | 161 | ScannerResult *info = new ScannerResult; 162 | info->m_filePath = filePath; 163 | info->m_tagList = *tags; 164 | 165 | if(m_db.contains(filePath)) 166 | { 167 | ScannerResult *oldInfo = m_db[filePath]; 168 | delete oldInfo; 169 | } 170 | 171 | m_db[filePath] = info; 172 | 173 | if(m_worker.isIdle()) 174 | emit onAllScansDone(); 175 | 176 | delete tags; 177 | } 178 | 179 | /** 180 | * @brief Tags a scan to be made later (in a seperate thread). 181 | */ 182 | int TagManager::queueScan(QStringList filePathList) 183 | { 184 | bool queuedAny = false; 185 | 186 | assert(m_dbgMainThread == QThread::currentThreadId ()); 187 | for(int i = 0;i < filePathList.size();i++) 188 | { 189 | QString filePath = filePathList[i]; 190 | if(!m_db.contains(filePath)) 191 | { 192 | m_worker.queueScan(filePath); 193 | queuedAny = true; 194 | } 195 | } 196 | 197 | if(!queuedAny) 198 | emit onAllScansDone(); 199 | 200 | return 0; 201 | } 202 | 203 | 204 | 205 | void TagManager::scan(QString filePath, QList *tagList) 206 | { 207 | if(!m_db.contains(filePath)) 208 | { 209 | ScannerResult *res = new ScannerResult; 210 | res->m_filePath = filePath; 211 | 212 | m_tagScanner.scan(res->m_filePath, &res->m_tagList); 213 | 214 | m_db[filePath] = res; 215 | } 216 | 217 | *tagList = m_db[filePath]->m_tagList; 218 | 219 | } 220 | 221 | void TagManager::abort() 222 | { 223 | m_worker.abort(); 224 | } 225 | 226 | void TagManager::getTags(QString filePath, QList *tagList) 227 | { 228 | if(m_db.contains(filePath)) 229 | { 230 | *tagList = m_db[filePath]->m_tagList; 231 | } 232 | } 233 | 234 | 235 | /** 236 | * @brief Lookup tags with a specific name. 237 | * @param name The name of the tag (Eg: "main" or "Class::myFunc"). 238 | * @return tagList The found tags. 239 | */ 240 | void TagManager::lookupTag(QString name, QList *tagList) 241 | { 242 | debugMsg("%s(name:'%s')", __func__, qPrintable(name)); 243 | 244 | QString funcName; 245 | QString className; 246 | 247 | if(name.contains("::")) 248 | { 249 | int divPos = name.indexOf("::"); 250 | funcName = name.mid(divPos+2); 251 | className = name.left(divPos); 252 | } 253 | else 254 | funcName = name; 255 | 256 | foreach (ScannerResult* info, m_db) 257 | { 258 | for(int j = 0;j < info->m_tagList.size();j++) 259 | { 260 | Tag &tag = info->m_tagList[j]; 261 | 262 | if(tag.getName() == funcName && className == tag.getClassName()) 263 | tagList->append(tag); 264 | 265 | } 266 | } 267 | 268 | } 269 | 270 | void TagManager::setConfig(Settings &cfg) 271 | { 272 | m_cfg = cfg; 273 | m_worker.setConfig(cfg); 274 | }; 275 | 276 | 277 | -------------------------------------------------------------------------------- /src/gd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #include 10 | #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) 11 | #include 12 | #else 13 | #include 14 | #endif 15 | 16 | #include 17 | #include 18 | 19 | #include "mainwindow.h" 20 | #include "core.h" 21 | #include "log.h" 22 | #include "util.h" 23 | #include "tree.h" 24 | #include "opendialog.h" 25 | #include "settings.h" 26 | #include "version.h" 27 | 28 | 29 | 30 | static int dumpUsage() 31 | { 32 | /* 33 | QMessageBox::information ( NULL, "Unable to start", 34 | "Usage: gd --args PROGRAM_NAME", 35 | QMessageBox::Ok, QMessageBox::Ok); 36 | */ 37 | printf("Usage: gede [OPTIONS] [--args PROGRAM_NAME [PROGRAM_ARGUMENTS...]]\n"); 38 | printf("\n"); 39 | printf("Where OPTIONS are:\n"); 40 | printf(" --no-show-config / --show-config Shows the configuration window at startup.\n"); 41 | printf(" --help Displays this text.\n"); 42 | printf(" --version Displays the version of gede.\n"); 43 | printf(" --projconfig FILENAME Specify config filename to use.\n"); 44 | printf(" Default is '%s' \n", PROJECT_CONFIG_FILENAME); 45 | printf("\n"); 46 | printf("Examples:\n"); 47 | printf("\n"); 48 | printf(" To start to debug the application \"my_application\":\n"); 49 | printf(" $ gede --args my_application\n"); 50 | printf("\n"); 51 | 52 | return -1; 53 | } 54 | 55 | static int dumpVersion() 56 | { 57 | printf("gede %d.%d.%d\n", GD_MAJOR, GD_MINOR, GD_PATCH); 58 | 59 | return -1; 60 | } 61 | 62 | 63 | 64 | /** 65 | * @brief Loads the breakpoints from the settings file and set the breakpoints. 66 | */ 67 | void loadBreakpoints(Settings &cfg, Core &core) 68 | { 69 | for(int i = 0;i < cfg.m_breakpoints.size();i++) 70 | { 71 | SettingsBreakpoint bkptCfg = cfg.m_breakpoints[i]; 72 | debugMsg("Setting breakpoint at %s:L%d", qPrintable(bkptCfg.m_filename), bkptCfg.m_lineNo); 73 | core.gdbSetBreakpoint(bkptCfg.m_filename, bkptCfg.m_lineNo); 74 | } 75 | } 76 | 77 | 78 | 79 | /** 80 | * @brief Main program entry. 81 | */ 82 | int main(int argc, char *argv[]) 83 | { 84 | int rc = 0; 85 | Settings cfg; 86 | bool showConfigDialog = true; 87 | 88 | // Ensure that the config dir exist 89 | QDir d; 90 | d.mkdir(QDir::homePath() + "/" + GLOBAL_CONFIG_DIR); 91 | 92 | // 93 | for(int i = 1;i < argc;i++) 94 | { 95 | const char *curArg = argv[i]; 96 | if(strcmp(curArg, "--version") == 0) 97 | { 98 | return dumpVersion(); 99 | } 100 | else if(strcmp(curArg, "--help") == 0) 101 | { 102 | return dumpUsage(); 103 | } 104 | else if((strcmp(curArg, "--projconfig") == 0 || strcmp(curArg, "--proj-config") == 0) 105 | && i+1 < argc) 106 | { 107 | i++; 108 | cfg.setProjectConfig(argv[i]); 109 | } 110 | 111 | } 112 | 113 | // Load default config 114 | cfg.load(); 115 | for(int i = 1;i < argc;i++) 116 | { 117 | const char *curArg = argv[i]; 118 | if((strcmp(curArg, "--projconfig") == 0 || strcmp(curArg, "--proj-config") == 0) 119 | && i+1 < argc) 120 | { 121 | i++; 122 | } 123 | else if(strcmp(curArg, "--args") == 0) 124 | { 125 | cfg.m_connectionMode = MODE_LOCAL; 126 | cfg.m_argumentList.clear(); 127 | for(int u = i+1;u < argc;u++) 128 | { 129 | if(u == i+1) 130 | cfg.m_lastProgram = argv[u]; 131 | else 132 | cfg.m_argumentList.push_back(argv[u]); 133 | } 134 | argc = i; 135 | } 136 | else if(strcmp(curArg, "--show-config") == 0) 137 | showConfigDialog = true; 138 | else if(strcmp(curArg, "--no-show-config") == 0) 139 | showConfigDialog = false; 140 | else if(strcmp(curArg, "--version") == 0) 141 | { 142 | return dumpVersion(); 143 | } 144 | else // if(strcmp(curArg, "--help") == 0) 145 | { 146 | return dumpUsage(); 147 | } 148 | } 149 | 150 | QApplication app(argc, argv); 151 | 152 | if(!cfg.m_guiStyleName.isEmpty()) 153 | { 154 | QApplication::setStyle(cfg.m_guiStyleName); 155 | } 156 | 157 | if(cfg.m_lastProgram.isEmpty()) 158 | showConfigDialog = true; 159 | 160 | // Got a program to debug? 161 | if(showConfigDialog) 162 | { 163 | // Ask user for program 164 | OpenDialog dlg(NULL); 165 | 166 | dlg.loadConfig(cfg); 167 | 168 | if(dlg.exec() != QDialog::Accepted) 169 | return 1; 170 | 171 | dlg.saveConfig(&cfg); 172 | } 173 | 174 | // Save config 175 | cfg.save(); 176 | 177 | // 178 | if(cfg.getProgramPath().isEmpty()) 179 | { 180 | errorMsg("No program to debug"); 181 | return 1; 182 | } 183 | 184 | Core &core = Core::getInstance(); 185 | 186 | 187 | MainWindow w(NULL); 188 | 189 | if(cfg.m_connectionMode == MODE_LOCAL) 190 | rc = core.initLocal(&cfg, cfg.m_gdbPath, cfg.m_lastProgram, cfg.m_argumentList); 191 | else if(cfg.m_connectionMode == MODE_COREDUMP) 192 | rc = core.initCoreDump(&cfg, cfg.m_gdbPath, cfg.m_lastProgram, cfg.m_coreDumpFile); 193 | else if(cfg.m_connectionMode == MODE_PID) 194 | rc = core.initPid(&cfg, cfg.m_gdbPath, cfg.m_lastProgram, cfg.m_runningPid); 195 | else 196 | rc = core.initRemote(&cfg, cfg.m_gdbPath, cfg.m_lastProgram, cfg.m_tcpHost, cfg.m_tcpPort); 197 | 198 | if(rc) 199 | return rc; 200 | 201 | // Set the status line 202 | w.setStatusLine(cfg); 203 | 204 | w.insertSourceFiles(); 205 | 206 | if(cfg.m_reloadBreakpoints) 207 | loadBreakpoints(cfg, core); 208 | 209 | if(rc == 0 && (cfg.m_connectionMode == MODE_LOCAL || cfg.m_connectionMode == MODE_TCP)) 210 | core.gdbRun(); 211 | 212 | w.show(); 213 | 214 | return app.exec(); 215 | } 216 | 217 | -------------------------------------------------------------------------------- /src/com.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__COM_H 10 | #define FILE__COM_H 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "tree.h" 18 | #include "config.h" 19 | 20 | 21 | class Token 22 | { 23 | public: 24 | 25 | enum Type{ 26 | UNKNOWN, 27 | C_STRING, // "string" 28 | C_CHAR, // 'c' 29 | KEY_EQUAL, // '=' 30 | KEY_LEFT_BRACE, // '{' 31 | KEY_RIGHT_BRACE, // '}' 32 | KEY_LEFT_BAR, // '[' 33 | KEY_RIGHT_BAR, // ']' 34 | KEY_UP, // '^' 35 | KEY_PLUS, // '-' 36 | KEY_COMMA, // ',' 37 | KEY_TILDE, // '~' 38 | KEY_SNABEL, // '@' 39 | KEY_STAR, // '*' 40 | KEY_AND, // '&' 41 | END_CODE, 42 | VAR 43 | }; 44 | public: 45 | 46 | Token(Type type) : m_type(type) {}; 47 | 48 | static const char *typeToString(Type type); 49 | Type getType() const { return m_type; }; 50 | void setType(Type type) { m_type = type; }; 51 | QString getString() const { return m_text; }; 52 | 53 | const char *toString(); 54 | 55 | private: 56 | Type m_type; 57 | char m_tmpBuff[128]; 58 | public: 59 | QString m_text; 60 | }; 61 | 62 | 63 | 64 | class GdbComListener : public QObject 65 | { 66 | 67 | private: 68 | Q_OBJECT 69 | 70 | public: 71 | 72 | enum AsyncClass 73 | { 74 | AC_STOPPED, 75 | AC_RUNNING, 76 | AC_THREAD_CREATED, 77 | AC_THREAD_GROUP_ADDED, 78 | AC_THREAD_GROUP_STARTED, 79 | AC_LIBRARY_LOADED, 80 | AC_BREAKPOINT_MODIFIED, 81 | AC_BREAKPOINT_DELETED, 82 | AC_THREAD_EXITED, 83 | AC_THREAD_GROUP_EXITED, 84 | AC_LIBRARY_UNLOADED, 85 | AC_THREAD_SELECTED, 86 | AC_DOWNLOAD, 87 | AC_CMD_PARAM_CHANGED, 88 | AC_UNKNOWN 89 | }; 90 | 91 | 92 | virtual void onStatusAsyncOut(Tree &tree, AsyncClass ac) = 0; 93 | virtual void onNotifyAsyncOut(Tree &tree, AsyncClass ac) = 0; 94 | virtual void onExecAsyncOut(Tree &tree, AsyncClass ac) = 0; 95 | virtual void onResult(Tree &tree) = 0; 96 | virtual void onConsoleStreamOutput(QString str) = 0; 97 | virtual void onTargetStreamOutput(QString str) = 0; 98 | virtual void onLogStreamOutput(QString str) = 0; 99 | 100 | }; 101 | 102 | enum GdbResult 103 | { 104 | GDB_DONE = 0, 105 | GDB_RUNNING, 106 | GDB_CONNECTED, 107 | GDB_ERROR, 108 | GDB_EXIT 109 | }; 110 | 111 | 112 | class PendingCommand 113 | { 114 | public: 115 | PendingCommand() {}; 116 | 117 | QString m_cmdText; 118 | 119 | 120 | }; 121 | 122 | 123 | class Resp 124 | { 125 | public: 126 | Resp() : m_type(UNKNOWN) {}; 127 | 128 | typedef enum { 129 | UNKNOWN = 0, 130 | RESULT, 131 | CONSOLE_STREAM_OUTPUT, 132 | TARGET_STREAM_OUTPUT, 133 | LOG_STREAM_OUTPUT, 134 | TERMINATION, 135 | STATUS_ASYNC_OUTPUT, 136 | NOTIFY_ASYNC_OUTPUT, 137 | EXEC_ASYNC_OUTPUT, 138 | } Type; 139 | 140 | bool isResult(); 141 | Type getType() { return m_type; }; 142 | void setType(Type t) { assert(m_type == UNKNOWN); m_type = t; }; 143 | 144 | bool isTermination() { return m_type == TERMINATION ? true : false; }; 145 | QString getString() { return m_str; }; 146 | void setString(QString str) { m_str = str; }; 147 | 148 | QString getDataStr() { return m_dataStr; }; 149 | private: 150 | Type m_type; 151 | QString m_str; 152 | QString m_dataStr; 153 | public: 154 | Tree tree; 155 | GdbComListener::AsyncClass reason; 156 | GdbResult m_result; 157 | 158 | 159 | }; 160 | 161 | 162 | 163 | class GdbCom : public QObject 164 | { 165 | private: 166 | 167 | Q_OBJECT 168 | 169 | GdbCom(); 170 | ~GdbCom(); 171 | 172 | public: 173 | 174 | 175 | static const char* asyncClassToString(GdbComListener::AsyncClass ac); 176 | 177 | static GdbCom& getInstance(); 178 | int init(QString gdbPath, bool enableDebugLog); 179 | 180 | void setListener(GdbComListener *listener) { m_listener = listener; }; 181 | 182 | int getPid(); 183 | 184 | GdbResult commandF(Tree *resultData, const char *cmd, ...); 185 | GdbResult command(Tree *resultData, QString cmd); 186 | 187 | static QList tokenize(QString str); 188 | 189 | void enableLog(bool enable); 190 | 191 | private: 192 | int parseAsyncOutput(Resp *resp, GdbComListener::AsyncClass *ac); 193 | Resp *parseAsyncRecord(); 194 | Resp *parseExecAsyncOutput(); 195 | Resp *parseNotifyAsyncOutput(); 196 | Resp *parseOutOfBandRecord(); 197 | Resp *parseOutput(); 198 | int parseResult(TreeNode *parent); 199 | Resp *parseResultRecord(); 200 | Resp *parseStatusAsyncOutput(); 201 | Resp *parseStreamRecord(); 202 | int parseValue(TreeNode *item); 203 | 204 | 205 | 206 | public slots: 207 | void onReadyReadStandardOutput (); 208 | void onReadyReadStandardError(); 209 | 210 | 211 | private: 212 | int readFromGdb(GdbResult *m_result, Tree *m_resultData); 213 | void decodeGdbResponse(); 214 | Token* pop_token(); 215 | Token* peek_token(); 216 | Token* checkToken(Token::Type type); 217 | Token* eatToken(Token::Type type); 218 | void dispatchResp(); 219 | bool isTokenPending(); 220 | void readTokens(); 221 | void writeLogEntry(QString logText); 222 | 223 | private: 224 | QProcess m_process; 225 | QList m_respQueue; //!< List of responses received from GDB 226 | QList m_pending; 227 | GdbComListener *m_listener; 228 | 229 | QList m_freeTokens; //!< List of tokens allocated but not in use. 230 | QList m_list; 231 | QFile m_logFile; 232 | QByteArray m_inputBuffer; //!< List of raw characters received from the GDB process. 233 | int m_busy; 234 | bool m_enableLog; 235 | }; 236 | 237 | 238 | #endif // FILE__COM_H 239 | -------------------------------------------------------------------------------- /src/codeviewtab.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #include "codeviewtab.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "config.h" 16 | #include "util.h" 17 | #include "log.h" 18 | 19 | 20 | CodeViewTab::CodeViewTab(QWidget *parent) 21 | : QWidget(parent) 22 | { 23 | m_ui.setupUi(this); 24 | 25 | connect(m_ui.comboBox_funcList, SIGNAL(activated(int)), SLOT(onFuncListItemActivated(int))); 26 | 27 | 28 | } 29 | 30 | CodeViewTab::~CodeViewTab() 31 | { 32 | } 33 | 34 | static bool compareTagsByLineNo(const Tag &t1, const Tag &t2) 35 | { 36 | return t1.getLineNo() < t2.getLineNo(); 37 | } 38 | 39 | static bool compareTagsByName(const Tag &t1, const Tag &t2) 40 | { 41 | return t1.getLongName() < t2.getLongName(); 42 | } 43 | 44 | void CodeViewTab::fillInFunctions(QList tagList) 45 | { 46 | m_ui.comboBox_funcList->clear(); 47 | if(m_cfg->m_tagSortByName) 48 | qSort(tagList.begin(),tagList.end(), compareTagsByName); 49 | else 50 | qSort(tagList.begin(),tagList.end(), compareTagsByLineNo); 51 | for(int tagIdx = 0;tagIdx < tagList.size();tagIdx++) 52 | { 53 | Tag &tag = tagList[tagIdx]; 54 | if(tag.m_type == Tag::TAG_FUNC) 55 | { 56 | QString text; 57 | if(m_cfg->m_tagShowLineNumbers) 58 | { 59 | text.sprintf("L%d: ", tag.getLineNo()); 60 | text = text.leftJustified(6, ' '); 61 | } 62 | text += tag.getLongName(); 63 | m_ui.comboBox_funcList->addItem(text, QVariant(tag.getLineNo())); 64 | } 65 | 66 | } 67 | 68 | } 69 | 70 | int CodeViewTab::open(QString filename, QList tagList) 71 | { 72 | m_filepath = filename; 73 | QString extension = getExtensionPart(filename); 74 | QString text; 75 | // Read file content 76 | QFile file(filename); 77 | if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) 78 | { 79 | errorMsg("Failed to open '%s'", stringToCStr(filename)); 80 | return -1; 81 | } 82 | const int tabIndent = m_cfg->getTabIndentCount(); 83 | while (!file.atEnd()) 84 | { 85 | QByteArray line = file.readLine(); 86 | 87 | // Replace tabs with spaces 88 | QByteArray expandedLine; 89 | for(int i = 0;i < line.size();i++) 90 | { 91 | char c = line[i]; 92 | if(c == '\t') 93 | { 94 | if(tabIndent > 0) 95 | { 96 | int spacesToAdd = tabIndent-(expandedLine.size()%tabIndent); 97 | const QByteArray spaces(spacesToAdd, ' '); 98 | expandedLine.append(spaces); 99 | } 100 | } 101 | else 102 | expandedLine += c; 103 | } 104 | 105 | text += expandedLine; 106 | } 107 | 108 | if(extension.toLower() == ".bas") 109 | m_ui.codeView->setPlainText(text, CodeView::CODE_BASIC); 110 | else if(extension.toLower() == ".f" || extension.toLower() == ".f95" 111 | || extension.toLower() == ".for") 112 | m_ui.codeView->setPlainText(text, CodeView::CODE_FORTRAN); 113 | else if(extension.toLower() == RUST_FILE_EXTENSION) 114 | m_ui.codeView->setPlainText(text, CodeView::CODE_RUST); 115 | else if(extension.toLower() == ADA_FILE_EXTENSION) 116 | m_ui.codeView->setPlainText(text, CodeView::CODE_ADA); 117 | else if(extension.toLower() == GOLANG_FILE_EXTENSION) 118 | m_ui.codeView->setPlainText(text, CodeView::CODE_GOLANG); 119 | else 120 | m_ui.codeView->setPlainText(text, CodeView::CODE_CXX); 121 | 122 | m_ui.scrollArea_codeView->setWidgetResizable(true); 123 | 124 | // Fill in the functions 125 | fillInFunctions(tagList); 126 | m_tagList = tagList; 127 | 128 | 129 | return 0; 130 | } 131 | 132 | 133 | /** 134 | * @brief Ensures that a specific line is visible. 135 | */ 136 | void CodeViewTab::ensureLineIsVisible(int lineIdx) 137 | { 138 | 139 | if(lineIdx < 0) 140 | lineIdx = 0; 141 | 142 | 143 | // Find the function in the function combobox that matches the line 144 | int bestFitIdx = -1; 145 | int bestFitDist = -1; 146 | for(int u = 0;u < m_ui.comboBox_funcList->count();u++) 147 | { 148 | int funcLineNo = m_ui.comboBox_funcList->itemData(u).toInt(); 149 | int dist = lineIdx-funcLineNo; 150 | if((bestFitDist > dist || bestFitIdx == -1) && dist >= 0) 151 | { 152 | bestFitDist = dist; 153 | bestFitIdx = u; 154 | } 155 | } 156 | 157 | if(m_ui.comboBox_funcList->count() > 0) 158 | { 159 | 160 | if(bestFitIdx == -1) 161 | { 162 | //m_ui.comboBox_funcList->hide(); 163 | } 164 | else 165 | { 166 | m_ui.comboBox_funcList->show(); 167 | m_ui.comboBox_funcList->setCurrentIndex(bestFitIdx); 168 | } 169 | 170 | } 171 | 172 | // Select the function in the function combobox 173 | int comboBoxIdx = m_ui.comboBox_funcList->findData(QVariant(lineIdx)); 174 | if(comboBoxIdx >= 0) 175 | { 176 | if(m_ui.comboBox_funcList->currentIndex() != comboBoxIdx) 177 | { 178 | m_ui.comboBox_funcList->setCurrentIndex(comboBoxIdx); 179 | } 180 | } 181 | 182 | m_ui.scrollArea_codeView->ensureVisible(0, m_ui.codeView->getRowHeight()*lineIdx-1); 183 | m_ui.scrollArea_codeView->ensureVisible(0, m_ui.codeView->getRowHeight()*lineIdx-1); 184 | } 185 | 186 | void CodeViewTab::onFuncListItemActivated(int index) 187 | { 188 | 189 | int funcLineNo = m_ui.comboBox_funcList->itemData(index).toInt(); 190 | int lineIdx = funcLineNo-2; 191 | if(lineIdx < 0) 192 | lineIdx = 0; 193 | m_ui.scrollArea_codeView->verticalScrollBar()->setValue(m_ui.codeView->getRowHeight()*lineIdx); 194 | } 195 | 196 | void CodeViewTab::setBreakpoints(const QVector &numList) 197 | { 198 | m_ui.codeView->setBreakpoints(numList); 199 | m_ui.codeView->update(); 200 | } 201 | 202 | 203 | void CodeViewTab::setConfig(Settings *cfg) 204 | { 205 | m_cfg = cfg; 206 | m_ui.codeView->setConfig(cfg); 207 | 208 | fillInFunctions(m_tagList); 209 | 210 | } 211 | 212 | void CodeViewTab::disableCurrentLine() 213 | { 214 | m_ui.codeView->disableCurrentLine(); 215 | } 216 | 217 | void CodeViewTab::setCurrentLine(int currentLine) 218 | { 219 | m_ui.codeView->setCurrentLine(currentLine); 220 | } 221 | 222 | 223 | void CodeViewTab::setInterface(ICodeView *inf) 224 | { 225 | m_ui.codeView->setInterface(inf); 226 | } 227 | 228 | 229 | -------------------------------------------------------------------------------- /src/processlistdialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | //#define ENABLE_DEBUGMSG 10 | 11 | #include "processlistdialog.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "version.h" 23 | #include "util.h" 24 | #include "log.h" 25 | 26 | 27 | 28 | enum 29 | { 30 | COLUMN_PID = 0 31 | ,COLUMN_UID 32 | ,COLUMN_TIME 33 | ,COLUMN_CMDLINE 34 | }; 35 | 36 | 37 | ProcessListWidgetItem::ProcessListWidgetItem() 38 | { 39 | 40 | } 41 | ProcessListWidgetItem::ProcessListWidgetItem( const ProcessInfo &prc) 42 | : m_prc(prc) 43 | { 44 | setText(COLUMN_PID, QString::number(prc.pid)); 45 | setText(COLUMN_UID, QString::number(prc.uid)); 46 | int secs = prc.mtime.secsTo(QDateTime::currentDateTime()); 47 | QString dtStr; 48 | dtStr.sprintf("%02d:%02d", secs/3600, (secs/60)%60); 49 | setText(COLUMN_TIME, dtStr); 50 | setText(COLUMN_CMDLINE, prc.getCmdline()); 51 | 52 | } 53 | ProcessListWidgetItem::~ProcessListWidgetItem() 54 | { 55 | } 56 | 57 | bool ProcessListWidgetItem::operator<(const QTreeWidgetItem &other) const 58 | { 59 | QTreeWidget * tree = treeWidget (); 60 | const ProcessListWidgetItem* item1 = this; 61 | const ProcessListWidgetItem* item2 = (ProcessListWidgetItem*)&other; 62 | int column = tree ? tree->sortColumn() : 0; 63 | if(column == COLUMN_UID) 64 | return item1->m_prc.mtime < item2->m_prc.mtime; 65 | else 66 | return text(column) < other.text(column); 67 | } 68 | 69 | 70 | 71 | 72 | QByteArray fileToContent(QString filename) 73 | { 74 | QByteArray cnt; 75 | QFile f(filename); 76 | if(!f.open(QIODevice::ReadOnly)) 77 | { 78 | } 79 | else 80 | { 81 | cnt = f.readAll(); 82 | } 83 | return cnt; 84 | } 85 | 86 | 87 | QList getProcessListByUser(int ownerUid) 88 | { 89 | QList lst; 90 | 91 | QDir dir("/proc"); 92 | dir.setFilter(QDir::Dirs | QDir::Hidden | QDir::NoSymLinks); 93 | QFileInfoList list = dir.entryInfoList(); 94 | for (int i = 0; i < list.size(); ++i) 95 | { 96 | QFileInfo fileInfo = list.at(i); 97 | QString fileName = fileInfo.fileName(); 98 | if(fileName != ".." && fileName != ".") 99 | { 100 | QString procDirPath = "/proc/" + fileInfo.fileName(); 101 | QFileInfo s(procDirPath + "/status"); 102 | if(s.exists()) 103 | { 104 | const int pid = fileInfo.fileName().toInt(); 105 | 106 | struct stat buf; 107 | if(stat(qPrintable(procDirPath), &buf) == 0) 108 | { 109 | if(buf.st_uid == (unsigned int)ownerUid || ownerUid == -1) 110 | { 111 | ProcessInfo prc; 112 | prc.uid = buf.st_uid; 113 | prc.pid = pid; 114 | prc.mtime.setTime_t(buf.st_mtim.tv_sec); 115 | 116 | prc.cmdline = QString(fileToContent(procDirPath + "/cmdline")).trimmed(); 117 | 118 | lst.append(prc); 119 | } 120 | } 121 | 122 | } 123 | } 124 | } 125 | 126 | 127 | 128 | /* 129 | for(int u = 0;u < lst.size();u++) 130 | { 131 | ProcessInfo &prc = lst[u]; 132 | debugMsg("[%d/%d] PID:%d UID:%d CMDLINE='%s'", u+1, lst.size(), prc.pid, prc.uid, qPrintable(prc.cmdline)); 133 | } 134 | */ 135 | return lst; 136 | } 137 | 138 | 139 | 140 | QList getProcessListAllUsers() 141 | { 142 | return getProcessListByUser(-1); 143 | } 144 | 145 | QList getProcessListThisUser() 146 | { 147 | return getProcessListByUser(getuid()); 148 | } 149 | 150 | //--------------------------------------------------------------------------- 151 | // 152 | // 153 | // 154 | //--------------------------------------------------------------------------- 155 | 156 | 157 | ProcessListDialog::ProcessListDialog(QWidget *parent) 158 | : QDialog(parent) 159 | { 160 | 161 | m_ui.setupUi(this); 162 | 163 | m_ui.treeWidget->setColumnCount(4); 164 | m_ui.treeWidget->setColumnWidth(COLUMN_PID, 80); 165 | m_ui.treeWidget->setColumnWidth(COLUMN_UID, 80); 166 | m_ui.treeWidget->setColumnWidth(COLUMN_TIME, 80); 167 | 168 | QStringList names; 169 | names += "PID"; 170 | names += "UID"; 171 | names += "Time"; 172 | names += "Cmdline"; 173 | m_ui.treeWidget->setHeaderLabels(names); 174 | 175 | fillInList(); 176 | 177 | connect(m_ui.treeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int )),this,SLOT(onItemDoubleClicked(QTreeWidgetItem *, int ))); 178 | 179 | } 180 | 181 | 182 | void ProcessListDialog::onItemDoubleClicked(QTreeWidgetItem *item, int column) 183 | { 184 | Q_UNUSED(item); 185 | Q_UNUSED(column); 186 | return accept(); 187 | } 188 | 189 | /** 190 | * @brief Selects a specific PID in the PID list. 191 | */ 192 | void ProcessListDialog::selectPid(int pid) 193 | { 194 | QTreeWidget *treeWidget = m_ui.treeWidget; 195 | QString pidText = QString::number(pid); 196 | QList foundItem = treeWidget->findItems ( pidText , Qt::MatchExactly, COLUMN_PID ); 197 | if(!foundItem.empty()) 198 | { 199 | treeWidget->setCurrentItem( foundItem[0]); 200 | } 201 | } 202 | 203 | 204 | /** 205 | * @brief Returns the selected process PID 206 | */ 207 | int ProcessListDialog::getSelectedProcess() 208 | { 209 | QTreeWidget *treeWidget = m_ui.treeWidget; 210 | int pid = -1; 211 | 212 | // No items? 213 | if(treeWidget->topLevelItemCount() == -1) 214 | return pid; 215 | 216 | // Get the selected ones 217 | QList selectedItems = treeWidget->selectedItems(); 218 | if(selectedItems.size() == 0) 219 | { 220 | selectedItems.append(treeWidget->topLevelItem(0)); 221 | } 222 | 223 | if(!selectedItems.empty()) 224 | pid = selectedItems[0]->data(0, Qt::UserRole).toInt(); 225 | 226 | return pid; 227 | } 228 | 229 | /** 230 | * @brief Fill in the list of processes. 231 | */ 232 | void ProcessListDialog::fillInList() 233 | { 234 | m_ui.treeWidget->clear(); 235 | 236 | // Get a list of processes 237 | QList list = getProcessListThisUser(); 238 | 239 | // Display the list 240 | for(int pIdx = 0;pIdx < list.size();pIdx++) 241 | { 242 | ProcessInfo &prc = list[pIdx]; 243 | ProcessListWidgetItem *item; 244 | item = new ProcessListWidgetItem(prc); 245 | item->setData(0, Qt::UserRole, prc.getPid()); 246 | m_ui.treeWidget->addTopLevelItem(item); 247 | 248 | } 249 | 250 | // Set correct column width 251 | m_ui.treeWidget->resizeColumnToContents(COLUMN_PID); 252 | m_ui.treeWidget->resizeColumnToContents(COLUMN_UID); 253 | m_ui.treeWidget->resizeColumnToContents(COLUMN_TIME); 254 | m_ui.treeWidget->resizeColumnToContents(COLUMN_CMDLINE); 255 | 256 | // Sort list 257 | m_ui.treeWidget->sortItems(COLUMN_TIME, Qt::AscendingOrder); 258 | } 259 | 260 | 261 | 262 | -------------------------------------------------------------------------------- /src/mainwindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__MAINWINDOW_H 10 | #define FILE__MAINWINDOW_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "consolewidget.h" 19 | #include "ui_mainwindow.h" 20 | #include "core.h" 21 | #include "codeview.h" 22 | #include "settings.h" 23 | #include "tagscanner.h" 24 | #include "autovarctl.h" 25 | #include "watchvarctl.h" 26 | #include "codeviewtab.h" 27 | #include "tagmanager.h" 28 | #include "log.h" 29 | 30 | 31 | class FileInfo 32 | { 33 | public: 34 | QString m_name; //!< The name of the file (Eg: "main.c"). 35 | QString m_fullName; //!< The full path (Eg: "/a/dir/main.c"). 36 | }; 37 | 38 | #include "locator.h" 39 | 40 | 41 | class MainWindow : public QMainWindow, public ICore, public ICodeView, public ILogger 42 | { 43 | Q_OBJECT 44 | public: 45 | MainWindow(QWidget *parent); 46 | virtual ~MainWindow(); 47 | 48 | CodeViewTab* open(Location loc); 49 | CodeViewTab* open(QString filename); 50 | CodeViewTab* open(QString filename, int lineNo); 51 | 52 | public: 53 | void insertSourceFiles(); 54 | void setStatusLine(Settings &cfg); 55 | 56 | public: 57 | void ICore_onStopped(ICore::StopReason reason, QString path, int lineNo); 58 | void ICore_onLocalVarChanged(QStringList varNames); 59 | void ICore_onWatchVarChanged(VarWatch &watch); 60 | void ICore_onConsoleStream(QString text); 61 | void ICore_onBreakpointsChanged(); 62 | void ICore_onThreadListChanged(); 63 | void ICore_onCurrentThreadChanged(int threadId); 64 | void ICore_onStackFrameChange(QList stackFrameList); 65 | void ICore_onFrameVarReset(); 66 | void ICore_onFrameVarChanged(QString name, QString value); 67 | void ICore_onMessage(QString message); 68 | void ICore_onCurrentFrameChanged(int frameIdx); 69 | void ICore_onSignalReceived(QString sigtype); 70 | void ICore_onTargetOutput(QString msg); 71 | void ICore_onStateChanged(TargetState state); 72 | void ICore_onSourceFileListChanged(); 73 | 74 | void ICodeView_onRowDoubleClick(int lineNo); 75 | void ICodeView_onContextMenu(QPoint pos, int lineNo, QStringList text); 76 | void ICodeView_onContextMenuIncFile(QPoint pos, int lineNo, QString incFile); 77 | 78 | void ICore_onWatchVarChildAdded(VarWatch &watch); 79 | 80 | 81 | 82 | void ILogger_onWarnMsg(QString text); 83 | void ILogger_onErrorMsg(QString text); 84 | void ILogger_onInfoMsg(QString text); 85 | 86 | 87 | private: 88 | void showEvent(QShowEvent *); 89 | void closeEvent(QCloseEvent *e); 90 | 91 | void showWidgets(); 92 | void fillInFuncList(); 93 | void fillInClassList(); 94 | 95 | public: 96 | 97 | private: 98 | void setConfig(); 99 | 100 | void wrapSourceTree(QTreeWidget *treeWidget); 101 | 102 | QTreeWidgetItem *addTreeWidgetPath(QTreeWidget *treeWidget, QTreeWidgetItem *parent, QString path); 103 | void fillInStack(); 104 | 105 | bool eventFilter(QObject *obj, QEvent *event); 106 | void loadConfig(); 107 | QTreeWidgetItem *insertTreeWidgetItem( 108 | VarCtl::DispInfoMap *map, 109 | QString fullPath, 110 | QString name, 111 | QString value); 112 | void addVariableDataTree( 113 | QTreeWidget *treeWidget, 114 | VarCtl::DispInfoMap *map, 115 | QTreeWidgetItem *item, TreeNode *rootNode); 116 | 117 | CodeViewTab* createTab(QString filename); 118 | CodeViewTab* currentTab(); 119 | void updateCurrentLine(QString filename, int lineno); 120 | void onCurrentLineChanged(int lineno); 121 | void onCurrentLineDisabled(); 122 | void hideSearchBox(); 123 | 124 | 125 | public slots: 126 | void onFuncFilter_textChanged(const QString &text); 127 | void onFuncFilterClear(); 128 | void onFuncFilterCheckBoxStateChanged(int state); 129 | void onClassFilterCheckBoxStateChanged(int state); 130 | void onClassFilterClear(); 131 | void onClassFilter_textChanged(const QString &text); 132 | 133 | void onIncSearch_textChanged(const QString &text); 134 | void onFolderViewItemActivated ( QTreeWidgetItem * item, int column ); 135 | void onThreadWidgetSelectionChanged( ); 136 | void onStackWidgetSelectionChanged(); 137 | void onQuit(); 138 | void onNext(); 139 | void onStepIn(); 140 | void onStepOut(); 141 | void onAbout(); 142 | void onSearch(); 143 | void onSearchCheckBoxStateChanged(int state); 144 | void onSearchNext(); 145 | void onSearchPrev(); 146 | void onGoToLine(); 147 | void onGoToMain(); 148 | void onStop(); 149 | void onBreakpointsWidgetItemDoubleClicked(QTreeWidgetItem * item,int column); 150 | void onRun(); 151 | void onContinue(); 152 | void onCodeViewContextMenuAddWatch(); 153 | void onCodeViewContextMenuOpenFile(); 154 | void onCodeViewContextMenuShowDefinition(); 155 | void onCodeViewContextMenuShowCurrentLocation(); 156 | void onSettings(); 157 | void onCodeViewContextMenuToggleBreakpoint(); 158 | void onCodeViewTab_tabCloseRequested ( int index ); 159 | void onCodeViewTab_currentChanged( int tabIdx); 160 | void onCodeViewTab_launchContextMenu(const QPoint&); 161 | void onCodeViewTab_closeTabsToLeft(); 162 | void onCodeViewTab_closeOtherTabs(); 163 | void onCodeViewContextMenuJumpToLocation(); 164 | 165 | void onViewStack(); 166 | void onViewBreakpoints(); 167 | void onViewThreads(); 168 | void onViewWatch(); 169 | void onViewAutoVariables(); 170 | void onViewTargetOutput(); 171 | void onViewGedeOutput(); 172 | void onViewGdbOutput(); 173 | void onViewFileBrowser(); 174 | void onViewFuncFilter(); 175 | void onViewClassFilter(); 176 | void onDefaultViewSetup(); 177 | 178 | void onBreakpointsRemoveSelected(); 179 | void onBreakpointsRemoveAll(); 180 | void onBreakpointsGoTo(); 181 | void onBreakpointsWidgetContextMenu(const QPoint& pt); 182 | 183 | void onAllTagScansDone(); 184 | void onFuncWidgetItemSelected(QTreeWidgetItem * item, int column); 185 | void onClassWidgetItemSelected(QTreeWidgetItem * item, int column); 186 | 187 | 188 | void onNewInfoMsg(QString text); 189 | void onNewWarnMsg(QString text); 190 | void onNewErrorMsg(QString text); 191 | 192 | signals: 193 | void newInfoMsg(QString text); 194 | void newWarnMsg(QString text); 195 | void newErrorMsg(QString text); 196 | 197 | private: 198 | QByteArray m_gui_default_mainwindowState; 199 | QByteArray m_gui_default_mainwindowGeometry; 200 | QByteArray m_gui_default_splitter1State; 201 | QByteArray m_gui_default_splitter2State; 202 | QByteArray m_gui_default_splitter3State; 203 | QByteArray m_gui_default_splitter4State; 204 | 205 | private: 206 | Ui_MainWindow m_ui; 207 | QIcon m_fileIcon; 208 | QIcon m_folderIcon; 209 | QString m_currentFile; //!< The file which the program counter points to. 210 | int m_currentLine; //!< The linenumber (first=1) which the program counter points to. 211 | QList m_stackFrameList; 212 | QMenu m_popupMenu; 213 | QVector m_funcFilterText; //!< Filter for the function list. 214 | QVector m_classFilterText; //!< Filter for the class list. 215 | 216 | 217 | Settings m_cfg; 218 | TagManager m_tagManager; 219 | QList m_sourceFiles; 220 | QList m_tagList; // Current list of tags 221 | 222 | AutoVarCtl m_autoVarCtl; 223 | WatchVarCtl m_watchVarCtl; 224 | QFont m_outputFont; 225 | QFont m_gdbOutputFont; 226 | QFont m_gedeOutputFont; 227 | QLabel m_statusLineWidget; 228 | Locator m_locator; 229 | }; 230 | 231 | 232 | #endif 233 | 234 | 235 | -------------------------------------------------------------------------------- /src/util.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #include "util.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | 21 | 22 | /** 23 | * @brief Divides a path into a filename and a path. 24 | * 25 | * Example: dividePath("/dir/filename.ext") => "/dir", "filename.ext". 26 | */ 27 | void dividePath(QString fullPath, QString *filename, QString *folderPath) 28 | { 29 | int divPos = fullPath.lastIndexOf('/'); 30 | if(divPos> 0) 31 | { 32 | if(filename) 33 | *filename = fullPath.mid(divPos+1); 34 | if(folderPath) 35 | *folderPath = fullPath.left(divPos); 36 | } 37 | else 38 | { 39 | if(filename) 40 | *filename = fullPath; 41 | } 42 | } 43 | 44 | /** 45 | * @brief Returns the filename of a path. 46 | * 47 | * Example: getFilenamePart("/dir/filename.ext") => "filename.ext". 48 | */ 49 | QString getFilenamePart(QString fullPath) 50 | { 51 | QString filename; 52 | dividePath(fullPath, &filename, NULL); 53 | return filename; 54 | } 55 | 56 | 57 | /** 58 | * @brief Returns the extension of a file. 59 | * @return The extension including the dot (Eg: ".txt"). 60 | */ 61 | QString getExtensionPart(QString filename) 62 | { 63 | int idx = filename.lastIndexOf('.'); 64 | if(idx == -1) 65 | return QString(""); 66 | return filename.mid(idx); 67 | } 68 | 69 | 70 | 71 | long long stringToLongLong(const char* str) 72 | { 73 | unsigned long long num = 0; 74 | QString str2 = str; 75 | str2.replace('_', ""); 76 | num = str2.toLongLong(0,0); 77 | 78 | return num; 79 | } 80 | 81 | 82 | QString longLongToHexString(long long num) 83 | { 84 | QString newStr; 85 | QString str; 86 | str.sprintf("%llx", num); 87 | if(num != 0) 88 | { 89 | while(str.length()%4 != 0) 90 | str = "0" + str; 91 | 92 | 93 | for(int i = str.length()-1;i >= 0;i--) 94 | { 95 | newStr += str[str.length()-i-1]; 96 | if(i%4 == 0 && i != 0) 97 | newStr += "_"; 98 | } 99 | str = newStr; 100 | } 101 | return "0x" + str; 102 | } 103 | 104 | 105 | static QString priv_simplifySubPath(QString path) 106 | { 107 | QString out; 108 | 109 | if(path.startsWith('/')) 110 | return simplifyPath(path.mid(1)); 111 | if(path.startsWith("./")) 112 | return simplifyPath(path.mid(2)); 113 | 114 | QString first; 115 | QString rest; 116 | 117 | int piv = path.indexOf('/'); 118 | if(piv == -1) 119 | return path; 120 | else 121 | { 122 | first = path.left(piv); 123 | rest = path.mid(piv+1); 124 | rest = priv_simplifySubPath(rest); 125 | if(rest.isEmpty()) 126 | path = first; 127 | else 128 | path = first + "/" + rest; 129 | } 130 | return path; 131 | } 132 | 133 | 134 | /** 135 | * @brief Simplifies a path by removing unnecessary seperators. 136 | * 137 | * Eg: simplifyPath("./a///path/") => "./a/path". 138 | */ 139 | QString simplifyPath(QString path) 140 | { 141 | QString out; 142 | if(path.startsWith("./")) 143 | out = "./" + priv_simplifySubPath(path.mid(2)); 144 | else if(path.startsWith('/')) 145 | out = '/' + priv_simplifySubPath(path.mid(1)); 146 | else 147 | out = priv_simplifySubPath(path); 148 | return out; 149 | } 150 | 151 | /** 152 | * @brief Converts a hex two byte string to a unsigned char. 153 | */ 154 | unsigned char hexStringToU8(const char *str) 155 | { 156 | unsigned char d = 0; 157 | char c1 = str[0]; 158 | char c2 = str[1]; 159 | 160 | // Upper byte 161 | if('0' <= c1 && c1 <= '9') 162 | d = c1-'0'; 163 | else if('a' <= c1 && c1 <= 'f') 164 | d = 0xa + (c1-'a'); 165 | else if('A' <= c1 && c1 <= 'F') 166 | d = 0xa + (c1-'A'); 167 | else // invalid character 168 | { 169 | assert(0); 170 | return 0; 171 | } 172 | d = d<<4; 173 | 174 | // Lower byte 175 | if('0' <= c2 && c2 <= '9') 176 | d += c2-'0'; 177 | else if('a' <= c2 && c2 <= 'f') 178 | d += 0xa + (c2-'a'); 179 | else if('A' <= c2 && c2 <= 'F') 180 | d += 0xa + (c2-'A'); 181 | else // invalid character? 182 | { 183 | assert(0); 184 | d = d>>4; 185 | } 186 | 187 | return d; 188 | } 189 | 190 | long long stringToLongLong(QString str) 191 | { 192 | return stringToLongLong(stringToCStr(str)); 193 | } 194 | 195 | 196 | /** 197 | * @brief Tries to detect the distro the system is running on. 198 | */ 199 | void detectDistro(DistroType *type, QString *distroDesc) 200 | { 201 | QString machine = ""; 202 | QString distroName = ""; 203 | 204 | distroName = "Unknown OS"; 205 | if(type) 206 | *type = DISTRO_UNKNOWN; 207 | 208 | // Check for Debian 209 | QFile file1("/etc/debian_version"); 210 | if(file1.open(QIODevice::ReadOnly)) 211 | { 212 | if(type) 213 | *type = DISTRO_DEBIAN; 214 | 215 | QString version = file1.readLine().trimmed(); 216 | distroName = "Debian " + version; 217 | } 218 | 219 | // Parse lsb-release file 220 | QFile file2("/etc/lsb-release"); 221 | if(file2.open(QIODevice::ReadOnly)) 222 | { 223 | QMap fields; 224 | // Parse ini-like structure 225 | while (!file2.atEnd()) 226 | { 227 | QString line = file2.readLine().trimmed(); 228 | QStringList tokens = line.split("="); 229 | if(tokens.size() == 2) 230 | { 231 | QString name = tokens[0].trimmed(); 232 | QString data = tokens[1].trimmed(); 233 | if(data.startsWith('"')) 234 | data = data.mid(1, data.length()-2); 235 | fields[name] = data; 236 | 237 | 238 | } 239 | 240 | } 241 | 242 | if(fields.contains("DISTRIB_ID")) 243 | { 244 | QString distribId = fields["DISTRIB_ID"]; 245 | if(type) 246 | { 247 | if(distribId == "Ubuntu") 248 | *type = DISTRO_UBUNTU; 249 | } 250 | distroName = distribId; 251 | if(fields.contains("DISTRIB_RELEASE")) 252 | distroName += " " + fields["DISTRIB_RELEASE"]; 253 | } 254 | if(fields.contains("DISTRIB_DESCRIPTION")) 255 | distroName = fields["DISTRIB_DESCRIPTION"]; 256 | 257 | } 258 | 259 | 260 | // Detect x64/x86 261 | QString versionStr; 262 | QProcess process; 263 | process.start("uname", 264 | QStringList("-m"), 265 | QIODevice::ReadOnly | QIODevice::Text); 266 | if(!process.waitForFinished(2000)) 267 | { 268 | } 269 | else 270 | { 271 | machine = process.readAllStandardOutput().trimmed(); 272 | } 273 | 274 | 275 | if(distroDesc) 276 | { 277 | *distroDesc = distroName; 278 | if(!machine.isEmpty()) 279 | *distroDesc += " " + machine; 280 | } 281 | } 282 | 283 | 284 | /** 285 | * @brief Returns a string describing an address (eg: "0x3000_1234"). 286 | */ 287 | QString addrToString(quint64 addr) 288 | { 289 | QString valueText; 290 | QString text; 291 | text.sprintf("%llx", (unsigned long long) addr); 292 | 293 | // Prefix the string with suitable number of zeroes 294 | while(text.length()%4 != 0 && text.length() > 4) 295 | text = "0" + text; 296 | if(text.length()%2 != 0) 297 | text = "0" + text; 298 | 299 | for(int i = 0;i < text.length();i++) 300 | { 301 | valueText = valueText + text[i]; 302 | if(i%4 == 3 && i+1 != text.length()) 303 | valueText += "_"; 304 | } 305 | valueText = "0x" + valueText; 306 | return valueText; 307 | } 308 | 309 | /** 310 | * @brief Checks if an executable exist in the PATH (or in current directory) 311 | * @param name Name of executable (Eg: "cp"). 312 | * @return true if the exe exists 313 | */ 314 | bool exeExists(QString name, bool checkCurrentDir) 315 | { 316 | QStringList pathList; 317 | 318 | // 319 | const char *pathStr = getenv("PATH"); 320 | if(pathStr) 321 | pathList = QString(pathStr).split(":"); 322 | 323 | if(checkCurrentDir) 324 | { 325 | pathList.append("./"); 326 | } 327 | 328 | for(int i = 0;i < pathList.size();i++) 329 | { 330 | QString exePath = pathList[i]; 331 | 332 | QDir dir(exePath); 333 | dir.setFilter(QDir::Files | QDir::Executable); 334 | if(dir.exists(name)) 335 | return true; 336 | } 337 | return false; 338 | } 339 | 340 | 341 | #ifdef NEVER 342 | void testFuncs() 343 | { 344 | printf("%12x -> '%s'\n", 0, stringToCStr(longLongToHexString(0))); 345 | printf("%12x -> '%s'\n", 0x1, stringToCStr(longLongToHexString(0x1))); 346 | printf("%12x -> '%s'\n", 0x123, stringToCStr(longLongToHexString(0x123))); 347 | printf("%12x -> '%s'\n", 0x1234, stringToCStr(longLongToHexString(0x1234))); 348 | printf("%12x -> '%s'\n", 0x1234567, stringToCStr(longLongToHexString(0x1234567))); 349 | printf("%12llx -> '%s'\n", 0x12345678ULL, stringToCStr(longLongToHexString(0x12345678ULL))); 350 | printf("%12llx -> '%s'\n", 0x123456789abcULL, stringToCStr(longLongToHexString(0x123456789abcULL))); 351 | } 352 | #endif 353 | 354 | -------------------------------------------------------------------------------- /src/tagscanner.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #include "tagscanner.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "config.h" 16 | #include "log.h" 17 | #include "util.h" 18 | #include "rusttagscanner.h" 19 | #include "adatagscanner.h" 20 | 21 | 22 | static bool g_ctagsExist = true; 23 | static bool g_doneCtagCheck = false; 24 | static QString g_ctagsCmd; //!< Name of executable 25 | 26 | 27 | Tag::Tag() 28 | : m_lineNo(0) 29 | { 30 | } 31 | 32 | 33 | QString Tag::getLongName() const 34 | { 35 | QString longName; 36 | if(m_className.isEmpty()) 37 | longName = m_name; 38 | else 39 | longName = m_className + "::" + m_name; 40 | longName += m_signature; 41 | return longName; 42 | } 43 | 44 | 45 | void Tag::dump() const 46 | { 47 | qDebug() << "/------------"; 48 | qDebug() << "Name: " << m_name; 49 | qDebug() << "Class: " << m_className; 50 | qDebug() << "Filepath: " << m_filepath; 51 | if(TAG_VARIABLE == m_type) 52 | qDebug() << "Type: " << " variable"; 53 | else if(TAG_FUNC == m_type) 54 | qDebug() << "Type: " << " function"; 55 | 56 | 57 | qDebug() << "Sig: " << m_signature; 58 | qDebug() << "Line: " << m_lineNo; 59 | qDebug() << "\\------------"; 60 | 61 | } 62 | 63 | /** 64 | *------------------------------------------------------------- 65 | * 66 | * 67 | * 68 | * 69 | * 70 | * 71 | *------------------------------------------------------------- 72 | */ 73 | 74 | TagScanner::TagScanner() 75 | : m_cfg(0) 76 | { 77 | 78 | } 79 | 80 | void TagScanner::checkForCtags() 81 | { 82 | // Only do check once 83 | if(g_doneCtagCheck) 84 | return; 85 | g_doneCtagCheck = true; 86 | 87 | // Check which executable to use 88 | g_ctagsExist = true; 89 | if(exeExists(ETAGS_CMD2)) 90 | g_ctagsCmd = ETAGS_CMD2; 91 | else if(exeExists(ETAGS_CMD1)) 92 | g_ctagsCmd = ETAGS_CMD1; 93 | else 94 | g_ctagsExist = false; 95 | 96 | // Found a executable? 97 | if(!g_ctagsExist) 98 | { 99 | QString msg; 100 | 101 | msg.sprintf("Failed to start program '%s/%s'\n", ETAGS_CMD1, ETAGS_CMD2); 102 | msg += "ctags can be installed on ubuntu/debian using command:\n"; 103 | msg += "\n"; 104 | msg += " apt-get install exuberant-ctags"; 105 | 106 | QMessageBox::warning(NULL, 107 | "Failed to start ctags", 108 | msg); 109 | 110 | } 111 | else 112 | { 113 | // Check if ctags can startup? 114 | QStringList argList; 115 | argList.push_back("--version"); 116 | QByteArray stdoutContent; 117 | int n = execProgram(g_ctagsCmd, argList, &stdoutContent, NULL); 118 | QStringList outputList = QString(stdoutContent).split('\n'); 119 | for(int u = 0;u < outputList.size();u++) 120 | { 121 | debugMsg("ETAGS: %s", stringToCStr(outputList[u])); 122 | } 123 | if(n) 124 | { 125 | QString msg; 126 | 127 | msg.sprintf("Failed to start program '%s'\n", qPrintable(g_ctagsCmd)); 128 | 129 | QMessageBox::warning(NULL, 130 | "Failed to start ctags", 131 | msg); 132 | g_ctagsExist = false; 133 | } 134 | else 135 | { 136 | infoMsg("Found ctags ('%s')", qPrintable(g_ctagsCmd)); 137 | g_ctagsExist = true; 138 | } 139 | } 140 | 141 | } 142 | 143 | TagScanner::~TagScanner() 144 | { 145 | 146 | } 147 | 148 | int TagScanner::execProgram(QString name, QStringList argList, 149 | QByteArray *stdoutContent, 150 | QByteArray *stderrContent) 151 | { 152 | 153 | int n = -1; 154 | QProcess proc; 155 | 156 | proc.start(name, argList, QProcess::ReadWrite); 157 | 158 | if(!proc.waitForStarted()) 159 | { 160 | return -1; 161 | } 162 | proc.waitForFinished(); 163 | 164 | if(stdoutContent) 165 | *stdoutContent = proc.readAllStandardOutput(); 166 | 167 | // Get standard output 168 | if(stderrContent) 169 | *stderrContent = proc.readAllStandardError(); 170 | 171 | n = proc.exitCode(); 172 | return n; 173 | 174 | 175 | } 176 | 177 | 178 | void TagScanner::init(Settings *cfg) 179 | { 180 | m_cfg = cfg; 181 | 182 | checkForCtags(); 183 | 184 | } 185 | 186 | 187 | /** 188 | * @brief Scans a sourcefile for tags. 189 | */ 190 | int TagScanner::scan(QString filepath, QList *taglist) 191 | { 192 | 193 | // Rust file? 194 | QString extension = getExtensionPart(filepath); 195 | if(extension.toLower() == RUST_FILE_EXTENSION) 196 | { 197 | RustTagScanner rs; 198 | rs.setConfig(m_cfg); 199 | return rs.scan(filepath, taglist); 200 | } 201 | if(extension.toLower() == ADA_FILE_EXTENSION) 202 | { 203 | AdaTagScanner rs; 204 | rs.setConfig(m_cfg); 205 | return rs.scan(filepath, taglist); 206 | } 207 | 208 | 209 | 210 | if(!g_ctagsExist) 211 | return 0; 212 | 213 | QString etagsCmd; 214 | etagsCmd = ETAGS_ARGS; 215 | etagsCmd += " "; 216 | etagsCmd += filepath; 217 | QString name = g_ctagsCmd; 218 | QStringList argList; 219 | argList = etagsCmd.split(' ', QString::SkipEmptyParts); 220 | 221 | QByteArray stdoutContent; 222 | QByteArray stderrContent; 223 | int rc = execProgram(g_ctagsCmd, argList, 224 | &stdoutContent, 225 | &stderrContent); 226 | 227 | parseOutput(stdoutContent, taglist); 228 | 229 | // Display stderr 230 | QString all = stderrContent; 231 | if(!all.isEmpty()) 232 | { 233 | QStringList outputList = all.split('\n', QString::SkipEmptyParts); 234 | for(int r = 0;r < outputList.size();r++) 235 | { 236 | QString text = outputList[r]; 237 | if(text.contains("Warning")) 238 | warnMsg("%s", stringToCStr(text)); 239 | else 240 | errorMsg("%s", stringToCStr(text)); 241 | } 242 | } 243 | 244 | return rc; 245 | } 246 | 247 | int TagScanner::parseOutput(QByteArray output, QList *taglist) 248 | { 249 | int n = 0; 250 | QList rowList = output.split('\n'); 251 | 252 | /* 253 | for(int rowIdx = 0;rowIdx < rowList.size();rowIdx++) 254 | { 255 | qDebug() << rowList[rowIdx]; 256 | } 257 | */ 258 | 259 | for(int rowIdx = 0;rowIdx < rowList.size();rowIdx++) 260 | { 261 | QByteArray row = rowList[rowIdx]; 262 | if(!row.isEmpty()) 263 | { 264 | QList colList = row.split('\t'); 265 | 266 | if(colList.size() < 5) 267 | { 268 | 269 | errorMsg("Failed to parse output from ctags (%d)", colList.size()); 270 | } 271 | else 272 | { 273 | 274 | Tag tag; 275 | 276 | tag.m_name = colList[0]; 277 | tag.m_filepath = colList[1]; 278 | QString type = colList[3]; 279 | if(type == "v") // v = variable 280 | tag.m_type = Tag::TAG_VARIABLE; 281 | else if(type == "f") // f = function 282 | { 283 | tag.m_type = Tag::TAG_FUNC; 284 | tag.setSignature("()"); 285 | } 286 | else if(type == "s") // s = subroutine? 287 | { 288 | tag.m_type = Tag::TAG_FUNC; 289 | tag.setSignature("()"); 290 | } 291 | else if(type == "p") // p = program? 292 | { 293 | tag.m_type = Tag::TAG_FUNC; 294 | tag.setSignature("()"); 295 | } 296 | else 297 | { 298 | tag.m_type = Tag::TAG_VARIABLE; 299 | //debugMsg("Unknown type (%s) returned from ctags", stringToCStr(type)); 300 | } 301 | for(int colIdx = 4;colIdx < colList.size();colIdx++) 302 | { 303 | QString field = colList[colIdx]; 304 | int div = field.indexOf(':'); 305 | if(div == -1) 306 | errorMsg("Failed to parse output from ctags (%d)", colList.size()); 307 | else 308 | { 309 | QString fieldName = field.left(div); 310 | QString fieldData = field.mid(div+1); 311 | // qDebug() << '|' << fieldName << '|' << fieldData << '|'; 312 | 313 | if(fieldName == "class") 314 | tag.m_className = fieldData; 315 | if(fieldName == "signature") 316 | { 317 | tag.setSignature(fieldData); 318 | } 319 | else if(fieldName == "line") 320 | tag.setLineNo(fieldData.toInt()); 321 | } 322 | } 323 | 324 | taglist->push_back(tag); 325 | } 326 | } 327 | } 328 | 329 | return n; 330 | } 331 | 332 | 333 | void TagScanner::dump(const QList &taglist) 334 | { 335 | for(int i = 0;i < taglist.size();i++) 336 | { 337 | const Tag &tag = taglist[i]; 338 | tag.dump(); 339 | } 340 | } 341 | 342 | 343 | 344 | 345 | -------------------------------------------------------------------------------- /src/core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2017 Johan Henriksson. 3 | * All rights reserved. 4 | * 5 | * This software may be modified and distributed under the terms 6 | * of the BSD license. See the LICENSE file for details. 7 | */ 8 | 9 | #ifndef FILE__CORE_H 10 | #define FILE__CORE_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "com.h" 20 | #include "settings.h" 21 | 22 | 23 | class Core; 24 | 25 | struct ThreadInfo 26 | { 27 | int m_id; //!< The numeric id assigned to the thread by GDB. 28 | QString m_name; //!< Target-specific string identifying the thread. 29 | 30 | QString m_func; //!< The name of the function (Eg: "func"). 31 | QString m_details; //!< Additional information about the thread provided by the target. 32 | }; 33 | 34 | 35 | struct StackFrameEntry 36 | { 37 | public: 38 | QString m_functionName; //!< Eg: "main". 39 | int m_line; //!< The line number. Eg: 1. 40 | QString m_sourcePath; //!< The full path of the source file. Eg: "/test/file.c". 41 | }; 42 | 43 | 44 | class SourceFile 45 | { 46 | public: 47 | QString m_name; 48 | QString m_fullName; 49 | }; 50 | 51 | /** 52 | * @brief A breakpoint. 53 | */ 54 | class BreakPoint 55 | { 56 | public: 57 | BreakPoint(int number) : m_number(number) { }; 58 | 59 | public: 60 | int m_number; 61 | QString m_fullname; 62 | int m_lineNo; 63 | QString m_funcName; 64 | unsigned long long m_addr; 65 | 66 | private: 67 | BreakPoint(){}; 68 | }; 69 | 70 | 71 | /** 72 | * @brief The value of a variable. 73 | */ 74 | class CoreVar 75 | { 76 | public: 77 | CoreVar(); 78 | CoreVar(QString name); 79 | virtual ~CoreVar(); 80 | 81 | typedef enum { FMT_HEX = 1, FMT_DEC, FMT_BIN, FMT_CHAR, FMT_NATIVE } DispFormat; 82 | typedef enum { TYPE_HEX_INT = 1, TYPE_DEC_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ENUM, TYPE_ERROR_MSG, TYPE_CHAR, TYPE_UNKNOWN } 83 | Type; 84 | 85 | QString getName() const { return m_name; }; 86 | QString getData(DispFormat fmt) const; 87 | 88 | void setVarType(QString varType) { m_varType = varType; }; 89 | QString getVarType() { return m_varType; }; 90 | void setData(Type type, QVariant data); 91 | quint64 getPointerAddress(); 92 | void setPointerAddress(quint64 addr) { m_addressValid = true; m_address = addr; }; 93 | bool hasPointerAddress() { return m_addressValid; }; 94 | 95 | bool hasChildren() { return m_hasChildren; }; 96 | 97 | void valueFromGdbString(QString data); 98 | 99 | private: 100 | void clear(); 101 | 102 | 103 | private: 104 | 105 | QString m_name; 106 | QVariant m_data; 107 | quint64 m_address; //!< The address of data the variable points to. 108 | Type m_type; 109 | QString m_varType; 110 | bool m_hasChildren; 111 | bool m_addressValid; 112 | }; 113 | 114 | 115 | class VarWatch 116 | { 117 | public: 118 | VarWatch(); 119 | VarWatch(QString watchId_, QString name_); 120 | 121 | QString getName() { return m_name; }; 122 | QString getWatchId() { return m_watchId; }; 123 | 124 | bool hasChildren(); 125 | bool inScope() { return m_inScope;}; 126 | QString getVarType() { return m_varType; }; 127 | QString getValue(CoreVar::DispFormat fmt = CoreVar::FMT_NATIVE) { return m_var.getData(fmt); }; 128 | 129 | void setValue(QString value); 130 | long long getPointerAddress() { return m_var.getPointerAddress(); }; 131 | bool hasPointerAddress() { return m_var.hasPointerAddress(); }; 132 | 133 | private: 134 | 135 | QString m_watchId; 136 | QString m_name; 137 | bool m_inScope; 138 | CoreVar m_var; 139 | QString m_varType; 140 | bool m_hasChildren; 141 | 142 | QString m_parentWatchId; 143 | 144 | friend Core; 145 | }; 146 | 147 | 148 | 149 | class ICore 150 | { 151 | public: 152 | 153 | enum TargetState 154 | { 155 | TARGET_STOPPED, 156 | TARGET_STARTING, 157 | TARGET_RUNNING, 158 | TARGET_FINISHED 159 | }; 160 | 161 | enum StopReason 162 | { 163 | UNKNOWN, 164 | END_STEPPING_RANGE, 165 | BREAKPOINT_HIT, 166 | SIGNAL_RECEIVED, 167 | EXITED_NORMALLY, 168 | FUNCTION_FINISHED, 169 | EXITED 170 | }; 171 | 172 | virtual void ICore_onStopped(StopReason reason, QString path, int lineNo) = 0; 173 | virtual void ICore_onStateChanged(TargetState state) = 0; 174 | virtual void ICore_onSignalReceived(QString signalName) = 0; 175 | virtual void ICore_onLocalVarChanged(QStringList varNames) = 0; 176 | virtual void ICore_onFrameVarReset() = 0; 177 | virtual void ICore_onFrameVarChanged(QString name, QString value) = 0; 178 | virtual void ICore_onWatchVarChanged(VarWatch &watch) = 0; 179 | virtual void ICore_onConsoleStream(QString text) = 0; 180 | virtual void ICore_onBreakpointsChanged() = 0; 181 | virtual void ICore_onThreadListChanged() = 0; 182 | virtual void ICore_onCurrentThreadChanged(int threadId) = 0; 183 | virtual void ICore_onStackFrameChange(QList stackFrameList) = 0; 184 | virtual void ICore_onMessage(QString message) = 0; 185 | virtual void ICore_onTargetOutput(QString message) = 0; 186 | virtual void ICore_onCurrentFrameChanged(int frameIdx) = 0; 187 | virtual void ICore_onSourceFileListChanged() = 0; 188 | 189 | /** 190 | * @brief Called when a new child item has been added for a watched item. 191 | * @param watchId The watchId of the new child. 192 | * @param name The name of the child. 193 | * @param valueString The value of the child. 194 | */ 195 | virtual void ICore_onWatchVarChildAdded(VarWatch &watch) = 0; 196 | 197 | }; 198 | 199 | 200 | 201 | 202 | 203 | class Core : public GdbComListener 204 | { 205 | private: 206 | Q_OBJECT 207 | 208 | private: 209 | 210 | Core(); 211 | ~Core(); 212 | 213 | public: 214 | 215 | 216 | static Core& getInstance(); 217 | int initPid(Settings *cfg, QString gdbPath, QString programPath, int pid); 218 | int initLocal(Settings *cfg, QString gdbPath, QString programPath, QStringList argumentList); 219 | int initCoreDump(Settings *cfg, QString gdbPath, QString programPath, QString coreDumpFile); 220 | int initRemote(Settings *cfg, QString gdbPath, QString programPath, QString tcpHost, int tcpPort); 221 | int evaluateExpression(QString expr, QString *data); 222 | 223 | void setListener(ICore *inf) { m_inf = inf; }; 224 | 225 | 226 | private: 227 | 228 | void onNotifyAsyncOut(Tree &tree, AsyncClass ac); 229 | void onExecAsyncOut(Tree &tree, AsyncClass ac); 230 | void onResult(Tree &tree); 231 | void onStatusAsyncOut(Tree &tree, AsyncClass ac); 232 | void onConsoleStreamOutput(QString str); 233 | void onTargetStreamOutput(QString str); 234 | void onLogStreamOutput(QString str); 235 | 236 | void dispatchBreakpointDeleted(int id); 237 | void dispatchBreakpointTree(Tree &tree); 238 | static ICore::StopReason parseReasonString(QString string); 239 | void detectMemoryDepth(); 240 | static int openPseudoTerminal(); 241 | void ensureStopped(); 242 | int runInitCommands(Settings *cfg); 243 | 244 | public: 245 | int gdbSetBreakpointAtFunc(QString func); 246 | void gdbNext(); 247 | void gdbStepIn(); 248 | void gdbStepOut(); 249 | void gdbContinue(); 250 | void gdbRun(); 251 | bool gdbGetFiles(); 252 | 253 | int getMemoryDepth(); 254 | 255 | int changeWatchVariable(QString variable, QString newValue); 256 | 257 | QStringList getLocalVars() { return m_localVars; }; 258 | 259 | quint64 getAddress(VarWatch &w); 260 | 261 | 262 | int jump(QString filename, int lineNo); 263 | 264 | int gdbSetBreakpoint(QString filename, int lineNo); 265 | void gdbGetThreadList(); 266 | void getStackFrames(); 267 | void stop(); 268 | int gdbExpandVarWatchChildren(QString watchId); 269 | int gdbGetMemory(quint64 addr, size_t count, QByteArray *data); 270 | 271 | void selectThread(int threadId); 272 | void selectFrame(int selectedFrameIdx); 273 | 274 | // Breakpoints 275 | QList getBreakPoints() { return m_breakpoints; }; 276 | BreakPoint* findBreakPoint(QString fullPath, int lineNo); 277 | BreakPoint* findBreakPointByNumber(int number); 278 | void gdbRemoveBreakpoint(BreakPoint* bkpt); 279 | void gdbRemoveAllBreakpoints(); 280 | 281 | QList getThreadList(); 282 | 283 | // Watch 284 | VarWatch *getVarWatchInfo(QString watchId); 285 | QList getWatchChildren(VarWatch &watch); 286 | int gdbAddVarWatch(QString varName, VarWatch **watchPtr); 287 | void gdbRemoveVarWatch(QString watchId); 288 | QString gdbGetVarWatchName(QString watchId); 289 | 290 | 291 | QVector getSourceFiles() { return m_sourceFiles; }; 292 | 293 | void writeTargetStdin(QString text); 294 | 295 | bool isRunning(); 296 | 297 | private slots: 298 | void onGdbOutput(int socketNr); 299 | 300 | private: 301 | ICore *m_inf; 302 | QList m_breakpoints; 303 | QVector m_sourceFiles; 304 | QMap m_threadList; 305 | int m_selectedThreadId; 306 | ICore::TargetState m_targetState; 307 | ICore::TargetState m_lastTargetState; 308 | int m_pid; 309 | int m_currentFrameIdx; 310 | QList m_watchList; 311 | int m_varWatchLastId; 312 | bool m_isRemote; //!< True if "remote target" or false if it is a "local target". 313 | int m_ptsFd; 314 | bool m_scanSources; //!< True if the source filelist may have changed 315 | QSocketNotifier *m_ptsListener; 316 | 317 | QStringList m_localVars; 318 | int m_memDepth; //!< The memory depth. (Either 64 or 32). 319 | }; 320 | 321 | 322 | #endif // FILE__CORE_H 323 | --------------------------------------------------------------------------------