Ejemplo n.º 1
0
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? */
}
Ejemplo n.º 2
0
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;
}