/*
 * This file and its contents are supplied under the terms of the
 * Mozilla Public License (MPL) version 2.0.  You may only use this
 * file in accordance with the terms of version 2.0 of the MPL.
 *
 * A full copy of the text of the MPL should have accompanied this
 * source.  A copy of the MPL is also available via the Internet at
 * https://www.mozilla.org/en-CA/MPL/2.0.
 *
 * This Source Code Form is "Incompatible With Secondary Licenses",
 * as defined by the Mozilla Public License, v. 2.0.
 *
 * This file implements some standard C library routines for the
 * Flight Board.
 *
 * (C) Copyright Rich Teer 1990, 2023, 2026.
 */


#include <varargs.h>
#define boolean int

static char *alpha_num = "0123456789ABCDEF";
static char *dummy_str = " ";


int strcmp (char *string1, char *string2)
{
	while (*string1++ == *string2++)
		if (*string1 == '\0')
			return (0);
	return (*string1 - *string2);
}


int strlen (char *string)
{
	int number = 0;

	while (*string++)
		number++;
	return (number);
}


strcat (char *string1, char *string2)
{
	while (*string1)
		string1++;
	while (*string1++ = *string2++);
}


strcpy (char *string1, char *string2)
{
	while (*string1++ = *string2++);
}


int abs (int number)
{
	return ((number < 0) ? -number : number);
}


itos (int number, int base, char *string)
{
	int digit;

	if (digit = number / base)
		itos (digit, base, string);
	*dummy_str = alpha_num[number % base];
	strcat (string, dummy_str);
}


ftos (double number, int precision, char *string)
{
	int integral = (int)number;
	double remainder;
	int loop;

	itos (integral, 10, string);
	strcat (string, ".");
	remainder = number - integral;
	for (loop = 0; loop < precision; loop++) {
		remainder *= 10.0;
		itos ((int)remainder, 10, string);
		remainder -= (int)remainder;
	}
}


sprintf (char *string, va_alist)
char *string;
va_dcl
{
	va_list args;											/* The list of arguments */
	char *format;											/* The format string */
	char *ptr;												/* Where we are in the format string */
	char *str_arg;											/* A string argument */
	int int_arg;											/* An integer argument */
	int char_arg;											/* A character argument */
	double float_arg;										/* A float or double argument */
	char output_string[1024];								/* The text finally printed */
	static char char_str[] = " ";
	char string1[33];										/* First string used for number conversion */
	int index1;												/* First array index used for number conversion */
	int index2;												/* Second number used for number conversion */
	int digit;												/* The digit's that's currently being converted */
	int factor;
	int modulus;
	boolean lead_zero;

	output_string [0] = '\0';
	*string = '\0';
	va_start (args);										/* Initialise arg list */
	format = va_arg (args, char *);							/* Get the format first */
	for (ptr = format; *ptr; ptr++) {
		if (*ptr == '%')
			switch (*++ptr) {
				case 's':
					str_arg = va_arg (args, char *);
					strcat (output_string, str_arg);
					break;
				case 'c':
					*char_str = va_arg (args, int);
					strcat (output_string, char_str);
					break;
				case 'd':
					int_arg = va_arg (args, int);
					*string1 = '\0';
					if (int_arg < 0) {
						strcat (output_string, "-");
						int_arg = abs (int_arg);
					}
					itos (int_arg, 10, string1);
					strcat (output_string, string1);
					break;
				case 'x':
					int_arg = va_arg (args, int);
					*string1 = '\0';
					if (int_arg < 0) {
						strcat (output_string, "-");
						int_arg = abs (int_arg);
					}
					itos (int_arg, 16, string1);
					strcat (output_string, string1);
					break;
				case 'b':
					int_arg = va_arg (args, int);
					*string1 = '\0';
					if (int_arg < 0) {
						strcat (output_string, "-");
						int_arg = abs (int_arg);
					}
					itos (int_arg, 2, string1);
					strcat (output_string, string1);
					break;
				case 'o':
					int_arg = va_arg (args, int);
					*string1 = '\0';
					if (int_arg < 0) {
						strcat (output_string, "-");
						int_arg = abs (int_arg);
					}
					itos (int_arg, 8, string1);
					strcat (output_string, string1);
					break;
				case 'f':
					float_arg = va_arg (args, double);
					*string1 = '\0';
					if (float_arg < 0.0) {
						strcat (output_string, "-");
						float_arg = abs (int_arg);
					}
					ftos (float_arg, 6, string1);
					strcat (output_string, string1);
					break;
				case '%':
					strcat (output_string, "%");
					break;
				default:
					puts ("printf: Illegal format\n");
					break;
			}
		else {
			*char_str = *ptr;
			strcat (output_string, char_str);
		}
	}
	strcat (string, output_string);
	va_end (args);											/* Clean up argument list */
}
