Metadata-Version: 2.4
Name: dtnma-camp
Version: 3.4.0
Summary: C code generator for DTNMA tools
Author-email: JHU/APL <dtnma-support@jhuapl.edu>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/JHUAPL-DTNMA/dtnma-camp
Project-URL: Documentation, https://jhuapl-dtnma.github.io/dtnma-camp/
Project-URL: Bug Tracker, https://github.com/JHUAPL-DTNMA/dtnma-camp/issues
Classifier: Development Status :: 5 - Production/Stable
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: dtnma-ace~=2.0
Requires-Dist: setuptools
Requires-Dist: jinja2~=3.1
Provides-Extra: test
Requires-Dist: jinja2; extra == "test"
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-subtests; extra == "test"
Requires-Dist: pytest-cov; extra == "test"
Requires-Dist: coverage; extra == "test"
Requires-Dist: psycopg2-binary; extra == "test"
Provides-Extra: pylint
Requires-Dist: pylint; extra == "pylint"
Requires-Dist: pylint_junit; extra == "pylint"
Provides-Extra: flake8
Requires-Dist: flake8; extra == "flake8"
Requires-Dist: flake8_pyproject; extra == "flake8"
Requires-Dist: flake8_formatter_junit_xml; extra == "flake8"
Provides-Extra: format
Requires-Dist: ruff==0.16.0; extra == "format"
Requires-Dist: licenseheaders==0.8.8; extra == "format"
Provides-Extra: docs
Requires-Dist: sphinx<6; extra == "docs"
Requires-Dist: sphinx_rtd_theme; extra == "docs"
Requires-Dist: sphinx-argparse; extra == "docs"
Dynamic: license-file

<!--
Copyright (c) 2020-2026 The Johns Hopkins University Applied Physics
Laboratory LLC.

This file is part of the C code generator for AMP (CAMP) under the
DTN Management Architecture (DTNMA) reference implementaton set from APL.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Portions of this work were performed for the Jet Propulsion Laboratory,
California Institute of Technology, sponsored by the United States Government
under the prime contract 80NM0018D0004 between the Caltech and NASA under
subcontract 1658085.
-->
# DTNMA CAMP

[![Documentation](https://github.com/JHUAPL-DTNMA/dtnma-camp/actions/workflows/docs.yaml/badge.svg)](https://jhuapl-dtnma.github.io/dtnma-camp/)
[![Sonar Coverage](https://img.shields.io/sonar/coverage/JHUAPL-DTNMA_dtnma-camp?server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/project/overview?id=JHUAPL-DTNMA_dtnma-camp)
[![PyPI Project](https://img.shields.io/pypi/v/dtnma-camp.svg)](https://pypi.org/project/dtnma-camp/)

This is the C code generator for the DTN Management Architecture (DTNMA).
It is part of the larger Asynchronous Network Managment System (ANMS) managed for [NASA AMMOS](https://ammos.nasa.gov/).



           (                 ,&&&.
             )                .,.&&
            (  (              \=__/
                )             ,'-'.
          (    (  ,,      _.__|/ /|
           ) /\ -((------((_|___/ |
         (  // | (`'      ((  `'--|
       _ -.;_/ \\--._      \\ \-._/.
      (_;-// | \ \-'.\    <_,\_\`--'|
      ( `.__ _  ___,')      <_,-'__,'
       `'(_ )_)(_)_)'


This tool uses the YANG representation of an Application Data Model (ADM) to
generate code for various purposes.

CAmp generates:

- C code for usage in a C11 [Reference DTNMA agent](https://jhuapl-dtnma.github.io/dtnma-tools/html/refda.html).
  This generation can also carry over custom functions in existing C files for
  the ADM, if indicated appropriately in the existing code (see the
  Round-tripping Section). 
- SQL code for usage by the [Reference DTNMA Manager](https://jhuapl-dtnma.github.io/dtnma-tools/html/refdm.html) and [ANMS](https://github.com/NASA-AMMOS/anms/) deployment.

Additional generators may be added to account for use cases outside of the reference DTNMA tools.
Please contact the developers for more information or suggestions. The
Architecture Section also provides some explanation of the components of CAmp,
and how to incorporate additional generators.

> [!NOTE]
> CAmp largely assumes that the ADM YANG input can be trusted.
> CAmp does properly escape necessary sequences found in the ADMs tested during development (e.g., apostrophes in object descriptions).

Moreover, the files generated by CAmp don't have cross-dependencies on preprocessor 
definitions or symbols outside of compilation. The output from CAmp can be placed 
anywhere in the compilation directory tree, because it doesn't depend on the other 
files generated by CAMP, outside of CACE and the REFDA. 

## Development

For development purposes, it is advised to operate within a Python virtual environment, ideally Python 3.11, to help prevent dependency errors later on. You can run the following commands to create and activate your venv:
```
python3.11 -m venv .venv
source .venv/bin/activate
```
If you wish to deactivate your venv, simply run `deactivate`.

Because CAmp utilizes ACE to run properly, one must install and set up ACE first before attempting to install and run CAmp. Set-up instructions for ACE can be found in the README [here](https://github.com/JHUAPL-DTNMA/dtnma-ace/tree/main). To install ACE via pip and point to a specific repo and branch (in this case, the main branch) like so: 
```
pip install git+https://github.com/JHUAPL-DTNMA/dtnma-ace.git@main
```
To install development and test dependencies for this project, run from the root directory (possibly under sudo if installing to the system path):
```sh
pip3 install -r <(python3 -m piptools compile --extra test pyproject.toml 2>&1)
```

If this command fails, you may have to install the pip-tools package first and then run two separate commands like so:
```
pip3 install pip-tools
python3 -m piptools compile --extra test pyproject.toml
pip3 install -r requirements.txt
```

If the `python3 -m piptools compile --extra test pyproject.toml` command fails due to the following error: "Could not find a version that satisfies the requirement dtnma-ace (from versions: none)", then one solution is to remove the `dtnma-ace` dependency from the `pyproject.toml` file via a text editor and then try the command again.

To execute all unit tests, importing CAMP from the source tree, run:
```
PYTHONPATH=src/ python3 -m pytest -v --cov=camp test
```

To install the project itself from source run:
```
pip3 install .
```
If you are still encountering installation errors, you may need to update the submodules:
```
git submodule update --init --recursive
```

### View Command Options for CAmp

```sh
camp -h
```

### Basic Usage

The camp tool takes a YANG representation of an ADM for a network protocol as input and calls each of the included generators to generate files for the ADM.

> [!NOTE]
> The included [`example-test.yang`](test/data/example-test.yang) and [`example-variety`](test/data/example-variety.yang) modules provides an example of how an ADM module should be formatted.
> For more information on this data model, please consult the [DTNMA Application Data Model](https://datatracker.ietf.org/doc/draft-ietf-dtn-adm-yang/) IETF draft.

Given the YANG representation of the ADM, run camp with:

```sh
camp <adm.yang>
```

The command argument only provides the principal module for which source is generated.
The environment variables `ADM_PATH`, `XDG_DATA_HOME`, and `XDG_DATA_DIRS` affect module import search behavior as described in the [command documentation](https://jhuapl-dtnma.github.io/dtnma-camp/camp.html#environment-variables).

### Output

During a successful camp execution, output similar to the following will be
printed to STDOUT.

```
INFO:camp.tools.camp:Loading <path_to_yang_file>/<adm.yang>  ...
INFO:camp.tools.camp:Finished loading ADM <adm>
INFO:camp.tools.camp:Generating files under ./
INFO:camp.tools.camp:Generating <adm>.h ...
INFO:camp.tools.camp:done.
INFO:camp.tools.camp:Generating <adm>.c ...
INFO:camp.tools.camp:done.
INFO:camp.tools.camp:Generating <adm>.sql
INFO:camp.tools.camp:done.
[ End of CAmpPython Execution ]
```

This output shows that camp completed a successful generation of each of the
files listed. Use the `-o`flag with camp to redirect output to a directory 
different from the current one.

```
    camp <adm.yang> -o <output_directory>
```

If the path at <output_directory> does not already exist, camp will create it.

> Camp will not delete any existing directory structure, but files present in
> the output directories with the same name as generated files will be
> overwritten. 

Custom Code and Round-tripping
------------------------------

The `adm_<adm>_impl.c` and `adm_<adm>_impl.h` files generated for the DTNMA agent
contain functions whose bodies cannot be automatically generated with knowledge
of the ADM alone. When generated, these fuctions are marked with tags similar to
the following:

```
    /*
     * +----------------------------------------------------------------------+
     * |START CUSTOM FUNCTION <function_name> BODY
     * +----------------------------------------------------------------------+
     */	
    /*
     * +----------------------------------------------------------------------+
     * |STOP CUSTOM FUNCTION <function_name> BODY	
     * +----------------------------------------------------------------------+
     */	
```

Additionally, the user may wish to add additional custom functions and/or header
files to these generated files. To allow re-generation of camp files with
minimal re-work for custom code in these files, camp has a 'roundtripping'
feature that allows preservation of these custom additions in subsequent file
generations by "scraping" from existing implementation files.

The roundtripping feature in camp will save any code in the file that falls
between camp custom tags, and will add it to the newly-generated version of the
file. This feature is controlled by the `--scrape` and `--no-scrape` command options.

Current acceptable custom tags are:

- custom function body (example above)
- custom includes (`/* [START|STOP] CUSTOM INCLUDES HERE */`)
- custom (static) functions (`/* [START|STOP] CUSTOM FUNCTIONS HERE */`)
- pre-model-init actions (`/* [START|STOP] CUSTOM PRE-INIT HERE */`)
- post-model-init actions (`/* [START|STOP] CUSTOM POST-INIT HERE */`)

For custom function bodies, the <function_name> included in the custom function
tag must be the same as the one used in the ADM for the custom function to be
copied over to the correct area of the new file. 

### CAmp Architecture

The online [API documentation](https://jhuapl-dtnma.github.io/dtnma-camp/index.html) for CAMP contains package and module structure.

### Adding Generators

To add a new generator to camp, create a python script that creates the file
and add it to the `src/camp/generators/` directory. Then, in src/.py, 
import the new generator and add it to the file generation code of the `main()`
function (starting at line 105).

All generators should: 
- define a `create()` method as their main function, which takes as its first 
  and second argument:
    1. a Retriever object (pre-populated with the ADM passed to camp)
    2. a string that represents the path to the output directory
- utilize the Retriever object to access fields of the ADM module
- place generated file(s) in the output directory passed as the second argument
  to the `create()` function (the generator may choose to make a sub-directory 
  in the output directory)


## Contributing

To contribute to this project, through issue reporting or change requests, see the [CONTRIBUTING](CONTRIBUTING.md) document.
