Core c99 package for AWS SDK for C. Includes cross-platform primitives, configuration, data structures, and error handling.
Core c99 package for AWS SDK for C. Includes cross-platform primitives, configuration, data structures, and error handling.
This library is licensed under the Apache 2.0 License.
aws-c-common uses CMake for setting up build environments. This library has no non-kernel dependencies so the build is quite simple.
For example:
git clone [email protected]:awslabs/aws-c-common.git aws-c-common mkdir aws-c-common-build cd aws-c-common-build cmake ../aws-c-common make -j 12 make test sudo make install
Keep in mind that CMake supports multiple build systems, so for each platform you can pass your own build system as the
-Goption. For example:
cmake -GNinja ../aws-c-common ninja build ninja test sudo ninja install
Or on windows,
cmake -G "Visual Studio 14 2015 Win64" ../aws-c-common msbuild.exe ALL_BUILD.vcproj
Every API has a specific set of styles and conventions. We'll outline them here. These conventions are followed in every library in the AWS C SDK ecosystem.
Every function that returns an
inttype, returns
AWS_OP_SUCCESS( 0 ) or
AWS_OP_ERR(-1) on failure. To retrieve the error code, use the function
aws_last_error(). Each error code also has a corresponding error string that can be accessed via the
aws_error_str()function.
In addition, you can install both a global and a thread local error handler by using the
aws_set_global_error_handler_fn()and
aws_set_thread_local_error_handler_fn()functions.
All error functions are in the
include/aws/common/error.hheader file.
Any function that allocates and initializes an object will be suffixed with
new(e.g.
aws_myobj_new()). Similarly, these objects will always have a corresponding function with a
destroysuffix. The
newfunctions will return the allocated object on success and
NULLon failure. To respond to the error, call
aws_last_error(). If several
newor
destroyfunctions are available, the variants should be named like
new_xor
destroy_x(e.g.
aws_myobj_new_copy()or
aws_myobj_destroy_secure()).
Any function that initializes an existing object will be suffixed with
init(e.g.
aws_myobj_init(). These objects will have a corresponding
clean_upfunction if necessary. In these cases, you are responsible for making the decisions for how your object is allocated. The
initfunctions return
AWS_OP_SUCCESS( 0 ) or
AWS_OP_ERR(-1) on failure. If several
initor
clean_upfunctions are available, they should be named like
init_xor
clean_up_x(e.g.
aws_myobj_init_static()or
aws_myobj_clean_up_secure()).
If you are contributing to this code-base, first off, THANK YOU!. There are a few things to keep in mind to minimize the pull request turn around time.
These "guidelines" are followed in every library in the AWS C SDK ecosystem.
aws_allocatorand use that. No
malloc()or
free()calls should be made directly.
AWS_ERROR_OOMerror code upon allocation failures. If it is a
new()function it should return NULL. If it is an
init()function, it should return
AWS_OP_ERR.
interror code. The only acceptable return types are
AWS_OP_SUCCESSand
AWS_OP_ERR. Before returning control to the caller, if you have an error to raise, use the
aws_raise_error()function.
NULLon failure. Before returning control to the caller, if you have an error to raise, use the
aws_raise_error()function.
The logging & error handling infrastructure is designed to support multiple libraries. For this to work, AWS maintained libraries have pre-slotted log subjects & error codes for each library. The currently allocated ranges are:
| Range | Library Name | | --- | --- | | [0x0000, 0x0400) | aws-c-common | | [0x0400, 0x0800) | aws-c-io | | [0x0800, 0x0C00) | aws-c-http | | [0x0C00, 0x1000) | aws-c-compression | | [0x1000, 0x1400) | aws-c-eventstream | | [0x1400, 0x1800) | aws-c-mqtt | | [0x1800, 0x1C00) | aws-c-auth | | [0x1C00, 0x2000) | aws-c-cal | | [0x2000, 0x2400) | aws-crt-cpp | | [0x2400, 0x2800) | aws-crt-java | | [0x2800, 0x2C00) | aws-crt-python | | [0x2C00, 0x3000) | aws-crt-nodejs | | [0x3000, 0x3400) | aws-crt-dotnet | | [0x3400, 0x3800) | aws-c-iot | | [0x3800, 0x3C00) | (reserved for future project) | | [0x3C00, 0x4000) | (reserved for future project) | | [0x4000, 0x4400) | (reserved for future project) | | [0x4400, 0x4800) | (reserved for future project) |
Each library should begin its error and log subject values at the beginning of its range and follow in sequence (don't skip codes). Upon adding an AWS maintained library, a new enum range must be approved and added to the above table.
We have a high bar for test coverage, and PRs fixing bugs or introducing new functionality need to have tests before they will be accepted. A couple of tips:
We provide a test harness for writing unit tests. This includes an allocator that will fail your test if you have any memory leaks, as well as some
ASSERTmacros. To write a test:
int test_case_name(struct aws_allocator *, void *ctx)
AWS_TEST_CASEmacro to declare the test.
tests/main.cfile.
tests/CMakeLists.txtfile.
(.
elseand
else ifstay on the same line as the closing brace.
Example:
if (condition) { do_something(); } else { do_something_else(); }
aws/common/common.h, so feel free to use them.
//.
void *implpattern. v-tables should be the last member in the struct.
Example:
#ifdef FOO do_something();ifdef BAR
do_something_else();
endif
#endif
AWS_ERROR__.
static(local file scope) variables that are not
constare prefixed by
s_and lower snake case.
constare prefixed by
g_and lower snake case.
tl_and lower snake case.
constvariables are upper snake case.
Example:
typedef int(fn_name_fn)(void *);
Not:
typedef int(*fn_name_fn)(void *);
extern inline. It's too unpredictable between compiler versions and language standards.
aws_?__. Lib name is not always required if a conflict is not likely and it provides better ergonomics.
init,
clean_up,
new,
destroyare suffixed to the function names for their object.
Example:
AWS_COMMON_API
int awsmoduleinit(awsmodulet *module); AWSCOMMONAPI void awsmodulecleanup(awsmodulet *module); AWSCOMMONAPI awsmodulet *awsmodulenew(awsallocatort *allocator); AWSCOMMONAPI void awsmoduledestroy(awsmodule_t *module);
NULLterminators. Expose
struct aws_byte_bufAPIs and let the user figure it out.
Example:
if (options->callback == NULL) { AWS_LOGF_ERROR(AWS_LS_SOME_SUBJECT, "Invalid options - callback is null"); return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); }if (options->allocator == NULL) { AWS_LOGF_ERROR(AWS_LS_SOME_SUBJECT, "Invalid options - allocator is null"); return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); }
Not:
if (options->callback == NULL || options->allocator == NULL) { AWS_LOGF_ERROR(AWS_LS_SOME_SUBJECT, "Invalid options - something is null"); return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); }