Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
4.4 KiB

  1. /***
  2. *fgetwc.c - get a wide character from a stream
  3. *
  4. * Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines fgetwc() - read a wide character from a stream
  8. *
  9. *Revision History:
  10. * 04-26-93 CFW Module created.
  11. * 04-30-93 CFW Bring wide char support from fgetc.c.
  12. * 05-03-93 CFW Add getwc function.
  13. * 05-10-93 CFW Optimize, fix error handling.
  14. * 06-02-93 CFW Wide get/put use wint_t.
  15. * 09-14-93 CFW Fix EOF cast bug.
  16. * 09-15-93 CFW Use ANSI conformant "__" names.
  17. * 10-01-93 CFW Test only for TEXT.
  18. * 10-22-93 CFW Test for invalid MB chars using global preset flag.
  19. * 10-28-93 CFW Test for both IOSTRG and TEXT.
  20. * 02-07-94 CFW POSIXify.
  21. * 08-31-94 CFW Fix for "C" locale, call mbtowc().
  22. * 09-06-94 CFW Replace MTHREAD with _MT.
  23. * 02-06-94 CFW assert -> _ASSERTE.
  24. * 03-07-95 GJF _[un]lock_str macros now take FILE * arg.
  25. * 06-12-95 GJF Replaced _osfile[] with _osfile() (macro referencing
  26. * field in ioinfo struct).
  27. * 07-28-95 GJF Replaced _osfile() with _osfile_safe().
  28. * 04-18-97 JWM Explicit cast added to avoid new C4242 warnings.
  29. * 02-27-98 GJF Exception-safe locking.
  30. *
  31. *******************************************************************************/
  32. #ifndef _POSIX_
  33. #include <cruntime.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <dbgint.h>
  37. #include <file2.h>
  38. #include <internal.h>
  39. #include <mtdll.h>
  40. #include <msdos.h>
  41. #include <errno.h>
  42. #include <wchar.h>
  43. #include <tchar.h>
  44. #include <setlocal.h>
  45. #ifdef _MT /* multi-thread; define both fgetwc and _getwc_lk */
  46. /***
  47. *wint_t fgetwc(stream) - read a wide character from a stream
  48. *
  49. *Purpose:
  50. * reads a wide character from the given stream
  51. *
  52. *Entry:
  53. * FILE *stream - stream to read wide character from
  54. *
  55. *Exit:
  56. * returns the wide character read
  57. * returns WEOF if at end of file or error occurred
  58. *
  59. *Exceptions:
  60. *
  61. *******************************************************************************/
  62. wint_t __cdecl fgetwc (
  63. REG1 FILE *stream
  64. )
  65. {
  66. wint_t retval;
  67. _ASSERTE(stream != NULL);
  68. #ifdef _MT
  69. _lock_str(stream);
  70. __try {
  71. #endif
  72. retval = _getwc_lk(stream);
  73. #ifdef _MT
  74. }
  75. __finally {
  76. _unlock_str(stream);
  77. }
  78. #endif
  79. return(retval);
  80. }
  81. /***
  82. *_getwc_lk() - getwc() core routine (locked version)
  83. *
  84. *Purpose:
  85. * Core getwc() routine; assumes stream is already locked.
  86. *
  87. * [See getwc() above for more info.]
  88. *
  89. *Entry: [See getwc()]
  90. *
  91. *Exit: [See getwc()]
  92. *
  93. *Exceptions:
  94. *
  95. *******************************************************************************/
  96. wint_t __cdecl _getwc_lk (
  97. REG1 FILE *stream
  98. )
  99. {
  100. #else /* non multi-thread; just define fgetwc */
  101. wint_t __cdecl fgetwc (
  102. REG1 FILE *stream
  103. )
  104. {
  105. #endif /* rejoin common code */
  106. #ifndef _NTSUBSET_
  107. if (!(stream->_flag & _IOSTRG) && (_osfile_safe(_fileno(stream)) &
  108. FTEXT))
  109. {
  110. int size = 1;
  111. int ch;
  112. char mbc[4];
  113. wchar_t wch;
  114. /* text (multi-byte) mode */
  115. if ((ch = _getc_lk(stream)) == EOF)
  116. return WEOF;
  117. mbc[0] = (char)ch;
  118. if (isleadbyte((unsigned char)mbc[0]))
  119. {
  120. if ((ch = _getc_lk(stream)) == EOF)
  121. {
  122. ungetc(mbc[0], stream);
  123. return WEOF;
  124. }
  125. mbc[1] = (char)ch;
  126. size = 2;
  127. }
  128. if (mbtowc(&wch, mbc, size) == -1)
  129. {
  130. /*
  131. * Conversion failed! Set errno and return
  132. * failure.
  133. */
  134. errno = EILSEQ;
  135. return WEOF;
  136. }
  137. return wch;
  138. }
  139. #endif
  140. /* binary (Unicode) mode */
  141. if ((stream->_cnt -= sizeof(wchar_t)) >= 0)
  142. return *((wchar_t *)(stream->_ptr))++;
  143. else
  144. return (wint_t) _filwbuf(stream);
  145. }
  146. #undef getwc
  147. wint_t __cdecl getwc (
  148. FILE *stream
  149. )
  150. {
  151. return fgetwc(stream);
  152. }
  153. #endif /* _POSIX_ */