You've already forked linuxdeploy
mirror of
https://github.com/encounter/linuxdeploy.git
synced 2026-03-30 11:18:58 -07:00
Switch to extracted desktop file library
This commit is contained in:
+3
-18
@@ -76,24 +76,9 @@
|
||||
[submodule "lib/googletest"]
|
||||
path = lib/googletest
|
||||
url = https://github.com/google/googletest
|
||||
[submodule "lib/boost-lexical_cast"]
|
||||
path = lib/boost-lexical_cast
|
||||
url = https://github.com/boostorg/lexical_cast
|
||||
[submodule "lib/boost-concept_check"]
|
||||
path = lib/boost-concept_check
|
||||
url = https://github.com/boostorg/concept_check
|
||||
[submodule "lib/boost-numeric_conversion"]
|
||||
path = lib/boost-numeric_conversion
|
||||
url = https://github.com/boostorg/numeric_conversion
|
||||
[submodule "lib/boost-array"]
|
||||
path = lib/boost-array
|
||||
url = https://github.com/boostorg/array
|
||||
[submodule "lib/boost-container"]
|
||||
path = lib/boost-container
|
||||
url = https://github.com/boostorg/container
|
||||
[submodule "lib/boost-move"]
|
||||
path = lib/boost-move
|
||||
url = https://github.com/boostorg/move
|
||||
[submodule "lib/boost-math"]
|
||||
path = lib/boost-math
|
||||
url = https://github.com/boostorg/math
|
||||
[submodule "lib/linuxdeploy-desktopfile"]
|
||||
path = lib/linuxdeploy-desktopfile
|
||||
url = https://github.com/linuxdeploy/linuxdeploy-desktopfile
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
// local includes
|
||||
#include "linuxdeploy/core/desktopfile/desktopfile.h"
|
||||
#include "linuxdeploy/desktopfile/desktopfile.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
// system includes
|
||||
#include <unordered_map>
|
||||
|
||||
// library includes
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
// local includes
|
||||
#include "desktopfileentry.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace linuxdeploy {
|
||||
namespace core {
|
||||
namespace desktopfile {
|
||||
/*
|
||||
* Parse and read desktop files.
|
||||
*/
|
||||
class DesktopFile {
|
||||
public:
|
||||
// describes a single section
|
||||
typedef std::unordered_map<std::string, DesktopFileEntry> section_t;
|
||||
|
||||
// describes all sections in the desktop file
|
||||
typedef std::unordered_map<std::string, section_t> sections_t;
|
||||
|
||||
private:
|
||||
// private data class pattern
|
||||
class PrivateData;
|
||||
std::shared_ptr<PrivateData> d;
|
||||
|
||||
// (in)equality operators are implemented outside this class
|
||||
friend bool operator==(const DesktopFile& first, const DesktopFile& second);
|
||||
friend bool operator!=(const DesktopFile& first, const DesktopFile& second);
|
||||
|
||||
public:
|
||||
// default constructor
|
||||
DesktopFile();
|
||||
|
||||
// construct from existing desktop file
|
||||
// if the file exists, it will be read using DesktopFileReader
|
||||
// if reading fails, exceptions will be thrown (see DesktopFileReader for more information)
|
||||
explicit DesktopFile(const boost::filesystem::path& path);
|
||||
|
||||
// construct by reading an existing stream
|
||||
// file must exist, otherwise std::runtime_error is thrown
|
||||
explicit DesktopFile(std::istream& is);
|
||||
|
||||
// copy constructor
|
||||
DesktopFile(const DesktopFile& other);
|
||||
|
||||
// copy assignment constructor
|
||||
DesktopFile& operator=(const DesktopFile& other);
|
||||
|
||||
// move assignment operator
|
||||
DesktopFile& operator=(DesktopFile&& other) noexcept;
|
||||
|
||||
public:
|
||||
// returns true if a file has been loaded, false otherwise
|
||||
bool isEmpty() const;
|
||||
|
||||
// read desktop file
|
||||
// sets path associated with this file
|
||||
// throws exceptions in case of issues, see DesktopFileReader for more information
|
||||
void read(const boost::filesystem::path& path);
|
||||
|
||||
// read desktop file from existing stream
|
||||
// throws exceptions in case of issues, see DesktopFileReader for more information
|
||||
void read(std::istream& is);
|
||||
|
||||
// get path associated with this file
|
||||
boost::filesystem::path path() const;
|
||||
|
||||
// sets the path associated with this desktop file
|
||||
// used to e.g., save the desktop file
|
||||
void setPath(const boost::filesystem::path& path);
|
||||
|
||||
// clear contents of desktop file
|
||||
void clear();
|
||||
|
||||
// save desktop file
|
||||
bool save() const;
|
||||
|
||||
// save desktop file to path
|
||||
// does not change path associated with desktop file
|
||||
// throws exceptions in case of errors, see DesktopFileWriter::save(...) for more information
|
||||
bool save(const boost::filesystem::path& path) const;
|
||||
|
||||
// save desktop file to ostream
|
||||
// does not change path associated with desktop file
|
||||
// throws exceptions in case of errors, see DesktopFileWriter::save(...) for more information
|
||||
bool save(std::ostream& os) const;
|
||||
|
||||
// check if entry exists in given section and key
|
||||
bool entryExists(const std::string& section, const std::string& key) const;
|
||||
|
||||
// get key from desktop file
|
||||
// an std::string passed as value parameter will be populated with the contents
|
||||
// returns true (and populates value) if the key exists, false otherwise
|
||||
bool getEntry(const std::string& section, const std::string& key, DesktopFileEntry& value) const;
|
||||
|
||||
// add key to section in desktop file
|
||||
// the section will be created if it doesn't exist already
|
||||
// returns true if an existing key was overwritten, false otherwise
|
||||
bool setEntry(const std::string& section, const DesktopFileEntry& entry);
|
||||
|
||||
// add key to section in desktop file
|
||||
// the section will be created if it doesn't exist already
|
||||
// returns true if an existing key was overwritten, false otherwise
|
||||
bool setEntry(const std::string& section, DesktopFileEntry&& entry);
|
||||
|
||||
// create common application entries in desktop file
|
||||
// returns false if one of the keys exists and was left unmodified
|
||||
bool addDefaultKeys(const std::string& executableFileName);
|
||||
|
||||
// validate desktop file
|
||||
bool validate() const;
|
||||
};
|
||||
|
||||
// DesktopFile equality operator
|
||||
bool operator==(const DesktopFile& first, const DesktopFile& second);
|
||||
|
||||
// DesktopFile inequality operator
|
||||
bool operator!=(const DesktopFile& first, const DesktopFile& second);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// system headers
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
// library headers
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace linuxdeploy {
|
||||
namespace core {
|
||||
namespace desktopfile {
|
||||
class DesktopFileEntry {
|
||||
private:
|
||||
// opaque data class pattern
|
||||
class PrivateData;
|
||||
|
||||
std::shared_ptr<PrivateData> d;
|
||||
|
||||
public:
|
||||
// default constructor
|
||||
DesktopFileEntry();
|
||||
|
||||
// construct from key and value
|
||||
explicit DesktopFileEntry(std::string key, std::string value);
|
||||
|
||||
// copy constructor
|
||||
DesktopFileEntry(const DesktopFileEntry& other);
|
||||
|
||||
// copy assignment constructor
|
||||
DesktopFileEntry& operator=(const DesktopFileEntry& other);
|
||||
|
||||
// move assignment operator
|
||||
DesktopFileEntry& operator=(DesktopFileEntry&& other) noexcept;
|
||||
|
||||
// equality operator
|
||||
bool operator==(const DesktopFileEntry& other) const;
|
||||
|
||||
// inequality operator
|
||||
bool operator!=(const DesktopFileEntry& other) const;
|
||||
|
||||
public:
|
||||
// checks whether a key and value have been set
|
||||
bool isEmpty() const;
|
||||
|
||||
// return entry's key
|
||||
const std::string& key() const;
|
||||
|
||||
// return entry's value
|
||||
const std::string& value() const;
|
||||
|
||||
public:
|
||||
// convert value to integer
|
||||
// throws boost::bad_lexical_cast in case of type errors
|
||||
int32_t asInt() const;
|
||||
|
||||
// convert value to long
|
||||
// throws boost::bad_lexical_cast in case of type errors
|
||||
int64_t asLong() const;
|
||||
|
||||
// convert value to double
|
||||
// throws boost::bad_lexical_cast in case of type errors
|
||||
double asDouble() const;
|
||||
|
||||
// split CSV list value into vector
|
||||
// the separator used to split the string is a semicolon as per desktop file spec
|
||||
std::vector<std::string> parseStringList() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// system includes
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace linuxdeploy {
|
||||
namespace core {
|
||||
namespace desktopfile {
|
||||
/**
|
||||
* Desktop file library's base exception.
|
||||
*/
|
||||
class DesktopFileError : public std::runtime_error {
|
||||
public:
|
||||
explicit DesktopFileError(const std::string& message = "unknown desktop file error") : runtime_error(message) {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception thrown by DesktopFileReader on parsing errors.
|
||||
*/
|
||||
class ParseError : public DesktopFileError {
|
||||
public:
|
||||
explicit ParseError(const std::string& message = "unknown parse error") : DesktopFileError(message) {};
|
||||
};
|
||||
|
||||
/**
|
||||
* I/O exception, thrown if files cannot be opened, reading or writing fails etc.
|
||||
*/
|
||||
class IOError : public DesktopFileError {
|
||||
public:
|
||||
explicit IOError(const std::string& message = "unknown I/O error") : DesktopFileError(message) {};
|
||||
};
|
||||
|
||||
class UnknownSectionError : public DesktopFileError {
|
||||
public:
|
||||
explicit UnknownSectionError(const std::string& section) : DesktopFileError("unknown section: " + section) {};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-31
@@ -9,6 +9,8 @@ add_library(args INTERFACE)
|
||||
target_sources(args INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/args/args.hxx)
|
||||
target_include_directories(args INTERFACE args)
|
||||
|
||||
add_subdirectory(linuxdeploy-desktopfile)
|
||||
|
||||
if(NOT USE_SYSTEM_BOOST)
|
||||
add_library(boost_config INTERFACE)
|
||||
set_property(TARGET boost_config PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-config/include>")
|
||||
@@ -101,38 +103,8 @@ if(NOT USE_SYSTEM_BOOST)
|
||||
boost_config boost_predef boost_assert boost_throw_exception boost_smart_ptr boost_core boost_mpl
|
||||
boost_type_traits boost_static_assert boost_integer boost_preprocessor boost_functional boost_detail
|
||||
)
|
||||
|
||||
add_library(boost_numeric_conversion INTERFACE)
|
||||
set_property(TARGET boost_numeric_conversion PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-numeric_conversion/include>")
|
||||
set_property(TARGET boost_numeric_conversion PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_concept_check INTERFACE)
|
||||
set_property(TARGET boost_concept_check PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-concept_check/include>")
|
||||
set_property(TARGET boost_concept_check PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
target_link_libraries(boost_concept_check INTERFACE boost_numeric_conversion)
|
||||
|
||||
add_library(boost_array INTERFACE)
|
||||
set_property(TARGET boost_array PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-array/include>")
|
||||
set_property(TARGET boost_array PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_move INTERFACE)
|
||||
set_property(TARGET boost_move PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-move/include>")
|
||||
set_property(TARGET boost_move PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_container INTERFACE)
|
||||
set_property(TARGET boost_container PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-container/include>")
|
||||
set_property(TARGET boost_container PROPERTY INTERFACE_LINK_LIBRARIES boost_config boost_move)
|
||||
|
||||
add_library(boost_math INTERFACE)
|
||||
set_property(TARGET boost_math PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-math/include>")
|
||||
set_property(TARGET boost_math PROPERTY INTERFACE_LINK_LIBRARIES boost_config boost_move)
|
||||
|
||||
add_library(boost_lexical_cast INTERFACE)
|
||||
set_property(TARGET boost_lexical_cast PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-lexical_cast/include>")
|
||||
set_property(TARGET boost_lexical_cast PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
target_link_libraries(boost_lexical_cast INTERFACE boost_concept_check boost_numeric_conversion boost_array boost_container boost_math)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
if(BUILD_TESTING AND NOT TARGET gtest)
|
||||
add_subdirectory(googletest)
|
||||
endif()
|
||||
|
||||
Submodule lib/boost-array deleted from cef221d8b4
Submodule lib/boost-concept_check deleted from 7dbaa85413
Submodule lib/boost-lexical_cast deleted from 5cd9771337
Submodule lib/boost-math deleted from 6bbba17f9e
Submodule lib/boost-move deleted from 3ce9452f93
Submodule lib/boost-numeric_conversion deleted from b900379a74
Submodule
+1
Submodule lib/linuxdeploy-desktopfile added at 31718acde5
+1
-1
@@ -10,7 +10,7 @@ if(USE_SYSTEM_BOOST)
|
||||
set(BOOST_LIBS Boost::filesystem Boost::regex)
|
||||
else()
|
||||
# use custom built libs
|
||||
set(BOOST_LIBS boost_system boost_filesystem boost_regex boost_lexical_cast)
|
||||
set(BOOST_LIBS boost_system boost_filesystem boost_regex)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
using namespace linuxdeploy::core;
|
||||
using namespace linuxdeploy::core::log;
|
||||
using namespace linuxdeploy::desktopfile;
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
namespace linuxdeploy {
|
||||
|
||||
@@ -18,11 +18,10 @@ target_include_directories(linuxdeploy_core_log PUBLIC ${PROJECT_SOURCE_DIR}/inc
|
||||
target_link_libraries(linuxdeploy_core_log PUBLIC ${BOOST_LIBS})
|
||||
|
||||
add_subdirectory(copyright)
|
||||
add_subdirectory(desktopfile)
|
||||
|
||||
add_library(linuxdeploy_core STATIC elf.cpp appdir.cpp ${HEADERS})
|
||||
target_link_libraries(linuxdeploy_core PUBLIC
|
||||
linuxdeploy_plugin linuxdeploy_core_log linuxdeploy_util linuxdeploy_core_desktopfile
|
||||
linuxdeploy_plugin linuxdeploy_core_log linuxdeploy_util linuxdeploy_desktopfile
|
||||
${BOOST_LIBS} CImg ${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
target_link_libraries(linuxdeploy_core PRIVATE linuxdeploy_core_copyright)
|
||||
|
||||
+3
-3
@@ -12,9 +12,9 @@
|
||||
|
||||
// local headers
|
||||
#include "linuxdeploy/core/appdir.h"
|
||||
#include "linuxdeploy/core/desktopfile/desktopfileentry.h"
|
||||
#include "linuxdeploy/core/elf.h"
|
||||
#include "linuxdeploy/core/log.h"
|
||||
#include "linuxdeploy/desktopfile/desktopfileentry.h"
|
||||
#include "linuxdeploy/util/util.h"
|
||||
#include "copyright.h"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "excludelist.h"
|
||||
|
||||
using namespace linuxdeploy::core;
|
||||
using namespace linuxdeploy::core::desktopfile;
|
||||
using namespace linuxdeploy::desktopfile;
|
||||
using namespace linuxdeploy::core::log;
|
||||
|
||||
using namespace cimg_library;
|
||||
@@ -651,7 +651,7 @@ namespace linuxdeploy {
|
||||
}), paths.end());
|
||||
|
||||
for (const auto& path : paths) {
|
||||
desktopFiles.emplace_back(path);
|
||||
desktopFiles.emplace_back(path.string());
|
||||
}
|
||||
|
||||
return desktopFiles;
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
file(GLOB HEADERS ${PROJECT_SOURCE_DIR}/include/linuxdeploy/core/desktopfile/*.h)
|
||||
|
||||
add_library(linuxdeploy_core_desktopfile STATIC
|
||||
desktopfile.cpp
|
||||
desktopfileentry.cpp
|
||||
desktopfilereader.cpp
|
||||
desktopfilewriter.cpp
|
||||
desktopfilereader.h
|
||||
desktopfilewriter.h
|
||||
${HEADERS}
|
||||
)
|
||||
|
||||
target_include_directories(linuxdeploy_core_desktopfile PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_link_libraries(linuxdeploy_core_desktopfile PUBLIC linuxdeploy_util linuxdeploy_core_log ${BOOST_LIBS})
|
||||
@@ -1,214 +0,0 @@
|
||||
// local headers
|
||||
#include "linuxdeploy/core/desktopfile/exceptions.h"
|
||||
#include "linuxdeploy/core/desktopfile/desktopfile.h"
|
||||
#include "linuxdeploy/core/log.h"
|
||||
#include "desktopfilereader.h"
|
||||
#include "desktopfilewriter.h"
|
||||
|
||||
using namespace linuxdeploy::core;
|
||||
using namespace linuxdeploy::core::log;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
namespace linuxdeploy {
|
||||
namespace core {
|
||||
namespace desktopfile {
|
||||
class DesktopFile::PrivateData {
|
||||
public:
|
||||
bf::path path;
|
||||
sections_t data;
|
||||
|
||||
public:
|
||||
PrivateData() = default;
|
||||
|
||||
void copyData(const std::shared_ptr<PrivateData>& other) {
|
||||
path = other->path;
|
||||
data = other->data;
|
||||
}
|
||||
|
||||
public:
|
||||
bool isEmpty() const {
|
||||
return data.empty();
|
||||
}
|
||||
};
|
||||
|
||||
DesktopFile::DesktopFile() : d(std::make_shared<PrivateData>()) {}
|
||||
|
||||
DesktopFile::DesktopFile(const bf::path& path) : DesktopFile() {
|
||||
// if the file doesn't exist, an exception shall be thrown
|
||||
// otherwise, a user cannot know for sure whether a file was actually read (would need to check this
|
||||
// manually beforehand
|
||||
if (!bf::exists(path)) {
|
||||
throw IOError("Could not find file " + path.string());
|
||||
}
|
||||
|
||||
// will throw exceptions in case of issues
|
||||
read(path);
|
||||
};
|
||||
|
||||
DesktopFile::DesktopFile(std::istream& is) : DesktopFile() {
|
||||
// will throw exceptions in case of issues
|
||||
read(is);
|
||||
};
|
||||
|
||||
// copy constructor
|
||||
DesktopFile::DesktopFile(const DesktopFile& other) : DesktopFile() {
|
||||
d->copyData(other.d);
|
||||
}
|
||||
|
||||
// copy assignment constructor
|
||||
DesktopFile& DesktopFile::operator=(const DesktopFile& other) {
|
||||
if (this != &other) {
|
||||
d->copyData(other.d);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move assignment operator
|
||||
DesktopFile& DesktopFile::operator=(DesktopFile&& other) noexcept {
|
||||
if (this != &other) {
|
||||
d = other.d;
|
||||
other.d = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void DesktopFile::read(const boost::filesystem::path& path) {
|
||||
setPath(path);
|
||||
|
||||
// clear data before reading a new file
|
||||
clear();
|
||||
|
||||
DesktopFileReader reader(path);
|
||||
d->data = std::move(reader.data());
|
||||
}
|
||||
|
||||
void DesktopFile::read(std::istream& is) {
|
||||
// clear data before reading a new file
|
||||
clear();
|
||||
|
||||
DesktopFileReader reader(is);
|
||||
d->data = reader.data();
|
||||
}
|
||||
|
||||
boost::filesystem::path DesktopFile::path() const {
|
||||
return d->path;
|
||||
}
|
||||
|
||||
void DesktopFile::setPath(const boost::filesystem::path& path) {
|
||||
d->path = path;
|
||||
}
|
||||
|
||||
bool DesktopFile::isEmpty() const {
|
||||
return d->isEmpty();
|
||||
}
|
||||
|
||||
void DesktopFile::clear() {
|
||||
d->data.clear();
|
||||
}
|
||||
|
||||
bool DesktopFile::save() const {
|
||||
return save(d->path);
|
||||
}
|
||||
|
||||
bool DesktopFile::save(const boost::filesystem::path& path) const {
|
||||
DesktopFileWriter writer(d->data);
|
||||
writer.save(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DesktopFile::save(std::ostream& os) const {
|
||||
DesktopFileWriter writer(d->data);
|
||||
writer.save(os);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DesktopFile::entryExists(const std::string& section, const std::string& key) const {
|
||||
auto it = d->data.find(section);
|
||||
if (it == d->data.end())
|
||||
return false;
|
||||
|
||||
return (it->second.find(key) != it->second.end());
|
||||
}
|
||||
|
||||
bool DesktopFile::setEntry(const std::string& section, const DesktopFileEntry& entry) {
|
||||
// check if value exists -- used for return value
|
||||
auto rv = entryExists(section, entry.key());
|
||||
|
||||
d->data[section][entry.key()] = entry;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool DesktopFile::setEntry(const std::string& section, DesktopFileEntry&& entry) {
|
||||
// check if value exists -- used for return value
|
||||
auto rv = entryExists(section, entry.key());
|
||||
|
||||
d->data[section][entry.key()] = entry;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool DesktopFile::getEntry(const std::string& section, const std::string& key, DesktopFileEntry& entry) const {
|
||||
if (!entryExists(section, key))
|
||||
return false;
|
||||
|
||||
entry = d->data[section][key];
|
||||
|
||||
// make sure keys are equal
|
||||
assert(key == entry.key());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DesktopFile::addDefaultKeys(const std::string& executableFileName) {
|
||||
ldLog() << "Adding default values to desktop file:" << path() << std::endl;
|
||||
|
||||
auto rv = true;
|
||||
|
||||
auto setDefault = [&rv, this](const std::string& section, const std::string& key, const std::string& value) {
|
||||
if (entryExists(section, key)) {
|
||||
DesktopFileEntry entry;
|
||||
|
||||
// this should never return false
|
||||
auto entryExists = getEntry(section, key, entry);
|
||||
assert(entryExists);
|
||||
|
||||
ldLog() << LD_WARNING << "Key exists, not modified:" << key << "(current value:" << entry.value() << LD_NO_SPACE << ")" << std::endl;
|
||||
rv = false;
|
||||
} else {
|
||||
auto entryOverwritten = setEntry(section, DesktopFileEntry(key, value));
|
||||
assert(!entryOverwritten);
|
||||
}
|
||||
};
|
||||
|
||||
setDefault("Desktop Entry", "Name", executableFileName);
|
||||
setDefault("Desktop Entry", "Exec", executableFileName);
|
||||
setDefault("Desktop Entry", "Icon", executableFileName);
|
||||
setDefault("Desktop Entry", "Type", "Application");
|
||||
setDefault("Desktop Entry", "Categories", "Utility;");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool DesktopFile::validate() const {
|
||||
// FIXME: call desktop-file-validate
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==(const DesktopFile& first, const DesktopFile& second) {
|
||||
return first.d->path == second.d->path && first.d->data == second.d->data;
|
||||
}
|
||||
|
||||
bool operator !=(const DesktopFile& first, const DesktopFile& second) {
|
||||
return !operator==(first, second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
// library headers
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
// local headers
|
||||
#include "linuxdeploy/core/log.h"
|
||||
#include "linuxdeploy/core/desktopfile/desktopfileentry.h"
|
||||
|
||||
using boost::lexical_cast;
|
||||
|
||||
namespace linuxdeploy {
|
||||
namespace core {
|
||||
using namespace log;
|
||||
|
||||
namespace desktopfile {
|
||||
class DesktopFileEntry::PrivateData {
|
||||
public:
|
||||
std::string key;
|
||||
std::string value;
|
||||
|
||||
public:
|
||||
void copyData(const std::shared_ptr<PrivateData>& other) {
|
||||
key = other->key;
|
||||
value = other->value;
|
||||
}
|
||||
|
||||
void assertValueNotEmpty() {
|
||||
if (value.empty())
|
||||
throw std::invalid_argument("value is empty");
|
||||
}
|
||||
};
|
||||
|
||||
DesktopFileEntry::DesktopFileEntry() : d(new PrivateData) {}
|
||||
|
||||
DesktopFileEntry::DesktopFileEntry(std::string key, std::string value) : DesktopFileEntry() {
|
||||
d->key = std::move(key);
|
||||
d->value = std::move(value);
|
||||
}
|
||||
|
||||
DesktopFileEntry::DesktopFileEntry(const DesktopFileEntry& other) : DesktopFileEntry() {
|
||||
d->copyData(other.d);
|
||||
}
|
||||
|
||||
DesktopFileEntry& DesktopFileEntry::operator=(const DesktopFileEntry& other) {
|
||||
if (this != &other) {
|
||||
d.reset(new PrivateData);
|
||||
d->copyData(other.d);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DesktopFileEntry& DesktopFileEntry::operator=(DesktopFileEntry&& other) noexcept {
|
||||
if (this != &other) {
|
||||
d = other.d;
|
||||
other.d = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool DesktopFileEntry::operator==(const DesktopFileEntry& other) const {
|
||||
return d->key == other.d->key && d->value == other.d->value;
|
||||
}
|
||||
|
||||
bool DesktopFileEntry::operator!=(const DesktopFileEntry& other) const {
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
bool DesktopFileEntry::isEmpty() const {
|
||||
return d->key.empty();
|
||||
}
|
||||
|
||||
const std::string& DesktopFileEntry::key() const {
|
||||
return d->key;
|
||||
}
|
||||
|
||||
const std::string& DesktopFileEntry::value() const {
|
||||
return d->value;
|
||||
}
|
||||
|
||||
int32_t DesktopFileEntry::asInt() const {
|
||||
d->assertValueNotEmpty();
|
||||
|
||||
return lexical_cast<int32_t>(value());
|
||||
}
|
||||
|
||||
int64_t DesktopFileEntry::asLong() const {
|
||||
d->assertValueNotEmpty();
|
||||
|
||||
return lexical_cast<int64_t>(value());
|
||||
}
|
||||
|
||||
double DesktopFileEntry::asDouble() const {
|
||||
d->assertValueNotEmpty();
|
||||
|
||||
return lexical_cast<double>(value());
|
||||
}
|
||||
|
||||
std::vector<std::string> DesktopFileEntry::parseStringList() const {
|
||||
const auto& value = this->value();
|
||||
|
||||
if (value.empty())
|
||||
return {};
|
||||
|
||||
if (value.back() != ';')
|
||||
ldLog() << LD_DEBUG << "desktop file string list does not end with semicolon:" << value
|
||||
<< std::endl;
|
||||
|
||||
std::vector<std::string> list;
|
||||
|
||||
std::stringstream ss(value);
|
||||
|
||||
std::string currentVal;
|
||||
while (std::getline(ss, currentVal, ';')) {
|
||||
// the last value will be empty, as in desktop files, lists shall end with a semicolon
|
||||
// therefore we skip all empty values (assuming that empty values in lists in desktop files don't make sense anyway)
|
||||
if (!currentVal.empty())
|
||||
list.emplace_back(currentVal);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user