
Create development environment
------------------------------

Defaults to Python 3.

    make virtualenv
    make develop



    make venv=/usr/tce/packages/python/python-3.7.2/bin/virtualenv virtualenv
    make develop

pythondevmode
-------------

If this environment variable is set to a non-empty string, enable
Python Development Mode, introducing additional runtime checks that
are too expensive to be enabled by default.  New in version 3.7.

setenv PYTHONDEVMODE 1

Parse test
----------

Parse some strings in ``tests/check_decl.py`` and compare to reference
in ``tests/check-decl.output``.
The parse trees are compared.

    make test-decl
    make test-decl-diff
    make test-decl-replace

Run unittest
------------

    make test

The tests are in the ``tests`` directory.

Run a single unittest:

    ../build/temp.linux-x86_64-3.7/venv/bin/python test_declast.py CheckParse.test_inheritance

Running a single Python unit test.

    # Use the Python in the virtual environment
    setenv WORK  .../build/temp.linux-x86_64-3.7
    setenv PYTHONEXE $WORK/venv/bin/python

    cd tests
    $PYTHONEXE -m unittest test_ast.CheckAst.test_d_generate1

    # Run a regression test
    setenv PYTHONPATH $WORK/run/struct-class-c/python
    cd regression/run/struct-class-c/python
    $PYTHONEXE -m unittest test.Struct.test_Arrays1


Regression tests
----------------

    make do-test

Run the script test/do-test.py over some yaml files.

The output is saved in build/temp.linux-x86_64-3.7/regression

Update fiducials

    make do-test-replace [ do-test-args=tutorial ]

Running a single test

    make do-test do-test-args=tutorial


Running a test manually (with pdb).
Run the test via do-test.  Extract run line from test.log
cd $WORK/build/temp.linux-x86_64-3.7/regression/classes
$WORK/build/temp.linux-x86_64-3.7/venv/bin/shroud ...  $WORK/regression/input/classes.yaml


Test generated code
-------------------

    make test-all

Compile the generated code (after do-test-replace) and run some unit
tests.  These tests are in tests/run and contains a small library
which is wrapped by the corresponding yaml file
(i.e. tests/tutorial.yaml wraps run/tutorial)

``regression/run/Makfile`` is top level makefile.
``regression/run/default.mk`` has compiler flags.

Compile a single test

    fortran-XXX        compile wrappers for XXX.yaml
    test-fortran-XXX   run test for XXX.yaml
    test-fortran       All Fortran tests
    test-cfi           Fortran tests with C-Fortran-Interface

    py-XXX             compile module for XXX.yaml
    test-python-XXX    run Python test for XXX.yaml
    test-python        All Python tests

Adding a regression test
------------------------

* Add a file ``regression/input/newtest.yaml``.
* Run the test ``make do-test do-test-args=newtest``
* Look for errors in ``$(tempdir)/regression/log.test``
  ``make print-tempdir``.
* Add a call to TestDesc in ``regression/do-test.py`` to run *newtest*.
* ``mkdir regression/run/newtest``
* Create files ``Makefile``, ``newtest.cpp`` and ``newtest.hpp``

* Add to variable *fortran-test-list-std* in
  ``regression/run/Makefile`` to run as part of ``test-all`` target.
  Try ``make -n test-fortran-newtest`` to see commands which will be
  run.


Several tests are run with language=c and c++.  To accomplish this,
the run/pkg files have the .c suffix. The sync-cxx target copies the
files to another directory with a .cpp suffix. This directory is added
to the VPATH.  For the Python tests, there is an explicit run to force
the use of CXX.  The VPATH finds both the C and C++ files since they
have the same stem.

reference counting
------------------

``Python-3.9.12/Misc/valgrind-python.supp``

```
valgrind --tool=memcheck --suppressions=valgrind-python.supp \
                                          python -E -tt ./my_python_script.py
```

Build Python with ``--with-address-sanitizer --with-pydebug``


file dependency
---------------

main.py
wrapX.py  generate.py
fcfmt.py  metaattrs.py
ast.py
declast.py declstr.py
typemap.py statements.py todict.py
whelpers.py
util.py visitor.py
error.py  # no dependencies
metadata.py



Error with template: 'call SHROUD_copy_array_{cxx_T}({c_var_context}, {f_var}, size({f_var},kind=C_SIZE_T))'
can be debugged by changing util.wformat to remove comment to provide a backtrace.


adding a type
-------------

typemap.py

ast.py LibraryNode.create_std_names()
  add to namespace

declast.py  get_canonical_typemap()
  Convert 'long int' into 'long'


formatting generated code
-------------------------

Always use `{nullptr}` instead of `NULL`.  Helps C++.

error checking
--------------

Write a `#error` line instead of generating bad code so the
compiler will point out the error.

debugging
---------

```
import yaml
print(yaml.dump(cf_tree, default_flow_style=False))

import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint( dict or tuple )
```

import pdb; pdb.set_trace()

% yes c | python ... >&! out
Answer 'c' to all pdb prompts.


To start pdb on an exception, uncomment line in main.py
#sys.excepthook = info
