arename(1) | User Contributed Perl Documentation | arename(1) |
arename - automatically rename audio files by tagging information
arename [OPTION(s)] FILE(s)...
Note that if the `verbosity' setting is at a high enough level, you may still get messages about the file being processed in the first place.
A word about option name stability: With arename version 3.0 we are now using Getopt::Long for parsing command lines options. That change was made, because the meaningful single letter options where used up. Every option is available via a --long-option. That interface will remain stable. If changes to the --long-option interface are done, that will happen with an appropriate deprecation phase, so users can adjust. So, if you want to use arename in scripts, those are the options you should use. There are currently no plans of removing or changing any further short options, but there are no guarantees. If it is indeed better to change a short option, we will do so.
A list of options that changed from arename 3.x to 4.0 can be found in the project's CHANGES file and general advice about incompatible changes from major version to major version are documented in the UPGRADING file.
The following options are deprecated and will be removed in a later version of arename.
arename is a tool that is able to rename audio files by looking at a file's tagging information. It uses this information to assemble a consistent destination file name. The user can define the format of the destination filename by the use of template strings.
Templates can be defined in the "Configuration files", by the template and comp_template settings (See "SETTINGS" below).
By default, arename will refuse to overwrite destination files, if the file in question already exists. You can force overwriting by supplying the --force option.
In order to see what would happen instead of actually modifying files, you can use the --dryrun option. This way you can avoid problems, that would occur if the situation (e.g. the information in the files or your configuration) is not exactly as you expected it.
Since version 4.0, arename supports a lot more file formats than it used to (version 3.0 only supported .mp3, .ogg and .flac files). Thanks to Audio::Scan, we now support a much wider range of file types, of which most may exist using different file name extensions (e.g. *.ogg and *.oga are both of the type ogg).
You may use the `--list-file-types' and `--list-ext-for-type' options to find out which file type is mapped to which file name extensions.
If you would like support for another file type in arename, you will have to persuade the Audio::Scan developers to extend their module with said feature. Adding support for it in arename after that should be trivial.
To give you an idea, arename (in connection with Audio::Scan 0.85) lets you rename mp3, mp4, aac, ogg, flac, asf, musepack, monkey audio, wav (this type also supports aiff) and wavpack files.
arename can be used to keep the file names of whole audio archives in sync. However, that means that you will have to tell the script the location of many files, thousands maybe.
In order to do that you will face the problem, that on most UNIX-like systems, the length of the argument list for external programs is limited (recent Linux versions, as an exception, do not have that limitation anymore).
So, even if your shell can do recursive globbing like ksh or zsh, this will most likely get you into trouble (for more than just a few files):
% arename -d **/*.mp3
There are several ways to overcome that limitation, of course.
The first solution is to use find in connection with arename's -s option:
% find . -name "*.mp3" -print | arename -d -s
This will break for file names that contain newlines, because --stdin will read one file name per line from the standard input stream.
Another way of using find to deal with this problem is to use find's -exec option:
% find . -name "*.mp3" -exec arename -d '{}' '+'
This will work for every possible file name. No matter if it has spaces or newlines in it. The + at the end of the call causes find to call the external program (arename in this case) with as many arguments as possible, without exceeding the limit. This requires a POSIXly correct find. GNU find for instance, did not support the + way for a long time. If you are stuck with an old version, you can exchange the + with a ; (note, that a semicolon must be quoted in any case), or use the xargs tool instead.
A last solution for zsh users would be zargs (which requires 'autoload zargs' in your zsh configuration):
% zargs -- **/*.mp3 -- arename -d
When you are first confronted with arename and you try to get started with the documentation you might argue, that a 1000+ lines manual, that is not filled with too many examples is hardly starter-friendly.
Therefore, this section was introduced to give you the bare minimum of information in order to use the program without going through too much fuzz.
If you are really afraid of documentation, you could of course just read the output of the --help option and see which options to provide in order to get what you want. Then again, you will soon be pissed by the weird default values arename uses.
You will probably want other templates. After all, the ability to have these expanded strings is one of the points to use arename in the first place. They are described in the TEMPLATE section; and reading that section is the minimum effort you will want to go through.
After that, you can open the file ~/.arenamerc in your favourite text editor and resemble the following text (and presumably change the few values in there to your liking):
# now you certainly want your own templates, so define them here # one for your normal files template &artist - &album - &tracknumber. &tracktitle # and another one for files that orignate from compilations comp_template va - &album - &tracknumber. &artist - &tracktitle
If you want more automation or more customization, you will not get around reading the manual below. If you need to solve special problems, the "HOOKS" part even further below is for you.
However, if warnings or errors are encoutered while loading the configuration, those messages are still emitted, of course.
Any other value but 1 - and that includes ARENAME_LOAD_QUIET being absent from the environment - will cause arename to start up in its normal manner.
arename's behaviour can be altered by a number of files it reads when starting up.
Normal configuration tasks are done in (how convenient) "Configuration files", described below.
If you need more control, or want to solve special problems you are having, you can do so by supplying Perl code in "Hook definition files".
arename can be configured to read configuration files as well as hook definition files from the current working directory. This feature is disabled by default, because they can be a security issue on multiuser systems.
There are no such things as system wide configuration files in arename.
For all setup files arename tries to find (except for the local ones) four different locations are tried. If the $XDG_CONFIG_HOME/arename directory exists, all files are expected to be there. If that directory does not exist, ~/etc/arename/ and if that is not there ~/.arename are are tried instead. If those directories could not be found either, arename will try to find the file it is looking for directly in the user's home directory.
The default for $XDG_CONFIG_HOME is ~/.config.
The first setup directory we find always wins. arename does not consider more than one setup directory.
If, for example, ~/etc/arename/ exists and we are looking for the normal configuration file (see below), but ~/etc/arename/rc could not be found, we do not try to find it in ~/.arename/ or the user's home directory.
arename uses up to three configuration files. As for most programs, the script will try to read a configuration file, that is located in the user's home directory. In addition to that, it will try to load local configuration files, if it finds appropriately named files in the current directory (and the uselocalrc feature is enabled):
The per-user normal configuration file can be substituted by another file, if specified via the --rc option.
Last but not least, you can specify an intermediate configuration file, that is read in between the normal and the per-directory file, via the --post-rc option.
File format
The format of the aforementioned files is pretty simple. It is parsed line by line. Empty lines, lines only containing whitespace and lines, whose first non whitespace character is a hash character (#) are ignored.
There are two different types of settings: boolean and scalar settings.
Booleans can be set like this:
<setting> [true|false]
If the value is omitted, true is assumed. true and false are recognized case insensitively, and a value of 1 is synonymous to true, as is 0 to false.
Scalar settings are done in a very similar way:
<setting> <value>
If the value is omitted, string values will be set to an empty string and numeric values will be set to zero.
In both cases, setting and value are separated by one or more whitespace characters. The value will be the rest of the line (all of it, including trailing whitespace).
If the value part starts with a backslash, that backslash is left out of the value. That makes it possible to define templates with leading whitespace.
If a line contains only a string within square brackets, that string is the start of a section. Section names are matches for starts of file names. That means, the settings following such a section definition will only applied for input file names that start with the same string as the section name. Where file name means the string, handed over to arename. The string ~/ at the beginning of a section name is expanded to the user's home directory.
You may start as many sections as you would like.
A section named /foo/bar/ supersedes a section named /foo/ for a file named /foo/bar/baz.ogg. So, the longest match wins.
Another possible configuration file entry is a user variable, which is defined via the set command. These settings are very different from the normal settings. Therefore, they are defined in a different way. That way is described in the "User defined variables" subsection below.
Last but not least, you may define so called profiles, see below.
Configuration profiles
Profiles are a very flexible and context sensitive way of using multiple configuration files at once. With profiles, local configuration files (and local hook definition files) can be substituted in a secure way; even on multi-user systems.
Reading local files (configs and hook-files) is still supported for backwards compatibility (see uselocalrc and uselocalhooks options). However, you are strongly encouraged to use profiles whenever you can.
As normal configuration files and global hook-files, profile-related files are searched in one of the setup directories described above. They are using the following naming conventions:
They are read after a intermediate config file defined by --post-rc and a local config file (if enabled).
These files are read, between global and local hook-definition files.
In order to define profiles, you need to use the profile keyword:
profile <name> <pattern>
Where name is a string, that is used in the place of PROFILENAME in the file location lists above. This name may contain of the following character range: a-zA-Z0-9_-
pattern is part of a Perl regex pattern (see perlreref and perlretut manpages). The pattern will be anchored at the beginning and is open at the end, somewhat like this pseudocode:
if ($working_directory =~ m/^PATTERN/) { use_this_profile(); }
Example:
profile music /mnt/audio/music/
Will cause the profile music to be active when the working directory is /mnt/audio/music/ or below. So, do not be afraid. You can use profiles without understanding regular expressions.
Like many other values in arename's configuration, a leading backslash of a pattern will be ignored to allow patterns, that start in white spaces. Furthermore, if a pattern starts in ~/, that string is replaced by the user's home directory.
You may add as many patterns to a profile name, as you want:
profile music /mnt/audio/music/ profile music /mnt/extern/audio/music/
The above activates the music profile in /mnt/audio/music/ and /mnt/extern/audio/music/, for example.
More than one profile can be activated at the same time. If that is true, the according configuration files are read in lexical order.
Sections versus Profiles
Since arename provides two context sensitive configuration facilities, you might ask yourself when to use which, when you are confronted with both for the first time.
First of all, profiles are more powerful. They may even introduce new hooks for arename to use. But that is not the conceptual difference between the two.
sections are sets of configuration settings, that are considered for each and every input file and they are only enabled for input files, whose name matches the section name.
profiles on the other hand are sets of configuration and hook-definition files, whose inclusion in the current arename run is decided at the beginning of the program's execution (not for every input file) - namely, if the name of the current working directory matches one of the profile's patterns.
That means, that if you need to introduce slight configuration changes based on an input file's name you want to use a section.
If you need to make broader configuration changes, considering the name of the current working directory, profiles are the way to go.
Of course, profile configuration files may introduce new sections, too.
# switch on verbosity verbosity 20 # canonicalize file names before working with them canonicalize # the author is crazy! use a sane template by default. :-) template &artist - &album (&year) - &tracknumber. &tracktitle # activate the 'music' profile below /mnt/audio/music/. profile music /mnt/audio/music/ # force files from /foo/bar/ to stay below that directory [/foo/bar/] prefix /foo/bar
For details about hooks in arename, see "HOOKS" below.
The following settings are supported in all configuration files.
Not all of them are usable in sections. The ones you can use in sections are: All default_* options, force, prefix, sepreplace, tnpad, comp_template and template.
When set to true, arename just uses the first value it encounters.
For maximum control over how tags with ambiguous values are handled, you may use the `ambiguoustag' hook. (default: false)
If unset, profiles without config file will not cause warnings. You will see messages about missing configuration files, if a profile without config file is active. (default: true)
Defines a default value, for the given tag in files, that lack this information. (default value: undefined)
This setting can still be overwritten by the --profile command line option. (default value: .)
When this option is set to true, a file matching *.oga would be renamed using .ogg as the extension, since its type is ogg. Otherwise, the original extension is left untouched. (default: true)
You can use the set command in arenamerc files. This way the user can define his own variables. The namespace is separate from arename's normal settings. (That means, you cannot, for example, overwrite the internal template variable with this command.)
The sytnax is quite simple (and different to normal settings on purpose!):
set varname = value
There may be an arbitrary amount of whitespace around the equal sign (including no whitespace at all). If you want to have a value that starts in a whitespace character, you may start the value with a backslash character (just like with the normal settings, a leading backslash is always ignored).
You may also set user defined variables on the command line by using the --userset option:
% arename --userset variable0=value % arename -u variable0=value
User defined variables are useful to make hooks configurable (see "HOOKS" below). Starting with version 4 of arename, user defined variables may also be defined within sections, which (just like normal option) makes them applicable only if said section is used for a given file.
arename's templates are fairly easy to understand, but powerful.
At simplest, a template is just a fixed character string. However, that would not be exactly useful, because then every file you would ever want to rename would be getting the exact same name. That is why arename is able to expand certain expressions with information gathered from the file's tagging information.
An expression basically looks like one of the following forms:
That means, if the artist of a file reveals to be 'Frank Zappa', then using '&artist[1]' will expand to 'F'.
If it is not available though, the expansion doesn't fail, but instead the `default-template' string is expanded.
If it is set, the string set-template is expanded; if it is unset, the unset-template string is used.
Both simple expansions may be used with braces, like the complex expansions are:
Backslashes are special in template strings, because they are used to quote characters that bear special meaning (for example, to get a ampersand character, you need to use "\&"). To get an actual backslash in the resulting string, you need to use a backslash, quoted by a backslash. A backslash on non-special characters is silently dropped.
In complex expressions, the strings called `default-template', `set-template' and `unset-template' are subject to regular template expansion. Hence, expressions like the following are possible:
"&{album?&album/!}"
If `album' were set, it would expand to its value followed by a slash; otherwise it would expand to nothing. Using this, it is fairly easy to deal with album-less tracks:
"&artist/&{album?&album/&tracknumber. !-no-album-/}&tracktitle"
That will effectively use the following template if `album' is set:
"&artist/&album/&tracknumber. &tracktitle"
But if it is not set, it will instead use this:
"&artist/-no-album-/&tracktitle"
Caution has to be taken if certain characters are to be used within conditional template expressions. For example, to use a closing curly bracket in either of them, it needs to be quoted using a backslash character.
Similarly, if an exclamation mark is to be used in a `set-template', it needs to be quoted by a backslash to avoid the character being interpreted as the end of the `set-template' string.
The data, that is expanded is derived from tagging information in the audio files. There are two kinds of information available. One is the purely informational tag (like a track's artist) and the other further describes the format of the audio file (like the file's bitrate).
If you are defining a lot of templates on the command line, you may find that these identifiers take quite a while to type. If the template_aliases option is set, you may use shorter alias names instead of the the real identifier. Available aliases are listed with their corresponding idetifier below.
This is a list of all informational identifiers available for all file-types:
Here is a list of file-format information tag available for all file-types:
For all file-types, the following tags are generated from the ones listed above (for convenience):
Some tags are only available for certain file-types. They are always called `type_*'. File-type specific identifiers do not have alias names. Here is a list of those tags:
arename returns zero if everything went fine; non-zero on fatal problems. This may change in future versions.
Before we start, a word of warning: Hooks can solve a lot of problems. That amount of flexibility comes at its price. All data passed to hook functions are references to the actual data in the script (except for the namespace argument, which is a copy). If you write hooks carelessly, arename will get back at you! HOOKS ARE A BIG HAMMER, THAT CAN CRUSH PROBLEMS AS WELL AS LIMBS!
You have been warned!
The reason for implementing hooks was to have a simple way of post processing tags, filenames etc. without having to invent own magic in the configuration files, when Perl has regular expressions on steriods anyway. Hooks can do more then pure pre and post processing, because they are called in numerous places and give broad access to the script's data structures. Still, post processing is probably the most useful feature they implement.
Hooks are just Perl subroutines, which are defined in one of two files (see "FILES"). They are run at certain events during the execution of arename. The contents of the argument list for each hook depends on what hook is called (see the "List of hook events" below). However, the first argument (argument zero aka. $_[0]) to all hooks is the hook namespace, the subroutine is called in.
The global hooks file is read before the local one, which means, that this local file may overwrite and extend the definitions from the global file, as much as Perl permits. This also means, that hooks from the local file are run after the ones from the global file (unless you are using your own method of registering hooks; but if you do so, you know what you are doing anyway).
Subroutines must be registered to arename, to be known as hooks. Once registered, a subroutine can be removed from the known hooks, if requested (see "Utility subroutines" below).
The keys in various data hashes passed to the hooks can be one of the following: album, artist, compilation, genre, tracknumber, tracktitle, year.
Registration subroutines
There are two subroutines, that are used to tell arename about subroutines, you defined that shall become hooks.
If the coderef was added more than once, all entries are removed.
File access and manipulation
The currently processed file name can be accessed via two subroutines:
With these, you could even change the file name of the processed file, while arename works on it (which you really should only do, if you know what you are doing).
User-defined-variable subroutines
Hooks can also use the data from user defined variables, via their Perl interface:
Here is an example for user defined settings:
# Assume, the user set the myvar-variable to "bar" in his # configuration file my $foo = user_get('myvar'); # $foo is now "bar" user_set('foo', "bar, baz"); my $foo = user_get('myvar'); # $foo is now "bar, baz"
API for accessing to arename's internal configuration
You can also access the configuration data of arename itself:
A list of settings arename will use: canonicalize, dryrun, force, hookerrfatal, prefix, quiet, quiet_skip, readstdin, sepreplace, tnpad, usehooks, uselocalhooks, uselocalrc, verbose, verbosity, comp_template and template.
If you want to actually change these settings, you should have a profound knowledge of arename's internals. Be careful.
API for default_* settings
If you need to access the current values of the default_* settings:
Miscellaneous subroutines
And finally, a few miscellaneous functions ARename.pm provides, that might be of interest.
Keep in mind that this function calls hooks itself. Avoid endless loops! See "Hooks when expanding the template" for details.
Dies if it cannot stat one of the given files.
If tokenisation already failed, a negative value is returned. In case of any warnings with the token tree, zero is returned. If nothing came up, a positive value is returned.
This subroutine is called for the `template' and `comp_template' strings in all sections when arename starts. If the user chooses to change a template string in a hook it is recommended to use this function to avoid any errors due to broken templates.
This is a complete list of hooks events with descriptions.
The first argument (argument number "zero") for every hook is the name space they are called in. To find out the name of the currently processed file, use the get_file() subroutine described above.
Hooks in the main loop
These hooks are called at the highest level of the script.
You can get the current file name via get_file(). The canonicalized file name is handed to you via the hook's arguments. The value from this argument will be assigned to the processed filename after the execution of this hook.
Arguments: 1: canonicalized file name
Arguments:
In this context, file checks means tests for read-access and for whether the processed file is a symlink. arename will refuse to process symlinks and files it cannot read.
Arguments:
Arguments:
Arguments:
Arguments: 1: the current file name extension 2: the file type that has been detected
Arguments: 1: the file type, 2: the extension that will be used to assemble the target filename, 3: the data hash
Hooks in the renaming procedure
When all data has been gathered, arename will go on to actually rename the files to their new destination name (which will be generated in the process, see "Hooks when expanding the template" below).
Arguments: 1: data hash, 2: file extension
Arguments: 1: data hash, 2: file extension
Arguments: 1: data hash, 2: file extension 3: the generated new filename (including directory prefix and file extension)
Arguments: 1: data hash, 2: file extension 3: the generated new filename (including directory prefix and file extension)
Arguments: 1: data hash, 2: file extension 3: the generated new filename (including directory prefix and file extension)
Hooks when expanding the template
These hooks are called when the template string is filled with the data from tags in the audio files. To do this, arename first tokenises the template string into a data structure, which is later used to assemble the target file name.
Arguments: 1: the template string, 2: the data hash
Arguments: 1: the template string (fully expanded), 2: the data hash
Arguments: 1: the tag's name, 2: the data hash
Arguments: 1: the supposedly expanded string (`undef' upon hook-entry), 2: the tag's name, 2: the data hash
At each point, this hook will be called right after the data was retrieved and post-processed.
Arguments: 1: the value, which will be used for expansion, 2: the tag's name, 2: the data hash
Hooks while gathering information
These hooks are triggered while the tag information is extracted from the audio files arename is processing. This is done in two steps. First the Audio::Scan module is used to scan for the raw meta data information from the current file. Then arename's data hash is being filled with that data.
Arguments: 1: the type of the file being processed (`ogg' for ogg vorbis files)
Arguments: 1: the type of the file being processed (`ogg' for ogg vorbis files), 2: the data structure returned by `Audio::Scan'
The hook may be used for maximum control over how ambiguous values are handled. To do this, the ambiguous value (passed as an array reference in the second argument) should be turned into the desired scalar value.
If the array reference is left as it is, the usual `ambiguoususefirst' behaviour is followed. The the option's description for details.
Arguments: 1: the name of the tag with the ambiguous value, 2: its current (ambiguous) value, 3: the data hash in its current form (obviously not all values will have been filled in at this point), 4: the data structure returned by Audio::Scan (see its documentation for details)
Arguments: 1: return code of the filling process (`0' in case of an error, `1' otherwise), 2: the type of the file being processed (`ogg' for ogg vorbis files), 3: the data structure returned by `Audio::Scan', 4: the data hash.
Miscellaneous hooks
Arguments: 1: data hash, 2: current key
This hook may be useful for postprocessing the configuration as well as for debugging.
Arguments: 1: program name, 2: its version, 3: configuration hash, 4: array of supported tags, 5: the program's argument list
Arguments: 1: the program's argument list
First, to give you an idea about how argument passing works in arename hooks, take a look at these two `startup' hooks:
sub print_banner0 { # Yes, everything handed over to hooks (except for the namespace) # are references. This gives us simple two way communication, but # it's also a pretty big responsibility to handle. Think before # screwing up. :) my ($ns, $nameref, $verref, $confref, $suptagsref, $argvref) = @_; print "BANNER! $$nameref $$verref " . $argvref->[0] . "\n"; # The following actually changes the $NAME variable, used # in ARename.pm, which doesn't hurt, because it is only the # name of the program running. For other hook events and variables, # there might be vital data in one of the references. Be very careful # before changing values willy-nilly. $$nameref =~ s/name/blame/; } register_hook('startup', \&print_banner0); sub print_banner1 { my ($ns, $nameref, $verref, $confref, $suptagsref, $argvref) = @_; # Since $NAME used to be 'arename', the substitution # in print_banner0() will have changed $NAME to 'areblame', # which $$nameref below will reveal. print "ANOTHER BANNER! $$nameref $$verref\n"; } register_hook('startup', \&print_banner1);
After that short introduction, here is something more useful. The following hook will replace all whitespace with underscores in generated file names.
sub replace_spaces_by_underscore { my ($templateref, $datref) = @_; $$templateref =~ s/\s+/_/g; } register_hook('post_expand_template', \&replace_spaces_by_underscore);
This will do the trick, but there is actually an arename extension that is distributed with the application, which is designed to solve exactly this problem. See "EXTENSIONS" below for details on the `ReplaceSpaces' extension module.
Arename comes with a number of extensions implemented as Perl modules, to solve a number of more exotic tasks, that are not addressed within the core Module `ARename.pm'.
All of these bundled extension modules (which are all children of the `ARename' namespace) are fully documented within their source files and is accessible by the `perldoc' utility:
% perldoc ARename::ReplaceSpaces
Modules, that implement a hook all feature a convenience subroutine `register()', which registers the hook code to the event the author intended. For example, to use the `RenameSpaces' hook, add the following to your hooks file:
use ARename::ReplaceSpaces; ARename::ReplaceSpaces::register();
Here is a list of bundled extensions:
This is also the extension module you want look at, if you are interested in writing your own extension modules. It features all code and documentation, that is required of an extension to make it into the arename package.
If you are on an UTF-8 based system and wonder why arename produces latin1 characters for mp3 files, that have non-ascii characters in their tags, this extension may be of help.
The idea is to have proper padding the large audiobooks that contain more than 99 tracks.
There are a few utility modules, that implement helpful code that is shared among all bundled extension modules. Some of the code may be useful to user defined hooks or extension modules, too.
Say you have decided, that the `ARename::Extension::register()' idea to encapsulate extensions is a good idea and now you want to do that yourself, too. Maybe because, you just like to keep your `hooks' file tidy or maybe because you want to contribute your awesome extension code back to arename. Either way, you will need a place to put your Perl code.
Arename does NOT set such a place by default. But it is very easy to set it yourself from the `hooks' file:
BEGIN { unshift @INC, $ENV{HOME} . q{/.arename}; }
That way you can place Perl modules into `~/.arename' like this:
~/.arename/ARename/MyAwesomeExtension.pm
And then just use it like the bundled extensions:
use ARename::MyAwesomeExtension.pm; ARename::MyAwesomeExtension::register();
Take a look at the `KillNonASCII.pm.in' file in the `arename' sources, for details about how to write proper extensions and how to make them configurable and how to make use of the bundled utilities to make your extension appropriate for inclusion with `arename'.
find(1), xargs(1), perldoc(1), Audio::Scan.
ARename::BailOut, ARename::KillNonASCII, ARename::MP3RecodeToUTF8, ARename::RemoveEmptySubdirs, ARename::ReplaceSpaces, ARename::TNPadAdjustByAlbum.
ARename::Template::Albumless
ARename::Util::Files, ARename::Util::IsNumber, ARename::Util::RegisterModuleHook, ARename::Util::VersionGuard.
This manual describes arename version 4.1.
Frank Terbeck <ft@bewatermyfriend.org>,
Please report bugs.
Copyright 2007-2017 Frank Terbeck <ft@bewatermyfriend.org>, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS OF THE PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2022-02-26 | perl v5.34.0 |