rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

argv.c
Go to the documentation of this file.
1
5 #include "system.h"
6
7 #include "rpmio_internal.h" /* XXX fdGetFILE() */
8 #include <argv.h>
9
10 #include "debug.h"
11
12 /*@access FD_t @*/ /* XXX fdGetFILE() */
13
14 void argvPrint(const char * msg, ARGV_t argv, FILE * fp)
15 {
16 ARGV_t av;
17
18 if (fp == NULL) fp = stderr;
19
20 if (msg)
21 fprintf(fp, "===================================== %s\n", msg);
22
23 if (argv)
24 for (av = argv; *av; av++)
25 fprintf(fp, "\t%s\n", *av);
26
27 }
28
29 ARGI_t argiFree(ARGI_t argi)
30 {
31 if (argi) {
32 argi->nvals = 0;
33 argi->vals = _free(argi->vals);
34 }
35 argi = _free(argi);
36 return NULL;
37 }
38
39 ARGV_t argvFree(/*@only@*/ /*@null@*/ ARGV_t argv)
40 {
41 ARGV_t av;
42
43 if (argv)
44 for (av = argv; *av; av++)
45 *av = _free(*av);
46 argv = _free(argv);
47 return NULL;
48 }
49
50 int argiCount(ARGI_t argi)
51 {
52 int nvals = 0;
53 if (argi)
54 nvals = argi->nvals;
55 return nvals;
56 }
57
58 ARGint_t argiData(ARGI_t argi)
59 {
60 ARGint_t vals = NULL;
61 if (argi && argi->nvals > 0)
62 vals = argi->vals;
63 return vals;
64 }
65
66 int argvCount(const ARGV_t argv)
67 {
68 int argc = 0;
69 if (argv)
70 while (argv[argc] != NULL)
71 argc++;
72 return argc;
73 }
74
75 ARGV_t argvData(ARGV_t argv)
76 {
77 /*@-retalias -temptrans @*/
78 return argv;
79 /*@=retalias =temptrans @*/
80 }
81
82 int argiCmp(const void * a, const void * b)
83 {
84 unsigned aint = *(ARGint_t)a;
85 unsigned bint = *(ARGint_t)b;
86 return ((aint < bint) ? -1 :
87 (aint > bint) ? +1 : 0);
88 }
89
90 int argvCmp(const void * a, const void * b)
91 {
92 ARGstr_t astr = *(ARGV_t)a;
93 ARGstr_t bstr = *(ARGV_t)b;
94 return strcmp(astr, bstr);
95 }
96
97 int argvStrcasecmp(const void * a, const void * b)
98 {
99 ARGstr_t astr = *(ARGV_t)a;
100 ARGstr_t bstr = *(ARGV_t)b;
101 return xstrcasecmp(astr, bstr);
102 }
103
104 #if defined(RPM_VENDOR_OPENPKG) /* wildcard-matching-arbitrary-tagnames */
105 int argvFnmatch(const void * a, const void * b)
106 {
107 ARGstr_t astr = *(ARGV_t)a;
108 ARGstr_t bstr = *(ARGV_t)b;
109 return (fnmatch(astr, bstr, 0) == 0 ? 0 : 1);
110 }
111
112 int argvFnmatchCasefold(const void * a, const void * b)
113 {
114 ARGstr_t astr = *(ARGV_t)a;
115 ARGstr_t bstr = *(ARGV_t)b;
116 return (fnmatch(astr, bstr, FNM_CASEFOLD) == 0 ? 0 : 1);
117 }
118 #endif
119
120 int argiSort(ARGI_t argi, int (*compar)(const void *, const void *))
121 {
122 unsigned nvals = argiCount(argi);
123 ARGint_t vals = argiData(argi);
124 if (compar == NULL)
125 compar = argiCmp;
126 if (nvals > 1)
127 qsort(vals, nvals, sizeof(*vals), compar);
128 return 0;
129 }
130
131 int argvSort(ARGV_t argv, int (*compar)(const void *, const void *))
132 {
133 if (compar == NULL)
134 compar = argvCmp;
135 qsort(argv, argvCount(argv), sizeof(*argv), compar);
136 return 0;
137 }
138
139 ARGV_t argvSearch(ARGV_t argv, ARGstr_t val,
140 int (*compar)(const void *, const void *))
141 {
142 if (argv == NULL)
143 return NULL;
144 if (compar == NULL)
145 compar = argvCmp;
146 return bsearch(&val, argv, argvCount(argv), sizeof(*argv), compar);
147 }
148
149 #if defined(RPM_VENDOR_OPENPKG) /* wildcard-matching-arbitrary-tagnames */
150 ARGV_t argvSearchLinear(ARGV_t argv, ARGstr_t val,
151 int (*compar)(const void *, const void *))
152 {
153 ARGV_t result;
154 ARGV_t av;
155 if (argv == NULL)
156 return NULL;
157 if (compar == NULL)
158 compar = argvCmp;
159 result = NULL;
160 for (av = argv; *av != NULL; av++) {
161 if (compar(av, &val) == 0) {
162 result = av;
163 break;
164 }
165 }
166 return result;
167 }
168 #endif
169
170 int argiAdd(/*@out@*/ ARGI_t * argip, int ix, int val)
171 {
172 ARGI_t argi;
173
174 if (argip == NULL)
175 return -1;
176 if (*argip == NULL)
177 *argip = xcalloc(1, sizeof(**argip));
178 argi = *argip;
179 if (ix < 0)
180 ix = argi->nvals;
181 if (ix >= (int)argi->nvals) {
182 argi->vals = xrealloc(argi->vals, (ix + 1) * sizeof(*argi->vals));
183 memset(argi->vals + argi->nvals, 0,
184 (ix - argi->nvals) * sizeof(*argi->vals));
185 argi->nvals = ix + 1;
186 }
187 argi->vals[ix] = val;
188 return 0;
189 }
190
191 int argvAdd(/*@out@*/ ARGV_t * argvp, ARGstr_t val)
192 {
193 ARGV_t argv;
194 int argc;
195
196 if (argvp == NULL)
197 return -1;
198 argc = argvCount(*argvp);
199 /*@-unqualifiedtrans@*/
200 *argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp));
201 /*@=unqualifiedtrans@*/
202 argv = *argvp;
203 argv[argc++] = xstrdup(val);
204 argv[argc ] = NULL;
205 return 0;
206 }
207
208 int argvAppend(/*@out@*/ ARGV_t * argvp, ARGV_t av)
209 {
210 int ac = argvCount(av);
211
212 if (av != NULL && ac > 0) {
213 ARGV_t argv = *argvp;
214 int argc = argvCount(argv);
215
216 argv = xrealloc(argv, (argc + ac + 1) * sizeof(*argv));
217 while (*av++)
218 argv[argc++] = xstrdup(av[-1]);
219 argv[argc] = NULL;
220 *argvp = argv;
221 }
222 return 0;
223 }
224
225 int argvSplit(ARGV_t * argvp, const char * str, const char * seps)
226 {
227 static char whitespace[] = " \f\n\r\t\v";
228 char * dest = xmalloc(strlen(str) + 1);
229 ARGV_t argv;
230 int argc = 1;
231 const char * s;
232 char * t;
233 int c;
234
235 if (seps == NULL)
236 seps = whitespace;
237
238 for (argc = 1, s = str, t = dest; (c = (int) *s); s++, t++) {
239 if (strchr(seps, c) && !(s[0] == ':' && s[1] == '/' && s[2] == '/')) {
240 argc++;
241 c = (int) '\0';
242 }
243 *t = (char) c;
244 }
245 *t = '\0';
246
247 argv = xmalloc( (argc + 1) * sizeof(*argv));
248
249 for (c = 0, s = dest; s < t; s += strlen(s) + 1) {
250 /* XXX Skip repeated seperators (i.e. whitespace). */
251 if (seps == whitespace && s[0] == '\0')
252 continue;
253 argv[c++] = xstrdup(s);
254 }
255 argv[c] = NULL;
256 if (argvp)
257 *argvp = argv;
258 else
259 argv = argvFree(argv);
260 dest = _free(dest);
261 /*@-nullstate@*/
262 return 0;
263 /*@=nullstate@*/
264 }
265
266 char * argvJoin(ARGV_t argv)
267 {
268 size_t nb = 0;
269 int argc;
270 char *t, *te;
271
272 for (argc = 0; argv[argc] != NULL; argc++) {
273 if (argc != 0)
274 nb++;
275 nb += strlen(argv[argc]);
276 }
277 nb++;
278
279 te = t = xmalloc(nb);
280 *te = '\0';
281 for (argc = 0; argv[argc] != NULL; argc++) {
282 if (argc != 0)
283 *te++ = ' ';
284 te = stpcpy(te, argv[argc]);
285 }
286 *te = '\0';
287 return t;
288 }
289
290 /*@-mustmod@*/
291 int argvFgets(ARGV_t * argvp, void * fd)
292 {
293 FILE * fp = (fd ? fdGetFILE(fd) : stdin);
294 ARGV_t av = NULL;
295 char buf[BUFSIZ];
296 char * b, * be;
297 int rc = 0;
298
299 if (fp == NULL)
300 return -2;
301 while (!rc && (b = fgets(buf, (int)sizeof(buf), fp)) != NULL) {
302 buf[sizeof(buf)-1] = '\0';
303 be = b + strlen(buf);
304 if (be > b) be--;
305 while (strchr("\r\n", *be) != NULL)
306 *be-- = '\0';
307 rc = argvAdd(&av, b);
308 }
309
310 if (!rc)
311 rc = ferror(fp);
312 if (!rc)
313 rc = (feof(fp) ? 0 : 1);
314 if (!rc && argvp)
315 *argvp = av;
316 else
317 av = argvFree(av);
318
319 /*@-nullstate@*/ /* XXX *argvp may be NULL. */
320 return rc;
321 /*@=nullstate@*/
322 }
323 /*@=mustmod@*/