1/** 2 * \file 3 * \brief Parse function for format returned by get_names. 4 */ 5 6/* 7 * Copyright (c) 2014, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14#include <stdlib.h> 15#include <stdio.h> 16 17#include <barrelfish/barrelfish.h> 18#include <octopus/getset.h> 19 20#include "strnatcmp.h" 21 22static char* mystrdup(char* data) 23{ 24 25 char *p = malloc(strlen(data) + 1); 26 if (p == NULL) { 27 return NULL; 28 } 29 30 strcpy(p, data); 31 return p; 32} 33 34static int cmpstringp(const void *p1, const void *p2) 35{ 36 return strnatcmp(*(char * const *) p1, *(char * const *) p2); 37} 38 39/** 40 * \brief Parses output from get_names call and stores it in an array. 41 * 42 * \note Use oct_free_names() to free names array. 43 * 44 * \param[in] input Comma separated string of names 45 * \param[out] names Array of strings containing all names 46 * \param[out] len Size of array. 47 * 48 * \retval LIB_ERR_MALLOC_FAIL 49 * \retval SYS_ERR_OK 50 */ 51errval_t oct_parse_names(char* input, char*** names, size_t* len) 52{ 53 errval_t err = SYS_ERR_OK; 54 55 char *p = mystrdup(input); 56 if (p == NULL) { 57 err = LIB_ERR_MALLOC_FAIL; 58 goto out; 59 } 60 61 // first get the number of elements 62 char* saveptr = NULL; 63 size_t i; 64 char* tok = p; // just make sure it's non-null 65 char* first = p; 66 for (i = 0; tok != NULL; i++, first = NULL) { 67 tok = strtok(first, ","); 68 } 69 assert(p != NULL); 70 free(p); 71 p = NULL; 72 *len = --i; 73 74 *names = malloc(sizeof(char*) * i); 75 if (*names == NULL) { 76 *len = 0; 77 err = LIB_ERR_MALLOC_FAIL; 78 goto out; 79 } 80 memset(*names, 0, sizeof(char*) * i); 81 82 // now get the actual elements 83 saveptr = NULL; 84 tok = input; // just make sure it's non-null 85 first = input; 86 for (i = 0; tok != NULL; i++, first = NULL) { 87 tok = strtok(first, ", "); 88 if (tok != NULL) { 89 (*names)[i] = mystrdup(tok); 90 if ((*names)[i] == NULL) { 91 oct_free_names(*names, i); 92 *names = NULL; 93 *len = 0; 94 err = LIB_ERR_MALLOC_FAIL; 95 goto out; 96 } 97 } else { 98 break; 99 } 100 } 101 qsort(*names, *len, sizeof(char*), cmpstringp); 102 103out: 104 return err; 105} 106 107/** 108 * \brief Helper function to free an array of strings. 109 * 110 * Frees all entries of the array and the array itself. 111 * 112 * \param names Non-null array of strings. 113 * \param len Size of the names array 114 115 * \see oct_get_names 116 */ 117void oct_free_names(char** names, size_t len) 118{ 119 //assert(names != NULL); 120 for (size_t i = 0; i < len; i++) { 121 free(names[i]); 122 } 123 124 free(names); 125}