Spin mostly complete file classifier off to rpmfc.[ch].

CVS patchset: 5773
CVS date: 2002/10/14 14:52:45
This commit is contained in:
jbj 2002-10-14 14:52:45 +00:00
parent 6278739895
commit a0bdebee4d
6 changed files with 456 additions and 23 deletions

View File

@ -26,14 +26,14 @@ tfr_LDADD = \
pkgincdir = $(pkgincludedir)
pkginc_HEADERS = rpmbuild.h rpmspec.h
noinst_HEADERS = argv.h buildio.h
noinst_HEADERS = argv.h buildio.h rpmfc.h
lib_LTLIBRARIES = librpmbuild.la
librpmbuild_la_SOURCES = \
argv.c build.c expression.c files.c misc.c names.c pack.c \
parseBuildInstallClean.c parseChangelog.c parseDescription.c \
parseFiles.c parsePreamble.c parsePrep.c parseReqs.c parseScript.c \
parseSpec.c poptBT.c reqprov.c spec.c
parseSpec.c poptBT.c reqprov.c rpmfc.c spec.c
librpmbuild_la_LDFLAGS = -release @VERSION@
# XXX Add internal libtool dependence

View File

@ -33,16 +33,27 @@ void argvPrint(const char * msg, ARGV_t argv, FILE * fp)
}
int argvFree(/*@only@*/ /*@null@*/ ARGV_t argv)
ARGI_t argiFree(ARGI_t argi)
{
if (argi) {
argi->nvals = 0;
argi->vals = _free(argi->vals);
}
argi = _free(argi);
return NULL;
}
ARGV_t argvFree(/*@only@*/ /*@null@*/ ARGV_t argv)
{
ARGV_t av;
if ((av = argv)) {
while (*av)
*av = _free(*av);
argv = _free(argv);
}
return 0;
/*@-branchstate@*/
if (argv)
for (av = argv; *av; av++)
*av = _free(*av);
/*@=branchstate@*/
argv = _free(argv);
return NULL;
}
int argvCount(/*@null@*/ const ARGV_t argv)
@ -57,22 +68,64 @@ int argvCount(/*@null@*/ const ARGV_t argv)
int argvCmp(const void * a, const void * b)
{
/*@-boundsread@*/
ARG_t astr = *(ARGV_t)a;
ARG_t bstr = *(ARGV_t)b;
ARGstr_t astr = *(ARGV_t)a;
ARGstr_t bstr = *(ARGV_t)b;
/*@=boundsread@*/
return strcmp(astr, bstr);
}
int argvSort(ARGV_t argv, int (*compar)(const void *, const void *))
{
if (compar == NULL)
compar = argvCmp;
qsort(argv, argvCount(argv), sizeof(*argv), compar);
return 0;
}
ARGV_t argvSearch(ARGV_t argv, ARG_t s,
ARGV_t argvSearch(ARGV_t argv, ARGstr_t val,
int (*compar)(const void *, const void *))
{
return bsearch(&s, argv, argvCount(argv), sizeof(*argv), compar);
if (argv == NULL)
return NULL;
if (compar == NULL)
compar = argvCmp;
return bsearch(&val, argv, argvCount(argv), sizeof(*argv), compar);
}
int argiAdd(/*@out@*/ ARGI_t * argip, unsigned ix, int val)
{
ARGI_t argi;
if (argip == NULL)
return -1;
if (*argip == NULL)
*argip = xcalloc(1, sizeof(**argip));
argi = *argip;
if (ix >= argi->nvals) {
argi->vals = xrealloc(argi->vals, (ix + 1) * sizeof(*argi->vals));
memset(argi->vals + argi->nvals, 0,
(ix - argi->nvals) * sizeof(*argi->vals));
argi->nvals = ix + 1;
}
argi->vals[ix] = val;
return 0;
}
int argvAdd(/*@out@*/ ARGV_t * argvp, ARGstr_t val)
{
ARGV_t argv;
int argc;
if (argvp == NULL)
return -1;
argc = argvCount(*argvp);
/*@-unqualifiedtrans@*/
*argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp));
/*@=unqualifiedtrans@*/
argv = *argvp;
argv[argc++] = xstrdup(val);
argv[argc ] = NULL;
return 0;
}
int argvAppend(/*@out@*/ ARGV_t * argvp, const ARGV_t av)

View File

@ -5,8 +5,15 @@
* \file build/argv.h
*/
typedef const char * ARG_t;
typedef ARG_t * ARGV_t;
typedef const char * ARGstr_t;
typedef ARGstr_t * ARGV_t;
typedef int * ARGint_t;
struct ARGI_s {
unsigned nvals;
ARGint_t vals;
};
typedef struct ARGI_s * ARGI_t;
#ifdef __cplusplus
extern "C" {
@ -22,11 +29,22 @@ void argvPrint(const char * msg, ARGV_t argv, FILE * fp)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/;
/**
* Destroy an argi array.
* @param argi argi array
* @return NULL always
*/
/*@null@*/
ARGI_t argiFree(/*@only@*/ /*@null@*/ ARGI_t argi)
/*@modifies argi @*/;
/**
* Destroy an argv array.
* @param argv argv array
* @return NULL always
*/
int argvFree(/*@only@*/ /*@null@*/ ARGV_t argv)
/*@null@*/
ARGV_t argvFree(/*@only@*/ /*@null@*/ ARGV_t argv)
/*@modifies argv @*/;
/**
@ -57,14 +75,34 @@ int argvSort(ARGV_t argv, int (*compar)(const void *, const void *))
* @param argv argv array
*/
/*@dependent@*/ /*@null@*/
ARGV_t argvSearch(ARGV_t argv, ARG_t s,
ARGV_t argvSearch(ARGV_t argv, ARGstr_t val,
int (*compar)(const void *, const void *))
/*@*/;
/**
* Add an int to an argi array.
* @retval *argip argi array
* @parm ix argi array index
* @param val int arg to add
* @return 0 always
*/
int argiAdd(/*@out@*/ ARGI_t * argip, unsigned ix, int val)
/*@modifies *argip @*/;
/**
* Add a string to an argv array.
* @retval *argvp argv array
* @param val string arg to append
* @return 0 always
*/
int argvAdd(/*@out@*/ ARGV_t * argvp, ARGstr_t val)
/*@modifies *argvp @*/;
/**
* Append one argv array to another.
* @retval *argvp argv array
* @param av argv array to append
* @return 0 always
*/
int argvAppend(/*@out@*/ ARGV_t * argvp, const ARGV_t av)
/*@modifies *argvp @*/;

254
build/rpmfc.c Normal file
View File

@ -0,0 +1,254 @@
/*@-bounds@*/
#include "system.h"
#include <rpmbuild.h>
#include <argv.h>
#include <rpmfc.h>
#include "debug.h"
/**
*/
/*@unchecked@*/ /*@observer@*/
static struct fclassTokens_s fclassTokens[] = {
{ "ELF 32-bit", RPMFC_ELF32|RPMFC_INCLUDE },
{ "ELF 64-bit", RPMFC_ELF64|RPMFC_INCLUDE },
{ "executable", RPMFC_EXECUTABLE },
{ "script", RPMFC_SCRIPT },
{ "text", RPMFC_TEXT },
{ "document", RPMFC_DOCUMENT },
{ "directory", RPMFC_DIRECTORY|RPMFC_INCLUDE },
{ "statically linked", RPMFC_STATIC },
{ "not stripped", RPMFC_NOTSTRIPPED },
{ "compressed", RPMFC_COMPRESSED },
{ "font", RPMFC_FONT },
{ "current ar archive", RPMFC_STATIC|RPMFC_LIBRARY|RPMFC_ARCHIVE|RPMFC_INCLUDE },
{ " font", RPMFC_FONT|RPMFC_INCLUDE },
{ " Font", RPMFC_FONT|RPMFC_INCLUDE },
{ "Zip archive data", RPMFC_COMPRESSED|RPMFC_ARCHIVE|RPMFC_INCLUDE },
{ "tar archive", RPMFC_ARCHIVE|RPMFC_INCLUDE },
{ "cpio archive", RPMFC_ARCHIVE|RPMFC_INCLUDE },
{ "RPM v3", RPMFC_ARCHIVE|RPMFC_INCLUDE },
{ "shell script", RPMFC_SCRIPT|RPMFC_INCLUDE },
{ "awk script", RPMFC_SCRIPT|RPMFC_INCLUDE },
{ "perl script", RPMFC_SCRIPT|RPMFC_INCLUDE },
{ "python script", RPMFC_SCRIPT|RPMFC_INCLUDE },
{ "python compiled", RPMFC_SCRIPT|RPMFC_INCLUDE },
{ "PHP script", RPMFC_SCRIPT|RPMFC_INCLUDE },
{ "empty", RPMFC_WHITE|RPMFC_INCLUDE },
{ "HTML", RPMFC_WHITE|RPMFC_INCLUDE },
{ "SGML", RPMFC_WHITE|RPMFC_INCLUDE },
{ "XML", RPMFC_WHITE|RPMFC_INCLUDE },
{ " program text", RPMFC_WHITE|RPMFC_INCLUDE },
{ " source", RPMFC_WHITE|RPMFC_INCLUDE },
{ "GLS_BINARY_LSB_FIRST", RPMFC_WHITE|RPMFC_INCLUDE },
{ " DB ", RPMFC_WHITE|RPMFC_INCLUDE },
{ "ASCII English text", RPMFC_WHITE|RPMFC_INCLUDE },
{ "ASCII text", RPMFC_WHITE|RPMFC_INCLUDE },
{ "ISO-8859 text", RPMFC_WHITE|RPMFC_INCLUDE },
{ "symbolic link to", RPMFC_SYMLINK },
{ "ASCII", RPMFC_WHITE },
{ "ISO-8859", RPMFC_WHITE },
{ "data", RPMFC_WHITE },
{ "application", RPMFC_WHITE },
{ "boot", RPMFC_WHITE },
{ "catalog", RPMFC_WHITE },
{ "code", RPMFC_WHITE },
{ "file", RPMFC_WHITE },
{ "format", RPMFC_WHITE },
{ "message", RPMFC_WHITE },
{ "program", RPMFC_WHITE },
{ "text", RPMFC_WHITE },
{ "broken symbolic link to ", RPMFC_WHITE|RPMFC_ERROR },
{ "can't read", RPMFC_WHITE|RPMFC_ERROR },
{ "can't stat", RPMFC_WHITE|RPMFC_ERROR },
{ "executable, can't read", RPMFC_WHITE|RPMFC_ERROR },
{ "core file", RPMFC_WHITE|RPMFC_ERROR },
{ NULL, RPMFC_BLACK }
};
/*@unchecked@*/
static int fcolorIgnore =
(RPMFC_ELF32|RPMFC_ELF64|RPMFC_DIRECTORY|RPMFC_LIBRARY|RPMFC_ARCHIVE|RPMFC_FONT|RPMFC_SCRIPT|RPMFC_WHITE);
int fclassColoring(const char * fmstr)
{
fclassToken fct;
int fcolor = RPMFC_BLACK;
for (fct = fclassTokens; fct->token != NULL; fct++) {
if (strstr(fmstr, fct->token) == NULL)
continue;
fcolor |= fct->colors;
if (fcolor & RPMFC_INCLUDE)
return fcolor;
}
return fcolor;
}
void fclassPrint(const char * msg, FCLASS_t fc, FILE * fp)
{
int ac = 0;
int fcolor;
int ix;
if (fp == NULL) fp = stderr;
if (msg)
fprintf(fp, "===================================== %s\n", msg);
if (fc)
while (1) {
if (fc->fn[ac] == NULL)
break;
if (ac >= fc->fdictx->nvals)
break;
ix = fc->fdictx->vals[ac];
if (ix < 0)
break;
fcolor = fc->fcolor->vals[ac];
if (ix > 0 && !(fcolor & fcolorIgnore)) {
fprintf(fp, "%3d %s", ix, fc->fn[ac]);
if (fcolor != RPMFC_BLACK)
fprintf(fp, "\t0x%x", fc->fcolor->vals[ac]);
else
fprintf(fp, "\t%s", fc->dict[ix]);
fprintf(fp, "\n");
}
ac++;
}
}
FCLASS_t fclassFree(FCLASS_t fc)
{
if (fc) {
fc->fn = argvFree(fc->fn);
fc->fdictx = argiFree(fc->fdictx);
fc->fcolor = argiFree(fc->fcolor);
fc->dict = argvFree(fc->dict);
}
fc = _free(fc);
return NULL;
}
FCLASS_t fclassNew(void)
{
FCLASS_t fc = xcalloc(1, sizeof(*fc));
return fc;
}
int fclassClassify(FCLASS_t *fcp, ARGV_t argv)
{
FCLASS_t fc;
char buf[BUFSIZ];
ARGV_t dav;
const char * s, * se;
char * t;
int fcolor;
int xx;
int fknown, fwhite;
if (fcp == NULL || argv == NULL)
return 0;
if (*fcp == NULL)
*fcp = fclassNew();
fc = *fcp;
/* Set up the file class dictionary. */
xx = argvAdd(&fc->dict, "");
xx = argvAdd(&fc->dict, "directory");
/*@-temptrans@*/
fc->av = argv;
/*@=temptrans@*/
while ((s = *fc->av++) != NULL) {
se = s;
while (*se && !(se[0] == ':' && se[1] == ' '))
se++;
if (*se == '\0')
return -1;
se++;
while (*se && (*se == ' ' || *se == '\t'))
se++;
if (*se == '\0')
return -1;
fcolor = fclassColoring(se);
if (fcolor == RPMFC_WHITE || !(fcolor & RPMFC_INCLUDE))
continue;
dav = argvSearch(fc->dict, se, NULL);
if (dav == NULL) {
xx = argvAdd(&fc->dict, se);
xx = argvSort(fc->dict, NULL);
}
}
/* Classify files. */
/*@-kepttrans@*/
fc->av = argv;
/*@=kepttrans@*/
fc->ix = 0;
fknown = 0;
while ((s = *fc->av++) != NULL) {
se = s;
while (*se && !(se[0] == ':' && se[1] == ' '))
se++;
if (*se == '\0')
return -1;
t = stpncpy(buf, s, (se - s));
*t = '\0';
xx = argvAdd(&fc->fn, buf);
se++;
while (*se && (*se == ' ' || *se == '\t'))
se++;
if (*se == '\0')
return -1;
dav = argvSearch(fc->dict, se, NULL);
if (dav) {
xx = argiAdd(&fc->fdictx, fc->ix, (dav - fc->dict));
fknown++;
} else {
xx = argiAdd(&fc->fdictx, fc->ix, 0);
fwhite++;
}
xx = argiAdd(&fc->fcolor, fc->ix, fclassColoring(se));
fc->ix++;
}
fc->av = NULL;
/*@-modfilesys@*/
sprintf(buf, "final: files %d dict[%d] %d%%", argvCount(fc->fn), argvCount(fc->dict), ((100 * fknown)/fc->ix));
fclassPrint(buf, fc, NULL);
/*@=modfilesys@*/
return 0;
}
/*@=bounds@*/

86
build/rpmfc.h Normal file
View File

@ -0,0 +1,86 @@
#ifndef _H_RPMFC_
#define _H_RPMFC_
typedef struct fclass_s * FCLASS_t;
struct fclass_s {
ARGV_t av; /*!< file(1) output lines */
int ac; /*!< no. of lines */
int ix; /*!< current lineno */
ARGV_t fn; /*!< file names */
ARGI_t fcolor; /*!< file colors */
ARGI_t fdictx; /*!< file class dictionary indices */
ARGV_t dict; /*!< file class dictionary */
};
enum FCOLOR_e {
RPMFC_BLACK = 0,
RPMFC_ELF32 = (1 << 0),
RPMFC_ELF64 = (1 << 1),
RPMFC_EXECUTABLE = (1 << 2),
RPMFC_SCRIPT = (1 << 3),
RPMFC_TEXT = (1 << 4),
RPMFC_DIRECTORY = (1 << 8),
RPMFC_LIBRARY = (1 << 9),
RPMFC_DOCUMENT = (1 << 10),
RPMFC_STATIC = (1 << 16),
RPMFC_NOTSTRIPPED = (1 << 18),
RPMFC_COMPRESSED = (1 << 19),
RPMFC_SYMLINK = (1 << 24),
RPMFC_ARCHIVE = (1 << 25),
RPMFC_FONT = (1 << 26),
RPMFC_WHITE = (1 << 29),
RPMFC_INCLUDE = (1 << 30),
RPMFC_ERROR = (1 << 31)
};
typedef enum FCOLOR_e FCOLOR_t;
struct fclassTokens_s {
/*@observer@*/
const char * token;
int colors;
};
typedef struct fclassTokens_s * fclassToken;
#ifdef __cplusplus
extern "C" {
#endif
/**
*/
int fclassColoring(const char * fmstr)
/*@*/;
/**
*/
void fclassPrint(const char * msg, FCLASS_t fc, FILE * fp)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/;
/**
*/
/*@null@*/
FCLASS_t fclassFree(/*@only@*/ /*@null@*/ FCLASS_t fc)
/*@modifies fc @*/;
/**
*/
FCLASS_t fclassNew(void)
/*@*/;
/**
*/
int fclassClassify(/*@out@*/ FCLASS_t *fcp, ARGV_t argv)
/*@modifies *fcp @*/;
#ifdef __cplusplus
}
#endif
#endif /* _H_RPMFC_ */

View File

@ -2,6 +2,7 @@
#include <rpmbuild.h>
#include <argv.h>
#include <rpmfc.h>
#include "debug.h"
@ -25,6 +26,7 @@ main(int argc, char *const argv[])
int pac = 0;
ARGV_t xav;
ARGV_t av = NULL;
FCLASS_t fc;
int ac = 0;
const char * s;
int ec = 1;
@ -50,23 +52,23 @@ main(int argc, char *const argv[])
xav = NULL;
xx = argvAppend(&xav, pav);
xx = argvAppend(&xav, av);
pav = _free(pav);
pav = _free(pav); /* XXX popt mallocs in single blob. */
s = _free(s);
/* Read file(1) output. */
sb = getOutputFrom(NULL, xav, NULL, 0, 1);
xav = argvFree(xav);
xx = argvFree(xav);
xav = NULL;
xx = argvSplit(&xav, getStringBuf(sb), "\n");
sb = freeStringBuf(sb);
xx = argvSort(xav, argvCmp);
argvPrint("final", xav, NULL);
fc = NULL;
xx = fclassClassify(&fc, xav);
fc = fclassFree(fc);
xx = argvFree(xav);
xav = argvFree(xav);
exit:
optCon = rpmcliFini(optCon);