00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00023 #include "../include/beeos.h"
00024 #include "../include/bstring.h"
00025
00026 #include <stdarg.h>
00027 #define IN_BPRINTF
00028 #include "../include/bprintf.h"
00029 #ifndef HOSTED_BUILD
00030 # include "../include/arch/param.h"
00031 # include "../include/asm/ports.h"
00032 # include "../include/asm/ports_std.h"
00033 # include "../include/sci.h"
00034 #else
00035 # include <stdio.h>
00036 #endif
00037
00038
00039 bool lk_bputs;
00040 bool lk_putchar;
00041
00042
00048 #define digit2char(dst, num) do {\
00049 if ((char)10 > num) {\
00050 dst = num + '0';\
00051 } else {\
00052 dst = num + (char)'a' - (char)10;\
00053 }\
00054 } while(0);
00055
00056 #ifndef HOSTED_BUILD
00057
00061 void putchar(char c)
00062 {
00066
00067 lk_putchar = true;
00068 sci_tx(((uchar *) (&SCI0BDH)), c);
00069 lk_putchar = false;
00070 }
00071 #endif
00072
00077
00078 void bputs(char *pSrc)
00079
00080 {
00081
00082 while (lk_bputs);
00083 lk_bputs = true;
00084 do {
00085 putchar(*pSrc);
00086 } while ('\0' != *pSrc++);
00087 lk_bputs = false;
00088
00089
00090 return;
00091 }
00092
00093 #ifdef INT2STRING
00094
00101 void int2string(char **ppDst, sshort number, uchar intbase)
00102 {
00119 ushort quotient, multiplier, i;
00120
00121 switch (intbase) {
00122 case 10: multiplier = 10000; break;
00123 case 0x10: multiplier = 0x1000; break;
00124 default: multiplier = 0x8000; break;
00125 }
00126 if (0 == number) *(*ppDst)++ = '0';
00127 else {
00128 if (0 > number) {
00129 *(*ppDst)++ = '-';
00130 number *= -1;
00131 }
00132 do {
00133 if (number >= multiplier) {
00134 quotient = number/multiplier;
00135 number -= quotient*multiplier;
00136 digit2char(**ppDst, quotient);
00137 (*ppDst)++;
00138 if (multiplier/intbase > number)
00139 for (i = multiplier/intbase; i > number; i /= intbase)
00140 *(*ppDst)++ = '0';
00141 }
00142 multiplier /= intbase;
00143 } while (multiplier > 0);
00144 }
00145
00146 return;
00147 }
00148 #endif
00149
00150 #ifdef INT2STRINGPADDED
00151
00160
00161 void int2stringpadded(char **ppDst, sshort number, uchar intbase, uchar padsize,
00162 bool numgroup, bool plussign)
00163
00164
00165 {
00186 ushort multiplier, i;
00187 uchar quotient, groupsize;
00188 uchar ndigit = (uchar)0;
00189
00190
00191 switch (intbase) {
00192 case 10:
00193 groupsize = 3;
00194 multiplier = 10000;
00195 break;
00196 case 0x10:
00197 groupsize = 4;
00198 multiplier = 0x1000;
00199 break;
00200 default:
00201 groupsize = 4;
00202 multiplier = 0x8000;
00203 break;
00204 }
00205 if (!numgroup) {
00206 groupsize = 127;
00207 }
00208
00209 if (0 > number) {
00210
00211 *(*ppDst)++ = '-';
00212 number *= -1;
00213 } else if (0 == number) {
00214 if (0 != padsize) padsize--;
00215 *(*ppDst)++ = '0';
00216 } else if (plussign) {
00217 *(*ppDst)++ = '+';
00218 }
00219
00220 for (i = number; 0 < i; i /= intbase) {
00221 ndigit++;
00222 }
00223
00224 for (i = padsize; i > ndigit; i--) {
00225 *(*ppDst)++ = '0';
00226 if ((0 == ((i - 1) % (groupsize))) && (1 != i)) {
00227 *(*ppDst)++ = ',';
00228 }
00229 }
00230
00231 do {
00232 if (number >= multiplier) {
00233 quotient = number/multiplier;
00234 number -= quotient*multiplier;
00235 digit2char(**ppDst, quotient);
00236 (*ppDst)++;
00237 ndigit--;
00238 if ((0 == (ndigit % groupsize)) && (0 != ndigit)) {
00239 *(*ppDst)++ = ',';
00240 }
00241 if (multiplier/intbase > number) {
00242 for (i = multiplier/intbase; i > number; i /= intbase) {
00243 *(*ppDst)++ = '0';
00244 ndigit--;
00245 if ((0 == (ndigit % groupsize)) && (0 != ndigit)) {
00246 *(*ppDst)++ = ',';
00247 }
00248
00249 }
00250 }
00251 }
00252 multiplier /= intbase;
00253 } while (multiplier > 0);
00254
00255 return;
00256 }
00257
00258 #endif
00259
00268 void bvsnprintf(char *pDst, ushort maxn, const char *pSrc, va_list ap)
00269
00270 {
00279 char *pString = NULL;
00280 ushort ncopied = 0;
00281 sshort intvar = 0;
00282 uchar intbase = 0;
00283 uchar padzeroes = 0;
00284 bool plussign = false, numgroup = false;
00285 bool foundvar = false;
00286
00287 #ifdef BPRINTF_DEBUG
00288 printf("bprintf(): pDst(%p), maxn(%i), pSrc = \"%s\"\n", pDst, maxn, pSrc);
00289 #endif
00290 do {
00291 if (*pSrc == '%') {
00292 foundvar = true;
00293 }
00294 if (foundvar) {
00295 switch (*(++pSrc)) {
00296 case '%':
00297 *pDst++ = *pSrc++;
00298 ncopied++;
00299 foundvar = false;
00300 break;
00301 case 'i':
00302 intbase = 10;
00303 break;
00304 case 'X':
00305 case 'x':
00306 case 'p':
00307 intbase = 0x10;
00308 break;
00309 case 'o':
00310 intbase = 010;
00311 break;
00312 case 'B':
00313 intbase = 2;
00314 break;
00315 case 'c':
00316 *pDst++ = (char) va_arg(ap, int);
00317 ncopied++;
00318 break;
00319 case 's':
00320 pString = va_arg(ap, char *);
00321 ncopied += bstrncpy(pDst, pString, maxn - ncopied);
00322 break;
00323 case '0':
00324 padzeroes = *(pSrc + 1) - '0';
00325 break;
00326 case '+':
00327 plussign = true;
00328 break;
00329 case '\'':
00330 numgroup = true;
00331 break;
00332 default:
00333 break;
00334 }
00335 if (0 < intbase) {
00336 intvar = (sshort) (va_arg(ap, int));
00337 pString = pDst;
00338
00339 #ifdef INT2STRINGPADDED
00340 int2stringpadded(&pDst, intvar, intbase, padzeroes, numgroup, plussign);
00341 #else
00342 #ifdef INT2STRING
00343 int2string(&pDst, intvar, intbase);
00344 #endif
00345 #endif
00346
00347 pSrc++;
00348 ncopied += pDst - pString;
00349 intbase = 0;
00350 foundvar = false;
00351 }
00352 } else {
00353 *(pDst++) = *pSrc;
00354 if ('\0' != *pSrc) pSrc++;
00355 ncopied++;
00356 }
00357 } while ( ((ushort)ncopied < maxn) && ('\0' != *(pSrc)) );
00358
00359 *pDst = '\0';
00360
00361
00362 return;
00363 }
00364
00365
00374 void bsnprintf(char *pDst, ushort maxn, const char *pSrc, ...)
00375 {
00377 va_list ap;
00378
00379 va_start(ap, pSrc);
00380 bvsnprintf(pDst, maxn, pSrc, ap);
00381 va_end(ap);
00382
00383 return;
00384 }
00385
00400 void bprintf(ushort extra, const char *pString, ...)
00401 {
00408 char pWorking[80];
00409 va_list ap;
00410
00411 va_start(ap, pString);
00412 bvsnprintf(pWorking, 80, pString, ap);
00413 va_end(ap);
00414 bputs(pWorking);
00415
00416 return;
00417 }