/* * Author: * Ted Gould * * Copyright (C) 2006 Johan Engelen, johan@shouraizou.nl * Copyright (C) 2004 Author * * Released under GNU GPL, read the file 'COPYING' for more information */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "config.h" #include "path-prefix.h" #include "dependency.h" #include "db.h" #include "extension.h" namespace Inkscape { namespace Extension { // These strings are for XML attribute comparisons and should not be translated gchar const * Dependency::_type_str[] = { "executable", "file", "extension", }; // These strings are for XML attribute comparisons and should not be translated gchar const * Dependency::_location_str[] = { "path", "extensions", "absolute", }; /** \brief Create a dependency using an XML definition \param in_repr XML definition of the dependency This function mostly looks for the 'location' and 'type' attributes and turns them into the enums of the same name. This makes things a little bit easier to use later. Also, a pointer to the core content is pulled out -- also to make things easier. */ Dependency::Dependency (Inkscape::XML::Node * in_repr) { _type = TYPE_FILE; _location = LOCATION_PATH; _repr = in_repr; _string = NULL; _description = NULL; Inkscape::GC::anchor(_repr); const gchar * location = _repr->attribute("location"); for (int i = 0; i < LOCATION_CNT && location != NULL; i++) { if (!strcmp(location, _location_str[i])) { _location = (location_t)i; break; } } const gchar * type = _repr->attribute("type"); for (int i = 0; i < TYPE_CNT && type != NULL; i++) { if (!strcmp(type, _type_str[i])) { _type = (type_t)i; break; } } _string = sp_repr_children(_repr)->content(); _description = _repr->attribute("description"); if (_description == NULL) _description = _repr->attribute("_description"); return; } /** \brief This depenency is not longer needed Unreference the XML structure. */ Dependency::~Dependency (void) { Inkscape::GC::release(_repr); } /** \brief Check if the dependency passes. \return Whether or not the dependency passes. This function depends largely on all of the enums. The first level that is evaluted is the \c _type. If the type is \c TYPE_EXTENSION then the id for the extension is looked up in the database. If the extension is found, and it is not deactivated, the dependency passes. If the type is \c TYPE_EXECUTABLE or \c TYPE_FILE things are getting even more interesting because now the \c _location variable is also taken into account. First, the difference between the two is that the file test for \c TYPE_EXECUTABLE also tests to make sure the file is executable, besides checking that it exists. If the \c _location is \c LOCATION_EXTENSIONS then the \c INKSCAPE_EXTENSIONDIR is put on the front of the string with \c build_filename. Then the appopriate filetest is run. If the \c _location is \c LOCATION_ABSOLUTE then the file test is run directly on the string. If the \c _location is \c LOCATION_PATH or not specified then the path is used to find the file. Each entry in the path is stepped through, attached to the string, and then tested. If the file is found then a TRUE is returned. If we get all the way through the path then a FALSE is returned, the command could not be found. */ bool Dependency::check (void) const { // std::cout << "Checking: " << *this << std::endl; if (_string == NULL) return FALSE; switch (_type) { case TYPE_EXTENSION: { Extension * myext = db.get(_string); if (myext == NULL) return FALSE; if (myext->deactivated()) return FALSE; break; } case TYPE_EXECUTABLE: case TYPE_FILE: { Glib::FileTest filetest = Glib::FILE_TEST_EXISTS; if (_type == TYPE_EXECUTABLE) { filetest |= Glib::FILE_TEST_IS_EXECUTABLE; } std::string location(_string); switch (_location) { case LOCATION_EXTENSIONS: { for (unsigned int i=0; i