1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# str-list.c: define routines for string lists.
#
# Copyright (C) 1993, 2011 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#include "config.h"
#include "str-list.h"
/* See the .h file for comments. */
str_list_type
str_list_init P1H(void)
{
str_list_type ret;
STR_LIST_LENGTH (ret) = 0;
STR_LIST (ret) = NULL;
return ret;
}
void
str_list_add P2C(str_list_type *, l, string, s)
{
STR_LIST_LENGTH (*l)++;
XRETALLOC (STR_LIST (*l), STR_LIST_LENGTH (*l), string);
STR_LIST_LAST_ELT (*l) = s;
}
/* May as well save some reallocations and do everything in a chunk
instead of calling str_list_add on each element. */
void
str_list_concat P2C(str_list_type *, target, str_list_type, more)
{
unsigned e;
unsigned prev_len = STR_LIST_LENGTH (*target);
STR_LIST_LENGTH (*target) += STR_LIST_LENGTH (more);
XRETALLOC (STR_LIST (*target), STR_LIST_LENGTH (*target), string);
for (e = 0; e < STR_LIST_LENGTH (more); e++)
STR_LIST_ELT (*target, prev_len + e) = STR_LIST_ELT (more, e);
}
/* Concatenate the elements of more to each element of target. This
_must_ be done with the first index varying fastest. */
/* Note that we free the old elements of target as well. */
void
str_list_concat_elements P2C(str_list_type *, target, str_list_type, more)
{
if (STR_LIST_LENGTH(more) == 0) {
return;
} else if (STR_LIST_LENGTH(*target) == 0) {
unsigned int i;
STR_LIST_LENGTH(*target) = STR_LIST_LENGTH(more);
STR_LIST(*target) =
(string*)xmalloc(STR_LIST_LENGTH(more)*sizeof(char*));
for (i=0;i!=STR_LIST_LENGTH(more);++i) {
STR_LIST_ELT(*target,i)=xstrdup(STR_LIST_ELT(more,i));
}
return;
} else {
unsigned new_len;
char ** new_list;
unsigned int i,j;
new_list = (string*)xmalloc(STR_LIST_LENGTH (*target)
* STR_LIST_LENGTH (more) * sizeof(char*));
new_len = 0;
for (j = 0; j != STR_LIST_LENGTH(more); ++j) {
for (i = 0; i != STR_LIST_LENGTH(*target); ++i) {
new_list[new_len] = concat(STR_LIST_ELT(*target,i),
STR_LIST_ELT(more,j));
++new_len;
}
}
for (i = 0; i != STR_LIST_LENGTH(*target); ++i)
free(STR_LIST_ELT(*target, i));
free(STR_LIST(*target));
STR_LIST_LENGTH(*target) = new_len;
STR_LIST(*target) = new_list;
}
}
/* Free the list (but not the elements within it). */
void
str_list_free P1C(str_list_type *, l)
{
if (STR_LIST (*l))
{
free (STR_LIST (*l));
STR_LIST (*l) = NULL;
}
}
|