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