Subversion Repositories DashDisplay

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.         Copyright 2001, 2002 Georges Menie (www.menie.org)
  3.         stdarg version contributed by Christian Ettinger
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU Lesser General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU Lesser General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Lesser General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18. */
  19.  
  20. /* Includes */
  21.  
  22.  
  23. #include "../../small_printf/Inc/small_printf.h"
  24.  
  25. #include <stdarg.h>
  26. #include <stdio.h>
  27. #include <string.h>
  28.  
  29. /*
  30.         putchar is the only external dependency for this file,
  31.         if you have a working putchar, leave it commented out.
  32.         If not, uncomment the define below and
  33.         replace outbyte(c) by your own function call.
  34. */
  35.  
  36.  
  37.  
  38. static void printchar(char **str, int c)
  39. {
  40.  
  41.  
  42.         if (str) {
  43.                 **str = c;
  44.                 ++(*str);
  45.         }
  46.         else (void)PutCharSerial(c);
  47. }
  48.  
  49. #define PAD_RIGHT 1
  50. #define PAD_ZERO 2
  51.  
  52. static int prints(char **out, const char *string, int width, int pad)
  53. {
  54.         register int pc = 0, padchar = ' ';
  55.  
  56.         if (width > 0) {
  57.                 register int len = 0;
  58.                 register const char *ptr;
  59.                 for (ptr = string; *ptr; ++ptr) ++len;
  60.                 if (len >= width) width = 0;
  61.                 else width -= len;
  62.                 if (pad & PAD_ZERO) padchar = '0';
  63.         }
  64.         if (!(pad & PAD_RIGHT)) {
  65.                 for ( ; width > 0; --width) {
  66.                         printchar (out, padchar);
  67.                         ++pc;
  68.                 }
  69.         }
  70.         for ( ; *string ; ++string) {
  71.                 printchar (out, *string);
  72.                 ++pc;
  73.         }
  74.         for ( ; width > 0; --width) {
  75.                 printchar (out, padchar);
  76.                 ++pc;
  77.         }
  78.  
  79.         return pc;
  80. }
  81.  
  82. /* the following should be enough for 32 bit int */
  83. #define PRINT_BUF_LEN 12
  84.  
  85. static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
  86. {
  87.         char print_buf[PRINT_BUF_LEN];
  88.         register char *s;
  89.         register int t, neg = 0, pc = 0;
  90.         register unsigned int u = i;
  91.  
  92.         if (i == 0) {
  93.                 print_buf[0] = '0';
  94.                 print_buf[1] = '\0';
  95.                 return prints (out, print_buf, width, pad);
  96.         }
  97.  
  98.         if (sg && b == 10 && i < 0) {
  99.                 neg = 1;
  100.                 u = -i;
  101.         }
  102.  
  103.         s = print_buf + PRINT_BUF_LEN-1;
  104.         *s = '\0';
  105.  
  106.         while (u) {
  107.                 t = u % b;
  108.                 if( t >= 10 )
  109.                         t += letbase - '0' - 10;
  110.                 *--s = t + '0';
  111.                 u /= b;
  112.         }
  113.  
  114.         if (neg) {
  115.                 if( width && (pad & PAD_ZERO) ) {
  116.                         printchar (out, '-');
  117.                         ++pc;
  118.                         --width;
  119.                 }
  120.                 else {
  121.                         *--s = '-';
  122.                 }
  123.         }
  124.  
  125.         return pc + prints (out, s, width, pad);
  126. }
  127.  
  128. static int small_print(char **out, const char *format, va_list args )
  129. {
  130.         register int width, pad;
  131.         register int pc = 0;
  132.         char scr[2];
  133.  
  134.         for (; *format != 0; ++format) {
  135.                 if (*format == '%') {
  136.                         ++format;
  137.                         width = pad = 0;
  138.                         if (*format == '\0') break;
  139.                         if (*format == '%') goto out;
  140.                         if (*format == '-') {
  141.                                 ++format;
  142.                                 pad = PAD_RIGHT;
  143.                         }
  144.                         while (*format == '0') {
  145.                                 ++format;
  146.                                 pad |= PAD_ZERO;
  147.                         }
  148.                         if ('*' == *format)
  149.                         {
  150.                                 width = va_arg( args, int );    // get width from next argument
  151.                                 format++;
  152.                         }
  153.                         else
  154.                         {
  155.                                 for ( ; *format >= '0' && *format <= '9'; ++format)
  156.                                 {
  157.                                         width *= 10;
  158.                                         width += *format - '0';
  159.                                 }
  160.                         }
  161.                         if( *format == 'l') { /* skip l in ld etc */
  162.                                 format++;
  163.                         }
  164.                         if( *format == 's' ) {
  165.                                 register char *s = (char *)va_arg( args, int );
  166.                                 pc += prints (out, s?s:"(null)", width, pad);
  167.                                 continue;
  168.                         }
  169.                         if( *format == 'd' ) {
  170.                                 pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');
  171.                                 continue;
  172.                         }
  173.                         if( *format == 'x' ) {
  174.                                 pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');
  175.                                 continue;
  176.                         }
  177.                         if( *format == 'X' ) {
  178.                                 pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');
  179.                                 continue;
  180.                         }
  181.                         if( *format == 'u' ) {
  182.                                 pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');
  183.                                 continue;
  184.                         }
  185.                         if( *format == 'c' ) {
  186.                                 /* char are converted to int then pushed on the stack */
  187.                                 scr[0] = (char)va_arg( args, int );
  188.                                 scr[1] = '\0';
  189.                                 pc += prints (out, scr, width, pad);
  190.                                 continue;
  191.                         }
  192.                         if( *format == 'n' )
  193.                         {       /* convert number printed so far and store in *va_arg( args, int)... */
  194.                                 int *dp = va_arg( args, int );
  195.                                 *dp = pc;
  196.                                 continue;
  197.                         }
  198.                 }
  199.                 else {
  200.                 out:
  201.                         /* deal with LF -> CRLF mapping */
  202.                         if(*format == '\n')
  203.                         {
  204.                                 printchar(out,'\r');
  205.                         }
  206.                         printchar (out, *format);
  207.                         ++pc;
  208.                 }
  209.         }
  210.         if (out) **out = '\0';
  211.         return pc;
  212. }
  213.  
  214.  
  215. int small_printf(const char *format, ...)
  216. {
  217.         int result = 0;
  218.         va_list args;
  219.  
  220.         va_start( args, format );
  221.         result = small_print( 0, format, args );
  222.         va_end(args);
  223.         return result;
  224. }
  225.  
  226. int small_sprintf(char *out, const char *format, ...)
  227. {
  228.     int result = 0;
  229.                 va_list args;
  230.         va_start( args, format );
  231.         result = small_print( &out, format, args );
  232.         va_end(args);
  233.         return result;
  234. }
  235.  
  236.