Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/clang-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install clang-format
run: sudo apt install -y cmake clang-format-19
run: sudo apt install -y cmake clang-format-20
- name: clang-format
# Create symbolic link to clang-format-19 and
# Create symbolic link to clang-format-20 and
# add it to PATH so that 'clang-format' can
# be used to run 'clang-format-19'.
# be used to run 'clang-format-20'.
run: |
ln -s $(which clang-format-19) clang-format
ln -s $(which clang-format-20) clang-format
export PATH=$PWD:$PATH
cmake .
make lint
54 changes: 25 additions & 29 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,36 +95,32 @@ target_compile_options(cbxp PUBLIC ${COMPILE_OPTIONS})
target_link_options(cbxp PUBLIC ${LINK_OPTIONS})

# ============================================================================
# Packaging
# Install
# ============================================================================
add_custom_target(
package
COMMAND "mkdir"
"-p"
"cbxp-${CMAKE_PROJECT_VERSION}/bin"
"cbxp-${CMAKE_PROJECT_VERSION}/lib"
"cbxp-${CMAKE_PROJECT_VERSION}/include"
COMMAND "cp"
"LICENSE"
"cbxp-${CMAKE_PROJECT_VERSION}/"
COMMAND "cp"
"NOTICES"
"cbxp-${CMAKE_PROJECT_VERSION}/"
COMMAND "cp"
"./dist/cbxp"
"cbxp-${CMAKE_PROJECT_VERSION}/bin/"
COMMAND "cp"
"./dist/libcbxp.a"
"cbxp-${CMAKE_PROJECT_VERSION}/lib/"
COMMAND "cp"
"./cbxp/cbxp.h"
"cbxp-${CMAKE_PROJECT_VERSION}/include/"
COMMAND "pax"
"-x" "pax"
"-wzvf"
"./dist/cbxp-${CMAKE_PROJECT_VERSION}.pax.Z"
"cbxp-${CMAKE_PROJECT_VERSION}/*"
DEPENDS libcbxp cbxp
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
SET(CMAKE_INSTALL_PREFIX "~/cbxp-${CMAKE_PROJECT_VERSION}" CACHE PATH "install path" FORCE)
endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)

include(GNUInstallDirs)

install(
FILES "LICENSE" "NOTICES"
DESTINATION ${CMAKE_INSTALL_PREFIX}
)

install(
TARGETS cbxp
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install(
TARGETS libcbxp
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

install(
FILES "./cbxp/cbxp.h"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

# ============================================================================
Expand Down
53 changes: 23 additions & 30 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ pipeline {
stage('Lint') {
steps {
echo "Linting with clang-format ..."
sh "gmake lint"
sh "cmake --build . --target lint --parallel"
}
}
stage('Cppcheck') {
steps {
echo "Running cppcheck ..."
sh "gmake check"
sh "cmake --build . --target check --parallel"
}
}
stage('Create Python Distribution Metadata') {
Expand All @@ -118,7 +118,7 @@ pipeline {

echo "Building '${wheel}' and '${tar}' ..."
sh """
${python} -m pip install build>=1.3.0
${python} -m pip install build>=1.5.0
${python} -m build
"""

Expand All @@ -139,25 +139,17 @@ pipeline {
clean_python_environment()
clean_git_repo()
}
// Shell/C/C++ pax distribution
// CLI/C/C++ distribution
def cbxp_version = get_cbxp_version()
def pax = "cbxp-${cbxp_version}.pax.Z"
echo "Building '${pax}' ..."
echo "Installing testing CBXP '${cbxp_version}' ..."
sh """
cmake .
gmake package
"""

echo "Install testing '${pax}' ..."
sh """
mkdir install-test
cd install-test
pax -rf ../dist/${pax}
ls -alT cbxp-${cbxp_version}/*
cmake . --install-prefix ${env.WORKSPACE}/install-test
cmake --build . --parallel
cmake --install .
"""

echo "'Function testing './dist/cbxp' ..."
sh "gmake test"
sh "cmake --build . --target test --parallel"

clean_git_repo()
}
Expand Down Expand Up @@ -213,7 +205,9 @@ def create_python_executables_and_wheels_map(python_versions) {
"cbxp-${cbxp_version}-cp3${python_version}-cp3${python_version}-zos.whl"
),
"wheelPublish": (
"cbxp-${cbxp_version}-cp3${python_version}-cp3${python_version}-zos.whl"
// New wheel naming convention does not work with PyPi so we
// do still need to rename the wheel file.
"cbxp-${cbxp_version}-cp3${python_version}-none-any.whl"
),
"tarPublish": "cbxp-${cbxp_version}.tar.gz"
]
Expand Down Expand Up @@ -334,14 +328,11 @@ def publish(
echo "Building '${wheel_default}' ..."

sh """
${python} -m pip install build>=1.2.2
${python} -m pip install build>=1.5.0
${python} -m build -w
"""

// Rename wheel file if the old naming convention is being used
if (wheel_default != wheel_publish) {
sh "mv ./dist/${wheel_default} ./dist/${wheel_publish}"
}
sh "mv ./dist/${wheel_default} ./dist/${wheel_publish}"

if (tar_built == false) {
tar_publish = python_executables_and_wheels_map[python]["tarPublish"]
Expand All @@ -354,29 +345,31 @@ def publish(
upload_asset(release_id, wheel_publish)

echo "Adding sha256 checksum for '${wheel_publish}' to ${checksums_file}..."
sh "cd dist && sha256sum -t ${wheel_publish} >> ${checksums_file}"
sh "cd dist && sha256sum ${wheel_publish} >> ${checksums_file}"
}

echo "Uploading '${tar_publish}' to '${release_title}' GitHub release ..."
upload_asset(release_id, tar_publish)

echo "Adding sha256 checksum for '${tar_publish}' to ${checksums_file}..."
sh "cd dist && sha256sum -t ${tar_publish} >> ${checksums_file}"
sh "cd dist && sha256sum ${tar_publish} >> ${checksums_file}"

// Build and publish Shell/C/C++ interface pax
// Build and publish CLI/C/C++ interface pax
def cbxp_version = get_cbxp_version()
def pax = "cbxp-${cbxp_version}.pax.Z"
echo "Building '${pax}' ..."
sh """
cmake .
gmake package
cmake . --install-prefix ${env.WORKSPACE}/cbxp-${cbxp_version}
cmake --build . --parallel
cmake --install .
pax -x pax -wzvf ./dist/${pax} cbxp-${cbxp_version}/*
"""

echo "Uploading '${pax}' to '${release_title}' GitHub release ..."
upload_asset(release_id, pax)

echo "Adding sha256 checksum for '${pax}' to ${checksums_file}..."
sh "cd dist && sha256sum -t ${pax} >> ${checksums_file}"
sh "cd dist && sha256sum ${pax} >> ${checksums_file}"

echo "Uploading '${checksums_file}' to '${release_title}' GitHub release ..."
upload_asset(release_id, checksums_file)
Expand Down Expand Up @@ -422,7 +415,7 @@ def build_description(python_executables_and_wheels_map, release_tag, release_no
+ "> :warning: _Requires z/OS Open XL C/C++ 2.2 compiler._\\n"
+ "```\\ncurl -O -L https://github.com/ambitus/cbxp/releases/download/${release_tag}/${tar} "
+ "&& python3 -m pip install ${tar}\\n```\\n"
+ "## Shell/C/C++ Interface Installation\\n"
+ "## CLI/C/C++ Interface Installation\\n"
+ "```\\ncurl -O -L https://github.com/ambitus/cbxp/releases/download/${release_tag}/${pax} "
+ "&& pax -rf ${pax}\\n```\\n"
)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ A unified and standardized interface for extracting and formatting z/OS control

## Description

z/OS Control Blocks are in-memory data structures that describe and control countless process, operating system components, and subsystems. Control blocks are ubiquitous on z/OS, but not very straight forward to access and extract information from. The mission of CBXP *(Control Block EXPlorer)* is to make it easy to extract z/OS control block data using industry standard tools and methodologies. CBXP accomplishes this by implementing a **C/C++ XPLINK ASCII** interface for extracting control blocks and post processing them into **JSON**. This makes it straight forward to integrate with industry standard programming languages and tools, which generally have well documented and understood foreign language interfaces for C/C++, and native and or third party JSON support that makes working with JSON data easy.
z/OS Control Blocks are in-memory data structures that describe and control countless process, operating system components, and subsystems. Control blocks are ubiquitous on z/OS, but not very straight forward to access and extract information from. The mission of CBXP *(Control Block EXPlorer)* is to make it easy to extract and format z/OS control block data using industry standard tools and methodologies. CBXP accomplishes this by implementing a **C/C++ XPLINK ASCII** interface for extracting control block data and post processing it into **JSON**. This makes it straight forward to integrate with industry standard programming languages and tools, which generally have well documented and understood foreign language interfaces for C/C++, and native and or third party JSON support that makes working with JSON data easy.

CBXP is the successor to the existing [cbxplorer](https://github.com/ambitus/cbexplorer) project. CBXP mainly improves upon this existing work by being implemented in C/C++ so that it is not limited to a specific programming language or tool. CBXP also focuses heavily on providing an interface that is simple and straight forward to use.

## Getting Started

### Minimum z/OS & Language Versions
Currently, CBXP is being developed on **z/OS 3.1**. We hope to eventually support all z/OS versions that are fully supported by IBM.
Currently, CBXP is being developed on **z/OS 3.2**. We hope to eventually support all z/OS versions that are fully supported by IBM.
* [z/OS Product Lifecycle](https://www.ibm.com/support/pages/lifecycle/search/?q=5655-ZOS,%205650-ZOS)

All versions of the **IBM Open Enterprise SDK for Python** that are fully supported by IBM are supported by CBXP.
Expand All @@ -33,7 +33,7 @@ All versions of the **IBM Open Enterprise SDK for Python** that are fully suppor
### Interfaces
Currently, the following interfaces are provided for CBXP. Additional interfaces can be added in the future if there are use cases for them.
* [Python Interface](https://ambitus.github.io/cbxp/interfaces/python)
* [CLI Interface](https://ambitus.github.io/cbxp/interfaces/shell)
* [CLI Interface](https://ambitus.github.io/cbxp/interfaces/cli)
* [C/C++ Interface](https://ambitus.github.io/cbxp/interfaces/c_cpp)

### Supported Control Blocks
Expand Down
4 changes: 2 additions & 2 deletions cbxp/cbxp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ cbxp_result_t* cbxp_extract(const char* control_block_name,

cbxp_result_t* cbxp_format(const char* control_block_name,
const size_t control_block_name_length,
const void* p_data, const size_t data_length,
const void* data, const size_t data_length,
bool debug) {
std::string control_block_name_string;

Expand All @@ -60,7 +60,7 @@ cbxp_result_t* cbxp_format(const char* control_block_name,
CBXP::ControlBlockExplorer explorer =
CBXP::ControlBlockExplorer(p_cbxp_result);

explorer.formatControlBlock(control_block_name_string, p_data, data_length);
explorer.formatControlBlock(control_block_name_string, data, data_length);

return p_cbxp_result;
}
Expand Down
2 changes: 1 addition & 1 deletion cbxp/cbxp.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ cbxp_result_t* cbxp_extract(const char* control_block_name,

cbxp_result_t* cbxp_format(const char* control_block_name,
const size_t control_block_name_length,
const void* p_data, const size_t data_length,
const void* data, const size_t data_length,
bool debug);

void cbxp_free(cbxp_result_t* cbxp_result, bool debug);
Expand Down
47 changes: 45 additions & 2 deletions cbxp/cli/command_processor.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#define _POSIX_SOURCE
#define _XOPEN_SOURCE_EXTENDED 1

#include "command_processor.hpp"

#include <poll.h>
#include <unistd.h>

#include <cstdio>
Expand All @@ -12,9 +16,47 @@

namespace CBXP {

void CommandProcessor::showASCIIArt() {
std::string ansi_bold = "\e[1m";
std::string ansi_blue_bold = "\e[1;34m";
std::string ansi_reset = "\e[0m";

// clang-format off
const std::vector<std::string> logo_ascii_art = {
" ____________ ",
" | |",
" | 1010 |",
" | |",
" | {} |",
" |____________|"
};

const std::vector<std::string> cbxp_ascii_art = {
" _____ ____ __ __ _____ ",
" / ____|| _ \\\\ \\ / /| __ \\",
" | | | |_) |\\ V / | |__) |",
" | | | _ < > < | ___/",
" | |____ | |_) |/ . \\ | |",
" \\_____||____//_/ \\_\\|_|"
};
// clang-format on

for (auto i = 0; i < logo_ascii_art.size(); i++) {
if (isatty(fileno(stdout))) {
std::cout << ansi_bold << logo_ascii_art[i] << ansi_blue_bold
<< cbxp_ascii_art[i] << ansi_reset << std::endl;
} else {
std::cout << logo_ascii_art[i] << cbxp_ascii_art[i] << std::endl;
}
}

std::cout << std::endl;
}

void CommandProcessor::showGeneralUsage() const {
CommandProcessor::showASCIIArt();
std::cout << "Full CLI documentation is available at: "
"https://ambitus.github.io/cbxp/interfaces/shell/"
"https://ambitus.github.io/cbxp/interfaces/cli/"
<< std::endl
<< std::endl;

Expand Down Expand Up @@ -301,7 +343,8 @@ void CommandProcessor::processFormatFlags() {
throw CLIExitFailure();
}
}
if (isatty(STDIN_FILENO) == 0) {
struct pollfd pfd = {STDIN_FILENO, POLLIN, 0};
if (poll(&pfd, 1, 0) > 0 && (pfd.revents & POLLIN)) {
CommandProcessor::readFormatDataFromPipe();
}
if (format_options_.data_buffer.empty()) {
Expand Down
1 change: 1 addition & 0 deletions cbxp/cli/command_processor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class CommandProcessor {
cbxp_global_options_t global_options_;
cbxp_extract_options_t extract_options_;
cbxp_format_options_t format_options_;
static void showASCIIArt();
void showGeneralUsage() const;
void showExtractUsage() const;
void showFormatUsage() const;
Expand Down
6 changes: 3 additions & 3 deletions cbxp/control_blocks/control_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,14 @@ void ControlBlock::createFilterLists(const std::vector<std::string>& filters) {
}

void ControlBlock::addCurrentFilter(const std::string& filter) {
std::string filter_key, filter_value;
std::vector<std::string> operations = {"<=", ">=", "<", ">", "="};
for (std::string operation : operations) {
size_t operation_pos = filter.find(operation);
if (operation_pos != std::string::npos) {
// If there's a delimeter then separate include into the key and its value
filter_value = filter.substr(operation_pos + operation.length());
filter_key = filter.substr(0, operation_pos);
std::string filter_value =
filter.substr(operation_pos + operation.length());
std::string filter_key = filter.substr(0, operation_pos);
cbxp_filter_t filter_data = {operation, filter_value};
Logger::getInstance().debug("Adding '" + filter_key + operation +
filter_value +
Expand Down
2 changes: 2 additions & 0 deletions cbxp/logger.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#define _POSIX_SOURCE

#include "logger.hpp"

#include <unistd.h>
Expand Down
Loading
Loading