rpm 5.3.12
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(ARGint_t * a, ARGint_t * 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(ARGstr_t * a, ARGstr_t * 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(ARGstr_t * a, ARGstr_t * 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(ARGstr_t * a, ARGstr_t * 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(ARGstr_t * a, ARGstr_t * 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)(ARGint_t *, ARGint_t *))
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),
00128                 (int(*)(const void *, const void *))compar);
00129     return 0;
00130 }
00131 
00132 int argvSort(ARGV_t argv, int (*compar)(ARGstr_t *, ARGstr_t *))
00133 {
00134     if (compar == NULL)
00135         compar = argvCmp;
00136     qsort(argv, argvCount(argv), sizeof(*argv),
00137                 (int(*)(const void *, const void *))compar);
00138     return 0;
00139 }
00140 
00141 ARGV_t argvSearch(ARGV_t argv, ARGstr_t val,
00142                 int (*compar)(ARGstr_t *, ARGstr_t *))
00143 {
00144     if (argv == NULL)
00145         return NULL;
00146     if (compar == NULL)
00147         compar = argvCmp;
00148     return bsearch(&val, argv, argvCount(argv), sizeof(*argv),
00149                 (int(*)(const void *, const void *))compar);
00150 }
00151 
00152 #if defined(RPM_VENDOR_OPENPKG) /* wildcard-matching-arbitrary-tagnames */
00153 ARGV_t argvSearchLinear(ARGV_t argv, ARGstr_t val,
00154                 int (*compar)(ARGstr_t *, ARGstr_t *))
00155 {
00156     ARGV_t result;
00157     ARGV_t av;
00158     if (argv == NULL)
00159         return NULL;
00160     if (compar == NULL)
00161         compar = argvCmp;
00162     result = NULL;
00163     for (av = argv; *av != NULL; av++) {
00164         if (compar(av, &val) == 0) {
00165             result = av;
00166             break;
00167         }
00168     }
00169     return result;
00170 }
00171 #endif
00172 
00173 int argiAdd(/*@out@*/ ARGI_t * argip, int ix, int val)
00174 {
00175     ARGI_t argi;
00176 
00177     if (argip == NULL)
00178         return -1;
00179     if (*argip == NULL)
00180         *argip = xcalloc(1, sizeof(**argip));
00181     argi = *argip;
00182     if (ix < 0)
00183         ix = argi->nvals;
00184     if (ix >= (int)argi->nvals) {
00185         argi->vals = xrealloc(argi->vals, (ix + 1) * sizeof(*argi->vals));
00186         memset(argi->vals + argi->nvals, 0,
00187                 (ix - argi->nvals) * sizeof(*argi->vals));
00188         argi->nvals = ix + 1;
00189     }
00190     argi->vals[ix] = val;
00191     return 0;
00192 }
00193 
00194 int argvAdd(/*@out@*/ ARGV_t * argvp, ARGstr_t val)
00195 {
00196     ARGV_t argv;
00197     int argc;
00198 
00199     if (argvp == NULL)
00200         return -1;
00201     argc = argvCount(*argvp);
00202 /*@-unqualifiedtrans@*/
00203     *argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp));
00204 /*@=unqualifiedtrans@*/
00205     argv = *argvp;
00206     argv[argc++] = xstrdup(val);
00207     argv[argc  ] = NULL;
00208     return 0;
00209 }
00210 
00211 int argvAppend(/*@out@*/ ARGV_t * argvp, ARGV_t av)
00212 {
00213     int ac = argvCount(av);
00214 
00215     if (av != NULL && ac > 0) {
00216         ARGV_t argv = *argvp;
00217         int argc = argvCount(argv);
00218 
00219         argv = xrealloc(argv, (argc + ac + 1) * sizeof(*argv));
00220         while (*av++)
00221             argv[argc++] = xstrdup(av[-1]);
00222         argv[argc] = NULL;
00223         *argvp = argv;
00224     }
00225     return 0;
00226 }
00227 
00228 int argvSplit(ARGV_t * argvp, const char * str, const char * seps)
00229 {
00230     static char whitespace[] = " \f\n\r\t\v";
00231     char * dest = xmalloc(strlen(str) + 1);
00232     ARGV_t argv;
00233     int argc = 1;
00234     const char * s;
00235     char * t;
00236     int c;
00237 
00238     if (seps == NULL)
00239         seps = whitespace;
00240 
00241     for (argc = 1, s = str, t = dest; (c = (int) *s); s++, t++) {
00242         if (strchr(seps, c) && !(s[0] == ':' && s[1] == '/' && s[2] == '/')) {
00243             argc++;
00244             c = (int) '\0';
00245         }
00246         *t = (char) c;
00247     }
00248     *t = '\0';
00249 
00250     argv = xmalloc( (argc + 1) * sizeof(*argv));
00251 
00252     for (c = 0, s = dest; s < t; s += strlen(s) + 1) {
00253         /* XXX Skip repeated seperators (i.e. whitespace). */
00254         if (seps == whitespace && s[0] == '\0')
00255             continue;
00256         argv[c++] = xstrdup(s);
00257     }
00258     argv[c] = NULL;
00259     if (argvp)
00260         *argvp = argv;
00261     else
00262         argv = argvFree(argv);
00263     dest = _free(dest);
00264 /*@-nullstate@*/
00265     return 0;
00266 /*@=nullstate@*/
00267 }
00268 
00269 char * argvJoin(ARGV_t argv, char sep)
00270 {
00271     size_t nb = 0;
00272     int argc;
00273     char *t, *te;
00274 
00275     for (argc = 0; argv[argc] != NULL; argc++) {
00276         if (argc != 0)
00277             nb++;
00278         nb += strlen(argv[argc]);
00279     }
00280     nb++;
00281 
00282     te = t = xmalloc(nb);
00283     *te = '\0';
00284     for (argc = 0; argv[argc] != NULL; argc++) {
00285         if (argc != 0)
00286             *te++ = sep;
00287         te = stpcpy(te, argv[argc]);
00288     }
00289     *te = '\0';
00290     return t;
00291 }
00292 
00293 /*@-mustmod@*/
00294 int argvFgets(ARGV_t * argvp, void * fd)
00295 {
00296     FILE * fp = (fd ? fdGetFILE(fd) : stdin);
00297     ARGV_t av = NULL;
00298     char buf[BUFSIZ];
00299     char * b, * be;
00300     int rc = 0;
00301 
00302     if (fp == NULL)
00303         return -2;
00304     while (!rc && (b = fgets(buf, (int)sizeof(buf), fp)) != NULL) {
00305         buf[sizeof(buf)-1] = '\0';
00306         be = b + strlen(buf);
00307         if (be > b) be--;
00308         while (strchr("\r\n", *be) != NULL)
00309             *be-- = '\0';
00310         rc = argvAdd(&av, b);
00311     }
00312 
00313     if (!rc)
00314         rc = ferror(fp);
00315     if (!rc)
00316         rc = (feof(fp) ? 0 : 1);
00317     if (!rc && argvp)
00318         *argvp = av;
00319     else
00320         av = argvFree(av);
00321     
00322 /*@-nullstate@*/        /* XXX *argvp may be NULL. */
00323     return rc;
00324 /*@=nullstate@*/
00325 }
00326 /*@=mustmod@*/