?login_element?

Subversion Repositories NedoOS

Rev

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

  1. /*-----------------------------------------------------------------
  2.     printfl.c - source file for reduced version of printf
  3.  
  4.    Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
  5.    2001060401: Improved by was@icb.snz.chel.su
  6.  
  7.    This library is free software; you can redistribute it and/or modify it
  8.    under the terms of the GNU General Public License as published by the
  9.    Free Software Foundation; either version 2, or (at your option) any
  10.    later version.
  11.  
  12.    This library is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with this library; see the file COPYING. If not, write to the
  19.    Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
  20.    MA 02110-1301, USA.
  21.  
  22.    As a special exception, if you link this library with other files,
  23.    some of which are compiled with SDCC, to produce an executable,
  24.    this library does not by itself cause the resulting executable to
  25.    be covered by the GNU General Public License. This exception does
  26.    not however invalidate any other reasons why the executable file
  27.    might be covered by the GNU General Public License.
  28. -------------------------------------------------------------------------*/
  29.  
  30. /* following formats are supported :-
  31.    format     output type       argument-type
  32.      %d        decimal             int
  33.      %ld       decimal             long
  34.      %hd       decimal             char
  35.      %x        hexadecimal         int
  36.      %lx       hexadecimal         long
  37.      %hx       hexadecimal         char
  38.      %o        octal               int
  39.      %lo       octal               long
  40.      %ho       octal               char
  41.      %c        character           char
  42.      %s        character           generic pointer
  43. */
  44.  
  45. #include <stdarg.h>
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48.  
  49. static __data char radix ;
  50. static __bit  long_flag = 0;
  51. static __bit  string_flag =0;
  52. static __bit  char_flag = 0;
  53. static char * __data str ;
  54. static __data long val;
  55.  
  56. /* This great loop fails with the ds390 port (2003-01-13).
  57.  
  58.    At the beginning resp. end of the loop the compiler inserts a "push ar2"
  59.    resp. "pop ar2", which badly interferes with the push/pop in the source.
  60.  
  61.    Library functions should be rock solid and portable. There's an _ltoa in
  62.    the library, so let's use it and don't reinvent the wheel.
  63.  
  64.    Bernhard
  65. */
  66.  
  67. #if NICE_LIFO_IMPLEMENTATION_BUT_NOT_PORTABLE
  68. /* just for the SP */
  69. #include <8051.h>
  70.  
  71. static __data volatile char ch;
  72. static __bit sign;
  73.  
  74. static void pval(void)
  75. {
  76.         volatile char sp;
  77.         unsigned long lval;
  78.         sp = SP;
  79.  
  80.         if (val < 0 && radix != 16)
  81.         {
  82.            lval = -val;
  83.            sign = 1;
  84.         }
  85.         else { sign = 0; lval = val;}
  86.  
  87.         if (!long_flag) {
  88.           lval &= 0x0000ffff;
  89.         }
  90.         if (char_flag) {
  91.           lval &= 0x000000ff;
  92.         }
  93.  
  94.         do
  95.         {
  96.  
  97. #  if 1
  98.                 if(radix != 16)  ch = (lval % radix) + '0';
  99.                 else ch = "0123456789ABCDEF"[(unsigned char)lval & 0x0f];
  100.                 __asm push _ch __endasm;
  101.                 lval /= radix;
  102. #  else
  103.                 // This only looks more efficient, but isn't. see the .map
  104.                 ch = (lval % radix) + '0';
  105.                 if (ch>'9') ch+=7;
  106.                 __asm push _ch __endasm;
  107.                 lval /= radix;
  108. #  endif
  109.         }
  110.         while (lval);
  111.  
  112.         if (sign) {
  113.                 ch = '-';
  114.                 __asm push _ch __endasm;
  115.         }
  116.  
  117.         while (sp != SP) {
  118.                 __asm pop _ch __endasm;
  119.                 putchar(ch);
  120.         }
  121. }
  122. #endif
  123.  
  124. void printf_small (char * fmt, ... ) __reentrant
  125. {
  126.     va_list ap ;
  127.  
  128.     va_start(ap,fmt);
  129.  
  130.     for (; *fmt ; fmt++ ) {
  131.         if (*fmt == '%') {
  132.             long_flag = string_flag = char_flag = 0;
  133.             fmt++ ;
  134.             switch (*fmt) {
  135.             case 'l':
  136.                 long_flag = 1;
  137.                 fmt++;
  138.                 break;
  139.             case 'h':
  140.                 char_flag = 1;
  141.                 fmt++;
  142.             }
  143.  
  144.             switch (*fmt) {
  145.             case 's':
  146.                 string_flag = 1;
  147.                 break;
  148.             case 'd':
  149.                 radix = 10;
  150.                 break;
  151.             case 'x':
  152.                 radix = 16;
  153.                 break;
  154.             case 'c':
  155.                 radix = 0;
  156.                 break;
  157.             case 'o':
  158.                 radix = 8;
  159.                 break;
  160.             }
  161.  
  162.             if (string_flag) {
  163.                 str = va_arg(ap, char *);
  164.                 while (*str) putchar(*str++);
  165.                 continue ;
  166.             }
  167.  
  168.             if (long_flag)
  169.                 val = va_arg(ap,long);
  170.             else
  171.                 if (char_flag)
  172.                     val = va_arg(ap,char);
  173.                 else
  174.                     val = va_arg(ap,int);
  175.  
  176. #if NICE_LIFO_IMPLEMENTATION_BUT_NOT_PORTABLE
  177.             if (radix) pval();
  178. #else
  179.             if (radix)
  180.             {
  181.               static char __idata buffer[12]; /* 37777777777(oct) */
  182.               char __idata * stri;
  183.  
  184.               _ltoa (val, buffer, radix);
  185.               stri = buffer;
  186.               while (*stri)
  187.                 {
  188.                   putchar (*stri);
  189.                   stri++;
  190.                 }
  191.             }
  192. #endif
  193.             else
  194.               putchar((char)val);
  195.  
  196.         } else
  197.             putchar(*fmt);
  198.     }
  199. }
  200.