| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- /*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: f_printf.c
- * Date: 2021-08-23 16:24:02
- * LastEditTime: 2022-02-17 18:01:19
- * Description: This files is for
- *
- * Modify History:
- * Ver Who Date Changes
- * ----- ------ -------- --------------------------------------
- */
- #include <stdarg.h>
- #include "fearly_uart.h"
- #define putchar(c) OutByte(c)
- #define PAD_RIGHT 1
- #define PAD_ZERO 2
- static void printchar(char **str, int c)
- {
- if (str)
- {
- **str = c;
- ++(*str);
- }
- else
- (void)putchar((const char)c);
- }
- static int prints(char **out, const char *string, int width, int pad)
- {
- register int pc = 0, padchar = ' ';
- if (width > 0)
- {
- register int len = 0;
- register const char *ptr;
- for (ptr = string; *ptr; ++ptr)
- ++len;
- if (len >= width)
- width = 0;
- else
- width -= len;
- if (pad & PAD_ZERO)
- padchar = '0';
- }
- if (!(pad & PAD_RIGHT))
- {
- for (; width > 0; --width)
- {
- printchar(out, padchar);
- ++pc;
- }
- }
- for (; *string; ++string)
- {
- printchar(out, *string);
- ++pc;
- }
- for (; width > 0; --width)
- {
- printchar(out, padchar);
- ++pc;
- }
- return pc;
- }
- /* the following should be enough for 32 bit int */
- #define PRINT_BUF_LEN 12
- static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
- {
- char print_buf[PRINT_BUF_LEN];
- register char *s;
- register int t, neg = 0, pc = 0;
- register unsigned int u = i;
- if (i == 0)
- {
- print_buf[0] = '0';
- print_buf[1] = '\0';
- return prints(out, print_buf, width, pad);
- }
- if (sg && b == 10 && i < 0)
- {
- neg = 1;
- u = -i;
- }
- s = print_buf + PRINT_BUF_LEN - 1;
- *s = '\0';
- while (u)
- {
- t = u % b;
- if (t >= 10)
- t += letbase - '0' - 10;
- *--s = t + '0';
- u /= b;
- }
- if (neg)
- {
- if (width && (pad & PAD_ZERO))
- {
- printchar(out, '-');
- ++pc;
- --width;
- }
- else
- {
- *--s = '-';
- }
- }
- return pc + prints(out, s, width, pad);
- }
- static int print(char **out, const char *format, va_list args)
- {
- register int width, pad;
- register int pc = 0;
- char scr[2];
- for (; *format != 0; ++format)
- {
- if (*format == '%')
- {
- ++format;
- width = pad = 0;
- if (*format == '\0')
- break;
- if (*format == '%')
- goto out;
- if (*format == '-')
- {
- ++format;
- pad = PAD_RIGHT;
- }
- while (*format == '0')
- {
- ++format;
- pad |= PAD_ZERO;
- }
- for (; *format >= '0' && *format <= '9'; ++format)
- {
- width *= 10;
- width += *format - '0';
- }
- if (*format == 's')
- {
- //register char *s = (char *)va_arg( args, int );
- register char *s = (char *)va_arg(args, char *);
- pc += prints(out, s ? s : "(null)", width, pad);
- continue;
- }
- if (*format == 'd')
- {
- pc += printi(out, va_arg(args, int), 10, 1, width, pad, 'a');
- continue;
- }
- if (*format == 'x')
- {
- pc += printi(out, va_arg(args, int), 16, 0, width, pad, 'a');
- continue;
- }
- if (*format == 'X')
- {
- pc += printi(out, va_arg(args, int), 16, 0, width, pad, 'A');
- continue;
- }
- if (*format == 'u')
- {
- pc += printi(out, va_arg(args, int), 10, 0, width, pad, 'a');
- continue;
- }
- if (*format == 'c')
- {
- /* char are converted to int then pushed on the stack */
- scr[0] = (char)va_arg(args, int);
- scr[1] = '\0';
- pc += prints(out, scr, width, pad);
- continue;
- }
- }
- else
- {
- out:
- printchar(out, *format);
- ++pc;
- }
- }
- if (out)
- **out = '\0';
- va_end(args);
- return pc;
- }
- int f_printf(const char *format, ...)
- {
- va_list args;
- va_start(args, format);
- return print(0, format, args);
- }
- #ifdef TEST_PRINTF
- int test_printf(void)
- {
- char *ptr = "Hello world!";
- char *np = 0;
- int i = 5;
- unsigned int bs = sizeof(int) * 8;
- int mi;
- char buf[80];
- mi = (1 << (bs - 1)) + 1;
- f_printf("%s\n", ptr);
- f_printf("printf test\n");
- f_printf("%s is null pointer\n", np);
- f_printf("%d = 5\n", i);
- f_printf("%d = - max int\n", mi);
- f_printf("char %c = 'a'\n", 'a');
- f_printf("hex %x = ff\n", 0xff);
- f_printf("hex %02x = 00\n", 0);
- f_printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
- f_printf("%d %s(s)%", 0, "message");
- f_printf("\n");
- f_printf("%d %s(s) with %%\n", 0, "message");
- sprintf(buf, "justif: \"%-10s\"\n", "left");
- f_printf("%s", buf);
- sprintf(buf, "justif: \"%10s\"\n", "right");
- f_printf("%s", buf);
- sprintf(buf, " 3: %04d zero padded\n", 3);
- f_printf("%s", buf);
- sprintf(buf, " 3: %-4d left justif.\n", 3);
- f_printf("%s", buf);
- sprintf(buf, " 3: %4d right justif.\n", 3);
- f_printf("%s", buf);
- sprintf(buf, "-3: %04d zero padded\n", -3);
- f_printf("%s", buf);
- sprintf(buf, "-3: %-4d left justif.\n", -3);
- f_printf("%s", buf);
- sprintf(buf, "-3: %4d right justif.\n", -3);
- f_printf("%s", buf);
- return 0;
- }
- #endif
|