source: trunk/third/rpm/rpmio/argv.c @ 19079

Revision 19079, 3.9 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19078, which included commits to RCS files with non-trunk default branches.
Line 
1/** \ingroup rpmio
2 * \file rpmio/argv.c
3 */
4
5#include "system.h"
6
7#include <argv.h>
8
9#include "debug.h"
10
11/*@-bounds@*/
12/**
13 * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
14 * @param p             memory to free
15 * @return              NULL always
16 */
17/*@unused@*/ static inline /*@null@*/
18void * _free(/*@only@*/ /*@null@*/ /*@out@*/ const void * p)
19        /*@modifies p @*/
20{
21    if (p != NULL)      free((void *)p);
22    return NULL;
23}
24
25void argvPrint(const char * msg, ARGV_t argv, FILE * fp)
26{
27    ARGV_t av;
28
29    if (fp == NULL) fp = stderr;
30
31    if (msg)
32        fprintf(fp, "===================================== %s\n", msg);
33
34    if (argv)
35    for (av = argv; *av; av++)
36        fprintf(fp, "%s\n", *av);
37
38}
39
40ARGI_t argiFree(ARGI_t argi)
41{
42    if (argi) {
43        argi->nvals = 0;
44        argi->vals = _free(argi->vals);
45    }
46    argi = _free(argi);
47    return NULL;
48}
49
50ARGV_t argvFree(/*@only@*/ /*@null@*/ ARGV_t argv)
51{
52    ARGV_t av;
53   
54/*@-branchstate@*/
55    if (argv)
56    for (av = argv; *av; av++)
57        *av = _free(*av);
58/*@=branchstate@*/
59    argv = _free(argv);
60    return NULL;
61}
62
63int argiCount(ARGI_t argi)
64{
65    int nvals = 0;
66    if (argi)
67        nvals = argi->nvals;
68    return nvals;
69}
70
71const ARGint_t argiData(const ARGI_t argi)
72{
73    ARGint_t vals = NULL;
74    if (argi && argi->nvals > 0)
75        vals = argi->vals;
76    return vals;
77}
78
79int argvCount(const ARGV_t argv)
80{
81    int argc = 0;
82    if (argv)
83    while (argv[argc] != NULL)
84        argc++;
85    return argc;
86}
87
88const ARGV_t argvData(const ARGV_t argv)
89{
90/*@-retalias -temptrans @*/
91    return argv;
92/*@=retalias =temptrans @*/
93}
94
95int argvCmp(const void * a, const void * b)
96{
97/*@-boundsread@*/
98    ARGstr_t astr = *(ARGV_t)a;
99    ARGstr_t bstr = *(ARGV_t)b;
100/*@=boundsread@*/
101    return strcmp(astr, bstr);
102}
103
104int argvSort(ARGV_t argv, int (*compar)(const void *, const void *))
105{
106    if (compar == NULL)
107        compar = argvCmp;
108    qsort(argv, argvCount(argv), sizeof(*argv), compar);
109    return 0;
110}
111
112ARGV_t argvSearch(ARGV_t argv, ARGstr_t val,
113                int (*compar)(const void *, const void *))
114{
115    if (argv == NULL)
116        return NULL;
117    if (compar == NULL)
118        compar = argvCmp;
119    return bsearch(&val, argv, argvCount(argv), sizeof(*argv), compar);
120}
121
122int argiAdd(/*@out@*/ ARGI_t * argip, int ix, int val)
123{
124    ARGI_t argi;
125
126    if (argip == NULL)
127        return -1;
128    if (*argip == NULL)
129        *argip = xcalloc(1, sizeof(**argip));
130    argi = *argip;
131    if (ix < 0)
132        ix = argi->nvals;
133    if (ix >= argi->nvals) {
134        argi->vals = xrealloc(argi->vals, (ix + 1) * sizeof(*argi->vals));
135        memset(argi->vals + argi->nvals, 0,
136                (ix - argi->nvals) * sizeof(*argi->vals));
137        argi->nvals = ix + 1;
138    }
139    argi->vals[ix] = val;
140    return 0;
141}
142
143int argvAdd(/*@out@*/ ARGV_t * argvp, ARGstr_t val)
144{
145    ARGV_t argv;
146    int argc;
147
148    if (argvp == NULL)
149        return -1;
150    argc = argvCount(*argvp);
151/*@-unqualifiedtrans@*/
152    *argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp));
153/*@=unqualifiedtrans@*/
154    argv = *argvp;
155    argv[argc++] = xstrdup(val);
156    argv[argc  ] = NULL;
157    return 0;
158}
159
160int argvAppend(/*@out@*/ ARGV_t * argvp, const ARGV_t av)
161{
162    ARGV_t argv = *argvp;
163    int argc = argvCount(argv);
164    int ac = argvCount(av);
165    int i;
166
167    argv = xrealloc(argv, (argc + ac + 1) * sizeof(*argv));
168    for (i = 0; i < ac; i++)
169        argv[argc + i] = xstrdup(av[i]);
170    argv[argc + ac] = NULL;
171    *argvp = argv;
172    return 0;
173}
174
175int argvSplit(ARGV_t * argvp, const char * str, const char * seps)
176{
177    char * dest = alloca(strlen(str) + 1);
178    ARGV_t argv;
179    int argc = 1;
180    const char * s;
181    char * t;
182    int c;
183
184    for (argc = 1, s = str, t = dest; (c = *s); s++, t++) {
185        if (strchr(seps, c)) {
186            argc++;
187            c = '\0';
188        }
189        *t = c;
190    }
191    *t = '\0';
192
193    argv = xmalloc( (argc + 1) * sizeof(*argv));
194
195    for (c = 0, s = dest; s < t; s+= strlen(s) + 1) {
196        if (*s == '\0')
197            continue;
198        argv[c] = xstrdup(s);
199        c++;
200    }
201    argv[c] = NULL;
202    *argvp = argv;
203/*@-nullstate@*/
204    return 0;
205/*@=nullstate@*/
206}
207/*@=bounds@*/
Note: See TracBrowser for help on using the repository browser.