lazysphere/command/printf.c
2023-05-15 10:57:33 -04:00

144 lines
2.7 KiB
C

#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(printf_main) {
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;
}