├── .appveyor.yml
├── .github
└── workflows
│ ├── cppcheck.yml
│ └── main.yml
├── .gitignore
├── .travis.yml
├── CMakeLists.txt
├── Doxyfile
├── LICENSE
├── README.md
├── bearparser.cppcheck
├── bearparser_autobuild.sh
├── build.sh
├── build_codelite.sh
├── build_qt4.sh
├── build_qt5.sh
├── build_qt6.sh
├── commander
├── CMakeLists.txt
├── Commander.cpp
├── Commander.h
├── ExeCommander.cpp
├── ExeCommander.h
├── PECommander.cpp
├── PECommander.h
└── main.cpp
├── parser
├── AbstractByteBuffer.cpp
├── ByteBuffer.cpp
├── CMakeLists.txt
├── ExeElementWrapper.cpp
├── ExeFactory.cpp
├── ExeNodeWrapper.cpp
├── Executable.cpp
├── FileBuffer.cpp
├── Formatter.cpp
├── MappedExe.cpp
├── Util.cpp
├── WrappedValue.cpp
├── include
│ └── bearparser
│ │ ├── AbstractByteBuffer.h
│ │ ├── ByteBuffer.h
│ │ ├── CustomException.h
│ │ ├── ExeElementWrapper.h
│ │ ├── ExeFactory.h
│ │ ├── ExeNodeWrapper.h
│ │ ├── Executable.h
│ │ ├── FileBuffer.h
│ │ ├── Formatter.h
│ │ ├── MappedExe.h
│ │ ├── Util.h
│ │ ├── WatchedLocker.h
│ │ ├── WrappedValue.h
│ │ ├── bearparser.h
│ │ ├── core.h
│ │ ├── pe.h
│ │ ├── pe
│ │ ├── BoundImpDirWrapper.h
│ │ ├── ClrDirWrapper.h
│ │ ├── CommonOrdinalsLookup.h
│ │ ├── DOSExe.h
│ │ ├── DataDirEntryWrapper.h
│ │ ├── DataDirWrapper.h
│ │ ├── DebugDirWrapper.h
│ │ ├── DelayImpDirWrapper.h
│ │ ├── DosHdrWrapper.h
│ │ ├── ExceptionDirWrapper.h
│ │ ├── ExportDirWrapper.h
│ │ ├── FileHdrWrapper.h
│ │ ├── ImportBaseDirWrapper.h
│ │ ├── ImportDirWrapper.h
│ │ ├── LdConfigDirWrapper.h
│ │ ├── OptHdrWrapper.h
│ │ ├── PECore.h
│ │ ├── PEFile.h
│ │ ├── PENodeWrapper.h
│ │ ├── RelocDirWrapper.h
│ │ ├── ResourceDirWrapper.h
│ │ ├── ResourceLeafWrapper.h
│ │ ├── RichHdrWrapper.h
│ │ ├── SectHdrsWrapper.h
│ │ ├── SecurityDirWrapper.h
│ │ ├── TlsDirWrapper.h
│ │ ├── lookup
│ │ │ ├── CommonOrdinalsMap.h
│ │ │ ├── CommonOrdinalsOleaut32.h
│ │ │ └── CommonOrdinalsWS2_32.h
│ │ ├── pe_formats.h
│ │ ├── pe_undoc.h
│ │ └── rsrc
│ │ │ ├── ResourceContentFactory.h
│ │ │ ├── ResourceContentWrapper.h
│ │ │ ├── ResourceStringsWrapper.h
│ │ │ ├── ResourceVersionWrapper.h
│ │ │ ├── ResourcesAlbum.h
│ │ │ └── pe_rsrc.h
│ │ └── win_hdrs
│ │ ├── poppack.h
│ │ ├── pshpack1.h
│ │ ├── pshpack2.h
│ │ ├── pshpack4.h
│ │ ├── pshpack8.h
│ │ └── win_types.h
└── pe
│ ├── BoundImpDirWrapper.cpp
│ ├── ClrDirWrapper.cpp
│ ├── DOSExe.cpp
│ ├── DataDirEntryWrapper.cpp
│ ├── DataDirWrapper.cpp
│ ├── DebugDirWrapper.cpp
│ ├── DelayImpDirWrapper.cpp
│ ├── DosHdrWrapper.cpp
│ ├── ExceptionDirWrapper.cpp
│ ├── ExportDirWrapper.cpp
│ ├── FileHdrWrapper.cpp
│ ├── ImportBaseDirWrapper.cpp
│ ├── ImportDirWrapper.cpp
│ ├── LdConfigDirWrapper.cpp
│ ├── OptHdrWrapper.cpp
│ ├── PECore.cpp
│ ├── PEFile.cpp
│ ├── PENodeWrapper.cpp
│ ├── RelocDirWrapper.cpp
│ ├── ResourceDirWrapper.cpp
│ ├── RichHdrWrapper.cpp
│ ├── SectHdrsWrapper.cpp
│ ├── SecurityDirWrapper.cpp
│ ├── TlsDirWrapper.cpp
│ └── rsrc
│ ├── ResourceContentFactory.cpp
│ ├── ResourceContentWrapper.cpp
│ ├── ResourceStringsWrapper.cpp
│ ├── ResourceVersionWrapper.cpp
│ └── ResourcesAlbum.cpp
├── test.sh
├── test_qt4.sh
└── tests_list.txt
/.appveyor.yml:
--------------------------------------------------------------------------------
1 | version: '{branch}.{build}'
2 | skip_tags: true
3 |
4 | image:
5 | - Visual Studio 2022
6 | - Visual Studio 2019
7 |
8 | matrix:
9 | exclude:
10 | - platform: x86
11 | image: Visual Studio 2022
12 | - platform: x64
13 | image: Visual Studio 2019
14 | - platform: x86
15 |
16 | platform:
17 | - x64
18 | - x86
19 |
20 | branches:
21 | only:
22 | - master
23 | build:
24 | verbosity: detailed
25 |
26 | configuration:
27 | - Release
28 |
29 | environment:
30 | artifactName: $(APPVEYOR_PROJECT_NAME)-$(APPVEYOR_REPO_COMMIT)-$(PLATFORM)
31 | buildPlatform: $(PLATFORM)
32 |
33 | for:
34 | -
35 | matrix:
36 | only:
37 | - image: Visual Studio 2022
38 | - image: Visual Studio 2019
39 |
40 | install:
41 | - git submodule update --init --recursive
42 | - if [%buildPlatform%]==[x64] (set QT_VER=6)
43 | - if [%buildPlatform%]==[x64] (set QT=C:\Qt\6.8\msvc2022_64)
44 | - if [%buildPlatform%]==[x86] (set QT_VER=5)
45 | - if [%buildPlatform%]==[x86] (set QT=C:\Qt\5.15.2\msvc2019)
46 | - set QT_DIR=%QT%
47 | - set PATH=%PATH%;%QT%\bin;%QT%\lib\cmake
48 |
49 | before_build:
50 | - mkdir build
51 | - cd build
52 |
53 | build_script:
54 | - if [%buildPlatform%]==[x64] ( cmake .. -A x64 )
55 | - if [%buildPlatform%]==[x86] ( cmake .. -A Win32 -DUSE_QT5=ON )
56 | - cmake --build . --config %CONFIGURATION%
57 |
58 | after_build:
59 | - mkdir %artifactName%
60 | - cp -r commander/%CONFIGURATION%/* %artifactName%
61 | - cp "%QT%\bin\Qt%QT_VER%Core.dll" %artifactName%
62 |
63 | artifacts:
64 | - path: build\%artifactName%
65 |
66 |
--------------------------------------------------------------------------------
/.github/workflows/cppcheck.yml:
--------------------------------------------------------------------------------
1 | name: Static analysis
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v4
10 |
11 | - name: Install Cppcheck
12 | run: |
13 | sudo apt update
14 | sudo apt --yes install cppcheck
15 |
16 | - name: Static analysis
17 | run: |
18 | cppcheck --project=bearparser.cppcheck --error-exitcode=1 --enable=warning
19 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
2 |
3 | name: Doxygen Action
4 |
5 | on: push
6 |
7 | permissions:
8 | contents: write
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v4
16 |
17 | - name: Doxygen Action
18 | uses: mattnotmitt/doxygen-action@v1.1.0
19 | with:
20 | doxyfile-path: "./Doxyfile" # default is ./Doxyfile
21 | working-directory: "." # default is .
22 |
23 | - name: Deploy
24 | uses: peaceiris/actions-gh-pages@v3
25 | with:
26 | github_token: ${{ secrets.GITHUB_TOKEN }}
27 | publish_dir: ./docs/html
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | build
3 | build_qt6/
4 | build_qt5/
5 | build_qt4/
6 | test_cases/
7 | docs/
8 | .vs/
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: cpp
2 |
3 | os:
4 | - linux
5 | # - osx
6 |
7 | compiler:
8 | - gcc
9 | - clang
10 |
11 | addons:
12 | apt:
13 | packages:
14 | - qt5-default
15 | - qt5-qmake
16 |
17 | before_install:
18 | - |
19 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then
20 | brew update-reset;
21 | brew upgrade cmake -v;
22 | brew install qt5;
23 | export PATH="/usr/local/opt/qt/bin:$PATH";
24 | export LDFLAGS="-L/usr/local/opt/qt/lib";
25 | export CPPFLAGS="-I/usr/local/opt/qt/include";
26 | export PKG_CONFIG_PATH="/usr/local/opt/qt/lib/pkgconfig";
27 | fi
28 |
29 | before_script:
30 | - cmake --version
31 | - qmake -v
32 | - mkdir build
33 | - cd build
34 |
35 | script:
36 | - cmake -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) ..
37 | - cmake --build . --target install
38 | - ctest -V
39 |
40 |
41 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 3.12)
2 | project (re-bear)
3 |
4 | option(CMD_BUILD_TESTING "Enable testing for bearcommander" ON)
5 |
6 | # modules:
7 | set ( M_BEARPARSER "parser" )
8 | set ( M_BEARCOMMANDER "commander" )
9 |
10 | option(USE_QT4 "Use Qt4" OFF )
11 | option(USE_QT5 "Use Qt5" OFF )
12 |
13 | # modules paths:
14 | set (BEARPARSER_INC "${M_BEARPARSER}/include")
15 |
16 | set (BEARPARSER_DIR "${CMAKE_SOURCE_DIR}/${M_BEARPARSER}" CACHE PATH "BearParser main path")
17 | set (COMMANDER_DIR "${CMAKE_SOURCE_DIR}/${M_BEARCOMMANDER}" CACHE PATH "BearCommander main path")
18 |
19 | # Add bearparser includes:
20 | include_directories( ${BEARPARSER_INC} )
21 |
22 | # Add sub-directories
23 | #
24 | # libs
25 |
26 | add_subdirectory ( ${M_BEARPARSER} )
27 | set (PARSER_LIB bearparser CACHE PATH "BearParser library path")
28 |
29 | # executables
30 | add_subdirectory( ${M_BEARCOMMANDER} )
31 |
32 | # dependencies
33 | add_dependencies(bearcommander bearparser)
34 |
35 | # Setup testing
36 | if(CMD_BUILD_TESTING)
37 | enable_testing()
38 |
39 | # 0) does the application run
40 | add_test (TestRuns ${CMAKE_BINARY_DIR}/bearcommander)
41 | set_tests_properties(TestRuns PROPERTIES PASS_REGULAR_EXPRESSION "Bearparser")
42 | IF (NOT WIN32)
43 | # 1) external tests
44 | add_test (TestExternal ${CMAKE_SOURCE_DIR}/test.sh ${CMAKE_SOURCE_DIR})
45 | set_tests_properties(TestExternal PROPERTIES PASS_REGULAR_EXPRESSION "All passed")
46 | ENDIF()
47 | endif()
48 |
49 |
50 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014-2025, hasherezade
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | bearparser
2 | ==========
3 | [](https://ci.appveyor.com/project/hasherezade/bearparser)
4 | [](https://app.codacy.com/gh/hasherezade/bearparser/dashboard?branch=master)
5 |
6 | Portable Executable parsing library
7 |
8 | Requires:
9 |
10 | + Qt6 SDK
11 | + Qt6 Core
12 | + cmake http://www.cmake.org/
13 |
14 | **Possible to build with older versions of QT (Qt4, Qt5) by setting an appropriate CMake flag: `USE_QT4` or `USE_QT5`**
15 |
16 | Example:
17 |
18 | ```
19 | cmake -G "Unix Makefiles" -D USE_QT4=ON ../
20 | ```
21 |
22 |
23 | ## Read more on Wiki:
24 |
25 | https://github.com/hasherezade/bearparser/wiki
26 |
27 | ## PE-bear
28 |
29 |
30 |
31 | Check also PE-bear - a GUI application using `bearparser`:
32 | + https://github.com/hasherezade/pe-bear
33 |
34 |
--------------------------------------------------------------------------------
/bearparser.cppcheck:
--------------------------------------------------------------------------------
1 |
2 |
3 | build/cppcheck
4 | false
5 | true
6 | true
7 | 10
8 | 100
9 |
10 |
11 |
12 |
13 |
14 | posix
15 | qt
16 | windows
17 |
18 |
19 | noExplicitConstructor
20 | useStlAlgorithm
21 | cstyleCast
22 | constVariablePointer
23 |
24 |
25 |
--------------------------------------------------------------------------------
/bearparser_autobuild.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo "Trying to autobuild bearparser..."
3 |
4 | git clone https://github.com/hasherezade/bearparser.git
5 | echo "[+] bearparser cloned"
6 | echo $$
7 | cd bearparser
8 | sh build.sh
9 |
10 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ./build_qt5.sh
4 |
--------------------------------------------------------------------------------
/build_codelite.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "Trying to build bearparser..."
4 |
5 | #QT check
6 |
7 | QT_VER=$(qmake -v)
8 | str="$QT_VER"
9 | substr="Qt version 6"
10 |
11 | echo $QT_VER
12 | if [[ $str == *"$substr"* ]]; then
13 | echo "[+] Qt6 found!"
14 | else
15 | str2=$(whereis qt6)
16 | substr2="/qt6"
17 | if [[ $str2 == *"$substr2"* ]]; then
18 | echo "[+] Qt6 found!"
19 | else
20 | echo "Install Qt6 SDK first"
21 | exit -1
22 | fi
23 | fi
24 |
25 | CMAKE_VER=$(cmake --version)
26 | CMAKEV="cmake version"
27 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then
28 | echo "[+] CMake found!"
29 | else
30 | echo "[-] CMake NOT found!"
31 | echo "Install cmake first"
32 | exit -1
33 | fi
34 | echo $CMAKE_VER
35 | mkdir build_qt6
36 | echo "[+] build directory created"
37 | cd build_qt6
38 | cmake -G"CodeLite - Unix Makefiles" -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) ..
39 | cmake --build . --target install
40 | make
41 | cd ..
42 |
43 |
--------------------------------------------------------------------------------
/build_qt4.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo "Trying to autobuild bearparser..."
3 |
4 | #QT check
5 |
6 | QT_VER=`qmake -v`
7 | str=$QT_VER
8 | substr="Qt version 4"
9 |
10 | echo $QT_VER
11 | if [[ $str == *"$substr"* ]]; then
12 | echo "[+] Qt4 found!"
13 | else
14 | str2=`whereis qt4`
15 | substr2="lib"
16 | if [[ $str2 == *"$substr2"* ]]; then
17 | echo "[+] Qt4 found!"
18 | else
19 | echo "Install Qt4 SDK first"
20 | exit -1
21 | fi
22 | fi
23 |
24 | CMAKE_VER=`cmake --version`
25 | CMAKEV="cmake version"
26 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then
27 | echo "[+] CMake found!"
28 | else
29 | echo "[-] CMake NOT found!"
30 | echo "Install cmake first"
31 | exit -1
32 | fi
33 |
34 | BUILD_DIR=build_qt4
35 | rm build
36 | mkdir $BUILD_DIR
37 | echo "[+] build directory created"
38 | ln -sf $BUILD_DIR build
39 | cd $BUILD_DIR
40 | cmake -G "CodeLite - Unix Makefiles" -DUSE_QT4=ON -DUSE_QT5=OFF -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) ..
41 | cmake --build . --target install
42 |
43 |
--------------------------------------------------------------------------------
/build_qt5.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo "Trying to autobuild bearparser..."
3 |
4 | #QT check
5 |
6 | QT_VER=`qmake -v`
7 | str=$QT_VER
8 | substr="Qt version 5"
9 |
10 | echo $QT_VER
11 | if [[ $str == *"$substr"* ]]; then
12 | echo "[+] Qt5 found!"
13 | else
14 | str2=`whereis qt5`
15 | substr2="/qt5"
16 | if [[ $str2 == *"$substr2"* ]]; then
17 | echo "[+] Qt5 found!"
18 | else
19 | echo "Install Qt5 SDK first"
20 | exit -1
21 | fi
22 | fi
23 |
24 | CMAKE_VER=`cmake --version`
25 | CMAKEV="cmake version"
26 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then
27 | echo "[+] CMake found!"
28 | else
29 | echo "[-] CMake NOT found!"
30 | echo "Install cmake first"
31 | exit -1
32 | fi
33 |
34 | BUILD_DIR=build_qt5
35 |
36 | rm build
37 | mkdir $BUILD_DIR
38 | echo "[+] build directory created"
39 | ln -sf $BUILD_DIR build
40 | cd $BUILD_DIR
41 | cmake -G "CodeLite - Unix Makefiles" -DUSE_QT4=OFF -DUSE_QT5=ON -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) ..
42 | cmake --build . --target install
43 |
44 |
--------------------------------------------------------------------------------
/build_qt6.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | echo "Trying to autobuild bearparser..."
3 |
4 | #QT check
5 |
6 | QT_VER=$(qmake -v)
7 | str=$QT_VER
8 | substr="Qt version 6"
9 |
10 | echo "$QT_VER"
11 | if [[ $str == *"$substr"* ]]; then
12 | echo "[+] Qt6 found!"
13 | else
14 | str2=$(whereis qt6)
15 | substr2="/qt6"
16 | if [[ $str2 == *"$substr2"* ]]; then
17 | echo "[+] Qt6 found!"
18 | else
19 | echo "Install Qt6 SDK first"
20 | exit -1
21 | fi
22 | fi
23 |
24 | CMAKE_VER=$(cmake --version)
25 | CMAKEV="cmake version"
26 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then
27 | echo "[+] CMake found!"
28 | else
29 | echo "[-] CMake NOT found!"
30 | echo "Install cmake first"
31 | exit -1
32 | fi
33 |
34 | BUILD_DIR=build_qt6
35 |
36 | rm build
37 | mkdir $BUILD_DIR
38 | echo "[+] build directory created"
39 | ln -sf $BUILD_DIR build
40 | cd $BUILD_DIR
41 | cmake -G "CodeLite - Unix Makefiles" -DUSE_QT4=OFF -DUSE_QT5=OFF -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) ..
42 | cmake --build . --target install
43 |
44 |
--------------------------------------------------------------------------------
/commander/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 3.12)
2 | project (bearcommander)
3 |
4 | if(USE_QT4)
5 | find_package (Qt4 REQUIRED)
6 | include_directories( ${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR} )
7 | INCLUDE( ${QT_USE_FILE} )
8 | ADD_DEFINITIONS( ${QT_DEFINITIONS} )
9 | else()
10 | find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
11 | find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
12 | get_target_property(QtCore_location Qt${QT_VERSION_MAJOR}::Core LOCATION)
13 | endif()
14 |
15 | set (imps_srcs
16 | main.cpp
17 | Commander.cpp
18 | ExeCommander.cpp
19 | PECommander.cpp
20 | )
21 |
22 | set (imps_hdrs
23 | Commander.h
24 | ExeCommander.h
25 | PECommander.h
26 | )
27 |
28 | add_executable (${PROJECT_NAME} ${imps_hdrs} ${imps_srcs} )
29 | target_link_libraries(${PROJECT_NAME} ${PARSER_LIB})
30 |
31 | if(USE_QT4)
32 | target_link_libraries (${PROJECT_NAME} ${QT_QTCORE_LIBRARIES} )
33 | else()
34 | target_link_libraries(${PROJECT_NAME} Qt${QT_VERSION_MAJOR}::Core)
35 | endif()
36 |
37 | #install
38 | INSTALL( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT ${PROJECT_NAME} )
39 |
40 |
--------------------------------------------------------------------------------
/commander/Commander.cpp:
--------------------------------------------------------------------------------
1 | #include "Commander.h"
2 | #include
3 | #include
4 |
5 | using namespace std;
6 |
7 | Commander::Commander(CmdContext *v_context)
8 | : context(v_context)
9 | {
10 | if (this->context == NULL) throw CmdException("Uninitialized commander context!");
11 | addCommand("q", new QuitCommand());
12 | }
13 |
14 | void Commander::clearCommands()
15 | {
16 | std::map::iterator itr;
17 | for (itr = cmds.begin(); itr != cmds.end(); ++itr) {
18 | Command* cmd = itr->second;
19 | delete cmd;
20 | }
21 | this->cmds.clear();
22 | }
23 |
24 | void Commander::printHelp()
25 | {
26 | std::cout << "Available commands: " << cmds.size() << endl;
27 | std::map::iterator itr;
28 | for (itr = cmds.begin(); itr != cmds.end(); ++itr) {
29 | Command *cmd = itr->second;
30 | if (cmd == NULL) continue;
31 | std::cout << itr->first << " \t- " << cmd->getDescription() << endl;
32 | }
33 | }
34 |
35 | Command* Commander::getCommand(const std::string& line)
36 | {
37 | std::string name = line;
38 | //TODO: split the line...
39 | if (cmds.find(name) == cmds.end() ) {
40 | std::cerr << "No such command" << endl;
41 | return NULL;
42 | }
43 |
44 | Command *cmd = this->cmds[name];
45 | return cmd;
46 | }
47 |
48 | bool Commander::addCommand(const std::string& name, Command *cmd, bool overwrite)
49 | {
50 | if ( cmds.find(name) != cmds.end() ) {
51 | if (!overwrite) return false; // already exist
52 | delete this->cmds[name];
53 | this->cmds[name] = NULL;
54 | }
55 | this->cmds[name] = cmd;
56 | return true;
57 | }
58 |
59 | void Commander::parseCommands()
60 | {
61 | const std::string PROMPT = "$ ";
62 |
63 | while (true) {
64 | if (this->context == NULL) throw CmdException("Uninitialized commander context!");
65 | if (this->context->isEndProcessing()) break;
66 |
67 | std::cout << PROMPT;
68 | std::string line;
69 | std::cin >> line;
70 |
71 | Command *cmd = getCommand(line);
72 |
73 | if (cmd == NULL) {
74 | this->printHelp();
75 | continue;
76 | }
77 | try {
78 | CmdParams *params = cmd->fetchParams(line);
79 | cmd->execute(params, this->context);
80 | } catch (CustomException &e) {
81 | std::cerr << "ERROR: " << e.what() << endl;
82 | }
83 | }
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/commander/Commander.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include