void _stdio_validate_FILE(const FILE *stream) { #ifdef __UCLIBC_HAS_THREADS__ assert(((unsigned int)(stream->__user_locking)) <= 2); #endif #warning Define a constant for minimum possible valid __filedes? assert(stream->__filedes >= -3); if (stream->__filedes < 0) { /* assert((stream->__filedes != -1) */ /* #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ /* || (stream->__cookie == &stream->__filedes) /\* custom *\/ */ /* #endif */ /* ); */ /* assert((stream->__filedes == -1) || __STDIO_STREAM_IS_FBF(stream)); */ assert(!__STDIO_STREAM_IS_FAKE_VSNPRINTF(stream) || __STDIO_STREAM_IS_NARROW(stream)); assert(!__STDIO_STREAM_IS_FAKE_VSSCANF(stream) || __STDIO_STREAM_IS_NARROW(stream)); #ifdef __STDIO_STREAM_IS_FAKE_VSWPRINTF assert(!__STDIO_STREAM_IS_FAKE_VSWPRINTF(stream) || __STDIO_STREAM_IS_WIDE(stream)); #endif #ifdef __STDIO_STREAM_IS_FAKE_VSWSCANF assert(!__STDIO_STREAM_IS_FAKE_VSWSCANF(stream) || __STDIO_STREAM_IS_WIDE(stream)); #endif } #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ if (stream->__cookie != &stream->__filedes) { /* custom */ assert(stream->__filedes == -1); } #endif /* Can not be both narrow and wide oriented at the same time. */ assert(!(__STDIO_STREAM_IS_NARROW(stream) && __STDIO_STREAM_IS_WIDE(stream))); /* The following impossible case is used to disable a stream. */ if ((stream->__modeflags & (__FLAG_READONLY|__FLAG_WRITEONLY)) == (__FLAG_READONLY|__FLAG_WRITEONLY) ) { assert(stream->__modeflags == (__FLAG_READONLY|__FLAG_WRITEONLY)); assert(stream->__filedes == -1); #ifdef __STDIO_BUFFERS assert(stream->__bufpos == stream->__bufstart); assert(stream->__bufread == stream->__bufstart); # ifdef __UCLIBC_HAS_STDIO_PUTC_MACRO__ assert(stream->__bufputc_u == stream->__bufstart); # endif # ifdef __UCLIBC_HAS_STDIO_GETC_MACRO__ assert(stream->__bufgetc_u == stream->__bufstart); # endif #endif } if (__STDIO_STREAM_IS_READONLY(stream)) { /* assert(!__STDIO_STREAM_IS_WRITEONLY(stream)); */ assert(!__STDIO_STREAM_IS_WRITING(stream)); if (stream->__modeflags & __FLAG_UNGOT) { assert(((unsigned)(stream->__ungot[1])) <= 1); assert(!__FEOF_UNLOCKED(stream)); } } if (__STDIO_STREAM_IS_WRITEONLY(stream)) { /* assert(!__STDIO_STREAM_IS_READONLY(stream)); */ assert(!__STDIO_STREAM_IS_READING(stream)); assert(!(stream->__modeflags & __FLAG_UNGOT)); } if (__STDIO_STREAM_IS_NBF(stream)) { /* We require that all non buffered streams have no buffer. */ assert(!__STDIO_STREAM_BUFFER_SIZE(stream)); } assert((stream->__modeflags & __MASK_BUFMODE) <= __FLAG_NBF); #ifdef __STDIO_BUFFERS /* Ensure __bufstart <= __bufpos <= __bufend. */ assert(stream->__bufpos >= stream->__bufstart); assert(stream->__bufpos <= stream->__bufend); /* Ensure __bufstart <= __bufread <= __bufend. */ assert(stream->__bufread >= stream->__bufstart); assert(stream->__bufread <= stream->__bufend); #endif /* If EOF, then we must have no buffered readable or ungots. */ if (__FEOF_UNLOCKED(stream)) { #ifdef __STDIO_BUFFERS assert(stream->__bufpos == stream->__bufread); #endif assert(!(stream->__modeflags & __FLAG_UNGOT)); } if (!__STDIO_STREAM_IS_WRITING(stream)) { #ifdef __STDIO_BUFFERS /* If not writing, then putc macro must be disabled. */ # ifdef __UCLIBC_HAS_STDIO_PUTC_MACRO__ assert(stream->__bufputc_u == stream->__bufstart); # endif #endif } if (!__STDIO_STREAM_IS_READING(stream)) { /* If not reading, then can not have ungots. */ assert(!(stream->__modeflags & __FLAG_UNGOT)); #ifdef __STDIO_BUFFERS /* Ensure __bufread == __bufstart. */ assert(stream->__bufread == stream->__bufstart); /* If not reading, then getc macro must be disabled. */ # ifdef __UCLIBC_HAS_STDIO_GETC_MACRO__ assert(stream->__bufgetc_u == stream->__bufstart); # endif #endif } if (__STDIO_STREAM_IS_READING(stream)) { assert(!__STDIO_STREAM_IS_WRITING(stream)); #ifdef __STDIO_BUFFERS /* Ensure __bufpos <= __bufread. */ assert(stream->__bufpos <= stream->__bufread); /* Ensure __bufgetc_u is valid. */ # ifdef __UCLIBC_HAS_STDIO_GETC_MACRO__ assert(stream->__bufgetc_u >= stream->__bufstart); assert(stream->__bufgetc_u <= stream->__bufread); # endif #endif } if (__STDIO_STREAM_IS_WRITING(stream)) { assert(!__STDIO_STREAM_IS_READING(stream)); #ifdef __STDIO_BUFFERS # ifdef __UCLIBC_HAS_STDIO_PUTC_MACRO__ assert(stream->__bufputc_u >= stream->__bufstart); assert(stream->__bufputc_u <= stream->__bufend); # endif #endif } /* If have an ungotten char, then getc (and putc) must be disabled. */ /* Also, wide streams must have the getc/putc macros disabled. */ if ((stream->__modeflags & __FLAG_UNGOT) || __STDIO_STREAM_IS_WIDE(stream) ) { #ifdef __STDIO_BUFFERS # ifdef __UCLIBC_HAS_STDIO_PUTC_MACRO__ assert(stream->__bufputc_u == stream->__bufstart); # endif # ifdef __UCLIBC_HAS_STDIO_GETC_MACRO__ assert(stream->__bufgetc_u == stream->__bufstart); # endif #endif } /* TODO -- filepos? ungot_width? filedes? nextopen? */ }
int __fputc_unlocked(int c, register FILE *stream) { __STDIO_STREAM_VALIDATE(stream); /* First the fast path. We're good to go if putc macro enabled. */ if (__STDIO_STREAM_CAN_USE_BUFFER_ADD(stream)) { __STDIO_STREAM_BUFFER_ADD(stream, ((unsigned char) c)); return (unsigned char) c; } /* Next quickest... writing and narrow oriented, but macro * disabled and/or buffer is full. */ if (__STDIO_STREAM_IS_NARROW_WRITING(stream) || !__STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_NARROW) ) { if (__STDIO_STREAM_IS_FAKE_VSNPRINTF(stream)) { return (unsigned char) c; } if (__STDIO_STREAM_BUFFER_SIZE(stream)) { /* Do we have a buffer? */ /* The buffer is full and/or the stream is line buffered. */ if (!__STDIO_STREAM_BUFFER_WAVAIL(stream) /* Buffer full? */ && __STDIO_COMMIT_WRITE_BUFFER(stream) /* Commit failed! */ ) { goto BAD; } #ifdef __UCLIBC_MJN3_ONLY__ #warning CONSIDER: Should we fail if the commit fails but we now have room? #endif __STDIO_STREAM_BUFFER_ADD(stream, ((unsigned char) c)); if (IS_STD_STREAM(stream)) { if( __STDIO_COMMIT_WRITE_BUFFER(stream)) { /* Commit failed! */ __STDIO_STREAM_BUFFER_UNADD(stream); /* Undo the write! */ goto BAD; } } else if (__STDIO_STREAM_IS_LBF(stream)) { if ((((unsigned char) c) == '\n') && __STDIO_COMMIT_WRITE_BUFFER(stream)) { /* Commit failed! */ __STDIO_STREAM_BUFFER_UNADD(stream); /* Undo the write! */ goto BAD; } } } else { /* NOTE: Do not try to save space by moving uc to the top of * the file, as that dramaticly increases runtime. */ unsigned char uc = (unsigned char) c; if (! __stdio_WRITE(stream, &uc, 1)) { goto BAD; } } return (unsigned char) c; } BAD: return EOF; }