예제 #1
0
static void 
spec_dealloc(specObject * s) 
{
    if (s->spec) {
	s->spec=rpmSpecFree(s->spec);
    }
    Py_TYPE(s)->tp_free((PyObject *)s);
}
예제 #2
0
파일: parseSpec.c 프로젝트: tomhughes/rpm
static rpmSpec parseSpec(const char *specFile, rpmSpecFlags flags,
                         const char *buildRoot, int recursing)
{
    int parsePart = PART_PREAMBLE;
    int initialPackage = 1;
    rpmSpec spec;

    /* Set up a new Spec structure with no packages. */
    spec = newSpec();

    spec->specFile = rpmGetPath(specFile, NULL);
    pushOFI(spec, spec->specFile);
    /* If buildRoot not specified, use default %{buildroot} */
    if (buildRoot) {
        spec->buildRoot = xstrdup(buildRoot);
    } else {
        spec->buildRoot = rpmGetPath("%{?buildroot:%{buildroot}}", NULL);
    }
    addMacro(NULL, "_docdir", NULL, "%{_defaultdocdir}", RMIL_SPEC);
    addMacro(NULL, "_licensedir", NULL, "%{_defaultlicensedir}", RMIL_SPEC);
    spec->recursing = recursing;
    spec->flags = flags;

    /* All the parse*() functions expect to have a line pre-read */
    /* in the spec's line buffer.  Except for parsePreamble(),   */
    /* which handles the initial entry into a spec file.         */

    while (parsePart != PART_NONE) {
        int goterror = 0;
        switch (parsePart) {
        case PART_ERROR: /* fallthrough */
        default:
            goterror = 1;
            break;
        case PART_PREAMBLE:
            parsePart = parsePreamble(spec, initialPackage);
            initialPackage = 0;
            break;
        case PART_PREP:
            parsePart = parsePrep(spec);
            break;
        case PART_BUILD:
        case PART_INSTALL:
        case PART_CHECK:
        case PART_CLEAN:
            parsePart = parseBuildInstallClean(spec, parsePart);
            break;
        case PART_CHANGELOG:
            parsePart = parseChangelog(spec);
            break;
        case PART_DESCRIPTION:
            parsePart = parseDescription(spec);
            break;

        case PART_PRE:
        case PART_POST:
        case PART_PREUN:
        case PART_POSTUN:
        case PART_PRETRANS:
        case PART_POSTTRANS:
        case PART_VERIFYSCRIPT:
        case PART_TRIGGERPREIN:
        case PART_TRIGGERIN:
        case PART_TRIGGERUN:
        case PART_TRIGGERPOSTUN:
        case PART_FILETRIGGERIN:
        case PART_FILETRIGGERUN:
        case PART_FILETRIGGERPOSTUN:
        case PART_TRANSFILETRIGGERIN:
        case PART_TRANSFILETRIGGERUN:
        case PART_TRANSFILETRIGGERPOSTUN:
            parsePart = parseScript(spec, parsePart);
            break;

        case PART_FILES:
            parsePart = parseFiles(spec);
            break;

        case PART_POLICIES:
            parsePart = parsePolicies(spec);
            break;

        case PART_NONE:		/* XXX avoid gcc whining */
        case PART_LAST:
        case PART_BUILDARCHITECTURES:
            break;
        }

        if (goterror || parsePart >= PART_LAST) {
            goto errxit;
        }

        if (parsePart == PART_BUILDARCHITECTURES) {
            int index;
            int x;

            closeSpec(spec);

            spec->BASpecs = xcalloc(spec->BACount, sizeof(*spec->BASpecs));
            index = 0;
            if (spec->BANames != NULL)
                for (x = 0; x < spec->BACount; x++) {

                    /* Skip if not arch is not compatible. */
                    if (!rpmMachineScore(RPM_MACHTABLE_BUILDARCH, spec->BANames[x]))
                        continue;
                    addMacro(NULL, "_target_cpu", NULL, spec->BANames[x], RMIL_RPMRC);
                    spec->BASpecs[index] = parseSpec(specFile, flags, buildRoot, 1);
                    if (spec->BASpecs[index] == NULL) {
                        spec->BACount = index;
                        goto errxit;
                    }
                    delMacro(NULL, "_target_cpu");
                    index++;
                }

            spec->BACount = index;
            if (! index) {
                rpmlog(RPMLOG_ERR,
                       _("No compatible architectures found for build\n"));
                goto errxit;
            }

            /*
             * Return the 1st child's fully parsed Spec structure.
             * The restart of the parse when encountering BuildArch
             * causes problems for "rpm -q --specfile". This is
             * still a hack because there may be more than 1 arch
             * specified (unlikely but possible.) There's also the
             * further problem that the macro context, particularly
             * %{_target_cpu}, disagrees with the info in the header.
             */
            if (spec->BACount >= 1) {
                rpmSpec nspec = spec->BASpecs[0];
                spec->BASpecs = _free(spec->BASpecs);
                rpmSpecFree(spec);
                spec = nspec;
            }

            goto exit;
        }
    }

    if (spec->clean == NULL) {
        char *body = rpmExpand("%{?buildroot: %{__rm} -rf %{buildroot}}", NULL);
        spec->clean = newStringBuf();
        appendLineStringBuf(spec->clean, body);
        free(body);
    }

    /* Check for description in each package */
    for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
        if (!headerIsEntry(pkg->header, RPMTAG_DESCRIPTION)) {
            rpmlog(RPMLOG_ERR, _("Package has no %%description: %s\n"),
                   headerGetString(pkg->header, RPMTAG_NAME));
            goto errxit;
        }
    }

    /* Add arch, os and platform, self-provides etc for each package */
    addTargets(spec->packages);

    /* Check for encoding in each package unless disabled */
    if (!(spec->flags & RPMSPEC_NOUTF8)) {
        int badenc = 0;
        for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
            if (checkForEncoding(pkg->header, 0) != RPMRC_OK) {
                badenc = 1;
            }
        }
        if (badenc)
            goto errxit;
    }

    closeSpec(spec);
exit:
    /* Assemble source header from parsed components */
    initSourceHeader(spec);

    return spec;

errxit:
    rpmSpecFree(spec);
    return NULL;
}
예제 #3
0
파일: rpmspec.c 프로젝트: soig/rpm
int main(int argc, char *argv[])
{
    rpmts ts = NULL;
    QVA_t qva = &rpmQVKArgs;

    poptContext optCon;
    int ec = 0;

    xsetprogname(argv[0]); /* Portability call -- see system.h */

    optCon = rpmcliInit(argc, argv, optionsTable);

    if (rpmcliPipeOutput && initPipe())
	exit(EXIT_FAILURE);

    if (target) {
	rpmFreeMacros(NULL);
	rpmFreeRpmrc();
	rpmReadConfigFiles(rpmcliRcfile, target);
    }
	
    ts = rpmtsCreate();
    switch (mode) {

    case MODE_QUERY:
	if (!poptPeekArg(optCon))
	    argerror(_("no arguments given for query"));

	qva->qva_queryFormat = queryformat;
	qva->qva_source = source;
	qva->qva_specQuery = rpmspecQuery;
	ec = rpmcliQuery(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
	break;

    case MODE_PARSE: {
	const char * spath;
	if (!poptPeekArg(optCon))
	    argerror(_("no arguments given for parse"));

	while ((spath = poptGetArg(optCon)) != NULL) {
	    rpmSpec spec = rpmSpecParse(spath, (RPMSPEC_ANYARCH|RPMSPEC_FORCE), NULL);
	    if (spec == NULL) {
		ec++;
		continue;
	    }
	    fprintf(stdout, "%s", rpmSpecGetSection(spec, RPMBUILD_NONE));
	    rpmSpecFree(spec);
	}
	break;
    }

    case MODE_UNKNOWN:
	if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
	    printUsage(optCon, stderr, 0);
	    ec = argc;
	}
	break;
    }

    rpmtsFree(ts);
    if (finishPipe())
	ec = EXIT_FAILURE;

    free(qva->qva_queryFormat);

    rpmcliFini(optCon);

    return RETVAL(ec);
}