Three configuration domains

In this article I would like to describe how pass variables(configuration) to application and core of libgreattao. Writing about core I have in mind the main libgreattao librarary – without backends. Core configuration can be separated into shell configuration and window classes configuration.

Each sub chapter I begun with describing how invoke application, giving t o it application’s configuration, shell’s configuration and window classes configuration.

Configuration can went from files or command line. Additionally, application’s configuration can went from arguments(command line) after three additional decorators and additionally from configuration window. Configuration window is automatically generatedby libgreattao. In future I would like to add configuration coming from network. I would like to add to libgreattao web serwer and wrote client. Of course, network source will be less important, so there’s no additional risk to application.

Application domain

Configuration from file


./our_program --tao-app-config-from-file /path/to/first/file,/path/to/second/file

Libgreattao will read configuration from files in giving order. Files read in future will override file read in past. There’s the same rules than in user’s file for specified application for selecting user’s application directory(~/.tao/apps), so options are assembled with spaces, name, equal signs and value. Name and value must be divided by equal sign not preceded with backslash character. Using of escape characters are allowed, like ‘\ ‘, ‘\n’, ‘\=’. Using sentences are allowed too.

Configuration from command line – line


./our_program --tao-app-config-from-line first_variable=first_value,second_variable=second_val

In this case application’s parameters are separated by commas. Each parameter are assembled by variable(variable’s name) and value.

Configuration from command line – tao-switch


./our_program --tao-app-config-tao-switch-first-option first_value --tao-app-config-tao-switch-second-option second_value

In this case you should use for all option –tao-app-config-tao-switch- and name of option. You should put value as next argument.

Long option – equivalent to getopts syntax


./our_program --first-option first_value --second-option second_value

It’s equivalent to long option getopts syntax. We here put two dash and next name of option.You should put option’s value as next argument. Difference between this and previous method is in handling way. In this case option with value are not removed from arguments list(char **argv, char *argv[]). As you can guess, in previous case, we remove option decorator and value from arguments list. It’s indented, because this syntax is also used by getopts and application can support custom options, so we cannot remove it on libgreattao_initialize.

Character-switch – (not) equivalent to getopts syntax


./our_program -a first_value -b second_value

In this case it looks like previous way. Decorator and value are not removed from list. As getopts short arguments, you can puts dash and letter as decorator. In difference to getopts you cannot put this characters together and after each decorator you must put value.

Reading order

In first position libgreattao tries to read files. As I explain above, files are read in order as given, so values in files read in future will override, what was read in past. In second step command line are read. In last step window with options are generated. For each command-line parameter application can select decorators for each option, so libgreattao can search for tao-switches, long switches, short switches. Tao command line switch(there, where you put options separated by commas) are always enabled to command-line source. Order for command line switches are described below:

  • tao-switches option
  • Long decorators
  • Characters(short) decorators
  • Tao line

For each option used decorators are determined by used flags for option. Values read in future overlapped values read in past.

Arguments querying


#include <libgreattao/tao.h>
#include <libgreattao/config.h>

#include <stdlib.h>
#include <string.h>

const struct tao_app_config_option options[4] =
{
{"a", "a", "a", TAO_TYPE_STRING, 'a', TAO_CONFIG_OPTION_ARG_TAO_DECORATOR | TAO_CONFIG_OPTION_ARG_LONG_DECORATOR | TAO_CONFIG_OPTION_ARG_CHARACTER_DECORATOR},
{"b", "b", "b", TAO_TYPE_INT, 'b', TAO_CONFIG_OPTION_ARG_TAO_DECORATOR | TAO_CONFIG_OPTION_ARG_LONG_DECORATOR | TAO_CONFIG_OPTION_ARG_CHARACTER_DECORATOR},
{"c", "c", "c", TAO_TYPE_UINT, 'c', TAO_CONFIG_OPTION_ARG_TAO_DECORATOR | TAO_CONFIG_OPTION_ARG_LONG_DECORATOR | TAO_CONFIG_OPTION_ARG_CHARACTER_DECORATOR},
{"file", "file", "file", TAO_TYPE_FILE_PATH, 0, 0}
};

struct tao_app_config_result results[4];

void close_window(void *mesh, void *mesh2)
{
tao_close();
}

int main(int argc, char **argv)
{
char *buffer;
void *message_window;
int length;
int number;

tao_initialize("tao options demonstration", "", &argc, argv);

tao_get_app_configuration(options, results, 4, TAO_APP_CONFIG_FROM_LINE | TAO_APP_CONFIG_FROM_FILE) ;

buffer = (char *) malloc(sizeof("Error getting string\n") - 1
+ sizeof("Error getting integer\n") - 1
+ sizeof("Error getting unsigned\n") - 1
+ sizeof("Error getting file path"));

buffer[0] = '';
if (results[0].error) {
strcat(buffer, "Error getting string\n");
}
if (results[1].error) {
strcat(buffer, "Error getting integer\n");
}
if (results[2].error) {
strcat(buffer, "Error getting unsigned\n");
}
if (results[3].error) {
strcat(buffer, "Error getting file path");
}

if (buffer[0] != '') {

message_window = tao_new_window("/desktop/dialogs/message_dialog");
tao_add_handler(message_window, "/message", NULL, 0);
tao_add_handler(message_window, "/:abort", close_window, 0);
tao_set_hint(message_window, "/message", HINT_NAME, buffer);
tao_handle_events();
tao_release_window(message_window);
}

length = sizeof("\"\" \"\"\n");
length += 2; /* Two numbers */
if (!results[0].error) {

length += strlen(results[0].result);
}
else {
length += sizeof("(null)") - 1;
}
if (!results[1].error) {

number = (int) results[1].result;
while (number /= 10) {
++length;
};
}
if (!results[2].error) {

number = (int) results[2].result;
while (number /= 10) {
++length;
}
}
if (!results[3].error) {

length += strlen(results[3].result);
}
else {
length += sizeof("(null)") - 1;
}

if (length > (sizeof("Error getting string\n") - 1
+ sizeof("Error getting integer\n") - 1
+ sizeof("Error getting unsigned\n") - 1
+ sizeof("Error getting file path"))) {

free(buffer);
buffer = (char *)malloc(sizeof(*buffer) * (length+1));
}
snprintf(buffer, length+1, "\"%s\" %d %d \"%s\"\n",results[0].result,results[1].result,results[2].result,results[3].result);
if (buffer[0] != '') {

message_window = tao_new_window("/desktop/dialogs/message_dialog");
tao_add_handler(message_window, "/message", NULL, 0);
tao_add_handler(message_window, "/:abort", close_window, 0);
tao_set_hint(message_window, "/message", HINT_NAME, buffer);
tao_handle_events();
tao_release_window(message_window);
}
free(buffer);
}

This is simple program, which obtain options and next displaying, which options are not passed and next displaying all option’s values. Most important is tao_get_app_configuration. It have pointer for option description as first argument. This structures are not modified by function. As next argument, there’s pointer for structure of results, which will be modified by this function. Program must result structures by 0 before calling this function. As next argument we have count of parameters and results structures. The numbers of parameter structures and result structures must match. As next argument we have flags. We can use these flags:

  • TAO_APP_CONFIG_FROM_FILE
  • TAO_APP_CONFIG_FROM_LINE
  • TAO_APP_CONFIG_INTERACTIVE
  • TAO_APP_CONFIG_INTERACTIVE_FORCE

First flag makes reading from files. Configuration came from files are read in libgrattao_initialize method – not in tao_get_app_config. Next flag makes reading form command line. Last two flags makes libgrattao display configuration window. The difference is flag with suffix _FORCE causes displaying all options – filled options too. Additional difference is flag without this suffix don’t display configuration window in case, when all options are filled.

In this paragraph I will describe option description structure. First field of this structure is name of option. It is used to add suffix of switches in command line and it’s also used to searching in command line. Second field is name displayed to user in configuration window. Third field is description displayed to user in configuration window. Fourth filed is option type. In example I uses all allowed types, like string, natural number, integer and file’s path. File path are handled in the same way as string, but for file path(in config window) there’s displayed additional button, which allows to select file. Next filed is character, which are used to short-switches(character decorators). Last argument are flags, which allows to select decorators allowed for current option.

Explained program don’t uses configuration window. To change this you should add flag to last argument of tao_get_app_configuration. It makes this function not returning, while passed data are incorrect. Configuration window guards to all option are correct and filled. Only in case, when user close configuration window, this function assign error to all options.

Shell configuration


./our_program --tao-shell-config-from-file /path/for/configuration/file/1,/path/for/configuration/file/2

It’s similar to application configuration. Files are parsed in giving order and have similar syntax as application configuration files.
Second case:

./our_program --tao-shell-config-from-line first_option=first_value,second_option=second_value

It’s similar to application configuration too

Of course, options given in command line are more important from that reading from files.

I will now show, how uses this data.

=fromconfig variable_name configuration_option_name

This command writes to variable with name given as first argument configuration option with name given as second argument.

Windows classes configuration


./our_program --tao-design-config-from-file /path/for/configuration/file/1,/path/for/configuration/file/2

It’s similar to application configuration. Files are parsed in giving order and have similar syntax as application configuration files.
Second case:

./our_program --tao-design-config-from-line first_option=first_value,second_option=second_value

This is similar as configuration of application.
Now, I will show how use this:

<root>

<fromconfig name="instance_id" configuration="instance_id" />
<label>
<attr-connect name="label" variable="instance_id" />
</label>
<label dir-for="label" path="/message" />
<label dir-for="description" path="/message" />

<hbox>
<template path="/actions/*">
<button label="ok" dir-for="event,label">
<attr-connect name="label" function="last-dir" />
</button>
</template>
</hbox>

</root>

We are using here fromconfig element. Name means variable name, which will be created/overwritten. Configuration is configuration option’s name of window classes. In next step we assign variable’s value to label element.

That’s all!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s