Skip to content

Commit ff94b81

Browse files
committed
Split monolithic libc.c into logical modules
This commit consolidates modular source files of libc for better maintainability: - lib/string.c: String manipulation functions - lib/memory.c: Memory operations (memcpy, memset, etc.) - lib/ctype.c: Character classification and conversion utilities - lib/random.c: xorshift32 PRNG implementation - lib/stdio.c: Standard I/O and printf formatting routines
1 parent 2ee6ac9 commit ff94b81

File tree

9 files changed

+1002
-927
lines changed

9 files changed

+1002
-927
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ KERNEL_OBJS := timer.o mqueue.o pipe.o semaphore.o mutex.o error.o syscall.o tas
2121
KERNEL_OBJS := $(addprefix $(BUILD_KERNEL_DIR)/,$(KERNEL_OBJS))
2222
deps += $(KERNEL_OBJS:%.o=%.o.d)
2323

24-
LIB_OBJS := stdio.o libc.o malloc.o queue.o
24+
LIB_OBJS := ctype.o malloc.o memory.o random.o stdio.o string.o queue.o
2525
LIB_OBJS := $(addprefix $(BUILD_LIB_DIR)/,$(LIB_OBJS))
2626
deps += $(LIB_OBJS:%.o=%.o.d)
2727

include/lib/libc.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,6 @@ char *strpbrk(const char *s1, const char *s2);
7676
char *strsep(char **pp, const char *delim);
7777
char *strtok(char *s, const char *delim);
7878
char *strtok_r(char *s, const char *delim, char **holder);
79-
int32_t strtol(const char *s, char **end, int32_t base);
80-
int32_t atoi(const char *s);
81-
void itoa(int32_t i, char *s, int32_t base); /* Integer to ASCII conversion */
8279

8380
/* Memory manipulation functions */
8481
void *memcpy(void *dst, const void *src, uint32_t n);
@@ -87,6 +84,11 @@ int32_t memcmp(const void *cs, const void *ct, uint32_t n);
8784
void *memset(void *s, int32_t c, uint32_t n);
8885
int32_t abs(int32_t n); /* Absolute value */
8986

87+
/* Character classification and conversion functions */
88+
int32_t strtol(const char *s, char **end, int32_t base);
89+
int32_t atoi(const char *s);
90+
void itoa(int32_t i, char *s, int32_t base); /* Integer to ASCII conversion */
91+
9092
/* Random number generation */
9193

9294
#ifndef RAND_MAX

lib/ctype.c

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/* libc: string-to-number conversion functions. */
2+
3+
#include <lib/libc.h>
4+
5+
/* Base-10 string conversion without division or multiplication */
6+
static char *__str_base10(uint32_t value, char *buffer, int *length)
7+
{
8+
if (value == 0) {
9+
buffer[0] = '0';
10+
*length = 1;
11+
return buffer;
12+
}
13+
int pos = 0;
14+
15+
while (value > 0) {
16+
uint32_t q, r, t;
17+
18+
q = (value >> 1) + (value >> 2);
19+
q += (q >> 4);
20+
q += (q >> 8);
21+
q += (q >> 16);
22+
q >>= 3;
23+
r = value - (((q << 2) + q) << 1);
24+
t = ((r + 6) >> 4);
25+
q += t;
26+
r -= (((t << 2) + t) << 1);
27+
28+
buffer[pos++] = '0' + r;
29+
value = q;
30+
}
31+
*length = pos;
32+
33+
return buffer;
34+
}
35+
36+
/* Handle signed integers */
37+
static char *__str_base10_signed(int32_t value, char *buffer, int *length)
38+
{
39+
if (value < 0) {
40+
buffer[0] = '-';
41+
__str_base10((uint32_t) (-value), buffer + 1, length);
42+
(*length)++;
43+
return buffer;
44+
}
45+
return __str_base10((uint32_t) value, buffer, length);
46+
}
47+
48+
/* Converts string @s to an integer. */
49+
int32_t strtol(const char *s, char **end, int32_t base)
50+
{
51+
int32_t i;
52+
uint32_t ch, value = 0, neg = 0;
53+
54+
/* Handle optional sign. */
55+
if (s[0] == '-') {
56+
neg = 1;
57+
++s;
58+
}
59+
60+
/* Handle common base prefixes (0x for hex). */
61+
if (s[0] == '0' && s[1] == 'x') {
62+
base = 16;
63+
s += 2;
64+
}
65+
66+
/* Convert digits based on the specified base. */
67+
for (i = 0; i <= 8; ++i) {
68+
ch = *s++;
69+
if ('0' <= ch && ch <= '9')
70+
ch -= '0';
71+
else if ('A' <= ch && ch <= 'Z')
72+
ch = ch - 'A' + 10;
73+
else if ('a' <= ch && ch <= 'z')
74+
ch = ch - 'a' + 10;
75+
else
76+
break;
77+
value = value * base + ch;
78+
}
79+
80+
if (end)
81+
*end = (char *) s - 1;
82+
if (neg)
83+
value = -(int32_t) value;
84+
85+
return value;
86+
}
87+
88+
/* Converts string @s to an integer. */
89+
int32_t atoi(const char *s)
90+
{
91+
int32_t n, f;
92+
93+
n = 0;
94+
f = 0; /* Flag for sign. */
95+
96+
/* Skip leading whitespace and handle optional sign. */
97+
for (;; s++) {
98+
switch (*s) {
99+
case ' ':
100+
case '\t':
101+
case '\n':
102+
case '\r':
103+
continue; /* Skip whitespace. */
104+
case '-':
105+
f++; /* Set negative flag. */
106+
__attribute__((fallthrough));
107+
case '+':
108+
s++; /* Skip '+' sign. */
109+
}
110+
break;
111+
}
112+
113+
/* Convert digits to integer. */
114+
while (*s >= '0' && *s <= '9')
115+
n = n * 10 + *s++ - '0';
116+
117+
return (f ? -n : n);
118+
}
119+
120+
/* Converts integer @i to an ASCII string @s in the given @base. */
121+
void itoa(int32_t i, char *s, int32_t base)
122+
{
123+
char c;
124+
char *p = s;
125+
char *q = s;
126+
uint32_t h;
127+
int32_t len;
128+
129+
if (base == 16) { /* Hexadecimal conversion */
130+
h = (uint32_t) i;
131+
do {
132+
*q++ = '0' + (h % base);
133+
} while (h /= base); /* Continue until number becomes 0. */
134+
135+
if ((i >= 0) && (i < 16)) /* Special case for small positive numbers */
136+
*q++ = '0';
137+
138+
/* Reverse the string (digits are collected in reverse order). */
139+
for (*q = 0; p <= --q; p++) {
140+
/* Convert digit character if needed (e.g., 'a'-'f'). */
141+
(*p > '9') ? (c = *p + 39) : (c = *p); /* ASCII 'a' is '0'+39 */
142+
/* Swap characters. */
143+
(*q > '9') ? (*p = *q + 39) : (*p = *q);
144+
*q = c;
145+
}
146+
} else if (base == 10) { /* Decimal conversion */
147+
__str_base10_signed(i, s, &len);
148+
149+
/* Reverse the string. */
150+
q = s + len;
151+
for (*q = 0; p <= --q; p++) {
152+
c = *p;
153+
*p = *q;
154+
*q = c;
155+
}
156+
} else { /* Other bases */
157+
if (i >= 0) {
158+
do {
159+
*q++ = '0' + (i % base);
160+
} while (i /= base);
161+
} else {
162+
*q++ = '-';
163+
p++;
164+
do {
165+
*q++ = '0' - (i % base);
166+
} while (i /= base);
167+
}
168+
169+
/* Reverse the string. */
170+
for (*q = 0; p <= --q; p++) {
171+
c = *p;
172+
*p = *q;
173+
*q = c;
174+
}
175+
}
176+
}

0 commit comments

Comments
 (0)