rpm  4.5
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 /*@-bounds@*/
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, "%s\n", *av);
26 
27 }
28 
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 /*@-branchstate@*/
44  if (argv)
45  for (av = argv; *av; av++)
46  *av = _free(*av);
47 /*@=branchstate@*/
48  argv = _free(argv);
49  return NULL;
50 }
51 
52 int argiCount(ARGI_t argi)
53 {
54  int nvals = 0;
55  if (argi)
56  nvals = argi->nvals;
57  return nvals;
58 }
59 
61 {
62  ARGint_t vals = NULL;
63  if (argi && argi->nvals > 0)
64  vals = argi->vals;
65  return vals;
66 }
67 
68 int argvCount(const ARGV_t argv)
69 {
70  int argc = 0;
71  if (argv)
72  while (argv[argc] != NULL)
73  argc++;
74  return argc;
75 }
76 
78 {
79 /*@-retalias -temptrans @*/
80  return argv;
81 /*@=retalias =temptrans @*/
82 }
83 
84 int argvCmp(const void * a, const void * b)
85 {
86 /*@-boundsread@*/
87  ARGstr_t astr = *(ARGV_t)a;
88  ARGstr_t bstr = *(ARGV_t)b;
89 /*@=boundsread@*/
90  return strcmp(astr, bstr);
91 }
92 
93 int argvSort(ARGV_t argv, int (*compar)(const void *, const void *))
94 {
95  if (compar == NULL)
96  compar = argvCmp;
97  qsort(argv, argvCount(argv), sizeof(*argv), compar);
98  return 0;
99 }
100 
102  int (*compar)(const void *, const void *))
103 {
104  if (argv == NULL)
105  return NULL;
106  if (compar == NULL)
107  compar = argvCmp;
108  return bsearch(&val, argv, argvCount(argv), sizeof(*argv), compar);
109 }
110 
111 int argiAdd(/*@out@*/ ARGI_t * argip, int ix, int val)
112 {
113  ARGI_t argi;
114 
115  if (argip == NULL)
116  return -1;
117  if (*argip == NULL)
118  *argip = xcalloc(1, sizeof(**argip));
119  argi = *argip;
120  if (ix < 0)
121  ix = argi->nvals;
122  if (ix >= argi->nvals) {
123  argi->vals = xrealloc(argi->vals, (ix + 1) * sizeof(*argi->vals));
124  memset(argi->vals + argi->nvals, 0,
125  (ix - argi->nvals) * sizeof(*argi->vals));
126  argi->nvals = ix + 1;
127  }
128  argi->vals[ix] = val;
129  return 0;
130 }
131 
132 int argvAdd(/*@out@*/ ARGV_t * argvp, ARGstr_t val)
133 {
134  ARGV_t argv;
135  int argc;
136 
137  if (argvp == NULL)
138  return -1;
139  argc = argvCount(*argvp);
140 /*@-unqualifiedtrans@*/
141  *argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp));
142 /*@=unqualifiedtrans@*/
143  argv = *argvp;
144  argv[argc++] = xstrdup(val);
145  argv[argc ] = NULL;
146  return 0;
147 }
148 
149 int argvAppend(/*@out@*/ ARGV_t * argvp, const ARGV_t av)
150 {
151  ARGV_t argv = *argvp;
152  int argc = argvCount(argv);
153  int ac = argvCount(av);
154  int i;
155 
156  argv = xrealloc(argv, (argc + ac + 1) * sizeof(*argv));
157  for (i = 0; i < ac; i++)
158  argv[argc + i] = xstrdup(av[i]);
159  argv[argc + ac] = NULL;
160  *argvp = argv;
161  return 0;
162 }
163 
164 int argvSplit(ARGV_t * argvp, const char * str, const char * seps)
165 {
166  static char whitespace[] = " \f\n\r\t\v";
167  char * dest = xmalloc(strlen(str) + 1);
168  ARGV_t argv;
169  int argc = 1;
170  const char * s;
171  char * t;
172  int c;
173 
174  if (seps == NULL)
175  seps = whitespace;
176 
177  for (argc = 1, s = str, t = dest; (c = *s); s++, t++) {
178  if (strchr(seps, c)) {
179  argc++;
180  c = '\0';
181  }
182  *t = c;
183  }
184  *t = '\0';
185 
186  argv = xmalloc( (argc + 1) * sizeof(*argv));
187 
188  for (c = 0, s = dest; s < t; s+= strlen(s) + 1) {
189  if (*s == '\0')
190  continue;
191  argv[c] = xstrdup(s);
192  c++;
193  }
194  argv[c] = NULL;
195  *argvp = argv;
196 /*@-nullstate@*/
197  return 0;
198 /*@=nullstate@*/
199 }
200 
201 char * argvJoin(ARGV_t argv)
202 {
203  size_t nb = 0;
204  int argc;
205  char *t, *te;
206 
207  for (argc = 0; argv[argc] != NULL; argc++) {
208  if (argc != 0)
209  nb++;
210  nb += strlen(argv[argc]);
211  }
212  nb++;
213 
214  te = t = xmalloc(nb);
215  *te = '\0';
216  for (argc = 0; argv[argc] != NULL; argc++) {
217  if (argc != 0)
218  *te++ = ' ';
219  te = stpcpy(te, argv[argc]);
220  }
221  *te = '\0';
222  return t;
223 }
224 
225 int argvFgets(ARGV_t * argvp, void * fd)
226 {
227  FILE * fp = (fd ? fdGetFILE(fd) : stdin);
228  ARGV_t av = NULL;
229  char buf[BUFSIZ];
230  char * b, * be;
231  int rc = 0;
232 
233  if (fp == NULL)
234  return -2;
235  while (!rc && (b = fgets(buf, sizeof(buf), fp)) != NULL) {
236  buf[sizeof(buf)-1] = '\0';
237  be = b + strlen(buf);
238  if (be > b) be--;
239  while (strchr("\r\n", *be) != NULL)
240  *be-- = '\0';
241  rc = argvAdd(&av, b);
242  }
243 
244  if (!rc)
245  rc = ferror(fp);
246  if (!rc)
247  rc = (feof(fp) ? 0 : 1);
248  if (!rc && argvp)
249  *argvp = av;
250  else
251  av = argvFree(av);
252 
253  return rc;
254 }
255 
256 /*@=bounds@*/