parent
07a348e2e6
commit
097ff145c9
|
@ -0,0 +1,205 @@
|
|||
#include "system.h"
|
||||
|
||||
#include <rpmbuild.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
*/
|
||||
static int argvFree(/*@only@*/ /*@null@*/ const char ** argv)
|
||||
/*@modifies argv @*/
|
||||
{
|
||||
const char ** av;
|
||||
|
||||
if ((av = argv)) {
|
||||
while (*av)
|
||||
*av = _free(*av);
|
||||
argv = _free(argv);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static void argvPrint(const char * msg, const char ** argv, FILE * fp)
|
||||
/*@*/
|
||||
{
|
||||
const char ** av;
|
||||
int ac;
|
||||
|
||||
if (fp == NULL) fp = stderr;
|
||||
|
||||
if (msg)
|
||||
fprintf(fp, "===================================== %s\n", msg);
|
||||
|
||||
for (ac = 0, av = argv; *av; av++, ac++)
|
||||
fprintf(fp, "%5d: %s\n", ac, *av);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static int argvCount(/*@null@*/ const char ** argv)
|
||||
/*@*/
|
||||
{
|
||||
int argc = 0;
|
||||
if (argv)
|
||||
while (argv[argc] != NULL)
|
||||
argc++;
|
||||
return argc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare argv arrays (qsort/bsearch).
|
||||
* @param a 1st instance address
|
||||
* @param b 2nd instance address
|
||||
* @return result of comparison
|
||||
*/
|
||||
static int argvCmp(const void * a, const void * b)
|
||||
/*@*/
|
||||
{
|
||||
/*@-boundsread@*/
|
||||
const char * astr = *(const char **)a;
|
||||
const char * bstr = *(const char **)b;
|
||||
/*@=boundsread@*/
|
||||
return strcmp(astr, bstr);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static int argvSort(const char ** argv,
|
||||
int (*compar)(const void *, const void *))
|
||||
/*@*/
|
||||
{
|
||||
qsort(argv, argvCount(argv), sizeof(*argv), compar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static const char ** argvSearch(const char ** argv, const char * s,
|
||||
int (*compar)(const void *, const void *))
|
||||
/*@*/
|
||||
{
|
||||
return bsearch(&s, argv, argvCount(argv), sizeof(*argv), compar);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static int argvAppend(/*@out@*/ const char *** argvp, const char ** av)
|
||||
/*@*/
|
||||
{
|
||||
const char ** argv = *argvp;
|
||||
int argc = argvCount(argv);
|
||||
int ac = argvCount(av);
|
||||
int i;
|
||||
|
||||
argv = xrealloc(argv, (argc + ac + 1) * sizeof(*argv));
|
||||
for (i = 0; i < ac; i++)
|
||||
argv[argc + i] = xstrdup(av[i]);
|
||||
argv[argc + ac] = NULL;
|
||||
*argvp = argv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static int argvSplit(const char *** argvp, const char * str, const char * seps)
|
||||
/*@*/
|
||||
{
|
||||
char * dest = alloca(strlen(str) + 1);
|
||||
const char ** argv;
|
||||
int argc = 1;
|
||||
const char * s;
|
||||
char * t;
|
||||
int c;
|
||||
|
||||
for (argc = 1, s = str, t = dest; (c = *s); s++, t++) {
|
||||
if (strchr(seps, c)) {
|
||||
argc++;
|
||||
c = '\0';
|
||||
}
|
||||
*t = c;
|
||||
}
|
||||
*t = '\0';
|
||||
|
||||
argv = xmalloc( (argc + 1) * sizeof(*argv));
|
||||
|
||||
for (c = 0, s = dest; s < t; s+= strlen(s) + 1) {
|
||||
if (*s == '\0')
|
||||
continue;
|
||||
argv[c] = xstrdup(s);
|
||||
c++;
|
||||
}
|
||||
argv[c] = NULL;
|
||||
*argvp = argv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct poptOption optionsTable[] = {
|
||||
|
||||
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
|
||||
N_("Common options for all rpm modes and executables:"),
|
||||
NULL },
|
||||
|
||||
POPT_AUTOALIAS
|
||||
POPT_AUTOHELP
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *const argv[])
|
||||
{
|
||||
poptContext optCon;
|
||||
StringBuf sb;
|
||||
const char ** pav;
|
||||
int pac = 0;
|
||||
const char ** xav;
|
||||
const char ** av = NULL;
|
||||
int ac = 0;
|
||||
const char * s;
|
||||
int ec = 1;
|
||||
int xx;
|
||||
|
||||
optCon = rpmcliInit(argc, argv, optionsTable);
|
||||
if (optCon == NULL)
|
||||
goto exit;
|
||||
|
||||
av = poptGetArgs(optCon);
|
||||
ac = argvCount(av);
|
||||
|
||||
/* Find path to file(1). */
|
||||
s = rpmExpand("%{?__file}", NULL);
|
||||
if (!(s && *s))
|
||||
goto exit;
|
||||
|
||||
/* Build argv, merging tokens from expansion with CLI args. */
|
||||
xx = poptParseArgvString(s, &pac, (const char ***)&pav);
|
||||
if (!(xx == 0 && pac > 0 && pav != NULL))
|
||||
goto exit;
|
||||
|
||||
xav = NULL;
|
||||
xx = argvAppend(&xav, pav);
|
||||
xx = argvAppend(&xav, av);
|
||||
pav = _free(pav);
|
||||
s = _free(s);
|
||||
|
||||
/* Read file(1) output. */
|
||||
sb = getOutputFrom(NULL, xav, NULL, 0, 1);
|
||||
|
||||
xx = argvFree(xav);
|
||||
|
||||
xav = NULL;
|
||||
xx = argvSplit(&xav, getStringBuf(sb), "\n");
|
||||
sb = freeStringBuf(sb);
|
||||
|
||||
xx = argvSort(xav, argvCmp);
|
||||
|
||||
argvPrint("final", xav, NULL);
|
||||
|
||||
xx = argvFree(xav);
|
||||
|
||||
exit:
|
||||
optCon = rpmcliFini(optCon);
|
||||
return ec;
|
||||
}
|
Loading…
Reference in New Issue