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