00001
00080 #include "formatwr.h"
00081
00082 #include "cfg/cfg_formatwr.h"
00083 #include <cfg/debug.h>
00084
00085 #include <cpu/pgm.h>
00086 #include <mware/hex.h>
00087
00088 #ifndef CONFIG_PRINTF_N_FORMATTER
00089
00090 #define CONFIG_PRINTF_N_FORMATTER 0
00091 #endif
00092
00093 #ifndef CONFIG_PRINTF_OCTAL_FORMATTER
00094
00095 #define CONFIG_PRINTF_OCTAL_FORMATTER 0
00096 #endif
00097
00098
00099 #define CONFIG_PRINTF_COUNT_CHARS (CONFIG_PRINTF_RETURN_COUNT || CONFIG_PRINTF_N_FORMATTER)
00100
00101 #if CONFIG_PRINTF
00102
00103 #if CONFIG_PRINTF > PRINTF_NOFLOAT
00104 #include <float.h>
00105
00106
00107 typedef long double max_float_t;
00108
00109
00110 #define FRMWRI_BUFSIZE 134
00111 #warning 134 is too much, the code must be fixed to have a lower precision limit
00112 #else
00113
00114
00115
00116
00117 #define FRMWRI_BUFSIZE 16
00118 #endif
00119
00120
00121 #ifndef MEM_ATTRIBUTE
00122 #define MEM_ATTRIBUTE
00123 #endif
00124
00125 #if CONFIG_PRINTF > PRINTF_NOMODIFIERS
00126 #define IS_SHORT (h_modifier || (sizeof(int) == 2 && !l_modifier))
00127 #else
00128 #define IS_SHORT (sizeof(int) == 2)
00129 #endif
00130
00131
00132 #if CONFIG_PRINTF > PRINTF_NOFLOAT
00133
00134 static char *float_conversion(MEM_ATTRIBUTE max_float_t value,
00135 MEM_ATTRIBUTE short nr_of_digits,
00136 MEM_ATTRIBUTE char *buf,
00137 MEM_ATTRIBUTE char format_flag,
00138 MEM_ATTRIBUTE char g_flag,
00139 MEM_ATTRIBUTE bool alternate_flag)
00140 {
00141 MEM_ATTRIBUTE char *cp;
00142 MEM_ATTRIBUTE char *buf_pointer;
00143 MEM_ATTRIBUTE short n, i, dec_point_pos, integral_10_log;
00144
00145 buf_pointer = buf;
00146 integral_10_log = 0;
00147
00148 if (value >= 1)
00149 {
00150 while (value >= 1e11)
00151 {
00152 value /= 1e10;
00153 integral_10_log += 10;
00154 }
00155 while (value >= 10)
00156 {
00157 value /= 10;
00158 integral_10_log++;
00159 }
00160 }
00161 else if (value)
00162 {
00163 while (value <= 1e-10)
00164 {
00165 value *= 1e10;
00166 integral_10_log -= 10;
00167 }
00168 while (value < 1)
00169 {
00170 value *= 10;
00171 integral_10_log--;
00172 }
00173 }
00174 if (g_flag)
00175 {
00176 if (integral_10_log < nr_of_digits && integral_10_log >= -4)
00177 {
00178 format_flag = 0;
00179 nr_of_digits -= integral_10_log;
00180 }
00181 nr_of_digits--;
00182 if (alternate_flag)
00183
00184 g_flag = 0;
00185 else
00186
00187 alternate_flag = true;
00188 }
00189
00190
00191 if (format_flag)
00192 {
00193 dec_point_pos = 0;
00194 }
00195 else
00196 {
00197
00198 if (integral_10_log < 0)
00199 {
00200 *buf_pointer++ = '0';
00201 if ((n = nr_of_digits) || alternate_flag)
00202 *buf_pointer++ = '.';
00203 i = 0;
00204 while (--i > integral_10_log && nr_of_digits)
00205 {
00206 *buf_pointer++ = '0';
00207 nr_of_digits--;
00208 }
00209 if (integral_10_log < (-n - 1))
00210
00211 goto CLEAN_UP;
00212 dec_point_pos = 1;
00213 }
00214 else
00215 {
00216 dec_point_pos = - integral_10_log;
00217 }
00218 }
00219
00220 i = dec_point_pos;
00221 while (i <= nr_of_digits )
00222 {
00223 value -= (max_float_t)(n = (short)value);
00224 value *= 10;
00225 *buf_pointer++ = n + '0';
00226 if ( ! i++ && (nr_of_digits || alternate_flag))
00227 *buf_pointer++ = '.';
00228 }
00229
00230
00231 if (value >= 5)
00232 {
00233 n = 1;
00234 cp = buf_pointer - 1;
00235 do
00236 {
00237 if (*cp != '.')
00238 {
00239 if ( (*cp += n) == ('9' + 1) )
00240 {
00241 *cp = '0';
00242 n = 1;
00243 }
00244 else
00245 n = 0;
00246 }
00247 } while (cp-- > buf);
00248 if (n)
00249 {
00250
00251 if (format_flag)
00252 {
00253 cp = buf_pointer;
00254 while (cp > buf)
00255 {
00256 if (*(cp - 1) == '.')
00257 {
00258 *cp = *(cp - 2);
00259 cp--;
00260 }
00261 else
00262 *cp = *(cp - 1);
00263 cp--;
00264 }
00265 integral_10_log++;
00266 }
00267 else
00268 {
00269 cp = ++buf_pointer;
00270 while (cp > buf)
00271 {
00272 *cp = *(cp - 1);
00273 cp--;
00274 }
00275 }
00276 *buf = '1';
00277 }
00278 }
00279
00280 CLEAN_UP:
00281
00282 if (g_flag)
00283 {
00284 while (*(buf_pointer - 1) == '0')
00285 buf_pointer--;
00286 if (*(buf_pointer - 1) == '.')
00287 buf_pointer--;
00288 }
00289
00290
00291 if (format_flag)
00292 {
00293 *buf_pointer++ = format_flag;
00294 if (integral_10_log < 0)
00295 {
00296 *buf_pointer++ = '-';
00297 integral_10_log = -integral_10_log;
00298 }
00299 else
00300 *buf_pointer++ = '+';
00301 n = 0;
00302 buf_pointer +=10;
00303 do
00304 {
00305 n++;
00306 *buf_pointer++ = (integral_10_log % 10) + '0';
00307 integral_10_log /= 10;
00308 } while ( integral_10_log || n < 2 );
00309 for ( i = n ; n > 0 ; n-- )
00310 *(buf_pointer - 11 - i + n) = *(buf_pointer - n);
00311 buf_pointer -= 10;
00312 }
00313 return (buf_pointer);
00314 }
00315
00316 #endif
00317
00323 int
00324 PGM_FUNC(_formatted_write)(const char * PGM_ATTR format,
00325 void put_one_char(char, void *),
00326 void *secret_pointer,
00327 va_list ap)
00328 {
00329 #if CONFIG_PRINTF > PRINTF_REDUCED
00330 MEM_ATTRIBUTE static char bad_conversion[] = "???";
00331 MEM_ATTRIBUTE static char null_pointer[] = "<NULL>";
00332
00333 MEM_ATTRIBUTE int precision;
00334 MEM_ATTRIBUTE int n;
00335 #if CONFIG_PRINTF_COUNT_CHARS
00336 MEM_ATTRIBUTE int nr_of_chars;
00337 #endif
00338 MEM_ATTRIBUTE int field_width;
00339 MEM_ATTRIBUTE char format_flag;
00340 enum PLUS_SPACE_FLAGS {
00341 PSF_NONE, PSF_PLUS, PSF_MINUS
00342 };
00343 enum DIV_FACTOR {
00344 DIV_DEC, DIV_HEX,
00345 #if CONFIG_PRINTF_OCTAL_FORMATTER
00346 DIV_OCT,
00347 #endif
00348 };
00349 MEM_ATTRIBUTE struct {
00350 enum PLUS_SPACE_FLAGS plus_space_flag : 2;
00351 #if CONFIG_PRINTF_OCTAL_FORMATTER
00352 enum DIV_FACTOR div_factor : 2;
00353 #else
00354 enum DIV_FACTOR div_factor : 1;
00355 #endif
00356 bool left_adjust : 1;
00357 bool l_L_modifier : 1;
00358 bool h_modifier : 1;
00359 bool alternate_flag : 1;
00360 bool nonzero_value : 1;
00361 bool zeropad : 1;
00362 #if CPU_HARVARD
00363 bool progmem : 1;
00364 #endif
00365 } flags;
00366 MEM_ATTRIBUTE unsigned long ulong;
00367
00368 #if CONFIG_PRINTF > PRINTF_NOFLOAT
00369 MEM_ATTRIBUTE max_float_t fvalue;
00370 #endif
00371
00372 MEM_ATTRIBUTE char *buf_pointer;
00373 MEM_ATTRIBUTE char *ptr;
00374 MEM_ATTRIBUTE const char *hex;
00375 MEM_ATTRIBUTE char buf[FRMWRI_BUFSIZE];
00376
00377 #if CONFIG_PRINTF_COUNT_CHARS
00378 nr_of_chars = 0;
00379 #endif
00380 for (;;)
00381 {
00382 while ((format_flag = PGM_READ_CHAR(format++)) != '%')
00383 {
00384 if (!format_flag)
00385 #if CONFIG_PRINTF_RETURN_COUNT
00386 return (nr_of_chars);
00387 #else
00388 return 0;
00389 #endif
00390 put_one_char(format_flag, secret_pointer);
00391 #if CONFIG_PRINTF_COUNT_CHARS
00392 nr_of_chars++;
00393 #endif
00394 }
00395 if (PGM_READ_CHAR(format) == '%')
00396 {
00397 format++;
00398 put_one_char('%', secret_pointer);
00399 #if CONFIG_PRINTF_COUNT_CHARS
00400 nr_of_chars++;
00401 #endif
00402 continue;
00403 }
00404
00405 flags.left_adjust = false;
00406 flags.alternate_flag = false;
00407 flags.plus_space_flag = PSF_NONE;
00408 flags.zeropad = false;
00409 #if CPU_HARVARD
00410 flags.progmem = false;
00411 #endif
00412 ptr = buf_pointer = &buf[0];
00413 hex = HEX_tab;
00414
00415
00416 for (;;)
00417 {
00418 switch (PGM_READ_CHAR(format))
00419 {
00420 case ' ':
00421 if (flags.plus_space_flag)
00422 goto NEXT_FLAG;
00423 case '+':
00424 flags.plus_space_flag = PSF_PLUS;
00425 goto NEXT_FLAG;
00426 case '-':
00427 flags.left_adjust = true;
00428 goto NEXT_FLAG;
00429 case '#':
00430 flags.alternate_flag = true;
00431 goto NEXT_FLAG;
00432 case '0':
00433 flags.zeropad = true;
00434 goto NEXT_FLAG;
00435 }
00436 break;
00437 NEXT_FLAG:
00438 format++;
00439 }
00440
00441
00442 if (PGM_READ_CHAR(format) == '*')
00443 {
00444 field_width = va_arg(ap, int);
00445 if (field_width < 0)
00446 {
00447 field_width = -field_width;
00448 flags.left_adjust = true;
00449 }
00450 format++;
00451 }
00452 else
00453 {
00454 field_width = 0;
00455 while (PGM_READ_CHAR(format) >= '0' && PGM_READ_CHAR(format) <= '9')
00456 field_width = field_width * 10 + (PGM_READ_CHAR(format++) - '0');
00457 }
00458
00459 if (flags.left_adjust)
00460 flags.zeropad = false;
00461
00462
00463 if (PGM_READ_CHAR(format) == '.')
00464 {
00465 if (PGM_READ_CHAR(++format) == '*')
00466 {
00467 precision = va_arg(ap, int);
00468 format++;
00469 }
00470 else
00471 {
00472 precision = 0;
00473 while (PGM_READ_CHAR(format) >= '0' && PGM_READ_CHAR(format) <= '9')
00474 precision = precision * 10 + (PGM_READ_CHAR(format++) - '0');
00475 }
00476 }
00477 else
00478 precision = -1;
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 flags.l_L_modifier = false;
00491 flags.h_modifier = false;
00492
00493
00494 switch (PGM_READ_CHAR(format))
00495 {
00496 case 'l':
00497 case 'L':
00498 case 'z':
00499 flags.l_L_modifier = true;
00500 format++;
00501 break;
00502 case 'h':
00503 flags.h_modifier = true;
00504 format++;
00505 break;
00506 }
00507
00508
00509
00510
00511
00512
00513 switch (format_flag = PGM_READ_CHAR(format++))
00514 {
00515 #if CONFIG_PRINTF_N_FORMATTER
00516 case 'n':
00517 if (sizeof(short) != sizeof(int))
00518 {
00519 if (sizeof(int) != sizeof(long))
00520 {
00521 if (h_modifier)
00522 *va_arg(ap, short *) = nr_of_chars;
00523 else if (flags.l_L_modifier)
00524 *va_arg(ap, long *) = nr_of_chars;
00525 else
00526 *va_arg(ap, int *) = nr_of_chars;
00527 }
00528 else
00529 {
00530 if (h_modifier)
00531 *va_arg(ap, short *) = nr_of_chars;
00532 else
00533 *va_arg(ap, int *) = nr_of_chars;
00534 }
00535 }
00536 else
00537 {
00538 if (flags.l_L_modifier)
00539 *va_arg(ap, long *) = nr_of_chars;
00540 else
00541 *va_arg(ap, int *) = nr_of_chars;
00542 }
00543 continue;
00544 #endif
00545 case 'c':
00546 buf[0] = va_arg(ap, int);
00547 ptr++;
00548 break;
00549
00550
00551 case 'S':
00552 #if CPU_HARVARD
00553 flags.progmem = true;
00554 #endif
00555
00556
00557 case 's':
00558 if ( !(buf_pointer = va_arg(ap, char *)) )
00559 buf_pointer = null_pointer;
00560 if (precision < 0)
00561 precision = 10000;
00562
00563
00564
00565
00566
00567 ptr = buf_pointer;
00568 #if CPU_HARVARD
00569 if (flags.progmem)
00570 {
00571 for (n=0; pgm_read_char(ptr) && n < precision; n++)
00572 ++ptr;
00573 }
00574 else
00575 #endif
00576 for (n=0; *ptr && n < precision; n++)
00577 ++ptr;
00578 break;
00579
00580 #if CONFIG_PRINTF_OCTAL_FORMATTER
00581 case 'o':
00582 if (flags.alternate_flag && !precision)
00583 precision++;
00584 #endif
00585 case 'x':
00586 hex = hex_tab;
00587 case 'u':
00588 case 'p':
00589 case 'X':
00590 if (format_flag == 'p')
00591 #if defined(__AVR__) || defined(__I196__)
00592 ulong = (unsigned long)(unsigned short)va_arg(ap, char *);
00593 #else
00594 ulong = (unsigned long)va_arg(ap, char *);
00595 #endif
00596 else if (flags.l_L_modifier)
00597 ulong = va_arg(ap, unsigned long);
00598 else if (flags.h_modifier)
00599 ulong = (unsigned long)(unsigned short)va_arg(ap, unsigned int);
00600 else
00601 ulong = va_arg(ap, unsigned int);
00602
00603 flags.div_factor =
00604 #if CONFIG_PRINTF_OCTAL_FORMATTER
00605 (format_flag == 'o') ? DIV_OCT :
00606 #endif
00607 (format_flag == 'u') ? DIV_DEC : DIV_HEX;
00608 flags.plus_space_flag = PSF_NONE;
00609 goto INTEGRAL_CONVERSION;
00610
00611 case 'd':
00612 case 'i':
00613 if (flags.l_L_modifier)
00614 ulong = (unsigned long)(long)va_arg(ap, long);
00615 else
00616 ulong = (unsigned long)(long)va_arg(ap, int);
00617
00618
00619 if ((signed long)ulong < 0)
00620 {
00621 flags.plus_space_flag = PSF_MINUS;
00622 ulong = (unsigned long)(-((signed long)ulong));
00623 }
00624
00625 flags.div_factor = DIV_DEC;
00626
00627
00628 INTEGRAL_CONVERSION:
00629 ptr = buf_pointer = &buf[FRMWRI_BUFSIZE - 1];
00630 flags.nonzero_value = (ulong != 0);
00631
00632
00633 if (precision != 0 || flags.nonzero_value)
00634 {
00635 switch (flags.div_factor)
00636 {
00637 case DIV_DEC:
00638 do
00639 *--buf_pointer = hex[ulong % 10];
00640 while (ulong /= 10);
00641 break;
00642
00643 case DIV_HEX:
00644 do
00645 *--buf_pointer = hex[ulong % 16];
00646 while (ulong /= 16);
00647 break;
00648 #if CONFIG_PRINTF_OCTAL_FORMATTER
00649 case DIV_OCT:
00650 do
00651 *--buf_pointer = hex[ulong % 8];
00652 while (ulong /= 8);
00653 break;
00654 #endif
00655 }
00656 }
00657
00658
00659 if (precision < 0)
00660 if (flags.zeropad)
00661 precision = field_width - (flags.plus_space_flag != PSF_NONE);
00662 while (precision > (int)(ptr - buf_pointer))
00663 *--buf_pointer = '0';
00664
00665 if (flags.alternate_flag && flags.nonzero_value)
00666 {
00667 if (format_flag == 'x' || format_flag == 'X')
00668 {
00669 *--buf_pointer = format_flag;
00670 *--buf_pointer = '0';
00671 }
00672 #if CONFIG_PRINTF_OCTAL_FORMATTER
00673 else if ((format_flag == 'o') && (*buf_pointer != '0'))
00674 {
00675 *--buf_pointer = '0';
00676 }
00677 #endif
00678 }
00679 ASSERT(buf_pointer >= buf);
00680 break;
00681
00682 #if CONFIG_PRINTF > PRINTF_NOFLOAT
00683 case 'g':
00684 case 'G':
00685 n = 1;
00686 format_flag -= 2;
00687 if (! precision)
00688 {
00689 precision = 1;
00690 }
00691 goto FLOATING_CONVERSION;
00692 case 'f':
00693 format_flag = 0;
00694 case 'e':
00695 case 'E':
00696 n = 0;
00697 FLOATING_CONVERSION:
00698 if (precision < 0)
00699 {
00700 precision = 6;
00701 }
00702
00703 if (sizeof(double) != sizeof(max_float_t))
00704 {
00705 fvalue = flags.l_L_modifier ?
00706 va_arg(ap,max_float_t) : va_arg(ap,double);
00707 }
00708 else
00709 fvalue = va_arg(ap,max_float_t);
00710
00711 if (fvalue < 0)
00712 {
00713 flags.plus_space_flag = PSF_MINUS;
00714 fvalue = -fvalue;
00715 }
00716 ptr = float_conversion (fvalue,
00717 (short)precision,
00718 buf_pointer += field_width,
00719 format_flag,
00720 (char)n,
00721 flags.alternate_flag);
00722 if (flags.zeropad)
00723 {
00724 precision = field_width - (flags.plus_space_flag != PSF_NONE);
00725 while (precision > ptr - buf_pointer)
00726 *--buf_pointer = '0';
00727 }
00728 break;
00729
00730 #endif
00731
00732 case '\0':
00733 format--;
00734
00735 default:
00736
00737 ptr = buf_pointer = bad_conversion;
00738 ptr += sizeof(bad_conversion) - 1;
00739 break;
00740
00741 }
00742
00743
00744
00745
00746
00747
00748 precision = ptr - buf_pointer;
00749
00750 if ( precision > field_width)
00751 {
00752 n = 0;
00753 }
00754 else
00755 {
00756 n = field_width - precision - (flags.plus_space_flag != PSF_NONE);
00757 }
00758
00759
00760 if (!flags.left_adjust)
00761 while (--n >= 0)
00762 {
00763 put_one_char(' ', secret_pointer);
00764 #if CONFIG_PRINTF_COUNT_CHARS
00765 nr_of_chars++;
00766 #endif
00767 }
00768
00769
00770 if (flags.plus_space_flag)
00771 {
00772 put_one_char(flags.plus_space_flag == PSF_PLUS ? '+' : '-', secret_pointer);
00773 #if CONFIG_PRINTF_COUNT_CHARS
00774 nr_of_chars++;
00775 #endif
00776 }
00777
00778 #if CPU_HARVARD
00779 if (flags.progmem)
00780 {
00781 while (--precision >= 0)
00782 {
00783 put_one_char(pgm_read_char(buf_pointer++), secret_pointer);
00784 #if CONFIG_PRINTF_COUNT_CHARS
00785 nr_of_chars++;
00786 #endif
00787 }
00788 }
00789 else
00790 #endif
00791 {
00792
00793 while (--precision >= 0)
00794 {
00795 put_one_char(*buf_pointer++, secret_pointer);
00796 #if CONFIG_PRINTF_COUNT_CHARS
00797 nr_of_chars++;
00798 #endif
00799 }
00800 }
00801
00802
00803 if (flags.left_adjust)
00804 while (--n >= 0)
00805 {
00806 put_one_char(' ', secret_pointer);
00807 #if CONFIG_PRINTF_COUNT_CHARS
00808 nr_of_chars++;
00809 #endif
00810 }
00811 }
00812
00813 #else
00814
00815 #if CONFIG_PRINTF > PRINTF_NOMODIFIERS
00816 bool l_modifier, h_modifier;
00817 unsigned long u_val, div_val;
00818 #else
00819 unsigned int u_val, div_val;
00820 #endif
00821
00822 char format_flag;
00823 unsigned int nr_of_chars, base;
00824 char outChar;
00825 char *ptr;
00826
00827 nr_of_chars = 0;
00828 for (;;)
00829 {
00830 while ((format_flag = PGM_READ_CHAR(format++)) != '%')
00831 {
00832 if (!format_flag)
00833 return (nr_of_chars);
00834 put_one_char(format_flag, secret_pointer);
00835 nr_of_chars++;
00836 }
00837
00838 #if CONFIG_PRINTF > PRINTF_NOMODIFIERS
00839
00840
00841
00842 l_modifier = h_modifier = false;
00843 switch (PGM_READ_CHAR(format))
00844 {
00845 case 'l':
00846 case 'z':
00847
00848 STATIC_ASSERT(sizeof(size_t) == sizeof(long));
00849 l_modifier = true;
00850 format++;
00851 break;
00852
00853 case 'h':
00854 h_modifier = true;
00855 format++;
00856 break;
00857 }
00858 #endif
00859
00860 switch (format_flag = PGM_READ_CHAR(format++))
00861 {
00862 case 'c':
00863 format_flag = va_arg(ap, int);
00864 default:
00865 put_one_char(format_flag, secret_pointer);
00866 nr_of_chars++;
00867 continue;
00868
00869 case 's':
00870 ptr = va_arg(ap, char *);
00871 while ((format_flag = *ptr++))
00872 {
00873 put_one_char(format_flag, secret_pointer);
00874 nr_of_chars++;
00875 }
00876 continue;
00877
00878 case 'o':
00879 base = 8;
00880 if (IS_SHORT)
00881 div_val = 0x8000;
00882 else
00883 div_val = 0x40000000;
00884 goto CONVERSION_LOOP;
00885
00886 case 'd':
00887 base = 10;
00888 if (IS_SHORT)
00889 div_val = 10000;
00890 else
00891 div_val = 1000000000;
00892 goto CONVERSION_LOOP;
00893
00894 case 'X':
00895 case 'x':
00896 base = 16;
00897 if (IS_SHORT)
00898 div_val = 0x1000;
00899 else
00900 div_val = 0x10000000;
00901
00902 CONVERSION_LOOP:
00903 #if CONFIG_PRINTF > PRINTF_NOMODIFIERS
00904 if (h_modifier)
00905 {
00906 if (format_flag == 'd')
00907 u_val = (short)va_arg(ap, int);
00908 else
00909 u_val = (unsigned short)va_arg(ap, int);
00910 }
00911 else if (l_modifier)
00912 u_val = va_arg(ap, long);
00913 else
00914 {
00915 if (format_flag == 'd')
00916 u_val = va_arg(ap, int);
00917 else
00918 u_val = va_arg(ap, unsigned int);
00919 }
00920
00921 #else
00922 u_val = va_arg(ap,int);
00923 #endif
00924 if (format_flag == 'd')
00925 {
00926 if (((int)u_val) < 0)
00927 {
00928 u_val = - u_val;
00929 put_one_char('-', secret_pointer);
00930 nr_of_chars++;
00931 }
00932 }
00933 while (div_val > 1 && div_val > u_val)
00934 {
00935 div_val /= base;
00936 }
00937 do
00938 {
00939 outChar = (u_val / div_val) + '0';
00940 if (outChar > '9')
00941 {
00942 if (format_flag == 'x')
00943 outChar += 'a'-'9'-1;
00944 else
00945 outChar += 'A'-'9'-1;
00946 }
00947 put_one_char(outChar, secret_pointer);
00948 nr_of_chars++;
00949 u_val %= div_val;
00950 div_val /= base;
00951 }
00952 while (div_val);
00953
00954 }
00955 }
00956 #endif
00957 }
00958
00959 #endif