YeXo - een kernel programmeren

01 april 2006

Variabel aantal argumenten voor functie

Functies met een variabel aantal argumenten kunnen erg handig zijn, bijvoorbeeld voor printf. Het eerste argument voor printf is een zogenaamde format string, een tekst waarin met speciale codes staat aangegeven op welke plaats de argumenten moeten worden ingevoegd. Deze codes zijn:

%c
In plaats hiervan wordt een character ingevoegd.
%s
In plaats hiervan wordt een string (tekenreeks) ingevoegd.
%d
Hier komt een decimaal getal te staan.
%x
Hier komt een hexadecimaal getal te staan.
Je zou de functie printf dus als volgt kunnen gebruiken: printf("%d %c %d = %x",8,'+',8,8+8);Dit geeft dan de volgende uitvoer:8 + 8 = 0x10Om zelf een print functie te schrijven voor een kernel moeten we eerst een paar macros maken. De kprintf functie moet namelijk wel de argumenten een voor een op kunnen vragen.

Een functie met een variabel aantal argumenten definieer je als volgt:void kprintf(char *str, ... );In de functie moet je daarna een aantal macros gebruiken om de argumenten op te vragen. Let erop dat de functie alleen weet hoeveel argumenten er doorgegeven worden als hij dat af kan lijden uit de string. Je hebt de volgende macros nodig:typedef struct {
void **ptr;
} va_list;

#define va_start( ap, lastarg ) ap.ptr = (void**)( (unsigned int)&lastarg + sizeof(void**) );


#define va_arg( ap, type) ((type)*(ap.ptr)); ap.ptr = (void**)( ((unsigned int)ap.ptr) + sizeof( unsigned long ) );

#define va_end( ap ) ap.ptr = NULL;
De functie kprintf kan er daarna bijvoorbeeld zo uitzien:void kprintf(char *text, ...){
va_list ap;
va_start(ap, text);
char *tp = text;
while( *tp != '\0' ){
if( *tp == '%' ){
*tp++;
unsigned long temp = va_arg(ap, unsigned long);
switch(*tp){
case 'c':
putch((char)temp);
break;
case 's':
kprintString((char*)temp);
break;
case 'd':
kprintInt(temp);
break;
case 'f':
kprintFloat((float)temp);
break;
case 'x':
kprinthex(temp);
break;
}
}
else {
putch(*tp);
}
*tp++;
}
va_end(ap);
}
Vergeet niet de functies te implementeren waarvan kprintf afhankelijk is, dus kprinthex, kprintString enz.

1 Reacties:

Een reactie posten

<< Home