* device/lib/_strlen.c: assembler version for mcs51
[fw/sdcc] / device / lib / printf_fast.c
index 1db100827710ce1ff0e0bf9473662a03f1aae361..63a4308e2aee918ab0bf31a24609bc4f75668e09 100644 (file)
 /******************************************************************/
 /**                                                              **/
 /**    Major features.  These determine what capabilities your   **/
-/**    comiled printf_fast will have.                            **/
+/**    compiled printf_fast will have.                           **/
 /**                                                              **/
 /******************************************************************/
 
 // Include support for 32 bit base 10 integers (%ld and %lu).  Without
 // this, you won't be able to print 32 bit integers as base 10.  They
-// will appear in hexidecimal.
+// will appear in hexadecimal.
 #define LONG
 
 // Include support for floating point numbers (%f).  Don't forget to
 
 /* extern void putchar(char ); */
 
+// Warning: using static/global variables makes these functions NON-reentrant!
+// reentrant keyword is only used for parameter passing method
 
 static bit long_flag, short_flag, print_zero_flag, negative_flag;
 
 #ifdef FIELD_WIDTH
 static bit field_width_flag;
+static bit leading_zero_flag;
 static data unsigned char field_width;
 #endif
 
@@ -133,7 +136,7 @@ static data unsigned int i2bcd_tmp;  // slow 32 int conversion needs temp space
 
 void PRINTF_FAST(code char *fmt, ...) reentrant
 {
-       fmt;    /* supress unreferenced variable warning */
+       fmt;    /* suppress unreferenced variable warning */
 
        _asm
 
@@ -161,6 +164,7 @@ printf_format:
        clr     _negative_flag
 #ifdef FIELD_WIDTH
        clr     _field_width_flag
+       clr     _leading_zero_flag
        mov     r1, #_field_width
        mov     @r1, #0
 #endif
@@ -181,6 +185,10 @@ printf_format_loop:
        jnc     printf_nondigit2
 #ifdef FIELD_WIDTH
 printf_digit:
+       jnz     printf_digit_2
+       cjne    a, _field_width, printf_digit_2
+       setb    _leading_zero_flag
+printf_digit_2:
        setb    _field_width_flag
        mov     r2, a
        mov     a, @r1
@@ -228,6 +236,7 @@ printf_format_u:
 printf_format_c:
        //cjne  a, #'c', printf_format_x
        cjne    a, #99, printf_format_x
+       dec     r0
        mov     a, @r0          // Acc has the character to print
        dec     r0
        sjmp    printf_char
@@ -286,6 +295,7 @@ printf_string:
 
 #ifdef FIELD_WIDTH
        jnb     _field_width_flag, printf_str_loop
+       clr     _leading_zero_flag      // never leading zeros for strings
        push    dpl
        push    dph
 printf_str_fw_loop:
@@ -927,6 +937,7 @@ print_float_int:
        jnc     print_float_size_ok
 printf_float_too_big:
        // TODO: should print some sort of overflow error??
+       pop     ar0
        ljmp    printf_format_loop
 print_float_size_ok:
        push    dpl
@@ -1409,6 +1420,10 @@ printf_i2bcd_add_skip:
 printf_space_loop:
        //mov   a, #' '
        mov     a, #32
+       jnb     _leading_zero_flag, printf_space_output
+       //mov   a, #'0'
+       mov     a, #48
+printf_space_output:
        lcall   printf_putchar
        dec     _field_width
 printf_space: