223 lines
9.0 KiB
Plaintext
223 lines
9.0 KiB
Plaintext
|
|
|
|
Description of the helper program stic*/bin/cgen
|
|
|
|
cgen is copyright 2001 to 2007, Thomas Schmitt <stic-source@gmx.net>
|
|
and provided under BSD license.
|
|
|
|
Compilation:
|
|
cc -g -o cgen cgen.c ctyp.c smem.c
|
|
|
|
|
|
cgen produces a class stub in C programming language. The data structure of
|
|
the class is described by some lines which get read from stdin. The stub will
|
|
consist of four files which emerge in the current working directory:
|
|
<classname>.h public header file of the class
|
|
<classname>.c automatically generated C code of the class
|
|
plus a copy of <classname>.c.methods
|
|
<classname>_private.h private header file of the class
|
|
<classname>.c.methods safe storage for manually created functions.
|
|
From here they get copied into the generated stub.
|
|
If such a file is missing, a dummy gets created.
|
|
It will define a struct <ClassnamE> for representing the class data aspects,
|
|
construtor <Classname>_new(), destructor <Classname>_destroy(),
|
|
getter <Classname>_<element>_get() for each structure element.
|
|
Some more functions get added for particular class and element roles.
|
|
|
|
cgen normally refuses to overwrite existing files because it supposes that
|
|
those contain code added by the human programmer.
|
|
Human programmer enhancements may be explanatory comments, class specific
|
|
methods, initial element values and other special precautions within the
|
|
generated functions.
|
|
As long as the modelling phase is going on, one may store such human code
|
|
in <classname>.c.methods and may use command line option -overwrite for
|
|
modelling development cycles.
|
|
|
|
At some point of model matureness one may decide to give up cgen and the
|
|
.c.method files and to go on only with _private.h , .h and .c files.
|
|
|
|
|
|
Command line options
|
|
|
|
-no_stic prevents usage of stic_dir/s_tools/*.[ch]
|
|
|
|
-ansi generates ANSI C function heads and makes file <classname>.h hold
|
|
only public definitions: an opaque declaration of the class struct
|
|
and a list of function prototypes. The definiton of the class
|
|
struct is then in <classname>_private.h .
|
|
-global_include filename
|
|
sets the name of a file which will contain globally necessary
|
|
declarations. Currently it lists the existence of all class
|
|
structs.
|
|
-lowercase generate struct <classname> rather than struct <ClassnamE> and
|
|
function names <classname>_func() rather than <Classname>_func() .
|
|
-overwrite allows to overwrite files <classname>_private.h, <classname>.h
|
|
and <classname>.c, but not <classname>.c.methods.
|
|
|
|
|
|
Input line format:
|
|
|
|
There are two states of input: class level and element level.
|
|
Exampes are shown below with class roles and element roles.
|
|
|
|
Input starts at class level. A class level line may be one of
|
|
|
|
- Comment. A line which begins with '#' is ignored on class level.
|
|
|
|
- Empty. A line with no characters is a comment with empty text (i.e. ignored).
|
|
|
|
- Class. Options which begin with '-' and finally a word in lowercase letters
|
|
which defines the <classname>. The classname leads to a struct ClassnamE
|
|
and some class methods implemented as C functions <Classnname>_<func>().
|
|
|
|
- End of input. Line "@@@" or EOF at stdin end the program run.
|
|
|
|
After a class line, input switches to element level where a line may be:
|
|
|
|
- Comment. A line which after some white space begins with '#' is considered
|
|
a comment. The preceeding white space is ignored and the text after '#' is
|
|
eventuellay trimmed by a single blank at both ends. This text will be part
|
|
of the class struct definition within file <classname_private>.h as a single
|
|
C comment line /* ... */. The sequence of elements and comments is preserved.
|
|
An empty comment text leads to an empty line in <classname_private>.h.
|
|
|
|
- Empty. A line with no characters is a comment with empty text.
|
|
|
|
- Element. Options which begin with '-', eventual C keywords "unsigned" or
|
|
"volatile", type or "struct <NamE>", element name. This leads to a struct
|
|
element which is taken into respect in some class methods. Depending on the
|
|
options in this line, some element methods <Classnname>_<func>_<element>()
|
|
may get generated.
|
|
|
|
- End of class. A single '@' marks the end of the element list and brings
|
|
input back to class level. I.e. next is expected another class name or
|
|
"@@@" or EOF at stdin.
|
|
|
|
Input semantics:
|
|
|
|
A class can have one of two roles:
|
|
|
|
- Standalone class.
|
|
Input example:
|
|
my_class
|
|
|
|
- Listable class, which has pointers to peer instances: .prev and .next
|
|
Such classes get a list destructor <Classname>_destroy_all() which destroys
|
|
all members of a list (which is given by any of the list members).
|
|
Such a class should have a pointer *boss as first element in which case
|
|
the constructor will look like
|
|
<Classname>_new(struct <ClassnamE> **o,struct <Some_clasS> *boss,int flag);
|
|
There is a function <Classname>_link() which inserts an instance into a list
|
|
and a function <Classname>_count() which tells the number of list members.
|
|
For pseudo random access there is function <Classname>_by_idx().
|
|
Input example:
|
|
-l my_class
|
|
|
|
|
|
A modifier is defined for classes:
|
|
|
|
- Bossless. Disables a special boss-subordinate relationship which is created
|
|
if the first element of a class is a struct pointer with the name "boss".
|
|
Like
|
|
-l <classname>
|
|
-v struct Some_clasS *boss
|
|
Normally such a parameter *boss becomes part of the constructor method
|
|
<Classname>_new(struct <ClassnamE> **o, struct Some_clasS *boss, int flag);
|
|
This relationship is typical for a listable class and a single class which
|
|
is designed to host instances of that listable class. Therefore one gets a
|
|
warning if a listable class does not begin with a struct pointer *boss.
|
|
But if -b is given, then CgeN ill not include a parameter *boss into the
|
|
constructor. It will rather look normal:
|
|
<Classname>_new(struct <ClassnamE> **o, int flag);
|
|
It will not warn if the first element of a listable class is not struct
|
|
pointer *boss.
|
|
|
|
|
|
Elements have one of the following roles:
|
|
|
|
- Value. It provides only storage for a C data type (which may be a C pointer
|
|
despite the role name "value"), a getter method <Classname>_<element>_get(),
|
|
and a setter method <Classname>_<element>_set().
|
|
Input examples:
|
|
-v int i
|
|
-v int a[100]
|
|
-v char *cpt
|
|
-v struct xyz x
|
|
-v struct xyz *xpt
|
|
|
|
- Managed. This has to be a pointer to a struct <XyZ> or to char. It will not
|
|
get attached to an object by the stub's code but its destructor
|
|
<Xyz>_destroy() will be called by <Classname>_destruct(). In case of (char *)
|
|
it is supposed that a non-NULL value has been allocated by malloc().
|
|
Managed (char *) types get a setter function <Classname>_<element>_set()
|
|
which allocates memory and copies the textstring from its parameter.
|
|
Input examples:
|
|
-m struct XyZ *xyzpt
|
|
-m char *textstring
|
|
|
|
- Chainlink. A pair of prev-next-style pointers to the own class struct.
|
|
Function <Classname>_destruct() will unlink the affected instance and
|
|
put together its link partners.
|
|
Input example (there must always be two consequtive -c lines):
|
|
-c struct My_clasS *up
|
|
-c struct My_clasS *down
|
|
|
|
- List. A pair of pointers to the struct <XyZ> of a listable class. The first
|
|
one <ls> holds the start of the list, the second one <eol> holds the end.
|
|
The getter function has an additional argument idx:
|
|
<Classname>_get_<ls>(struct <ClassnamE> *o, int idx, struct <XyZ> **pt,
|
|
int flag)
|
|
idx == 0 is the start of the list, idx=1 the next element, ...
|
|
idx == -1 retrieves the last element of the list.
|
|
For insertion of list items there is provided method <Classname>_new_<ls>().
|
|
The inserted item is reachable via the getter function with idx == -1
|
|
<Classname>_destroy() instance calls <Xyz>_destroy_all(). Note that the end
|
|
pointer is always generated as private element (-p).
|
|
Input example (there must always be a -l and a -v line):
|
|
-l struct XyZ *list_start
|
|
-v struct XyZ *list_end
|
|
|
|
The availability of getter method <Classname>_get_<element>(), and setter
|
|
method <Classname>_set_<element>_set() can be controled by two modifiers:
|
|
|
|
- Readonly. Only a getter method.
|
|
Input example
|
|
-r -v int broadcasted_status
|
|
|
|
- Private. Neither getter nor setter method.
|
|
Input example
|
|
-p -v int private_value
|
|
|
|
- Bossless listable. This marks elements which are listable objects but do not
|
|
expect a boss pointer in their constructor. See above: Listable class and
|
|
the bossless modifier for classes.
|
|
Input example
|
|
-b -l struct XyZ *list
|
|
-v struct XyZ *last_in_list
|
|
|
|
- Initialization free. The class constructor will not initialize this element.
|
|
This modifier has to be used if neither NULL nor 0 are suitable
|
|
initialization values.
|
|
|
|
Example run:
|
|
|
|
rm class_x.c class_x.h class_y.c class_y.h
|
|
bin/cgen <<+
|
|
-l class_x
|
|
-r -v struct Boss_clasS *boss
|
|
-v int x
|
|
-r -v struct stat stbuf
|
|
-m struct Class_Y *y
|
|
-m char *text
|
|
-c struct Class_X *master
|
|
-c struct Class_X *slave
|
|
-b -l struct Class_X *provider
|
|
-p -v struct Class_X *last_provider
|
|
@
|
|
-b -l class_y
|
|
-r -v char providername[80]
|
|
@
|
|
+
|
|
|
|
|