⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stand_lib.c

📁 系统调用是系统内核和应用程序的接口 此代码展示了linux系统调用的实现
💻 C
字号:
size_t strlen(const char *str)
{
    size_t ret_val;

    for(ret_val = 0; *str != '\0'; str++)
        ret_val++;
    return ret_val;
}

int strcmp(const char *str1, const char *str2)
{
    while ((*str2 != '\0') && (*str1 == *str2))
    {
        str1++;
        str2++;
    }
    return *str1 -  *str2;
}

const char *strstr(const char *s1, const char *s2)
{
    const char *start_s1 = NULL;
    const char *in_s2 = NULL;

    for( ; *s1 != '\0'; s1++)
    {
        if(start_s1 == NULL)
        {
            /* first char of match */
            if(*s1 == *s2)
            {
                /* remember start of matching substring in s1 */
                start_s1 = s1;
                in_s2 = s2 + 1;
                /* done already? */
                if(*in_s2 == '\0')
                    return start_s1;
            }
            /*	continued mis-match
            else
            	nothing ; */
        }
        else
        {
            /* continued match */
            if(*s1 == *in_s2)
            {
                in_s2++;
                /* done */
                if(*in_s2 == '\0')
                    return start_s1;
            }
            else
                /* first char of mis-match */
                start_s1 = NULL;
        }
    }
    return NULL;
}

void *memcpy(void *dst_ptr, const void *src_ptr, size_t count)
{
    const char *src = (const char *)src_ptr;
    char *dst = (char *)dst_ptr;
    void *ret_val = dst_ptr;

    for(; count != 0; count--)
    {
        *dst = *src;
        dst++;
        src++;
    }
    return ret_val;
}

void *memmove(void *dst_p, const void *src_p, size_t count)
{
    const char *src = (const char *)src_p;
    char *dst = (char *)dst_p;

    if(dst_p < src_p)	/* copy up */
    {
        for(; count != 0; count--)
            *dst++ = *src++;
    }
    else			/* copy down */
    {
        dst += (count - 1);
        src += (count - 1);
        for(; count != 0; count--)
            *dst-- = *src--;
    }
    return dst_p;
}

int fputc(int c, FILE *stream)
{
    char one_char;
    int ret_val;

    ret_val = c;
    if(stream->flags == _IONBF || stream->size == 0) /* unbuffered */
    {
        one_char = (char)c;
        if(write(stream->handle, &one_char, 1) != 1)
            ret_val = EOF;
    }
    else										/* buffered */
    {
        if(stream->room == 0)
        {
            if(fflush(stream) != 0)
                return EOF;
        }
        *stream->buf_ptr = (char)c;
        stream->buf_ptr++;
        stream->room--;
        if((stream->flags & _IOLBF) && (c == '\n'))
        {
            if(fflush(stream) != 0)
                ret_val = EOF;
        }
    }
    return ret_val;
}

int fflush(FILE *stream)
{
    int bytes_to_write, ret_val;

    ret_val = 0;
    if(stream->size != 0)						/* buffered? */
    {
        bytes_to_write = stream->size - stream->room;
        if(bytes_to_write != 0)
        {
            if(write(stream->handle, stream->buf_base,
                     bytes_to_write) != bytes_to_write)
                ret_val = EOF;
            stream->buf_ptr = stream->buf_base;
            stream->room = stream->size;
        }
    }
    return ret_val;
}


#include <_printf.h>		/* fnptr_t */
#include <string.h>			/* strlen() */
#include <stdarg.h>		/* va_list, va_arg() */
/*******************************************************************
	name:	do_printf
	action:	minimal subfunction for ?printf, calls function
		'fn' with arg 'ptr' for each character to be output
	returns:total number of characters output

	%[flag][width][.prec][mod][conv]
	flag:	-	left justify, pad right w/ blanks	DONE
		0	pad left w/ 0 for numerics		DONE
		+	always print sign, + or -		xxx
		' '	(blank)					xxx
		#	(???)					xxx

	width:		(field width)				DONE

	prec:		(precision)				xxx

	conv:	d,i	decimal int				DONE
		u	decimal unsigned			DONE
		o	octal					DONE
		x,X	hex					DONE
		f,e,g,E,G float					xxx
		c	char					DONE
		s	string					DONE
		p	ptr					DONE

	mod:	N	near ptr				DONE
		F	far ptr					xxx
		h	short (16-bit) int			DONE
		l	long (32-bit) int			DONE
		L	long long (64-bit) int			xxx
*******************************************************************/
/* flags used in processing format string */
#define		PR_LJ	0x01	/* left justify */
#define		PR_CA	0x02	/* use A-F instead of a-f for hex */
#define		PR_SG	0x04	/* signed numeric conversion (%d vs. %u) */
#define		PR_32	0x08	/* long (32-bit) numeric conversion */
#define		PR_16	0x10	/* short (16-bit) numeric conversion */
#define		PR_WS	0x20	/* PR_SG set and num was < 0 */
#define		PR_LZ	0x40	/* pad left with '0' instead of ' ' */
#define		PR_FP	0x80	/* pointers are far */

/* largest number handled is 2^32-1, lowest radix handled is 8.
2^32-1 in base 8 has 11 digits (add 5 for trailing NUL and for slop) */
#define		PR_BUFLEN	16

int do_printf(const char *fmt, va_list args, fnptr_t fn, void *ptr)
{
    unsigned char state, flags, radix, actual_wd;
    unsigned short count, given_wd;
    char *where, buf[PR_BUFLEN];
    long num;

    state = flags = count = given_wd = 0;
    /* begin scanning format specifier list */
    for(; *fmt; fmt++)
    {
        switch(state)
        {
            /* STATE 0: AWAITING % */
        case 0:
            if(*fmt != '%')	/* not %... */
            {
                fn(*fmt, &ptr);	/* ...just echo it */
                count++;
                break;
            }
            /* found %, get next char and advance state to check if next char is a flag */
            state++;
            fmt++;
            /* FALL THROUGH */
            /* STATE 1: AWAITING FLAGS (%-0) */
        case 1:
            if(*fmt == '%')	/* %% */
            {
                fn(*fmt, &ptr);
                count++;
                state = flags = given_wd = 0;
                break;
            }
            if(*fmt == '-')
            {
                if(flags & PR_LJ)/* %-- is illegal */
                    state = flags = given_wd = 0;
                else
                    flags |= PR_LJ;
                break;
            }
            /* not a flag char: advance state to check if it's field width */
            state++;
            /* check now for '%0...' */
            if(*fmt == '0')
            {
                flags |= PR_LZ;
                fmt++;
            }
            /* FALL THROUGH */
            /* STATE 2: AWAITING (NUMERIC) FIELD WIDTH */
        case 2:
            if(*fmt >= '0' && *fmt <= '9')
            {
                given_wd = 10 * given_wd +
                           (*fmt - '0');
                break;
            }
            /* not field width: advance state to check if it's a modifier */
            state++;
            /* FALL THROUGH */
            /* STATE 3: AWAITING MODIFIER CHARS (FNlh) */
        case 3:
            if(*fmt == 'F')
            {
                flags |= PR_FP;
                break;
            }
            if(*fmt == 'N')
                break;
            if(*fmt == 'l')
            {
                flags |= PR_32;
                break;
            }
            if(*fmt == 'h')
            {
                flags |= PR_16;
                break;
            }
            /* not modifier: advance state to check if it's a conversion char */
            state++;
            /* FALL THROUGH */
            /* STATE 4: AWAITING CONVERSION CHARS (Xxpndiuocs) */
        case 4:
            where = buf + PR_BUFLEN - 1;
            *where = '\0';
            switch(*fmt)
            {
            case 'X':
                flags |= PR_CA;
                /* FALL THROUGH */
                /* xxx - far pointers (%Fp, %Fn) not yet supported */
            case 'x':
            case 'p':
            case 'n':
                radix = 16;
                goto DO_NUM;
            case 'd':
            case 'i':
                flags |= PR_SG;
                /* FALL THROUGH */
            case 'u':
                radix = 10;
                goto DO_NUM;
            case 'o':
                radix = 8;
                /* load the value to be printed. l=long=32 bits: */
DO_NUM:				if(flags & PR_32)
                num = va_arg(args, unsigned long);
                /* h=short=16 bits (signed or unsigned) */
                else if(flags & PR_16)
                {
                    if(flags & PR_SG)
                        num = va_arg(args, short);
                    else
                        num = va_arg(args, unsigned short);
                }
                /* no h nor l: sizeof(int) bits (signed or unsigned) */
                else
                {
                    if(flags & PR_SG)
                        num = va_arg(args, int);
                    else
                        num = va_arg(args, unsigned int);
                }
                /* take care of sign */
                if(flags & PR_SG)
                {
                    if(num < 0)
                    {
                        flags |= PR_WS;
                        num = -num;
                    }
                }
                /* convert binary to octal/decimal/hex ASCII
                OK, I found my mistake. The math here is _always_ unsigned */
                do
                {
                    unsigned long temp;

                    temp = (unsigned long)num % radix;
                    where--;
                    if(temp < 10)
                        *where = temp + '0';
                    else if(flags & PR_CA)
                        *where = temp - 10 + 'A';
                    else
                        *where = temp - 10 + 'a';
                    num = (unsigned long)num / radix;
                }
                while(num != 0);
                goto EMIT;
            case 'c':
                /* disallow pad-left-with-zeroes for %c */
                flags &= ~PR_LZ;
                where--;
                *where = (char)va_arg(args, char);
                actual_wd = 1;
                goto EMIT2;
            case 's':
                /* disallow pad-left-with-zeroes for %s */
                flags &= ~PR_LZ;
                where = va_arg(args, char *);
EMIT:
                actual_wd = strlen(where);
                if(flags & PR_WS)
                    actual_wd++;
                /* if we pad left with ZEROES, do the sign now */
                if((flags & (PR_WS | PR_LZ)) ==
                        (PR_WS | PR_LZ))
                {
                    fn('-', &ptr);
                    count++;
                }
                /* pad on left with spaces or zeroes (for right justify) */
EMIT2:				if((flags & PR_LJ) == 0)
                {
                    while(given_wd > actual_wd)
                    {
                        fn(flags & PR_LZ ? '0' :
                           ' ', &ptr);
                        count++;
                        given_wd--;
                    }
                }
                /* if we pad left with SPACES, do the sign now */
                if((flags & (PR_WS | PR_LZ)) == PR_WS)
                {
                    fn('-', &ptr);
                    count++;
                }
                /* emit string/char/converted number */
                while(*where != '\0')
                {
                    fn(*where++, &ptr);
                    count++;
                }
                /* pad on right with spaces (for left justify) */
                if(given_wd < actual_wd)
                    given_wd = 0;
                else given_wd -= actual_wd;
                for(; given_wd; given_wd--)
                {
                    fn(' ', &ptr);
                    count++;
                }
                break;
            default:
                break;
            }
        default:
            state = flags = given_wd = 0;
            break;
        }
    }
    return count;
}

#if 0 /* testing */
int vsprintf_help(char c, void **ptr)
{
    char *dst;

    dst = *ptr;
    *dst++ = c;
    *ptr = dst;
    return 0 ;
}
int vsprintf(char *buffer, const char *fmt, va_list args)
{
    int ret_val;

    ret_val = do_printf(fmt, args, vsprintf_help, (void *)buffer);
    buffer[ret_val] = '\0';
    return ret_val;
}
int sprintf(char *buffer, const char *fmt, ...)
{
    va_list args;
    int ret_val;

    va_start(args, fmt);
    ret_val = vsprintf(buffer, fmt, args);
    va_end(args);
    return ret_val;
}

int vprintf_help(char c, void **ptr)
{
    putchar(c);
    return 0 ;
}
int vprintf(const char *fmt, va_list args)
{
    return do_printf(fmt, args, vprintf_help, NULL);
}

int printf(const char *fmt, ...)
{
    va_list args;
    int ret_val;

    va_start(args, fmt);
    ret_val = vprintf(fmt, args);
    va_end(args);
    return ret_val;
}

int main(void)
{
    char buf[64];

    sprintf(buf, "%u score and %i years ago...\n", 4, -7);
    puts(buf);

    sprintf(buf, "-1L == 0x%lX == octal %lo\n", -1L, -1L);
    puts(buf);

    printf("<%-08s> and <%08s> justified strings\n", "left", "right");
    return 0;
}
#endif

unsigned _seed;
unsigned rand(void) /* stdlib.h */
{
    if(_seed == 0)
        _seed = 1;
    if((((_seed << 3) ^ _seed) & 0x80000000L) != 0)
        _seed = (_seed << 1) | 1;
    else
        _seed <<= 1;
    return _seed - 1;
}

extern unsigned _seed; /* in rand.c */
void srand(unsigned new_seed) /* stdlib.h */
{
    _seed = new_seed;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -