Skip to content

Commit

Permalink
pretty printer module
Browse files Browse the repository at this point in the history
  • Loading branch information
grisumbras committed Sep 9, 2024
1 parent 824cc59 commit 9faecfc
Show file tree
Hide file tree
Showing 5 changed files with 570 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/bin
/bin.v2
/bin64
/_build*
temp
Expand All @@ -19,3 +20,6 @@ temp
# local copy of bench
/bench/bench
/bench/bench.exe

# Python
__pycache__
118 changes: 118 additions & 0 deletions pretty_printers/FindBoostPrettyPrinters.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#
# Copyright (c) 2024 Dmitry Arkhipov ([email protected])
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# Official repository: https://github.com/boostorg/json
#

find_package(Python3 QUIET COMPONENTS Interpreter)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(BoostPrettyPrinters
REQUIRED_VARS Python3_Interpreter_FOUND)

find_program(BoostPrettyPrinters_GDB gdb DOC "GDB executable tos use")
set(BoostPrettyPrinters_HAS_GDB "${BoostPrettyPrinters_GDB}")

set(BoostPrettyPrinters_GDB_HEADER_SCRIPT
"${CMAKE_CURRENT_LIST_DIR}/generate-gdb-header.py")
set(BoostPrettyPrinters_GDB_TEST_SCRIPT
"${CMAKE_CURRENT_LIST_DIR}/generate-gdb-test-runner.py")
set(BoostPrettyPrinters_INCLUDES "${CMAKE_CURRENT_LIST_DIR}/include")

function(boost_pretty_printers_gdb_python_header)
set(options EXCLUDE_FROM_ALL)
set(oneValueArgs TARGET INPUT OUTPUT HEADER_GUARD DISABLE_MACRO)
set(multiValueArgs)
cmake_parse_arguments(BOOST_PPRINT_GDB_GEN
"${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
foreach(kw TARGET INPUT OUTPUT)
if(NOT DEFINED "BOOST_PPRINT_GDB_GEN_${kw}")
message(FATAL_ERROR "Argument ${kw} is required for function \
boost_pretty_printers_gdb_python_header.")
endif()
endforeach()

if(DEFINED BOOST_PPRINT_GDB_GEN_HEADER_GUARD)
set(BOOST_PPRINT_GDB_GEN_HEADER_GUARD
"--header-guard=${BOOST_PPRINT_GDB_GEN_HEADER_GUARD}")
endif()
if(DEFINED BOOST_PPRINT_GDB_GEN_DISABLE_MACRO)
set(BOOST_PPRINT_GDB_GEN_DISABLE_MACRO
"--disable-macro=${BOOST_PPRINT_GDB_GEN_DISABLE_MACRO}")
endif()
add_custom_command(
OUTPUT "${BOOST_PPRINT_GDB_GEN_OUTPUT}"
MAIN_DEPENDENCY "${BOOST_PPRINT_GDB_GEN_INPUT}"
DEPENDS "${BoostPrettyPrinters_GDB_HEADER_SCRIPT}"
COMMAND
"${Python3_EXECUTABLE}"
"${BoostPrettyPrinters_GDB_HEADER_SCRIPT}"
"${CMAKE_CURRENT_SOURCE_DIR}/${BOOST_PPRINT_GDB_GEN_INPUT}"
"${CMAKE_CURRENT_SOURCE_DIR}/${BOOST_PPRINT_GDB_GEN_OUTPUT}"
${BOOST_PPRINT_GDB_GEN_HEADER_GUARD}
${BOOST_PPRINT_GDB_GEN_DISABLE_MACRO}
COMMENT "Regenerating ${BOOST_PPRINT_GDB_GEN_OUTPUT}")

if(NOT BOOST_PPRINT_GDB_GEN_EXCLUDE_FROM_ALL)
set(isInAll ALL)
endif()
add_custom_target(${BOOST_PPRINT_GDB_GEN_TARGET}
${isInAll}
DEPENDS "${BOOST_PPRINT_GDB_GEN_OUTPUT}")
endfunction()


function(boost_pretty_printers_test_gdb_printers)
set(options EXCLUDE_FROM_ALL)
set(oneValueArgs TEST PROGRAM)
set(multiValueArgs SOURCES)
cmake_parse_arguments(BOOST_PPRINT_TEST_GDB
"${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
foreach(kw TEST SOURCES)
if(NOT DEFINED "BOOST_PPRINT_TEST_GDB_${kw}")
message(FATAL_ERROR "Argument ${kw} is required for function \
boost_pretty_printers_test_gdb_printers.")
endif()
endforeach()

if(NOT DEFINED BOOST_PPRINT_TEST_GDB_PROGRAM)
set(BOOST_PPRINT_TEST_GDB_PROGRAM ${BOOST_PPRINT_TEST_GDB_TEST})
endif()
if(BOOST_PPRINT_TEST_GDB_EXCLUDE_FROM_ALL)
set(excludeFromAll EXCLUDE_FROM_ALL)
else()
set(includeInAll ALL)
endif()

LIST(GET BOOST_PPRINT_TEST_GDB_SOURCES 0 source0)
add_custom_command(
OUTPUT "${BOOST_PPRINT_TEST_GDB_TEST}.py"
DEPENDS "${source0}"
COMMAND
"${Python3_EXECUTABLE}"
"${BoostPrettyPrinters_GDB_TEST_SCRIPT}"
"${CMAKE_CURRENT_SOURCE_DIR}/${source0}"
"${BOOST_PPRINT_TEST_GDB_TEST}.py"
COMMENT "Generating ${source0}")

add_custom_target(${BOOST_PPRINT_TEST_GDB_TEST}_runner
${includeInAll}
DEPENDS "${BOOST_PPRINT_TEST_GDB_TEST}.py")

add_executable(${BOOST_PPRINT_TEST_GDB_PROGRAM}
${excludeFromAll}
${BOOST_PPRINT_TEST_GDB_SOURCES})
add_dependencies(
${BOOST_PPRINT_TEST_GDB_PROGRAM}
${BOOST_PPRINT_TEST_GDB_TEST}_runner)

add_test(
NAME ${BOOST_PPRINT_TEST_GDB_TEST}
COMMAND "${BoostPrettyPrinters_GDB}"
--batch-silent
-x "${BOOST_PPRINT_TEST_GDB_TEST}.py"
$<TARGET_FILE:${BOOST_PPRINT_TEST_GDB_PROGRAM}>)
endfunction()
159 changes: 159 additions & 0 deletions pretty_printers/boost-pretty-printers.jam
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#
# Copyright (c) 2024 Dmitry Arkhipov ([email protected])
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# Official repository: https://github.com/boostorg/json
#

import common ;
import make ;
import modules ;
import param ;
import path ;
import project ;
import property ;
import python ;
import testing ;
import toolset ;


rule init ( command * )
{
if ! $(.initialized)
{
.initialized = true ;
}
else
{
if ! $(command)
{
return ;
}
}
command ?= gdb ;

GDB_COMMAND = ;
.has-gdb = ;
for local part in $(command)
{
local found = [ common.find-tool $(part) ] ;
if $(found)
{
.has-gdb = true ;
}
else
{
found = $(part) ;
}
GDB_COMMAND += $(found) ;
}
}

rule has-gdb
{
return $(.has-gdb) ;
}

rule gdb-python-header ( target : sources + : requirements *
: usage-requirements * )
{
param.handle-named-params sources requirements usage-requirements ;

make $(target)
: $(sources)
: @boost-pretty-printers.generate-gdb-header
: $(requirements)
<dependency>$(.gdb-header-script)
: $(usage-requirements)
;
}

rule test-gdb-printers ( target : sources + : requirements * : default-build *
: usage-requirements * )
{
param.handle-named-params
sources requirements default-build usage-requirements ;

local project = [ project.current ] ;

local test-runner = _$(target:S=.py) ;
make $(test-runner)
: $(sources[1])
: @boost-pretty-printers.generate-gdb-test-runner
: <dependency>$(.gdb-test-generator-script)
;
$(project).mark-target-as-explicit $(test-runner) ;

local test-program = _$(target) ;
run $(sources)
: target-name $(test-program)
: requirements
<testing.launcher>$(GDB_COMMAND)
<testing.arg>--batch-silent
<testing.arg>-x
<testing.input-file>$(test-runner)
<debug-symbols>on
<runtime-debugging>on
<optimization>debug
$(requirements)
: default-build
$(default-build)
;
$(project).mark-target-as-explicit $(test-program) ;

alias $(target)
: $(test-program)
: $(requirements)
: $(default-build)
: $(usage-requirements)
;
}

.here = [ path.make [ modules.binding $(__name__) ] ] ;
.here = $(.here:D) ;
.gdb-header-script = $(.here)/generate-gdb-header.py ;
.gdb-test-generator-script = $(.here)/generate-gdb-test-runner.py ;

rule generate-gdb-header ( target : sources + : properties * )
{
warn-if-not-configuered ;
RUNNER on $(target) = [ path.native $(.gdb-header-script) ] ;
}
actions generate-gdb-header
{
"$(PYTHON:E=python)" "$(RUNNER)" $(>[1]) $(<) $(FLAGS)
}
toolset.flags boost-pretty-printers.generate-gdb-header FLAGS <flags> ;
toolset.flags boost-pretty-printers.generate-gdb-header PYTHON <python.interpreter> ;

rule generate-gdb-test-runner ( target : sources + : properties * )
{
warn-if-not-configuered ;
RUNNER on $(target) = [ path.native $(.gdb-test-generator-script) ] ;
}
actions generate-gdb-test-runner
{
"$(PYTHON:E=python)" "$(RUNNER)" $(>[1]) $(<)
}
toolset.flags boost-pretty-printers.generate-gdb-test-runner PYTHON <python.interpreter> ;

rule warn-if-not-configuered ( )
{
if $(.checked) { return ; }

if ! $(.initialized)
{
echo "warning: module boost-pretty-printers was not initialized!" ;
echo " add \"using boost-pretty-printers ;\" to your build scripts." ;
}

if ! [ python.configured ]
{
echo "warning: module python was not initialized!" ;
echo " add \"using python ;\" to your build scripts." ;
}

.checked = true ;
}
Loading

0 comments on commit 9faecfc

Please sign in to comment.