/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>

/* Tiny, but not-as-primitive-as-it-looks implementation of something
 * like s/n/printf().  Handles %d, %x, %p, %c and %s only, allows a
 * "l" qualifier on %d and %x (and silently ignores one %s/%c/%p).
 * Accepts, but ignores, field width and precision values that match:
 * the regex: [0-9]*\.?[0-9]*
 */

struct _pfr {
	char *buf;
	int len;
	int idx;
};

/* Set this function pointer to something that generates output */
static void (*z_putchar)(int c);

static void pc(struct _pfr *r, int c)
{
	if (r->buf != NULL) {
		if (r->idx <= r->len) {
			r->buf[r->idx] = c;
		}
	} else {
		z_putchar(c);
	}
	r->idx++;
}

static void prdec(struct _pfr *r, long v)
{
	if (v < 0) {
		pc(r, '-');
		v = -v;
	}

	char digs[11 * sizeof(long)/4];
	int i = sizeof(digs) - 1;

	digs[i] = 0;
	--i;
	while (v || i == 9) {
		digs[i] = '0' + (v % 10);
		--i;
		v /= 10;
	}

	++i;
	while (digs[i] != '\0') {
		pc(r, digs[i]);
		++i;
	}
}

static void endrec(struct _pfr *r)
{
	if (r->buf && r->idx < r->len) {
		r->buf[r->idx] = 0;
	}
}

static int vpf(struct _pfr *r, const char *f, va_list ap)
{
	for (/**/; *f != '\0'; f++) {
		bool islong = false;

		if (*f != '%') {
			pc(r, *f);
			continue;
		}

		if (f[1] == 'l') {
			islong = sizeof(long) > 4;
			f++;
		}

		/* Ignore (but accept) field width and precision values */
		while (f[1] >= '0' && f[1] <= '9') {
			f++;
		}
		if (f[1] == '.') {
			f++;
		}
		while (f[1] >= '0' && f[1] <= '9') {
			f++;
		}

		switch (*(++f)) {
		case 0:
			return r->idx;
		case '%':
			pc(r, '%');
			break;
		case 'c':
			pc(r, va_arg(ap, int));
			break;
		case 's': {
			char *s = va_arg(ap, char *);

			while (*s != '\0') {
				pc(r, *s);
				++s;
			}
			break;
		}
		case 'p':
			pc(r, '0');
			pc(r, 'x'); /* fall through... */
			islong = sizeof(long) > 4;
		case 'x': {
			int sig = 0;
			unsigned long v = islong ? va_arg(ap, unsigned long)
				: va_arg(ap, unsigned int);
			for (int i = 2*sizeof(long) - 1; i >= 0; i--) {
				int d = (v >> (i*4)) & 0xf;

				sig += !!d;
				if (sig || i == 0) {
					pc(r, "0123456789abcdef"[d]);
				}
			}
			break;
		}
		case 'd':
			prdec(r, va_arg(ap, int));
			break;
		default:
			pc(r, '%');
			pc(r, *f);
		}
	}
	endrec(r);
	return r->idx;
}

#define CALL_VPF(rec)				\
	va_list ap;				\
	va_start(ap, f);			\
	ret = vpf(&r, f, ap);			\
	va_end(ap);

static inline int snprintf(char *buf, unsigned long len, const char *f, ...)
{
	int ret;
	struct _pfr r = { .buf = buf, .len = len };

	CALL_VPF(&r);
	return ret;
}

static inline int sprintf(char *buf, const char *f, ...)
{
	int ret;
	struct _pfr r = { .buf = buf, .len = 0x7fffffff };

	CALL_VPF(&r);
	return ret;
}

static inline int printf(const char *f, ...)
{
	int ret;
	struct _pfr r = {0};

	CALL_VPF(&r);
	return ret;
}
