00001
00005 #include "system.h"
00006
00007 #include "rpmio_internal.h"
00008 #include <argv.h>
00009
00010 #include "debug.h"
00011
00012
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( 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
00078 return argv;
00079
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)
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)
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( 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( 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
00200 *argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp));
00201
00202 argv = *argvp;
00203 argv[argc++] = xstrdup(val);
00204 argv[argc ] = NULL;
00205 return 0;
00206 }
00207
00208 int argvAppend( 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
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
00262 return 0;
00263
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
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
00320 return rc;
00321
00322 }
00323