PageRenderTime 28ms CodeModel.GetById 1ms app.highlight 21ms RepoModel.GetById 2ms app.codeStats 0ms

/src/common/split.c

https://code.google.com/
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