gr1c
0.13.0
|
This page describes how to navigate the code in a way useful to those who wish to modify it, link against, etc.
The main program for users is gr1c
. Besides access to the basic GR(1) synthesis routine, gr1c
handles commands like gr1c rg
that cause separate programs to be invoked, e.g., gr1c-rg
. These programs must be on the system path, so ./gr1c rg
may fail if the local directory is not on the path. To add it, try
export PATH=`pwd`:$PATH
.
Root directory of the source tree. Contains LICENSE.txt, the directories listed below, etc.
src/
Source code. Noteworthy files for beginning to learn the internals of gr1c include:
common.h
, which defines the version number. main.c
, main entry point for the program gr1c
. rg_main.c
, main entry point for the program gr1c-rg
. exp/
Consult exp/README.txt
. The main entry point for the program gr1c-patch
is in exp/grpatch.c
.
aux/
Consult aux/README.txt
. The main entry point for the program gr1c-autman
is in aux/autman.c
.
examples/
Example specifications, edge change files, etc. Some files are intended for use with the program gr1c
, others with rg
, and still others with grpatch
and grjit
, or some combination thereof. Documentation for examples is provided in examples/README.md
or in comments at the top of the respective file.
tests/
A test suite, which is usually invoked by make check
from the root directory. Tests are built and run by tests/Makefile
. An environment variable VERBOSE
may be set to 1 to indicate that testing progress should be reported as it happens.
doc/
Documentation source files and configuration.
packaging/
Consult packaging/README.txt
.
Internally, variables of non-Boolean domains are mapped into a set of Boolean variables that use the original variable name as a prefix and then append the corresponding bit index. E.g., y
with domain of {0,1,2} would translate to 2 variables, y0
, y1
that are used to encode the bitvectors 00, 01, and 10. 11 (i.e., y0
and y1
both set to True
) is unreachable.
A significant consequence is that the number of states generated internally happens at boundaries of powers of two, e.g., so that an integer variable domain of [0,513]
incurs the same number of states as [0,1023]
.
Test coverage can be measured by gcov, which is distributed with GCC. To use it, add -fprofile-arcs -ftest-coverage
to CFLAGS and -lgcov
to LDFLAGS in the root Makefile and tests/Makefile. Examples of how to do so are in the comments of these Makefiles. Then, make check
to run all tests. (Consider doing make clean && make all
before to ensure that all built files are up-to-date.) The coverage report for a source file can be obtained from gcov
by calling it with the file name. E.g.,
gcov automaton.c
will produce automaton.c.gcov, which describes coverage of src/automaton.c. To obtain coverage-annotated files for all C source code, try
for k in `find src exp aux -name \*.c`; do gcov `basename ${k}`; done
Usage on gr1c of several tools for static analysis, i.e., tools that examine the source code without running the programs, are given below. The treatment is not exhaustive. For Clang static analyzer http://clang-analyzer.llvm.org, try
scan-build make all
For cppcheck http://cppcheck.sourceforge.net, try
cppcheck --enable=all src 2> cppcheck-issues.txt
Other websites about cppcheck are https://github.com/danmar/cppcheck/ and https://sourceforge.net/projects/cppcheck/.
Several tools for dynamic analysis, i.e., tools that examine the behavior of live processes, are listed below. The treatment is not exhaustive.
Scripts and other files useful for creating release distributions are under packaging/
. Currently these are Git-agnostic, so the version must be explicitly declared by setting the environment variable GR1C_VERSION
. If Git is installed and a release commit is checked-out, then try
export GR1C_VERSION=`git describe --tags --candidates=0 HEAD|cut -c 2-`
RELEASE=1
at the top of the root Makefile.RELEASE=0
at the top of the root Makefile to indicate that commits after the tag are under development.Version numbers are of the form MAJOR.MINOR.MICRO; when a tag is made for a release, it must be named as the version number preceded by "v", e.g., "v0.6.1" for version 0.6.1. The next commit following a release tag should use a version number greater than that of the tag. For example, the first commit after that tagged "v0.6.1" has version 0.6.2.
For C, I mostly prefer the Linux kernel style (as expounded in Documentation/CodingStyle in the Linux source tree), except that indentation should use spaces (not tab charactors) and be in units of 4 spaces. Documentation in source code should usually be line-wrapped at 70 characters (default in Emacs), but more importantly, lines of code or comments should rarely exceed 80 characters in length. README or other plain text files describing nearby stuff are written in Markdown and line-wrapped at 80 characters. Many comments in the code (e.g., if beginning with /**
) and .md
files under the doc
directory are processed by Doxygen. With Emacs it may be possible to achieve the correct line width and tab conventions by adding the following to your .emacs
configuration file.
(add-hook 'rst-mode-hook '(lambda () (setq fill-column 80))) (add-hook 'c-mode-common-hook '(lambda () (c-add-style "scott-c-style" scott-c-style t))) (add-hook 'c++-mode-common-hook '(lambda () (c-add-style "scott-c-style" scott-c-style t))) (setq scott-c-style '((tab-width . 4) (indent-tabs-mode . nil) (c-basic-offset . 4)))