fgetc.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
  2. *
  3. * GNU Library General Public License (LGPL) version 2 or later.
  4. *
  5. * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
  6. */
  7. #include "_stdio.h"
  8. #undef fgetc
  9. #undef fgetc_unlocked
  10. #undef getc
  11. #undef getc_unlocked
  12. #ifdef __DO_UNLOCKED
  13. int attribute_hidden __fgetc_unlocked(FILE *stream)
  14. {
  15. __STDIO_STREAM_VALIDATE(stream);
  16. /* First the fast path. We're good to go if getc macro enabled. */
  17. if (__STDIO_STREAM_CAN_USE_BUFFER_GET(stream)) {
  18. return __STDIO_STREAM_BUFFER_GET(stream);
  19. }
  20. /* Next quickest... reading and narrow oriented, but macro
  21. * disabled and/or buffer is exhausted. */
  22. if (__STDIO_STREAM_IS_NARROW_READING(stream)
  23. || !__STDIO_STREAM_TRANS_TO_READ(stream, __FLAG_NARROW)
  24. ) {
  25. if (stream->__modeflags & __FLAG_UNGOT) { /* Use ungots first. */
  26. unsigned char uc = stream->__ungot[(stream->__modeflags--) & 1];
  27. stream->__ungot[1] = 0;
  28. __STDIO_STREAM_VALIDATE(stream);
  29. return uc;
  30. }
  31. if (__STDIO_STREAM_BUFFER_RAVAIL(stream)) { /* Have buffered? */
  32. return __STDIO_STREAM_BUFFER_GET(stream);
  33. }
  34. /* Is this a fake stream for *sscanf? */
  35. if (__STDIO_STREAM_IS_FAKE_VSSCANF(stream)) {
  36. __STDIO_STREAM_SET_EOF(stream);
  37. return EOF;
  38. }
  39. /* We need to read from the host environment, so we must
  40. * flush all line buffered streams if the stream is not
  41. * fully buffered. */
  42. if (!__STDIO_STREAM_IS_FBF(stream)) {
  43. __STDIO_FLUSH_LBF_STREAMS;
  44. }
  45. if (__STDIO_STREAM_BUFFER_SIZE(stream)) { /* Do we have a buffer? */
  46. __STDIO_STREAM_DISABLE_GETC(stream);
  47. if(__STDIO_FILL_READ_BUFFER(stream)) { /* Refill succeeded? */
  48. __STDIO_STREAM_ENABLE_GETC(stream); /* FBF or LBF */
  49. return __STDIO_STREAM_BUFFER_GET(stream);
  50. }
  51. } else {
  52. unsigned char uc;
  53. if (__stdio_READ(stream, &uc, 1)) {
  54. return uc;
  55. }
  56. }
  57. }
  58. return EOF;
  59. }
  60. weak_alias(__fgetc_unlocked,fgetc_unlocked);
  61. weak_alias(__fgetc_unlocked,getc_unlocked);
  62. #ifndef __UCLIBC_HAS_THREADS__
  63. weak_alias(__fgetc_unlocked,fgetc);
  64. weak_alias(__fgetc_unlocked,getc);
  65. #endif
  66. #elif defined __UCLIBC_HAS_THREADS__
  67. int fgetc(register FILE *stream)
  68. {
  69. if (stream->__user_locking != 0) {
  70. return __GETC_UNLOCKED_MACRO(stream);
  71. } else {
  72. int retval;
  73. __STDIO_ALWAYS_THREADLOCK(stream);
  74. retval = __GETC_UNLOCKED_MACRO(stream);
  75. __STDIO_ALWAYS_THREADUNLOCK(stream);
  76. return retval;
  77. }
  78. }
  79. weak_alias(fgetc,getc);
  80. #endif