Modify eu-strip option to perform strip in post script of rpm package & add option...
[platform/upstream/rpm.git] / rpmio / argv.c
1 /** \ingroup rpmio
2  * \file rpmio/argv.c
3  */
4
5 #include "system.h"
6
7 #include <stdlib.h>
8 #include <rpm/argv.h>
9 #include <rpm/rpmstring.h>
10
11 #include "debug.h"
12
13 void argvPrint(const char * msg, ARGV_const_t argv, FILE * fp)
14 {
15     ARGV_const_t av;
16
17     if (fp == NULL) fp = stderr;
18
19     if (msg)
20         fprintf(fp, "===================================== %s\n", msg);
21
22     if (argv)
23     for (av = argv; *av; av++)
24         fprintf(fp, "%s\n", *av);
25
26 }
27
28 ARGV_t argvNew(void)
29 {
30     ARGV_t argv = xcalloc(1, sizeof(*argv));
31     return argv;
32 }
33
34 ARGI_t argiFree(ARGI_t argi)
35 {
36     if (argi) {
37         argi->nvals = 0;
38         free(argi->vals);
39         free(argi);
40     }
41     return NULL;
42 }
43
44 ARGV_t argvFree(ARGV_t argv)
45 {
46     if (argv) {
47         for (ARGV_t av = argv; *av; av++)
48             free(*av);
49         free(argv);
50     }
51     return NULL;
52 }
53
54 int argiCount(ARGI_const_t argi)
55 {
56     int nvals = 0;
57     if (argi)
58         nvals = argi->nvals;
59     return nvals;
60 }
61
62 ARGint_t argiData(ARGI_const_t argi)
63 {
64     ARGint_t vals = NULL;
65     if (argi && argi->nvals > 0)
66         vals = argi->vals;
67     return vals;
68 }
69
70 int argvCount(ARGV_const_t argv)
71 {
72     int argc = 0;
73     if (argv)
74     while (argv[argc] != NULL)
75         argc++;
76     return argc;
77 }
78
79 ARGV_t argvData(ARGV_t argv)
80 {
81     return argv;
82 }
83
84 int argvCmp(const void * a, const void * b)
85 {
86     const char *astr = *(ARGV_t)a;
87     const char *bstr = *(ARGV_t)b;
88     return strcmp(astr, bstr);
89 }
90
91 int argvSort(ARGV_t argv, int (*compar)(const void *, const void *))
92 {
93     if (compar == NULL)
94         compar = argvCmp;
95     qsort(argv, argvCount(argv), sizeof(*argv), compar);
96     return 0;
97 }
98
99 ARGV_t argvSearch(ARGV_const_t argv, const char *val,
100                 int (*compar)(const void *, const void *))
101 {
102     if (argv == NULL)
103         return NULL;
104     if (compar == NULL)
105         compar = argvCmp;
106     return bsearch(&val, argv, argvCount(argv), sizeof(*argv), compar);
107 }
108
109 int argiAdd(ARGI_t * argip, int ix, int val)
110 {
111     ARGI_t argi;
112
113     if (argip == NULL)
114         return -1;
115     if (*argip == NULL)
116         *argip = xcalloc(1, sizeof(**argip));
117     argi = *argip;
118     if (ix < 0)
119         ix = argi->nvals;
120     if (ix >= argi->nvals) {
121         argi->vals = xrealloc(argi->vals, (ix + 1) * sizeof(*argi->vals));
122         memset(argi->vals + argi->nvals, 0,
123                 (ix - argi->nvals) * sizeof(*argi->vals));
124         argi->nvals = ix + 1;
125     }
126     argi->vals[ix] = val;
127     return 0;
128 }
129
130 int argvAdd(ARGV_t * argvp, const char *val)
131 {
132     ARGV_t argv;
133     int argc;
134
135     if (argvp == NULL)
136         return -1;
137     argc = argvCount(*argvp);
138     *argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp));
139     argv = *argvp;
140     argv[argc++] = xstrdup(val);
141     argv[argc  ] = NULL;
142     return 0;
143 }
144
145 int argvAddNum(ARGV_t *argvp, int val)
146 {
147     char *valstr = NULL;
148     int rc;
149     rasprintf(&valstr, "%d", val);
150     rc = argvAdd(argvp, valstr);
151     free(valstr);
152     return rc;
153 }
154
155 int argvAppend(ARGV_t * argvp, ARGV_const_t av)
156 {
157     ARGV_t argv = *argvp;
158     int argc = argvCount(argv);
159     int ac = argvCount(av);
160     int i;
161
162     argv = xrealloc(argv, (argc + ac + 1) * sizeof(*argv));
163     for (i = 0; i < ac; i++)
164         argv[argc + i] = xstrdup(av[i]);
165     argv[argc + ac] = NULL;
166     *argvp = argv;
167     return 0;
168 }
169
170 ARGV_t argvSplitString(const char * str, const char * seps, argvFlags flags)
171 {
172     char *dest = NULL;
173     ARGV_t argv;
174     int argc = 1;
175     const char * s;
176     char * t;
177     int c;
178
179     if (str == NULL || seps == NULL)
180         return NULL;
181
182     dest = xmalloc(strlen(str) + 1);
183     for (argc = 1, s = str, t = dest; (c = *s); s++, t++) {
184         if (strchr(seps, c)) {
185             argc++;
186             c = '\0';
187         }
188         *t = c;
189     }
190     *t = '\0';
191
192     argv = xmalloc( (argc + 1) * sizeof(*argv));
193
194     for (c = 0, s = dest; s < t; s+= strlen(s) + 1) {
195         if (*s == '\0' && (flags & ARGV_SKIPEMPTY))
196             continue;
197         argv[c] = xstrdup(s);
198         c++;
199     }
200     argv[c] = NULL;
201     free(dest);
202     return argv;
203 }
204
205 /* Backwards compatibility */
206 int argvSplit(ARGV_t * argvp, const char * str, const char * seps)
207 {
208     if (argvp) {
209         *argvp = argvSplitString(str, seps, ARGV_SKIPEMPTY);
210     }
211     return 0;
212 }
213
214 char *argvJoin(ARGV_const_t argv, const char *sep)
215 {
216     char *dest = NULL;
217     char * const *arg;
218
219     for (arg = argv; arg && *arg; arg++) {
220         rstrscat(&dest, *arg, *(arg+1) ? sep : "", NULL);
221     } 
222     return dest;
223 }
224