2023-04-27 23:06:40 +00:00
|
|
|
#include "../command.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("%lf", 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;
|
|
|
|
default:
|
|
|
|
putchar('\\');
|
|
|
|
putchar(n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-01 22:43:32 +00:00
|
|
|
static void help(void) {
|
2023-04-30 19:51:58 +00:00
|
|
|
printf("Usage printf FORMAT [ARG]...\n\n");
|
|
|
|
printf("Format and print ARG(s) according to FORMAT (a-la C prinf)\n");
|
|
|
|
}
|
|
|
|
|
2023-04-27 23:06:40 +00:00
|
|
|
COMMAND(print) {
|
|
|
|
if (argc < 1) {
|
|
|
|
error("usage: printf FORMAT [ARG]...\n");
|
|
|
|
}
|
|
|
|
|
2023-05-01 22:43:32 +00:00
|
|
|
parse_help(argc, argv, help);
|
2023-04-30 19:51:58 +00:00
|
|
|
|
2023-04-27 23:06:40 +00:00
|
|
|
size_t index = 0;
|
|
|
|
int arg_index = 0;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
char c = argv[0][index];
|
|
|
|
index++;
|
|
|
|
|
|
|
|
if (c == '\0') break;
|
|
|
|
if (c != '%' && c != '\\') {
|
|
|
|
putchar(c);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
char n = argv[0][index];
|
|
|
|
index++;
|
|
|
|
|
|
|
|
char* 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;
|
|
|
|
}
|