wm: teppich

Download patch

ref: cea5b851fc55e241c24792c50157adc2cb2cc240
parent: 9eddf61979d8dbc0029c85b400f2488bdcabf25c
author: Mahdi <mahdi.hoseini1381@yahoo.com>
date: Fri Dec 1 14:15:43 EST 2023

rewritten itoa.c and scanf.c, added adler32.c hash algorithm,

--- a/include/libc.h
+++ b/include/libc.h
@@ -25,4 +25,6 @@
 int printf(const char* restrict format, ...);
 int scanf (char * str, ...);
 
-char* itoa(int value, int base);
+char* itoa(int num, char* str, int base);
+
+long adler32(char *data);
--- /dev/null
+++ b/libc/adler32.c
@@ -1,0 +1,16 @@
+long
+adler32(char *data)
+{
+	const int prime = 65521;
+	int i = 0;
+	int a = 0, b = 1;
+	while (i < strlen(data))
+	{
+		b += data[i];
+		a += b;
+		i++;
+	}
+	b = b % prime;
+	a = a % prime;
+	return(b << 16 | a);
+}
\ No newline at end of file
--- a/libc/itoa.c
+++ b/libc/itoa.c
@@ -1,39 +1,59 @@
+// A utility function to reverse a string
+void
+reverse(char str[], int length)
+{
+	int start = 0;
+	int end = length - 1;
+	while (start < end) 
+	{
+		char temp = str[start];
+		str[start] = str[end];
+		str[end] = temp;
+		end--;
+		start++;
+	}
+}
+
 char*
-itoa(int value, int base )
+itoa(int num, char* str, int base)
 {
-	char *rc;
-	char *ptr;
-	char *low;
-	char *str;
-	// Check for supported base.
-	if ( base < 2 || base > 36 )
+	int i = 0;
+	int isNegative = 0;
+
+	// Handle 0 explicitly
+	if (num == 0) 
 	{
-		*str = '\0';
+		str[i++] = '0';
+		str[i] = '\0';
 		return str;
 	}
-	rc = ptr = str;
-	// Set '-' for negative decimals.
-	if ( value < 0 && base == 10 )
+
+	/* In standard itoa(), negative numbers are handled
+	 only with base 10. Otherwise numbers are
+	 considered unsigned. */
+	if (num < 0 && base == 10) 
 	{
-		*ptr++ = '-';
+		isNegative = 1;
+		num = -num;
 	}
-	// Remember where the numbers start.
-	low = ptr;
-	// The actual conversion.
-	do
+
+	// Process individual digits
+	while (num != 0) 
 	{
-		// 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;
+		int rem = num % base;
+		str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
+		num = num / base;
 	}
-	return rc;
-}
+
+	// If number is negative, append '-'
+	if (isNegative)
+		str[i++] = '-';
+
+	// Reverse the string
+	reverse(str, i);
+	
+	// Append string terminator
+	str[i] = '\0';
+
+	return str;
+}
\ No newline at end of file
--- a/libc/scanf.c
+++ b/libc/scanf.c
@@ -3,62 +3,67 @@
 
 #include <vga.h>
 #include <ps2.h>
+#include <mem.h>
 
-int scanf(char *str, ...)
+char*
+get_char()
 {
-	va_list vl;
-	int i = 0, j=0, ret = 0;
-	char buff[100] = {0}, tmp[20], c;
-	char *out_loc;
-
-
-	while(c != '\r') 
-	{
+    int i = 0;
+    char *buff = malloc(10), c;
+    while (1 == 1)
+    {
 		c = ps2_getc();
 		vga_putc(c);
-		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;
+        if (c != '\r')
+        {
+            buff[i] = c;
+            i++;
+        }
+        else break;
+    }
+    return buff; 
 }
+
+int
+scanf(char *str, ...)
+{
+    va_list ap;
+    va_start(ap, str);
+
+    int count = 0;
+    char *buffer, *temp;
+
+    while (*str != '\0')
+    {
+        if (*str == '%')
+        {
+            buffer = get_char();
+            str++;
+            switch(*str)
+            {
+                case 'c':
+                    *va_arg(ap, char*) = buffer[0];
+                    count++;
+                    break;
+                case 's':
+                    *va_arg(ap, char**) = buffer;
+                    count++;
+                    break;
+                case 'd':
+                    *va_arg(ap, int*) = strtol(buffer, &temp, 10);
+                    count++;
+                    break;
+                case 'x':
+                    *va_arg(ap, int*) = strtol(buffer, &temp, 16);
+                    count++;
+                    break;
+                default:
+                    break;
+            }
+        }
+        str++;
+    }
+    va_end(ap);
+    return count;
+}
+