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