commit a0686a8684b94a8d9ff5b9a2cbf5d56e890f1b72 Author: anon Date: Mon Aug 12 14:00:59 2024 +0200 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f47cb20 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.out diff --git a/README.md b/README.md new file mode 100644 index 0000000..8b1bc36 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# Caret Notater +> Header only C library for converting to caret notation + +### What is caret notation +You may recognize it like this: `^H`. +It is commonly used on the command line, an example would be Bash's Readline input. +For details consult other sources: [wiki](https://en.wikipedia.org/wiki/Caret_notation). + +### API +```C +static inline int is_caretable(const char c); +static inline char to_caret_char(const char c); +// NOTE: these functions return their `output` argument +char * char_to_caret_notation(const char c, char output[3]); +char * string_to_caret_notation(const char * const input, const unsigned long size, char * const output); +#if CARET_NOTATER_ALLOC == 1 +static inline char * alloc_char_to_caret_notation(const char c); +static inline char * alloc_string_to_caret_notation(const char * const input, const unsigned long size); +``` + +### NOTES +`*string_to_caret_notation()` takes a (-n input) size explicitly because +you may want to convert null characters as `'\0'` is `"^@"` in caret notation. +If you dont care, you are advised to just pass a `strlen()` call. diff --git a/caret_notater.h b/caret_notater.h new file mode 100644 index 0000000..4c2579d --- /dev/null +++ b/caret_notater.h @@ -0,0 +1,83 @@ +#ifndef CARET_NOTATER_H +#define CARET_NOTATER_H +/* caret_notater.h converts strings containing + * unprintable characters to equivalent strings + * in caret notation. + */ + +#if !defined(CARET_NOTATER_ALLOC) && defined(__STDC__) && __STDC__ == 1 +# define CARET_NOTATER_ALLOC 1 +#endif + +static inline int is_caretable(const char c); +static inline char to_caret_char(const char c); +// NOTE: these functions return their `output` argument +char * char_to_caret_notation(const char c, char output[3]); +char * string_to_caret_notation(const char * const input, const unsigned long size, char * const output); +#if CARET_NOTATER_ALLOC == 1 +static inline char * alloc_char_to_caret_notation(const char c); +static inline char * alloc_string_to_caret_notation(const char * const input, const unsigned long size); +#endif + +// --- Implementation + +static inline +int is_caretable(const char c) { + return ((0 <= c && c <= 31) || c == 127); +} + +static inline +char to_caret_char(const char c) { + return c ^ 0x40; +} + +char * char_to_caret_notation(const char c, char output[3]) { + if (is_caretable(c)) { + output[0] = '^'; + output[1] = to_caret_char(c); + output[2] = '\0'; + } else { + output[0] = '\0'; + } + return output; +} + +/* NOTE: the size must be passed because `'\0' -> "^@"` must be a valid transformation + */ +char * string_to_caret_notation(const char * const input, const unsigned long size, char * const output) { + int output_empty_end = 0; + for (unsigned long i = 0; i < size; i++) { + if (is_caretable(input[i])) { + output[output_empty_end++] = '^'; + output[output_empty_end++] = to_caret_char(input[i]); + } else { + output[output_empty_end++] = input[i]; + } + } + output[output_empty_end] = '\0'; + + return output; +} + +#if CARET_NOTATER_ALLOC == 1 + #include + + static inline + char * alloc_char_to_caret_notation(const char c) { + char * const r = malloc(3); + return char_to_caret_notation(c, r); + } + + static inline + char * alloc_string_to_caret_notation(const char * const input, const unsigned long size) { + char * const r = malloc(size*2); + return string_to_caret_notation(input, size, r); + } +#endif + +#endif +/* --- LICENSE + * This software is in the Public Domain; + * and if (You) dare to say this notice is not legally valid, + * I will sue you. + */ diff --git a/example.c b/example.c new file mode 100644 index 0000000..626ef3b --- /dev/null +++ b/example.c @@ -0,0 +1,9 @@ +// @BAKE gcc $@ -o $*.out; ./$*.out +#include +#include "caret_notater.h" + +signed main() { + char input[] = "null: \00; \\07: \07; esc: \033; del: \x7f"; + puts(alloc_string_to_caret_notation(input, sizeof(input)-1)); + return 0; +}