Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

stdarg.h in C

Name: Anonymous 2012-09-05 16:00

I'm currently writing a C standard library for academic purposes, and I wondered how to implement stdarg.h (the va_* macros) in C (probably with inline ASM) and if this was the libc's work, or the compiler's ?
Thanks in advance.

Name: Anonymous 2012-09-06 2:18

Sometime ago I wrote a simple OS and it just used macros from stdarg.h

so you never need to touch them.


#define VIDEO_WIDTH 80
#define VIDEO_HEIGHT 25
#define VIDEO_RAM 0xb8000
#include <stdarg.h>
#include "tty.h"

int tty_cursor;
int tty_attribute;

void init_tty() {
    tty_cursor = 0;
    tty_attribute = 10;
}

static int textcolor(int c) {
    tty_attribute = c;
}

void clear_screen() {
    char *video = (char*) VIDEO_RAM;
    int i;
    for (i = 0; i < VIDEO_HEIGHT*VIDEO_WIDTH; i++) {
        *(video + i*2) = ' ';
    }
    tty_cursor = 0;
}

void putchar(char c) {
    char *video = (char*) VIDEO_RAM;
    int i;
    switch (c) {
    case '\n':
        tty_cursor+=VIDEO_WIDTH;
        tty_cursor-=tty_cursor%VIDEO_WIDTH;
        break;
    default:
        *(video + tty_cursor*2) = c;
        *(video + tty_cursor*2+1) = tty_attribute;
        tty_cursor++;
        break;
    }
    // do we need to shift screen horizontally?
    if (tty_cursor>VIDEO_WIDTH*VIDEO_HEIGHT) {
        for (i=VIDEO_WIDTH*2;i<=VIDEO_WIDTH*VIDEO_HEIGHT*2+VIDEO_WIDTH*2;i++) {
            *(video+i-VIDEO_WIDTH*2)=*(video+i);
        }
        tty_cursor-=VIDEO_WIDTH;
    }
}

static void reverse(char *s) {
    char *p = s;
    while(*p) p++;
    while(s < --p) {
        int t = *s;
        *s++ = *p;
        *p = t;
    }
}


static char *puthex_digit(char *b, unsigned char digit) {
    char table[]="0123456789ABCDEF";
    *b++ = table[digit];
    return b;
}

static char *puthex_tetra(char *b, unsigned char byte) {
    b = puthex_digit(b, byte >> 4);
    b = puthex_digit(b, byte & 0x0F);
    return b;
}

static char *puthex(char *b, unsigned int dword) {
    b = puthex_tetra(b, (dword & 0xFF000000) >>24);
    b = puthex_tetra(b, (dword & 0x00FF0000) >>16);
    b = puthex_tetra(b, (dword & 0x0000FF00) >>8);
    b = puthex_tetra(b, (dword & 0x000000FF));
    return b;
}

static char *int2string(char *b, int v, int base, int unsign) {
    char *p = b;
    unsigned int x;
    int sign = 0;

    if(v < 0 && !unsign) {
        sign = 1;
        x = -v;
        *p++ = '-';
    } else {
        if(v < 0) x = -v;
        else x = v;
    }

    do {
        unsigned int c = x % base;
        x /= base;
        if(c < 10) c += '0';
        else {
            c -= 10;
            c += 'A';
        }
        *p++ = c;
    } while(x);
    *p = 0;
    reverse(b+sign);
    return p;
}

static void vsprintf_helper(char *b, const char *fmt, va_list args) {
    for( ; *fmt; fmt++) {
        if(*fmt != '%') {
            putchar(*fmt);
            continue;
        }
        fmt++;
        switch (*fmt) {
        case 's': {
            char *p = va_arg(args, char *);
            while(*b++ = *p++);
            b--;
            break;}

        case 'c':
            *b++ = va_arg(args, unsigned int);
            break;

        case 'i': case 'd':
            b = int2string(b, va_arg(args, unsigned int), 10, 0);
            break;
   
        case 'u':
            b = int2string(b, va_arg(args, unsigned int), 10, 1);

        case 'x': case 'X':
            b = puthex(b, va_arg(args, unsigned int));
            break;

        case 'z':
            textcolor(va_arg(args,unsigned int));
            break;
        }
    }
    *b = 0;
}

void puts(const char *s) {
    while(*s) putchar(*s++);
}


void vsprintf(char *b, const char *fmt, ...) {
    va_list args;
    va_start(args, fmt);
    vsprintf_helper(b, fmt, args);
    va_end(args);
}

void printf(const char *fmt, ...) {
    char b[512];
    va_list args;
    va_start(args, fmt);

    textcolor(0xf);

    vsprintf_helper(b, fmt, args);

    va_end(args);
    puts(b);
}

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List