summaryrefslogtreecommitdiff
path: root/src/user/lib/libc/std/string.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/lib/libc/std/string.c')
-rw-r--r--src/user/lib/libc/std/string.c113
1 files changed, 108 insertions, 5 deletions
diff --git a/src/user/lib/libc/std/string.c b/src/user/lib/libc/std/string.c
index 619b8c6..02225a6 100644
--- a/src/user/lib/libc/std/string.c
+++ b/src/user/lib/libc/std/string.c
@@ -17,7 +17,18 @@ char *strchr(const char *str, int c) {
char *strcpy(char *dest, const char *src) {
memcpy(dest, src, strlen(src) + 1);
- return (char*)src;
+ return (char*)dest;
+}
+
+char *strncpy(char *dest, const char *src, int n) {
+ size_t i;
+
+ for (i = 0; i < n && src[i] != '\0'; i++)
+ dest[i] = src[i];
+ for ( ; i < n; i++)
+ dest[i] = '\0';
+
+ return dest;
}
char *strdup(const char *src) {
@@ -29,11 +40,10 @@ char *strdup(const char *src) {
char *strcat(char *dest, const char *src) {
char *dest2 = dest;
- dest2 += strlen(dest) - 1;
+ while (*dest2) dest2++; // move to end of string
+
while (*src) {
- *dest2 = *src;
- src++;
- dest2++;
+ *(dest2++) = *(src++);
}
*dest2 = 0;
return dest;
@@ -133,6 +143,8 @@ int printf_str_len(const char *format, va_list ap) {
va_arg(ap, void*);
} else if (*format == 's') {
l += strlen(va_arg(ap, const char*));
+ } else if (*format == 'c') {
+ l += 1;
}
} else {
l++;
@@ -164,6 +176,10 @@ int vsprintf(char *buf, const char *format, va_list ap) {
const char *s = va_arg(ap, const char*);
strcpy(end, s);
end += strlen(s);
+ } else if (*format == 'c') {
+ char k = va_arg(ap, int);
+ *(end++) = k;
+ *end = 0;
}
format++;
} else {
@@ -173,3 +189,90 @@ int vsprintf(char *buf, const char *format, va_list ap) {
*end = 0;
return end - buf;
}
+
+
+// ****** PATH CONCATENATION FUNCTION *******
+
+
+void simplify_path(char* p) {
+ char *it = p;
+ char *member = it;
+ while (*it != 0) {
+ if (*it == '/') {
+ if (it == member && it != p) {
+ // two consecutive slashes
+ char *i = member;
+ while (1) {
+ i[0] = i[1];
+ if (i[0] == 0) break;
+ i++;
+ }
+ } else {
+ *it = 0;
+ if (strcmp(member, ".") == 0) {
+ char *i = member;
+ while (1) {
+ i[0] = i[2];
+ if (i[0] == 0) break;
+ i++;
+ }
+ } else if (strcmp(member, "..") == 0) {
+ *it = '/';
+ char* start = member - 2;
+ char* next = member + 3;
+ while (start > p && *start != '/') {
+ start--;
+ }
+ start++;
+ it = member = start;
+ while (1) {
+ *start = *next;
+ if (*start == 0) break;
+ start++;
+ next++;
+ }
+ } else {
+ *it = '/';
+ it++;
+ member = it;
+ }
+ }
+ } else {
+ it++;
+ }
+ }
+}
+
+char* path_cat(const char *a, const char *b, int trailing_slash) {
+ int len, la = strlen(a), lb = strlen(b);
+ if (b[0] == '/') {
+ len = lb + 2;
+ } else {
+ len = la + lb + 3;
+ }
+ char *buf = malloc(len + 1);
+ if (b[0] == '/') {
+ memcpy(buf, b, lb);
+ if (buf[lb-1] != '/') {
+ buf[lb++] = '/';
+ }
+ buf[lb] = 0;
+ } else {
+ memcpy(buf, a, la);
+ if (buf[la-1] != '/') {
+ buf[la++] = '/';
+ }
+ memcpy(buf + la, b, lb);
+ if (buf[la + lb - 1] != '/') {
+ buf[la + lb] = '/';
+ lb++;
+ }
+ buf[la + lb] = 0;
+ }
+ simplify_path(buf);
+ if (!trailing_slash) {
+ int l = strlen(buf);
+ if (buf[l-1] == '/') buf[l-1] = 0;
+ }
+ return buf;
+}