2002-03-25 23:16:26 +03:00
/** \ingroup rpmbuild
* \ file build / parseSpec . c
* Top level dispatcher for spec file parsing .
*/
# include "system.h"
/*@unchecked@*/
static int _debug = 0 ;
2002-03-26 02:09:32 +03:00
extern char * _rpm_nosource , * _rpm_nopatch ;
2002-03-26 01:02:39 +03:00
# include "rpmio_internal.h"
# include "rpmbuild.h"
2002-03-25 23:16:26 +03:00
# include "debug.h"
/*@access FD_t @*/ /* compared with NULL */
/**
*/
/*@unchecked@*/
static struct PartRec {
int part ;
int len ;
/*@observer@*/ /*@null@*/ const char * token ;
} partList [ ] = {
{ PART_PREAMBLE , 0 , " %package " } ,
{ PART_PREP , 0 , " %prep " } ,
{ PART_BUILD , 0 , " %build " } ,
{ PART_INSTALL , 0 , " %install " } ,
{ PART_CLEAN , 0 , " %clean " } ,
{ PART_PREUN , 0 , " %preun " } ,
{ PART_POSTUN , 0 , " %postun " } ,
{ PART_PRE , 0 , " %pre " } ,
{ PART_POST , 0 , " %post " } ,
{ PART_FILES , 0 , " %files " } ,
{ PART_CHANGELOG , 0 , " %changelog " } ,
{ PART_DESCRIPTION , 0 , " %description " } ,
{ PART_TRIGGERPOSTUN , 0 , " %triggerpostun " } ,
{ PART_TRIGGERUN , 0 , " %triggerun " } ,
{ PART_TRIGGERIN , 0 , " %triggerin " } ,
{ PART_TRIGGERIN , 0 , " %trigger " } ,
{ PART_VERIFYSCRIPT , 0 , " %verifyscript " } ,
{ 0 , 0 , 0 }
} ;
/**
*/
static inline void initParts ( struct PartRec * p )
/*@modifies p->len @*/
{
for ( ; p - > token ! = NULL ; p + + )
p - > len = strlen ( p - > token ) ;
}
rpmParseState isPart ( const char * line )
{
struct PartRec * p ;
if ( partList [ 0 ] . len = = 0 )
initParts ( partList ) ;
for ( p = partList ; p - > token ! = NULL ; p + + ) {
char c ;
if ( xstrncasecmp ( line , p - > token , p - > len ) )
continue ;
c = * ( line + p - > len ) ;
if ( c = = ' \0 ' | | xisspace ( c ) )
break ;
}
return ( p - > token ? p - > part : PART_NONE ) ;
}
/**
*/
static int matchTok ( const char * token , const char * line )
/*@*/
{
const char * b , * be = line ;
size_t toklen = strlen ( token ) ;
int rc = 0 ;
while ( * ( b = be ) ! = ' \0 ' ) {
SKIPSPACE ( b ) ;
be = b ;
SKIPNONSPACE ( be ) ;
if ( be = = b )
break ;
if ( toklen ! = ( be - b ) | | xstrncasecmp ( token , b , ( be - b ) ) )
continue ;
rc = 1 ;
break ;
}
return rc ;
}
void handleComments ( char * s )
{
SKIPSPACE ( s ) ;
if ( * s = = ' # ' )
* s = ' \0 ' ;
}
/**
*/
static void forceIncludeFile ( Spec spec , const char * fileName )
/*@modifies spec->fileStack @*/
{
OFI_t * ofi ;
ofi = newOpenFileInfo ( ) ;
ofi - > fileName = xstrdup ( fileName ) ;
ofi - > next = spec - > fileStack ;
spec - > fileStack = ofi ;
}
/**
*/
static int copyNextLine ( Spec spec , OFI_t * ofi , int strip )
/*@globals rpmGlobalMacroContext,
fileSystem @ */
/*@modifies spec->nextline, spec->nextpeekc, spec->lbuf, spec->line,
ofi - > readPtr ,
rpmGlobalMacroContext , fileSystem @ */
{
char * last ;
char ch ;
/* Restore 1st char in (possible) next line */
if ( spec - > nextline ! = NULL & & spec - > nextpeekc ! = ' \0 ' ) {
* spec - > nextline = spec - > nextpeekc ;
spec - > nextpeekc = ' \0 ' ;
}
/* Expand next line from file into line buffer */
if ( ! ( spec - > nextline & & * spec - > nextline ) ) {
2005-10-10 16:57:57 +04:00
int pc = 0 , bc = 0 , nc = 0 ;
char * from , * to , * p ;
to = spec - > lbufPtr ? spec - > lbufPtr : spec - > lbuf ;
2002-03-25 23:16:26 +03:00
from = ofi - > readPtr ;
ch = ' ' ;
while ( * from & & ch ! = ' \n ' )
ch = * to + + = * from + + ;
2005-10-10 16:57:57 +04:00
spec - > lbufPtr = to ;
2002-03-25 23:16:26 +03:00
* to + + = ' \0 ' ;
ofi - > readPtr = from ;
2005-10-10 16:57:57 +04:00
/* Check if we need another line before expanding the buffer. */
for ( p = spec - > lbuf ; * p ; p + + ) {
switch ( * p ) {
case ' \\ ' :
switch ( * ( p + 1 ) ) {
case ' \n ' : p + + , nc = 1 ; break ;
case ' \0 ' : break ;
default : p + + ; break ;
}
break ;
case ' \n ' : nc = 0 ; break ;
case ' % ' :
switch ( * ( p + 1 ) ) {
case ' { ' : p + + , bc + + ; break ;
case ' ( ' : p + + , pc + + ; break ;
case ' % ' : p + + ; break ;
}
break ;
case ' { ' : if ( bc > 0 ) bc + + ; break ;
case ' } ' : if ( bc > 0 ) bc - - ; break ;
case ' ( ' : if ( pc > 0 ) pc + + ; break ;
case ' ) ' : if ( pc > 0 ) pc - - ; break ;
}
}
/* If it doesn't, ask for one more line. We need a better
* error code for this . */
if ( pc | | bc | | nc ) {
spec - > nextline = " " ;
return RPMERR_UNMATCHEDIF ;
}
spec - > lbufPtr = spec - > lbuf ;
2002-03-25 23:16:26 +03:00
/* Don't expand macros (eg. %define) in false branch of %if clause */
if ( spec - > readStack - > reading & &
expandMacros ( spec , spec - > macros , spec - > lbuf , sizeof ( spec - > lbuf ) ) ) {
rpmError ( RPMERR_BADSPEC , _ ( " line %d: %s \n " ) ,
spec - > lineNum , spec - > lbuf ) ;
return RPMERR_BADSPEC ;
}
spec - > nextline = spec - > lbuf ;
}
/* Find next line in expanded line buffer */
spec - > line = last = spec - > nextline ;
ch = ' ' ;
while ( * spec - > nextline & & ch ! = ' \n ' ) {
ch = * spec - > nextline + + ;
if ( ! xisspace ( ch ) )
last = spec - > nextline ;
}
/* Save 1st char of next line in order to terminate current line. */
if ( * spec - > nextline ! = ' \0 ' ) {
spec - > nextpeekc = * spec - > nextline ;
* spec - > nextline = ' \0 ' ;
}
if ( strip & STRIP_COMMENTS )
handleComments ( spec - > line ) ;
if ( strip & STRIP_TRAILINGSPACE )
* last = ' \0 ' ;
return 0 ;
}
int readLine ( Spec spec , int strip )
{
# ifdef DYING
const char * arch ;
const char * os ;
# endif
char * s ;
int match ;
struct ReadLevelEntry * rl ;
OFI_t * ofi = spec - > fileStack ;
int rc ;
retry :
/* Make sure the current file is open */
/*@-branchstate@*/
if ( ofi - > fd = = NULL ) {
ofi - > fd = Fopen ( ofi - > fileName , " r.fpio " ) ;
if ( ofi - > fd = = NULL | | Ferror ( ofi - > fd ) ) {
/* XXX Fstrerror */
rpmError ( RPMERR_BADSPEC , _ ( " Unable to open %s: %s \n " ) ,
ofi - > fileName , Fstrerror ( ofi - > fd ) ) ;
return RPMERR_BADSPEC ;
}
spec - > lineNum = ofi - > lineNum = 0 ;
}
/*@=branchstate@*/
/* Make sure we have something in the read buffer */
if ( ! ( ofi - > readPtr & & * ( ofi - > readPtr ) ) ) {
/*@-type@*/ /* FIX: cast? */
FILE * f = fdGetFp ( ofi - > fd ) ;
/*@=type@*/
if ( f = = NULL | | ! fgets ( ofi - > readBuf , BUFSIZ , f ) ) {
/* EOF */
if ( spec - > readStack - > next ) {
rpmError ( RPMERR_UNMATCHEDIF , _ ( " Unclosed %%if \n " ) ) ;
return RPMERR_UNMATCHEDIF ;
}
/* remove this file from the stack */
spec - > fileStack = ofi - > next ;
( void ) Fclose ( ofi - > fd ) ;
ofi - > fileName = _free ( ofi - > fileName ) ;
ofi = _free ( ofi ) ;
/* only on last file do we signal EOF to caller */
ofi = spec - > fileStack ;
if ( ofi = = NULL )
return 1 ;
/* otherwise, go back and try the read again. */
goto retry ;
}
ofi - > readPtr = ofi - > readBuf ;
ofi - > lineNum + + ;
spec - > lineNum = ofi - > lineNum ;
if ( spec - > sl ) {
speclines sl = spec - > sl ;
if ( sl - > sl_nlines = = sl - > sl_nalloc ) {
sl - > sl_nalloc + = 100 ;
sl - > sl_lines = ( char * * ) xrealloc ( sl - > sl_lines ,
sl - > sl_nalloc * sizeof ( * ( sl - > sl_lines ) ) ) ;
}
sl - > sl_lines [ sl - > sl_nlines + + ] = xstrdup ( ofi - > readBuf ) ;
}
}
# ifdef DYING
arch = NULL ;
rpmGetArchInfo ( & arch , NULL ) ;
os = NULL ;
rpmGetOsInfo ( & os , NULL ) ;
# endif
/* Copy next file line into the spec line buffer */
2005-10-10 16:57:57 +04:00
if ( ( rc = copyNextLine ( spec , ofi , strip ) ) ! = 0 ) {
if ( rc = = RPMERR_UNMATCHEDIF )
goto retry ;
2002-03-25 23:16:26 +03:00
return rc ;
2005-10-10 16:57:57 +04:00
}
2002-03-25 23:16:26 +03:00
s = spec - > line ;
SKIPSPACE ( s ) ;
match = - 1 ;
2005-10-10 16:50:41 +04:00
if ( ! spec - > readStack - > reading & & ! strncmp ( " %if " , s , sizeof ( " %if " ) - 1 ) ) {
match = 0 ;
} else if ( ! strncmp ( " %ifarch " , s , sizeof ( " %ifarch " ) - 1 ) ) {
2002-03-25 23:16:26 +03:00
const char * arch = rpmExpand ( " %{_target_cpu} " , NULL ) ;
s + = 7 ;
match = matchTok ( arch , s ) ;
arch = _free ( arch ) ;
} else if ( ! strncmp ( " %ifnarch " , s , sizeof ( " %ifnarch " ) - 1 ) ) {
const char * arch = rpmExpand ( " %{_target_cpu} " , NULL ) ;
s + = 8 ;
match = ! matchTok ( arch , s ) ;
arch = _free ( arch ) ;
} else if ( ! strncmp ( " %ifos " , s , sizeof ( " %ifos " ) - 1 ) ) {
const char * os = rpmExpand ( " %{_target_os} " , NULL ) ;
s + = 5 ;
match = matchTok ( os , s ) ;
os = _free ( os ) ;
} else if ( ! strncmp ( " %ifnos " , s , sizeof ( " %ifnos " ) - 1 ) ) {
const char * os = rpmExpand ( " %{_target_os} " , NULL ) ;
s + = 6 ;
match = ! matchTok ( os , s ) ;
os = _free ( os ) ;
} else if ( ! strncmp ( " %if " , s , sizeof ( " %if " ) - 1 ) ) {
s + = 3 ;
match = parseExpressionBoolean ( spec , s ) ;
if ( match < 0 ) {
rpmError ( RPMERR_UNMATCHEDIF ,
_ ( " %s:%d: parseExpressionBoolean returns %d \n " ) ,
ofi - > fileName , ofi - > lineNum , match ) ;
return RPMERR_BADSPEC ;
}
} else if ( ! strncmp ( " %else " , s , sizeof ( " %else " ) - 1 ) ) {
s + = 5 ;
if ( ! spec - > readStack - > next ) {
/* Got an else with no %if ! */
rpmError ( RPMERR_UNMATCHEDIF ,
_ ( " %s:%d: Got a %%else with no %%if \n " ) ,
ofi - > fileName , ofi - > lineNum ) ;
return RPMERR_UNMATCHEDIF ;
}
spec - > readStack - > reading =
spec - > readStack - > next - > reading & & ! spec - > readStack - > reading ;
spec - > line [ 0 ] = ' \0 ' ;
} else if ( ! strncmp ( " %endif " , s , sizeof ( " %endif " ) - 1 ) ) {
s + = 6 ;
if ( ! spec - > readStack - > next ) {
/* Got an end with no %if ! */
rpmError ( RPMERR_UNMATCHEDIF ,
_ ( " %s:%d: Got a %%endif with no %%if \n " ) ,
ofi - > fileName , ofi - > lineNum ) ;
return RPMERR_UNMATCHEDIF ;
}
rl = spec - > readStack ;
spec - > readStack = spec - > readStack - > next ;
free ( rl ) ;
spec - > line [ 0 ] = ' \0 ' ;
} else if ( ! strncmp ( " %include " , s , sizeof ( " %include " ) - 1 ) ) {
char * fileName , * endFileName , * p ;
s + = 8 ;
fileName = s ;
if ( ! xisspace ( * fileName ) ) {
rpmError ( RPMERR_BADSPEC , _ ( " malformed %%include statement \n " ) ) ;
return RPMERR_BADSPEC ;
}
SKIPSPACE ( fileName ) ;
endFileName = fileName ;
SKIPNONSPACE ( endFileName ) ;
p = endFileName ;
SKIPSPACE ( p ) ;
if ( * p ! = ' \0 ' ) {
rpmError ( RPMERR_BADSPEC , _ ( " malformed %%include statement \n " ) ) ;
return RPMERR_BADSPEC ;
}
* endFileName = ' \0 ' ;
forceIncludeFile ( spec , fileName ) ;
ofi = spec - > fileStack ;
goto retry ;
}
if ( match ! = - 1 ) {
rl = xmalloc ( sizeof ( * rl ) ) ;
rl - > reading = spec - > readStack - > reading & & match ;
rl - > next = spec - > readStack ;
spec - > readStack = rl ;
spec - > line [ 0 ] = ' \0 ' ;
}
if ( ! spec - > readStack - > reading ) {
spec - > line [ 0 ] = ' \0 ' ;
}
2002-03-26 02:09:32 +03:00
if ( spec - > preprocess_mode ) {
char * chomped = xstrdup ( spec - > line ) ;
int len = strlen ( chomped ) ;
if ( ' \n ' = = chomped [ len - 1 ] )
chomped [ len - 1 ] = ' \0 ' ;
puts ( chomped ) ;
chomped = _free ( chomped ) ;
}
2002-03-25 23:16:26 +03:00
/*@-compmempass@*/ /* FIX: spec->readStack->next should be dependent */
return 0 ;
/*@=compmempass@*/
}
void closeSpec ( Spec spec )
{
OFI_t * ofi ;
while ( spec - > fileStack ) {
ofi = spec - > fileStack ;
spec - > fileStack = spec - > fileStack - > next ;
if ( ofi - > fd ) ( void ) Fclose ( ofi - > fd ) ;
ofi - > fileName = _free ( ofi - > fileName ) ;
ofi = _free ( ofi ) ;
}
}
/*@-redecl@*/
/*@unchecked@*/
extern int noLang ; /* XXX FIXME: pass as arg */
/*@=redecl@*/
2005-10-06 22:21:26 +04:00
typedef struct tags_struct {
int len ;
const char * token ;
} tags_struct ;
static int
comp_tags ( const void * m1 , const void * m2 )
{
tags_struct * p1 = ( tags_struct * ) m1 ;
tags_struct * p2 = ( tags_struct * ) m2 ;
int len = ( p1 - > len < p2 - > len ) ? p1 - > len : p2 - > len ;
int rc = strncasecmp ( p1 - > token , p2 - > token , len ) ;
if ( rc )
return rc ;
return p1 - > len - p2 - > len ;
}
# define nr_of_tags(list) (sizeof(list) / sizeof(list[0]))
static tags_struct tags_common_list [ ] = {
{ 0 , " build " } ,
{ 0 , " changelog " } ,
{ 0 , " clean " } ,
{ 0 , " description " } ,
{ 0 , " else " } ,
{ 0 , " endif " } ,
{ 0 , " files " } ,
{ 0 , " if " } ,
{ 0 , " ifarch " } ,
{ 0 , " ifnarch " } ,
{ 0 , " ifnos " } ,
{ 0 , " ifos " } ,
{ 0 , " include " } ,
{ 0 , " install " } ,
{ 0 , " package " } ,
{ 0 , " post " } ,
{ 0 , " postun " } ,
{ 0 , " pre " } ,
{ 0 , " prep " } ,
{ 0 , " preun " } ,
{ 0 , " trigger " } ,
{ 0 , " triggerin " } ,
{ 0 , " triggerpostun " } ,
{ 0 , " triggerun " } ,
{ 0 , " verifyscript " }
} ;
static tags_struct tags_files_list [ ] = {
{ 0 , " attr " } ,
{ 0 , " config " } ,
{ 0 , " defattr " } ,
{ 0 , " defverify " } ,
{ 0 , " dev " } ,
{ 0 , " dir " } ,
{ 0 , " doc " } ,
2005-10-10 16:26:34 +04:00
{ 0 , " docdir " } ,
2005-10-06 22:21:26 +04:00
{ 0 , " exclude " } ,
{ 0 , " ghost " } ,
{ 0 , " lang " } ,
{ 0 , " license " } ,
{ 0 , " multilib " } ,
{ 0 , " readme " } ,
{ 0 , " verify " } ,
} ;
static const char *
is_builtin_tag ( const char * line , int len , tags_struct * tlist , size_t nlist )
{
int i ;
tags_struct key ;
if ( tlist [ 0 ] . len = = 0 )
{
for ( i = 0 ; i < nlist ; + + i )
tlist [ i ] . len = strlen ( tlist [ i ] . token ) ;
qsort ( tlist , nlist , sizeof ( tags_struct ) , comp_tags ) ;
}
for ( i = 0 ; i < len ; + + i )
{
if ( line [ i ] = = ' \0 ' | | line [ i ] = = ' ( ' | | xisspace ( line [ i ] ) )
{
len = i ;
break ;
}
}
key . token = line ;
key . len = len ;
if ( bsearch
( & key , tlist , nlist , sizeof ( tags_struct ) , comp_tags ) )
return line ;
return NULL ;
}
static const char *
is_builtin_preamble_tag ( const char * line , int len )
{
return is_builtin_tag ( line , len , tags_common_list , nr_of_tags ( tags_common_list ) ) ;
}
static const char *
is_builtin_prep_tag ( const char * line , int len )
{
int i ;
const char * rc ;
for ( i = 0 ; i < len ; + + i )
{
if ( line [ i ] = = ' \0 ' | | xisspace ( line [ i ] ) )
{
len = i ;
break ;
}
}
if ( ( rc = is_builtin_tag ( line , len , tags_common_list , nr_of_tags ( tags_common_list ) ) ) )
return rc ;
if ( len = = 5 & & ! strncasecmp ( line , " setup " , 5 ) )
return line ;
if ( len > = 5 & & ! strncasecmp ( line , " patch " , 5 ) )
{
for ( i = 5 ; i < len ; + + i )
if ( ! xisdigit ( line [ i ] ) )
break ;
if ( i > = len )
return line ;
}
return 0 ;
}
static const char *
is_builtin_build_tag ( const char * line , int len )
{
return is_builtin_tag ( line , len , tags_common_list , nr_of_tags ( tags_common_list ) ) ;
}
2005-10-13 03:35:17 +04:00
static const char *
is_builtin_changelog_tag ( const char * line , int len )
{
return is_builtin_tag ( line , len , tags_common_list , nr_of_tags ( tags_common_list ) ) ;
}
2005-10-06 22:21:26 +04:00
static const char *
is_builtin_description_tag ( const char * line , int len )
{
return is_builtin_tag ( line , len , tags_common_list , nr_of_tags ( tags_common_list ) ) ;
}
static const char *
is_builtin_script_tag ( const char * line , int len )
{
return is_builtin_tag ( line , len , tags_common_list , nr_of_tags ( tags_common_list ) ) ;
}
static const char *
is_builtin_files_tag ( const char * line , int len )
{
const char * rc ;
if ( ( rc = is_builtin_tag ( line , len , tags_common_list , nr_of_tags ( tags_common_list ) ) ) )
return rc ;
return is_builtin_tag ( line , len , tags_files_list , nr_of_tags ( tags_files_list ) ) ;
}
2002-03-25 23:16:26 +03:00
/*@todo Skip parse recursion if os is not compatible. @*/
int parseSpec ( Spec * specp , const char * specFile , const char * rootURL ,
const char * buildRootURL , int recursing , const char * passPhrase ,
2002-03-26 02:09:32 +03:00
char * cookie , int anyarch , int force , int preprocess )
2002-03-25 23:16:26 +03:00
{
rpmParseState parsePart = PART_PREAMBLE ;
int initialPackage = 1 ;
# ifdef DYING
const char * saveArch ;
# endif
Package pkg ;
Spec spec ;
/* Set up a new Spec structure with no packages. */
spec = newSpec ( ) ;
/*
* Note : rpmGetPath should guarantee a " canonical " path . That means
* that the following pathologies should be weeded out :
* //bin//sh
* //usr//bin/
* / . . / . / . . / usr / . . / bin //./sh (XXX FIXME: dots not handled yet)
*/
spec - > specFile = rpmGetPath ( specFile , NULL ) ;
spec - > fileStack = newOpenFileInfo ( ) ;
spec - > fileStack - > fileName = xstrdup ( spec - > specFile ) ;
2002-03-26 02:09:32 +03:00
spec - > preprocess_mode = preprocess ;
2002-03-25 23:16:26 +03:00
if ( buildRootURL ) {
const char * buildRoot ;
( void ) urlPath ( buildRootURL , & buildRoot ) ;
/*@-branchstate@*/
if ( * buildRoot = = ' \0 ' ) buildRoot = " / " ;
/*@=branchstate@*/
if ( ! strcmp ( buildRoot , " / " ) ) {
rpmError ( RPMERR_BADSPEC ,
_ ( " BuildRoot can not be \" / \" : %s \n " ) , buildRootURL ) ;
return RPMERR_BADSPEC ;
}
spec - > gotBuildRootURL = 1 ;
spec - > buildRootURL = xstrdup ( buildRootURL ) ;
addMacro ( spec - > macros , " buildroot " , NULL , buildRoot , RMIL_SPEC ) ;
if ( _debug )
fprintf ( stderr , " *** PS buildRootURL(%s) %p macro set to %s \n " , spec - > buildRootURL , spec - > buildRootURL , buildRoot ) ;
}
addMacro ( NULL , " _docdir " , NULL , " %{_defaultdocdir} " , RMIL_SPEC ) ;
spec - > recursing = recursing ;
spec - > anyarch = anyarch ;
spec - > force = force ;
if ( rootURL )
spec - > rootURL = xstrdup ( rootURL ) ;
if ( passPhrase )
spec - > passPhrase = xstrdup ( passPhrase ) ;
if ( cookie )
spec - > cookie = xstrdup ( cookie ) ;
2005-09-29 19:46:13 +04:00
spec - > timeCheck = rpmExpandNumeric ( " %{?_timecheck} " ) ;
2002-03-25 23:16:26 +03:00
/* 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. */
/*@-infloops@*/ /* LCL: parsePart is modified @*/
while ( parsePart < PART_LAST & & parsePart ! = PART_NONE ) {
2005-10-07 00:31:10 +04:00
rpmBuiltinMacroLookup saved_lookup = rpmSetBuiltinMacroLookup ( NULL ) ;
2005-10-13 03:35:17 +04:00
int saved_lookup_failed = rpmSetBuiltinMacroLookupFailedOK ( rpmExpandNumeric ( " %{?_allow_undefined_macros} " ) ) ;
2002-03-25 23:16:26 +03:00
switch ( parsePart ) {
case PART_PREAMBLE :
2005-10-13 03:35:17 +04:00
rpmSetBuiltinMacroLookup ( is_builtin_preamble_tag ) ;
2002-03-25 23:16:26 +03:00
parsePart = parsePreamble ( spec , initialPackage ) ;
initialPackage = 0 ;
/*@switchbreak@*/ break ;
case PART_PREP :
2005-10-13 03:35:17 +04:00
rpmSetBuiltinMacroLookup ( is_builtin_prep_tag ) ;
rpmSetBuiltinMacroLookupFailedOK ( 1 ) ;
2002-03-25 23:16:26 +03:00
parsePart = parsePrep ( spec ) ;
/*@switchbreak@*/ break ;
case PART_BUILD :
case PART_INSTALL :
case PART_CLEAN :
2005-10-13 03:35:17 +04:00
rpmSetBuiltinMacroLookup ( is_builtin_build_tag ) ;
rpmSetBuiltinMacroLookupFailedOK ( 1 ) ;
2002-03-25 23:16:26 +03:00
parsePart = parseBuildInstallClean ( spec , parsePart ) ;
/*@switchbreak@*/ break ;
case PART_CHANGELOG :
2005-10-13 03:35:17 +04:00
rpmSetBuiltinMacroLookup ( is_builtin_changelog_tag ) ;
rpmSetBuiltinMacroLookupFailedOK ( 1 ) ;
2002-03-25 23:16:26 +03:00
parsePart = parseChangelog ( spec ) ;
/*@switchbreak@*/ break ;
case PART_DESCRIPTION :
2005-10-13 03:35:17 +04:00
rpmSetBuiltinMacroLookup ( is_builtin_description_tag ) ;
2002-03-25 23:16:26 +03:00
parsePart = parseDescription ( spec ) ;
/*@switchbreak@*/ break ;
case PART_PRE :
case PART_POST :
case PART_PREUN :
case PART_POSTUN :
case PART_VERIFYSCRIPT :
case PART_TRIGGERIN :
case PART_TRIGGERUN :
case PART_TRIGGERPOSTUN :
2005-10-13 03:35:17 +04:00
rpmSetBuiltinMacroLookup ( is_builtin_script_tag ) ;
2002-03-25 23:16:26 +03:00
parsePart = parseScript ( spec , parsePart ) ;
/*@switchbreak@*/ break ;
case PART_FILES :
2005-10-13 03:35:17 +04:00
rpmSetBuiltinMacroLookup ( is_builtin_files_tag ) ;
2002-03-25 23:16:26 +03:00
parsePart = parseFiles ( spec ) ;
/*@switchbreak@*/ break ;
case PART_NONE : /* XXX avoid gcc whining */
case PART_LAST :
case PART_BUILDARCHITECTURES :
/*@switchbreak@*/ break ;
}
2005-10-07 00:31:10 +04:00
rpmSetBuiltinMacroLookup ( saved_lookup ) ;
2005-10-13 03:35:17 +04:00
rpmSetBuiltinMacroLookupFailedOK ( saved_lookup_failed ) ;
2002-03-25 23:16:26 +03:00
if ( parsePart > = PART_LAST ) {
spec = freeSpec ( spec ) ;
return parsePart ;
}
if ( parsePart = = PART_BUILDARCHITECTURES ) {
int index ;
int x ;
closeSpec ( spec ) ;
/* LCL: sizeof(spec->BASpecs[0]) -nullderef whine here */
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 ] ) )
/*@innercontinue@*/ continue ;
# ifdef DYING
rpmGetMachine ( & saveArch , NULL ) ;
saveArch = xstrdup ( saveArch ) ;
rpmSetMachine ( spec - > BANames [ x ] , NULL ) ;
# else
addMacro ( NULL , " _target_cpu " , NULL , spec - > BANames [ x ] , RMIL_RPMRC ) ;
# endif
spec - > BASpecs [ index ] = NULL ;
if ( parseSpec ( & ( spec - > BASpecs [ index ] ) ,
specFile , spec - > rootURL , buildRootURL , 1 ,
2002-03-26 02:09:32 +03:00
passPhrase , cookie , anyarch , force , preprocess ) )
2002-03-25 23:16:26 +03:00
{
spec - > BACount = index ;
spec = freeSpec ( spec ) ;
return RPMERR_BADSPEC ;
}
# ifdef DYING
rpmSetMachine ( saveArch , NULL ) ;
saveArch = _free ( saveArch ) ;
# else
delMacro ( NULL , " _target_cpu " ) ;
# endif
index + + ;
}
spec - > BACount = index ;
if ( ! index ) {
spec = freeSpec ( spec ) ;
rpmError ( RPMERR_BADSPEC ,
_ ( " No compatible architectures found for build \n " ) ) ;
return RPMERR_BADSPEC ;
}
/*
* Return the 1 st 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 .
*/
/*@-branchstate@*/
if ( spec - > BACount > = 1 ) {
Spec nspec = spec - > BASpecs [ 0 ] ;
spec - > BASpecs = _free ( spec - > BASpecs ) ;
spec = freeSpec ( spec ) ;
spec = nspec ;
}
/*@=branchstate@*/
* specp = spec ;
return 0 ;
}
}
/*@=infloops@*/ /* LCL: parsePart is modified @*/
/* Check for description in each package and add arch and os */
{
# ifdef DYING
const char * arch = NULL ;
const char * os = NULL ;
char * myos = NULL ;
rpmGetArchInfo ( & arch , NULL ) ;
rpmGetOsInfo ( & os , NULL ) ;
/*
* XXX Capitalizing the ' L ' is needed to insure that old
* XXX os - from - uname ( e . g . " Linux " ) is compatible with the new
* XXX os - from - platform ( e . g " linux " from " sparc-*-linux " ) .
* XXX A copy of this string is embedded in headers .
*/
if ( ! strcmp ( os , " linux " ) ) {
myos = xstrdup ( os ) ;
* myos = ' L ' ;
os = myos ;
}
# else
const char * platform = rpmExpand ( " %{_target_platform} " , NULL ) ;
const char * arch = rpmExpand ( " %{_target_cpu} " , NULL ) ;
const char * os = rpmExpand ( " %{_target_os} " , NULL ) ;
# endif
for ( pkg = spec - > packages ; pkg ! = NULL ; pkg = pkg - > next ) {
if ( ! headerIsEntry ( pkg - > header , RPMTAG_DESCRIPTION ) ) {
const char * name ;
( void ) headerNVR ( pkg - > header , & name , NULL , NULL ) ;
rpmError ( RPMERR_BADSPEC , _ ( " Package has no %%description: %s \n " ) ,
name ) ;
spec = freeSpec ( spec ) ;
return RPMERR_BADSPEC ;
}
( void ) headerAddEntry ( pkg - > header , RPMTAG_OS , RPM_STRING_TYPE , os , 1 ) ;
( void ) headerAddEntry ( pkg - > header , RPMTAG_ARCH ,
RPM_STRING_TYPE , arch , 1 ) ;
if ( ! headerIsEntry ( pkg - > header , RPMTAG_RHNPLATFORM ) )
( void ) headerAddEntry ( pkg - > header , RPMTAG_RHNPLATFORM ,
RPM_STRING_TYPE , arch , 1 ) ;
( void ) headerAddEntry ( pkg - > header , RPMTAG_PLATFORM ,
RPM_STRING_TYPE , platform , 1 ) ;
}
# ifdef DYING
myos = _free ( myos ) ;
# else
platform = _free ( platform ) ;
arch = _free ( arch ) ;
os = _free ( os ) ;
# endif
}
2002-03-26 02:09:32 +03:00
if ( _rpm_nosource | | _rpm_nopatch )
{
spec - > noSource = 1 ;
if ( _rpm_nosource ) parseNoSource ( spec , _rpm_nosource , RPMTAG_NOSOURCE ) ;
if ( _rpm_nopatch ) parseNoSource ( spec , _rpm_nopatch , RPMTAG_NOPATCH ) ;
}
2002-03-25 23:16:26 +03:00
closeSpec ( spec ) ;
* specp = spec ;
return 0 ;
}