aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2010-04-29 17:44:46 +0530
committerAnthony Liguori <aliguori@us.ibm.com>2010-05-03 12:17:38 -0500
commita03f7874396c909562d35931d03eca79c5c7f708 (patch)
tree9622f33831ae13e3488fe7027e7f8a0c7e2e963a
parent405a549a160ce632826661902aebee71c2e196bb (diff)
virtio-9p: Add string manipulation support.
Add helpers to do string manipulation. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--hw/virtio-9p.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 10d832a7b4..97e9b04a60 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -21,6 +21,126 @@
int dotu = 1;
int debug_9p_pdu;
+static void v9fs_string_init(V9fsString *str)
+{
+ str->data = NULL;
+ str->size = 0;
+}
+
+static void v9fs_string_free(V9fsString *str)
+{
+ qemu_free(str->data);
+ str->data = NULL;
+ str->size = 0;
+}
+
+static void v9fs_string_null(V9fsString *str)
+{
+ v9fs_string_free(str);
+}
+
+static int number_to_string(void *arg, char type)
+{
+ unsigned int ret = 0;
+
+ switch (type) {
+ case 'u': {
+ unsigned int num = *(unsigned int *)arg;
+
+ do {
+ ret++;
+ num = num/10;
+ } while (num);
+ break;
+ }
+ default:
+ printf("Number_to_string: Unknown number format\n");
+ return -1;
+ }
+
+ return ret;
+}
+
+static int v9fs_string_alloc_printf(char **strp, const char *fmt, va_list ap)
+{
+ va_list ap2;
+ char *iter = (char *)fmt;
+ int len = 0;
+ int nr_args = 0;
+ char *arg_char_ptr;
+ unsigned int arg_uint;
+
+ /* Find the number of %'s that denotes an argument */
+ for (iter = strstr(iter, "%"); iter; iter = strstr(iter, "%")) {
+ nr_args++;
+ iter++;
+ }
+
+ len = strlen(fmt) - 2*nr_args;
+
+ if (!nr_args) {
+ goto alloc_print;
+ }
+
+ va_copy(ap2, ap);
+
+ iter = (char *)fmt;
+
+ /* Now parse the format string */
+ for (iter = strstr(iter, "%"); iter; iter = strstr(iter, "%")) {
+ iter++;
+ switch (*iter) {
+ case 'u':
+ arg_uint = va_arg(ap2, unsigned int);
+ len += number_to_string((void *)&arg_uint, 'u');
+ break;
+ case 's':
+ arg_char_ptr = va_arg(ap2, char *);
+ len += strlen(arg_char_ptr);
+ break;
+ case 'c':
+ len += 1;
+ break;
+ default:
+ fprintf(stderr,
+ "v9fs_string_alloc_printf:Incorrect format %c", *iter);
+ return -1;
+ }
+ iter++;
+ }
+
+alloc_print:
+ *strp = qemu_malloc((len + 1) * sizeof(**strp));
+
+ return vsprintf(*strp, fmt, ap);
+}
+
+static void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...)
+{
+ va_list ap;
+ int err;
+
+ v9fs_string_free(str);
+
+ va_start(ap, fmt);
+ err = v9fs_string_alloc_printf(&str->data, fmt, ap);
+ BUG_ON(err == -1);
+ va_end(ap);
+
+ str->size = err;
+}
+
+static void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs)
+{
+ v9fs_string_free(lhs);
+ v9fs_string_sprintf(lhs, "%s", rhs->data);
+}
+
+static size_t v9fs_string_size(V9fsString *str)
+{
+ return str->size;
+}
+
static V9fsPDU *alloc_pdu(V9fsState *s)
{
V9fsPDU *pdu = NULL;
@@ -311,6 +431,13 @@ static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu)
* They will be removed in the subsequent patches */
(void)pdu_unmarshal;
(void) complete_pdu;
+ (void) v9fs_string_init;
+ (void) v9fs_string_free;
+ (void) v9fs_string_null;
+ (void) v9fs_string_sprintf;
+ (void) v9fs_string_copy;
+ (void) v9fs_string_size;
+
}
static void v9fs_version(V9fsState *s, V9fsPDU *pdu)