/** @page guide_developer_styleguide Style Guide @brief Guide for the coding style used in this SDK. The goal of this style guide is to encourage a readable and consistent coding style across the entire SDK. @section guide_developer_styleguide_codingstyle Coding Style @brief The coding style used in this SDK. The coding style aims to produce code that is readable and easy to debug. An example is provided in @ref guide_developer_styleguide_codingstyle_example. @subsection guide_developer_styleguide_codingstyle_generalguidelines General guidelines @brief General guidelines for library style. - Libraries should only use features from [C99](https://en.wikipedia.org/wiki/C99) and earlier. - Libraries should [log](@ref logging) extensively. - Code should be well-commented. - Only `/*` and @c *`/` should be used to start and end comments. - All comments end with a period. - Only spaces should be used for indenting. A single indent is 4 spaces. No tab characters should be used. - A parenthesis is usually followed by a space (see @ref guide_developer_styleguide_codingstyle_example). - Lines of code should be less than 80 characters long, although longer lines are permitted. - All local variables should be declared at the top of a function. - All global variables should be declared at the top of a file. - Variables are always initialized. - A separator is placed between different sections of a file. The current separator is: @code{c} /*-----------------------------------------------------------*/ @endcode - All files must include `iot_config.h` at the top of the file before any other includes. - `static` functions must have a declaration at the top of the file and be implemented before any application-facing functions. @subsection guide_developer_styleguide_codingstyle_typeguidelines Type guidelines @brief Guidelines for variable types. - Only fixed-width integer types should be used. Exceptions for `bool` and types required by third-party APIs. - The default integer in the libraries should be 32 bits wide, i.e. `int32_t` or `uint32_t`. - Sizes and lengths should be represented with `size_t`, and Boolean variables with `bool`. @subsection guide_developer_styleguide_codingstyle_example Example File @brief An example file that follows the coding style rules. See @ref guide_developer_styleguide_naming for how to name the functions, variables, and macros. @code{c} /* Included headers are at the top of the file. The config file include is always first. */ #include "iot_config.h" /* Standard includes are immediately after the config file. They are sorted alphabetically. * They use angle brackets <> around the file name. */ /* Standard includes. */ #include #include #include #include /* Library internal headers are included next. They use quotes "" around the file name. */ /* Library internal include. */ #include "private/iot_library_internal.h" /* Error handling include (include only when needed). */ #include "private/iot_error.h" /* Library application-facing headers are included last. They use quotes "" around the file name. */ /* Library include. */ #include "iot_library.h" /*-----------------------------------------------------------*/ /* Defined constants follow the included headers. */ /* When possible, parentheses () should be placed around contant values and a type * should be specified. */ #define LIBRARY_CONSTANT ( ( int32_t ) 10 ) #define LIBRARY_FUNCTION_MACRO( argument ) \ /* Line continuators are right-aligned. */ { \ /* Function-like macros are surrounded by curly braces {}. */ macro_body( argument ); \ } /*-----------------------------------------------------------*/ /* Library typedefs follow the defined constants. */ /* Forward declarations are used only when necessary. They are placed before all * other typedefs. */ typedef int32_t _type_t; typedef struct _structType /* Structs are named along with the typedef. */ { int32_t member; union /* Anonymous structs/unions are permitted only inside of other structs. */ { int32_t a; int32_t b; }; int32_t variableLengthMember[]; /* Variable length arrays (a C99 feature) are permitted. */ } _structType_t; /*-----------------------------------------------------------*/ /* Declarations of static and extern functions follow the typedefs. */ static bool _libraryStaticFunction( void * pArgument, size_t argumentLength ); /* External function declarations should be used sparingly (using an internal * header file to declare functions is preferred). */ extern int32_t IotLibrary_ExternalFunction( void * pArgument ); /*-----------------------------------------------------------*/ /* Declarations of global variables follow the static and extern function * declarations. Global variables are permitted, but should be avoided when * possible. */ /* Global variables are always initialized. */ static int _globalVariable = 0; static int _globalArray[ _LIBRARY_CONSTANT ] = { 0 }; /*-----------------------------------------------------------*/ /* Implementations of static functions follow the global variable declarations. */ static bool _libraryStaticFunction( void * pArgument, size_t argumentLength ) { /* All local variables are declared at the top of the function. Variables are * always initialized. */ size_t i = 0; int32_t localVariable = 0; int32_t * pLocalPointer = ( int32_t * ) pArgument; /* Error handling setup, which declares a status variable type and initial * value. */ IOT_FUNCTION_ENTRY( bool, true ); /* All functions make generous use of the logging library. */ IotLogInfo( "Performing calculation..." ); if( ( pArgument == NULL ) || ( argumentLength == 0 ) ) /* Note the parentheses and spacing in if statements */ { IotLogError( "Bad parameters." ); /* Error handling exit. */ IOT_SET_AND_GOTO_CLEANUP( false ); } for( i = 0; i < argumentLength; i++ ) /* Note the spacing in the for loop. */ { localVariable += IotLibrary_ExternalFunction( pArgument ); IotLogDebug( "Current value is %d.", ( int ) localVariable ); } if( localVariable < 0 ) { IotLogWarn( "Failed to calculate positive value." ); } IotLogInfo( "Calculation done." ); /* Error handling exit. */ IOT_FUNCTION_EXIT_NO_CLEANUP(); } /* A separator is placed between all function implementations. */ /*-----------------------------------------------------------*/ /* Implementations of application-facing functions are at the bottom of the file. */ bool IotLibrary_ApplicationFunction( void ) /* Functions with no arguments have void in their argument list. */ { LIBRARY_FUNCTION_MACRO( _globalArray ); return true; } /* Separator and newline at end of file */ /*-----------------------------------------------------------*/ @endcode @section guide_developer_styleguide_naming Naming @brief Naming convention used in this SDK. The naming convention aims to differentiate this SDK's files, variables, and functions to avoid name collisions. In general: - The first characters of all publicly visible names should identify the name as part of this SDK.
Example: For general-purpose libraries (such as MQTT), names start with `iot_` or `Iot`.
Example: For libraries specific to AWS IoT (such as Shadow), names start with `aws_iot_` or `AwsIot`. - Words in names should be ordered with the most general word first and the most specific word last.
Example: `iot_mqtt_api.c` identifies a file as part of the general MQTT library. `_IotMqtt_ValidateConnect` identifies a function as part of the Internal component of the general MQTT library. - Names should avoid using abbreviations. @subsection guide_developer_styleguide_naming_definedconstantsandenumvalues Defined constants and enum values @brief Naming convention for constants set using preprocessor @c #`define` and enum values. @formattable{defined constants and enum values} @formattableentry{`IOT_`LIBRARY`_`DESCRIPTION
`AWS_IOT_`LIBRARY`_`DESCRIPTION,Defined constants and enum values in application-facing library header files,`IOT_MQTT_SUCCESS` (iot_mqtt.h)
`AWS_IOT_SHADOW_SUCCESS` (aws_iot_shadow.h)} @formattableentry{`IOT_DEMO_`DESCRIPTION
`IOT_TEST_`DESCRIPTION,Defined constants and enum values in demos and tests,`IOT_DEMO_MQTT_PUBLISH_BURST_SIZE`
`IOT_TEST_MQTT_THREADS`} @formattableentry{`AWS_IOT_DEMO_`DESCRIPTION
`AWS_IOT_TEST_`DESCRIPTION,Defined constants and enum values in demos and tests specific to AWS IoT,`AWS_IOT_DEMO_THING_NAME`
`AWS_IOT_TEST_SHADOW_THING_NAME`} @formattableentry{DESCRIPTION,Internal constants and enum values
No `AWS_` prefix for internal names in AWS-specific libraries,`MQTT_PACKET_TYPE_CONNECT`
(iot_mqtt_internal.h)
`SHADOW_OPERATION_COUNT`
(aws_iot_shadow_internal.h)} Names of constants and enum values should contain only uppercase letters and underscores. All names intended for application use must begin with `IOT_` or `AWS_IOT_`. @subsection guide_developer_styleguide_naming_files Files @brief Naming convention for files. @formattable{files} @formattableentry{`iot_`library`_`description`.extension`
`aws_iot_`library`_`description`.extension`,General library file,`iot_mqtt_api.c`
`aws_iot_shadow_api.c`} @formattableentry{`iot_`library`_internal.h`
`aws_iot_`library`_internal.h`,Internal library header,`iot_mqtt_internal.h`
`aws_iot_shadow_internal.h`} @formattableentry{`iot_demo_`library`.c`
`aws_iot_demo_`library`.c`,Library demo source,`iot_demo_mqtt.c`
`aws_iot_demo_shadow.c`} @formattableentry{`iot_tests_`library`_`description`.c`
`aws_iot_tests_`library`_`description`.c`,Library test source,`iot_tests_mqtt_api.c`
`aws_iot_tests_shadow_api.c`} File names contain only lowercase letters and underscores. All file names should start with `iot_` or `aws_iot_` and be named according to their purpose. For example: - `iot_mqtt_api.c`: A file in the MQTT library that implements the MQTT API functions. - `iot_demo_mqtt.c`: A file in the Demos for the MQTT library. - `iot_demo_mqtt_posix.c`: A file in the Demos for the MQTT library on POSIX systems. - `iot_tests_mqtt_api.c`: A file in the Tests for the MQTT library. Since the tests currently only run on POSIX systems, test file names do not use the `_posix` suffix. Library file names should use one or two words to describe the functions implemented in that file. For example: - `iot_mqtt_serialize.c`: Implements the MQTT library's packet serialization and deserialization functions. - `iot_clock_posix.c`: Implements the platform clock component for POSIX systems. Declarations of internal functions, structures, macros, etc. of a library should be placed in a header file with an `_internal` suffix. The `_internal` header file should go in the `lib/include/private` directory. For example: - `iot_mqtt_internal.h`: Declares the MQTT library's internal functions, structures, macros, etc. File names for tests and demos should all begin with `iot_demo_` and `iot_tests_`, respectively. The names should then specify the library being demoed or or tested; for example, the files names of the MQTT library's demos and tests start with `iot_demo_mqtt_` and `iot_tests_mqtt_`. Additionally, test file names should describe what tests are implemented in the file, such as `iot_tests_mqtt_api.c` for a file containing tests for the MQTT library API functions. @subsection guide_developer_styleguide_naming_functions Functions (and function-like macros) @brief Naming convention of functions and function-like macros. @formattable{functions} @formattableentry{`Iot`Library`_`Description
`AwsIot`Library`_`Description,Externally-visible library function,`IotMqtt_Publish`
`AwsIotShadow_Update`} @formattableentry{`_Iot`Library`_`Description
`_AwsIot`Library`_`Description,Internal (but not `static`) library function,`_IotMqtt_ValidateNetIf`
`_AwsIotShadow_ParseShadowStatus`} @formattableentry{`IotTest`Library`_`Description,Function only used in tests,`IotTest_NetworkConnect`
`IotTestMqtt_createMqttConnection`} @formattableentry{`_`description,`static` function (never uses `Aws` prefix),`_createMqttConnection`
`_codeToShadowStatus`} @formattableentry{`IotTest`Library`_`accessedFunction,Test access function,`IotTestMqtt_createMqttConnection`} Externally visible (i.e. not `static`) functions are [UpperCamelCased](https://en.wikipedia.org/wiki/Camel_case) and must begin with `Iot` or `AwsIot` (public API functions); or `_Iot` or `_AwsIot` (internal functions). Function names should then specify their library name; followed by an underscore; followed by a brief description of what the function does. For example: - `IotMqtt_Publish`: This function is part of the public MQTT API. It Publishes an MQTT message. - `_IotMqtt_ValidateNetIf`: This function is internal to the MQTT library, but not `static`. It validates an `IotMqttNetIf_t`. Functions not visible outside their source file (i.e. `static` functions) have names that are [lowerCamelCased](https://en.wikipedia.org/wiki/Camel_case) and begin with an underscore. These function names do not contain the library name or `Aws`. For example: - `_createMqttConnection`: A `static` function in `iot_mqtt_api.c`. - `_codeToShadowStatus`: A `static` function in `aws_iot_shadow_parser.c`. Test access functions begin with `IotTest`; followed by the library name; followed by an underscore; followed by the function that the test function accesses. Since the accessed function is always `static`, the accessed function will be [lowerCamelCased](https://en.wikipedia.org/wiki/Camel_case). @subsection guide_developer_styleguide_naming_types Types @brief Naming conventions of library `typedef` types. @formattable{types} @formattableentry{`Iot`LibraryDescription`_t`
`AwsIot`LibraryDescription`_t`,General types in application-facing library header files,`IotMqttError_t` (iot_mqtt.h)
`AwsIotShadowError_t` (aws_iot_shadow.h)} @formattableentry{`Iot`LibraryFunction`Info_t`
`AwsIot`LibraryFunction`Info_t`,Application-facing parameter structure,`IotMqttPublishInfo_t`
(Parameter structure to `IotMqtt_Publish`)
`AwsIotShadowDocumentInfo_t`
(Parameter structure for Shadow documents)} @formattableentry{`_`libraryDescription`_t`,Type in an `internal` header,`_mqttOperation_t` (iot_mqtt_internal.h)
`_shadowOperation_t` (aws_iot_shadow_internal.h)} @formattableentry{`_`description`_t`,Internal type in source file,`_topicMatchParams_t` (iot_mqtt_subscription.c)} Types intended for use in applications are [UpperCamelCased](https://en.wikipedia.org/wiki/Camel_case). The names must start with `Iot` or `AwsIot` and end with `_t`. Parameter structures should indicate their associated function: for example, `IotMqttPublishInfo_t` is passed as a parameter to `IotMqtt_Publish`. Types intended for internal library use defined in a header file are [lowerCamelCased](https://en.wikipedia.org/wiki/Camel_case). The names must start with `_`, followed by the library name, and end with `_t`. Internal types defined in a library source file must start with `_`, end with `_t`, and not include the library name. `struct` typedefs should always be named along with the `typedef`. The struct name should be identical to the `typedef` name, but without the `_t` at the end. For example: @code{c} typedef struct IotLibraryStruct { int32_t member; } IotLibraryStruct_t; typedef struct _libraryInternalStruct { int32_t member; } _libraryInternalStruct_t; @endcode A `struct` may contain anonymous `struct` or `union` members. @subsection guide_developer_styleguide_naming_variables Variables @brief Naming conventions of variables. @formattable{variables} @formattableentry{variableDescription,General local variable,`startTime`} @formattableentry{`p`VariableDescription,Local variable pointers and arrays (including strings),`pSubscriptionList`} @formattableentry{`_`variableDescription,Global variable that is `static`,`_connectMutex` (iot_mqtt_api.c)
`_pSamplePayload` (string)} @formattableentry{`_Iot`LibraryDescription
`_AwsIot`LibraryDescription,Global variable that is NOT `static`,`_IotMqttTaskPool` (iot_mqtt_operation.c)
`_pIotSamplePayload` (string)} Local variable names are [lowerCamelCased](https://en.wikipedia.org/wiki/Camel_case) and consist only of a description of the variable. Names like `i` or `j` are acceptable for loop counters, but all other variables should have a descriptive name. Global variable names always start with a `_`. Global variables that are `static` consist of only the description in [lowerCamelCase](https://en.wikipedia.org/wiki/Camel_case). Global variables that are not static consist of the library name and the description in [UpperCamelCase](https://en.wikipedia.org/wiki/Camel_case); for example: `_IotLibraryNonStaticGlobalVariable`. All pointers, arrays, and strings (both global and local) start with `p` (local) or `_p` (global). */