C++ API
The C++ API is in the development stage and contributions are welcome.
Prerequisites
- CMake >= 3.10
- C++ Compiler with C++17 Support
- Cargo
Installation
CMake
You can use FetchContent to add KCL C++ Lib to your project.
FetchContent_Declare(
kcl-lib
GIT_REPOSITORY https://github.com/kcl-lang/lib.git
GIT_TAG v0.9.1 # You can change the GitHub branch tag.
SOURCE_SUBDIR cpp
)
FetchContent_MakeAvailable(kcl-lib)
Or you can download the source code and add it to your project.
mkdir third_party
cd third_party
git clone https://github.com/kcl-lang/lib.git
Update your CMake files.
add_subdirectory(third_party/lib/cpp)
target_link_libraries(your_target kcl-lib-cpp)
API Reference
exec_program
Execute KCL file with arguments and return the JSON/YAML result.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::ExecProgramArgs {
.k_filename_list = { "../test_data/schema.k" },
};
auto result = kcl_lib::exec_program(args);
std::cout << result.yaml_result.c_str() << std::endl;
return 0;
}
parse_file
Parse KCL single file to Module AST JSON string with import dependencies and parse errors.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::ParseFileArgs {
.path = "../test_data/schema.k",
};
auto result = kcl_lib::parse_file(args);
std::cout << result.deps.size() << std::endl;
std::cout << result.errors.size() << std::endl;
std::cout << result.ast_json.c_str() << std::endl;
return 0;
}
parse_program
Parse KCL program with entry files and return the AST JSON string.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::ParseProgramArgs {
.paths = { "../test_data/schema.k" },
};
auto result = kcl_lib::parse_program(args);
std::cout << result.paths[0].c_str() << std::endl;
std::cout << result.errors.size() << std::endl;
std::cout << result.ast_json.c_str() << std::endl;
return 0;
}
load_package
load_package provides users with the ability to parse KCL program and semantic model information including symbols, types, definitions, etc.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto parse_args = kcl_lib::ParseProgramArgs {
.paths = { "../test_data/schema.k" },
};
auto args = kcl_lib::LoadPackageArgs {
.resolve_ast = true,
};
args.parse_args = kcl_lib::OptionalParseProgramArgs {
.has_value = true,
.value = parse_args,
};
auto result = kcl_lib::load_package(args);
std::cout << result.symbols[0].value.ty.value.c_str() << std::endl;
return 0;
}
list_variables
list_variables provides users with the ability to parse KCL program and get all variables by specs.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::ListVariablesArgs {
.files = { "../test_data/schema.k" },
};
auto result = kcl_lib::list_variables(args);
std::cout << result.variables[0].value[0].value.c_str() << std::endl;
return 0;
}
list_options
list_options provides users with the ability to parse KCL program and get all option information.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::ParseProgramArgs {
.paths = { "../test_data/option/main.k" },
};
auto result = kcl_lib::list_options(args);
std::cout << result.options[0].name.c_str() << std::endl;
std::cout << result.options[1].name.c_str() << std::endl;
std::cout << result.options[2].name.c_str() << std::endl;
return 0;
}
get_schema_type_mapping
Get schema type mapping defined in the program.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto exec_args = kcl_lib::ExecProgramArgs {
.k_filename_list = { "../test_data/schema.k" },
};
auto args = kcl_lib::GetSchemaTypeMappingArgs();
args.exec_args = kcl_lib::OptionalExecProgramArgs {
.has_value = true,
.value = exec_args,
};
auto result = kcl_lib::get_schema_type_mapping(args);
std::cout << result.schema_type_mapping[0].key.c_str() << std::endl;
std::cout << result.schema_type_mapping[0].value.properties[0].key.c_str() << std::endl;
std::cout << result.schema_type_mapping[0].value.properties[0].value.ty.c_str() << std::endl;
return 0;
}
override_file
Override KCL file with arguments. See https://www.kcl-lang.io/docs/user_docs/guides/automation for more override spec guide.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::OverrideFileArgs {
.file = { "../test_data/override_file/main.k" },
.specs = { "b.a=2" },
};
auto result = kcl_lib::override_file(args);
std::cout << result.result << std::endl;
std::cout << result.parse_errors.size() << std::endl;
return 0;
}
format_code
Format the code source.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::FormatCodeArgs {
.source = "schema Person:\n"
" name: str\n"
" age: int\n"
" check:\n"
" 0 < age < 120\n",
};
auto result = kcl_lib::format_code(args);
std::cout << result.formatted.c_str() << std::endl;
return 0;
}
format_path
Format KCL file or directory path contains KCL files and returns the changed file paths.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::FormatPathArgs {
.path = "../test_data/format_path/test.k",
};
auto result = kcl_lib::format_path(args);
std::cout << result.changed_paths.size() << std::endl;
return 0;
}
lint_path
Lint files and return error messages including errors and warnings.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::LintPathArgs {
.paths = { "../test_data/lint_path/test-lint.k" }
};
auto result = kcl_lib::lint_path(args);
std::cout << result.results[0].c_str() << std::endl;
return 0;
}
validate_code
Validate code using schema and JSON/YAML data strings.
Example
#include "kcl_lib.hpp"
#include <iostream>
int validate(const char* code_str, const char* data_str)
{
auto args = kcl_lib::ValidateCodeArgs {
.code = code_str,
.data = data_str,
};
auto result = kcl_lib::validate_code(args);
std::cout << result.success << std::endl;
std::cout << result.err_message.c_str() << std::endl;
return 0;
}
int main()
{
const char* code_str = "schema Person:\n"
" name: str\n"
" age: int\n"
" check:\n"
" 0 < age < 120\n";
const char* data_str = "{\"name\": \"Alice\", \"age\": 10}";
const char* error_data_str = "{\"name\": \"Alice\", \"age\": 1110}";
validate(code_str, data_str);
validate(code_str, error_data_str);
return 0;
}
Run the ValidateAPI example.
./validate_api
rename
Rename all the occurrences of the target symbol in the files. This API will rewrite files if they contain symbols to be renamed. Return the file paths that got changed.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::RenameArgs {
.package_root = "../test_data/rename",
.symbol_path = "a",
.file_paths = { "../test_data/rename/main.k" },
.new_name = "a",
};
auto result = kcl_lib::rename(args);
std::cout << result.changed_files[0].c_str() << std::endl;
return 0;
}
rename_code
Rename all the occurrences of the target symbol and return the modified code if any code has been changed. This API won't rewrite files but return the changed code.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::RenameCodeArgs {
.package_root = "/mock/path",
.symbol_path = "a",
.source_codes = { {
.key = "/mock/path/main.k",
.value = "a = 1\nb = a\nc = a",
} },
.new_name = "a2",
};
auto result = kcl_lib::rename_code(args);
std::cout << result.changed_codes[0].value.c_str() << std::endl;
return 0;
}
test
Test KCL packages with test arguments.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::TestArgs {
.pkg_list = { "../test_data/testing/..." },
};
auto result = kcl_lib::test(args);
std::cout << result.info[0].name.c_str() << std::endl;
return 0;
}
load_settings_files
Load the setting file config defined in kcl.yaml
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::LoadSettingsFilesArgs {
.work_dir = "../test_data/settings",
.files = { "../test_data/settings/kcl.yaml" },
};
auto result = kcl_lib::load_settings_files(args);
std::cout << result.kcl_cli_configs.value.files.size() << std::endl;
std::cout << result.kcl_cli_configs.value.strict_range_check << std::endl;
std::cout << result.kcl_options[0].key.c_str() << std::endl;
std::cout << result.kcl_options[0].value.c_str() << std::endl;
return 0;
}
update_dependencies
Download and update dependencies defined in the kcl.mod
file and return the external package name and location list.
Example
The content of module/kcl.mod
is
[package]
name = "mod_update"
edition = "0.0.1"
version = "0.0.1"
[dependencies]
helloworld = { oci = "oci://ghcr.io/kcl-lang/helloworld", tag = "0.1.0" }
flask = { git = "https://github.com/kcl-lang/flask-demo-kcl-manifests", commit = "ade147b" }
C++ Code
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::UpdateDependenciesArgs {
.manifest_path = "../test_data/update_dependencies",
};
auto result = kcl_lib::update_dependencies(args);
std::cout << result.external_pkgs[0].pkg_name.c_str() << std::endl;
std::cout << result.external_pkgs[1].pkg_name.c_str() << std::endl;
return 0;
}
Call exec_program
with external dependencies
Example
The content of module/kcl.mod
is
[package]
name = "mod_update"
edition = "0.0.1"
version = "0.0.1"
[dependencies]
helloworld = { oci = "oci://ghcr.io/kcl-lang/helloworld", tag = "0.1.0" }
flask = { git = "https://github.com/kcl-lang/flask-demo-kcl-manifests", commit = "ade147b" }
The content of module/main.k
is
import helloworld
import flask
a = helloworld.The_first_kcl_program
C++ Code
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto args = kcl_lib::UpdateDependenciesArgs {
.manifest_path = "../test_data/update_dependencies",
};
auto result = kcl_lib::update_dependencies(args);
auto exec_args = kcl_lib::ExecProgramArgs {
.k_filename_list = { "../test_data/update_dependencies/main.k" },
.external_pkgs = result.external_pkgs,
};
auto exec_result = kcl_lib::exec_program(exec_args);
std::cout << exec_result.yaml_result.c_str() << std::endl;
return 0;
}
get_version
Return the KCL service version information.
Example
#include "kcl_lib.hpp"
#include <iostream>
int main()
{
auto result = kcl_lib::get_version();
std::cout << result.checksum.c_str() << std::endl;
std::cout << result.git_sha.c_str() << std::endl;
std::cout << result.version.c_str() << std::endl;
std::cout << result.version_info.c_str() << std::endl;
return 0;
}