Hatena::Diary

Asia in Water - Tech & Fishing Plus RSSフィード

2010-01-29

C言語素人が読むソースコード #1 printf.c

17:02 | C言語素人が読むソースコード #1 printf.c - Asia in Water - Tech & Fishing Plus を含むブックマーク はてなブックマーク - C言語素人が読むソースコード #1 printf.c - Asia in Water - Tech & Fishing Plus

Netbsd 1.6から拾ってきたコード。

printf.c

#include <varargs.h>

struct __suio uio; /* output information: summary */

int
printf(fmt, va_alist)
{
	int ret;
	va_list ap;

	va_start(ap);
	ret = vfprintf(stdout, fmt, ap);
	va_end(ap);
	return (ret);
}

printfは、ret(vfprintfの返り値)を返却しているだけかな?。

vfprintf.c:vfprintf()

int
vfprintf(fp, fmt0, ap)
{
.
.
	PRINT(cp, size);
	FLUSH();	/* copy out the I/O vectors */
error:
}

まずはPRINT(cp, size)か。

#define PRINT(ptr, len) { \
	iovp->iov_base = __UNCONST(ptr); \
	iovp->iov_len = (len); \
	uio.uio_resid += (len); \
	iovp++; \
	if (++uio.uio_iovcnt >= NIOV) { \
		if (__sprint(fp, &uio)) { \
			goto error; \
		iovp = iov; \
	} \
}

__sprint() ?

/*
 * Flush out all the vectors defined by the given uio,
 * then reset it so that it can be reused.
 */
static int
__sprint(fp, uio)
	FILE *fp;
	struct __suio *uio;
{
	int err;

	_DIAGASSERT(fp != NULL);
	_DIAGASSERT(uio != NULL);

	if (uio->uio_resid == 0) {
		uio->uio_iovcnt = 0;
		return 0;
	}
	err = __sfvwrite(fp, uio);
	uio->uio_resid = 0;
	uio->uio_iovcnt = 0;
	return (err);
}

uio!

man uioすると、

#include <sys/types.h>
#include <sys/uio.h>

struct uio {
	struct	iovec *uio_iov;		/* scatter/gather list */
	int 	uio_iovcnt;		/* length of scatter/gather list */
	off_t	uio_offset;		/* offset in target object */
	int	uio_resid;		/* remaining bytes to copy */
	enum	uio_seg uio_segflg;	/* address space */
	enum	uio_rw uio_rw;		/* operation */
	struct	thread *uio_td;		/* owner */
};

ほほう。

なんだかこれ以上わからんなぁ。

いったい、どこでstdoutに文字を表示しているのだろうか。

asiainwaterasiainwater 2010/01/29 17:58 __sprintって、多分print.cに定義されているんだろうなと思った。