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:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)" ;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user