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) ; 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 rule AddOptionalPackageDescriptionToHaikuImage file : searchPath
{ {
-19
View File
@@ -1597,11 +1597,6 @@ if [ IsOptionalHaikuImagePackageAdded P7zip ] {
InstallOptionalHaikuImagePackage InstallOptionalHaikuImagePackage
$(baseURL)/p7zip-9.20.1-x86_64-2012-12-08.zip ; $(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 { } else {
Echo "No optional package P7zip available for $(TARGET_ARCH)" ; 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" Echo "No optional package XZ-Utils available for gcc"
$(HAIKU_GCC_VERSION[1]) ; $(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 { } else {
Echo "No optional package XZ-Utils available for $(TARGET_ARCH)" ; Echo "No optional package XZ-Utils available for $(TARGET_ARCH)" ;
} }
+119 -96
View File
@@ -16,23 +16,19 @@
#include <compat/sys/stat.h> #include <compat/sys/stat.h>
#include "ExpanderSettings.h"
static const char* const kRulesDirectoryPath = "expander/rules";
static const char* const kUserRulesFileName = "rules";
// #pragma mark - ExpanderRule // #pragma mark - ExpanderRule
ExpanderRule::ExpanderRule(BString mimetype, BString filenameExtension, ExpanderRule::ExpanderRule(const char* mimetype,
BString listingCmd, BString expandCmd) const BString& filenameExtension, const BString& listingCmd,
: const 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)
: :
fMimeType(mimetype), fMimeType(mimetype),
fFilenameExtension(filenameExtension), fFilenameExtension(filenameExtension),
@@ -47,68 +43,23 @@ ExpanderRule::ExpanderRule(const char* mimetype, const char* filenameExtension,
ExpanderRules::ExpanderRules() ExpanderRules::ExpanderRules()
{ {
fList.AddItem(new ExpanderRule("", ".tar.gz", // Load the rules files first, then add the built-in rules. This way the
"tar -ztvf %s", "tar -zxf %s")); // built-ins can be overridden, if the files contain matching rules.
fList.AddItem(new ExpanderRule("", ".tar.bz2", _LoadRulesFiles();
"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"));
BFile file; _AddRule("", ".tar.gz", "tar -ztvf %s", "tar -zxf %s");
if (_Open(&file) != B_OK) _AddRule("", ".tar.bz2", "tar -jtvf %s", "tar -jxf %s");
return; _AddRule("", ".tar.Z", "tar -Ztvf %s", "tar -Zxf %s");
_AddRule("", ".tgz", "tar -ztvf %s", "tar -zxf %s");
int fd = file.Dup(); _AddRule("application/x-tar", ".tar", "tar -tvf %s", "tar -xf %s");
FILE* f = fdopen(fd, "r"); _AddRule("application/x-gzip", ".gz", "echo %s | sed 's/.gz$//g'",
"gunzip -c %s > `echo %s | sed 's/.gz$//g'`");
char buffer[1024]; _AddRule("application/x-bzip2", ".bz2", "echo %s | sed 's/.bz2$//g'",
BString strings[4]; "bunzip2 -k %s");
while (fgets(buffer, 1024 - 1, f) != NULL) { _AddRule("application/zip", ".zip", "unzip -l %s", "unzip -o %s");
int32 i = 0, j = 0; _AddRule("application/x-zip-compressed", ".zip", "unzip -l %s",
int32 firstQuote = -1; "unzip -o %s");
while (buffer[i] != '#' && buffer[i] != '\n' && j < 4) { _AddRule("application/x-rar", ".rar", "unrar v %s", "unrar x -y %s");
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);
} }
@@ -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* ExpanderRule*
ExpanderRules::MatchingRule(BString& fileName, const char* filetype) 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 // #pragma mark - RuleRefFilter
+10 -7
View File
@@ -16,13 +16,10 @@
class ExpanderRule { class ExpanderRule {
public: public:
ExpanderRule(BString mimetype,
BString filenameExtension,
BString listingCmd, BString expandCmd);
ExpanderRule(const char* mimetype, ExpanderRule(const char* mimetype,
const char* filenameExtension, const BString& filenameExtension,
const char* listingCmd, const BString& listingCmd,
const char* expandCmd); const BString& expandCmd);
const BMimeType& MimeType() const const BMimeType& MimeType() const
{ return fMimeType; } { return fMimeType; }
@@ -51,7 +48,13 @@ public:
ExpanderRule* MatchingRule(const entry_ref* ref); ExpanderRule* MatchingRule(const entry_ref* ref);
private: 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: private:
BList fList; 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 status_t
ExpanderSettings::Open(BFile *file, int32 mode) ExpanderSettings::Open(BFile *file, int32 mode)
{ {
BPath path; BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) status_t error = GetSettingsDirectoryPath(path);
return B_ERROR; 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); return file->SetTo(path.Path(), mode);
} }
+6
View File
@@ -32,6 +32,10 @@
#include <Message.h> #include <Message.h>
#include <File.h> #include <File.h>
class BPath;
static const uint32 kMsgExpanderSettings = 'Exst'; static const uint32 kMsgExpanderSettings = 'Exst';
class ExpanderSettings { class ExpanderSettings {
@@ -42,6 +46,8 @@ class ExpanderSettings {
const BMessage &Message() const { return fMessage; } const BMessage &Message() const { return fMessage; }
void UpdateFrom(BMessage *message); void UpdateFrom(BMessage *message);
static status_t GetSettingsDirectoryPath(BPath& _path);
private: private:
status_t Open(BFile *file, int32 mode); status_t Open(BFile *file, int32 mode);