[pacman-dev] [PATCH v2] Enable inverted patterns in NoExtract and NoUpgrade.

Andrew Gregory andrew.gregory.8 at gmail.com
Tue Jun 18 09:22:54 EDT 2013


On 06/18/13 at 09:14am, Patrick Steinhardt wrote:
> It is now possible to invert patterns in NoExtract and NoUpgrade.
> This feature allows users to whitelist certain files that were
> previously blacklisted by another entry.
> ---
>  doc/pacman.conf.5.txt | 10 ++++++++--
>  lib/libalpm/add.c     |  4 ++--
>  lib/libalpm/util.c    | 32 ++++++++++++++++++++++++++++++++
>  lib/libalpm/util.h    |  1 +
>  4 files changed, 43 insertions(+), 4 deletions(-)
> 

Looks good.  Fairly minor comments below.

> diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt
> index 83a399e..e87f4c2 100644
> --- a/doc/pacman.conf.5.txt
> +++ b/doc/pacman.conf.5.txt
> @@ -128,7 +128,10 @@ Options
>  	'.pacnew' extension.
>  	These files refer to files in the package archive, so do not include the
>  	leading slash (the RootDir) when specifying them. Shell-style glob patterns
> -	are allowed.
> +	are allowed. It is possible to invert matches by prepending a file with
> +	an exclamation mark. Inverted files will result in previously blacklisted
> +	files to be whitelisted again. Subsequent matches will override previous
> +	ones.

s/to be/being/

Need to mention that a leading literal ! or \ needs to be escaped.

>  
>  *NoExtract =* file ...::
>  	All files listed with a `NoExtract` directive will never be extracted from
> @@ -138,7 +141,10 @@ Options
>  	from the 'apache' package.
>  	These files refer to files in the package archive, so do not include the
>  	leading slash (the RootDir) when specifying them. Shell-style glob patterns
> -	are allowed.
> +	are allowed. It is possible to invert matches by prepending a file with
> +	an exclamation mark. Inverted files will result in previously blacklisted
> +	files to be whitelisted again. Subsequent matches will override previous
> +	ones.

Same.

>  
>  *CleanMethod =* KeepInstalled &| KeepCurrent::
>  	If set to `KeepInstalled` (the default), the '-Sc' operation will clean
> diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
> index c20e7c6..6e12f56 100644
> --- a/lib/libalpm/add.c
> +++ b/lib/libalpm/add.c
> @@ -183,7 +183,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
>  	}
>  
>  	/* if a file is in NoExtract then we never extract it */
> -	if(alpm_list_find(handle->noextract, entryname, _alpm_fnmatch)) {
> +	if(_alpm_fnmatch_patterns(handle->noextract, entryname) == 0) {
>  		_alpm_log(handle, ALPM_LOG_DEBUG, "%s is in NoExtract,"
>  				" skipping extraction of %s\n",
>  				entryname, filename);
> @@ -245,7 +245,7 @@ static int extract_single_file(alpm_handle_t *handle, struct archive *archive,
>  		} else {
>  			/* case 3: */
>  			/* if file is in NoUpgrade, don't touch it */
> -			if(alpm_list_find(handle->noupgrade, entryname, _alpm_fnmatch)) {
> +			if(_alpm_fnmatch_patterns(handle->noupgrade, entryname) == 0) {
>  				notouch = 1;
>  			} else {
>  				alpm_backup_t *backup;
> diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
> index f84fb66..1382889 100644
> --- a/lib/libalpm/util.c
> +++ b/lib/libalpm/util.c
> @@ -1249,6 +1249,38 @@ int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int a
>  	return ret;
>  }
>  
> +/** Checks whether a string matches at least one shell wildcard pattern.
> + * Checks for matches with fnmatch. Matches are inverted by prepending
> + * patterns with an exclamation mark. Preceding exclamation marks may be
> + * escaped. Subsequent matches override previous ones.
> + * @param patterns patterns to match against
> + * @param string string to check against pattern
> + * @return 0 if string matches pattern, negative if they don't match and
> + * positive if the last match was inverted
> + */
> +int _alpm_fnmatch_patterns(alpm_list_t *patterns, const char *string)
> +{
> +	int result = -1;
> +	alpm_list_t *i;
> +	char *pattern;
> +	short inverted;

pattern and inverted should be moved to inside the loop.

> +
> +	for(i = patterns; i; i = i->next) {
> +		pattern = i->data;
> +
> +		inverted = pattern[0] == '!';
> +		if(inverted || pattern[0] == '\\') {
> +			pattern++;
> +		}
> +
> +		if(_alpm_fnmatch(pattern, string) == 0) {
> +			result = inverted;

If we just loop through the list backwards (or reverse the list) we
could return after the first match instead of saving the result and
continuing the loop.

> +		}
> +	}
> +
> +	return result;
> +}
> +
>  /** Checks whether a string matches a shell wildcard pattern.
>   * Wrapper around fnmatch.
>   * @param pattern pattern to match against
> diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h
> index 56031f3..24b7c22 100644
> --- a/lib/libalpm/util.h
> +++ b/lib/libalpm/util.h
> @@ -140,6 +140,7 @@ alpm_time_t _alpm_parsedate(const char *line);
>  int _alpm_raw_cmp(const char *first, const char *second);
>  int _alpm_raw_ncmp(const char *first, const char *second, size_t max);
>  int _alpm_access(alpm_handle_t *handle, const char *dir, const char *file, int amode);
> +int _alpm_fnmatch_patterns(alpm_list_t *patterns, const char *string);
>  int _alpm_fnmatch(const void *pattern, const void *string);
>  
>  #ifndef HAVE_STRSEP
> -- 
> 1.8.3.1
> 

apg


More information about the pacman-dev mailing list