Description
Rewritten of printf () functions from standard library without external libraries.
Rewritten of printf () functions from standard library without external libraries.
#define NULL 0x00 #define pop_arg(list, mode) (sizeof(mode)==1 ? ((mode *) (list += 4))[-4] : \ sizeof(mode)==2 ? ((mode *) (list += 4))[-2] : \ ((mode *) (list += sizeof(mode)))[-1]) /* Richiamo le funzioni non implementate */ extern void *malloc (unsigned int size); extern void free (void *ptr); extern void *realloc (void *ptr, unsigned int size); void _printf (char *, ...); int strlen (char *); void _print (char *); void _putchar (int c); char *int_to_string (int); char *strdup (char *); /* Funzione per la stampa a video di un carattere */ void _putchar (int c) { asm ("movl $4,%%eax\n" "movl $1,%%ebx\n" "movl %0,%%ecx\n" "movl $1,%%edx\n" "int $0x80" : : "r" (&c) :"eax", "ebx", "ecx", "edx"); } /* Calcolo lunghezza stringhe NULL-terminated */ int strlen (char *str) { int i; for (i = 0; str[i] != NULL; ++i); return i; } /* copia una stringa */ char * strdup (char *str) { int i = strlen (str), c = 0; char *l_str = (char *) malloc (i); for (; c < i; ++c) l_str[c] = str[c]; l_str[c] = NULL; return l_str; } /* Converte un intero in una stringa */ char * int_to_string (int n) { int i, sign, x = n; char *str, *t_str; if (!n) { str = (char *) malloc (1); *str = 0x30; return str; } if ((sign = x) < 0) x *= -1; str = (char *) malloc (2); for (i = 0; x > 0; i++) { str[i] = (x % 10) + 0x30; x /= 10; str = realloc (str, i + 3); } if (sign < 0) { str[i] = '-'; str[i + 1] = NULL; } else str[i] = NULL; t_str = strdup (str); for (sign = 0, i = strlen (str); sign < i; sign++) str[sign] = t_str[i - (1 + sign)]; free (t_str); return str; } /* Funzione per la conversione in ottale */ char * octal_to_string (int x) { char *local_str, *tmp_str; int y = x, mem = 2; local_str = (char *) malloc (mem); while (!NULL) { local_str[mem - 2] = *(int_to_string (y % 8)); local_str = (char *) realloc (local_str, mem++); if (y < 8) break; else y /= 8; } local_str[mem - 2] = NULL; mem = strlen (local_str); tmp_str = strdup (local_str); for (y = 0; y < mem; ++y) local_str[mem - (1 + y)] = tmp_str[y]; free (tmp_str); return local_str; } /* Funzione per la conversione in esadecimale */ char * hex_to_string (int x, int mode) { char *local_str, *tmp_str, *alpha_hex; int y = x, mem = 2; local_str = (char *) malloc (mem); if (mode) alpha_hex = strdup ("ABCDEF"); else alpha_hex = strdup ("abcdef"); while (!NULL) { if (y % 16 < 0x0A) local_str[mem - 2] = *(int_to_string (y % 16)); else local_str[mem - 2] = alpha_hex[(y % 16) - 10]; local_str = (char *) realloc (local_str, mem++); if (y < 16) break; else y /= 16; } free (alpha_hex); local_str[mem - 2] = NULL; tmp_str = strdup (local_str); mem = strlen (tmp_str); free (local_str); local_str = strdup (tmp_str); for (y = 0; y < mem; ++y) local_str[mem - (1 + y)] = tmp_str[y]; free (tmp_str); return local_str; } /* Funzione per la stampa a video */ void _print (char *str) { int i = strlen (str), c; for (c = 0; c < i; ++c) _putchar (str[c]); } /* Funzione per la stampa a video formattato */ void _printf (char *str, ...) { int i = strlen (str), c; char *list = (char *) (&(str) + 1), *temp; for (c = 0; c < i;) { if (c != i - 1 && str[c] == '%') { switch (str[++c]) { case '%': _putchar ('%'); break; case 's': _print (pop_arg (list, char *)); break; case 'c': _putchar (pop_arg (list, char)); break; case 'd': temp = int_to_string (pop_arg (list, int)); _print (temp); free (temp); break; case 'o': temp = octal_to_string (pop_arg (list, int)); _print (temp); free (temp); break; case 'x': temp = hex_to_string (pop_arg (list, int), NULL); _print (temp); free (temp); break; case 'X': temp = hex_to_string (pop_arg (list, int), !NULL); _print (temp); free (temp); break; default: _printf ("** ERROR: `%%%c` **", str[c]); break; } ++c; } else _putchar (str[c++]); } } int main (void) { _printf ("Stringa: %s\n" "Intero: %d\n" "Ottale: %o\n" "Esadecimale ( min ): %x\n" "Esadecimale ( max ): %X\n" "Carattere: %c\n" "Percentuale: %%\n" "Errore opzione: %j\n", "Hello World!", 123456, 123456, 123456, 123456, 'H'); }