Newer
Older
patacongo
committed
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
if (IS_SIGNED(flags))
{
numwidth++;
}
for (i = fieldwidth - numwidth; i > 0; i--)
{
obj->put(obj, ' ');
}
if (IS_NEGATE(flags))
{
obj->put(obj, '-');
}
else if (IS_SHOWPLUS(flags))
{
obj->put(obj, '+');
}
break;
case FMT_RJUST0:
if (IS_NEGATE(flags))
{
obj->put(obj, '-');
numwidth++;
}
else if (IS_SHOWPLUS(flags))
{
obj->put(obj, '+');
numwidth++;
}
for (i = fieldwidth - numwidth; i > 0; i--)
{
obj->put(obj, '0');
}
break;
case FMT_LJUST:
if (IS_NEGATE(flags))
{
obj->put(obj, '-');
}
else if (IS_SHOWPLUS(flags))
{
obj->put(obj, '+');
}
break;
}
}
/************************************************************
* Name: postjustify
************************************************************/
static void postjustify(struct lib_stream_s *obj, ubyte fmt,
ubyte flags, int fieldwidth, int numwidth)
{
int i;
/* Apply field justification to the integer value. */
switch (fmt)
{
default:
case FMT_RJUST:
case FMT_RJUST0:
break;
case FMT_LJUST:
if (IS_SIGNED(flags))
{
numwidth++;
}
for (i = fieldwidth - numwidth; i > 0; i--)
{
obj->put(obj, ' ');
}
break;
}
}
/************************************************************
* Public Functions
************************************************************/
/************************************************************
* lib_vsprintf
************************************************************/
int lib_vsprintf(struct lib_stream_s *obj, const char *src, va_list ap)
{
char *ptmp;
patacongo
committed
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
int width;
int trunc;
ubyte fmt;
#endif
ubyte flags;
for (; *src; src++)
{
/* Just copy regular characters */
if (*src != '%')
{
obj->put(obj, *src);
patacongo
committed
continue;
patacongo
committed
/* We have found a format specifier. Move past it. */
src++;
/* Assume defaults */
flags = 0;
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
fmt = FMT_RJUST;
width = 0;
trunc = 0;
#endif
/* Process each format qualifier. */
for (; *src; src++)
patacongo
committed
/* Break out of the loop when the format is known. */
patacongo
committed
if (strchr("diuxXpobeEfgGlLsc%", *src))
{
break;
}
patacongo
committed
/* Check for left justification. */
patacongo
committed
else if (*src == '-')
{
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
fmt = FMT_LJUST;
#endif
}
/* Check for leading zero fill right justification. */
else if (*src == '0')
{
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
fmt = FMT_RJUST0;
#endif
}
#if 0
/* Center justification. */
patacongo
committed
else if (*src == '~')
patacongo
committed
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
fmt = FMT_CENTER;
#endif
}
#endif
patacongo
committed
else if (*src == '*')
{
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
int value = va_arg(ap, int);
if (IS_HASDOT(flags))
patacongo
committed
trunc = value;
SET_HASASTERISKTRUNC(flags);
patacongo
committed
else
patacongo
committed
width = value;
SET_HASASTERISKWIDTH(flags);
patacongo
committed
#endif
}
patacongo
committed
/* Check for field width */
patacongo
committed
else if (*src >= '1' && *src <= '9')
{
#ifdef CONFIG_NOPRINTF_FIELDWIDTH
for (src++; (*src >= '0' && *src <= '9'); src++);
#else
/* Accumulate the field width integer. */
int n = ((int)(*src)) - (int)'0';
for (src++; (*src >= '0' && *src <= '9'); src++)
patacongo
committed
n = 10*n + (((int)(*src)) - (int)'0');
patacongo
committed
if (IS_HASDOT(flags))
patacongo
committed
trunc = n;
patacongo
committed
else
patacongo
committed
width = n;
patacongo
committed
#endif
/* Back up to the last digit. */
patacongo
committed
src--;
}
patacongo
committed
/* Check for a decimal point. */
patacongo
committed
else if (*src == '.')
{
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
SET_HASDOT(flags);
#endif
}
patacongo
committed
/* Check for leading plus sign. */
patacongo
committed
else if (*src == '+')
{
SET_SHOWPLUS(flags);
}
patacongo
committed
/* Check for alternate form. */
patacongo
committed
else if (*src == '#')
{
SET_ALTFORM(flags);
}
}
patacongo
committed
/* "%%" means that a literal '%' was intended (instead of a format
* specification).
*/
patacongo
committed
if (*src == '%')
{
obj->put(obj, '%');
continue;
}
patacongo
committed
/* Check for the string format. */
patacongo
committed
if (*src == 's')
{
/* Just concatenate the string into the output */
patacongo
committed
ptmp = va_arg(ap, char *);
if (!ptmp)
{
ptmp = (char*)g_nullstring;
patacongo
committed
while(*ptmp)
{
obj->put(obj, *ptmp);
ptmp++;
}
continue;
}
patacongo
committed
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
/* Check for the character output */
else if (*src == 'c')
{
/* Just copy the character into the output. */
int n = va_arg(ap, int);
obj->put(obj, n);
continue;
}
/* Check for the long long prefix. */
if (*src == 'L')
{
SET_LONGLONGPRECISION(flags);
++src;
}
else if (*src == 'l')
{
SET_LONGPRECISION(flags);
if (*++src == 'l')
patacongo
committed
SET_LONGLONGPRECISION(flags);
++src;
patacongo
committed
}
patacongo
committed
/* Handle integer conversions */
patacongo
committed
if (strchr("diuxXpob", *src))
{
#ifdef CONFIG_HAVE_LONG_LONG
if (IS_LONGLONGPRECISION(flags) && *src != 'p')
patacongo
committed
long long lln;
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
int lluwidth;
#endif
/* Extract the long long value. */
patacongo
committed
lln = va_arg(ap, long long);
patacongo
committed
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
#ifdef CONFIG_NOPRINTF_FIELDWIDTH
/* Output the number */
llutoascii(obj, *src, flags, (unsigned long long)lln);
#else
/* Resolve sign-ness and format issues */
llfixup(*src, &flags, &lln);
/* Get the width of the output */
lluwidth = getllusize(*src, flags, lln);
/* Perform left field justification actions */
prejustify(obj, fmt, flags, width, lluwidth);
/* Output the number */
llutoascii(obj, *src, flags, (unsigned long long)lln);
/* Perform right field justification actions */
postjustify(obj, fmt, flags, width, lluwidth);
#endif
patacongo
committed
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
else
#endif /* CONFIG_HAVE_LONG_LONG */
#ifdef CONFIG_LONG_IS_NOT_INT
if (IS_LONGPRECISION(flags) && *src != 'p')
{
long ln;
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
int luwidth;
#endif
/* Extract the long long value. */
ln = va_arg(ap, long);
#ifdef CONFIG_NOPRINTF_FIELDWIDTH
/* Output the number */
lutoascii(obj, *src, flags, (unsigned long)ln);
#else
/* Resolve sign-ness and format issues */
lfixup(*src, &flags, &ln);
/* Get the width of the output */
luwidth = getlusize(*src, flags, ln);
/* Perform left field justification actions */
patacongo
committed
prejustify(obj, fmt, flags, width, luwidth);
patacongo
committed
/* Output the number */
lutoascii(obj, *src, flags, (unsigned long)ln);
/* Perform right field justification actions */
postjustify(obj, fmt, flags, width, luwidth);
#endif
}
else
#endif /* CONFIG_LONG_IS_NOT_INT */
#ifdef CONFIG_PTR_IS_NOT_INT
if (*src == 'p')
patacongo
committed
void *p;
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
int pwidth;
#endif
/* Extract the long long value. */
patacongo
committed
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
p = va_arg(ap, void *);
#ifdef CONFIG_NOPRINTF_FIELDWIDTH
/* Output the pointer value */
ptohex(obj, flags, p);
#else
/* Resolve sign-ness and format issues */
lfixup(*src, &flags, &ln);
/* Get the width of the output */
luwidth = getpsize(*src, flags, p);
/* Perform left field justification actions */
prejustify(obj, fmt, flags, width, pwidth);
/* Output the pointer value */
ptohex(obj, flags, p);
/* Perform right field justification actions */
postjustify(obj, fmt, flags, width, pwidth);
#endif
patacongo
committed
#endif
patacongo
committed
int n;
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
int uwidth;
#endif
/* Extract the long long value. */
patacongo
committed
n = va_arg(ap, int);
patacongo
committed
#ifdef CONFIG_NOPRINTF_FIELDWIDTH
/* Output the number */
patacongo
committed
utoascii(obj, *src, flags, (unsigned int)n);
#else
/* Resolve sign-ness and format issues */
patacongo
committed
fixup(*src, &flags, &n);
patacongo
committed
/* Get the width of the output */
patacongo
committed
uwidth = getusize(*src, flags, n);
/* Perform left field justification actions */
prejustify(obj, fmt, flags, width, uwidth);
/* Output the number */
utoascii(obj, *src, flags, (unsigned int)n);
/* Perform right field justification actions */
postjustify(obj, fmt, flags, width, uwidth);
#endif
patacongo
committed
/* Handle floating point conversions */
else if (strchr("eEfgG", *src))
{
#warning "No floating point support"
}