ReactOS  0.4.15-dev-439-g292f67a
vfprintf.c File Reference
#include <stdio.h>
#include <stdarg.h>
Include dependency graph for vfprintf.c:

Go to the source code of this file.

Functions

int __cdecl streamout (FILE *stream, const char *format, va_list argptr)
 
int __cdecl vfprintf (FILE *file, const char *format, va_list argptr)
 

Function Documentation

◆ streamout()

int __cdecl streamout ( FILE stream,
const char format,
va_list  argptr 
)

Definition at line 326 of file streamout.c.

327 {
328  static const TCHAR digits_l[] = _T("0123456789abcdef0x");
329  static const TCHAR digits_u[] = _T("0123456789ABCDEF0X");
330  static const char *_nullstring = "(null)";
331  TCHAR buffer[BUFFER_SIZE + 1];
332  TCHAR chr, *string;
333  STRING *nt_string;
334  const TCHAR *digits, *prefix;
335  int base, fieldwidth, precision, padding;
336  size_t prefixlen, len;
337  int written = 1, written_all = 0;
338  unsigned int flags;
339  unsigned __int64 val64;
340 
341  buffer[BUFFER_SIZE] = '\0';
342 
343  while (written >= 0)
344  {
345  chr = *format++;
346 
347  /* Check for end of format string */
348  if (chr == _T('\0')) break;
349 
350  /* Check for 'normal' character or double % */
351  if ((chr != _T('%')) ||
352  (chr = *format++) == _T('%'))
353  {
354  /* Write the character to the stream */
355  if ((written = streamout_char(stream, chr)) == 0) return -1;
356  written_all += written;
357  continue;
358  }
359 
360  /* Handle flags */
361  flags = 0;
362  while (1)
363  {
364  if (chr == _T('-')) flags |= FLAG_ALIGN_LEFT;
365  else if (chr == _T('+')) flags |= FLAG_FORCE_SIGN;
366  else if (chr == _T(' ')) flags |= FLAG_FORCE_SIGNSP;
367  else if (chr == _T('0')) flags |= FLAG_PAD_ZERO;
368  else if (chr == _T('#')) flags |= FLAG_SPECIAL;
369  else break;
370  chr = *format++;
371  }
372 
373  /* Handle field width modifier */
374  if (chr == _T('*'))
375  {
376 #ifdef _USER32_WSPRINTF
377  if ((written = streamout_char(stream, chr)) == 0) return -1;
378  written_all += written;
379  continue;
380 #else
381  fieldwidth = va_arg(argptr, int);
382  if (fieldwidth < 0)
383  {
385  fieldwidth = -fieldwidth;
386  }
387  chr = *format++;
388 #endif
389  }
390  else
391  {
392  fieldwidth = 0;
393  while (chr >= _T('0') && chr <= _T('9'))
394  {
395  fieldwidth = fieldwidth * 10 + (chr - _T('0'));
396  chr = *format++;
397  }
398  }
399 
400  /* Handle precision modifier */
401  if (chr == '.')
402  {
403  chr = *format++;
404 
405  if (chr == _T('*'))
406  {
407 #ifdef _USER32_WSPRINTF
408  if ((written = streamout_char(stream, chr)) == 0) return -1;
409  written_all += written;
410  continue;
411 #else
412  precision = va_arg(argptr, int);
413  chr = *format++;
414 #endif
415  }
416  else
417  {
418  precision = 0;
419  while (chr >= _T('0') && chr <= _T('9'))
420  {
421  precision = precision * 10 + (chr - _T('0'));
422  chr = *format++;
423  }
424  }
425  }
426  else precision = -1;
427 
428  /* Handle argument size prefix */
429  do
430  {
431  if (chr == _T('h')) flags |= FLAG_SHORT;
432  else if (chr == _T('w')) flags |= FLAG_WIDECHAR;
433  else if (chr == _T('L')) flags |= 0; // FIXME: long double
434  else if (chr == _T('F')) flags |= 0; // FIXME: what is that?
435  else if (chr == _T('l'))
436  {
437  /* Check if this is the 2nd 'l' in a row */
438  if (format[-2] == 'l') flags |= FLAG_INT64;
439  else flags |= FLAG_LONG;
440  }
441  else if (chr == _T('I'))
442  {
443  if (format[0] == _T('3') && format[1] == _T('2'))
444  {
445  format += 2;
446  }
447  else if (format[0] == _T('6') && format[1] == _T('4'))
448  {
449  format += 2;
450  flags |= FLAG_INT64;
451  }
452  else if (format[0] == _T('x') || format[0] == _T('X') ||
453  format[0] == _T('d') || format[0] == _T('i') ||
454  format[0] == _T('u') || format[0] == _T('o'))
455  {
456  flags |= FLAG_INTPTR;
457  }
458  else break;
459  }
460  else break;
461  chr = *format++;
462  }
463  while (USE_MULTISIZE);
464 
465  /* Handle the format specifier */
466  digits = digits_l;
467  string = &buffer[BUFFER_SIZE];
468  base = 10;
469  prefix = 0;
470  switch (chr)
471  {
472  case _T('n'):
473  if (flags & FLAG_INT64)
474  *va_arg(argptr, __int64*) = written_all;
475  else if (flags & FLAG_SHORT)
476  *va_arg(argptr, short*) = written_all;
477  else
478  *va_arg(argptr, int*) = written_all;
479  continue;
480 
481  case _T('C'):
482 #ifndef _UNICODE
484 #endif
485  goto case_char;
486 
487  case _T('c'):
488 #ifdef _UNICODE
490 #endif
491  case_char:
492  string = buffer;
493  len = 1;
494  if (flags & FLAG_WIDECHAR)
495  {
496  ((wchar_t*)string)[0] = va_arg(argptr, int);
497  ((wchar_t*)string)[1] = _T('\0');
498  }
499  else
500  {
501  ((char*)string)[0] = va_arg(argptr, int);
502  ((char*)string)[1] = _T('\0');
503  }
504  break;
505 
506  case _T('Z'):
507  nt_string = va_arg(argptr, void*);
508  if (nt_string && (string = nt_string->Buffer))
509  {
510  len = nt_string->Length;
511  if (flags & FLAG_WIDECHAR) len /= sizeof(wchar_t);
512  break;
513  }
514  string = 0;
515  goto case_string;
516 
517  case _T('S'):
518  string = va_arg(argptr, void*);
519 #ifndef _UNICODE
520  if (!(flags & FLAG_SHORT)) flags |= FLAG_WIDECHAR;
521 #endif
522  goto case_string;
523 
524  case _T('s'):
525  string = va_arg(argptr, void*);
526 #ifdef _UNICODE
527  if (!(flags & FLAG_SHORT)) flags |= FLAG_WIDECHAR;
528 #endif
529 
530  case_string:
531  if (!string)
532  {
533  string = (TCHAR*)_nullstring;
534  flags &= ~FLAG_WIDECHAR;
535  }
536 
537  if (flags & FLAG_WIDECHAR)
538  len = wcsnlen((wchar_t*)string, (unsigned)precision);
539  else
540  len = strnlen((char*)string, (unsigned)precision);
541  precision = 0;
542  break;
543 
544 #ifndef _USER32_WSPRINTF
545  case _T('G'):
546  case _T('E'):
547  case _T('A'):
548  case _T('g'):
549  case _T('e'):
550  case _T('a'):
551  case _T('f'):
552 #ifdef _UNICODE
553  flags |= FLAG_WIDECHAR;
554 #else
555  flags &= ~FLAG_WIDECHAR;
556 #endif
557  /* Use external function, one for kernel one for user mode */
558  format_float(chr, flags, precision, &string, &prefix, &argptr);
559  len = _tcslen(string);
560  precision = 0;
561  break;
562 #endif
563 
564  case _T('d'):
565  case _T('i'):
566  val64 = (__int64)va_arg_f(argptr, flags);
567 
568  if ((__int64)val64 < 0)
569  {
570  val64 = -(__int64)val64;
571  prefix = _T("-");
572  }
573  else if (flags & FLAG_FORCE_SIGN)
574  prefix = _T("+");
575  else if (flags & FLAG_FORCE_SIGNSP)
576  prefix = _T(" ");
577 
578  goto case_number;
579 
580  case _T('o'):
581  base = 8;
582  if (flags & FLAG_SPECIAL)
583  {
584  prefix = _T("0");
585  if (precision > 0) precision--;
586  }
587  goto case_unsigned;
588 
589  case _T('p'):
590  precision = 2 * sizeof(void*);
591  flags &= ~FLAG_PAD_ZERO;
592  flags |= FLAG_INTPTR;
593  /* Fall through */
594 
595  case _T('X'):
596  digits = digits_u;
597  /* Fall through */
598 
599  case _T('x'):
600  base = 16;
601  if (flags & FLAG_SPECIAL)
602  {
603  prefix = &digits[16];
604 #ifdef _USER32_WSPRINTF
605  fieldwidth += 2;
606 #endif
607  }
608 
609  case _T('u'):
610  case_unsigned:
611  val64 = va_arg_fu(argptr, flags);
612 
613  case_number:
614 #ifdef _UNICODE
615  flags |= FLAG_WIDECHAR;
616 #else
617  flags &= ~FLAG_WIDECHAR;
618 #endif
619  if (precision < 0) precision = 1;
620 
621  /* Gather digits in reverse order */
622  while (val64)
623  {
624  *--string = digits[val64 % base];
625  val64 /= base;
626  precision--;
627  }
628 
629  len = _tcslen(string);
630  break;
631 
632  default:
633  /* Treat anything else as a new character */
634  format--;
635  continue;
636  }
637 
638  /* Calculate padding */
639  prefixlen = prefix ? _tcslen(prefix) : 0;
640  if (precision < 0) precision = 0;
641  padding = (int)(fieldwidth - len - prefixlen - precision);
642  if (padding < 0) padding = 0;
643 
644  /* Optional left space padding */
645  if ((flags & (FLAG_ALIGN_LEFT | FLAG_PAD_ZERO)) == 0)
646  {
647  for (; padding > 0; padding--)
648  {
649  if ((written = streamout_char(stream, _T(' '))) == 0) return -1;
650  written_all += written;
651  }
652  }
653 
654  /* Optional prefix */
655  if (prefix)
656  {
657  written = streamout_string(stream, prefix, prefixlen);
658  if (written == -1) return -1;
659  written_all += written;
660  }
661 
662  /* Optional left '0' padding */
663  if ((flags & FLAG_ALIGN_LEFT) == 0) precision += padding;
664  while (precision-- > 0)
665  {
666  if ((written = streamout_char(stream, _T('0'))) == 0) return -1;
667  written_all += written;
668  }
669 
670  /* Output the string */
671  if (flags & FLAG_WIDECHAR)
672  written = streamout_wstring(stream, (wchar_t*)string, len);
673  else
674  written = streamout_astring(stream, (char*)string, len);
675  if (written == -1) return -1;
676  written_all += written;
677 
678 #if 0 && SUPPORT_FLOAT
679  /* Optional right '0' padding */
680  while (precision-- > 0)
681  {
682  if ((written = streamout_char(stream, _T('0'))) == 0) return -1;
683  written_all += written;
684  len++;
685  }
686 #endif
687 
688  /* Optional right padding */
689  if (flags & FLAG_ALIGN_LEFT)
690  {
691  while (padding-- > 0)
692  {
693  if ((written = streamout_char(stream, _T(' '))) == 0) return -1;
694  written_all += written;
695  }
696  }
697 
698  }
699 
700  if (written == -1) return -1;
701 
702  return written_all;
703 }
#define va_arg_fu(argptr, flags)
Definition: streamout.c:62
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
void format_float(TCHAR chr, unsigned int flags, int precision, TCHAR **string, const TCHAR **prefix, va_list *argptr)
Definition: streamout.c:82
GLuint buffer
Definition: glext.h:5915
#define USE_MULTISIZE
Definition: streamout.c:321
#define va_arg_f(argptr, flags)
Definition: streamout.c:57
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLuint base
Definition: 3dtext.c:35
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
GLenum GLint GLint * precision
Definition: glext.h:7539
char TCHAR
Definition: xmlstorage.h:189
#define streamout_string
Definition: streamout.c:315
static int streamout_wstring(FILE *stream, const wchar_t *string, size_t count)
Definition: streamout.c:280
#define _T(x)
Definition: vfdio.h:22
unsigned int padding
Definition: isohybrid.c:50
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define BUFFER_SIZE
Definition: streamout.c:23
GLbitfield flags
Definition: glext.h:7161
std::wstring STRING
Definition: fontsub.cpp:33
Definition: parse.h:22
GLenum GLsizei len
Definition: glext.h:6722
static int streamout_astring(FILE *stream, const char *string, size_t count)
Definition: streamout.c:252
int chr(char *serport)
Definition: gdblib.c:152
char string[160]
Definition: util.h:11
#define va_arg(ap, T)
Definition: acmsvcex.h:89
static int streamout_char(FILE *stream, int chr)
Definition: streamout.c:229
#define wchar_t
Definition: wchar.h:102
#define _UNICODE
Definition: audio_test.c:1
static const int digits[]
Definition: decode.c:71
#define __int64
Definition: basetyps.h:16
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

Referenced by vfprintf().

◆ vfprintf()

int __cdecl vfprintf ( FILE file,
const char format,
va_list  argptr 
)

Definition at line 16 of file vfprintf.c.

17 {
18  int result;
19 
21  result = streamout(file, format, argptr);
23 
24  return result;
25 }
int __cdecl streamout(FILE *stream, const char *format, va_list argptr)
Definition: streamout.c:326
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
_CRTIMP void __cdecl _lock_file(_Inout_ FILE *_File)
_CRTIMP void __cdecl _unlock_file(_Inout_ FILE *_File)
GLuint64EXT * result
Definition: glext.h:11304
Definition: fci.c:126