1995-11-28 06:31:21 +08:00
|
|
|
/* RPM - Copyright (C) 1995 Red Hat Software
|
|
|
|
*
|
|
|
|
* spec.c - routines for parsing a spec file
|
|
|
|
*/
|
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
/*****************************
|
|
|
|
TODO:
|
|
|
|
|
1995-12-14 23:52:51 +08:00
|
|
|
. skip blank lines
|
|
|
|
. strip leading/trailing spaces in %preamble and %files
|
1995-12-13 01:53:17 +08:00
|
|
|
. multiline descriptions (general backslash processing)
|
1995-12-21 07:30:46 +08:00
|
|
|
. source and patch lines (multiple)
|
|
|
|
. %exclude and real arch/os checking
|
|
|
|
. %dir %doc %config globbing
|
|
|
|
. %setup %patch
|
1995-12-13 01:53:17 +08:00
|
|
|
. root: option
|
|
|
|
|
|
|
|
******************************/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <regex.h>
|
|
|
|
|
1995-11-28 06:31:21 +08:00
|
|
|
#include "header.h"
|
|
|
|
#include "spec.h"
|
1995-12-14 23:52:51 +08:00
|
|
|
#include "specP.h"
|
1995-11-28 06:31:21 +08:00
|
|
|
#include "rpmerr.h"
|
1995-12-12 06:52:59 +08:00
|
|
|
#include "messages.h"
|
1995-12-13 01:53:17 +08:00
|
|
|
#include "rpmlib.h"
|
1995-12-13 23:57:59 +08:00
|
|
|
#include "stringbuf.h"
|
1995-11-28 06:31:21 +08:00
|
|
|
|
|
|
|
#define LINE_BUF_SIZE 1024
|
1995-12-13 01:53:17 +08:00
|
|
|
#define FREE(x) { if (x) free(x); }
|
1995-11-28 06:31:21 +08:00
|
|
|
|
1995-12-13 23:57:59 +08:00
|
|
|
static struct PackageRec *new_packagerec(void);
|
1995-12-12 06:52:59 +08:00
|
|
|
static int read_line(FILE *f, char *line);
|
|
|
|
static int match_arch(char *s);
|
|
|
|
static int match_os(char *s);
|
|
|
|
static void free_packagerec(struct PackageRec *p);
|
1995-12-13 01:53:17 +08:00
|
|
|
static void reset_spec(void);
|
|
|
|
static int find_preamble_line(char *line, char **s);
|
|
|
|
static int check_part(char *line, char **s);
|
1995-12-14 23:52:51 +08:00
|
|
|
int lookup_package(Spec s, struct PackageRec **pr, char *name, int flags);
|
|
|
|
static void dumpPackage(struct PackageRec *p, FILE *f);
|
|
|
|
char *chop_line(char *s);
|
|
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Spec and package structure creation/deletion/lookup */
|
|
|
|
/* */
|
|
|
|
/**********************************************************************/
|
|
|
|
|
1995-12-13 23:57:59 +08:00
|
|
|
static struct PackageRec *new_packagerec(void)
|
|
|
|
{
|
|
|
|
struct PackageRec *p = malloc(sizeof(struct PackageRec));
|
|
|
|
|
|
|
|
p->subname = NULL;
|
|
|
|
p->newname = NULL;
|
|
|
|
p->header = newHeader();
|
|
|
|
p->filelist = newStringBuf();
|
1995-12-20 01:56:45 +08:00
|
|
|
p->files = -1; /* -1 means no %files, thus no package */
|
1995-12-13 23:57:59 +08:00
|
|
|
p->next = NULL;
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
1995-12-12 06:52:59 +08:00
|
|
|
void free_packagerec(struct PackageRec *p)
|
|
|
|
{
|
|
|
|
freeHeader(p->header);
|
1995-12-13 23:57:59 +08:00
|
|
|
freeStringBuf(p->filelist);
|
1995-12-13 01:53:17 +08:00
|
|
|
FREE(p->subname);
|
|
|
|
FREE(p->newname);
|
1995-12-12 06:52:59 +08:00
|
|
|
if (p->next) {
|
|
|
|
free_packagerec(p->next);
|
|
|
|
}
|
|
|
|
free(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
void freeSpec(Spec s)
|
1995-11-28 06:31:21 +08:00
|
|
|
{
|
1995-12-13 01:53:17 +08:00
|
|
|
FREE(s->name);
|
1995-12-13 23:57:59 +08:00
|
|
|
freeStringBuf(s->prep);
|
|
|
|
freeStringBuf(s->build);
|
|
|
|
freeStringBuf(s->install);
|
|
|
|
freeStringBuf(s->clean);
|
1995-12-12 06:52:59 +08:00
|
|
|
free_packagerec(s->packages);
|
1995-11-28 06:31:21 +08:00
|
|
|
free(s);
|
|
|
|
}
|
|
|
|
|
1995-12-14 23:52:51 +08:00
|
|
|
#define LP_CREATE 1
|
|
|
|
#define LP_FAIL_EXISTS (1 << 1)
|
|
|
|
#define LP_SUBNAME (1 << 2)
|
|
|
|
#define LP_NEWNAME (1 << 3)
|
|
|
|
|
|
|
|
int lookup_package(Spec s, struct PackageRec **pr, char *name, int flags)
|
|
|
|
{
|
1995-12-20 05:06:39 +08:00
|
|
|
char buf[1024];
|
1995-12-14 23:52:51 +08:00
|
|
|
struct PackageRec *package;
|
|
|
|
struct PackageRec **ppp;
|
|
|
|
|
|
|
|
package = s->packages;
|
|
|
|
while (package) {
|
|
|
|
if (flags & (LP_SUBNAME | LP_NEWNAME)) {
|
|
|
|
if ((! package->newname) & (! package->subname)) {
|
|
|
|
package = package->next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (flags & LP_SUBNAME) {
|
|
|
|
if (! strcmp(package->subname, name)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (flags & LP_NEWNAME) {
|
|
|
|
if (! strcmp(package->newname, name)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Base package */
|
|
|
|
if ((! package->newname) & (! package->subname)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
package = package->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (package && (flags & LP_FAIL_EXISTS)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (package) {
|
|
|
|
*pr = package;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* At this point the package does not exist */
|
|
|
|
|
|
|
|
if (! (flags & LP_CREATE)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create it */
|
|
|
|
package = new_packagerec();
|
|
|
|
if (flags & LP_SUBNAME) {
|
|
|
|
package->subname = strdup(name);
|
1995-12-20 05:06:39 +08:00
|
|
|
sprintf(buf, "%s-%s", s->name, name);
|
1995-12-14 23:52:51 +08:00
|
|
|
} else if (flags & LP_NEWNAME) {
|
|
|
|
package->newname = strdup(name);
|
1995-12-20 05:06:39 +08:00
|
|
|
sprintf(buf, "%s", name);
|
|
|
|
}
|
|
|
|
if (name) {
|
|
|
|
addEntry(package->header, RPMTAG_NAME, STRING_TYPE, buf, 1);
|
1995-12-14 23:52:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Link it in to the spec */
|
|
|
|
ppp = &(s->packages);
|
|
|
|
while (*ppp) {
|
|
|
|
ppp = &((*ppp)->next);
|
|
|
|
}
|
|
|
|
*ppp = package;
|
|
|
|
|
|
|
|
*pr = package;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Line reading */
|
|
|
|
/* */
|
|
|
|
/**********************************************************************/
|
|
|
|
|
1995-11-28 06:31:21 +08:00
|
|
|
static int match_arch(char *s)
|
|
|
|
{
|
|
|
|
if (! strncmp(s, "%ifarch i386", 12)) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int match_os(char *s)
|
|
|
|
{
|
|
|
|
if (! strncmp(s, "%ifos linux", 11)) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
static struct read_level_entry {
|
|
|
|
int reading; /* 1 if we are reading at this level */
|
|
|
|
struct read_level_entry *next;
|
|
|
|
} *read_level = NULL;
|
1995-11-28 06:31:21 +08:00
|
|
|
|
|
|
|
static int read_line(FILE *f, char *line)
|
|
|
|
{
|
1995-12-13 01:53:17 +08:00
|
|
|
static struct read_level_entry *rl;
|
|
|
|
int gotline;
|
|
|
|
char *r;
|
1995-11-28 06:31:21 +08:00
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
do {
|
|
|
|
gotline = 0;
|
|
|
|
if (! fgets(line, LINE_BUF_SIZE, f)) {
|
|
|
|
/* the end */
|
|
|
|
if (read_level->next) {
|
|
|
|
return RPMERR_UNMATCHEDIF;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (! strncmp("%ifarch", line, 7)) {
|
|
|
|
rl = malloc(sizeof(struct read_level_entry));
|
|
|
|
rl->next = read_level;
|
|
|
|
rl->reading = read_level->reading && match_arch(line);
|
|
|
|
read_level = rl;
|
|
|
|
} else if (! strncmp("%ifos", line, 5)) {
|
|
|
|
rl = malloc(sizeof(struct read_level_entry));
|
|
|
|
rl->next = read_level;
|
|
|
|
rl->reading = read_level->reading && match_os(line);
|
|
|
|
read_level = rl;
|
|
|
|
} else if (! strncmp("%else", line, 5)) {
|
|
|
|
if (! read_level->next) {
|
|
|
|
/* Got an else with no %if ! */
|
|
|
|
return RPMERR_UNMATCHEDIF;
|
|
|
|
}
|
|
|
|
read_level->reading =
|
|
|
|
read_level->next->reading && ! read_level->reading;
|
|
|
|
} else if (! strncmp("%endif", line, 6)) {
|
|
|
|
rl = read_level;
|
|
|
|
read_level = rl->next;
|
|
|
|
free(rl);
|
|
|
|
} else {
|
|
|
|
gotline = 1;
|
|
|
|
}
|
|
|
|
} while (! (gotline && read_level->reading));
|
|
|
|
|
|
|
|
r = line + (strlen(line)) - 1;
|
|
|
|
if (*r == '\n') {
|
|
|
|
*r = '\0';
|
1995-11-28 06:31:21 +08:00
|
|
|
}
|
1995-12-13 01:53:17 +08:00
|
|
|
return 1;
|
|
|
|
}
|
1995-11-28 06:31:21 +08:00
|
|
|
|
1995-12-14 23:52:51 +08:00
|
|
|
/**********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Line parsing */
|
|
|
|
/* */
|
|
|
|
/**********************************************************************/
|
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
struct preamble_line {
|
|
|
|
int tag;
|
|
|
|
int len;
|
|
|
|
char *token;
|
|
|
|
} preamble_spec[] = {
|
|
|
|
{RPMTAG_NAME, 0, "name"},
|
|
|
|
{RPMTAG_VERSION, 0, "version"},
|
|
|
|
{RPMTAG_RELEASE, 0, "release"},
|
|
|
|
{RPMTAG_SERIAL, 0, "serial"},
|
|
|
|
{RPMTAG_DESCRIPTION, 0, "description"},
|
|
|
|
{RPMTAG_SUMMARY, 0, "summary"},
|
|
|
|
{RPMTAG_COPYRIGHT, 0, "copyright"},
|
|
|
|
{RPMTAG_DISTRIBUTION, 0, "distribution"},
|
|
|
|
{RPMTAG_VENDOR, 0, "vendor"},
|
|
|
|
{RPMTAG_GROUP, 0, "group"},
|
|
|
|
{RPMTAG_PACKAGER, 0, "packager"},
|
|
|
|
{0, 0, 0}
|
|
|
|
};
|
1995-11-28 06:31:21 +08:00
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
static int find_preamble_line(char *line, char **s)
|
|
|
|
{
|
|
|
|
struct preamble_line *p = preamble_spec;
|
1995-11-28 06:31:21 +08:00
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
while (p->token && strncasecmp(line, p->token, p->len)) {
|
|
|
|
p++;
|
1995-11-28 06:31:21 +08:00
|
|
|
}
|
1995-12-13 01:53:17 +08:00
|
|
|
if (!p) return 0;
|
|
|
|
*s = line + p->len;
|
|
|
|
*s += strspn(*s, ": \t");
|
|
|
|
return p->tag;
|
1995-11-28 06:31:21 +08:00
|
|
|
}
|
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
/* None of these can be 0 !! */
|
1995-12-21 07:30:46 +08:00
|
|
|
#define PREAMBLE_PART 1
|
|
|
|
#define PREP_PART 2
|
|
|
|
#define BUILD_PART 3
|
|
|
|
#define INSTALL_PART 4
|
|
|
|
#define CLEAN_PART 5
|
|
|
|
#define PREIN_PART 6
|
|
|
|
#define POSTIN_PART 7
|
|
|
|
#define PREUN_PART 8
|
|
|
|
#define POSTUN_PART 9
|
|
|
|
#define FILES_PART 10
|
|
|
|
#define CHANGELOG_PART 11
|
1995-12-13 01:53:17 +08:00
|
|
|
|
|
|
|
static struct part_rec {
|
|
|
|
int part;
|
|
|
|
int len;
|
1995-12-12 06:52:59 +08:00
|
|
|
char *s;
|
1995-12-13 01:53:17 +08:00
|
|
|
} part_list[] = {
|
1995-12-21 07:30:46 +08:00
|
|
|
{PREAMBLE_PART, 0, "%package"},
|
|
|
|
{PREP_PART, 0, "%prep"},
|
|
|
|
{BUILD_PART, 0, "%build"},
|
|
|
|
{INSTALL_PART, 0, "%install"},
|
|
|
|
{CLEAN_PART, 0, "%clean"},
|
|
|
|
{PREIN_PART, 0, "%prein"},
|
|
|
|
{POSTIN_PART, 0, "%postin"},
|
|
|
|
{PREUN_PART, 0, "%preun"},
|
|
|
|
{POSTUN_PART, 0, "%postun"},
|
|
|
|
{FILES_PART, 0, "%files"},
|
|
|
|
{CHANGELOG_PART, 0, "%changelog"},
|
1995-12-13 01:53:17 +08:00
|
|
|
{0, 0, 0}
|
1995-12-12 06:52:59 +08:00
|
|
|
};
|
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
static int check_part(char *line, char **s)
|
1995-12-12 06:52:59 +08:00
|
|
|
{
|
1995-12-13 01:53:17 +08:00
|
|
|
struct part_rec *p = part_list;
|
|
|
|
|
|
|
|
while (p->s && strncasecmp(line, p->s, p->len)) {
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
if (!p) return 0;
|
|
|
|
*s = line + p->len;
|
|
|
|
*s += strspn(*s, " \t");
|
|
|
|
if (**s == '\0') {
|
|
|
|
*s = NULL;
|
1995-12-12 06:52:59 +08:00
|
|
|
}
|
1995-12-13 01:53:17 +08:00
|
|
|
return p->part;
|
1995-12-12 06:52:59 +08:00
|
|
|
}
|
|
|
|
|
1995-12-14 23:52:51 +08:00
|
|
|
char *chop_line(char *s)
|
|
|
|
{
|
|
|
|
char *p, *e;
|
|
|
|
|
|
|
|
p = s;
|
|
|
|
p += strspn(s, " \t");
|
|
|
|
if (*p == '\0') {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
e = s + strlen(s) - 1;
|
|
|
|
while (index(" \t", *e)) {
|
|
|
|
e--;
|
|
|
|
}
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Main specfile parsing routine */
|
|
|
|
/* */
|
|
|
|
/**********************************************************************/
|
|
|
|
|
1995-12-12 06:52:59 +08:00
|
|
|
Spec parseSpec(FILE *f)
|
1995-11-28 06:31:21 +08:00
|
|
|
{
|
1995-12-18 22:56:49 +08:00
|
|
|
char buf[LINE_BUF_SIZE]; /* read buffer */
|
|
|
|
char *line; /* "parsed" read buffer */
|
|
|
|
|
1995-12-13 23:57:59 +08:00
|
|
|
int x, tag, cur_part, t1;
|
1995-12-14 23:52:51 +08:00
|
|
|
int lookupopts;
|
1995-12-13 23:57:59 +08:00
|
|
|
StringBuf sb;
|
1995-12-14 23:52:51 +08:00
|
|
|
char *s = NULL;
|
1995-12-12 06:52:59 +08:00
|
|
|
|
1995-12-13 23:57:59 +08:00
|
|
|
struct PackageRec *cur_package = NULL;
|
1995-12-13 01:53:17 +08:00
|
|
|
Spec spec = (struct SpecRec *) malloc(sizeof(struct SpecRec));
|
1995-12-13 23:57:59 +08:00
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
spec->name = NULL;
|
1995-12-13 23:57:59 +08:00
|
|
|
spec->prep = newStringBuf();
|
|
|
|
spec->build = newStringBuf();
|
|
|
|
spec->install = newStringBuf();
|
|
|
|
spec->clean = newStringBuf();
|
|
|
|
spec->packages = NULL;
|
1995-11-28 06:31:21 +08:00
|
|
|
|
1995-12-13 23:57:59 +08:00
|
|
|
sb = newStringBuf();
|
|
|
|
reset_spec(); /* Reset the parser */
|
1995-11-28 06:31:21 +08:00
|
|
|
|
1995-12-13 23:57:59 +08:00
|
|
|
cur_part = PREAMBLE_PART;
|
1995-12-18 22:56:49 +08:00
|
|
|
while ((x = read_line(f, buf)) > 0) {
|
|
|
|
line = buf;
|
1995-12-14 23:52:51 +08:00
|
|
|
s = NULL;
|
1995-12-13 01:53:17 +08:00
|
|
|
if ((tag = check_part(line, &s))) {
|
1995-12-20 05:06:39 +08:00
|
|
|
message(MESS_DEBUG, "Switching to part: %d\n", tag);
|
1995-12-19 02:44:16 +08:00
|
|
|
t1 = 0;
|
1995-12-13 23:57:59 +08:00
|
|
|
switch (cur_part) {
|
|
|
|
case PREIN_PART:
|
|
|
|
t1 = RPMTAG_PREIN;
|
1995-12-19 02:44:16 +08:00
|
|
|
break;
|
1995-12-13 23:57:59 +08:00
|
|
|
case POSTIN_PART:
|
|
|
|
t1 = RPMTAG_POSTIN;
|
1995-12-19 02:44:16 +08:00
|
|
|
break;
|
1995-12-13 23:57:59 +08:00
|
|
|
case PREUN_PART:
|
|
|
|
t1 = RPMTAG_PREUN;
|
1995-12-19 02:44:16 +08:00
|
|
|
break;
|
1995-12-13 23:57:59 +08:00
|
|
|
case POSTUN_PART:
|
|
|
|
t1 = RPMTAG_POSTUN;
|
1995-12-19 02:44:16 +08:00
|
|
|
break;
|
1995-12-21 07:30:46 +08:00
|
|
|
case CHANGELOG_PART:
|
|
|
|
t1 = RPMTAG_CHANGELOG;
|
|
|
|
break;
|
1995-12-19 02:44:16 +08:00
|
|
|
}
|
|
|
|
if (t1) {
|
1995-12-13 23:57:59 +08:00
|
|
|
addEntry(cur_package->header, t1,
|
|
|
|
STRING_TYPE, getStringBuf(sb), 1);
|
|
|
|
}
|
|
|
|
cur_part = tag;
|
|
|
|
truncStringBuf(sb);
|
1995-12-14 23:52:51 +08:00
|
|
|
|
|
|
|
/* Now switch the current package to s */
|
|
|
|
if (s) {
|
|
|
|
switch (tag) {
|
|
|
|
case PREP_PART:
|
|
|
|
case BUILD_PART:
|
|
|
|
case INSTALL_PART:
|
|
|
|
case CLEAN_PART:
|
1995-12-21 07:30:46 +08:00
|
|
|
case CHANGELOG_PART:
|
1995-12-14 23:52:51 +08:00
|
|
|
error(RPMERR_BADARG, "Tag takes no arguments: %s", s);
|
1995-12-18 22:56:49 +08:00
|
|
|
return NULL;
|
1995-12-14 23:52:51 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1995-12-21 07:30:46 +08:00
|
|
|
/* Handle -n in part tags */
|
|
|
|
lookupopts = 0;
|
|
|
|
if (s) {
|
|
|
|
if (!strncmp(s, "-n", 2)) {
|
|
|
|
s += 2;
|
|
|
|
s += strspn(s, ": \t");
|
|
|
|
if (*s == '\0') {
|
|
|
|
error(RPMERR_BADARG, "-n takes argument");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
lookupopts = LP_NEWNAME;
|
|
|
|
} else {
|
|
|
|
lookupopts = LP_SUBNAME;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tag == PREAMBLE_PART) {
|
|
|
|
lookupopts |= LP_CREATE | LP_FAIL_EXISTS;
|
|
|
|
}
|
|
|
|
|
1995-12-14 23:52:51 +08:00
|
|
|
if (! lookup_package(spec, &cur_package, s, lookupopts)) {
|
|
|
|
error(RPMERR_INTERNAL, "Package lookup failed!");
|
1995-12-18 22:56:49 +08:00
|
|
|
return NULL;
|
1995-12-14 23:52:51 +08:00
|
|
|
}
|
|
|
|
|
1995-12-20 05:06:39 +08:00
|
|
|
message(MESS_DEBUG, "Switched to package: %s\n", s);
|
1995-12-20 01:56:45 +08:00
|
|
|
|
|
|
|
if (cur_part == FILES_PART) {
|
1995-12-21 07:30:46 +08:00
|
|
|
/* set files to 0 (current -1 means no %files, no package */
|
1995-12-20 01:56:45 +08:00
|
|
|
cur_package->files = 0;
|
|
|
|
}
|
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
continue;
|
|
|
|
}
|
1995-12-14 23:52:51 +08:00
|
|
|
|
|
|
|
/* Check for implicit "base" package */
|
|
|
|
if (! cur_package) {
|
|
|
|
lookupopts = 0;
|
|
|
|
if (cur_part == PREAMBLE_PART) {
|
|
|
|
lookupopts = LP_CREATE | LP_FAIL_EXISTS;
|
|
|
|
}
|
|
|
|
if (! lookup_package(spec, &cur_package, NULL, lookupopts)) {
|
|
|
|
error(RPMERR_INTERNAL, "Base package lookup failed!");
|
1995-12-18 22:56:49 +08:00
|
|
|
return NULL;
|
1995-12-14 23:52:51 +08:00
|
|
|
}
|
1995-12-20 05:06:39 +08:00
|
|
|
message(MESS_DEBUG, "Switched to BASE package\n");
|
1995-12-14 23:52:51 +08:00
|
|
|
}
|
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
switch (cur_part) {
|
|
|
|
case PREAMBLE_PART:
|
|
|
|
if ((tag = find_preamble_line(line, &s))) {
|
|
|
|
switch (tag) {
|
|
|
|
case RPMTAG_NAME:
|
1995-12-14 23:52:51 +08:00
|
|
|
if (!spec->name) {
|
|
|
|
spec->name = strdup(s);
|
|
|
|
}
|
1995-12-13 01:53:17 +08:00
|
|
|
case RPMTAG_VERSION:
|
|
|
|
case RPMTAG_RELEASE:
|
|
|
|
case RPMTAG_SERIAL:
|
|
|
|
case RPMTAG_SUMMARY:
|
|
|
|
case RPMTAG_DESCRIPTION:
|
|
|
|
case RPMTAG_DISTRIBUTION:
|
|
|
|
case RPMTAG_VENDOR:
|
|
|
|
case RPMTAG_COPYRIGHT:
|
|
|
|
case RPMTAG_PACKAGER:
|
|
|
|
case RPMTAG_GROUP:
|
|
|
|
case RPMTAG_URL:
|
1995-12-13 23:57:59 +08:00
|
|
|
addEntry(cur_package->header, tag, STRING_TYPE, s, 1);
|
1995-12-13 01:53:17 +08:00
|
|
|
break;
|
|
|
|
default:
|
1995-12-20 05:06:39 +08:00
|
|
|
message(MESS_DEBUG, "Skipping: %s\n", line);
|
1995-12-13 01:53:17 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Not a recognized preamble part */
|
1995-12-20 05:06:39 +08:00
|
|
|
message(MESS_DEBUG, "Unknown Field: %s\n", line);
|
1995-12-13 01:53:17 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PREP_PART:
|
1995-12-13 23:57:59 +08:00
|
|
|
appendLineStringBuf(spec->prep, line);
|
|
|
|
break;
|
1995-12-13 01:53:17 +08:00
|
|
|
case BUILD_PART:
|
1995-12-13 23:57:59 +08:00
|
|
|
appendLineStringBuf(spec->build, line);
|
|
|
|
break;
|
1995-12-13 01:53:17 +08:00
|
|
|
case INSTALL_PART:
|
1995-12-13 23:57:59 +08:00
|
|
|
appendLineStringBuf(spec->install, line);
|
|
|
|
break;
|
1995-12-13 01:53:17 +08:00
|
|
|
case CLEAN_PART:
|
1995-12-13 23:57:59 +08:00
|
|
|
appendLineStringBuf(spec->clean, line);
|
1995-12-13 01:53:17 +08:00
|
|
|
break;
|
1995-12-21 07:30:46 +08:00
|
|
|
case CHANGELOG_PART:
|
1995-12-13 01:53:17 +08:00
|
|
|
case PREIN_PART:
|
|
|
|
case POSTIN_PART:
|
|
|
|
case PREUN_PART:
|
|
|
|
case POSTUN_PART:
|
1995-12-13 23:57:59 +08:00
|
|
|
appendLineStringBuf(sb, line);
|
1995-12-13 01:53:17 +08:00
|
|
|
break;
|
|
|
|
case FILES_PART:
|
1995-12-14 23:52:51 +08:00
|
|
|
cur_package->files++;
|
1995-12-13 23:57:59 +08:00
|
|
|
appendLineStringBuf(cur_package->filelist, line);
|
1995-12-13 01:53:17 +08:00
|
|
|
break;
|
|
|
|
default:
|
1995-12-14 23:52:51 +08:00
|
|
|
error(RPMERR_INTERNAL, "Bad part");
|
1995-12-18 22:56:49 +08:00
|
|
|
return NULL;
|
1995-12-14 23:52:51 +08:00
|
|
|
} /* switch */
|
1995-11-28 06:31:21 +08:00
|
|
|
}
|
|
|
|
if (x < 0) {
|
1995-12-18 22:56:49 +08:00
|
|
|
error(RPMERR_READERROR, "Error reading specfile");
|
1995-11-28 06:31:21 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
1995-12-13 23:57:59 +08:00
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
return spec;
|
|
|
|
}
|
|
|
|
|
1995-12-14 23:52:51 +08:00
|
|
|
/**********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Resets the parser */
|
|
|
|
/* */
|
|
|
|
/**********************************************************************/
|
|
|
|
|
1995-12-13 01:53:17 +08:00
|
|
|
static void reset_spec()
|
|
|
|
{
|
|
|
|
static done = 0;
|
|
|
|
struct read_level_entry *rl;
|
|
|
|
struct preamble_line *p = preamble_spec;
|
|
|
|
struct part_rec *p1 = part_list;
|
|
|
|
|
|
|
|
while (read_level) {
|
|
|
|
rl = read_level;
|
|
|
|
read_level = read_level->next;
|
|
|
|
free(rl);
|
|
|
|
}
|
|
|
|
read_level = malloc(sizeof(struct read_level_entry));
|
|
|
|
read_level->next = NULL;
|
|
|
|
read_level->reading = 1;
|
|
|
|
|
|
|
|
if (! done) {
|
|
|
|
/* Put one time only things in here */
|
|
|
|
while (p->tag) {
|
|
|
|
p->len = strlen(p->token);
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
while (p1->part) {
|
|
|
|
p1->len = strlen(p1->s);
|
|
|
|
p1++;
|
|
|
|
}
|
|
|
|
|
|
|
|
done = 1;
|
|
|
|
}
|
1995-11-28 06:31:21 +08:00
|
|
|
}
|
1995-12-18 22:56:49 +08:00
|
|
|
|
|
|
|
/**********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Spec struct dumping (for debugging) */
|
|
|
|
/* */
|
|
|
|
/**********************************************************************/
|
|
|
|
|
|
|
|
void dumpSpec(Spec s, FILE *f)
|
|
|
|
{
|
|
|
|
struct PackageRec *p;
|
|
|
|
|
|
|
|
fprintf(f, "########################################################\n");
|
|
|
|
fprintf(f, "SPEC NAME = (%s)\n", s->name);
|
|
|
|
fprintf(f, "PREP =v\n");
|
|
|
|
fprintf(f, "%s", getStringBuf(s->prep));
|
|
|
|
fprintf(f, "PREP =^\n");
|
|
|
|
fprintf(f, "BUILD =v\n");
|
|
|
|
fprintf(f, "%s", getStringBuf(s->build));
|
|
|
|
fprintf(f, "BUILD =^\n");
|
|
|
|
fprintf(f, "INSTALL =v\n");
|
|
|
|
fprintf(f, "%s", getStringBuf(s->install));
|
|
|
|
fprintf(f, "INSTALL =^\n");
|
|
|
|
fprintf(f, "CLEAN =v\n");
|
|
|
|
fprintf(f, "%s", getStringBuf(s->clean));
|
|
|
|
fprintf(f, "CLEAN =^\n");
|
|
|
|
|
|
|
|
p = s->packages;
|
|
|
|
while (p) {
|
|
|
|
dumpPackage(p, f);
|
|
|
|
p = p->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dumpPackage(struct PackageRec *p, FILE *f)
|
|
|
|
{
|
|
|
|
fprintf(f, "_________________________________________________________\n");
|
|
|
|
fprintf(f, "SUBNAME = (%s)\n", p->subname);
|
|
|
|
fprintf(f, "NEWNAME = (%s)\n", p->newname);
|
|
|
|
fprintf(f, "FILES = %d\n", p->files);
|
|
|
|
fprintf(f, "FILES =v\n");
|
|
|
|
fprintf(f, "%s", getStringBuf(p->filelist));
|
|
|
|
fprintf(f, "FILES =^\n");
|
|
|
|
fprintf(f, "HEADER =v\n");
|
|
|
|
dumpHeader(p->header, f, 1);
|
|
|
|
fprintf(f, "HEADER =^\n");
|
|
|
|
|
|
|
|
}
|