diff --git a/cmake/Modules/Tools.cmake b/cmake/Modules/Tools.cmake index 94e077d51e..e37e262bfe 100644 --- a/cmake/Modules/Tools.cmake +++ b/cmake/Modules/Tools.cmake @@ -6,6 +6,10 @@ if(BUILD_TOOLS) add_executable(stl_bin2txt ${LAMMPS_TOOLS_DIR}/stl_bin2txt.cpp) install(TARGETS stl_bin2txt DESTINATION ${CMAKE_INSTALL_BINDIR}) + add_executable(reformat-json ${LAMMPS_TOOLS_DIR}/json/reformat-json.cpp) + target_include_directories(reformat-json PRIVATE ${LAMMPS_SOURCE_DIR}) + install(TARGETS reformat-json DESTINATION ${CMAKE_INSTALL_BINDIR}) + include(CheckGeneratorSupport) if(CMAKE_GENERATOR_SUPPORT_FORTRAN) include(CheckLanguage) diff --git a/doc/src/Tools.rst b/doc/src/Tools.rst index 2ace39c500..bb59f72fb3 100644 --- a/doc/src/Tools.rst +++ b/doc/src/Tools.rst @@ -489,6 +489,29 @@ files even if the LAMMPS sources are not locally available. Example: check-jsonschema --schemafile https://download.lammps.org/json/molecule-schema.json tip3p.json +JSON file format normalization +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There are extensions to the strict JSON format that allow for comments +or ignore additional (dangling) commas. The ``reformat-json.cpp`` tool +will read JSON files in relaxed format, but write it out in strict format. +It is also possible to change the level of indentation from -1 (all data +one long line) to any positive integer value. The original file will be +backed up (.bak added to file name) and then overwritten. + +Manual compilation (it will be automatically included in the CMake build +if building tools is requested during CMake configuration): + +.. code-block:: sh + + g++ -I -o reformat-json reformat-json.cpp + +Usage: + +.. parsed-literal:: + + reformat-json [ ...] + ---------- .. _kate: diff --git a/tools/json/README.md b/tools/json/README.md index 135cdb8fb4..a4b2a11f1f 100644 --- a/tools/json/README.md +++ b/tools/json/README.md @@ -40,6 +40,22 @@ ok -- validation done ``` Otherwise details about the non-conforming fields are given. +# JSON file format normalization + +There are extensions to the strict JSON format that allow for comments +or ignore additional (dangling) commas. The ``reformat-json.cpp`` tool +will read JSON files in relaxed format, but write it out in strict format. +It is also possible to change the level of indentation from -1 (all data +one long line) to any positive integer value. The original file will be +backed up (.bak added to file name) and then overwritten. + +Manual compilation (it will be automatically included in the CMake build +if building tools is requested during CMake configuration): + +```bash +g++ -I -o reformat-json reformat-json.cpp +``` + ------- updated by Axel Kohlmeyer, 2025-05-23 diff --git a/tools/json/reformat-json.cpp b/tools/json/reformat-json.cpp new file mode 100644 index 0000000000..54897233b4 --- /dev/null +++ b/tools/json/reformat-json.cpp @@ -0,0 +1,47 @@ + +#include "json.h" + +#include +#include +#include + +using json = LAMMPS_NS::json; + +int main(int argc, char **argv) +{ + if (argc < 3) { + printf("Usage: %s [ ...]\n", argv[0]); + return 1; + } + + int indent = std::stoi(argv[1]); + + // loop over files + + for (int i=2; i < argc; ++i) { + std::string file = argv[i]; + std::string backup = file + ".bak"; + + FILE *fp = fopen(file.c_str(), "r"); + if (!fp) { + printf("Cannot open file %s for reading: %s\n", file.c_str(), strerror(errno)); + return 2; + } + + auto jsondata = json::parse(fp, nullptr, true, true); + fclose(fp); + + rename(file.c_str(), backup.c_str()); + + fp = fopen(file.c_str(), "w"); + if (!fp) { + printf("Cannot open file %s for writing: %s\n", file.c_str(), strerror(errno)); + return 3; + } + std::string data = jsondata.dump(indent); + data += '\n'; + fputs(data.c_str(), fp); + fclose(fp); + } + return 0; +}