#ifndef CSTRING_H #define CSTRING_H /* CSTRING RETURN CODE */ #define CSTRING_RC_TYPE unsigned char extern __thread CSTRING_RC_TYPE logger_errno; #define CSTRING_RC_OK ((CSTRING_RC_TYPE) 0L) /* No Error */ #define CSTRING_RC_EVN ((CSTRING_RC_TYPE) 1L) /* Value is Null */ #include __attribute__((__pure__)) size_t cstring_len(const char *cstring); __attribute__((__pure__)) _Bool cstring_equal(const char *restrict cstring_1, const char *restrict cstring_2); #define IMPLEMENTATIONS #if defined(CSTRING_IMP) || defined(IMPLEMENTATIONS) #include #include #if defined(CSTRING_LOG) || defined(LOGS) #define __LOG(OUT, PFX, TXT) fprintf(OUT, PFX" %s: %s", __func__, TXT) #define LOG_ERROR(TXT) __LOG(stderr, "[ERROR]", TXT) #else #define LOG_ERROR(TXT) ; #endif /* CSTRING_LOG */ #define true ((unsigned char) 1L) #define false ((unsigned char) 0L) #define TEST_FOR_NULL(POINTER) \ if ( POINTER == NULL ) { \ LOG_ERROR("Null Pointer Not Expected"); \ logger_errno = CSTRING_RC_EVN; \ return logger_errno; \ } size_t cstring_len(const char *p_cstr) { TEST_FOR_NULL(p_cstr); size_t len = 0; while ( *(p_cstr + len++) ) {} return --len; } _Bool cstring_equal(const char *restrict p_cstr1, const char *restrict p_cstr2) { TEST_FOR_NULL(p_cstr1); TEST_FOR_NULL(p_cstr2); const size_t cstr1_size = cstring_len(p_cstr1); const size_t cstr2_size = cstring_len(p_cstr2); if ( cstr1_size != cstr2_size ) { return false; } for ( size_t i = 0; i < cstr1_size; ++i ) { if ( p_cstr1[i] != p_cstr2[i] ) { return false; } } return true; } #undef true #undef false #undef LOG_ERROR #undef TEST_FOR_NULL #endif /* CSTRING_IMP || IMPLEMENTATIONS */ #endif /* CSTRING_H */