diff --git a/c-programming/strings/string_case.c b/c-programming/strings/string_case.c new file mode 100644 index 0000000..de5b756 --- /dev/null +++ b/c-programming/strings/string_case.c @@ -0,0 +1,38 @@ +/* + * string_case.c + * + * Author: Intel A80486DX2-66 + * License: Unlicense + */ + +#include "string_case.h" + +char* ascii_lowercase_str(const char* s) { ASCII_LOWERCASE_STR_T(s); } +char* ascii_lowercase_strm(char* s) { ASCII_LOWERCASE_STRM_T(s); } +char* ascii_uppercase_str(const char* s) { ASCII_UPPERCASE_STR_T(s); } +char* ascii_uppercase_strm(char* s) { ASCII_UPPERCASE_STRM_T(s); } + +#ifdef TEST +# include +# include + +int main(void) { + printf("Constant string:\n"); + const char* const_str = "Hello, World!"; + char* str1 = ascii_lowercase_str(const_str), + * str2 = ascii_uppercase_str(const_str); + printf("original string: %s\n", const_str); + printf("lower: %s\n", str1); free(str1); + printf("upper: %s\n", str2); free(str2); + printf("original string: %s\n", const_str); + + printf("\nNon-constant string:\n"); + char non_const_str[] = "Hello, user!"; + printf("original string: %s\n", non_const_str); + printf("lower: %s\n", ascii_lowercase_strm(non_const_str)); + printf("upper: %s\n", ascii_uppercase_strm(non_const_str)); + printf("original string: %s\n", non_const_str); + + return EXIT_SUCCESS; +} +#endif diff --git a/c-programming/strings/string_case.h b/c-programming/strings/string_case.h new file mode 100644 index 0000000..be6ba74 --- /dev/null +++ b/c-programming/strings/string_case.h @@ -0,0 +1,51 @@ +/* + * string_case.h + * + * Author: Intel A80486DX2-66 + * License: Unlicense + */ + +#ifndef _STRING_CASE_H +#define _STRING_CASE_H + +#ifdef __STDC_ALLOC_LIB__ +# define __STDC_WANT_LIB_EXT2__ 1 +#else +# define _POSIX_C_SOURCE 200809L +#endif +#include +#include + +#define ASCII_IS_LOWER(c) ((c) >= 'a' && (c) <= 'z') +#define ASCII_IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z') +#define ASCII_IS_ALPHA(c) (ASCII_IS_LOWER(c) || ASCII_IS_UPPER(c)) +#define ASCII_MOD_ALPHA(c, v) (ASCII_IS_ALPHA(c) ? v : c) +#define ASCII_LOWERCASE(c) (ASCII_MOD_ALPHA((c), (c) | 0x20)) +#define ASCII_UPPERCASE(c) (ASCII_MOD_ALPHA((c), ASCII_LOWERCASE(c) - 0x20)) +#define ASCII_MOD_STRM(s, m) \ + char* ptr = s; \ + while (*ptr) { \ + *ptr = m(*ptr); \ + ptr++; \ + } \ + return s + +#define ASCII_MOD_STR(s, m) \ + char* s_dup = strdup((s)), * ptr = s_dup; \ + while (*ptr) { \ + *ptr = m(*ptr); \ + ptr++; \ + } \ + return s_dup + +#define ASCII_UPPERCASE_STRM_T(s) ASCII_MOD_STRM(s, ASCII_UPPERCASE) +#define ASCII_LOWERCASE_STRM_T(s) ASCII_MOD_STRM(s, ASCII_LOWERCASE) +#define ASCII_UPPERCASE_STR_T(s) ASCII_MOD_STR(s, ASCII_UPPERCASE) +#define ASCII_LOWERCASE_STR_T(s) ASCII_MOD_STR(s, ASCII_LOWERCASE) + +char* ascii_lowercase_str(const char* s); +char* ascii_lowercase_strm(char* s); +char* ascii_uppercase_str(const char* s); +char* ascii_uppercase_strm(char* s); + +#endif /* _STRING_CASE_H */