diff options
author | Tyler Murphy <tylerm@tylerm.dev> | 2023-05-06 00:39:44 -0400 |
---|---|---|
committer | Tyler Murphy <tylerm@tylerm.dev> | 2023-05-06 00:39:44 -0400 |
commit | d8f2c10b7108fff6b7e437291093a1cadc15ab9f (patch) | |
tree | 3fc50a19d6fbb9c94a8fe147cd2a6c4ba7f59b8d /command/printf.c | |
parent | ansii c (diff) | |
download | lazysphere-d8f2c10b7108fff6b7e437291093a1cadc15ab9f.tar.gz lazysphere-d8f2c10b7108fff6b7e437291093a1cadc15ab9f.tar.bz2 lazysphere-d8f2c10b7108fff6b7e437291093a1cadc15ab9f.zip |
refactor
Diffstat (limited to 'command/printf.c')
-rw-r--r-- | command/printf.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/command/printf.c b/command/printf.c new file mode 100644 index 0000000..99139d0 --- /dev/null +++ b/command/printf.c @@ -0,0 +1,144 @@ +#include "command.h" +#include "lslib.h" + +#include <stdlib.h> + +static long cast_long(const char* arg) { + char* end; + long l = strtol(arg, &end, 10); + if (end == arg) { + return 0; + } else { + return l; + } +} + +static double cast_double(const char* arg) { + char* end; + double d = strtod(arg, &end); + if (end == arg) { + return 0.0; + } else { + return d; + } +} + +#define NUMBER(name, type, arg) \ + long l = cast_long(arg); \ + type* t = (type*) &l; \ + type name = *t; + +static void handle_percent(char n, const char* arg) { + switch (n) { + case 'd': + case 'z': { + NUMBER(i, int, arg) + printf("%d", i); + break; + } + case 'u': { + NUMBER(u, unsigned int, arg); + printf("%u", u); + break; + } + case 'f': { + double d = cast_double(arg); + printf("%f", d); + break; + } + case 'c': { + putchar(arg[0]); + break; + } + case 's': { + printf("%s", arg); + break; + } + default: { + putchar('%'); + putchar(n); + } + } +} + +static void handle_slash(char n) { + switch (n) { + case 'n': + putchar('\n'); + break; + case 't': + putchar('\t'); + break; + case 'v': + putchar('\v'); + break; + case 'b': + putchar('\b'); + break; + case 'f': + putchar('\f'); + break; + case 'a': + putchar('\a'); + break; + case '"': + putchar('"'); + break; + case 'c': + exit(EXIT_SUCCESS); + default: + putchar('\\'); + putchar(n); + } +} + +static void help(void) { + printf("Usage printf FORMAT [ARG]...\n\n"); + printf("Format and print ARG(s) according to FORMAT (a-la C prinf)\n"); +} + +COMMAND(print) { + + size_t index; + int arg_index; + char n, *arg; + + if (argc < 1) { + global_help(help); + return EXIT_SUCCESS; + } + + parse_help(argc, argv, help); + + index = 0; + arg_index = 0; + + while (true) { + char c = argv[0][index]; + index++; + + if (c == '\0') break; + if (c != '%' && c != '\\') { + putchar(c); + continue; + } + + n = argv[0][index]; + index++; + + arg = NULL; + if (arg_index < argc) { + arg = argv[arg_index + 1]; + } + + if (c == '%') { + handle_percent(n, arg); + } else { + handle_slash(n); + } + + arg_index++; + } + + return EXIT_SUCCESS; +} |