Jive reference manual
Properties file format

A properties file is made up of a series of comments, include statements, and property definition statements. Whitespace – a series of spaces, tabs and newlines – is not significant.

Comments

Comments come in two flavors: single-line comments and comment blocks. A single-line comment starts with two slashes and ends at the first newline character. A comment block starts with a slash-star and ends with a star-slash. Comment blocks may contain nested comment blocks. The file fragment below demonstrates the use of different types of comments.

// This is a single line comment. Two slashes, //, or a
// slash-star, /*, have no special meaning in a single-line
// comment. 

/* This is a comment block. Two slashes, //, have no special
   meaning inside a comment block. A slash-star starts a nested
   comment block: /* this nested block must be properly terminated
   by a star-slash */. The main comment block ends here. */

Include statements

A properties file may include another file by means an include statement. Such a statements has the following format:

include file ;

where file is a quoted string specifying the name of the file to be included. The contents of that file are inserted into the current properties file, right after the include statement. If file is a relative file name, then the search for the file starts from the directory containing the current properties file.

If the string file contains substitution directives, these are expanded before the file is opened (provided that string expansion is enabled). See the section String expansions for more information.

Note that support for include statements is controlled by the constant Properties::PARSE_INCLUDE.

Property definitions

A property definition has the following format:

name = value ;

The name of a property is either a simple name or a compound name. A simple name starts with an alphabetic character or an underscore, followed by an arbitrary number of alphanumeric characters and/or underscores. A compound name consists of one or more simple names separated by dots. Such a compound name refers to a property in a nested properties set. If a compound name starts with a single dot, it refers to a property in the root properties set; see the section Nested properties for the details.

The value of a property can be a boolean, an integer, a floating point number, a string, or a one-dimensional array containing elements of these types. The value of a property can also be a nested set of properties or a reference to another property.

The file fragment below shows a some property definitions. The details are discussed in the following sections.

company   = "ACME Corp";
countries = [ "USA", "Mexico", "Cuba" ];

finances  = {
  revenues = 1.2e9;
  costs    = 0.8e9;
  taxes    = 0.2e9;
};

people.management  = 125;
people.engineering = 814;
people.marketing   = 245;
people.sales       = people.marketing;

Boolean properties

The value of a boolean property is specified by the words true and false. Example:

displaySplashScreen = true;
enableExpertMenus   = false;

Note that case matters; words such as False and TRUE do not specify a boolean value.

A boolean property has type bool in a C++ program.

Integer properties

The value of an integer property can be specified as a decimal or hexadecimal number. The former consists of an optional plus or minus sign, followed by one or more decimal digits. The latter consists of the prefix 0x or 0X, followed by one or more hexadecimal digits. Here is an example:

i =     123;
j =    -123;
k =  0xff11;
m =  0XFF11;

An integer property has type int in a C++ program.

Floating point properties

The value of a floating point property starts with an optional plus or minus sign, followed by one or more decimal digits, followed by a decimal point, followed by one or more decimal digits. Optionally, it ends with an exponent: the character e or E, followed by an optional plus or minus sign, followed by one or more decimal digits. Here is an example:

x =      1.0;
y =    -2.33;
z = +3.44e-8;

A floating point property has type double in a C++ program.

String properties

The value of a string property consists of a series of characters and/or whitespace between two single quotes ' or two double quotes ". A single-quoted string may contain double quotes, and the other way around. Two strings separated by whitespace are joined into a single string.

Special characters can be entered by using an escape escape sequence: a backslash followed by some other character. The table below lists the available escape sequences.

Escape sequenceResulting character
\\backslash
\nnewline
\thorizontal tab
\vvertical tab
\bbackspace
\fform feed
\rcarriage return
\'single quote
\"double quote

In addition, a backslash followed by a space results in space.

A string may contain multiple newline characters. All whitespace after a newline character is discarded, except when the newline character is preceded by a backslash. In this case, the backslash-newline sequence is discarded but all following whitespace is included in the string.

Below is an example properties file containing some string properties.

str1 = 'a single-quoted string';
str2 = "a double-quoted string";
str3 = "a string " "split in two";
str4 = "a string with a \t tab and a \n newline";
str5 = "a string spanning 
        two lines";

String properties may contain embedded substitution directives that are expanded before the string is stored in a properties set. See the section String expansions for more information.

A string property has type jem::String in a C++ program.

Array properties

The value of an array property is made up of a comma-separated list of elements between an left bracket [ and a right bracket ]. An array element can be a boolean values, an integer number, a floating point number and a string. All array elements must have the same type. An empty array – that is, an array without elements – consists of only a left bracket followed by a right bracket. Here is an example involving some array properties:

a = [];                    // An empty array
b = [ true, false ];       // A boolean array
c = [ 1, -1,  3 ];         // An integer array
d = [ "hello", "world" ];  // A string array
e = [ 1.0, false, 2.0 ];   // Error: elements have mixed type

Substitution directives embedded in the elements of a string array are expanded in the same way as they are expanded in string properties.

Array properties have type jem::Array<T> in a C++ program. The template parameter T equals the type of the array elements. An empty array is represented by an object reference that has value NIL.

Nested properties

A nested set of properties is composed of a left brace ({), followed by zero or more property definitions, followed by a right brace (}). Here is an example:

displayOptions =
{
  fontType     = "Times";
  lineWidth    = 4;
  antiAliasing = true;
};

This file fragment defines a nested properties set named displayOptions that contains the properties fontType, lineWidth, and antiAliasing.

Properties sets may be nested to any depth. The top-most set of properties is called the root set.

Nested properties sets have type jem::util::Properties in a C++ program.

Property references

If the value of a property is a property name, then the value of the named property is assigned to the target property. This is best explained with a simple example:

a = 10;
b = a;

After reading this properties file, both properties a and b will have the integer value 10.

The right-hand side property is looked up in the current set of properties. If it can not be found, it is recursively looked up in the enclosing properties set, until the root set is reached. If the property can not be found in the root set, an error is generated. In the case that the name of the right-hand side property starts with a dot, the search for the property is limited to the root set. Here is an example involving nested properties sets:

a =
{
  a = 1;
  b =
  {
    a = 2;
  };
  c =
  {
    d = 3;
    e = d;
    f = a;
    g = b.a;
    h = .a.b.a;
  };
};

These property definitions specify that the property a.c.e should be assigned the value 3; that the property a.c.f should be assigned the value 1; that the property a.c.g should be assigned the value 2; and that the property a.c.h should also be assigned the value 2.

Note that poperties are assigned by value. This means that the left-hand property and the right-hand property refer to different objects. A consequence of this is that the left-hand property is not affected by any later modifications to the right-hand property, and the other way around. This is illustrated by the following example:

a =
{
  x = 1.0;
  y = 2.0;
};

b   = a;
b.x = 1.5;

After reading this properties file, the property a.x will be equal to 1.0, and the property b.x will be equal to 1.5.

String expansions

A string may contain substitution directives that have the following format:

$(name)

where name is either the name of an existing property, or the name of a built-in command. Such a substitution directive is replaced by the value of the referenced property or the output produced by the built-in command. This is illustrated in the following example:

strings =
{
  hello = "Hello";
};

dialog  =
{
  text  = "$(strings.hello) $(_USER_)!";
};

Once this file has been parsed, the property dialog.text will have the value "Hello mike!" if the current user is named mike.

The following table lists the available built-in commands.

Name

Resulting string

_PATH_

the full path name of the current file

_FILE_

the name of the current file

_DIR_

the name of the directory containing the current file

_USER_

the name of the current user

_HOME_

the home directory of the current user

_HOST_

the name of the current computer

_TIME_

the current time

_DATE_ the current date

Because each $ character in a string is assumed to be the beginning of a substitution directive, two consecutive $ characters must be used to obtain a single $ character in an expanded string. Thus, the string "\$\$(_DATE_)" will be expanded to the string "\$(_DATE_)".

Note that string expansion must be enabled with the constant Properties::PARSE_STRINGS.