The @ShortCIdentifiers annotation

It is possible to add annotations to a statechart’s specification to alter their or the code generator’s behavior, see Statechart Annotations.

The C/C++ domain offers one more annotation: @ShortCIdentifiers helps you to keep the generated code compliant to rules which require C identifiers not to be longer than 31 characters (or rather, to be uniquely identified by the first 31 characters). To achieve this, instead of aggressively shortening names which are part of a statechart’s API, YAKINDU Statechart Tools gives feedback about the names that will be generated and warns if any user input results in C code that is non-compliant with the 31 character rule. This puts the user in charge of the naming scheme and keeps the resulting C identifiers predictable.

This is mainly done by:

  1. Using only the actual state’s name to identify it and forcing you to use individual names for all states
  2. Checking all names that will be generated by constructs in the statecharts and providing you with feedback if any of them will be longer than 31 characters
  3. An intelligent name shortening strategy is applied to the static functions in the statechart’s source file that keeps a good balance between readability and shortness

Please note that the generator model’s option statemachinePrefix is ignored when @ShortCIdentifiers is used.

Keep in mind that all public functions and types of the statechart are prefixed with its name, so keeping that one short helps a lot.

Example

See the following example:

Unambiguous state names produce errors

State names that are not globally unique produce errors.

Warnings for elements in the definition section

The name of some elements in the definition section produces warnings because resulting identifiers in the source code will be longer than 31 characters.

All issues resolved

All issues resolved: the states were renamed to be globally unique and some identifiers as well as the statechart’s name were shortened to keep everything short.

The state’s names need to be globally unique because of a change in the naming scheme of the state enum.

Enum without @ShortCIdentifiers:

/*! Enumeration of all states */ 
typedef enum
{
	House_last_state,
	House_main_region_Idle,
	House_main_region_Automation,
	House_main_region_Automation_heater_Manual,
	House_main_region_Automation_heater_Auto,
	House_main_region_Automation_heater_Auto_modes_Normal,
	House_main_region_Automation_heater_Auto_modes_Absence,
	House_main_region_Automation_lights_Lights_Off,
	House_main_region_Automation_lights_Lights_On,
	House_main_region_Automation_pond_Pond_Off,
	House_main_region_Automation_pond_Pond_On
} HouseStates;

Enum with @ShortCIdentifiers:

/*! Enumeration of all states */ 
typedef enum
{
	House_last_state,
	House_Idle,
	House_Automation,
	House_Manual,
	House_Auto,
	House_Normal,
	House_Absence,
	House_Lights_Off,
	House_Lights_On,
	House_Pond_Off,
	House_Pond_On
} HouseStates;

Notice how the state’s names are not prefixed with their containing regions anymore to save characters.

The name shortening algorithm for the static functions works like this, again without @ShortCIdentifiers:

/* prototypes of all internal functions */
static sc_boolean check_main_region_Idle_tr0_tr0(const House* handle);
static sc_boolean check_main_region_Automation_tr0_tr0(const House* handle);
static sc_boolean check_main_region_Automation_heater_Manual_tr0_tr0(const House* handle);
static sc_boolean check_main_region_Automation_heater_Auto_tr0_tr0(const House* handle);
static sc_boolean check_main_region_Automation_heater_Auto_modes_Normal_lr0_lr0(const House* handle);
static sc_boolean check_main_region_Automation_heater_Auto_modes_Normal_tr0_tr0(const House* handle);
static sc_boolean check_main_region_Automation_heater_Auto_modes_Absence_lr0_lr0(const House* handle);
static sc_boolean check_main_region_Automation_heater_Auto_modes_Absence_tr0_tr0(const House* handle);
static sc_boolean check_main_region_Automation_lights_Lights_Off_tr0_tr0(const House* handle);
static sc_boolean check_main_region_Automation_lights_Lights_On_tr0_tr0(const House* handle);
static sc_boolean check_main_region_Automation_pond_Pond_Off_tr0_tr0(const House* handle);
static sc_boolean check_main_region_Automation_pond_Pond_On_tr0_tr0(const House* handle);

With @ShortCIdentifiers annotation:

/* prototypes of all internal functions */
static sc_boolean Idle_tr0_check(const House* handle);
static sc_boolean Automation_tr0_check(const House* handle);
static sc_boolean Manual_tr0_check(const House* handle);
static sc_boolean Auto_tr0_check(const House* handle);
static sc_boolean Normal_lr0_check(const House* handle);
static sc_boolean Normal_tr0_check(const House* handle);
static sc_boolean Absence_lr0_check(const House* handle);
static sc_boolean Absence_tr0_check(const House* handle);
static sc_boolean Lights_Off_tr0_check(const House* handle);
static sc_boolean Lights_On_tr0_check(const House* handle);
static sc_boolean Pond_Off_tr0_check(const House* handle);
static sc_boolean Pond_On_tr0_check(const House* handle);