rpm  5.2.1
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@*/