# Features

- What is a feature?
- What is not a feature?
- Where are the features described?
- How does the feature system get the product's feature settings?
- How do I add a new feature?
- What is the syntax for features.version.txt?
- Current feature configuration

## What is a feature?

A feature is functionality implemented in the Opera source code. A feature turns on some code which does something.

This is true for all features:

- The have names on the form: FEATURE_NAME.
- They all turn on at least one preprocessor define.
- They can be turned on or off by defining the FEATURE_NAME to either YES or NO.
- To be able to turn on a feature, it may require other features to be turned on (dependencies).

## What is not a feature?

A platform or product dependant feature may not qualify as a real feature. A feature must be something other products may be interested in. It's not worth polluting the features system with non-portable features.

Functionality not ready for realease is also sometimes not qualified to be a feature. Depending on the phase of the current core code this may be more or less true. For example, if some functionality is developed in the early-phase of core-x, it can be a candidate for a feature, on the other hand if it is developed when some products already have shipped or are in release-phase, that is, when core-x is in late-phase, it may not be a candidate for a feature until the code is of good quality (matching the state of the rest of core-x).

## Where are the features described?

In `modules/hardcore/features/features.version.txt`. Where version is the version number if the current mainline configuration. Each mainline configuration has its own feature file. The version number is specified in modules/hardcore/version.ini. E.g. the feature file for the 2.4 version is `modules/hardcore/features/features.2.4.txt`.

The script that processes features.version.txt and generates the various related header files also generates an XML file containing the information in features.version.txt. This generated XML file is named `modules/hardcore/documentation/features.version.xml` and uses an XSLT stylesheet to render in a semi-useful format (including a colorful feature/profile matrix).

See:

## How does the feature system get the product's feature settings?

Each product must either define PRODUCT_FEATURE_FILE to the file to be used or change features.version.txt and add a PRODUCT_FEATURE_FILE-row at the top.

Then, the file is simply included like this:

    #include PRODUCT_FEATURE_FILE

## How do I add a new feature?

First, answer these questions:

- Is your code platform independent?
- Is your code protected by a single `#ifdef`?
- Is your code of accaptable quality, matching the state of the current core code?
- Does your code follow the coding standards?
- Is this something product manager will be interested in turning on or off?

If the answers are all positive, add your feature to features.version.txt and submit a patch bug.

Also consider if your code should instead go into the TWEAKS system.

## What is the syntax for features.version.txt?

    FEATURE_NAME					feature-owner

    	Description text.

    	Defines       : preprocessor-defines
    	Undefines     : preprocessor-defines
    	Group         : group
    	Depends on    : feature-list
    	Required by   : feature-list
    	Conflicts with: feature-list
            Enabled for   : profile-list
            Disabled for  : profile-list

feature-owner
  The feature owner is the name of the developer responsible for the feature. If this value is set to "deprecated" it means the feature is no longer available. The feature cannot be set (to YES or NO), and an error will be produced if it is set. Mandatory.
Description
  The description should describe the feature in such a way that the branch manager for a platform can easily understand what the feature does, without having to look at the source code. If possible, it should also say something about what configurations should enable or disable it. Can span several lines. Mandatory.
Defines
  A list of preprocessor defines separated by "," and/or "and". These will be defined when the feature is set to YES and be undefined when the feature is set to NO. Undefines or Defines is mandatory for every feature.
Undefines
  A list of preprocessor defines separated by "," and/or "and". These will be undefined when the feature is set to NO and defined when the feature is set to YES. For example, FEATURE_MOUSE has Undefines set to MOUSELESS, which means that FEATURE_MOUSE set to NO will define MOUSELESS. Undefines or Defines is mandatory for every feature.
Group
  Documentation purpose to make it easier to see which features belong together. Is used by the editor.pike tool. Not mandatory.
Depends on
  List of features which this feature depends on. The other features must be turned on to be able to turn this feature on. The features are separated by "," and/or "and". "nothing" is a valid value. Not mandatory, if left out it means "nothing".
Required by
  List of features which depend on this feature. The features are separated by "," and/or "and". "nothing" is a valid value. Not mandatory, if left out it means "nothing".
Conflicts with
  List of features which cannot be turned on if this feature is turned on. The features are separated by "," and/or "and". "nothing" is a valid value. Not mandatory, if left out it means "nothing".
Enabled for
  List of profiles for which this feature is enabled by default. For each listed profile X, the file hardcore/features/profile_X.h will contain the line `#define FEATURE_WHATEVER YES`. The value special value "none" means the feature is not enabled for any profiles by default.
Disabled for
  List of profiles for which this feature is disabled by default. For each listed profile X, the file hardcore/features/profile_X.h will contain the line `#define FEATURE_WHATEVER NO`. The value special value "none" means the feature is not disabled for any profiles by default.

Example:

    FEATURE_PREFS_WRITE							peter

    	Makes preferences support writing. Enables all APIs to save
    	preferences, and also turns on support for writing generic INI files.
    	Most normal platforms will want to enable this.

    	Defines     : PREFS_WRITE, PREFSFILE_WRITE
    	Undefines   : PREFS_NO_WRITE
    	Group       : prefs
    	Depends on  : nothing
    	Required by : FEATURE_OPERACONFIG_URL, FEATURE_PREFS_DOWNLOAD
    	Enabled for : desktop, smartphone, tv
    	Disabled for: minimal, mini

Let's look at the autogenerated code which turns on defines for FEATURE_PREFS_WRITE:

    #if FEATURE_PREFS_WRITE == YES
    # undef PREFSFILE_WRITE
    # define PREFSFILE_WRITE
    # undef PREFS_WRITE
    # define PREFS_WRITE
    #else
    # undef PREFS_NO_WRITE
    # define PREFS_NO_WRITE
    # endif // FEATURE_PREFS_WRITE

This means the "Defines" defines are turned on if set to YES and the "Undefines" are turned on if set to NO. This feature is required by FEATURE_OPERACONFIG_URL and FEATURE_PREFS_DOWNLOAD which means neither of them can be turned on if FEATURE_PREFS_WRITE is set to NO.

## Current feature configuration

current | next
--- | ---