Expander: also read rules from data directories

* ExpanderSettings: Use a settings directory "expander" and rename
  settings file to "settings".
* ExpanderRules: Read expander rules from "rules" files in the settings
  directory, then from files in expander/rules subdirectories of the
  installation location data directories, and finally add the built-in
  rules. This allows packages to provide expander rules (as already
  done by the p7zip package).
* OptionalPackages: Remove AddExpanderRuleToHaikuImage invocations.
* ImageRules: Remove Expander rule file related rules.
This commit is contained in:
Ingo Weinhold
2013-06-30 13:29:48 +02:00
parent 2cf916cbe2
commit 301f4b463a
6 changed files with 149 additions and 162 deletions
-37
View File
@@ -1098,43 +1098,6 @@ rule AddGroupToHaikuImage group : gid : members
AddEntryToHaikuImageUserGroupFile <haiku-image>group : $(entry) ;
}
rule AddEntryToHaikuImageExpanderRuleFile file : entry
{
local allEntries
= [ on $(file) return $(HAIKU_IMAGE_EXPANDER_RULES_ENTRIES) ] ;
if $(allEntries) {
allEntries = $(allEntries)!$(entry) ;
} else {
allEntries = $(entry) ;
Always $(file) ;
MakeLocate $(file) : $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) ;
BuildHaikuImageExpanderRules $(file) ;
AddFilesToHaikuImage common data : $(file) ;
}
HAIKU_IMAGE_EXPANDER_RULES_ENTRIES on $(file) = $(allEntries) ;
}
actions BuildHaikuImageExpanderRules
{
echo -e "$(HAIKU_IMAGE_EXPANDER_RULES_ENTRIES)" | tr '!' '\n' > $(1)
}
rule AddExpanderRuleToHaikuImage mimetype : extension : list : extract
{
#AddExpanderRuleToHaikuImage <mimetype> : <extension> : <list> : <extract>
if ! $(mimetype) || ! $(extension) || ! $(list) || ! $(extract) {
Exit "Invalid expander rule specification passed to AddExpanderRule." ;
}
local entry
= "\\\"$(mimetype)\\\"\\\t$(extension)\\\t\\\"$(list)\\\"\\\t\\\"$(extract)\\\"" ;
AddEntryToHaikuImageExpanderRuleFile <haiku-image>expander.rules
: $(entry) ;
}
rule AddOptionalPackageDescriptionToHaikuImage file : searchPath
{
-19
View File
@@ -1597,11 +1597,6 @@ if [ IsOptionalHaikuImagePackageAdded P7zip ] {
InstallOptionalHaikuImagePackage
$(baseURL)/p7zip-9.20.1-x86_64-2012-12-08.zip ;
}
AddExpanderRuleToHaikuImage "application/x-7z-compressed" : .7z
: "7za l \\0045s"
: "7za x -y \\0045s"
;
} else {
Echo "No optional package P7zip available for $(TARGET_ARCH)" ;
}
@@ -2160,20 +2155,6 @@ if [ IsOptionalHaikuImagePackageAdded XZ-Utils ] {
Echo "No optional package XZ-Utils available for gcc"
$(HAIKU_GCC_VERSION[1]) ;
}
# TODO: Move rules into package!
# AddExpanderRuleToHaikuImage "application/x-xz" : .tar.xz
# : "tar -Jtvf \\0045s"
# : "tar -Jxvf \\0045s"
# ;
# AddExpanderRuleToHaikuImage "application/x-xz" : .txz
# : "tar -Jtvf \\0045s"
# : "tar -Jxvf \\0045s"
# ;
# AddExpanderRuleToHaikuImage "application/x-xz" : .xz
# : "echo \\0045s | sed 's/.xz\\\$//g'"
# : "xz -df \\0045s"
# ;
} else {
Echo "No optional package XZ-Utils available for $(TARGET_ARCH)" ;
}
+119 -96
View File
@@ -16,23 +16,19 @@
#include <compat/sys/stat.h>
#include "ExpanderSettings.h"
static const char* const kRulesDirectoryPath = "expander/rules";
static const char* const kUserRulesFileName = "rules";
// #pragma mark - ExpanderRule
ExpanderRule::ExpanderRule(BString mimetype, BString filenameExtension,
BString listingCmd, BString expandCmd)
:
fMimeType(mimetype.String()),
fFilenameExtension(filenameExtension),
fListingCmd(listingCmd),
fExpandCmd(expandCmd)
{
}
ExpanderRule::ExpanderRule(const char* mimetype, const char* filenameExtension,
const char* listingCmd, const char* expandCmd)
ExpanderRule::ExpanderRule(const char* mimetype,
const BString& filenameExtension, const BString& listingCmd,
const BString& expandCmd)
:
fMimeType(mimetype),
fFilenameExtension(filenameExtension),
@@ -47,68 +43,23 @@ ExpanderRule::ExpanderRule(const char* mimetype, const char* filenameExtension,
ExpanderRules::ExpanderRules()
{
fList.AddItem(new ExpanderRule("", ".tar.gz",
"tar -ztvf %s", "tar -zxf %s"));
fList.AddItem(new ExpanderRule("", ".tar.bz2",
"tar -jtvf %s", "tar -jxf %s"));
fList.AddItem(new ExpanderRule("", ".tar.Z",
"tar -Ztvf %s", "tar -Zxf %s"));
fList.AddItem(new ExpanderRule("", ".tgz",
"tar -ztvf %s", "tar -zxf %s"));
fList.AddItem(new ExpanderRule("application/x-tar", ".tar",
"tar -tvf %s", "tar -xf %s"));
fList.AddItem(new ExpanderRule("application/x-gzip", ".gz",
"echo %s | sed 's/.gz$//g'",
"gunzip -c %s > `echo %s | sed 's/.gz$//g'`"));
fList.AddItem(new ExpanderRule("application/x-bzip2", ".bz2",
"echo %s | sed 's/.bz2$//g'", "bunzip2 -k %s"));
fList.AddItem(new ExpanderRule("application/zip", ".zip",
"unzip -l %s", "unzip -o %s"));
fList.AddItem(new ExpanderRule("application/x-zip-compressed", ".zip",
"unzip -l %s", "unzip -o %s"));
fList.AddItem(new ExpanderRule("application/x-rar", ".rar",
"unrar v %s", "unrar x -y %s"));
// Load the rules files first, then add the built-in rules. This way the
// built-ins can be overridden, if the files contain matching rules.
_LoadRulesFiles();
BFile file;
if (_Open(&file) != B_OK)
return;
int fd = file.Dup();
FILE* f = fdopen(fd, "r");
char buffer[1024];
BString strings[4];
while (fgets(buffer, 1024 - 1, f) != NULL) {
int32 i = 0, j = 0;
int32 firstQuote = -1;
while (buffer[i] != '#' && buffer[i] != '\n' && j < 4) {
if ((j == 0 || j > 1) && buffer[i] == '"') {
if (firstQuote >= 0) {
strings[j++].SetTo(&buffer[firstQuote+1],
i - firstQuote - 1);
firstQuote = -1;
} else
firstQuote = i;
} else if (j == 1 && (buffer[i] == ' ' || buffer[i] == '\t')) {
if (firstQuote >= 0) {
if (firstQuote + 1 != i) {
strings[j++].SetTo(&buffer[firstQuote+1],
i - firstQuote - 1);
firstQuote = -1;
} else
firstQuote = i;
} else
firstQuote = i;
}
i++;
}
if (j == 4) {
fList.AddItem(new ExpanderRule(strings[0], strings[1], strings[2],
strings[3]));
}
}
fclose(f);
close(fd);
_AddRule("", ".tar.gz", "tar -ztvf %s", "tar -zxf %s");
_AddRule("", ".tar.bz2", "tar -jtvf %s", "tar -jxf %s");
_AddRule("", ".tar.Z", "tar -Ztvf %s", "tar -Zxf %s");
_AddRule("", ".tgz", "tar -ztvf %s", "tar -zxf %s");
_AddRule("application/x-tar", ".tar", "tar -tvf %s", "tar -xf %s");
_AddRule("application/x-gzip", ".gz", "echo %s | sed 's/.gz$//g'",
"gunzip -c %s > `echo %s | sed 's/.gz$//g'`");
_AddRule("application/x-bzip2", ".bz2", "echo %s | sed 's/.bz2$//g'",
"bunzip2 -k %s");
_AddRule("application/zip", ".zip", "unzip -l %s", "unzip -o %s");
_AddRule("application/x-zip-compressed", ".zip", "unzip -l %s",
"unzip -o %s");
_AddRule("application/x-rar", ".rar", "unrar v %s", "unrar x -y %s");
}
@@ -120,28 +71,6 @@ ExpanderRules::~ExpanderRules()
}
status_t
ExpanderRules::_Open(BFile* file)
{
directory_which which[] = {
B_USER_DATA_DIRECTORY,
B_COMMON_DATA_DIRECTORY
};
for (size_t i = 0; i < sizeof(which) / sizeof(which[0]); i++) {
BPath path;
if (find_directory(which[i], &path) != B_OK)
continue;
path.Append("expander.rules");
if (file->SetTo(path.Path(), B_READ_ONLY) == B_OK)
return B_OK;
}
return B_ENTRY_NOT_FOUND;
}
ExpanderRule*
ExpanderRules::MatchingRule(BString& fileName, const char* filetype)
{
@@ -173,6 +102,100 @@ ExpanderRules::MatchingRule(const entry_ref* ref)
}
void
ExpanderRules::_LoadRulesFiles()
{
// load the user editable rules first
BPath path;
if (ExpanderSettings::GetSettingsDirectoryPath(path) == B_OK
&& path.Append(kUserRulesFileName) == B_OK) {
_LoadRulesFile(path.Path());
}
// load the rules files from the data directories
const directory_which kDirectories[] = {
B_USER_NONPACKAGED_DATA_DIRECTORY,
B_USER_DATA_DIRECTORY,
B_COMMON_NONPACKAGED_DATA_DIRECTORY,
B_COMMON_DATA_DIRECTORY,
B_SYSTEM_DATA_DIRECTORY
};
for (size_t i = 0; i < sizeof(kDirectories) / sizeof(kDirectories[0]);
i++) {
BDirectory directory;
if (find_directory(kDirectories[i], &path) != B_OK
|| path.Append(kRulesDirectoryPath) != B_OK
|| directory.SetTo(path.Path()) != B_OK) {
continue;
}
entry_ref entry;
while (directory.GetNextRef(&entry) == B_OK) {
BPath filePath;
if (filePath.SetTo(path.Path(), entry.name) == B_OK)
_LoadRulesFile(filePath.Path());
}
}
}
void
ExpanderRules::_LoadRulesFile(const char* path)
{
FILE* file = fopen(path, "r");
if (file == NULL)
return;
char buffer[1024];
BString strings[4];
while (fgets(buffer, 1024 - 1, file) != NULL) {
int32 i = 0, j = 0;
int32 firstQuote = -1;
while (buffer[i] != '#' && buffer[i] != '\n' && j < 4) {
if ((j == 0 || j > 1) && buffer[i] == '"') {
if (firstQuote >= 0) {
strings[j++].SetTo(&buffer[firstQuote+1],
i - firstQuote - 1);
firstQuote = -1;
} else
firstQuote = i;
} else if (j == 1 && (buffer[i] == ' ' || buffer[i] == '\t')) {
if (firstQuote >= 0) {
if (firstQuote + 1 != i) {
strings[j++].SetTo(&buffer[firstQuote+1],
i - firstQuote - 1);
firstQuote = -1;
} else
firstQuote = i;
} else
firstQuote = i;
}
i++;
}
if (j == 4)
_AddRule(strings[0], strings[1], strings[2], strings[3]);
}
fclose(file);
}
bool
ExpanderRules::_AddRule(const char* mimetype, const BString& filenameExtension,
const BString& listingCmd, const BString& expandCmd)
{
ExpanderRule* rule = new(std::nothrow) ExpanderRule(mimetype,
filenameExtension, listingCmd, expandCmd);
if (rule == NULL || !fList.AddItem(rule)) {
delete rule;
return false;
}
return true;
}
// #pragma mark - RuleRefFilter
+10 -7
View File
@@ -16,13 +16,10 @@
class ExpanderRule {
public:
ExpanderRule(BString mimetype,
BString filenameExtension,
BString listingCmd, BString expandCmd);
ExpanderRule(const char* mimetype,
const char* filenameExtension,
const char* listingCmd,
const char* expandCmd);
const BString& filenameExtension,
const BString& listingCmd,
const BString& expandCmd);
const BMimeType& MimeType() const
{ return fMimeType; }
@@ -51,7 +48,13 @@ public:
ExpanderRule* MatchingRule(const entry_ref* ref);
private:
status_t _Open(BFile* file);
void _LoadRulesFiles();
void _LoadRulesFile(const char* path);
bool _AddRule(const char* mimetype,
const BString& filenameExtension,
const BString& listingCmd,
const BString& expandCmd);
private:
BList fList;
+14 -3
View File
@@ -181,14 +181,25 @@ ExpanderSettings::~ExpanderSettings()
}
/*static*/ status_t
ExpanderSettings::GetSettingsDirectoryPath(BPath& _path)
{
status_t error = find_directory(B_USER_SETTINGS_DIRECTORY, &_path);
return error == B_OK ? _path.Append("expander") : error;
}
status_t
ExpanderSettings::Open(BFile *file, int32 mode)
{
BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
return B_ERROR;
status_t error = GetSettingsDirectoryPath(path);
if (error != B_OK)
return error;
path.Append("Expander_Settings");
error = path.Append("settings");
if (error != B_OK)
return error;
return file->SetTo(path.Path(), mode);
}
+6
View File
@@ -32,6 +32,10 @@
#include <Message.h>
#include <File.h>
class BPath;
static const uint32 kMsgExpanderSettings = 'Exst';
class ExpanderSettings {
@@ -42,6 +46,8 @@ class ExpanderSettings {
const BMessage &Message() const { return fMessage; }
void UpdateFrom(BMessage *message);
static status_t GetSettingsDirectoryPath(BPath& _path);
private:
status_t Open(BFile *file, int32 mode);