                   _________________________________

                    NAMED CONSTANT GENERATOR README

                           Johannes Willkomm
                   _________________________________


Table of Contents
_________________

1 About
2 Obtaining
3 Installing Named Constant Generator
4 Using Named Constant Generator
.. 4.1 Defining named constants
.. 4.2 Generating C/C++ code
.. 4.3 Using the generated code in your program
.. 4.4 Generating Matlab code
.. 4.5 Generating JavaScript code
5 About this file





1 About
=======

  Named Constant Generator (GenNC) is a utility to define and maintain
  sets of named constants (enumerations) in C and C++ software. Named
  constants are defined by a XML documents in a simple format. The
  program gennc generates code from this definition that not only
  contains an enum definition corresponding to the input, but also a set
  of utility functions. These offer the following functionality:

  - Convert from constant values (integers) to names
  - Convert names (case insensitive) to constant values (integers)
  - Inquire number of constant values
  - Enumerate constant values

  These function allow the use of user friendly names instead of numbers
  in option processing. Since the conversion functions are generated,
  they are guaranteed to be consistent. A common prefix can be defined
  for the enumeration names, which is not considered by the name to
  value conversion, allowing both save programming and easy usage. The
  functions can generated as plain C functions of as static class
  methods.


2 Obtaining
===========

  Named Constant Generator is kindly hosted at the Savannah site
  *Savannah.nongnu.org*. The main project site is
  [https://savannah.nongnu.org/projects/named-constant/] and the project
  homepage is [http://www.nongnu.org/named-constant/].

  Download the latest version in source from
  [http://download.savannah.gnu.org/releases/named-constant/]. You also
  find there .deb packages for the Debian and Ubuntu distributions.


3 Installing Named Constant Generator
=====================================

  On the command line, type:

  ,----
  | make install prefix=/usr/local/named-constant
  `----

  To install to directory /usr/local/named-constant. The default
  directory is /usr.

  When installed to a directory other then /usr, set the environment
  variable GENNC_HOME to the installation directory:

  ,----
  | export GENNC_HOME=/usr/local/named-constant
  `----

  Also add the bin subdirectory to the PATH:

  ,----
  | export PATH=$PATH:$GENNC_HOME/bin
  `----


4 Using Named Constant Generator
================================

4.1 Defining named constants
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  Define your named constants using an XML file. As an example refer to
  [./example.ncd.xml]:

  ,----
  | <ncdef name="demo" c-prefix="CONSTANT_">
  |    <c val="0" name="A">
  |      <comment>Constant A</comment>
  |    </c>
  |    <c val="1" name="B">
  |      <comment>Constant B</comment>
  |    </c>
  |    <c val="2" name="C">
  |      <comment>Constant C</comment>
  |    </c>
  |    <c name="D">
  |      <comment>Constant D</comment>
  |    </c>
  |    <c val="4" name="E">
  |      <comment>Constant E</comment>
  |    </c>
  | </ncdef>
  `----

  The base name of the input file is `example.ncd' and the name defined
  in the first `name' attribute in the example is `demo', which is used
  in the generated function names and as the name of the C/C++
  *enum*. Finally, the constant prefix is given by the optional
  `c-prefix' attribute, `CONSTANT_' in the example, and the constants
  are named `A', `B', `C', `D', and `E' as given by `name' attributes on
  the `c' elements.  The optional `val' attribute can assign an integer
  value to a constant. Otherwise values are assigned automatically as
  also done in a C *enum*.


4.2 Generating C/C++ code
~~~~~~~~~~~~~~~~~~~~~~~~~

  Generate the corresponding C files by invoking gennc on the definition
  file, in this case using the "function mode", which means that plain
  C++ functions are generated:

  ,----
  | gennc -f example.ncd.xml
  `----

  This generates C or C++ functions to perform the most common tasks
  with the named constants declared in [file:example.ncd.xml]:

  getdemoValue(name): return the value of the constant whose name is given
                      by *name*, which may be prefixed with the
                      /prefix/. The lookup is case-insensitive
  getNumdemo(): return the number of constants
  getdemo(i): return the value of the *i*-th constant
  getdemoName(value): return the name of the constant with *value*

  Three files are generated by this invocation as described in the
  following.

  - [./example.ncd.enum.hh]
  Contains the enum definition.


  - [./example.ncd.hh]
  Contains the declarations of generated functions.


  - [./example.ncd.cc]
  Contains the generated functions.


4.3 Using the generated code in your program
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  Possibly the easiest way is to include all three generated function at
  appropriate locations in your C or C++ project. Just make sure that
  the .ncd.cc file is included only in one compilation unit, for example
  in the file containing the main function. An example is shown in
  Listing 1.

  ,----
  | #include <stdio.h>
  | #include <assert.h>
  | 
  | #include "example.ncd.enum.hh"
  | #include "example.ncd.hh"
  | #include "example.ncd.cc"
  | 
  | int main() {
  |   unsigned i;
  |   int res = 0;
  |   for (i = 0; i < getNumdemo(); ++i) {
  |     enum demo c1 = getdemo(i);
  |     char const *name = getdemoName(c1);
  |     enum demo c1_chck = getdemoValue(name, 0);
  |     assert(c1 == c1_chck);
  |     fprintf(stdout, "Enum value number %d has name \"%s\" and value %d\n",
  |             i, name, c1);
  |   }
  |   return res;
  | }
  `----
  Listing 1: Example C program using the generated constants


4.4 Generating Matlab code
~~~~~~~~~~~~~~~~~~~~~~~~~~

  Generate Matlab files invoking gennc on the definition file, in this
  case using the option `-m Matlab':

  ,----
  | gennc -m Matlab example.ncd.xml
  `----

  This generates a Matlab function *createdemo* in file
  [file:createdemo.m], which is shown in Listing 2.

  ,----
  | % -*- matlab -*- 
  | %%
  | % This file has been automatically generated by 
  | % gennc.sh $Id: gennc-mat.xsl 50 2015-04-08 12:45:49Z jwillkomm $ 
  | % from definition file example.ncd.xml.
  | function res = createdemo()
  |   res.prefix = 'CONSTANT_';
  |   res.index = struct('A',0, 'B',1, 'C',12, 'D',13, 'E',4);
  |   res.lower_index = struct('a',0, 'b',1, 'c',12, 'd',13, 'e',4);
  |   res.names_index = struct('x0','A', 'x1','B', 'x12','C', 'x13','D', 'x4','E');
  |   res.comments = struct('A','Constant A', 'B','Constant B', 'C','Constant C', 'D','Constant D', 'E','Constant E');
  `----
  Listing 2: The generated Matlab function.

  Use the utility functions *gennc_lookup* and *gennc_get_name* to
  translate from name to number and vice versa, as in the example
  program shown in Listing 3.

  ,----
  | %%
  | % Test script for Matlab Named Constant Generator (GENNC)
  | % Copyright (C) 2015 Johannes Willkomm 
  | 
  | %%
  | % add directory with helper functions to path
  | addpath([getenv('GENNC_HOME') '/share/named-constant/matlab'])
  | 
  | %%
  | % run the generated function which creates the ENUM structure
  | gennc = createManagedEnum();
  | 
  | %%
  | % print all entries with their names and values
  | fns = fieldnames(gennc.index);
  | for i=1:length(fns)
  |   val = gennc.index.(fns{i});
  |   assert(val == gennc_lookup(gennc, fns{i}))
  |   assert(strcmp(gennc_get_name(gennc, val), fns{i}))
  |   fprintf(1, 'Enum value number %d has name "%s" and value %d\n',...
  |           i-1, gennc_get_name(gennc, val), gennc.index.(fns{i}));
  | end
  `----
  Listing 3: A test program working with named constants in Matlab.


4.5 Generating JavaScript code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  Generate Matlab files invoking gennc on the definition file, in this
  case using the option `-m Matlab':

  ,----
  | gennc -m JavaScript example.ncd.xml
  `----

  This generates a JavaScript file [file:example.ncd.js], which has code
  similar to the C/C++ mode.


  An example program is shown in Listing 4.

  ,----
  | ////
  | // Test script for JavaScript Named Constant Generator (GENNC)
  | // Copyright (C) 2015 Johannes Willkomm 
  | 
  | assert = require('assert')
  | 
  | function importObject(obj, target) {
  |     for (k in obj) {
  |         target[k] = obj[k]
  |     }
  | }
  | 
  | var ENUM = {}
  | // require the generated script which creates the ENUM structure.
  | // using importObject we can accumulate several name collections in a
  | // single object
  | importObject(require('./example.ncd.js'), ENUM)
  | 
  | // when we import the constant and function names in the global
  | // namespace, we can even use the constant and function names just as
  | // in C/C++: CONSTANT_A, etc.
  | importObject(ENUM, global)
  | 
  | // print all entries with their names and values
  | for (k = 0; k < getNumdemo(); ++k) {
  |     var val = getdemo(k)
  |     var name = getdemoName(val)
  |     console.log('Enum value number %d has name "%s" and value %d',
  |                 k, name, val);
  |     assert(val == getdemoValue(name))
  |     assert(val == getdemoValue(name.toLowerCase()))
  |     assert(val == demo.index[name])
  |     assert(val == demo[demo.prefix + name])
  |     assert(name == demo.names_index[val])
  | }
  `----
  Listing 4: A test program working with named constants in Java.


5 About this file
=================

  This file is part of Named Constant Generator. Copyright (C) 2013,
  2015 Johannes Willkomm. See the file gennc for copying conditions.
