The C code generator is a plug-out directly written in C++.
The generated sources follows the definition made in BOUML at the artifact / class / operation / relation / attribute levels, reusing the parts specific to the C++ language with adapted values.
The best way to get the right generation settings is to load the project C part of the distribution, or to import its settings.
When the code generation is applied on a artifact associated to several classes, the code generation is made for all these classes. Nevertheless the C code generator produce first the code in memory and update the appropriate files only when it is necessary, to not change the last write date of the files for nothing. Depending on the toggle verbose code generation of the global menu Languages the code generator is verbose or not.
The C code generator plug-out may be called on :
a class : in this case the code generation is in fact applied on the class's artifact, then on all the classes associated to this artifact
a artifact : in this case the code generation is in fact applied on all the classes associated to the artifact
a class view : the code generation will be applied on all the sub classes, then on all the artifacts associated to these classes
a deployment view : the code generation is applied on all the sub artifacts
a package (may be the project itself) : the code generation will be applied on all the sub class views and deployment views, then on all their sub classes and artifacts.
When the C code generator is ask through the Tools menu, it is applied on the project, then on all the artifacts.
The name of the generated files depend on the artifact name, the extension depend on the language and is fixed for each by the generations settings (see below), the directory where the files are generated may be set in each package containing directly or indirectly the artifact (see generation directory).
The C definition of a artifact is set through the C++ header and C++ source tabs of the artifact dialog.
The code generation depend on the stereotype of the artifact :
text : the C definition of the artifact is produced without changes, the name of the generated file is the name of the artifact, including the extension.
source : see below.
else nothing is generated for the artifact.
The generated file name is the artifact's name with the extension specified in the first C++ tab of the generations settings
In BOUML the generated code is obtained by the substitution of macros in a text, the macros known by the C code generator are :
${NAME} produce the artifact name capitalized, ${Name} produce the artifact name with the first letter capitalized, ${nAME} produce the artifact name forced in lowercase, at least ${name} produce the artifact name without modification.
${comment} is replaced by the artifact description adding //
${description} is replaced by the artifact description without adding //
${includes} is replaced by the automatically generated #include forms, it is also a good place to add your #include forms, when the ones produced by the code generator are not sufficient. To limit the included files number and to not produce circular #include, the C code generator does not produce an #include to define a type only used by pointer (*). The C code generator does not look at in the operations body, only the operation's profiles, relations and attributes etc ... are used to compute the needed #include list. You can also use dependencies between classes to add #include, and to choose to place them in the header of the source file editing the dependency tab C++. ${includes} and ${all_includes} are exclusive.
Note : the generation settings allows to choose between four ways to produce #include :
without path : ask for the C code generator to generate the #include without relative or absolute path
with absolute path : ask for the C code generator to generate the absolute path of the automatically included files.
with relative path : ask for the C code generator to generate the relative path of the automatically included files, relative to the file containing the #include
with root relative path : ask for the C code generator to generate the relative path of the automatically included files, relative to the directory specified by the generation settings
${all_includes} is replaced by all the automatically generated #include forms, it is also a good place to add your #include forms, when the ones produced by the code generator are not sufficient. In this case the code generator doesn't produce declarations in the header file nor #include in the source file, except the ones added by you. ${all_includes} and ${includes} are exclusive.
${declarations} is replaced by the class declarations when the #include form is not produced, it is also a good place to add your declarations, when the ones produced by the code generator are not sufficient. Produce nothing if ${all_includes} is used.
${definition} is replaced by the definition of the classes and extra artifact definitions associated to the artifact
@{xyz} is replaced by the user property value in case xyz is the key of this property. The property if searched first for the artifact, if not found for the deployment view containing the artifact, if not found in the package containing the deployment view etc ...
The generated file name is the artifact's name with the extension specified in the first C++ tab of the generations settings.
In BOUML the generated code is obtained by the substitution of macros in a text, the macros known by the C++ code generator are :
${NAME} produce the artifact name capitalized, ${Name} produce the artifact name with the first letter capitalized, ${nAME} produce the artifact name forced in lowercase, at least ${name} produce the artifact name without modification.
${comment} is replaced by the description of the artifact adding //
${description} is replaced by the artifact description without adding //
${includes} if ${all_includes} is not used in the header definition, it is replaced by the automatically generated #include and using forms, corresponding to the declaration generated in the header file. If ${all_includes} is used in the header definition, it is replaced by the #include of the header. It is also a good place to add your #include and using forms.
${members} is replaced by the members of the classes associated to the artifact.
@{xyz} is replaced by the user property value in case xyz is the key of this property. The property if searched first for the artifact, if not found for the deployment view containing the artifact, if not found in the package containing the deployment view etc ...
The C++ definition of a class is set through the Uml and C++ tabs of the class dialog.
The generated C type depends on the translation in C++ of its stereotype (see generation settings), a c_enum will produce an enum, c_struct a struct, a c_union an union and a c_typedef a typedef, and a c_module will produce its members (including operations as functions), in the other cases nothing is produced.
In BOUML the generated code is obtained by the substitution of macros in a text, the macros known by the C++ code generator are :
${comment} is replaced by the description of the class adding /* */
${description} is replaced by the class description without adding /* */
${name} is replaced by the class's name
${members} is replaced by the code generated for the class's members (relations, attributes, operations) following the browser order.
${items} only for the enums, is replaced by the enum's items
@{xyz} is replaced by the user property value in case xyz is the key of this property. The property if searched first for the class, if not found for the container of the class (an other class of a class view) etc ...
In the special case where the class is declared external, its C++ type declaration must contains at least one line indicating how the name of the class is generated, the other lines will be added in the header file of the components referencing the class. By default the first line only contain ${name} meaning that the name is produced unchanged, the only allowed keywords are ${name}, ${Name} and ${NAME}. Remember in C you have to add the kind of the type like struct.
The C++ definition of an operation is set through the Uml and C++ tabs of the operation dialog. In C an operation produces a function, and this is done only for classes stereotyped c_module.
In BOUML the generated code is obtained by the substitution of macros in a text, the macros known by the C code generator are :
${comment} is replaced by the description of the operation adding /* */
${description} is replaced by the operation description without adding /* */
${static} produce static in the definition of a function when the operation is a class operation (see the UML tab). The declaration of a non static function is produced in the header file.
${type} is replaced by the returned value type (see the UML tab)
${multiplicity} is replaced by the multiplicity of the return type (see the UML tab), a priori used in a comment
${name} is replaced by the operation's name
${(} and ${)} produce ( and ), but there are also a mark for BOUML to find the parameters list
${t<n>} and ${p<n>} produce the type and name of each parameter (count from 0), this allows you to remove a parameter, add type modifiers etc ...
${m<n>} produce the multiplicity of each parameter (count from 0), a priori used in a comment
${body} is replaced by the body of the operation I nthe source file, this macro may also be replaced by the body itself (BOUML use this way for the get and set operations associated to a relation/attribute). The usage of ${body} has a great advantage : when you hit Default definition or From declaration the body is not cleared ! At least BOUML share the declaration and definition forms of the operations (and other objects) to minimize the needed memory size, ${body} help for this ! The indentation of the keyword ${body} is added at the beginning of each line except the ones starting by a '#' or when the previous one ends by '\'.
@{xyz} is replaced by the user property value in case xyz is the key of this property. The property if searched first for the operation, if not found for the class containing the operation etc ...
If the toggle preserve operations's body is set through the Languages menu, the generators do not modify the body of the operations protected by dedicated delimiters. This means that for them the body definition set through BOUML is not used. The first time you generate the code with the toggle set, because the delimiters are not yet present in the generated code, the operation's body will be updated depending on their definition under BOUML. After, while the toggle is set and the delimiters present, the bodies will not change, allowing you to modify them out of BOUML.
Notes :
In case the file containing a body definition is not consistent with the artifact under BOUML, the body will be regenerated by the code generation, using its definition under the model.
When you import a project, the body of the imported operations must be the right one in the imported model. The preserved bodies of the imported operations will not be find because the identifier of an operation used to mark its body changes during the import.
The bodies under the model are not updated by the code generation
Only the operations using the keyword ${body} may have a preserved body.
The only modification you can do in the lines containing the delimiters is the indent.
The toggle is saved in the file associated to the project, be sure the save is done when you change this toggle !
The C++ definition of an attribute is set through the Uml and C++ tabs of the attribute dialog.
An attribute may be a C variable or the item of an enumeration.
In BOUML the generated code is obtained by the substitution of macros in a text, the macros known by the C++ code generator are :
${comment} is replaced by the description of the attribute adding /* */
${description} is replaced by the attribute description without adding /* */
${static} produce static in the source file when the attribute is a class attribute (see the UML tab). The declaration of a non static variable is produced in the header file.
${volatile} produce volatile when the attribute is volatile
${const} produce const when the attribute is const (see the UML tab)
${type} is replaced by the type of the attribute (see the UML tab)
${stereotype} is replaced by the translation in C++ of the relation's stereotype (see the UML tab)
${multiplicity} is replaced by the multiplicity of the relation (see the UML tab), must be used in case the multiplicity is a vector or array dimensioning ([ and ] are added when they are not present).
${name} is replaced by the attribute's name (see the UML tab)
${value} is replaced by the initial value of the static attribute in the definition part generated in the source file (see the UML tab)
@{xyz} is replaced by the user property value in case xyz is the key of this property. The property if searched first for the attribute, if not found for the class containing the attribute etc ...
The macros known by the C++ code generator are :
${comment} is replaced by the description of the item adding //
${description} is replaced by the item description without adding //
${name} is replaced by the item's name (see the UML tab)
${value} is replaced by the value of the item (see the UML tab)
@{xyz} is replaced by the user property value in case xyz is the key of this property. The property if searched first for the attribute, if not found for the class containing the attribute etc ...
The C++ definition of a relation is set through the Uml and C++ tabs of the relation dialog.
In BOUML the generated code is obtained by the substitution of macros in a text, the macros known by the C++ code generator are :
${comment} is replaced by the description of the relation adding /* */
${description} is replaced by the relation description without adding /* */
${static} produce static in the source file when the relation is a class relation (see the UML tab). The declaration of a non static variable is produced in the header file.
${const} produce const when the relation is read-only (see the UML tab)
${type} is replaced by the class pointed by the relation (see the UML tab)
${name} is replaced by the relation's role name (see the UML tab)
${inverse_name} is replaced by the name of the inverse role (see the UML tab)
${value} is replaced by the initial value of the static relation in the definition part generated in the source file (see the UML tab)
${volatile} produce volatile when the relation is volatile
${stereotype} is replaced by the translation in C++ of the relation's stereotype (see the UML tab)
${multiplicity} is replaced by the multiplicity of the relation (see the UML tab), must be used in case the multiplicity is a vector or array dimensioning ([ and ] are added when they are not present).
${association} is replaced by the association class (see UML tab)
@{xyz} is replaced by the user property value in case xyz is the key of this property. The property if searched first for the relation, if not found for the class containing the relation etc ...
The dependency may produce an #include of the artifact associated to the target class, and you can choose to place this #include in the header or source file by editing the dependency using the tab C++.
Previous : C++ roundtrip
Next : Java generator