/*********************************************************************************************************//**
* @file printf.c
* @version $Rev:: 5 $
* @date $Date:: 2017-05-11 #$
* @brief Print functions.
*************************************************************************************************************
* @attention
*
* Firmware Disclaimer Information
*
* 1. The customer hereby acknowledges and agrees that the program technical documentation, including the
* code, which is supplied by Holtek Semiconductor Inc., (hereinafter referred to as "HOLTEK") is the
* proprietary and confidential intellectual property of HOLTEK, and is protected by copyright law and
* other intellectual property laws.
*
* 2. The customer hereby acknowledges and agrees that the program technical documentation, including the
* code, is confidential information belonging to HOLTEK, and must not be disclosed to any third parties
* other than HOLTEK and the customer.
*
* 3. The program technical documentation, including the code, is provided "as is" and for customer reference
* only. After delivery by HOLTEK, the customer shall use the program technical documentation, including
* the code, at their own risk. HOLTEK disclaims any expressed, implied or statutory warranties, including
* the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
*
*
Copyright (C) Holtek Semiconductor Inc. All rights reserved
************************************************************************************************************/
/* Includes ------------------------------------------------------------------------------------------------*/
#include "ht32.h"
#include
/** @addtogroup HT32_Peripheral_Driver HT32 Peripheral Driver
* @{
*/
/** @defgroup PRINTF printf re-implementation
* @brief printf related functions
* @{
*/
/* Private macro -------------------------------------------------------------------------------------------*/
/** @defgroup PRINTF_Private_Macro printf private macros
* @{
*/
#define vaStart(list, param) list = (char*)((int)¶m + sizeof(param))
#define vaArg(list, type) ((type *)(list += sizeof(type)))[-1]
/**
* @}
*/
/* Private function prototypes -----------------------------------------------------------------------------*/
static const char *FormatItem(const char *f, int a);
static void PutRepChar(const char c, int count);
static int PutString(const char *pString);
static int PutStringReverse(const char *pString, int index);
static void PutNumber(int value, int radix, int width, char fill);
/* Global functions ----------------------------------------------------------------------------------------*/
/** @defgroup PRINTF_Exported_Functions printf exported functions
* @{
*/
/*********************************************************************************************************//**
* @brief Print function.
* @param f: Format string.
* @retval String length.
************************************************************************************************************/
signed int printf(const char *f, ...)
{
char *argP;
int i = 0;
vaStart(argP, f);
while (*f)
{
if (*f == '%')
{
f = FormatItem(f + 1, vaArg(argP, int));
}
else
{
fputc(*f++, (FILE *)1);
}
i++;
}
return i;
}
/*********************************************************************************************************//**
* @brief Put string.
* @param pString: String.
* @retval String length.
************************************************************************************************************/
signed int puts(const char *pString)
{
int i;
i = PutString(pString);
fputc('\n', (FILE *)1);
return i;
}
/**
* @}
*/
/* Private functions ---------------------------------------------------------------------------------------*/
/** @defgroup PRINTF_Private_Function printf private functions
* @{
*/
/*********************************************************************************************************//**
* @brief Format item for print function.
* @param f: Format string.
* @param a: Length of format string.
* @retval Point of string.
************************************************************************************************************/
static const char *FormatItem(const char *f, int a)
{
char c;
int fieldwidth = 0;
int leftjust = FALSE;
int radix = 0;
char fill = ' ';
int i;
if (*f == '0')
{
fill = '0';
}
while ((c = *f++) != 0)
{
if (c >= '0' && c <= '9')
{
fieldwidth = (fieldwidth * 10) + (c - '0');
}
else
{
switch (c)
{
case '\000':
{
return (--f);
}
case '%':
{
fputc('%', (FILE *)1);
return (f);
}
case '-':
{
leftjust = TRUE;
break;
}
case 'c':
{
if (leftjust)
{
fputc(a & 0x7f, (FILE *)f);
}
if (fieldwidth > 0)
{
PutRepChar(fill, fieldwidth - 1);
}
if (!leftjust)
{
fputc(a & 0x7f, (FILE *)f);
return (f);
}
}
case 's':
{
i = 0;
while (*((char *)(a + i)) !='\0' )
{
i++;
}
if (leftjust)
{
PutString((char *)a);
}
if (fieldwidth > i )
{
PutRepChar(fill, fieldwidth - i);
}
if (!leftjust)
{
PutString((char *)a);
}
return (f);
}
case 'l':
{
radix = -10;
f++;
break;
}
case 'd':
case 'i':
{
radix = -10;
break;
}
case 'u':
{
radix = 10;
break;
}
case 'x':
case 'X':
{
radix = 16;
break;
}
case 'o':
{
radix = 8;
break;
}
default:
{
radix = 3;
break;
}
}
}
if (radix)
{
break;
}
}
if (leftjust)
{
fieldwidth = -fieldwidth;
}
PutNumber(a, radix, fieldwidth, fill);
return (f);
}
/*********************************************************************************************************//**
* @brief Put repeat character.
* @param c: Character.
* @param count: Repeat count
************************************************************************************************************/
static void PutRepChar(const char c, int count)
{
while (count--)
{
fputc(c, (FILE *)1);
}
}
/*********************************************************************************************************//**
* @brief Put string.
* @param pString: String.
* @retval String length.
************************************************************************************************************/
static int PutString(const char *pString)
{
int i = 0;
while (*pString != '\0')
{
fputc(*pString, (FILE *)1);
pString++;
i++;
}
return i;
}
/*********************************************************************************************************//**
* @brief Put string in reversed order.
* @param pString: String.
* @param index: String length
* @retval String length.
************************************************************************************************************/
static int PutStringReverse(const char *pString, int index)
{
int i = 0;
while ((index--) > 0)
{
fputc(pString[index], (FILE *)1);
i++;
}
return i;
}
/*********************************************************************************************************//**
* @brief Put number.
* @param value: Value of number.
* @param radix: Radix of number.
* @param width: Width of number.
* @param fill: fill character.
************************************************************************************************************/
static void PutNumber(int value, int radix, int width, char fill)
{
char buffer[8];
int bi = 0;
unsigned int uvalue;
unsigned short digit;
unsigned short left = FALSE;
unsigned short negative = FALSE;
if (fill == 0)
{
fill = ' ';
}
if (width < 0)
{
width = -width;
left = TRUE;
}
if (width < 0 || width > 80)
{
width = 0;
}
if (radix < 0)
{
radix = -radix;
if (value < 0)
{
negative = TRUE;
value = -value;
}
}
uvalue = value;
do
{
if (radix != 16)
{
digit = uvalue % radix;
uvalue = uvalue / radix;
}
else
{
digit = uvalue & 0xf;
uvalue = uvalue >> 4;
}
buffer[bi] = digit + ((digit <= 9) ? '0' : ('A' - 10));
bi++;
}
while (uvalue != 0);
if (negative)
{
buffer[bi] = '-';
bi += 1;
}
if (width <= bi)
{
PutStringReverse(buffer, bi);
}
else
{
width -= bi;
if (!left)
{
PutRepChar(fill, width);
}
PutStringReverse(buffer, bi);
if (left)
{
PutRepChar(fill, width);
}
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/