/src/common/split.c
C | 165 lines | 87 code | 29 blank | 49 comment | 41 complexity | 61936cbed53afac9c19ac61790b6ee9e MD5 | raw file
1/*****************************************************************************\ 2 * $Id$ 3 ***************************************************************************** 4 * Copyright (C) 2006 The Regents of the University of California. 5 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). 6 * Written by Jim Garlick <garlick@llnl.gov>. 7 * UCRL-CODE-2003-005. 8 * 9 * This file is part of Pdsh, a parallel remote shell program. 10 * For details, see <http://www.llnl.gov/linux/pdsh/>. 11 * 12 * Pdsh is free software; you can redistribute it and/or modify it under 13 * the terms of the GNU General Public License as published by the Free 14 * Software Foundation; either version 2 of the License, or (at your option) 15 * any later version. 16 * 17 * Pdsh is distributed in the hope that it will be useful, but WITHOUT ANY 18 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 19 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 20 * details. 21 * 22 * You should have received a copy of the GNU General Public License along 23 * with Pdsh; if not, write to the Free Software Foundation, Inc., 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 25\*****************************************************************************/ 26 27#if HAVE_CONFIG_H 28# include <config.h> 29#endif 30 31#include <string.h> 32#include <stdio.h> 33#include <stdlib.h> 34#include "xmalloc.h" 35#include "split.h" 36 37/* 38 * Helper function for list_split(). Extract tokens from str. 39 * Return a pointer to the next token; at the same time, advance 40 * *str to point to the next separator. 41 * sep (IN) string containing list of separator characters 42 * str (IN) double-pointer to string containing tokens and separators 43 * RETURN next token 44 */ 45static char *_next_tok(char *sep, char **str) 46{ 47 char *tok; 48 int level = 0; 49 50 /* push str past any leading separators */ 51 while (**str != '\0' && strchr(sep, **str) != NULL) 52 (*str)++; 53 54 if (**str == '\0') 55 return NULL; 56 57 /* assign token pointer */ 58 tok = *str; 59 60 /* push str past token and leave pointing to first separator, 61 ignoring separators between any '[]' */ 62 while (**str != '\0' && (level != 0 || strchr(sep, **str) == NULL)) { 63 if (**str == '[') 64 level++; 65 else if (**str == ']') 66 level--; 67 (*str)++; 68 } 69 70 /* nullify consecutive separators and push str beyond them */ 71 while (**str != '\0' && strchr(sep, **str) != NULL) 72 *(*str)++ = '\0'; 73 74 return tok; 75} 76 77static void free_f (char *str) 78{ 79 Free ((void **) &str); 80} 81 82/* 83 * Given a list of separators and a string, generate a list 84 * sep (IN) string containing separater characters 85 * str (IN) string containing tokens and separators 86 * RETURN new list containing all tokens 87 */ 88List list_split(char *sep, char *str) 89{ 90 List new = list_create((ListDelF) free_f); 91 char *tok; 92 93 if (sep == NULL) 94 sep = " \t"; 95 96 while ((tok = _next_tok(sep, &str)) != NULL) { 97 if (strlen(tok) > 0) 98 list_append(new, Strdup(tok)); 99 } 100 101 return new; 102} 103 104List list_split_append (List l, char *sep, char *str) 105{ 106 char *tok; 107 108 if (l == NULL) 109 return (list_split (sep, str)); 110 111 if (sep == NULL) 112 sep = " \t"; 113 114 while ((tok = _next_tok(sep, &str)) != NULL) { 115 if (strlen(tok) > 0) 116 list_append(l, Strdup(tok)); 117 } 118 119 return l; 120} 121 122int list_join (char *result, size_t len, const char *sep, List l) 123{ 124 char *str = NULL; 125 int n = 0; 126 int truncated = 0; 127 ListIterator i; 128 129 memset (result, 0, len); 130 131 if (list_count(l) == 0) 132 return (0); 133 134 i = list_iterator_create(l); 135 while ((str = list_next(i))) { 136 int count; 137 138 if (!truncated) { 139 count = snprintf(result + n, len - n, "%s%s", str, sep); 140 141 if ((count >= (len - n)) || (count < 0)) 142 truncated = 1; 143 else 144 n += count; 145 } 146 else 147 n += strlen (str) + strlen (sep); 148 } 149 list_iterator_destroy(i); 150 151 if (truncated) 152 result [len - 1] = '\0'; 153 else { 154 /* 155 * Delete final separator 156 */ 157 result[strlen(result) - strlen(sep)] = '\0'; 158 } 159 160 return (n); 161} 162 163/* vi: ts=4 sw=4 expandtab 164 */ 165