Reuse, not rework
Home

License Awareness



Highly Reusable Software

By activity
Professions, Sciences, Humanities, Business, ...

User Interface
Text-based, GUI, Audio, Video, Keyboards, Mouse, Images,...

Text Strings
Conversions, tests, processing, manipulation,...

Math
Integer, Floating point, Matrix, Statistics, Boolean, ...

Processing
Algorithms, Memory, Process control, Debugging, ...

Stored Data
Data storage, Integrity, Encryption, Compression, ...

Communications
Networks, protocols, Interprocess, Remote, Client Server, ...

Hard World
Timing, Calendar and Clock, Audio, Video, Printer, Controls...

File System
Management, Filtering, File & Directory access, Viewers, ...


LibROCK attribute files are human-editable text files used to specify name-value pairs and are often used for configuration and settings.

The file format supports assignment, directive, and comment lines, as well as nested sections (which are denoted by curly braces '{' and '}'.)

LibROCK provides functions to interpret files, report syntax errors, and use the results. (source file is data/attrib.c)

File syntax and semantics are documented on this page. (See also Core functions and Extensions.)

Attribute Files

The lines in libROCK attribute files are always evaluated in order, but the result is always equivalent to a list of attribute names and values in no guaranteed order.

All leading and trailing whitespace on a line is stripped before processing the line. (This allows indented formating.)

By design there is no line continuation character. There is no fixed limit on the number of characters in a line.

Assignment Lines

Assignment lines consist of a C language identifier followed by '=', and a value. (Whitespace before and after the '=' is ignored.) The characters permitted in an identifier can be changed using the .idchars directive.

There are three forms of assignment lines:

name = simple-string

name = "interpreted string"

name = ( expr )

All attribute values are processed as strings. (A client obtaining an attribute value may translate the string to a numeric or other value.)

Unless the first non-blank character following the '=' is a double-quote, or left parenthesis, the value string starts at that character and ends at the first whitespace. simple-string may not may not start '(' and may not contain '#' or '$'.

Strings surrounded in double-quotes are interpreted as a "C-backslash escaped" string, with any variable names in the form ${varname} substituted. These interpreted strings end at the next non-escaped double-quote, which must appear before the end of the line. Interpreted strings and expressions may optionally be followed by whitespace and '#'.

Attribute names are not case-sensitive.

It is a syntax error to have '#' comments on assignment lines unless you use double-quotes. (This also means that values which contain '#' must appear in double-quotes.) This is not necessary for the grammar, but detects ambiguous intent.

Directive lines

Lines which have '.' as the first non-blank character are directive lines. These directives are currently implemented. .include for using the contents of another attribute file.

.preserve for specifying that only some values in a section should be copied into the parent.

.prefix for prefixing values before they are copied to a parent.

.list for building indexed lists.

.call for performing user-defined operations.

.idchars for setting the characters permitted in names.

.error for writing error messages.

The syntax and use of these directives is detailed later.

Comment lines

Comments are empty lines, lines with only whitespace, and lines with '#' as the first non-blank character. Comments run to the end of the line.

Other lines may support comments appearing after the statement.

Section grouping lines

Sections are a very important feature of attribute files. They can be used to define name-value pairs in a heirarchy or list. Sections can nest, and can be conditionally skipped.

Sections in chisel attribute files always start with a left brace '{' and end with a '}' appearing as the first non-blank character on a line.

At the end of a section, the results of assignments within the section are copied to the parent attribute list, according to the collected preserve directives within the section and the last seen prefix directive. (These directives are described below.)

Sections may be conditionally skipped, starting them '{if expr' or '{ifnot expr', The expression syntax is described below, and the section is skipped when expr evaluates to "0" or "" or "false" in any combination of upper and lower case.

Sections which are being skipped are scanned only for section grouping lines and need not conform to any other syntax. (You may notice that this permits some block-style comments provided that lines with left or right braces as the first non-blank characters are suitably paired or formatted.)

When sections are used with included files, sections must end within the file they began, but intervening include directives are supported.

Expressions for assignments and conditional sections

expr used in the conditional directives and assignments is one of

    0

1

${name}

"interpreted string"

( expr )

A boolean function: DEFINED(name) EQ(expr,expr) NE(expr,expr) AND(exprlist) OR(exprlist) NOT(expr)

A built-in string function: _UCASE(expr) _LCASE(expr)

A function supplied by the client.

exprlist is one of
    expr

expr , exprlist

It is generally an error to have any part of expression undefined. (By design, undefined is not the same as false. The DEFINED() operator should be used instead.)

AND() and OR() operators do have C-like "short-circuiting" behavior, with exprlist evaluated left to right. This means that result may be defined in some cases even when all expressions in the exprlist are not.

EQ() and NE() are case-sensitive string tests.

The boolean functions (EQ,NE,NOT,AND,OR,DEFINED) have two possible results: "1" or ""

The expression processor is extensible, but names of operations beginning with a single '_' and with uppercase anywhere an alphabetic character appears are reserved for future standardization.

The .include directive

The include directive takes the following form:

.include "filename"

Use the .include directive to act as if the text from another file was inserted.

By design, "filename" is not an interpreted string. There certainly is more expressive power of being able to do something like .include ${the_file}, but the potential for abuse and unexpected behavior is large. (If an application has no alternative, it can be provided by implementing a function extension accessed through the .call directive.)

The .prefix directive

The prefix directive causes a string to be pre-pended to names copied to the parent list of attributes. This is very useful for specifying hierarchies of attributes.

The prefix directive takes two forms

.prefix simple-string

or

.prefix "interpreted string"

Where simple-string must not contain whitespace or '#', and "interpreted string" is evaluated when the directive is seen. A comment starting with '#' may appear after "interpreted string"

At the section ending, the string specified by the last prefix directive to appear during the section will be pre-pended to all names when the name-value pairs are copied to the parent's list of attributes. Normally the last character in the prefix string is a hierarchy separation character. (We suggest using '.' or '/'.)

The .idchars directive

This directive takes the form .idchars "interpreted string"

And all characters in the string after interpretation will be accepted as valid characters within a name for subsequent assignment statements.

"\0" (HEX 00, ASCII NUL) is never permitted in a name. Behavior if it appears in the idchars parameter string is indeterminate. There are other characters which are ill-advised, such as tabs, spaces, end of line characters, '#','=', and trying to use them will probably have limited utility.

The API has a function which permits setting a different set of characters for the first as compared to subsequent characters in a name. This distinction is not available with a directive.

The .error directive

This directive in a non-skipped section causes all characters after the directive up to the end of line to appear in the error output string, prefixed by the file position.

The .list directive

The .list directive permits sub-sections without a prefix directive to get an incrementing numerical prefix. This makes it easy to construct lists.

The .list directive takes two forms

.list simple-string

or

.list "interpreted string"

Where simple-string must not contain whitespace or '#', and "interpreted string" is evaluated when the directive is seen. A comment starting with '#' may appear after "interpreted string"

The string is used as the prefix for all following sub-sections which do not have a .prefix directive. Numerical digits in the string are replaced with the base 10 digits of counter value incremented each time it is used. If the value does not fit, an error is reported.

The primary purpose of this feature is to allow the .prefix directive to be used to construct lists of values and structures without requiring the user to manage an actual numeric or symbolic prefix.

The client software uses iteration functions to locate and extract such lists.


Source Code

./data/attrib.c (implementation, plus source of this manual page)

This software is part of Librock

Rapid reuse, without rework. Details
This page copyright (C) 2002-2004 Forrest J. Cavalier III, d-b-a Mib Software, Saylorsburg PA 18353, USA

Verbatim copying and distribution of this generated page is permitted in any medium provided that no changes are made.
(The source of this manual page may be covered by a more permissive license which allows modifications.)

Want to help? We welcome comments, patches. -- Need help? Request paid support.