<commit_before>include(CMakeParseArguments)
define_property(GLOBAL PROPERTY Z3_LIBZ3_COMPONENTS
                BRIEF_DOCS "List of Z3 components to use in libz3"
                FULL_DOCS "List of Z3 components to use in libz3")

function(z3_expand_dependencies output_var)
  if (ARGC LESS 2)
    message(FATAL_ERROR "Invalid number of arguments")
  endif()
  # Remaing args should be component names
  set(_expanded_deps ${ARGN})
  set(_old_number_of_deps 0)
  list(LENGTH _expanded_deps _number_of_deps)
  while (_number_of_deps GREATER _old_number_of_deps)
    set(_old_number_of_deps "${_number_of_deps}")
    # Loop over the known dependencies and retrieve their dependencies
    set(_old_expanded_deps ${_expanded_deps})
    foreach (dependency ${_old_expanded_deps})
      get_property(_depdeps GLOBAL PROPERTY Z3_${dependency}_DEPS)
      list(APPEND _expanded_deps ${_depdeps})
      unset(_depdeps)
    endforeach()
    list(REMOVE_DUPLICATES _expanded_deps)
    list(LENGTH _expanded_deps _number_of_deps)
  endwhile()
  set(${output_var} ${_expanded_deps} PARENT_SCOPE)
endfunction()

function(z3_add_component_dependencies_to_target target_name)
  if (ARGC LESS 2)
    message(FATAL_ERROR "Invalid number of arguments")
  endif()
  if (NOT (TARGET ${target_name}))
    message(FATAL_ERROR "Target \"${target_name}\" does not exist")
  endif()
  # Remaing args should be component names
  set(_expanded_deps ${ARGN})
  foreach (dependency ${_expanded_deps})
    # FIXME: Adding these include paths wouldn't be necessary if the sources
    # used include paths rooted in the ``src`` directory.
    get_property(_dep_include_dirs GLOBAL PROPERTY Z3_${dependency}_INCLUDES)
    foreach (inc_dir ${_dep_include_dirs})
      target_include_directories(${target_name} PRIVATE "${inc_dir}")
    endforeach()
    unset(_dep_include_dirs)
    # Ensure this component's dependencies are built before this component.
    # This important because we might need the generated header files in
    # other components.
    add_dependencies(${target_name} ${dependency})
  endforeach()
endfunction()

macro(z3_add_component component_name)
  CMAKE_PARSE_ARGUMENTS("Z3_MOD" "NOT_LIBZ3_COMPONENT" "" "SOURCES;COMPONENT_DEPENDENCIES;PYG_FILES" ${ARGN})
  message(STATUS "Adding component ${component_name}")
  # Note: We don't check the sources exist here because
  # they might be generated files that don't exist yet.

  set(_list_generated_headers "")
  foreach (pyg_file ${Z3_MOD_PYG_FILES})
    set(_full_pyg_file_path "${CMAKE_CURRENT_SOURCE_DIR}/${pyg_file}")
    if (NOT (EXISTS "${_full_pyg_file_path}"))
      message(FATAL_ERROR "\"${_full_pyg_file_path}\" does not exist")
    endif()
    string(REPLACE ".pyg" ".hpp" _output_file "${pyg_file}")
    if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_output_file}")
      message(FATAL_ERROR "\"${CMAKE_CURRENT_SOURCE_DIR}/${_output_file}\" "
        ${z3_polluted_tree_msg}
      )
    endif()
    set(_full_output_file_path "${CMAKE_CURRENT_BINARY_DIR}/${_output_file}")
    message(STATUS "Adding rule to generate \"${_output_file}\"")
    add_custom_command(OUTPUT "${_output_file}"
      COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/scripts/pyg2hpp.py" "${_full_pyg_file_path}" "${CMAKE_CURRENT_BINARY_DIR}"
      MAIN_DEPENDENCY "${_full_pyg_file_path}"
      DEPENDS "${CMAKE_SOURCE_DIR}/scripts/pyg2hpp.py" "${CMAKE_SOURCE_DIR}/scripts/mk_util.py"
      COMMENT "Generating \"${_full_output_file_path}\" from \"${pyg_file}\""
      WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
      ${ADD_CUSTOM_COMMAND_USES_TERMINAL_ARG}
      VERBATIM
    )
    list(APPEND _list_generated_headers "${_full_output_file_path}")<commit_msg>Document ``z3_add_component()``.<commit_after>include(CMakeParseArguments)
define_property(GLOBAL PROPERTY Z3_LIBZ3_COMPONENTS
                BRIEF_DOCS "List of Z3 components to use in libz3"
                FULL_DOCS "List of Z3 components to use in libz3")

function(z3_expand_dependencies output_var)
  if (ARGC LESS 2)
    message(FATAL_ERROR "Invalid number of arguments")
  endif()
  # Remaing args should be component names
  set(_expanded_deps ${ARGN})
  set(_old_number_of_deps 0)
  list(LENGTH _expanded_deps _number_of_deps)
  while (_number_of_deps GREATER _old_number_of_deps)
    set(_old_number_of_deps "${_number_of_deps}")
    # Loop over the known dependencies and retrieve their dependencies
    set(_old_expanded_deps ${_expanded_deps})
    foreach (dependency ${_old_expanded_deps})
      get_property(_depdeps GLOBAL PROPERTY Z3_${dependency}_DEPS)
      list(APPEND _expanded_deps ${_depdeps})
      unset(_depdeps)
    endforeach()
    list(REMOVE_DUPLICATES _expanded_deps)
    list(LENGTH _expanded_deps _number_of_deps)
  endwhile()
  set(${output_var} ${_expanded_deps} PARENT_SCOPE)
endfunction()

function(z3_add_component_dependencies_to_target target_name)
  if (ARGC LESS 2)
    message(FATAL_ERROR "Invalid number of arguments")
  endif()
  if (NOT (TARGET ${target_name}))
    message(FATAL_ERROR "Target \"${target_name}\" does not exist")
  endif()
  # Remaing args should be component names
  set(_expanded_deps ${ARGN})
  foreach (dependency ${_expanded_deps})
    # FIXME: Adding these include paths wouldn't be necessary if the sources
    # used include paths rooted in the ``src`` directory.
    get_property(_dep_include_dirs GLOBAL PROPERTY Z3_${dependency}_INCLUDES)
    foreach (inc_dir ${_dep_include_dirs})
      target_include_directories(${target_name} PRIVATE "${inc_dir}")
    endforeach()
    unset(_dep_include_dirs)
    # Ensure this component's dependencies are built before this component.
    # This important because we might need the generated header files in
    # other components.
    add_dependencies(${target_name} ${dependency})
  endforeach()
endfunction()

# z3_add_component(component_name
#   [NOT_LIBZ3_COMPONENT]
#   SOURCES source1 [source2...]
#   [COMPONENT_DEPENDENCIES component1 [component2...]]
#   [PYG_FILES pygfile1 [pygfile2...]]
# )
#
# Declares a Z3 component (as a CMake "object library") with target name
# ``component_name``.
#
# The option ``NOT_LIBZ3_COMPONENT`` declares that the
# component should not be included in libz3. If this is not specified
# the component will be included in libz3.
#
# The mandatory ``SOURCES`` keyword should be followed by the source files
# (including any files generated at build or configure time) that are should be
# included in the component. It is not necessary to list header files here as
# CMake infers header file dependencies unless that header file is generated at
# build time.
#
# The optional ``COMPONENT_DEPENDENCIES`` keyword should be followed by a list of
# components that ``component_name`` should depend on. The components listed here
# must have already been declared using ``z3_add_component()``. Listing components
# here causes them to be built before ``component_name``. It also currently causes
# the include directories used by the transistive closure of the dependencies
# to be added to the list of include directories used to build ``component_name``.
#
# The optional ``PYG_FILES`` keyword should be followed by a list of one or
# more ``<NAME>.pyg`` files that should used to be generate
# ``<NAME>_params.hpp`` header files used by the ``component_name``.
#
macro(z3_add_component component_name)
  CMAKE_PARSE_ARGUMENTS("Z3_MOD" "NOT_LIBZ3_COMPONENT" "" "SOURCES;COMPONENT_DEPENDENCIES;PYG_FILES" ${ARGN})
  message(STATUS "Adding component ${component_name}")
  # Note: We don't check the sources exist here because
  # they might be generated files that don't exist yet.

  set(_list_generated_headers "")
  foreach (pyg_file ${Z3_MOD_PYG_FILES})
    set(_full_pyg_file_path "${CMAKE_CURRENT_SOURCE_DIR}/${pyg_file}")
    if (NOT (EXISTS "${_full_pyg_file_path}"))
      message(FATAL_ERROR "\"${_full_pyg_file_path}\" does not exist")
    endif()
    string(REPLACE ".pyg" ".hpp" _output_file "${pyg_file}")
    if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_output_file}")
      message(FATAL_ERROR "\"${CMAKE_CURRENT_SOURCE_DIR}/${_output_file}\" "
        ${z3_polluted_tree_msg}
      )
    endif()
    set(_full_output_file_path "${CMAKE_CURRENT_BINARY_DIR}/${_output_file}")
    message(STATUS "Adding rule to generate \"${_output_file}\"")
    add_custom_command(OUTPUT "${_output_file}"
      COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/scripts/pyg2hpp.py" "${_full_pyg_file_path}" "${CMAKE_CURRENT_BINARY_DIR}"
      MAIN_DEPENDENCY "${_full_pyg_file_path}"
      DEPENDS "${CMAKE_SOURCE_DIR}/scripts/pyg2hpp.py" "${CMAKE_SOURCE_DIR}/scripts/mk_util.py"
      COMMENT "Generating \"${_full_output_file_path}\" from \"${pyg_file}\""
      WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
      ${ADD_CUSTOM_COMMAND_USES_TERMINAL_ARG}
      VERBATIM
    )
    list(APPEND _list_generated_headers "${_full_output_file_path}")
{'fraction_non_alphanumeric': 0.10340947451333408, 'fraction_numerical': 0.006076291211882525, 'mean_word_length': 5.021680216802168, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6975310', 'n_tokens_mistral': 3052, 'n_tokens_neox': 2956, 'n_words': 726}