%module conf %include %include %include %include %import(module="libdnf.common_types") "common_types.i" %begin %{ #define SWIG_PYTHON_2_UNICODE %} %{ // make SWIG wrap following headers #include "libdnf/conf/ConfigRepo.hpp" #include "libdnf/conf/ConfigParser.hpp" #include #include #include %} %exception { try { $action } catch (const std::exception & e) { SWIG_exception(SWIG_RuntimeError, e.what()); } } #define final // make SWIG look into following headers %ignore libdnf::Option::Exception; %ignore libdnf::Option::InvalidValue; %ignore libdnf::Option::ValueNotSet; %include "libdnf/conf/Option.hpp" %include "libdnf/conf/OptionChild.hpp" %include "libdnf/conf/OptionBool.hpp" %include "libdnf/conf/OptionEnum.hpp" %template(OptionEnumString) libdnf::OptionEnum; %include "libdnf/conf/OptionNumber.hpp" %template(OptionNumberInt32) libdnf::OptionNumber; %template(OptionNumberUInt32) libdnf::OptionNumber; %template(OptionNumberInt64) libdnf::OptionNumber; %template(OptionNumberUInt64) libdnf::OptionNumber; %template(OptionNumberFloat) libdnf::OptionNumber; %include "libdnf/conf/OptionSeconds.hpp" %include "libdnf/conf/OptionString.hpp" %include "libdnf/conf/OptionStringList.hpp" %include "libdnf/conf/OptionPath.hpp" %template(OptionChildBool) libdnf::OptionChild; %template(OptionChildString) libdnf::OptionChild; %template(OptionChildStringList) libdnf::OptionChild; %template(OptionChildNumberInt32) libdnf::OptionChild>; %template(OptionChildNumberUInt32) libdnf::OptionChild>; %template(OptionChildNumberFloat) libdnf::OptionChild>; %template(OptionChildEnumString) libdnf::OptionChild>; %template(OptionChildSeconds) libdnf::OptionChild; %include %inline %{ class StopIterator {}; template class Iterator { public: Iterator(typename T::iterator _cur, typename T::iterator _end) : cur(_cur), end(_end) {} Iterator* __iter__() { return this; } typename T::iterator cur; typename T::iterator end; }; %} %feature ("flatnested", "1"); %rename (OptionBinds_Item) libdnf::OptionBinds::Item; %ignore libdnf::OptionBinds::Exception; %ignore libdnf::OptionBinds::OutOfRange; %ignore libdnf::OptionBinds::AlreadyExists; %ignore libdnf::OptionBinds::add(const std::string & id, Option & option, const Item::NewStringFunc & newString, const Item::GetValueStringFunc & getValueString, bool addValue); %ignore libdnf::OptionBinds::add(const std::string & id, Option & option, Item::NewStringFunc && newString, Item::GetValueStringFunc && getValueString, bool addValue); %ignore libdnf::OptionBinds::begin; %ignore libdnf::OptionBinds::cbegin; %ignore libdnf::OptionBinds::end; %ignore libdnf::OptionBinds::cend; %ignore libdnf::OptionBinds::find; %include "libdnf/conf/OptionBinds.hpp" %feature ("flatnested", "0"); %include "libdnf/conf/Config.hpp" %include "libdnf/conf/ConfigMain.hpp" %include "libdnf/conf/ConfigRepo.hpp" %template(OptionBindsIterator) Iterator; %exception libdnf::ConfigParser::read { try { $action } catch (const libdnf::ConfigParser::CantOpenFile & e) { SWIG_exception(SWIG_IOError, e.what()); } catch (const libdnf::ConfigParser::Exception & e) { SWIG_exception(SWIG_RuntimeError, e.what()); } catch (const std::exception & e) { SWIG_exception(SWIG_RuntimeError, e.what()); } } %exception libdnf::ConfigParser::getValue { try { $action } catch (const libdnf::ConfigParser::MissingSection & e) { SWIG_exception(SWIG_IndexError, e.what()); } catch (const libdnf::ConfigParser::MissingOption & e) { SWIG_exception(SWIG_IndexError, e.what()); } catch (const libdnf::ConfigParser::Exception & e) { SWIG_exception(SWIG_RuntimeError, e.what()); } catch (const std::exception & e) { SWIG_exception(SWIG_RuntimeError, e.what()); } } %exception libdnf::ConfigParser::getSubstitutedValue { try { $action } catch (const libdnf::ConfigParser::MissingSection & e) { SWIG_exception(SWIG_IndexError, e.what()); } catch (const libdnf::ConfigParser::MissingOption & e) { SWIG_exception(SWIG_IndexError, e.what()); } catch (const libdnf::ConfigParser::Exception & e) { SWIG_exception(SWIG_RuntimeError, e.what()); } catch (const std::exception & e) { SWIG_exception(SWIG_RuntimeError, e.what()); } } %apply std::string & INOUT { std::string & text } namespace libdnf { struct ConfigParser { public: typedef PreserveOrderMap> Container; static void substitute(std::string & text, const std::map & substitutions); void setSubstitutions(const std::map & substitutions); const std::map & getSubstitutions() const; void read(const std::string & filePath); void write(const std::string & filePath, bool append) const; void write(const std::string & filePath, bool append, const std::string & section) const; void write(std::ostream & outputStream, const std::string & section) const; void write(std::ostream & outputStream) const; bool addSection(const std::string & section, const std::string & rawLine); bool addSection(const std::string & section); bool hasSection(const std::string & section) const noexcept; bool hasOption(const std::string & section, const std::string & key) const noexcept; void setValue(const std::string & section, const std::string & key, const std::string & value, const std::string & rawItem); void setValue(const std::string & section, const std::string & key, const std::string & value); bool removeSection(const std::string & section); bool removeOption(const std::string & section, const std::string & key); void addCommentLine(const std::string & section, const std::string & comment); const std::string & getValue(const std::string & section, const std::string & key) const; std::string getSubstitutedValue(const std::string & section, const std::string & key) const; const std::string & getHeader() const noexcept; std::string & getHeader() noexcept; const Container & getData() const noexcept; Container & getData() noexcept; }; } %clear std::string & text; %extend libdnf::ConfigParser { void readString(const std::string & content) { std::unique_ptr istream(new std::istringstream(content)); self->read(std::move(istream)); } } %exception __next__() { try { $action // calls %extend function next() below } catch (const StopIterator &) { PyErr_SetString(PyExc_StopIteration, "End of iterator"); return NULL; } catch (const std::exception & e) { SWIG_exception(SWIG_RuntimeError, e.what()); } } // For old Python %exception next() { try { $action // calls %extend function next() below } catch (const StopIterator &) { PyErr_SetString(PyExc_StopIteration, "End of iterator"); return NULL; } catch (const std::exception & e) { SWIG_exception(SWIG_RuntimeError, e.what()); } } %template(PairStringOptionBindsItem) std::pair; %extend Iterator { std::pair __next__() { if ($self->cur != $self->end) { auto & id = $self->cur->first; auto pValue = &($self->cur++)->second; return {id, pValue}; } throw StopIterator(); } std::pair next() { if ($self->cur != $self->end) { auto & id = $self->cur->first; auto pValue = &($self->cur++)->second; return {id, pValue}; } throw StopIterator(); } } %exception libdnf::OptionBinds::__getitem__ { try { $action } catch (const libdnf::OptionBinds::OutOfRange & e) { SWIG_exception(SWIG_IndexError, e.what()); } catch (const std::exception & e) { SWIG_exception(SWIG_RuntimeError, e.what()); } } %extend libdnf::OptionBinds { Item & __getitem__(const std::string & id) { return $self->at(id); } size_t __len__() { return $self->size(); } Iterator __iter__() { return Iterator($self->begin(), $self->end()); } } %pythoncode %{ # Partial compatibility with Python ConfigParser ConfigParser.readFileName = ConfigParser.read def ConfigParser__newRead(self, filenames): parsedFNames = [] try: if isinstance(filenames, str) or isinstance(filenames, unicode): filenames = [filenames] except NameError: pass for fname in filenames: try: self.readFileName(fname) parsedFNames.append(fname) except IOError: pass except Exception as e: raise RuntimeError("Parsing file '%s' failed: %s" % (fname, str(e))) return parsedFNames ConfigParser.read = ConfigParser__newRead del ConfigParser__newRead def ConfigParser__read_string(self, string, source=''): try: self.readString(string) except Exception as e: raise RuntimeError("Parsing source '%s' failed: %s" % (source, str(e))) ConfigParser.read_string = ConfigParser__read_string del ConfigParser__read_string def ConfigParser__add_section(self, section): if not self.addSection(section): raise KeyError("Section '%s' already exists" % section) ConfigParser.add_section = ConfigParser__add_section del ConfigParser__add_section ConfigParser.has_section = ConfigParser.hasSection ConfigParser.has_option = ConfigParser.hasOption def ConfigParser__get(self, section, option, raw=False): try: if raw: return self.getValue(section, option) else: return self.getSubstitutedValue(section, option) except IndexError as e: raise KeyError(str(e)) ConfigParser.get = ConfigParser__get del ConfigParser__get def ConfigParser__getint(self, section, option, raw=False): return int(self.get(section, option, raw=raw)) ConfigParser.getint = ConfigParser__getint del ConfigParser__getint def ConfigParser__getfloat(self, section, option, raw=False): return float(self.get(section, option, raw=raw)) ConfigParser.getfloat = ConfigParser__getfloat del ConfigParser__getfloat def ConfigParser__getboolean(self, section, option, raw=False): v = self.get(section, option, raw=raw) try: return OptionBool(False).fromString(v) except RuntimeError: raise ValueError('Not a boolean: %s' % v) ConfigParser.getboolean = ConfigParser__getboolean del ConfigParser__getboolean def ConfigParser__items(self, section, raw=False): if not self.hasSection(section): raise KeyError("No section: '%s'" % section) sectObj = self.getData()[section] items = [] for key in sectObj: if not key.startswith('#'): value = self.get(section, key, raw=raw) items.append((key, value)) return items ConfigParser.items = ConfigParser__items del ConfigParser__items def ConfigParser__set(self, section, option, value): if not self.hasSection(section): raise KeyError("No section: '%s'" % section) self.setValue(section, option, value) ConfigParser.set = ConfigParser__set del ConfigParser__set ConfigParser.remove_section = ConfigParser.removeSection def ConfigParser__remove_option(self, section, option): if not self.hasSection(section): raise KeyError("No section: '%s'" % section) return self.removeOption(section, option) ConfigParser.remove_option = ConfigParser__remove_option del ConfigParser__remove_option def ConfigParser__options(self, section): if not self.hasSection(section): raise KeyError("No section: '%s'" % section) sectObj = self.getData()[section] return [item for item in sectObj if not item.startswith('#')] ConfigParser.options = ConfigParser__options del ConfigParser__options def ConfigParser__sections(self): return list(self.getData()) ConfigParser.sections = ConfigParser__sections del ConfigParser__sections # Compatible name aliases ConfigMain.exclude = ConfigMain.excludepkgs ConfigRepo.exclude = ConfigRepo.excludepkgs %}