--- /dev/null
+/*
+ * String library
+ * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
+ * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/* Modifications by Jack Lange <jarusl@cs.northwestern.edu> */
+
+
+
+/*
+ * NOTE:
+ * These are slow and simple implementations of a subset of
+ * the standard C library string functions.
+ * We also have an implementation of snprintf().
+ */
+
+
+
+#define NEED_MEMSET 0
+#define NEED_MEMCPY 0
+#define NEED_MEMCMP 0
+#define NEED_STRLEN 0
+#define NEED_STRNLEN 0
+#define NEED_STRCMP 0
+#define NEED_STRNCMP 0
+#define NEED_STRCAT 0
+#define NEED_STRNCAT 0
+#define NEED_STRCPY 0
+#define NEED_STRNCPY 0
+#define NEED_STRDUP 0
+#define NEED_ATOI 0
+#define NEED_STRCHR 0
+#define NEED_STRRCHR 0
+#define NEED_STRPBRK 0
+
+
+
+#include <palacios/vmm_string.h>
+#include <palacios/vmm.h>
+
+
+
+static float e = 0.00000001;
+
+double v3_ceil(double x) {
+ if ((double)(x - (int)x) == 0) {
+ return (int)x;
+ }
+ return (int)(x + e) + 1;
+}
+
+
+#if NEED_MEMSET
+void* memset(void* s, int c, size_t n)
+{
+ unsigned char* p = (unsigned char*) s;
+
+ while (n > 0) {
+ *p++ = (unsigned char) c;
+ --n;
+ }
+
+ return s;
+}
+#endif
+
+#if NEED_MEMCPY
+void* memcpy(void *dst, const void* src, size_t n)
+{
+ unsigned char* d = (unsigned char*) dst;
+ const unsigned char* s = (const unsigned char*) src;
+
+ while (n > 0) {
+ *d++ = *s++;
+ --n;
+ }
+
+ return dst;
+}
+#endif
+
+
+#if NEED_CMP
+int memcmp(const void *s1_, const void *s2_, size_t n)
+{
+ const signed char *s1 = s1_, *s2 = s2_;
+
+ while (n > 0) {
+ int cmp = *s1 - *s2;
+ if (cmp != 0)
+ return cmp;
+ ++s1;
+ ++s2;
+ }
+
+ return 0;
+}
+#endif
+
+
+#if NEED_STRLEN
+size_t strlen(const char* s)
+{
+ size_t len = 0;
+ while (*s++ != '\0')
+ ++len;
+ return len;
+}
+#endif
+
+
+
+#if NEED_STRNLEN
+/*
+ * This it a GNU extension.
+ * It is like strlen(), but it will check at most maxlen
+ * characters for the terminating nul character,
+ * returning maxlen if it doesn't find a nul.
+ * This is very useful for checking the length of untrusted
+ * strings (e.g., from user space).
+ */
+size_t strnlen(const char *s, size_t maxlen)
+{
+ size_t len = 0;
+ while (len < maxlen && *s++ != '\0')
+ ++len;
+ return len;
+}
+#endif
+
+
+#if NEED_STRCMP
+int strcmp(const char* s1, const char* s2)
+{
+ while (1) {
+ int cmp = *s1 - *s2;
+ if (cmp != 0 || *s1 == '\0' || *s2 == '\0')
+ return cmp;
+ ++s1;
+ ++s2;
+ }
+}
+#endif
+
+
+#if NEED_STRNCMP
+int strncmp(const char* s1, const char* s2, size_t limit)
+{
+ size_t i = 0;
+ while (i < limit) {
+ int cmp = *s1 - *s2;
+ if (cmp != 0 || *s1 == '\0' || *s2 == '\0')
+ return cmp;
+ ++s1;
+ ++s2;
+ ++i;
+ }
+
+ /* limit reached and equal */
+ return 0;
+}
+#endif
+
+
+#if NEED_STRCAT
+char *strcat(char *s1, const char *s2)
+{
+ char *t1;
+
+ t1 = s1;
+ while (*s1) s1++;
+ while(*s2) *s1++ = *s2++;
+ *s1 = '\0';
+
+ return t1;
+}
+#endif
+
+
+#if NEED_STRNCAT
+char *strncat(char *s1, const char *s2, size_t limit)
+{
+ size_t i = 0;
+ char *t1;
+ t1 = s1;
+ while (*s1) s1++;
+ while (i < limit) {
+ if(*s2 == '\0') break;
+ *s1++ = *s2++;
+ }
+ *s1 = '\0';
+ return t1;
+}
+#endif
+
+
+
+#if NEED_STRCPY
+char *strcpy(char *dest, const char *src)
+{
+ char *ret = dest;
+
+ while (*src) {
+ *dest++ = *src++;
+ }
+ *dest = '\0';
+
+ return ret;
+}
+#endif
+
+
+#if NEED_STRNCPY
+char *strncpy(char *dest, const char *src, size_t limit)
+{
+ char *ret = dest;
+
+ while (*src != '\0' && limit > 0) {
+ *dest++ = *src++;
+ --limit;
+ }
+ if (limit > 0)
+ *dest = '\0';
+
+ return ret;
+}
+#endif
+
+
+
+#if NEED_STRDUP
+char *strdup(const char *s1)
+{
+ char *ret;
+
+ ret = V3_Malloc(strlen(s1) + 1);
+ strcpy(ret, s1);
+
+ return ret;
+}
+#endif
+
+
+
+
+#if NEED_ATOI
+int atoi(const char *buf)
+{
+ int ret = 0;
+
+ while (*buf >= '0' && *buf <= '9') {
+ ret *= 10;
+ ret += *buf - '0';
+ buf++;
+ }
+
+ return ret;
+}
+#endif
+
+
+#if NEED_STRCHR
+char *strchr(const char *s, int c)
+{
+ while (*s != '\0') {
+ if (*s == c)
+ return (char *) s;
+ ++s;
+ }
+ return 0;
+}
+#endif
+
+
+#if NEED_STRRCHR
+char *strrchr(const char *s, int c)
+{
+ size_t len = strlen(s);
+ const char *p = s + len;
+
+ while (p > s) {
+ --p;
+ if (*p == c)
+ return (char*) p;
+ }
+ return 0;
+}
+#endif
+
+#if NEED_STRPBRK
+char *strpbrk(const char *s, const char *accept)
+{
+ size_t setLen = strlen(accept);
+
+ while (*s != '\0') {
+ size_t i;
+ for (i = 0; i < setLen; ++i) {
+ if (*s == accept[i])
+ return (char *) s;
+ }
+ ++s;
+ }
+
+ return 0;
+}
+#endif
+