2002-03-25 23:16:26 +03:00
/** \ingroup rpmbuild
* \ file build / parseReqs . c
* Parse dependency tag from spec file or from auto - dependency generator .
*/
# include "system.h"
# include "rpmbuild.h"
# include "debug.h"
/**
*/
/*@observer@*/ /*@unchecked@*/
static struct ReqComp {
/*@observer@*/ /*@null@*/ const char * token ;
rpmsenseFlags sense ;
} ReqComparisons [ ] = {
{ " <= " , RPMSENSE_LESS | RPMSENSE_EQUAL } ,
{ " =< " , RPMSENSE_LESS | RPMSENSE_EQUAL } ,
{ " < " , RPMSENSE_LESS } ,
{ " == " , RPMSENSE_EQUAL } ,
{ " = " , RPMSENSE_EQUAL } ,
{ " >= " , RPMSENSE_GREATER | RPMSENSE_EQUAL } ,
{ " => " , RPMSENSE_GREATER | RPMSENSE_EQUAL } ,
{ " > " , RPMSENSE_GREATER } ,
{ NULL , 0 } ,
} ;
# define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
# define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
int parseRCPOT ( Spec spec , Package pkg , const char * field , int tag ,
int index , rpmsenseFlags tagflags )
{
const char * r , * re , * v , * ve ;
char * req , * version ;
Header h ;
rpmsenseFlags flags ;
switch ( tag ) {
case RPMTAG_PROVIDEFLAGS :
tagflags | = RPMSENSE_PROVIDES ;
h = pkg - > header ;
break ;
case RPMTAG_OBSOLETEFLAGS :
tagflags | = RPMSENSE_OBSOLETES ;
h = pkg - > header ;
break ;
case RPMTAG_CONFLICTFLAGS :
tagflags | = RPMSENSE_CONFLICTS ;
h = pkg - > header ;
break ;
case RPMTAG_BUILDCONFLICTS :
tagflags | = RPMSENSE_CONFLICTS ;
h = spec - > buildRestrictions ;
break ;
case RPMTAG_PREREQ :
tagflags | = RPMSENSE_PREREQ ;
h = pkg - > header ;
break ;
case RPMTAG_BUILDPREREQ :
tagflags | = RPMSENSE_PREREQ ;
h = spec - > buildRestrictions ;
break ;
case RPMTAG_TRIGGERIN :
tagflags | = RPMSENSE_TRIGGERIN ;
h = pkg - > header ;
break ;
case RPMTAG_TRIGGERPOSTUN :
tagflags | = RPMSENSE_TRIGGERPOSTUN ;
h = pkg - > header ;
break ;
case RPMTAG_TRIGGERUN :
tagflags | = RPMSENSE_TRIGGERUN ;
h = pkg - > header ;
break ;
case RPMTAG_BUILDREQUIRES :
tagflags | = RPMSENSE_ANY ;
h = spec - > buildRestrictions ;
break ;
default :
case RPMTAG_REQUIREFLAGS :
tagflags | = RPMSENSE_ANY ;
h = pkg - > header ;
break ;
}
for ( r = field ; * r ! = ' \0 ' ; r = re ) {
SKIPWHITE ( r ) ;
if ( * r = = ' \0 ' )
break ;
flags = ( tagflags & ~ RPMSENSE_SENSEMASK ) ;
/* Tokens must begin with alphanumeric, _, or / */
if ( ! ( xisalnum ( r [ 0 ] ) | | r [ 0 ] = = ' _ ' | | r [ 0 ] = = ' / ' ) ) {
rpmError ( RPMERR_BADSPEC ,
_ ( " line %d: Dependency tokens must begin with alpha-numeric, '_' or '/': %s \n " ) ,
2004-04-25 14:34:53 +04:00
spec - > lineNum , ( spec - > fileStack ? spec - > line : field ) ) ;
2002-03-25 23:16:26 +03:00
return RPMERR_BADSPEC ;
}
/* Don't permit file names as args for certain tags */
switch ( tag ) {
case RPMTAG_OBSOLETEFLAGS :
case RPMTAG_CONFLICTFLAGS :
case RPMTAG_BUILDCONFLICTS :
if ( r [ 0 ] = = ' / ' ) {
rpmError ( RPMERR_BADSPEC , _ ( " line %d: File name not permitted: %s \n " ) ,
2004-04-25 14:34:53 +04:00
spec - > lineNum , ( spec - > fileStack ? spec - > line : field ) ) ;
2002-03-25 23:16:26 +03:00
return RPMERR_BADSPEC ;
}
/*@switchbreak@*/ break ;
default :
/*@switchbreak@*/ break ;
}
re = r ;
SKIPNONWHITE ( re ) ;
req = xmalloc ( ( re - r ) + 1 ) ;
strncpy ( req , r , ( re - r ) ) ;
req [ re - r ] = ' \0 ' ;
2004-01-27 13:56:42 +03:00
/* Names must not contain '%<=>' symbols - it's common error */
if ( strpbrk ( req , " %<=> " ) ) {
rpmError ( RPMERR_BADSPEC ,
_ ( " line %d: Dependency tokens must not contain '%%<=>' symbols: %s \n " ) ,
2004-04-25 14:34:53 +04:00
spec - > lineNum , ( spec - > fileStack ? spec - > line : field ) ) ;
2004-01-27 13:56:42 +03:00
return RPMERR_BADSPEC ;
}
2002-03-25 23:16:26 +03:00
/* Parse version */
v = re ;
SKIPWHITE ( v ) ;
ve = v ;
SKIPNONWHITE ( ve ) ;
re = v ; /* ==> next token (if no version found) starts here */
/* Check for possible logical operator */
if ( ve > v ) {
struct ReqComp * rc ;
for ( rc = ReqComparisons ; rc - > token ! = NULL ; rc + + ) {
if ( ( ve - v ) ! = strlen ( rc - > token ) | | strncmp ( v , rc - > token , ( ve - v ) ) )
/*@innercontinue@*/ continue ;
flags | = rc - > sense ;
/* now parse version */
v = ve ;
SKIPWHITE ( v ) ;
ve = v ;
SKIPNONWHITE ( ve ) ;
/*@innerbreak@*/ break ;
}
}
/*@-branchstate@*/
if ( flags & RPMSENSE_SENSEMASK ) {
if ( * v = = ' \0 ' | | ve = = v ) {
rpmError ( RPMERR_BADSPEC , _ ( " line %d: Version required: %s \n " ) ,
2004-04-25 14:34:53 +04:00
spec - > lineNum , ( spec - > fileStack ? spec - > line : field ) ) ;
2002-03-25 23:16:26 +03:00
return RPMERR_BADSPEC ;
}
version = xmalloc ( ( ve - v ) + 1 ) ;
strncpy ( version , v , ( ve - v ) ) ;
version [ ve - v ] = ' \0 ' ;
re = ve ; /* ==> next token after version string starts here */
} else
version = NULL ;
/*@=branchstate@*/
2004-01-27 13:56:42 +03:00
/* Versions must not contain '%<=>' symbols - it's common error */
if ( version & & strpbrk ( version , " %<=> " ) ) {
2004-01-24 17:00:51 +03:00
rpmError ( RPMERR_BADSPEC ,
2004-01-27 13:56:42 +03:00
_ ( " line %d: Dependency tokens must not contain '%%<=>' symbols: %s \n " ) ,
2004-04-25 14:34:53 +04:00
spec - > lineNum , ( spec - > fileStack ? spec - > line : field ) ) ;
2004-01-24 17:00:51 +03:00
req = _free ( req ) ;
version = _free ( version ) ;
return RPMERR_BADSPEC ;
}
2010-09-11 01:00:13 +04:00
if ( addReqProv ( spec , h , flags , req , version , index ) = = 0 ) {
// Set-versions need their rpmlib feature.
if ( version & & strncmp ( version , " set: " , 4 ) = = 0 )
// Except for provides, to facilitate bootstrap.
if ( tag ! = RPMTAG_PROVIDEFLAGS )
rpmlibNeedsFeature ( h , " SetVersions " , NULL ) ;
}
2002-03-25 23:16:26 +03:00
req = _free ( req ) ;
version = _free ( version ) ;
}
return 0 ;
}