Newer
Older
/****************************************************************************
patacongo
committed
* Name: prejustify
****************************************************************************/
patacongo
committed
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
static void prejustify(FAR struct lib_stream_s *obj, ubyte fmt,
patacongo
committed
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
ubyte flags, int fieldwidth, int numwidth)
{
int i;
switch (fmt)
{
default:
case FMT_RJUST:
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;
}
}
patacongo
committed
/****************************************************************************
patacongo
committed
* Name: postjustify
****************************************************************************/
patacongo
committed
#ifndef CONFIG_NOPRINTF_FIELDWIDTH
static void postjustify(FAR struct lib_stream_s *obj, ubyte fmt,
patacongo
committed
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
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;
}
}
/****************************************************************************
****************************************************************************/
/****************************************************************************
****************************************************************************/
int lib_vsprintf(FAR struct lib_stream_s *obj, const char *src, va_list ap)
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
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
/* 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
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
#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
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
patacongo
committed
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
patacongo
committed
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
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))
{
#ifdef CONFIG_CPP_HAVE_WARNING
# warning "No floating point support"
#endif
patacongo
committed
}