* New version 2.26
[alpine.git] / pith / list.c
blobde0dae0089b7460aa59d7432c2ed9febdf29e12e
1 /*
2 * ========================================================================
3 * Copyright 2006-2007 University of Washington
4 * Copyright 2013-2022 Eduardo Chappa
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
15 /*======================================================================
16 list.c
17 ====*/
20 #include "../pith/headers.h"
21 #include "../pith/list.h"
22 #include "../pith/string.h"
26 * Internal prototypes
31 * parse_list - takes a comma delimited list of "count" elements and
32 * returns an array of pointers to each element neatly
33 * malloc'd in its own array. Any errors are returned
34 * in the string pointed to by "error"
36 * If remove_surrounding_double_quotes is set, then double quotes around
37 * each element of the list are removed. We can't do this for all list
38 * variables. For example, incoming folders look like
39 * nickname foldername
40 * in the config file. Each of those may be quoted separately.
42 * NOTE: only recognizes escaped quotes
44 char **
45 parse_list(char *list, int count, int flags, char **error)
47 char **lvalue, *p2, *p3, *p4;
48 int was_quoted = 0;
49 int remove_surrounding_double_quotes;
50 int commas_may_be_escaped;
52 remove_surrounding_double_quotes = (flags & PL_REMSURRQUOT);
53 commas_may_be_escaped = (flags & PL_COMMAQUOTE);
55 lvalue = (char **) fs_get((count+1) * sizeof(char *));
56 count = 0;
57 while(*list){ /* pick elements from list */
58 p2 = list; /* find end of element */
59 while(1){
60 if(*p2 == '"') /* ignore ',' if quoted */
61 was_quoted = (was_quoted) ? 0 : 1 ;
63 if(*p2 == '\\' && *(p2+1) == '"')
64 p2++; /* preserve escaped quotes, too */
66 if((*p2 == ',' && !was_quoted) || *p2 == '\0')
67 break;
69 if(commas_may_be_escaped && *p2 == '\\' && *(p2+1) == ',')
70 p2++;
72 p2++;
75 if(was_quoted){ /* unbalanced quotes! */
76 if(error)
77 *error = "Unbalanced quotes";
79 break;
83 * if element found, eliminate trailing
84 * white space and tie into variable list
86 if(p2 != list){
87 for(p3 = p2 - 1; isspace((unsigned char) *p3) && list < p3; p3--)
90 p4 = fs_get(((p3 - list) + 2) * sizeof(char));
91 lvalue[count] = p4;
92 while(list <= p3)
93 *p4++ = *list++;
95 *p4 = '\0';
97 if(remove_surrounding_double_quotes)
98 removing_double_quotes(lvalue[count]);
100 count++;
103 if(*(list = p2) != '\0'){ /* move to beginning of next val */
104 while(*list == ',' || isspace((unsigned char)*list))
105 list++;
109 lvalue[count] = NULL; /* tie off pointer list */
110 return(lvalue);
115 * Free array of string pointers and associated strings
117 * Args: list -- array of char *'s
119 void
120 free_list_array(char ***list)
122 char **p;
124 if(list && *list){
125 for(p = *list; *p; p++)
126 fs_give((void **) p);
128 fs_give((void **) list);
134 * Copy array of string pointers and associated strings
136 * Args: list -- array of char *'s
138 * Returns: Allocated array of string pointers and allocated copies of strings.
139 * Caller should free the list array when done.
141 char **
142 copy_list_array(char **list)
144 int i, cnt = 0;
145 char **p, **ret_list = NULL;
147 if(list){
148 while(list[cnt++])
151 p = ret_list = (char **)fs_get((cnt+1) * sizeof(char *));
152 memset((void *) ret_list, 0, (cnt+1) * sizeof(char *));
154 for(i=0; list[i]; i++, p++)
155 *p = cpystr(list[i]);
157 *p = NULL;
161 return(ret_list);
166 equal_list_arrays(char **list1, char **list2)
168 int ret = 0;
170 if(list1 && list2){
171 while(*list1){
172 if(!*list2 || strcmp(*list1, *list2) != 0)
173 break;
175 list1++;
176 list2++;
179 if(*list1 == NULL && *list2 == NULL)
180 ret++;
183 return(ret);