fgetc.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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_internal(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. strong_alias(__fgetc_unlocked_internal,__fgetc_unlocked)
  61. weak_alias(__fgetc_unlocked_internal,fgetc_unlocked)
  62. weak_alias(__fgetc_unlocked_internal,getc_unlocked)
  63. #ifndef __UCLIBC_HAS_THREADS__
  64. weak_alias(__fgetc_unlocked_internal,fgetc)
  65. weak_alias(__fgetc_unlocked_internal,getc)
  66. #endif
  67. #elif defined __UCLIBC_HAS_THREADS__
  68. int fgetc(register FILE *stream)
  69. {
  70. if (stream->__user_locking != 0) {
  71. return __GETC_UNLOCKED_MACRO(stream);
  72. } else {
  73. int retval;
  74. __STDIO_ALWAYS_THREADLOCK(stream);
  75. retval = __GETC_UNLOCKED_MACRO(stream);
  76. __STDIO_ALWAYS_THREADUNLOCK(stream);
  77. return retval;
  78. }
  79. }
  80. weak_alias(fgetc,getc);
  81. #endif