/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*//*** This file is part of systemd. Copyright 2010 Lennart Poettering systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. systemd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with systemd; If not, see <http://www.gnu.org/licenses/>.***/

char*strv_find(char**l,constchar*name){char**i;assert(name);STRV_FOREACH(i,l)if(streq(*i,name))return*i;returnNULL;}char*strv_find_prefix(char**l,constchar*name){char**i;assert(name);STRV_FOREACH(i,l)if(startswith(*i,name))return*i;returnNULL;}char*strv_find_startswith(char**l,constchar*name){char**i,*e;assert(name);/* Like strv_find_prefix, but actually returns only the * suffix, not the whole item */STRV_FOREACH(i,l){e=startswith(*i,name);if(e)returne;}returnNULL;}

char**strv_copy(char*const*l){char**r,**k;k=r=new(char*,strv_length(l)+1);if(!r)returnNULL;if(l)for(;*l;k++,l++){*k=strdup(*l);if(!*k){strv_free(r);returnNULL;}}*k=NULL;returnr;}unsignedstrv_length(char*const*l){unsignedn=0;if(!l)return0;for(;*l;l++)n++;returnn;}char**strv_new_ap(constchar*x,va_listap){constchar*s;char**a;unsignedn=0,i=0;va_listaq;/* As a special trick we ignore all listed strings that equal * (const char*) -1. This is supposed to be used with the * STRV_IFNOTNULL() macro to include possibly NULL strings in * the string list. */if(x){n=x==(constchar*)-1?0:1;va_copy(aq,ap);while((s=va_arg(aq,constchar*))){if(s==(constchar*)-1)continue;n++;}va_end(aq);}a=new(char*,n+1);if(!a)returnNULL;if(x){if(x!=(constchar*)-1){a[i]=strdup(x);if(!a[i])gotofail;i++;}while((s=va_arg(ap,constchar*))){if(s==(constchar*)-1)continue;a[i]=strdup(s);if(!a[i])gotofail;i++;}}a[i]=NULL;returna;fail:strv_free(a);returnNULL;}char**strv_new(constchar*x,...){char**r;va_listap;va_start(ap,x);r=strv_new_ap(x,ap);va_end(ap);returnr;}

}intstrv_extend_strv_concat(char***a,char**b,constchar*suffix){intr;char**s;STRV_FOREACH(s,b){char*v;v=strappend(*s,suffix);if(!v)return-ENOMEM;r=strv_push(a,v);if(r<0){free(v);returnr;}}return0;}char**strv_split(constchar*s,constchar*separator){constchar*word,*state;size_tl;unsignedn,i;char**r;assert(s);n=0;FOREACH_WORD_SEPARATOR(word,l,s,separator,state)n++;r=new(char*,n+1);if(!r)returnNULL;i=0;FOREACH_WORD_SEPARATOR(word,l,s,separator,state){r[i]=strndup(word,l);if(!r[i]){strv_free(r);returnNULL;}i++;}r[i]=NULL;returnr;}char**strv_split_newlines(constchar*s){char**l;unsignedn;assert(s);/* Special version of strv_split() that splits on newlines and * suppresses an empty string at the end */l=strv_split(s,NEWLINE);if(!l)returnNULL;n=strv_length(l);if(n<=0)returnl;

char*strv_join(char**l,constchar*separator){char*r,*e;char**s;size_tn,k;if(!separator)separator=" ";k=strlen(separator);n=0;STRV_FOREACH(s,l){if(n!=0)n+=k;n+=strlen(*s);}r=new(char,n+1);if(!r)returnNULL;e=r;STRV_FOREACH(s,l){if(e!=r)e=stpcpy(e,separator);e=stpcpy(e,*s);}*e=0;returnr;}char*strv_join_quoted(char**l){char*buf=NULL;char**s;size_tallocated=0,len=0;STRV_FOREACH(s,l){/* assuming here that escaped string cannot be more * than twice as long, and reserving space for the * separator and quotes. */_cleanup_free_char*esc=NULL;size_tneeded;if(!GREEDY_REALLOC(buf,allocated,len+strlen(*s)*2+3))gotooom;esc=cescape(*s);if(!esc)gotooom;needed=snprintf(buf+len,allocated-len,"%s\"%s\"",len>0?" ":"",esc);assert(needed<allocated-len);len+=needed;}if(!buf)buf=malloc0(1);returnbuf;oom:free(buf);returnNULL;}intstrv_push(char***l,char*value){char**c;unsignedn,m;if(!value)return0;n=strv_length(*l);

char**strv_shell_escape(char**l,constchar*bad){char**s;/* Escapes every character in every string in l that is in bad, * edits in-place, does not roll-back on error. */STRV_FOREACH(s,l){char*v;v=shell_escape(*s,bad);if(!v)returnNULL;free(*s);*s=v;}returnl;}