summaryrefslogtreecommitdiff
path: root/unotools
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2012-01-31 15:36:49 +0100
committerStephan Bergmann <sbergman@redhat.com>2012-01-31 15:50:10 +0100
commitca3e3e7e3198f492b2d4608ffc5420e657d99b00 (patch)
tree98b28439bf0cf0a45b8e87bbcb45aea0431d99c3 /unotools
parent9babbf346c4d6f76e8b3a243a00e73a173c16ba6 (diff)
Move unotools/configuration.hxx to comphelper
...so that other code in comphelper can use it.
Diffstat (limited to 'unotools')
-rw-r--r--unotools/Library_utl.mk1
-rw-r--r--unotools/Package_inc.mk1
-rw-r--r--unotools/inc/unotools/configuration.hxx353
-rw-r--r--unotools/source/config/configuration.cxx232
4 files changed, 0 insertions, 587 deletions
diff --git a/unotools/Library_utl.mk b/unotools/Library_utl.mk
index 71ca9c895734..5454edf46af0 100644
--- a/unotools/Library_utl.mk
+++ b/unotools/Library_utl.mk
@@ -80,7 +80,6 @@ $(eval $(call gb_Library_add_exception_objects,utl,\
unotools/source/config/configmgr \
unotools/source/config/confignode \
unotools/source/config/configpathes \
- unotools/source/config/configuration \
unotools/source/config/configvaluecontainer \
unotools/source/config/defaultoptions \
unotools/source/config/docinfohelper \
diff --git a/unotools/Package_inc.mk b/unotools/Package_inc.mk
index 426a8c0df48a..46cb143fa50b 100644
--- a/unotools/Package_inc.mk
+++ b/unotools/Package_inc.mk
@@ -44,7 +44,6 @@ $(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/configitem.hxx,unoto
$(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/configmgr.hxx,unotools/configmgr.hxx))
$(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/confignode.hxx,unotools/confignode.hxx))
$(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/configpathes.hxx,unotools/configpathes.hxx))
-$(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/configuration.hxx,unotools/configuration.hxx))
$(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/configvaluecontainer.hxx,unotools/configvaluecontainer.hxx))
$(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/datetime.hxx,unotools/datetime.hxx))
$(eval $(call gb_Package_add_file,unotools_inc,inc/unotools/defaultoptions.hxx,unotools/defaultoptions.hxx))
diff --git a/unotools/inc/unotools/configuration.hxx b/unotools/inc/unotools/configuration.hxx
deleted file mode 100644
index f308aa818037..000000000000
--- a/unotools/inc/unotools/configuration.hxx
+++ /dev/null
@@ -1,353 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * Version: MPL 1.1 / GPLv3+ / LGPLv3+
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License or as specified alternatively below. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * Major Contributor(s):
- * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
- * (initial developer)
- *
- * All Rights Reserved.
- *
- * For minor contributions see the git repository.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
- * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
- * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
- * instead of those above.
- */
-
-#ifndef INCLUDED_UNOTOOLS_CONFIGURATION_HXX
-#define INCLUDED_UNOTOOLS_CONFIGURATION_HXX
-
-#include "sal/config.h"
-
-#include "boost/noncopyable.hpp"
-#include "boost/optional.hpp"
-#include "boost/shared_ptr.hpp"
-#include "com/sun/star/uno/Any.hxx"
-#include "com/sun/star/uno/Reference.hxx"
-#include "sal/types.h"
-#include "unotools/unotoolsdllapi.h"
-
-namespace com { namespace sun { namespace star {
- namespace configuration { class XReadWriteAccess; }
- namespace container {
- class XHierarchicalNameAccess;
- class XHierarchicalNameReplace;
- class XNameAccess;
- class XNameContainer;
- }
- namespace uno { class XComponentContext; }
-} } }
-namespace rtl { class OUString; }
-
-namespace unotools {
-
-namespace detail { class ConfigurationWrapper; }
-
-/// A batch of configuration changes that is committed as a whole.
-///
-/// Client code needs to call commit explicitly; otherwise the changes are lost
-/// when the instance is destroyed.
-///
-/// This is the only class from this header file that client code should use
-/// directly.
-class UNOTOOLS_DLLPUBLIC ConfigurationChanges: private boost::noncopyable {
-public:
- static boost::shared_ptr< ConfigurationChanges > create(
- com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context);
-
- ~ConfigurationChanges();
-
- void commit() const;
-
-private:
- SAL_DLLPRIVATE ConfigurationChanges(
- com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context);
-
- SAL_DLLPRIVATE void setPropertyValue(
- rtl::OUString const & path, com::sun::star::uno::Any const & value)
- const;
-
- SAL_DLLPRIVATE com::sun::star::uno::Reference<
- com::sun::star::container::XHierarchicalNameReplace >
- getGroup(rtl::OUString const & path) const;
-
- SAL_DLLPRIVATE
- com::sun::star::uno::Reference< com::sun::star::container::XNameContainer >
- getSet(rtl::OUString const & path) const;
-
- com::sun::star::uno::Reference<
- com::sun::star::configuration::XReadWriteAccess > access_;
-
- friend class detail::ConfigurationWrapper;
-};
-
-namespace detail {
-
-/// @internal
-class UNOTOOLS_DLLPUBLIC ConfigurationWrapper: private boost::noncopyable {
-public:
- static ConfigurationWrapper const & get(
- com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context);
-
- SAL_DLLPRIVATE explicit ConfigurationWrapper(
- com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context);
-
- SAL_DLLPRIVATE ~ConfigurationWrapper();
-
- com::sun::star::uno::Any getPropertyValue(rtl::OUString const & path) const;
-
- void setPropertyValue(
- boost::shared_ptr< ConfigurationChanges > const & batch,
- rtl::OUString const & path, com::sun::star::uno::Any const & value)
- const;
-
- com::sun::star::uno::Any getLocalizedPropertyValue(
- rtl::OUString const & path) const;
-
- void setLocalizedPropertyValue(
- boost::shared_ptr< ConfigurationChanges > const & batch,
- rtl::OUString const & path, com::sun::star::uno::Any const & value)
- const;
-
- com::sun::star::uno::Reference<
- com::sun::star::container::XHierarchicalNameAccess >
- getGroupReadOnly(rtl::OUString const & path) const;
-
- com::sun::star::uno::Reference<
- com::sun::star::container::XHierarchicalNameReplace >
- getGroupReadWrite(
- boost::shared_ptr< ConfigurationChanges > const & batch,
- rtl::OUString const & path) const;
-
- com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >
- getSetReadOnly(rtl::OUString const & path) const;
-
- com::sun::star::uno::Reference< com::sun::star::container::XNameContainer >
- getSetReadWrite(
- boost::shared_ptr< ConfigurationChanges > const & batch,
- rtl::OUString const & path) const;
-
- boost::shared_ptr< ConfigurationChanges > createChanges() const;
-
-private:
- rtl::OUString extendLocalizedPath(rtl::OUString const & path) const;
-
- com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- context_;
-
- com::sun::star::uno::Reference<
- com::sun::star::container::XHierarchicalNameAccess > access_;
-};
-
-/// @internal
-template< typename T > struct Convert: private boost::noncopyable {
- static com::sun::star::uno::Any toAny(T const & value)
- { return com::sun::star::uno::makeAny(value); }
-
- static T fromAny(com::sun::star::uno::Any const & value)
- { return value.get< T >(); }
-
-private:
- Convert(); // not defined
- ~Convert(); // not defined
-};
-
-/// @internal
-template< typename T > struct Convert< boost::optional< T > >:
- private boost::noncopyable
-{
- static com::sun::star::uno::Any toAny(boost::optional< T > const & value) {
- return value
- ? com::sun::star::uno::makeAny(value.get())
- : com::sun::star::uno::Any();
- }
-
- static boost::optional< T > fromAny(com::sun::star::uno::Any const & value)
- {
- return value.hasValue()
- ? boost::optional< T >(value.get< T >()) : boost::optional< T >();
- }
-
-private:
- Convert(); // not defined
- ~Convert(); // not defined
-};
-
-}
-
-/// A type-safe wrapper around a (non-localized) configuration property.
-///
-/// Automatically generated headers for the various configuration properties
-/// derive from this template and make available its member functions to access
-/// each given configuration property.
-template< typename T, typename U > struct ConfigurationProperty:
- private boost::noncopyable
-{
- /// Get the value of the given (non-localized) configuration property.
- ///
- /// For nillable properties, U is of type boost::optional<U'>.
- static U get(
- com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context)
- {
- // Folding this into one statement causes a bogus error at least with
- // Red Hat GCC 4.6.2-1:
- com::sun::star::uno::Any a(
- detail::ConfigurationWrapper::get(context).getPropertyValue(
- T::path()));
- return detail::Convert< U >::fromAny(a);
- }
-
- /// Set the value of the given (non-localized) configuration property, via a
- /// given changes batch.
- ///
- /// For nillable properties, U is of type boost::optional<U'>.
- static void set(
- com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context,
- boost::shared_ptr< ConfigurationChanges > const & batch,
- U const & value)
- {
- detail::ConfigurationWrapper::get(context).setPropertyValue(
- batch, T::path(), detail::Convert< U >::toAny(value));
- }
-
-private:
- ConfigurationProperty(); // not defined
- ~ConfigurationProperty(); // not defined
-};
-
-/// A type-safe wrapper around a localized configuration property.
-///
-/// Automatically generated headers for the various localized configuration
-/// properties derive from this template and make available its member functions
-/// to access each given localized configuration property.
-template< typename T, typename U > struct ConfigurationLocalizedProperty:
- private boost::noncopyable
-{
- /// Get the value of the given localized configuration property, for the
- /// locale currently set at the
- /// com.sun.star.configuration.theDefaultProvider.
- ///
- /// For nillable properties, U is of type boost::optional<U'>.
- static U get(
- com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context)
- {
- // Folding this into one statement causes a bogus error at least with
- // Red Hat GCC 4.6.2-1:
- com::sun::star::uno::Any a(
- detail::ConfigurationWrapper::get(context).
- getLocalizedPropertyValue(T::path()));
- return detail::Convert< U >::fromAny(a);
- }
-
- /// Set the value of the given localized configuration property, for the
- /// locale currently set at the
- /// com.sun.star.configuration.theDefaultProvider, via a given changes
- /// batch.
- ///
- /// For nillable properties, U is of type boost::optional<U'>.
- static void set(
- com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context,
- boost::shared_ptr< ConfigurationChanges > const & batch,
- U const & value)
- {
- detail::ConfigurationWrapper::get(context).setLocalizedPropertyValue(
- batch, T::path(), detail::Convert< U >::toAny(value));
- }
-
-private:
- ConfigurationLocalizedProperty(); // not defined
- ~ConfigurationLocalizedProperty(); // not defined
-};
-
-/// A type-safe wrapper around a configuration group.
-///
-/// Automatically generated headers for the various configuration groups derive
-/// from this template and make available its member functions to access each
-/// given configuration group.
-template< typename T > struct ConfigurationGroup: private boost::noncopyable {
- /// Get read-only access to the given configuration group.
- static com::sun::star::uno::Reference<
- com::sun::star::container::XHierarchicalNameAccess >
- get(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context)
- {
- return detail::ConfigurationWrapper::get(context).getGroupReadOnly(
- T::path());
- }
-
- /// Get read/write access to the given configuration group, storing any
- /// modifications via the given changes batch.
- static com::sun::star::uno::Reference<
- com::sun::star::container::XHierarchicalNameReplace >
- get(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context,
- boost::shared_ptr< ConfigurationChanges > const & batch)
- {
- return detail::ConfigurationWrapper::get(context).getGroupReadWrite(
- batch, T::path());
- }
-
-private:
- ConfigurationGroup(); // not defined
- ~ConfigurationGroup(); // not defined
-};
-
-/// A type-safe wrapper around a configuration set.
-///
-/// Automatically generated headers for the various configuration sets derive
-/// from this template and make available its member functions to access each
-/// given configuration set.
-template< typename T > struct ConfigurationSet: private boost::noncopyable {
- /// Get read-only access to the given configuration set.
- static
- com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >
- get(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context)
- {
- return detail::ConfigurationWrapper::get(context).getSetReadOnly(
- T::path());
- }
-
- /// Get read/write access to the given configuration set, storing any
- /// modifications via the given changes batch.
- static
- com::sun::star::uno::Reference< com::sun::star::container::XNameContainer >
- get(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
- const & context,
- boost::shared_ptr< ConfigurationChanges > const & batch)
- {
- return detail::ConfigurationWrapper::get(context).getSetReadWrite(
- batch, T::path());
- }
-
-private:
- ConfigurationSet(); // not defined
- ~ConfigurationSet(); // not defined
-};
-
-}
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/unotools/source/config/configuration.cxx b/unotools/source/config/configuration.cxx
deleted file mode 100644
index a8c818c124dd..000000000000
--- a/unotools/source/config/configuration.cxx
+++ /dev/null
@@ -1,232 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * Version: MPL 1.1 / GPLv3+ / LGPLv3+
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License or as specified alternatively below. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * Major Contributor(s):
- * Copyright (C) 2011 Red Hat, Inc., Stephan Bergmann <sbergman@redhat.com>
- * (initial developer)
- *
- * All Rights Reserved.
- *
- * For minor contributions see the git repository.
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
- * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
- * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
- * instead of those above.
- */
-
-#include "sal/config.h"
-
-#include <cassert>
-
-#include "boost/shared_ptr.hpp"
-#include "com/sun/star/configuration/ReadOnlyAccess.hpp"
-#include "com/sun/star/configuration/ReadWriteAccess.hpp"
-#include "com/sun/star/configuration/XReadWriteAccess.hpp"
-#include "com/sun/star/configuration/theDefaultProvider.hpp"
-#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
-#include "com/sun/star/container/XHierarchicalNameReplace.hpp"
-#include "com/sun/star/container/XNameAccess.hpp"
-#include "com/sun/star/container/XNameContainer.hpp"
-#include "com/sun/star/lang/Locale.hpp"
-#include "com/sun/star/lang/XLocalizable.hpp"
-#include "com/sun/star/uno/Any.hxx"
-#include "com/sun/star/uno/Reference.hxx"
-#include "com/sun/star/uno/XComponentContext.hpp"
-#include "rtl/instance.hxx"
-#include "rtl/oustringostreaminserter.hxx"
-#include "rtl/ustrbuf.hxx"
-#include "rtl/ustring.h"
-#include "rtl/ustring.hxx"
-#include "sal/log.hxx"
-#include "unotools/configuration.hxx"
-
-namespace {
-
-namespace css = com::sun::star;
-
-struct TheConfigurationWrapper:
- public rtl::StaticWithArg<
- unotools::detail::ConfigurationWrapper,
- css::uno::Reference< css::uno::XComponentContext >,
- TheConfigurationWrapper >
-{};
-
-}
-
-boost::shared_ptr< unotools::ConfigurationChanges >
-unotools::ConfigurationChanges::create(
- css::uno::Reference< css::uno::XComponentContext > const & context)
-{
- return TheConfigurationWrapper::get(context).createChanges();
-}
-
-
-unotools::ConfigurationChanges::~ConfigurationChanges() {}
-
-void unotools::ConfigurationChanges::commit() const {
- access_->commitChanges();
-}
-
-unotools::ConfigurationChanges::ConfigurationChanges(
- css::uno::Reference< css::uno::XComponentContext > const & context):
- access_(css::configuration::ReadWriteAccess::create(context))
-{}
-
-void unotools::ConfigurationChanges::setPropertyValue(
- rtl::OUString const & path, css::uno::Any const & value) const
-{
- access_->replaceByHierarchicalName(path, value);
-}
-
-css::uno::Reference< css::container::XHierarchicalNameReplace >
-unotools::ConfigurationChanges::getGroup(rtl::OUString const & path) const
-{
- return css::uno::Reference< css::container::XHierarchicalNameReplace >(
- access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
-}
-
-css::uno::Reference< css::container::XNameContainer >
-unotools::ConfigurationChanges::getSet(rtl::OUString const & path) const
-{
- return css::uno::Reference< css::container::XNameContainer >(
- access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
-}
-
-unotools::detail::ConfigurationWrapper const &
-unotools::detail::ConfigurationWrapper::get(
- css::uno::Reference< css::uno::XComponentContext > const & context)
-{
- return TheConfigurationWrapper::get(context);
-}
-
-unotools::detail::ConfigurationWrapper::ConfigurationWrapper(
- css::uno::Reference< css::uno::XComponentContext > const & context):
- context_(context), access_(css::configuration::ReadOnlyAccess::get(context))
-{}
-
-unotools::detail::ConfigurationWrapper::~ConfigurationWrapper() {}
-
-css::uno::Any unotools::detail::ConfigurationWrapper::getPropertyValue(
- rtl::OUString const & path) const
-{
- return access_->getByHierarchicalName(path);
-}
-
-void unotools::detail::ConfigurationWrapper::setPropertyValue(
- boost::shared_ptr< ConfigurationChanges > const & batch,
- rtl::OUString const & path, com::sun::star::uno::Any const & value) const
-{
- assert(batch.get() != 0);
- batch->setPropertyValue(path, value);
-}
-
-css::uno::Any unotools::detail::ConfigurationWrapper::getLocalizedPropertyValue(
- rtl::OUString const & path) const
-{
- return access_->getByHierarchicalName(extendLocalizedPath(path));
-}
-
-void unotools::detail::ConfigurationWrapper::setLocalizedPropertyValue(
- boost::shared_ptr< ConfigurationChanges > const & batch,
- rtl::OUString const & path, com::sun::star::uno::Any const & value) const
-{
- assert(batch.get() != 0);
- batch->setPropertyValue(extendLocalizedPath(path), value);
-}
-
-css::uno::Reference< css::container::XHierarchicalNameAccess >
-unotools::detail::ConfigurationWrapper::getGroupReadOnly(
- rtl::OUString const & path) const
-{
- return css::uno::Reference< css::container::XHierarchicalNameAccess >(
- access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
-}
-
-css::uno::Reference< css::container::XHierarchicalNameReplace >
-unotools::detail::ConfigurationWrapper::getGroupReadWrite(
- boost::shared_ptr< ConfigurationChanges > const & batch,
- rtl::OUString const & path) const
-{
- assert(batch.get() != 0);
- return batch->getGroup(path);
-}
-
-css::uno::Reference< css::container::XNameAccess >
-unotools::detail::ConfigurationWrapper::getSetReadOnly(
- rtl::OUString const & path) const
-{
- return css::uno::Reference< css::container::XNameAccess >(
- access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
-}
-
-css::uno::Reference< css::container::XNameContainer >
-unotools::detail::ConfigurationWrapper::getSetReadWrite(
- boost::shared_ptr< ConfigurationChanges > const & batch,
- rtl::OUString const & path) const
-{
- assert(batch.get() != 0);
- return batch->getSet(path);
-}
-
-boost::shared_ptr< unotools::ConfigurationChanges >
-unotools::detail::ConfigurationWrapper::createChanges() const {
- return boost::shared_ptr< ConfigurationChanges >(
- new ConfigurationChanges(context_));
-}
-
-rtl::OUString unotools::detail::ConfigurationWrapper::extendLocalizedPath(
- rtl::OUString const & path) const
-{
- rtl::OUStringBuffer buf(path);
- buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("/['"));
- css::lang::Locale locale(
- css::uno::Reference< css::lang::XLocalizable >(
- css::configuration::theDefaultProvider::get(context_),
- css::uno::UNO_QUERY_THROW)->
- getLocale());
- SAL_WARN_IF(
- locale.Language.indexOf('-') == -1, "unotools",
- "Locale language \"" << locale.Language << "\" contains \"-\"");
- assert(locale.Language.indexOf('&') == -1);
- assert(locale.Language.indexOf('"') == -1);
- assert(locale.Language.indexOf('\'') == -1);
- buf.append(locale.Language);
- SAL_WARN_IF(
- locale.Country.isEmpty() && !locale.Variant.isEmpty(), "unotools",
- "Locale has empty country but non-empty variant \"" << locale.Variant
- << '"');
- if (!locale.Country.isEmpty()) {
- buf.append('-');
- SAL_WARN_IF(
- locale.Country.indexOf('-') == -1, "unotools",
- "Locale language \"" << locale.Country << "\" contains \"-\"");
- assert(locale.Country.indexOf('&') == -1);
- assert(locale.Country.indexOf('"') == -1);
- assert(locale.Country.indexOf('\'') == -1);
- buf.append(locale.Country);
- if (!locale.Variant.isEmpty()) {
- buf.append('-');
- assert(locale.Variant.indexOf('&') == -1);
- assert(locale.Variant.indexOf('"') == -1);
- assert(locale.Variant.indexOf('\'') == -1);
- buf.append(locale.Variant);
- }
- }
- buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("']"));
- return buf.makeStringAndClear();
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */