rpm 5.2.1

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

- File List
- Globals

rpmio/argv.c
Go to the documentation of this file.

    00001
    00005 #include "system.h"
    00006
    00007 #include "rpmio_internal.h"     /* XXX fdGetFILE() */
    00008 #include <argv.h>
    00009
    00010 #include "debug.h"
    00011
    00012 /*@access FD_t @*/              /* XXX fdGetFILE() */
    00013
    00014 void argvPrint(const char * msg, ARGV_t argv, FILE * fp)
    00015 {
    00016     ARGV_t av;
    00017
    00018     if (fp == NULL) fp = stderr;
    00019
    00020     if (msg)
    00021         fprintf(fp, "===================================== %s\n", msg);
    00022
    00023     if (argv)
    00024     for (av = argv; *av; av++)
    00025         fprintf(fp, "\t%s\n", *av);
    00026
    00027 }
    00028
    00029 ARGI_t argiFree(ARGI_t argi)
    00030 {
    00031     if (argi) {
    00032         argi->nvals = 0;
    00033         argi->vals = _free(argi->vals);
    00034     }
    00035     argi = _free(argi);
    00036     return NULL;
    00037 }
    00038
    00039 ARGV_t argvFree(/*@only@*/ /*@null@*/ ARGV_t argv)
    00040 {
    00041     ARGV_t av;
    00042
    00043     if (argv)
    00044     for (av = argv; *av; av++)
    00045         *av = _free(*av);
    00046     argv = _free(argv);
    00047     return NULL;
    00048 }
    00049
    00050 int argiCount(ARGI_t argi)
    00051 {
    00052     int nvals = 0;
    00053     if (argi)
    00054         nvals = argi->nvals;
    00055     return nvals;
    00056 }
    00057
    00058 ARGint_t argiData(ARGI_t argi)
    00059 {
    00060     ARGint_t vals = NULL;
    00061     if (argi && argi->nvals > 0)
    00062         vals = argi->vals;
    00063     return vals;
    00064 }
    00065
    00066 int argvCount(const ARGV_t argv)
    00067 {
    00068     int argc = 0;
    00069     if (argv)
    00070     while (argv[argc] != NULL)
    00071         argc++;
    00072     return argc;
    00073 }
    00074
    00075 ARGV_t argvData(ARGV_t argv)
    00076 {
    00077 /*@-retalias -temptrans @*/
    00078     return argv;
    00079 /*@=retalias =temptrans @*/
    00080 }
    00081
    00082 int argiCmp(const void * a, const void * b)
    00083 {
    00084     unsigned aint = *(ARGint_t)a;
    00085     unsigned bint = *(ARGint_t)b;
    00086     return ((aint < bint) ? -1 :
    00087             (aint > bint) ? +1 : 0);
    00088 }
    00089
    00090 int argvCmp(const void * a, const void * b)
    00091 {
    00092     ARGstr_t astr = *(ARGV_t)a;
    00093     ARGstr_t bstr = *(ARGV_t)b;
    00094     return strcmp(astr, bstr);
    00095 }
    00096
    00097 int argvStrcasecmp(const void * a, const void * b)
    00098 {
    00099     ARGstr_t astr = *(ARGV_t)a;
    00100     ARGstr_t bstr = *(ARGV_t)b;
    00101     return xstrcasecmp(astr, bstr);
    00102 }
    00103
    00104 #if defined(RPM_VENDOR_OPENPKG) /* wildcard-matching-arbitrary-tagnames */
    00105 int argvFnmatch(const void * a, const void * b)
    00106 {
    00107     ARGstr_t astr = *(ARGV_t)a;
    00108     ARGstr_t bstr = *(ARGV_t)b;
    00109     return (fnmatch(astr, bstr, 0) == 0 ? 0 : 1);
    00110 }
    00111
    00112 int argvFnmatchCasefold(const void * a, const void * b)
    00113 {
    00114     ARGstr_t astr = *(ARGV_t)a;
    00115     ARGstr_t bstr = *(ARGV_t)b;
    00116     return (fnmatch(astr, bstr, FNM_CASEFOLD) == 0 ? 0 : 1);
    00117 }
    00118 #endif
    00119
    00120 int argiSort(ARGI_t argi, int (*compar)(const void *, const void *))
    00121 {
    00122     unsigned nvals = argiCount(argi);
    00123     ARGint_t vals = argiData(argi);
    00124     if (compar == NULL)
    00125         compar = argiCmp;
    00126     if (nvals > 1)
    00127         qsort(vals, nvals, sizeof(*vals), compar);
    00128     return 0;
    00129 }
    00130
    00131 int argvSort(ARGV_t argv, int (*compar)(const void *, const void *))
    00132 {
    00133     if (compar == NULL)
    00134         compar = argvCmp;
    00135     qsort(argv, argvCount(argv), sizeof(*argv), compar);
    00136     return 0;
    00137 }
    00138
    00139 ARGV_t argvSearch(ARGV_t argv, ARGstr_t val,
    00140                 int (*compar)(const void *, const void *))
    00141 {
    00142     if (argv == NULL)
    00143         return NULL;
    00144     if (compar == NULL)
    00145         compar = argvCmp;
    00146     return bsearch(&val, argv, argvCount(argv), sizeof(*argv), compar);
    00147 }
    00148
    00149 #if defined(RPM_VENDOR_OPENPKG) /* wildcard-matching-arbitrary-tagnames */
    00150 ARGV_t argvSearchLinear(ARGV_t argv, ARGstr_t val,
    00151                 int (*compar)(const void *, const void *))
    00152 {
    00153     ARGV_t result;
    00154     ARGV_t av;
    00155     if (argv == NULL)
    00156         return NULL;
    00157     if (compar == NULL)
    00158         compar = argvCmp;
    00159     result = NULL;
    00160     for (av = argv; *av != NULL; av++) {
    00161         if (compar(av, &val) == 0) {
    00162             result = av;
    00163             break;
    00164         }
    00165     }
    00166     return result;
    00167 }
    00168 #endif
    00169
    00170 int argiAdd(/*@out@*/ ARGI_t * argip, int ix, int val)
    00171 {
    00172     ARGI_t argi;
    00173
    00174     if (argip == NULL)
    00175         return -1;
    00176     if (*argip == NULL)
    00177         *argip = xcalloc(1, sizeof(**argip));
    00178     argi = *argip;
    00179     if (ix < 0)
    00180         ix = argi->nvals;
    00181     if (ix >= (int)argi->nvals) {
    00182         argi->vals = xrealloc(argi->vals, (ix + 1) * sizeof(*argi->vals));
    00183         memset(argi->vals + argi->nvals, 0,
    00184                 (ix - argi->nvals) * sizeof(*argi->vals));
    00185         argi->nvals = ix + 1;
    00186     }
    00187     argi->vals[ix] = val;
    00188     return 0;
    00189 }
    00190
    00191 int argvAdd(/*@out@*/ ARGV_t * argvp, ARGstr_t val)
    00192 {
    00193     ARGV_t argv;
    00194     int argc;
    00195
    00196     if (argvp == NULL)
    00197         return -1;
    00198     argc = argvCount(*argvp);
    00199 /*@-unqualifiedtrans@*/
    00200     *argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp));
    00201 /*@=unqualifiedtrans@*/
    00202     argv = *argvp;
    00203     argv[argc++] = xstrdup(val);
    00204     argv[argc  ] = NULL;
    00205     return 0;
    00206 }
    00207
    00208 int argvAppend(/*@out@*/ ARGV_t * argvp, ARGV_t av)
    00209 {
    00210     int ac = argvCount(av);
    00211
    00212     if (av != NULL && ac > 0) {
    00213         ARGV_t argv = *argvp;
    00214         int argc = argvCount(argv);
    00215
    00216         argv = xrealloc(argv, (argc + ac + 1) * sizeof(*argv));
    00217         while (*av++)
    00218             argv[argc++] = xstrdup(av[-1]);
    00219         argv[argc] = NULL;
    00220         *argvp = argv;
    00221     }
    00222     return 0;
    00223 }
    00224
    00225 int argvSplit(ARGV_t * argvp, const char * str, const char * seps)
    00226 {
    00227     static char whitespace[] = " \f\n\r\t\v";
    00228     char * dest = xmalloc(strlen(str) + 1);
    00229     ARGV_t argv;
    00230     int argc = 1;
    00231     const char * s;
    00232     char * t;
    00233     int c;
    00234
    00235     if (seps == NULL)
    00236         seps = whitespace;
    00237
    00238     for (argc = 1, s = str, t = dest; (c = (int) *s); s++, t++) {
    00239         if (strchr(seps, c) && !(s[0] == ':' && s[1] == '/' && s[2] == '/')) {
    00240             argc++;
    00241             c = (int) '\0';
    00242         }
    00243         *t = (char) c;
    00244     }
    00245     *t = '\0';
    00246
    00247     argv = xmalloc( (argc + 1) * sizeof(*argv));
    00248
    00249     for (c = 0, s = dest; s < t; s += strlen(s) + 1) {
    00250         /* XXX Skip repeated seperators (i.e. whitespace). */
    00251         if (seps == whitespace && s[0] == '\0')
    00252             continue;
    00253         argv[c++] = xstrdup(s);
    00254     }
    00255     argv[c] = NULL;
    00256     if (argvp)
    00257         *argvp = argv;
    00258     else
    00259         argv = argvFree(argv);
    00260     dest = _free(dest);
    00261 /*@-nullstate@*/
    00262     return 0;
    00263 /*@=nullstate@*/
    00264 }
    00265
    00266 char * argvJoin(ARGV_t argv)
    00267 {
    00268     size_t nb = 0;
    00269     int argc;
    00270     char *t, *te;
    00271
    00272     for (argc = 0; argv[argc] != NULL; argc++) {
    00273         if (argc != 0)
    00274             nb++;
    00275         nb += strlen(argv[argc]);
    00276     }
    00277     nb++;
    00278
    00279     te = t = xmalloc(nb);
    00280     *te = '\0';
    00281     for (argc = 0; argv[argc] != NULL; argc++) {
    00282         if (argc != 0)
    00283             *te++ = ' ';
    00284         te = stpcpy(te, argv[argc]);
    00285     }
    00286     *te = '\0';
    00287     return t;
    00288 }
    00289
    00290 /*@-mustmod@*/
    00291 int argvFgets(ARGV_t * argvp, void * fd)
    00292 {
    00293     FILE * fp = (fd ? fdGetFILE(fd) : stdin);
    00294     ARGV_t av = NULL;
    00295     char buf[BUFSIZ];
    00296     char * b, * be;
    00297     int rc = 0;
    00298
    00299     if (fp == NULL)
    00300         return -2;
    00301     while (!rc && (b = fgets(buf, (int)sizeof(buf), fp)) != NULL) {
    00302         buf[sizeof(buf)-1] = '\0';
    00303         be = b + strlen(buf);
    00304         if (be > b) be--;
    00305         while (strchr("\r\n", *be) != NULL)
    00306             *be-- = '\0';
    00307         rc = argvAdd(&av, b);
    00308     }
    00309
    00310     if (!rc)
    00311         rc = ferror(fp);
    00312     if (!rc)
    00313         rc = (feof(fp) ? 0 : 1);
    00314     if (!rc && argvp)
    00315         *argvp = av;
    00316     else
    00317         av = argvFree(av);
    00318
    00319 /*@-nullstate@*/        /* XXX *argvp may be NULL. */
    00320     return rc;
    00321 /*@=nullstate@*/
    00322 }
    00323 /*@=mustmod@*/