wm: teppich

Download patch

ref: 40b1fef01b2962896ed4eab1ae7f90eb7f58a73f
parent: 3ffef0f58e132850684dad253b11ba73cfa959c1
author: Mahdi <mahdi.hoseini1381@yahoo.com>
date: Thu Nov 23 07:31:01 EST 2023

Added printf.c, scanf.c, strtol.c, strncpy.c, itoa.c

--- /dev/null
+++ b/libc/itoa.c
@@ -1,0 +1,39 @@
+char*
+itoa( int value, int base )
+{
+    char *rc;
+    char *ptr;
+    char *low;
+    char *str;
+    // Check for supported base.
+    if ( base < 2 || base > 36 )
+    {
+        *str = '\0';
+        return str;
+    }
+    rc = ptr = str;
+    // Set '-' for negative decimals.
+    if ( value < 0 && base == 10 )
+    {
+        *ptr++ = '-';
+    }
+    // Remember where the numbers start.
+    low = ptr;
+    // The actual conversion.
+    do
+    {
+        // Modulo is negative for negative value. This trick makes abs() unnecessary.
+        *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + value % base];
+        value /= base;
+    } while ( value );
+    // Terminating the string.
+    *ptr-- = '\0';
+    // Invert the numbers.
+    while ( low < ptr )
+    {
+        char tmp = *low;
+        *low++ = *ptr;
+        *ptr-- = tmp;
+    }
+    return rc;
+}
\ No newline at end of file
--- /dev/null
+++ b/libc/printf.c
@@ -1,0 +1,86 @@
+#include <u.h>
+#include <libc.h>
+
+int
+print_char(int c)
+{
+	return vga_putc(c);
+}
+
+int
+print_str(char *str)
+{
+
+	vga_puts(str);
+
+	return strlen(str);
+}
+
+int
+print_digit(long num, int base)
+{
+	int count;
+	char* symbols = "0123456789abcdef";
+
+	if (num < 0)
+	{
+		vga_puts("-");
+		return print_digit(-num, base) + 1;
+	}
+	else if (num < base)
+	{
+		return print_char(symbols[num]);
+	}
+	else
+	{
+		count = print_digit(num / base, base);
+		return count + print_digit(num % base, base);
+	}
+	
+}
+
+int
+print_format(char specifier, va_list ap)
+{
+	int count = 0;
+
+	switch (specifier)
+	{
+	case 'c':
+		count += print_char(va_arg(ap, int));	// Type promotion
+		break;
+	case 's':
+		count += print_str(va_arg(ap, char*));
+		break;
+	case 'd':
+		count += print_digit((long)va_arg(ap, int), 10);
+		break;
+	case 'x':
+		count += print_digit((long)va_arg(ap, unsigned int), 16);
+	default:
+		count += vga_puts(specifier);
+		break;
+	}
+
+	return count;
+}
+
+int
+printf(const char* restrict format, ...) 
+{
+	va_list ap;
+	va_start(ap, format);
+	int count = 0;
+
+	while (*format) 
+	{
+		if (*format == '%') 
+			count += print_format(*(++format), ap);
+		else 
+			count += vga_putc(format);
+		format++;
+	}
+
+	va_end(ap);
+	return count;
+}
--- /dev/null
+++ b/libc/scanf.c
@@ -1,0 +1,58 @@
+
+#include <u.h>
+#include <libc.h>
+
+int scanf (char * str, ...)
+{
+    va_list vl;
+    int i = 0, j=0, ret = 0;
+    char buff[100] = {0}, tmp[20], c;
+    char *out_loc;
+    while(c != '\0') 
+    {
+        c = ps2_getc();
+ 	    buff[i] = c;
+ 	    i++;
+ 	}
+ 	va_start( vl, str );
+ 	i = 0;
+ 	while (str && str[i])
+ 	{
+ 	    if (str[i] == '%') 
+ 	    {
+ 	       i++;
+ 	       switch (str[i]) 
+ 	       {
+ 	           case 'c': 
+ 	           {
+	 	           *(char *)va_arg( vl, char* ) = buff[j];
+	 	           j++;
+	 	           ret ++;
+	 	           break;
+ 	           }
+ 	           case 'd': 
+ 	           {
+	 	           *(int *)va_arg( vl, int* ) =strtol(&buff[j], &out_loc, 10);
+	 	           j+=out_loc -&buff[j];
+	 	           ret++;
+	 	           break;
+ 	            }
+ 	            case 'x': 
+ 	            {
+	 	           *(int *)va_arg( vl, int* ) =strtol(&buff[j], &out_loc, 16);
+	 	           j+=out_loc -&buff[j];
+	 	           ret++;
+	 	           break;
+ 	            }
+ 	        }
+ 	    } 
+ 	    else 
+ 	    {
+ 	        buff[j] =str[i];
+            j++;
+        }
+        i++;
+    }
+    va_end(vl);
+    return ret;
+}
--- /dev/null
+++ b/libc/strncpy.c
@@ -1,0 +1,20 @@
+#include <u.h>
+
+char*
+strncpy(char *dst, const char *src, size_t num)
+{
+	char *dst_p = dst;
+
+	if (num != 0) {
+
+		do {
+			if ((*dst++ = *src++) == 0) {
+				/* NULL pad the remaining n-1 bytes */
+				while (--num != 0)
+					*dst++ = 0;
+				break;
+			}
+		} while (--num != 0);
+	}
+	return (dst_p);
+}
--- /dev/null
+++ b/libc/strtol.c
@@ -1,0 +1,97 @@
+#include <u.h>
+
+long
+strtol(char *nptr, char **endptr, int base)
+{
+	char *p;
+	long n, nn, m;
+	int c, ovfl, v, neg, ndig;
+
+	p = nptr;
+	neg = 0;
+	n = 0;
+	ndig = 0;
+	ovfl = 0;
+
+	/*
+	 * White space
+	 */
+	for(;; p++) {
+		switch(*p) {
+		case ' ':
+		case '\t':
+		case '\n':
+		case '\f':
+		case '\r':
+		case '\v':
+			continue;
+		}
+		break;
+	}
+
+	/*
+	 * Sign
+	 */
+	if(*p=='-' || *p=='+')
+		if(*p++ == '-')
+			neg = 1;
+
+	/*
+	 * Base
+	 */
+	if(base==0) {
+		base = 10;
+		if(*p == '0') {
+			base = 8;
+			if(p[1]=='x' || p[1]=='X') {
+				p += 2;
+				base = 16;
+			}
+		}
+	} else
+	if(base==16 && *p=='0'){
+		if(p[1]=='x' || p[1]=='X')
+			p += 2;
+	} else
+	if(base<0 || 36<base)
+		goto Return;
+
+	/*
+	 * Non-empty sequence of digits
+	 */
+	m = LONG_MAX/base;
+	for(;; p++,ndig++){
+		c = *p;
+		v = base;
+		if('0'<=c && c<='9')
+			v = c - '0';
+		else
+		if('a'<=c && c<='z')
+			v = c - 'a' + 10;
+		else
+		if('A'<=c && c<='Z')
+			v = c - 'A' + 10;
+		if(v >= base)
+			break;
+		if(n > m)
+			ovfl = 1;
+		nn = n*base + v;
+		if(nn < n)
+			ovfl = 1;
+		n = nn;
+	}
+
+Return:
+	if(ndig == 0)
+		p = nptr;
+	if(endptr)
+		*endptr = p;
+	if(ovfl){
+		if(neg)
+			return LONG_MIN;
+		return LONG_MAX;
+	}
+	if(neg)
+		return -n;
+	return n;
+}